diff --git a/components/metrics/BarChart.js b/components/metrics/BarChart.js index 3065247a..95f25a5e 100644 --- a/components/metrics/BarChart.js +++ b/components/metrics/BarChart.js @@ -1,5 +1,5 @@ import { useState, useRef, useEffect, useMemo, useCallback } from 'react'; -import { StatusLight } from 'react-basics'; +import { StatusLight, Loading } from 'react-basics'; import classNames from 'classnames'; import Chart from 'chart.js/auto'; import HoverTooltip from 'components/common/HoverTooltip'; @@ -39,6 +39,26 @@ export default function BarChart({ 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; @@ -115,6 +135,7 @@ export default function BarChart({ color: colors.text, autoSkip: false, maxRotation: 0, + callback: renderXLabel, }, }, y: { @@ -135,7 +156,7 @@ export default function BarChart({ }, }, }; - }, [animationDuration, renderTooltip, stacked, colors, unit]); + }, [animationDuration, renderTooltip, renderXLabel, stacked, colors, unit, locale]); const createChart = () => { Chart.defaults.font.family = 'Inter'; @@ -158,7 +179,9 @@ export default function BarChart({ chart.current.options = getOptions(); - chart.current.data.datasets = datasets; + if (datasets.length) { + chart.current.data.datasets = datasets; + } chart.current.update(); @@ -173,11 +196,12 @@ export default function BarChart({ updateChart(); } } - }, [datasets, unit, theme, animationDuration, locale, loading]); + }, [datasets, unit, theme, animationDuration, locale]); return ( <>
+ {loading && }
diff --git a/components/metrics/Legend.js b/components/metrics/Legend.js index 32267970..10848066 100644 --- a/components/metrics/Legend.js +++ b/components/metrics/Legend.js @@ -1,3 +1,4 @@ +import { useEffect } from 'react'; import { StatusLight } from 'react-basics'; import { colord } from 'colord'; import classNames from 'classnames'; @@ -9,7 +10,7 @@ export default function Legend({ chart }) { const { locale } = useLocale(); const forceUpdate = useForceUpdate(); - function handleClick(index) { + const handleClick = index => { const meta = chart.getDatasetMeta(index); meta.hidden = meta.hidden === null ? !chart.data.datasets[index].hidden : null; @@ -17,7 +18,11 @@ export default function Legend({ chart }) { chart.update(); forceUpdate(); - } + }; + + useEffect(() => { + forceUpdate(); + }, [locale]); if (!chart?.legend?.legendItems.find(({ text }) => text)) { return null; diff --git a/components/metrics/PageviewsChart.js b/components/metrics/PageviewsChart.js index c3c1d6fa..7370e5f9 100644 --- a/components/metrics/PageviewsChart.js +++ b/components/metrics/PageviewsChart.js @@ -4,6 +4,7 @@ import BarChart from './BarChart'; import { THEME_COLORS } from 'lib/constants'; import useTheme from 'hooks/useTheme'; import useMessages from 'hooks/useMessages'; +import useLocale from 'hooks/useLocale'; export default function PageviewsChart({ websiteId, @@ -16,6 +17,7 @@ export default function PageviewsChart({ }) { const { formatMessage, labels } = useMessages(); const [theme] = useTheme(); + const { locale } = useLocale(); const colors = useMemo(() => { const primaryColor = colord(THEME_COLORS[theme].primary); @@ -52,7 +54,7 @@ export default function PageviewsChart({ ...colors.views, }, ]; - }, [data]); + }, [data, locale, colors]); return (