fix(api): filter empty values when using sum and average, added min and max

This commit is contained in:
Carl-Gerhard Lindesvärd
2025-06-04 12:45:26 +02:00
parent 5c5154ee86
commit 5b1e94e9ad
8 changed files with 142 additions and 135 deletions

View File

@@ -102,6 +102,18 @@ export const chartTypes = {
conversion: 'Conversion',
} as const;
export const chartSegments = {
event: 'All events',
user: 'Unique users',
session: 'Unique sessions',
user_average: 'Average users',
one_event_per_user: 'One event per user',
property_sum: 'Sum of property',
property_average: 'Average of property',
property_max: 'Max of property',
property_min: 'Min of property',
};
export const lineTypes = {
monotone: 'Monotone',
monotoneX: 'Monotone X',

View File

@@ -162,12 +162,22 @@ export function getChartSql({
if (event.segment === 'property_sum' && event.property) {
sb.select.count = `sum(toFloat64(${getSelectPropertyKey(event.property)})) as count`;
sb.where.property = `${getSelectPropertyKey(event.property)} IS NOT NULL`;
sb.where.property = `${getSelectPropertyKey(event.property)} IS NOT NULL AND notEmpty(${getSelectPropertyKey(event.property)})`;
}
if (event.segment === 'property_average' && event.property) {
sb.select.count = `avg(toFloat64(${getSelectPropertyKey(event.property)})) as count`;
sb.where.property = `${getSelectPropertyKey(event.property)} IS NOT NULL`;
sb.where.property = `${getSelectPropertyKey(event.property)} IS NOT NULL AND notEmpty(${getSelectPropertyKey(event.property)})`;
}
if (event.segment === 'property_max' && event.property) {
sb.select.count = `max(toFloat64(${getSelectPropertyKey(event.property)})) as count`;
sb.where.property = `${getSelectPropertyKey(event.property)} IS NOT NULL AND notEmpty(${getSelectPropertyKey(event.property)})`;
}
if (event.segment === 'property_min' && event.property) {
sb.select.count = `min(toFloat64(${getSelectPropertyKey(event.property)})) as count`;
sb.where.property = `${getSelectPropertyKey(event.property)} IS NOT NULL AND notEmpty(${getSelectPropertyKey(event.property)})`;
}
if (event.segment === 'one_event_per_user') {

View File

@@ -1,6 +1,7 @@
import { z } from 'zod';
import {
chartSegments,
chartTypes,
intervals,
lineTypes,
@@ -29,6 +30,11 @@ export const zChartEventFilter = z.object({
.describe('The values to filter on'),
});
export const zChartEventSegment = z
.enum(objectToZodEnums(chartSegments))
.default('event')
.describe('Defines how the event data should be segmented or aggregated');
export const zChartEvent = z.object({
id: z
.string()
@@ -45,18 +51,7 @@ export const zChartEvent = z.object({
.describe(
'Optional property of the event used for specific segment calculations (e.g., value for property_sum/average)',
),
segment: z
.enum([
'event',
'user',
'session',
'user_average',
'one_event_per_user',
'property_sum',
'property_average',
])
.default('event')
.describe('Defines how the event data should be segmented or aggregated'),
segment: zChartEventSegment,
filters: z
.array(zChartEventFilter)
.default([])

View File

@@ -3,6 +3,7 @@ import type { z } from 'zod';
import type {
zChartBreakdown,
zChartEvent,
zChartEventSegment,
zChartInput,
zChartInputAI,
zChartType,
@@ -23,6 +24,7 @@ export type IChartProps = z.infer<typeof zReportInput> & {
previousIndicatorInverted?: boolean;
};
export type IChartEvent = z.infer<typeof zChartEvent>;
export type IChartEventSegment = z.infer<typeof zChartEventSegment>;
export type IChartEventFilter = IChartEvent['filters'][number];
export type IChartEventFilterValue =
IChartEvent['filters'][number]['value'][number];