feat: always-visible visitors bar chart, replace doughnut
All checks were successful
Deploy HiHala Dashboard / deploy (push) Successful in 7s
All checks were successful
Deploy HiHala Dashboard / deploy (push) Successful in 7s
- Visitors by Event and Revenue by Event are now horizontal bar charts - Both always visible (no longer hidden when events are filtered) - Free attractions (Trail To Hira Cave, Makkah Greets Us) now visible - Removed Doughnut chart and unused import Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import React, { useState, useMemo, useEffect } from 'react';
|
import React, { useState, useMemo, useEffect } from 'react';
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { Line, Doughnut, Bar } from 'react-chartjs-2';
|
import { Line, Bar } from 'react-chartjs-2';
|
||||||
import { Carousel, EmptyState, FilterControls, MultiSelect, StatCard } from './shared';
|
import { Carousel, EmptyState, FilterControls, MultiSelect, StatCard } from './shared';
|
||||||
import { ExportableChart } from './ChartExport';
|
import { ExportableChart } from './ChartExport';
|
||||||
import { chartColors, createBaseOptions } from '../config/chartConfig';
|
import { chartColors, createBaseOptions } from '../config/chartConfig';
|
||||||
@@ -95,9 +95,8 @@ function Dashboard({ data, showDataLabels, setShowDataLabels, includeVAT, setInc
|
|||||||
|
|
||||||
// Chart carousel labels
|
// Chart carousel labels
|
||||||
const chartLabels = useMemo(() => {
|
const chartLabels = useMemo(() => {
|
||||||
const labels = [t('charts.revenueTrend'), t('charts.visitors'), t('charts.revenue'), t('charts.quarterly'), t('charts.channel'), t('charts.district'), t('charts.captureRate')];
|
return [t('charts.revenueTrend'), t('charts.visitors'), t('charts.revenue'), t('charts.quarterly'), t('charts.channel'), t('charts.district'), t('charts.captureRate')];
|
||||||
return filters.museum.length === 0 ? labels : labels.filter((_, i) => i !== 1 && i !== 2);
|
}, [t]);
|
||||||
}, [filters.museum, t]);
|
|
||||||
|
|
||||||
// Dynamic lists from data
|
// Dynamic lists from data
|
||||||
const years = useMemo(() => getUniqueYears(data), [data]);
|
const years = useMemo(() => getUniqueYears(data), [data]);
|
||||||
@@ -547,21 +546,17 @@ function Dashboard({ data, showDataLabels, setShowDataLabels, includeVAT, setInc
|
|||||||
</ExportableChart>
|
</ExportableChart>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{filters.museum.length === 0 && (
|
<div className="chart-card half-width">
|
||||||
<div className="chart-card half-width">
|
<ExportableChart filename="visitors-by-event" title={t('dashboard.visitorsByMuseum')} className="chart-container">
|
||||||
<ExportableChart filename="visitors-by-museum" title={t('dashboard.visitorsByMuseum')} className="chart-container">
|
<Bar data={museumData.visitors} options={{...baseOptions, indexAxis: 'y'}} />
|
||||||
<Doughnut data={museumData.visitors} options={{...baseOptions, plugins: {...baseOptions.plugins, legend: {display: true, position: 'bottom', labels: {boxWidth: 12, padding: 16, font: {size: 13}}}}}} />
|
</ExportableChart>
|
||||||
</ExportableChart>
|
</div>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{filters.museum.length === 0 && (
|
<div className="chart-card half-width">
|
||||||
<div className="chart-card half-width">
|
<ExportableChart filename="revenue-by-event" title={t('dashboard.revenueByMuseum')} className="chart-container">
|
||||||
<ExportableChart filename="revenue-by-museum" title={t('dashboard.revenueByMuseum')} className="chart-container">
|
<Bar data={museumData.revenue} options={{...baseOptions, indexAxis: 'y'}} />
|
||||||
<Bar data={museumData.revenue} options={baseOptions} />
|
</ExportableChart>
|
||||||
</ExportableChart>
|
</div>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="chart-card half-width">
|
<div className="chart-card half-width">
|
||||||
<ExportableChart filename="quarterly-yoy" title={t('dashboard.quarterlyRevenue')} className="chart-container">
|
<ExportableChart filename="quarterly-yoy" title={t('dashboard.quarterlyRevenue')} className="chart-container">
|
||||||
@@ -645,27 +640,23 @@ function Dashboard({ data, showDataLabels, setShowDataLabels, includeVAT, setInc
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{filters.museum.length === 0 && (
|
<div className="carousel-slide">
|
||||||
<div className="carousel-slide">
|
<div className="chart-card">
|
||||||
<div className="chart-card">
|
<h2>{t('dashboard.visitorsByMuseum')}</h2>
|
||||||
<h2>{t('dashboard.visitorsByMuseum')}</h2>
|
<div className="chart-container">
|
||||||
<div className="chart-container">
|
<Bar data={museumData.visitors} options={{...baseOptions, indexAxis: 'y'}} />
|
||||||
<Doughnut data={museumData.visitors} options={{...baseOptions, plugins: {...baseOptions.plugins, legend: {display: true, position: 'bottom', labels: {boxWidth: 12, padding: 12, font: {size: 12}}}}}} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
</div>
|
||||||
|
|
||||||
{filters.museum.length === 0 && (
|
<div className="carousel-slide">
|
||||||
<div className="carousel-slide">
|
<div className="chart-card">
|
||||||
<div className="chart-card">
|
<h2>{t('dashboard.revenueByMuseum')}</h2>
|
||||||
<h2>{t('dashboard.revenueByMuseum')}</h2>
|
<div className="chart-container">
|
||||||
<div className="chart-container">
|
<Bar data={museumData.revenue} options={{...baseOptions, indexAxis: 'y'}} />
|
||||||
<Bar data={museumData.revenue} options={baseOptions} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
</div>
|
||||||
|
|
||||||
<div className="carousel-slide">
|
<div className="carousel-slide">
|
||||||
<div className="chart-card">
|
<div className="chart-card">
|
||||||
|
|||||||
Reference in New Issue
Block a user