Skip to content

Commit a7ee284

Browse files
daharoniclaude
andcommitted
fix(cadecon): keep x-axis aligned at iteration 0, null out placeholder values
All charts now share the same x-axis starting at 0 for cursor sync. Per-cell trends (Alpha, Threshold, PVE, Event Rate) null out iteration 0 values so they aren't plotted but the axis aligns with the Kernel chart. Kernel chart nulls out the residual at iteration 0 (placeholder 0). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8c90e41 commit a7ee284

2 files changed

Lines changed: 18 additions & 8 deletions

File tree

apps/cadecon/src/components/charts/KernelConvergence.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export function KernelConvergence(): JSX.Element {
119119
h.map((s) => s.iteration),
120120
h.map((s) => s.tauRise * 1000),
121121
h.map((s) => s.tauDecay * 1000),
122-
h.map((s) => s.residual),
122+
h.map((s) => (s.iteration === 0 ? null : s.residual)),
123123
];
124124
});
125125

apps/cadecon/src/components/charts/PerCellTrendsChart.tsx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,13 @@ export interface TrendsData {
4141
yMax: number;
4242
}
4343

44-
/** Extract a numeric field from TraceResultEntry history into TrendsData. */
44+
/** Extract a numeric field from TraceResultEntry history into TrendsData.
45+
* When `skipZero` is true, iteration 0 is kept in the x-axis (so cursor
46+
* sync lines up across charts) but its values are null (not plotted). */
4547
export function deriveTrendsData(
4648
history: IterationHistoryEntry[],
4749
accessor: (entry: TraceResultEntry) => number,
50+
skipZero = false,
4851
): TrendsData {
4952
if (history.length === 0) {
5053
return {
@@ -80,10 +83,15 @@ export function deriveTrendsData(
8083
}
8184

8285
for (let i = 0; i < history.length; i++) {
86+
const isZero = skipZero && history[i].iteration === 0;
8387
const results = history[i].results;
8488
const values: number[] = [];
8589

8690
for (const key of keys) {
91+
if (isZero) {
92+
perKey.get(key)!.push(null);
93+
continue;
94+
}
8795
const entry = results[key];
8896
const val = entry != null ? accessor(entry) : null;
8997
perKey.get(key)!.push(val);
@@ -94,7 +102,11 @@ export function deriveTrendsData(
94102
}
95103
}
96104

97-
if (values.length > 0) {
105+
if (isZero) {
106+
median.push(null as unknown as number);
107+
q25.push(null as unknown as number);
108+
q75.push(null as unknown as number);
109+
} else if (values.length > 0) {
98110
const sorted = [...values].sort((a, b) => a - b);
99111
const mid = Math.floor(sorted.length / 2);
100112
median.push(sorted.length % 2 !== 0 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2);
@@ -265,11 +277,9 @@ export interface PerCellTrendsChartProps {
265277
export function PerCellTrendsChart(props: PerCellTrendsChartProps): JSX.Element {
266278
const [uplotRef, setUplotRef] = createSignal<uPlot | null>(null);
267279

268-
const trendsData = createMemo(() => {
269-
const skip = props.skipZero !== false; // default true
270-
const history = skip ? iterationHistory().filter((h) => h.iteration > 0) : iterationHistory();
271-
return deriveTrendsData(history, props.accessor);
272-
});
280+
const trendsData = createMemo(() =>
281+
deriveTrendsData(iterationHistory(), props.accessor, props.skipZero !== false),
282+
);
273283

274284
// Redraw when overlay state changes
275285
createEffect(() => {

0 commit comments

Comments
 (0)