mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 13:45:23 +02:00
feat: Add YTD (Year-To-Date) cumulative lines to chart
- Calculate accumulated Sell Out and Units per week for each year - Add toggle button to show/hide YTD lines (cyan color) - YTD lines use thicker stroke with lower opacity for distinction
This commit is contained in:
@@ -249,6 +249,7 @@ const DataGrid: React.FC<DataGridProps> = ({ data, hasCustomerFilter, adsData, s
|
|||||||
const [visibleMetrics, setVisibleMetrics] = useState<('sellOut' | 'units')[]>(['sellOut', 'units']);
|
const [visibleMetrics, setVisibleMetrics] = useState<('sellOut' | 'units')[]>(['sellOut', 'units']);
|
||||||
const [showAdsMetrics, setShowAdsMetrics] = useState(true);
|
const [showAdsMetrics, setShowAdsMetrics] = useState(true);
|
||||||
const [showAttributedSales, setShowAttributedSales] = useState(false);
|
const [showAttributedSales, setShowAttributedSales] = useState(false);
|
||||||
|
const [showYTD, setShowYTD] = useState(false);
|
||||||
const [showOnlyTop50, setShowOnlyTop50] = useState(false);
|
const [showOnlyTop50, setShowOnlyTop50] = useState(false);
|
||||||
const [showDimensionMenu, setShowDimensionMenu] = useState(false);
|
const [showDimensionMenu, setShowDimensionMenu] = useState(false);
|
||||||
const dimensionRef = useRef<HTMLDivElement>(null);
|
const dimensionRef = useRef<HTMLDivElement>(null);
|
||||||
@@ -350,6 +351,27 @@ const DataGrid: React.FC<DataGridProps> = ({ data, hasCustomerFilter, adsData, s
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate YTD (Year-To-Date) cumulative values for each year
|
||||||
|
const ytdAccumulators: { [year: string]: { sellOut: number; units: number } } = {};
|
||||||
|
yearsInView.forEach((year: string) => {
|
||||||
|
ytdAccumulators[year] = { sellOut: 0, units: 0 };
|
||||||
|
});
|
||||||
|
|
||||||
|
salesChartData.forEach((point: any) => {
|
||||||
|
yearsInView.forEach((year: string) => {
|
||||||
|
const sellOutKey = isMultiYear ? `${year}_sellOut` : 'sellOut';
|
||||||
|
const unitsKey = isMultiYear ? `${year}_units` : 'units';
|
||||||
|
|
||||||
|
// Accumulate values
|
||||||
|
ytdAccumulators[year].sellOut += (point[sellOutKey] as number) || 0;
|
||||||
|
ytdAccumulators[year].units += (point[unitsKey] as number) || 0;
|
||||||
|
|
||||||
|
// Add YTD values directly to point
|
||||||
|
point[`${year}_ytdSellOut`] = ytdAccumulators[year].sellOut;
|
||||||
|
point[`${year}_ytdUnits`] = ytdAccumulators[year].units;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
chartData: salesChartData,
|
chartData: salesChartData,
|
||||||
uniqueYears: yearsInView,
|
uniqueYears: yearsInView,
|
||||||
@@ -700,6 +722,33 @@ const DataGrid: React.FC<DataGridProps> = ({ data, hasCustomerFilter, adsData, s
|
|||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
dot={false}
|
dot={false}
|
||||||
/>
|
/>
|
||||||
|
),
|
||||||
|
// YTD Sell Out line (cumulative)
|
||||||
|
showYTD && visibleMetrics.includes('sellOut') && (
|
||||||
|
<Line
|
||||||
|
key={`${year}_ytdSellOut`}
|
||||||
|
type="monotone"
|
||||||
|
dataKey={`${year}_ytdSellOut`}
|
||||||
|
name={`YTD Sell Out ${year}`}
|
||||||
|
stroke={CHART_COLORS[idx % CHART_COLORS.length]}
|
||||||
|
strokeWidth={3}
|
||||||
|
strokeOpacity={0.6}
|
||||||
|
dot={false}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
// YTD Units line (cumulative)
|
||||||
|
showYTD && visibleMetrics.includes('units') && (
|
||||||
|
<Line
|
||||||
|
key={`${year}_ytdUnits`}
|
||||||
|
type="monotone"
|
||||||
|
dataKey={`${year}_ytdUnits`}
|
||||||
|
name={`YTD Units ${year}`}
|
||||||
|
stroke={CHART_COLORS[idx % CHART_COLORS.length]}
|
||||||
|
strokeWidth={3}
|
||||||
|
strokeDasharray="10 5"
|
||||||
|
strokeOpacity={0.6}
|
||||||
|
dot={false}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
])
|
])
|
||||||
) : (
|
) : (
|
||||||
@@ -856,6 +905,17 @@ const DataGrid: React.FC<DataGridProps> = ({ data, hasCustomerFilter, adsData, s
|
|||||||
<span className="hidden sm:inline">{showAttributedSales ? 'Hide Attr. Sales' : 'Show Attr. Sales'}</span>
|
<span className="hidden sm:inline">{showAttributedSales ? 'Hide Attr. Sales' : 'Show Attr. Sales'}</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* YTD (Year-To-Date) Toggle */}
|
||||||
|
<button
|
||||||
|
onClick={() => setShowYTD(!showYTD)}
|
||||||
|
className={`flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium border transition-colors ${showYTD ? 'bg-cyan-600/20 text-cyan-400 border-cyan-500/50' : 'bg-slate-800 text-slate-300 border-slate-700 hover:bg-slate-700'}`}
|
||||||
|
>
|
||||||
|
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" strokeWidth={2} stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z" />
|
||||||
|
</svg>
|
||||||
|
<span className="hidden sm:inline">{showYTD ? 'Hide YTD' : 'Show YTD'}</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-3 w-full lg:w-auto justify-between lg:justify-end">
|
<div className="flex items-center gap-3 w-full lg:w-auto justify-between lg:justify-end">
|
||||||
|
|||||||
Reference in New Issue
Block a user