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;