import { useState, useRef, useEffect, useMemo, useCallback } from 'react'; import { StatusLight, Loading } from 'react-basics'; import classNames from 'classnames'; import Chart from 'chart.js/auto'; 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 { DEFAULT_ANIMATION_DURATION, THEME_COLORS } from 'lib/constants'; import styles from './BarChart.module.css'; export function BarChart({ datasets, unit, animationDuration = DEFAULT_ANIMATION_DURATION, stacked = false, loading = false, onCreate = () => {}, onUpdate = () => {}, className, }) { const canvas = useRef(); const chart = useRef(null); const [tooltip, setTooltip] = useState(null); const { locale } = useLocale(); const [theme] = useTheme(); const colors = useMemo( () => ({ text: THEME_COLORS[theme].gray700, line: THEME_COLORS[theme].gray200, }), [theme], ); const renderYLabel = label => { return +label > 1000 ? formatLongNumber(label) : label; }; const renderXLabel = useCallback( (label, index, values) => { const d = new Date(values[index].value); switch (unit) { case 'minute': return dateFormat(d, 'h:mm', locale); case 'hour': return dateFormat(d, 'p', locale); case 'day': return dateFormat(d, 'MMM d', locale); case 'month': return dateFormat(d, 'MMM', locale); default: return label; } }, [locale, unit], ); const renderTooltip = useCallback( model => { const { opacity, labelColors, dataPoints } = model.tooltip; if (!dataPoints?.length || !opacity) { setTooltip(null); return; } const formats = { millisecond: 'T', second: 'pp', minute: 'p', hour: 'h:mm aaa - PP', day: 'PPPP', week: 'PPPP', month: 'LLLL yyyy', quarter: 'qqq', year: 'yyyy', }; setTooltip(