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;