feat: add stacked option for histogram
This commit is contained in:
@@ -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) {
|
||||
<div className={cn('h-full w-full', isEditMode && 'card p-4')}>
|
||||
<ResponsiveContainer>
|
||||
<BarChart data={rechartData}>
|
||||
<CartesianGrid
|
||||
strokeDasharray="3 3"
|
||||
vertical={false}
|
||||
className="stroke-def-200"
|
||||
/>
|
||||
<Tooltip
|
||||
content={<ReportChartTooltip.Tooltip />}
|
||||
cursor={<BarHover />}
|
||||
/>
|
||||
<YAxis {...yAxisProps} />
|
||||
<XAxis {...xAxisProps} scale={'auto'} type="category" />
|
||||
{previous
|
||||
? series.map((serie) => {
|
||||
return (
|
||||
<Bar
|
||||
key={`${serie.id}:prev`}
|
||||
name={`${serie.id}:prev`}
|
||||
dataKey={`${serie.id}:prev:count`}
|
||||
fill={getChartColor(serie.index)}
|
||||
fillOpacity={0.3}
|
||||
radius={5}
|
||||
/>
|
||||
);
|
||||
})
|
||||
: null}
|
||||
{series.map((serie) => {
|
||||
return (
|
||||
<Bar
|
||||
key={serie.id}
|
||||
name={serie.id}
|
||||
dataKey={`${serie.id}:count`}
|
||||
fill={getChartColor(serie.index)}
|
||||
radius={5}
|
||||
fillOpacity={1}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{references.data?.map((ref) => (
|
||||
<ReferenceLine
|
||||
key={ref.id}
|
||||
x={ref.date.getTime()}
|
||||
stroke={'oklch(from var(--foreground) l c h / 0.1)'}
|
||||
strokeDasharray={'3 3'}
|
||||
label={{
|
||||
value: ref.title,
|
||||
position: 'centerTop',
|
||||
fill: '#334155',
|
||||
fontSize: 12,
|
||||
}}
|
||||
fontSize={10}
|
||||
<CartesianGrid
|
||||
strokeDasharray="3 3"
|
||||
vertical={false}
|
||||
className="stroke-def-200"
|
||||
/>
|
||||
))}
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
{isEditMode && (
|
||||
<ReportTable
|
||||
data={data}
|
||||
visibleSeries={series}
|
||||
setVisibleSeries={setVisibleSeries}
|
||||
/>
|
||||
)}
|
||||
<Tooltip
|
||||
content={<ReportChartTooltip.Tooltip />}
|
||||
cursor={<BarHover />}
|
||||
/>
|
||||
<YAxis {...yAxisProps} />
|
||||
<XAxis {...xAxisProps} scale={'auto'} type="category" />
|
||||
{previous
|
||||
? series.map((serie) => {
|
||||
return (
|
||||
<Bar
|
||||
key={`${serie.id}:prev`}
|
||||
name={`${serie.id}:prev`}
|
||||
dataKey={`${serie.id}:prev:count`}
|
||||
fill={getChartColor(serie.index)}
|
||||
fillOpacity={0.3}
|
||||
radius={5}
|
||||
stackId={isStacked ? 'prev' : undefined}
|
||||
/>
|
||||
);
|
||||
})
|
||||
: null}
|
||||
{series.map((serie) => {
|
||||
return (
|
||||
<Bar
|
||||
key={serie.id}
|
||||
name={serie.id}
|
||||
dataKey={`${serie.id}:count`}
|
||||
fill={getChartColor(serie.index)}
|
||||
radius={isStacked ? 0 : 4}
|
||||
fillOpacity={1}
|
||||
stackId={isStacked ? 'current' : undefined}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{references.data?.map((ref) => (
|
||||
<ReferenceLine
|
||||
key={ref.id}
|
||||
x={ref.date.getTime()}
|
||||
stroke={'oklch(from var(--foreground) l c h / 0.1)'}
|
||||
strokeDasharray={'3 3'}
|
||||
label={{
|
||||
value: ref.title,
|
||||
position: 'centerTop',
|
||||
fill: '#334155',
|
||||
fontSize: 12,
|
||||
}}
|
||||
fontSize={10}
|
||||
/>
|
||||
))}
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
{isEditMode && (
|
||||
<ReportTable
|
||||
data={data}
|
||||
visibleSeries={series}
|
||||
setVisibleSeries={setVisibleSeries}
|
||||
/>
|
||||
)}
|
||||
</ChartClickMenu>
|
||||
</ReportChartTooltip.TooltipProvider>
|
||||
);
|
||||
|
||||
@@ -361,6 +361,17 @@ export const reportSlice = createSlice({
|
||||
state.options.include = action.payload;
|
||||
}
|
||||
},
|
||||
changeStacked(state, action: PayloadAction<boolean>) {
|
||||
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;
|
||||
|
||||
|
||||
@@ -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() {
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{fields.includes('stacked') && (
|
||||
<Label className="flex items-center justify-between mb-0">
|
||||
<span className="whitespace-nowrap">Stack series</span>
|
||||
<Switch
|
||||
checked={stacked}
|
||||
onCheckedChange={(val) => dispatch(changeStacked(!!val))}
|
||||
/>
|
||||
</Label>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user