diff --git a/apps/start/src/components/report-chart/histogram/chart.tsx b/apps/start/src/components/report-chart/histogram/chart.tsx index 529ab1a2..ac63c2c4 100644 --- a/apps/start/src/components/report-chart/histogram/chart.tsx +++ b/apps/start/src/components/report-chart/histogram/chart.tsx @@ -61,9 +61,14 @@ export function Chart({ data }: Props) { range, series: reportSeries, breakdowns, + options: reportOptions, }, options: { hideXAxis, hideYAxis }, } = useReportChartContext(); + + const histogramOptions = + reportOptions?.type === 'histogram' ? reportOptions : undefined; + const isStacked = histogramOptions?.stacked ?? false; const trpc = useTRPC(); const references = useQuery( trpc.reference.getChartReferences.queryOptions( @@ -155,68 +160,70 @@ export function Chart({ data }: Props) {
- - } - cursor={} - /> - - - {previous - ? series.map((serie) => { - return ( - - ); - }) - : null} - {series.map((serie) => { - return ( - - ); - })} - {references.data?.map((ref) => ( - - ))} - - -
- {isEditMode && ( - - )} + } + cursor={} + /> + + + {previous + ? series.map((serie) => { + return ( + + ); + }) + : null} + {series.map((serie) => { + return ( + + ); + })} + {references.data?.map((ref) => ( + + ))} + + + + {isEditMode && ( + + )} ); diff --git a/apps/start/src/components/report/reportSlice.ts b/apps/start/src/components/report/reportSlice.ts index 24351176..8b4ebd99 100644 --- a/apps/start/src/components/report/reportSlice.ts +++ b/apps/start/src/components/report/reportSlice.ts @@ -361,6 +361,17 @@ export const reportSlice = createSlice({ state.options.include = action.payload; } }, + changeStacked(state, action: PayloadAction) { + state.dirty = true; + if (!state.options || state.options.type !== 'histogram') { + state.options = { + type: 'histogram', + stacked: action.payload, + }; + } else { + state.options.stacked = action.payload; + } + }, reorderEvents( state, action: PayloadAction<{ fromIndex: number; toIndex: number }>, @@ -406,6 +417,7 @@ export const { changeSankeySteps, changeSankeyExclude, changeSankeyInclude, + changeStacked, reorderEvents, } = reportSlice.actions; diff --git a/apps/start/src/components/report/sidebar/ReportSettings.tsx b/apps/start/src/components/report/sidebar/ReportSettings.tsx index 6c31095b..7f12ce34 100644 --- a/apps/start/src/components/report/sidebar/ReportSettings.tsx +++ b/apps/start/src/components/report/sidebar/ReportSettings.tsx @@ -17,6 +17,7 @@ import { changeSankeyInclude, changeSankeyMode, changeSankeySteps, + changeStacked, changeUnit, } from '../reportSlice'; @@ -25,14 +26,17 @@ export function ReportSettings() { const previous = useSelector((state) => state.report.previous); const unit = useSelector((state) => state.report.unit); const options = useSelector((state) => state.report.options); - + const retentionOptions = options?.type === 'retention' ? options : undefined; const criteria = retentionOptions?.criteria ?? 'on_or_after'; - + const funnelOptions = options?.type === 'funnel' ? options : undefined; const funnelGroup = funnelOptions?.funnelGroup; const funnelWindow = funnelOptions?.funnelWindow; + const histogramOptions = options?.type === 'histogram' ? options : undefined; + const stacked = histogramOptions?.stacked ?? false; + const dispatch = useDispatch(); const { projectId } = useAppParams(); const eventNames = useEventNames({ projectId }); @@ -61,6 +65,10 @@ export function ReportSettings() { fields.push('sankeyInclude'); } + if (chartType === 'histogram') { + fields.push('stacked'); + } + return fields; }, [chartType]); @@ -259,6 +267,15 @@ export function ReportSettings() { /> )} + {fields.includes('stacked') && ( + + )} ); diff --git a/packages/validation/src/index.ts b/packages/validation/src/index.ts index 0d7dc1c6..0b101226 100644 --- a/packages/validation/src/index.ts +++ b/packages/validation/src/index.ts @@ -126,14 +126,21 @@ export const zSankeyOptions = z.object({ include: z.array(z.string()).optional(), }); +export const zHistogramOptions = z.object({ + type: z.literal('histogram'), + stacked: z.boolean().default(false), +}); + export const zReportOptions = z.discriminatedUnion('type', [ zFunnelOptions, zRetentionOptions, zSankeyOptions, + zHistogramOptions, ]); export type IReportOptions = z.infer; export type ISankeyOptions = z.infer; +export type IHistogramOptions = z.infer; export const zWidgetType = z.enum(['realtime', 'counter']); export type IWidgetType = z.infer;