feat: add % toggle to revenue/visitors by event chart
All checks were successful
Deploy HiHala Dashboard / deploy (push) Successful in 8s

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
fahed
2026-04-07 13:16:15 +03:00
parent 0a80103cfc
commit e373363e75

View File

@@ -83,6 +83,7 @@ function Dashboard({ data, seasons, userRole, showDataLabels, setShowDataLabels,
const [eventChartType, setEventChartType] = useState<'bar' | 'pie'>('pie');
const [channelChartType, setChannelChartType] = useState<'bar' | 'pie'>('pie');
const [channelDisplayMode, setChannelDisplayMode] = useState<'absolute' | 'percent'>('absolute');
const [eventDisplayMode, setEventDisplayMode] = useState<'absolute' | 'percent'>('absolute');
const filteredData = useMemo(() => filterData(data, filters), [data, filters]);
@@ -254,6 +255,17 @@ function Dashboard({ data, seasons, userRole, showDataLabels, setShowDataLabels,
};
}, [seasonFilteredData, includeVAT]);
const eventChartData = useMemo(() => {
const source = museumData[eventMetric];
if (eventDisplayMode === 'absolute') return source;
const total = source.datasets[0].data.reduce((s: number, v: number) => s + v, 0);
if (total === 0) return source;
return {
...source,
datasets: [{ ...source.datasets[0], data: source.datasets[0].data.map((v: number) => parseFloat(((v / total) * 100).toFixed(1))) }]
};
}, [museumData, eventMetric, eventDisplayMode]);
const channelChartData = useMemo(() => {
if (channelDisplayMode === 'absolute') return channelData;
const total = channelData.datasets[0].data.reduce((s: number, v: number) => s + v, 0);
@@ -639,12 +651,25 @@ function Dashboard({ data, seasons, userRole, showDataLabels, setShowDataLabels,
<button className={eventChartType === 'bar' ? 'active' : ''} onClick={() => setEventChartType('bar')}>{t('metrics.bar')}</button>
<button className={eventChartType === 'pie' ? 'active' : ''} onClick={() => setEventChartType('pie')}>{t('metrics.pie')}</button>
</div>
<div className="toggle-switch">
<button className={eventDisplayMode === 'absolute' ? 'active' : ''} onClick={() => setEventDisplayMode('absolute')}>#</button>
<button className={eventDisplayMode === 'percent' ? 'active' : ''} onClick={() => setEventDisplayMode('percent')}>%</button>
</div>
</div>
}
>
{eventChartType === 'bar'
? <Bar data={museumData[eventMetric]} options={{...baseOptions, indexAxis: 'y'}} />
: <Pie data={museumData[eventMetric]} options={pieOptions} />
? <Bar data={eventChartData} options={{...baseOptions, indexAxis: 'y'}} />
: <Pie data={eventChartData} options={{
...pieOptions,
plugins: {
...pieOptions.plugins,
datalabels: eventDisplayMode === 'percent'
? { display: true, color: '#fff', font: { size: 11, weight: 'bold' as const }, formatter: (v: number) => v > 3 ? v.toFixed(1) + '%' : '' }
: { display: false },
tooltip: { ...pieOptions.plugins.tooltip, callbacks: { label: (ctx: any) => eventDisplayMode === 'percent' ? ` ${ctx.parsed.toFixed(1)}%` : ` ${formatCurrency(ctx.parsed)}` } }
}
}} />
}
</ExportableChart>
</div>
@@ -776,11 +801,24 @@ function Dashboard({ data, seasons, userRole, showDataLabels, setShowDataLabels,
<button className={eventChartType === 'bar' ? 'active' : ''} onClick={() => setEventChartType('bar')}>{t('metrics.bar')}</button>
<button className={eventChartType === 'pie' ? 'active' : ''} onClick={() => setEventChartType('pie')}>{t('metrics.pie')}</button>
</div>
<div className="toggle-switch">
<button className={eventDisplayMode === 'absolute' ? 'active' : ''} onClick={() => setEventDisplayMode('absolute')}>#</button>
<button className={eventDisplayMode === 'percent' ? 'active' : ''} onClick={() => setEventDisplayMode('percent')}>%</button>
</div>
</div>
<div className="chart-container">
{eventChartType === 'bar'
? <Bar data={museumData[eventMetric]} options={{...baseOptions, indexAxis: 'y'}} />
: <Pie data={museumData[eventMetric]} options={pieOptions} />
? <Bar data={eventChartData} options={{...baseOptions, indexAxis: 'y'}} />
: <Pie data={eventChartData} options={{
...pieOptions,
plugins: {
...pieOptions.plugins,
datalabels: eventDisplayMode === 'percent'
? { display: true, color: '#fff', font: { size: 11, weight: 'bold' as const }, formatter: (v: number) => v > 3 ? v.toFixed(1) + '%' : '' }
: { display: false },
tooltip: { ...pieOptions.plugins.tooltip, callbacks: { label: (ctx: any) => eventDisplayMode === 'percent' ? ` ${ctx.parsed.toFixed(1)}%` : ` ${formatCurrency(ctx.parsed)}` } }
}
}} />
}
</div>
</div>