Fix forecast burndown chart data issues

- Fix Date object handling for resolution_date from PostgreSQL
- Fix totalAssets using per-metric summary (vcl_multi_vertical_summary)
  instead of vertical-level compliance_snapshots total_devices
- Fix duplicate current month in chart (forecast starts from next month)
- Fix multi-vertical metrics summing across all relevant verticals
- Fix bar stacking: orange (non-compliant) on bottom, blue (compliant)
  on top, both sharing same baseline (stacked to total)
- Add fill props to Bar components for correct legend colors
- Backfill historical snapshots with per-metric totalAssets
This commit is contained in:
Jordan Ramos
2026-05-20 17:28:20 -06:00
parent f9770872ba
commit e45deccdb7
3 changed files with 79 additions and 41 deletions

View File

@@ -1367,8 +1367,8 @@ function ForecastBurndownChart({ metricId }) {
// Combine historical and forecast into a single array with isForecast flag
const combinedData = [
...historical.map(d => ({ ...d, isForecast: false })),
...forecast.map(d => ({ ...d, isForecast: true })),
...historical.map(d => ({ ...d, compliant: (d.total_assets || 0) - (d.non_compliant || 0), isForecast: false })),
...forecast.map(d => ({ ...d, compliant: (d.total_assets || 0) - (d.non_compliant || 0), isForecast: true })),
];
// Determine the divider position (between last historical and first forecast)
@@ -1399,11 +1399,12 @@ function ForecastBurndownChart({ metricId }) {
// Custom label for bars (device counts inside bars)
const renderTotalLabel = (props) => {
const { x, y, width, height, value } = props;
if (!value || height < 14) return null;
const { x, y, width, height, payload } = props;
const total = payload ? payload.total_assets : null;
if (!total || height < 14) return null;
return (
<text x={x + width / 2} y={y + height / 2} textAnchor="middle" dominantBaseline="middle" fill="#FFF" fontSize={9} fontWeight="600">
{value}
{total}
</text>
);
};
@@ -1487,19 +1488,23 @@ function ForecastBurndownChart({ metricId }) {
)}
<Bar
yAxisId="left"
dataKey="total_assets"
name="Total Assets"
shape={renderTotalAssetsBar}
label={renderTotalLabel}
barSize={28}
dataKey="non_compliant"
name="Non-Compliant"
stackId="devices"
fill="#F97316"
shape={renderNonCompliantBar}
label={renderNonCompliantLabel}
barSize={36}
/>
<Bar
yAxisId="left"
dataKey="non_compliant"
name="Non-Compliant"
shape={renderNonCompliantBar}
label={renderNonCompliantLabel}
barSize={28}
dataKey="compliant"
name="Compliant"
stackId="devices"
fill="#3B82F6"
shape={renderTotalAssetsBar}
label={renderTotalLabel}
barSize={36}
/>
<Line
yAxisId="right"