From 4fe61a6d7c11c99ce3fd4b8ec0cfa2c78cb5c077 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Fri, 23 Feb 2024 00:38:18 +0800 Subject: [PATCH] refactor: refactor chart render and perf pageview data handle logic --- src/client/components/TimeEventChart.tsx | 46 +++++++++ .../components/website/WebsiteOverview.tsx | 98 ++++++------------- 2 files changed, 74 insertions(+), 70 deletions(-) create mode 100644 src/client/components/TimeEventChart.tsx diff --git a/src/client/components/TimeEventChart.tsx b/src/client/components/TimeEventChart.tsx new file mode 100644 index 0000000..4f41b66 --- /dev/null +++ b/src/client/components/TimeEventChart.tsx @@ -0,0 +1,46 @@ +import { useMemo } from 'react'; +import { useTheme } from '../hooks/useTheme'; +import { DateUnit } from '@tianji/shared'; +import React from 'react'; +import { formatDate, formatDateWithUnit } from '../utils/date'; +import { Column, ColumnConfig } from '@ant-design/charts'; + +export const TimeEventChart: React.FC<{ + data: { x: string; y: number; type: string }[]; + unit: DateUnit; +}> = React.memo((props) => { + const { colors } = useTheme(); + + const config = useMemo( + () => + ({ + data: props.data, + isStack: true, + xField: 'x', + yField: 'y', + seriesField: 'type', + label: { + position: 'middle' as const, + style: { + fill: '#FFFFFF', + opacity: 0.6, + }, + }, + tooltip: { + title: (t) => formatDate(t), + }, + color: [colors.chart.pv, colors.chart.uv], + xAxis: { + label: { + autoHide: true, + autoRotate: false, + formatter: (text) => formatDateWithUnit(text, props.unit), + }, + }, + } satisfies ColumnConfig), + [props.data, props.unit] + ); + + return ; +}); +TimeEventChart.displayName = 'TimeEventChart'; diff --git a/src/client/components/website/WebsiteOverview.tsx b/src/client/components/website/WebsiteOverview.tsx index 8010d8b..84e4847 100644 --- a/src/client/components/website/WebsiteOverview.tsx +++ b/src/client/components/website/WebsiteOverview.tsx @@ -1,19 +1,12 @@ import { Button, message, Spin, Switch } from 'antd'; -import React, { useMemo } from 'react'; -import { Column, ColumnConfig } from '@ant-design/charts'; +import React from 'react'; import { SyncOutlined } from '@ant-design/icons'; import { DateFilter } from '../DateFilter'; import { WebsiteInfo } from '../../api/model/website'; -import { - DateUnit, - formatDate, - formatDateWithUnit, - getDateArray, -} from '../../utils/date'; +import { getDateArray } from '../../utils/date'; import { useEvent } from '../../hooks/useEvent'; import { MetricCard } from './MetricCard'; import { formatNumber, formatShortTime } from '../../utils/common'; -import { useTheme } from '../../hooks/useTheme'; import { WebsiteOnlineCount } from './WebsiteOnlineCount'; import { useGlobalRangeDate } from '../../hooks/useGlobalRangeDate'; import { MonitorHealthBar } from '../monitor/MonitorHealthBar'; @@ -22,6 +15,7 @@ import { AppRouterOutput, trpc } from '../../api/trpc'; import { getUserTimezone } from '../../api/model/user'; import { useGlobalStateStore } from '../../store/global'; import { useTranslation } from '@i18next-toolkit/react'; +import { TimeEventChart } from '../TimeEventChart'; export const WebsiteOverview: React.FC<{ website: WebsiteInfo; @@ -37,18 +31,32 @@ export const WebsiteOverview: React.FC<{ ); const { - data, + data: chartData = [], isLoading: isLoadingPageview, refetch: refetchPageview, - } = trpc.website.pageviews.useQuery({ - workspaceId: website.workspaceId, - websiteId: website.id, - startAt: startDate.valueOf(), - endAt: endDate.valueOf(), - unit, - }); - const pageviews = data?.pageviews ?? []; - const sessions = data?.sessions ?? []; + } = trpc.website.pageviews.useQuery( + { + workspaceId: website.workspaceId, + websiteId: website.id, + startAt: startDate.valueOf(), + endAt: endDate.valueOf(), + unit, + }, + { + select(data) { + const pageviews = data.pageviews ?? []; + const sessions = data.sessions ?? []; + + const pageviewsArr = getDateArray(pageviews, startDate, endDate, unit); + const sessionsArr = getDateArray(sessions, startDate, endDate, unit); + + return [ + ...pageviewsArr.map((item) => ({ ...item, type: 'pageview' })), + ...sessionsArr.map((item) => ({ ...item, type: 'session' })), + ]; + }, + } + ); const { data: stats, @@ -71,16 +79,6 @@ export const WebsiteOverview: React.FC<{ message.success(t('Refreshed')); }); - const chartData = useMemo(() => { - const pageviewsArr = getDateArray(pageviews, startDate, endDate, unit); - const sessionsArr = getDateArray(sessions, startDate, endDate, unit); - - return [ - ...pageviewsArr.map((item) => ({ ...item, type: 'pageview' })), - ...sessionsArr.map((item) => ({ ...item, type: 'session' })), - ]; - }, [pageviews, sessions, unit]); - const loading = isLoadingPageview || isLoadingStats; return ( @@ -145,7 +143,7 @@ export const WebsiteOverview: React.FC<{
- +
); @@ -216,43 +214,3 @@ export const MetricsBar: React.FC<{ ); }); MetricsBar.displayName = 'MetricsBar'; - -export const StatsChart: React.FC<{ - data: { x: string; y: number; type: string }[]; - unit: DateUnit; -}> = React.memo((props) => { - const { colors } = useTheme(); - - const config = useMemo( - () => - ({ - data: props.data, - isStack: true, - xField: 'x', - yField: 'y', - seriesField: 'type', - label: { - position: 'middle' as const, - style: { - fill: '#FFFFFF', - opacity: 0.6, - }, - }, - tooltip: { - title: (t) => formatDate(t), - }, - color: [colors.chart.pv, colors.chart.uv], - xAxis: { - label: { - autoHide: true, - autoRotate: false, - formatter: (text) => formatDateWithUnit(text, props.unit), - }, - }, - } satisfies ColumnConfig), - [props.data, props.unit] - ); - - return ; -}); -StatsChart.displayName = 'StatsChart';