import { useState, useRef, useEffect } from 'react'; import { StatusLight } from 'react-basics'; import classNames from 'classnames'; import ChartJS from 'chart.js'; import HoverTooltip from 'components/common/HoverTooltip'; import Legend from 'components/metrics/Legend'; import { formatLongNumber } from 'lib/format'; import { dateFormat } from 'lib/date'; import useLocale from 'hooks/useLocale'; import useTheme from 'hooks/useTheme'; import useForceUpdate from 'hooks/useForceUpdate'; import { DEFAULT_ANIMATION_DURATION, THEME_COLORS } from 'lib/constants'; import styles from './BarChart.module.css'; export default function BarChart({ datasets, unit, records, animationDuration = DEFAULT_ANIMATION_DURATION, className, stacked = false, loading = false, onCreate = () => {}, onUpdate = () => {}, }) { const canvas = useRef(); const chart = useRef(); const [tooltip, setTooltip] = useState(null); const { locale } = useLocale(); const [theme] = useTheme(); const forceUpdate = useForceUpdate(); const colors = { text: THEME_COLORS[theme].gray700, line: THEME_COLORS[theme].gray200, zeroLine: THEME_COLORS[theme].gray500, }; function renderXLabel(label, index, values) { if (loading) return ''; const d = new Date(values[index].value); const sw = canvas.current.width / window.devicePixelRatio; switch (unit) { case 'minute': return index % 2 === 0 ? dateFormat(d, 'H:mm', locale) : ''; case 'hour': return dateFormat(d, 'p', locale); case 'day': if (records > 25) { if (sw <= 275) { return index % 10 === 0 ? dateFormat(d, 'M/d', locale) : ''; } if (sw <= 550) { return index % 5 === 0 ? dateFormat(d, 'M/d', locale) : ''; } if (sw <= 700) { return index % 2 === 0 ? dateFormat(d, 'M/d', locale) : ''; } return dateFormat(d, 'MMM d', locale); } if (sw <= 375) { return index % 2 === 0 ? dateFormat(d, 'MMM d', locale) : ''; } if (sw <= 425) { return dateFormat(d, 'MMM d', locale); } return dateFormat(d, 'EEE M/d', locale); case 'month': if (sw <= 330) { return index % 2 === 0 ? dateFormat(d, 'MMM', locale) : ''; } return dateFormat(d, 'MMM', locale); default: return label; } } function renderYLabel(label) { return +label > 1000 ? formatLongNumber(label) : label; } function renderTooltip(model) { const { opacity, title, body, labelColors } = model; if (!opacity || !title) { setTooltip(null); return; } const [label, value] = body[0].lines[0].split(':'); const format = unit === 'hour' ? 'EEE p — PPP' : 'PPPP'; setTooltip( <>