1
0
mirror of https://github.com/kremalicious/umami.git synced 2025-02-14 21:10:34 +01:00

Localize x axis labels. Closes

This commit is contained in:
Mike Cao 2023-04-19 11:41:31 -07:00
parent 083a9ffc2c
commit cc20f898b1
3 changed files with 38 additions and 7 deletions

View File

@ -1,5 +1,5 @@
import { useState, useRef, useEffect, useMemo, useCallback } from 'react'; import { useState, useRef, useEffect, useMemo, useCallback } from 'react';
import { StatusLight } from 'react-basics'; import { StatusLight, Loading } from 'react-basics';
import classNames from 'classnames'; import classNames from 'classnames';
import Chart from 'chart.js/auto'; import Chart from 'chart.js/auto';
import HoverTooltip from 'components/common/HoverTooltip'; import HoverTooltip from 'components/common/HoverTooltip';
@ -39,6 +39,26 @@ export default function BarChart({
return +label > 1000 ? formatLongNumber(label) : 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( const renderTooltip = useCallback(
model => { model => {
const { opacity, labelColors, dataPoints } = model.tooltip; const { opacity, labelColors, dataPoints } = model.tooltip;
@ -115,6 +135,7 @@ export default function BarChart({
color: colors.text, color: colors.text,
autoSkip: false, autoSkip: false,
maxRotation: 0, maxRotation: 0,
callback: renderXLabel,
}, },
}, },
y: { y: {
@ -135,7 +156,7 @@ export default function BarChart({
}, },
}, },
}; };
}, [animationDuration, renderTooltip, stacked, colors, unit]); }, [animationDuration, renderTooltip, renderXLabel, stacked, colors, unit, locale]);
const createChart = () => { const createChart = () => {
Chart.defaults.font.family = 'Inter'; Chart.defaults.font.family = 'Inter';
@ -158,7 +179,9 @@ export default function BarChart({
chart.current.options = getOptions(); chart.current.options = getOptions();
chart.current.data.datasets = datasets; if (datasets.length) {
chart.current.data.datasets = datasets;
}
chart.current.update(); chart.current.update();
@ -173,11 +196,12 @@ export default function BarChart({
updateChart(); updateChart();
} }
} }
}, [datasets, unit, theme, animationDuration, locale, loading]); }, [datasets, unit, theme, animationDuration, locale]);
return ( return (
<> <>
<div className={classNames(styles.chart, className)}> <div className={classNames(styles.chart, className)}>
{loading && <Loading position="page" icon="dots" />}
<canvas ref={canvas} /> <canvas ref={canvas} />
</div> </div>
<Legend chart={chart.current} /> <Legend chart={chart.current} />

View File

@ -1,3 +1,4 @@
import { useEffect } from 'react';
import { StatusLight } from 'react-basics'; import { StatusLight } from 'react-basics';
import { colord } from 'colord'; import { colord } from 'colord';
import classNames from 'classnames'; import classNames from 'classnames';
@ -9,7 +10,7 @@ export default function Legend({ chart }) {
const { locale } = useLocale(); const { locale } = useLocale();
const forceUpdate = useForceUpdate(); const forceUpdate = useForceUpdate();
function handleClick(index) { const handleClick = index => {
const meta = chart.getDatasetMeta(index); const meta = chart.getDatasetMeta(index);
meta.hidden = meta.hidden === null ? !chart.data.datasets[index].hidden : null; meta.hidden = meta.hidden === null ? !chart.data.datasets[index].hidden : null;
@ -17,7 +18,11 @@ export default function Legend({ chart }) {
chart.update(); chart.update();
forceUpdate(); forceUpdate();
} };
useEffect(() => {
forceUpdate();
}, [locale]);
if (!chart?.legend?.legendItems.find(({ text }) => text)) { if (!chart?.legend?.legendItems.find(({ text }) => text)) {
return null; return null;

View File

@ -4,6 +4,7 @@ import BarChart from './BarChart';
import { THEME_COLORS } from 'lib/constants'; import { THEME_COLORS } from 'lib/constants';
import useTheme from 'hooks/useTheme'; import useTheme from 'hooks/useTheme';
import useMessages from 'hooks/useMessages'; import useMessages from 'hooks/useMessages';
import useLocale from 'hooks/useLocale';
export default function PageviewsChart({ export default function PageviewsChart({
websiteId, websiteId,
@ -16,6 +17,7 @@ export default function PageviewsChart({
}) { }) {
const { formatMessage, labels } = useMessages(); const { formatMessage, labels } = useMessages();
const [theme] = useTheme(); const [theme] = useTheme();
const { locale } = useLocale();
const colors = useMemo(() => { const colors = useMemo(() => {
const primaryColor = colord(THEME_COLORS[theme].primary); const primaryColor = colord(THEME_COLORS[theme].primary);
@ -52,7 +54,7 @@ export default function PageviewsChart({
...colors.views, ...colors.views,
}, },
]; ];
}, [data]); }, [data, locale, colors]);
return ( return (
<BarChart <BarChart