Add PNG export for charts

- Hover any chart to reveal download button
- Exports with white background and padding
- Works on Dashboard and Comparison pages
This commit is contained in:
fahed
2026-02-02 17:39:11 +03:00
parent a2e7aa16cd
commit 22878d5a16
4 changed files with 111 additions and 14 deletions

View File

@@ -2,6 +2,7 @@ import React, { useState, useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';
import { Line, Doughnut, Bar } from 'react-chartjs-2';
import { Carousel, EmptyState, FilterControls, StatCard } from './shared';
import { ExportableChart } from './ChartExport';
import { chartColors, createBaseOptions } from '../config/chartConfig';
import {
filterData,
@@ -435,41 +436,41 @@ function Dashboard({ data, showDataLabels }) {
<button className={trendGranularity === 'day' ? 'active' : ''} onClick={() => setTrendGranularity('day')}>Daily</button>
<button className={trendGranularity === 'week' ? 'active' : ''} onClick={() => setTrendGranularity('week')}>Weekly</button>
</div>
<div className="chart-container">
<ExportableChart filename="revenue-trend" className="chart-container">
<Line data={trendData} options={{...baseOptions, scales: {...baseOptions.scales, x: {...baseOptions.scales.x, ticks: {...baseOptions.scales.x.ticks, maxTicksLimit: trendGranularity === 'week' ? 15 : 20}}}}} />
</div>
</ExportableChart>
</div>
{filters.museum === 'all' && (
<div className="chart-card half-width">
<h2>Visitors by Museum</h2>
<div className="chart-container">
<ExportableChart filename="visitors-by-museum" className="chart-container">
<Doughnut data={museumData.visitors} options={{...baseOptions, plugins: {...baseOptions.plugins, legend: {display: true, position: 'bottom', labels: {boxWidth: 12, padding: 16, font: {size: 11}}}}}} />
</div>
</ExportableChart>
</div>
)}
{filters.museum === 'all' && (
<div className="chart-card half-width">
<h2>Revenue by Museum</h2>
<div className="chart-container">
<ExportableChart filename="revenue-by-museum" className="chart-container">
<Bar data={museumData.revenue} options={baseOptions} />
</div>
</ExportableChart>
</div>
)}
<div className="chart-card half-width">
<h2>Quarterly Revenue (YoY)</h2>
<div className="chart-container">
<ExportableChart filename="quarterly-yoy" className="chart-container">
<Bar data={quarterlyYoYData} options={{...baseOptions, plugins: {...baseOptions.plugins, legend: {display: true, position: 'top', align: 'end', labels: {boxWidth: 12, padding: 12, font: {size: 11}}}}}} />
</div>
</ExportableChart>
</div>
<div className="chart-card half-width">
<h2>District Performance</h2>
<div className="chart-container">
<ExportableChart filename="district-performance" className="chart-container">
<Bar data={districtData} options={{...baseOptions, indexAxis: 'y'}} />
</div>
</ExportableChart>
</div>
<div className="chart-card full-width">