diff --git a/apps/web/src/components/report/chart/ReportBarChart.tsx b/apps/web/src/components/report/chart/ReportBarChart.tsx index 61d3d22f..5581ea26 100644 --- a/apps/web/src/components/report/chart/ReportBarChart.tsx +++ b/apps/web/src/components/report/chart/ReportBarChart.tsx @@ -57,7 +57,7 @@ export function ReportBarChart({ data }: ReportBarChartProps) { footer: (info) => info.column.id, size: width ? width * 0.3 : undefined, }), - columnHelper.accessor((row) => row.totalCount, { + columnHelper.accessor((row) => row.metrics.total, { id: 'totalCount', cell: (info) => (
{info.getValue()}
@@ -67,7 +67,7 @@ export function ReportBarChart({ data }: ReportBarChartProps) { size: width ? width * 0.1 : undefined, enableSorting: true, }), - columnHelper.accessor((row) => row.totalCount, { + columnHelper.accessor((row) => row.metrics.total, { id: 'graph', cell: (info) => (
Total
+
Average
{data.series[0]?.data.map((serie) => (
- {serie.totalCount} + {serie.metrics.total} +
+
+ {serie.metrics.average}
{serie.data.map((item) => { return ( @@ -127,9 +131,13 @@ export function ReportTable({
-
Summary
+
Total
- {data.series.reduce((acc, serie) => serie.totalCount + acc, 0)} + {data.series.reduce((acc, serie) => serie.metrics.total + acc, 0)} +
+
Average
+
+ {data.series.reduce((acc, serie) => serie.metrics.average + acc, 0)}
diff --git a/apps/web/src/server/api/routers/chart.ts b/apps/web/src/server/api/routers/chart.ts index c1265691..d4c87c70 100644 --- a/apps/web/src/server/api/routers/chart.ts +++ b/apps/web/src/server/api/routers/chart.ts @@ -10,6 +10,7 @@ import type { IInterval, } from '@/types'; import { getDaysOldDate } from '@/utils/date'; +import { average, isFloat, round, sum } from '@/utils/math'; import { toDots } from '@/utils/object'; import { zChartInputWithDates } from '@/utils/validation'; import { last, pipe, sort, uniq } from 'ramda'; @@ -141,13 +142,13 @@ export const chartRouter = createTRPCRouter({ const sumB = b.data.reduce((acc, item) => acc + item.count, 0); return sumB - sumA; } else { - return b.totalCount - a.totalCount; + return b.metrics.total - a.metrics.total; } }); const meta = { - highest: sorted[0]?.totalCount ?? 0, - lowest: last(sorted)?.totalCount ?? 0, + highest: sorted[0]?.metrics.total ?? 0, + lowest: last(sorted)?.metrics.total ?? 0, }; return { @@ -155,9 +156,9 @@ export const chartRouter = createTRPCRouter({ series.reduce( (acc, item) => { if (acc[item.event.id]) { - acc[item.event.id] += item.totalCount; + acc[item.event.id] += item.metrics.total; } else { - acc[item.event.id] = item.totalCount; + acc[item.event.id] = item.metrics.total; } return acc; }, @@ -215,14 +216,6 @@ function getEventLegend(event: IChartEvent) { return `${event.name} (${event.id})`; } -function getTotalCount(arr: ResultItem[]) { - return arr.reduce((acc, item) => acc + item.count, 0); -} - -function isFloat(n: number) { - return n % 1 !== 0; -} - function getDatesFromRange(range: IChartRange) { if (range === 0) { const startDate = new Date(); @@ -488,14 +481,17 @@ async function getChartData({ id: event.id, name: event.name, }, - totalCount: getTotalCount(data), + metrics: { + total: sum(data.map((item) => item.count)), + average: round(average(data.map((item) => item.count))), + }, data: chartType === 'linear' ? fillEmptySpotsInTimeline(data, interval, startDate, endDate).map( (item) => { return { label: legend, - count: item.count, + count: round(item.count), date: new Date(item.date).toISOString(), }; } diff --git a/apps/web/src/utils/math.ts b/apps/web/src/utils/math.ts new file mode 100644 index 00000000..8c55e8f8 --- /dev/null +++ b/apps/web/src/utils/math.ts @@ -0,0 +1,12 @@ +export const round = (num: number, decimals = 2) => { + const factor = Math.pow(10, decimals); + return Math.round((num + Number.EPSILON) * factor) / factor; +}; + +export const average = (arr: number[]) => + arr.reduce((p, c) => p + c, 0) / arr.length; + +export const sum = (arr: number[]) => + round(arr.reduce((acc, item) => acc + item, 0)); + +export const isFloat = (n: number) => n % 1 !== 0;