This commit is contained in:
Carl-Gerhard Lindesvärd
2025-11-25 10:18:20 +01:00
parent 3bbeb927cc
commit 958ba535d6
6 changed files with 34 additions and 17 deletions

View File

@@ -13,7 +13,7 @@ import { Summary } from './summary';
export function ReportConversionChart() {
const { isLazyLoading, report } = useReportChartContext();
const trpc = useTRPC();
console.log(report.limit);
const res = useQuery(
trpc.chart.conversion.queryOptions(report, {
placeholderData: keepPreviousData,

View File

@@ -40,6 +40,7 @@ export function ReportFunnelChart() {
metric: 'sum',
startDate,
endDate,
limit: 20,
};
const trpc = useTRPC();
const res = useQuery(

View File

@@ -26,6 +26,7 @@ export function format(
}>,
includeAlphaIds: boolean,
previousSeries: ConcreteSeries[] | null = null,
limit: number | undefined = undefined,
): FinalChart {
const series = concreteSeries.map((cs) => {
// Find definition for this series
@@ -124,6 +125,9 @@ export function format(
};
});
// Sort series by sum (biggest first)
series.sort((a, b) => b.metrics.sum - a.metrics.sum);
// Calculate global metrics
const allValues = concreteSeries.flatMap((cs) => cs.data.map((d) => d.count));
const globalMetrics = {
@@ -135,7 +139,7 @@ export function format(
};
return {
series,
series: limit ? series.slice(0, limit) : series,
metrics: globalMetrics,
};
}

View File

@@ -18,8 +18,6 @@ import type { ConcreteSeries } from './types';
* Executes the pipeline: normalize -> plan -> fetch -> compute -> format
*/
export async function executeChart(input: IChartInput): Promise<FinalChart> {
const { timezone } = await getSettingsForProject(input.projectId);
// Stage 1: Normalize input
const normalized = await normalize(input);

View File

@@ -20,6 +20,7 @@ export class ConversionService {
funnelWindow = 24,
series,
breakdowns = [],
limit,
interval,
timezone,
}: Omit<IChartInput, 'range' | 'previous' | 'metric' | 'chartType'> & {
@@ -114,7 +115,8 @@ export class ConversionService {
}
const results = await query.execute();
return this.toSeries(results, breakdowns).map((serie, serieIndex) => {
return this.toSeries(results, breakdowns, limit).map(
(serie, serieIndex) => {
return {
...serie,
data: serie.data.map((d, index) => ({
@@ -125,7 +127,8 @@ export class ConversionService {
serie: omit(['data'], serie),
})),
};
});
},
);
}
private toSeries(
@@ -137,6 +140,7 @@ export class ConversionService {
[key: string]: string | number;
}[],
breakdowns: { name: string }[] = [],
limit: number | undefined = undefined,
) {
if (!breakdowns.length) {
return [
@@ -156,6 +160,10 @@ export class ConversionService {
// Group by breakdown values
const series = data.reduce(
(acc, d) => {
if (limit && Object.keys(acc).length >= limit) {
return acc;
}
const key =
breakdowns.map((b, index) => d[`b_${index}`]).join('|') ||
NOT_SET_VALUE;

View File

@@ -126,6 +126,7 @@ export class FunnelService {
toSeries(
funnel: { level: number; count: number; [key: string]: any }[],
breakdowns: { name: string }[] = [],
limit: number | undefined = undefined,
) {
if (!breakdowns.length) {
return [
@@ -141,6 +142,10 @@ export class FunnelService {
// Group by breakdown values
const series = funnel.reduce(
(acc, f) => {
if (limit && Object.keys(acc).length >= limit) {
return acc;
}
const key = breakdowns.map((b, index) => f[`b_${index}`]).join('|');
if (!acc[key]) {
acc[key] = [];
@@ -183,6 +188,7 @@ export class FunnelService {
funnelWindow = 24,
funnelGroup,
breakdowns = [],
limit,
timezone = 'UTC',
}: IChartInput & { timezone: string; events?: IChartEvent[] }) {
if (!startDate || !endDate) {
@@ -267,7 +273,7 @@ export class FunnelService {
.orderBy('level', 'DESC');
const funnelData = await funnelQuery.execute();
const funnelSeries = this.toSeries(funnelData, breakdowns);
const funnelSeries = this.toSeries(funnelData, breakdowns, limit);
return funnelSeries
.map((data) => {