From 3ccdd95f49948202ada769530f07bc71bb58fa46 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Thu, 25 May 2023 10:26:00 -0700 Subject: [PATCH] Moved render functions into lib/charts. --- components/common/WorldMap.js | 2 +- components/metrics/BarChart.js | 8 +-- components/metrics/EventsChart.js | 12 ++-- components/metrics/PageviewsChart.js | 71 ++----------------- .../pages/reports/funnel/FunnelParameters.js | 47 ++++++------ lib/charts.js | 62 ++++++++++++++++ 6 files changed, 101 insertions(+), 101 deletions(-) create mode 100644 lib/charts.js diff --git a/components/common/WorldMap.js b/components/common/WorldMap.js index a371e2d3..31c6686b 100644 --- a/components/common/WorldMap.js +++ b/components/common/WorldMap.js @@ -86,7 +86,7 @@ export function WorldMap({ data, className }) { - {tooltip && } + {tooltip && {tooltip}} ); } diff --git a/components/metrics/BarChart.js b/components/metrics/BarChart.js index 9206b800..2aba3ea5 100644 --- a/components/metrics/BarChart.js +++ b/components/metrics/BarChart.js @@ -4,16 +4,12 @@ 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 useLocale from 'hooks/useLocale'; import useTheme from 'hooks/useTheme'; import { DEFAULT_ANIMATION_DURATION } from 'lib/constants'; +import { renderNumberLabels } from 'lib/charts'; import styles from './BarChart.module.css'; -function defaultRenderYLabel(label) { - return +label > 1000 ? formatLongNumber(label) : label; -} - export function BarChart({ datasets, unit, @@ -90,7 +86,7 @@ export function BarChart({ }, ticks: { color: colors.text, - callback: renderYLabel || defaultRenderYLabel, + callback: renderYLabel || renderNumberLabels, }, }, }, diff --git a/components/metrics/EventsChart.js b/components/metrics/EventsChart.js index eb397cc9..334ee591 100644 --- a/components/metrics/EventsChart.js +++ b/components/metrics/EventsChart.js @@ -2,16 +2,15 @@ import { useMemo } from 'react'; import { Loading } from 'react-basics'; import { colord } from 'colord'; import BarChart from './BarChart'; -import { getDateArray, getDateLength } from 'lib/date'; -import useApi from 'hooks/useApi'; -import useDateRange from 'hooks/useDateRange'; -import useTimezone from 'hooks/useTimezone'; -import usePageQuery from 'hooks/usePageQuery'; +import { getDateArray } from 'lib/date'; +import { useApi, useLocale, useDateRange, useTimezone, usePageQuery } from 'hooks'; import { EVENT_COLORS } from 'lib/constants'; +import { renderDateLabels, renderStatusTooltip } from 'lib/charts'; export function EventsChart({ websiteId, className, token }) { const { get, useQuery } = useApi(); const [{ startDate, endDate, unit, modified }] = useDateRange(websiteId); + const { locale } = useLocale(); const [timezone] = useTimezone(); const { query: { url, eventName }, @@ -70,9 +69,10 @@ export function EventsChart({ websiteId, className, token }) { datasets={datasets} unit={unit} height={300} - records={getDateLength(startDate, endDate, unit)} loading={isLoading} stacked + renderXLabel={renderDateLabels(unit, locale)} + renderTooltip={renderStatusTooltip(unit, locale)} /> ); } diff --git a/components/metrics/PageviewsChart.js b/components/metrics/PageviewsChart.js index 0dcf0ac5..bf56a0bd 100644 --- a/components/metrics/PageviewsChart.js +++ b/components/metrics/PageviewsChart.js @@ -1,74 +1,13 @@ -import { useCallback, useMemo } from 'react'; -import { StatusLight } from 'react-basics'; +import { useMemo } from 'react'; import BarChart from './BarChart'; -import useTheme from 'hooks/useTheme'; -import useMessages from 'hooks/useMessages'; -import useLocale from 'hooks/useLocale'; -import { dateFormat } from 'lib/date'; -import { formatLongNumber } from 'lib/format'; +import { useLocale, useTheme, useMessages } from 'hooks'; +import { renderDateLabels, renderStatusTooltip } from 'lib/charts'; export function PageviewsChart({ websiteId, data, unit, className, loading, ...props }) { const { formatMessage, labels } = useMessages(); const { colors } = useTheme(); 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( - <> -
{dateFormat(new Date(dataPoints[0].raw.x), formats[unit], locale)}
-
- - {formatLongNumber(dataPoints[0].raw.y)} {dataPoints[0].dataset.label} - -
- , - ); - }, - [unit], - ); - const datasets = useMemo(() => { if (!data) return []; @@ -96,8 +35,8 @@ export function PageviewsChart({ websiteId, data, unit, className, loading, ...p datasets={datasets} unit={unit} loading={loading} - renderXLabel={renderXLabel} - renderTooltip={renderTooltip} + renderXLabel={renderDateLabels(unit, locale)} + renderTooltip={renderStatusTooltip(unit, locale)} /> ); } diff --git a/components/pages/reports/funnel/FunnelParameters.js b/components/pages/reports/funnel/FunnelParameters.js index bced9a1a..3caf6a8e 100644 --- a/components/pages/reports/funnel/FunnelParameters.js +++ b/components/pages/reports/funnel/FunnelParameters.js @@ -11,6 +11,7 @@ import { SubmitButton, Text, TextField, + Tooltip, } from 'react-basics'; import Icons from 'components/icons'; import { updateReport } from 'store/reports'; @@ -91,28 +92,30 @@ function AddURLButton({ onAdd }) { }; return ( - - - - - - {close => { - return ( -
- - - - - - - -
- ); - }} -
-
+ + + + + + + {close => { + return ( +
+ + + + + + + +
+ ); + }} +
+
+
); } diff --git a/lib/charts.js b/lib/charts.js new file mode 100644 index 00000000..c9d54218 --- /dev/null +++ b/lib/charts.js @@ -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( + <> +
{dateFormat(new Date(dataPoints[0].raw.x), formats[unit], locale)}
+
+ + {formatLongNumber(dataPoints[0].raw.y)} {dataPoints[0].dataset.label} + +
+ , + ); + }; +}