Skip to content

Commit 714fad6

Browse files
committed
fix(ChartState): Don't create spurious implicit series when mark accessor matches chart's own axis accessor, fixing domain corruption for heatmap/Cell charts
1 parent dd4932a commit 714fad6

File tree

4 files changed

+30
-3
lines changed

4 files changed

+30
-3
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'layerchart': patch
3+
---
4+
5+
fix(ChartState): Don't create spurious implicit series when mark accessor matches chart's own axis accessor, fixing domain corruption for heatmap/Cell charts

packages/layerchart/src/lib/states/__fixtures__/ComponentNodeLifecycleChild.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
ctx.registerComponent({
77
name: 'ComponentNodeLifecycleChild',
88
kind: 'mark',
9-
markInfo: () => ({ y: 'value' }),
9+
markInfo: () => ({ y: 'other' }),
1010
});
1111
</script>
1212

packages/layerchart/src/lib/states/chart.svelte.test.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,6 @@ describe('ChartState mark registration', () => {
225225
const { state, cleanup } = createChartState<TestData>({
226226
data: [{ date: '2024-01', value: 10 }],
227227
x: 'date',
228-
y: 'value',
229228
});
230229

231230
try {
@@ -250,6 +249,24 @@ describe('ChartState mark registration', () => {
250249
}
251250
});
252251

252+
it('should not create implicit series when mark accessor matches chart accessor', () => {
253+
const { state, cleanup } = createChartState<TestData>({
254+
data: [{ date: '2024-01', value: 10 }],
255+
x: 'date',
256+
y: 'value',
257+
});
258+
259+
try {
260+
// Mark with same y as chart — not a new series, just using chart's axis
261+
state.registerMark({ y: 'value', color: 'red' });
262+
flushSync();
263+
264+
expect(state.seriesState.isDefaultSeries).toBe(true);
265+
} finally {
266+
cleanup();
267+
}
268+
});
269+
253270
it('should generate implicit series from marks with string y accessors', () => {
254271
const data: MultiSeriesData[] = [
255272
{ date: '2024-01', apples: 10, bananas: 15 },

packages/layerchart/src/lib/states/chart.svelte.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,14 +250,19 @@ export class ChartState<
250250

251251
// Generate implicit series from registered marks.
252252
// Use the value axis accessor (y for horizontal charts, x for vertical).
253-
const valueAxis = this.props.valueAxis ?? 'y';
253+
const valueAxis = this.valueAxis;
254+
const chartValueProp = valueAxis === 'y' ? this.props.y : this.props.x;
254255
const implicitSeries: SeriesData<TData, any>[] = [];
255256
for (const { info } of this._markInfos) {
256257
const valueAccessor = valueAxis === 'y' ? info.y : info.x;
257258
const key =
258259
info.seriesKey ??
259260
(typeof valueAccessor === 'string' ? (valueAccessor as string) : undefined);
260261
if (!key) continue;
262+
// Skip if the mark just reuses the chart's own axis accessor and has no
263+
// separate data — it's not defining a new series, just using the chart's axis.
264+
// Marks with their own data arrays are kept (multi-dataset scenario).
265+
if (key === chartValueProp && !info.data) continue;
261266
if (implicitSeries.some((s) => s.key === key)) continue;
262267
implicitSeries.push({
263268
key,

0 commit comments

Comments
 (0)