import { ChartFrame, SvgA11y } from "./frame.tsx";
import { chartId, finiteDomain, formatValue, plotArea, truncateLabel } from "./format.ts";
import { linearScale, niceTicks } from "./scale.ts";
import type { ComparisonChartProps } from "./types.ts";
export function ComparisonChart({
meta,
data,
baselineLabel = "Baseline",
trainedLabel = "Trained",
domain,
format = "number",
digits = 2,
width = 720,
height = 340,
}: ComparisonChartProps) {
const valid = data.filter((datum) => Number.isFinite(datum.baseline) && Number.isFinite(datum.trained));
const invalid = data.length - valid.length;
if (valid.length === 0) {
return ;
}
const values = valid.flatMap((datum) => [datum.baseline, datum.trained]);
const dataMin = Math.min(0, ...values);
const dataMax = Math.max(0, ...values);
const [yMin, yMax] = finiteDomain(domain, [dataMin, dataMax]);
const area = plotArea(width, height, { marginLeft: 68, marginBottom: 68 });
const y = linearScale([yMin, yMax], [area.marginTop + area.innerHeight, area.marginTop]);
const zeroY = y(Math.min(yMax, Math.max(yMin, 0)));
const ticks = niceTicks(yMin, yMax, 5);
const step = area.innerWidth / valid.length;
const groupWidth = Math.min(68, step * 0.7);
const gap = Math.max(3, groupWidth * 0.08);
const barWidth = Math.max(2, (groupWidth - gap) / 2);
const titleId = chartId(meta, "title");
const descriptionId = chartId(meta, "description");
const graphic = (
);
const table = (
{meta.title}
| Measure | {baselineLabel} | {trainedLabel} | Change |
{valid.map((datum) => (
| {datum.label} |
{formatValue(datum.baseline, format, digits)} |
{formatValue(datum.trained, format, digits)} |
{formatValue(datum.trained - datum.baseline, format, digits)} |
))}
);
return (
0 ? `${invalid} row${invalid === 1 ? " was" : "s were"} omitted because it contained a non-finite value.` : undefined}
/>
);
}