From 8a33e494b2d2a383e3063eec8f6da801723e0211 Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 22 Dec 2024 15:11:59 -0500 Subject: [PATCH] Improve shipping pie chart --- .../src/components/dashboard/StatCards.jsx | 81 +++++++++++++++++-- 1 file changed, 76 insertions(+), 5 deletions(-) diff --git a/dashboard/src/components/dashboard/StatCards.jsx b/dashboard/src/components/dashboard/StatCards.jsx index fbb6345..5514af1 100644 --- a/dashboard/src/components/dashboard/StatCards.jsx +++ b/dashboard/src/components/dashboard/StatCards.jsx @@ -504,6 +504,66 @@ const ShippingDetails = ({ data }) => { const locations = data[0]?.shipping?.locations || {}; const methodStats = data[0]?.shipping?.methodStats || []; + // Custom colors for the pie chart + const COLORS = [ + 'hsl(171.2 77.2% 53.3%)', + 'hsl(200 95% 50%)', + 'hsl(280 95% 60%)', + 'hsl(340 95% 60%)', + 'hsl(40 95% 50%)', + 'hsl(120 95% 45%)', + 'hsl(240 95% 60%)', + 'hsl(30 95% 50%)', + ]; + + // Custom label renderer for pie chart + const renderCustomizedLabel = ({ cx, cy, midAngle, innerRadius, outerRadius, percent, index, name }) => { + const RADIAN = Math.PI / 180; + // Extend the radius for label placement + const radius = outerRadius * 1.2; + + // Calculate position + const x = cx + radius * Math.cos(-midAngle * RADIAN); + const y = cy + radius * Math.sin(-midAngle * RADIAN); + + // Only show label if percentage is greater than 3% + if (percent < 0.03) return null; + + return ( + cx ? 'start' : 'end'} + dominantBaseline="central" + className="text-xs font-medium" + > + {name} ({(percent * 100).toFixed(1)}%) + + ); + }; + + // Custom legend renderer + const renderLegend = (props) => { + const { payload } = props; + + return ( +
+ {payload.map((entry, index) => ( +
+
+ + {entry.value}: {((entry.payload.value / shippedCount) * 100).toFixed(1)}% + +
+ ))} +
+ ); + }; + return (
@@ -533,15 +593,15 @@ const ShippingDetails = ({ data }) => { dataKey="value" nameKey="name" cx="50%" - cy="50%" - outerRadius={150} - fill="hsl(171.2 77.2% 53.3%)" - label={({ name, percent }) => `${name} (${(percent * 100).toFixed(1)}%)`} + cy="45%" + outerRadius={120} + labelLine={false} + label={renderCustomizedLabel} > {methodStats.map((entry, index) => ( ))} @@ -550,6 +610,17 @@ const ShippingDetails = ({ data }) => { `${value.toLocaleString()} orders (${((value / shippedCount) * 100).toFixed(1)}%)`, name ]} + contentStyle={{ + backgroundColor: 'hsl(var(--background))', + border: '1px solid hsl(var(--border))', + borderRadius: '0.5rem', + padding: '0.5rem' + }} + /> +