mirror of
https://github.com/kremalicious/umami.git
synced 2025-02-14 21:10:34 +01:00
Moved render functions into lib/charts.
This commit is contained in:
parent
5a5127c921
commit
3ccdd95f49
@ -86,7 +86,7 @@ export function WorldMap({ data, className }) {
|
|||||||
</Geographies>
|
</Geographies>
|
||||||
</ZoomableGroup>
|
</ZoomableGroup>
|
||||||
</ComposableMap>
|
</ComposableMap>
|
||||||
{tooltip && <HoverTooltip tooltip={tooltip} />}
|
{tooltip && <HoverTooltip>{tooltip}</HoverTooltip>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,12 @@ 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';
|
||||||
import Legend from 'components/metrics/Legend';
|
import Legend from 'components/metrics/Legend';
|
||||||
import { formatLongNumber } from 'lib/format';
|
|
||||||
import useLocale from 'hooks/useLocale';
|
import useLocale from 'hooks/useLocale';
|
||||||
import useTheme from 'hooks/useTheme';
|
import useTheme from 'hooks/useTheme';
|
||||||
import { DEFAULT_ANIMATION_DURATION } from 'lib/constants';
|
import { DEFAULT_ANIMATION_DURATION } from 'lib/constants';
|
||||||
|
import { renderNumberLabels } from 'lib/charts';
|
||||||
import styles from './BarChart.module.css';
|
import styles from './BarChart.module.css';
|
||||||
|
|
||||||
function defaultRenderYLabel(label) {
|
|
||||||
return +label > 1000 ? formatLongNumber(label) : label;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function BarChart({
|
export function BarChart({
|
||||||
datasets,
|
datasets,
|
||||||
unit,
|
unit,
|
||||||
@ -90,7 +86,7 @@ export function BarChart({
|
|||||||
},
|
},
|
||||||
ticks: {
|
ticks: {
|
||||||
color: colors.text,
|
color: colors.text,
|
||||||
callback: renderYLabel || defaultRenderYLabel,
|
callback: renderYLabel || renderNumberLabels,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -2,16 +2,15 @@ import { useMemo } from 'react';
|
|||||||
import { Loading } from 'react-basics';
|
import { Loading } from 'react-basics';
|
||||||
import { colord } from 'colord';
|
import { colord } from 'colord';
|
||||||
import BarChart from './BarChart';
|
import BarChart from './BarChart';
|
||||||
import { getDateArray, getDateLength } from 'lib/date';
|
import { getDateArray } from 'lib/date';
|
||||||
import useApi from 'hooks/useApi';
|
import { useApi, useLocale, useDateRange, useTimezone, usePageQuery } from 'hooks';
|
||||||
import useDateRange from 'hooks/useDateRange';
|
|
||||||
import useTimezone from 'hooks/useTimezone';
|
|
||||||
import usePageQuery from 'hooks/usePageQuery';
|
|
||||||
import { EVENT_COLORS } from 'lib/constants';
|
import { EVENT_COLORS } from 'lib/constants';
|
||||||
|
import { renderDateLabels, renderStatusTooltip } from 'lib/charts';
|
||||||
|
|
||||||
export function EventsChart({ websiteId, className, token }) {
|
export function EventsChart({ websiteId, className, token }) {
|
||||||
const { get, useQuery } = useApi();
|
const { get, useQuery } = useApi();
|
||||||
const [{ startDate, endDate, unit, modified }] = useDateRange(websiteId);
|
const [{ startDate, endDate, unit, modified }] = useDateRange(websiteId);
|
||||||
|
const { locale } = useLocale();
|
||||||
const [timezone] = useTimezone();
|
const [timezone] = useTimezone();
|
||||||
const {
|
const {
|
||||||
query: { url, eventName },
|
query: { url, eventName },
|
||||||
@ -70,9 +69,10 @@ export function EventsChart({ websiteId, className, token }) {
|
|||||||
datasets={datasets}
|
datasets={datasets}
|
||||||
unit={unit}
|
unit={unit}
|
||||||
height={300}
|
height={300}
|
||||||
records={getDateLength(startDate, endDate, unit)}
|
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
stacked
|
stacked
|
||||||
|
renderXLabel={renderDateLabels(unit, locale)}
|
||||||
|
renderTooltip={renderStatusTooltip(unit, locale)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,74 +1,13 @@
|
|||||||
import { useCallback, useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { StatusLight } from 'react-basics';
|
|
||||||
import BarChart from './BarChart';
|
import BarChart from './BarChart';
|
||||||
import useTheme from 'hooks/useTheme';
|
import { useLocale, useTheme, useMessages } from 'hooks';
|
||||||
import useMessages from 'hooks/useMessages';
|
import { renderDateLabels, renderStatusTooltip } from 'lib/charts';
|
||||||
import useLocale from 'hooks/useLocale';
|
|
||||||
import { dateFormat } from 'lib/date';
|
|
||||||
import { formatLongNumber } from 'lib/format';
|
|
||||||
|
|
||||||
export function PageviewsChart({ websiteId, data, unit, className, loading, ...props }) {
|
export function PageviewsChart({ websiteId, data, unit, className, loading, ...props }) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
const { locale } = useLocale();
|
const { locale } = useLocale();
|
||||||
|
|
||||||
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);
|
|
||||||
case 'year':
|
|
||||||
return dateFormat(d, 'YYY', locale);
|
|
||||||
default:
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[locale, unit],
|
|
||||||
);
|
|
||||||
|
|
||||||
const renderTooltip = useCallback(
|
|
||||||
(setTooltip, 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(
|
|
||||||
<>
|
|
||||||
<div>{dateFormat(new Date(dataPoints[0].raw.x), formats[unit], locale)}</div>
|
|
||||||
<div>
|
|
||||||
<StatusLight color={labelColors?.[0]?.backgroundColor}>
|
|
||||||
{formatLongNumber(dataPoints[0].raw.y)} {dataPoints[0].dataset.label}
|
|
||||||
</StatusLight>
|
|
||||||
</div>
|
|
||||||
</>,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
[unit],
|
|
||||||
);
|
|
||||||
|
|
||||||
const datasets = useMemo(() => {
|
const datasets = useMemo(() => {
|
||||||
if (!data) return [];
|
if (!data) return [];
|
||||||
|
|
||||||
@ -96,8 +35,8 @@ export function PageviewsChart({ websiteId, data, unit, className, loading, ...p
|
|||||||
datasets={datasets}
|
datasets={datasets}
|
||||||
unit={unit}
|
unit={unit}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
renderXLabel={renderXLabel}
|
renderXLabel={renderDateLabels(unit, locale)}
|
||||||
renderTooltip={renderTooltip}
|
renderTooltip={renderStatusTooltip(unit, locale)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
SubmitButton,
|
SubmitButton,
|
||||||
Text,
|
Text,
|
||||||
TextField,
|
TextField,
|
||||||
|
Tooltip,
|
||||||
} from 'react-basics';
|
} from 'react-basics';
|
||||||
import Icons from 'components/icons';
|
import Icons from 'components/icons';
|
||||||
import { updateReport } from 'store/reports';
|
import { updateReport } from 'store/reports';
|
||||||
@ -91,6 +92,7 @@ function AddURLButton({ onAdd }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<Tooltip label={formatMessage(labels.addUrl)}>
|
||||||
<ModalTrigger>
|
<ModalTrigger>
|
||||||
<Icon>
|
<Icon>
|
||||||
<Icons.Plus />
|
<Icons.Plus />
|
||||||
@ -113,6 +115,7 @@ function AddURLButton({ onAdd }) {
|
|||||||
}}
|
}}
|
||||||
</Modal>
|
</Modal>
|
||||||
</ModalTrigger>
|
</ModalTrigger>
|
||||||
|
</Tooltip>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
62
lib/charts.js
Normal file
62
lib/charts.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { StatusLight } from 'react-basics';
|
||||||
|
import { dateFormat } from 'lib/date';
|
||||||
|
import { formatLongNumber } from 'lib/format';
|
||||||
|
|
||||||
|
export function renderNumberLabels(label) {
|
||||||
|
return +label > 1000 ? formatLongNumber(label) : label;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function renderDateLabels(unit, locale) {
|
||||||
|
return (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);
|
||||||
|
case 'year':
|
||||||
|
return dateFormat(d, 'YYY', locale);
|
||||||
|
default:
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function renderStatusTooltip(unit, locale) {
|
||||||
|
return (setTooltip, 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(
|
||||||
|
<>
|
||||||
|
<div>{dateFormat(new Date(dataPoints[0].raw.x), formats[unit], locale)}</div>
|
||||||
|
<div>
|
||||||
|
<StatusLight color={labelColors?.[0]?.backgroundColor}>
|
||||||
|
{formatLongNumber(dataPoints[0].raw.y)} {dataPoints[0].dataset.label}
|
||||||
|
</StatusLight>
|
||||||
|
</div>
|
||||||
|
</>,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user