layerchart 2.0.0-next.56 → 2.0.0-next.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -73,20 +73,31 @@
|
|
|
73
73
|
const ctx = getChartContext();
|
|
74
74
|
|
|
75
75
|
const rect = $derived.by(() => {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const
|
|
76
|
+
// `null`/`undefined` on either side means "extend to chart edge" (xRange/yRange).
|
|
77
|
+
// Tracked so band adjustments only apply to endpoints derived from the band scale,
|
|
78
|
+
// not to the xRange fallback (which already contains the full pixel extent).
|
|
79
|
+
const x0FromScale = x?.[0] != null;
|
|
80
|
+
const x1FromScale = x?.[1] != null;
|
|
81
|
+
const x0 = x0FromScale ? ctx.xScale(x![0]) : ctx.xRange[0];
|
|
82
|
+
const x1 = x1FromScale ? ctx.xScale(x![1]) : ctx.xRange[1];
|
|
83
|
+
const y0 = y?.[0] != null ? ctx.yScale(y[0]) : ctx.yRange[0];
|
|
84
|
+
const y1 = y?.[1] != null ? ctx.yScale(y[1]) : ctx.yRange[1];
|
|
80
85
|
|
|
81
86
|
const bandPadding = isScaleBand(ctx.xScale)
|
|
82
87
|
? (ctx.xScale.padding() * ctx.xScale.step()) / 2
|
|
83
88
|
: 0;
|
|
84
89
|
const bandStep = isScaleBand(ctx.xScale) ? ctx.xScale.step() : 0;
|
|
85
90
|
|
|
91
|
+
const leftFromScale = x0 <= x1 ? x0FromScale : x1FromScale;
|
|
92
|
+
const rightFromScale = x0 <= x1 ? x1FromScale : x0FromScale;
|
|
93
|
+
|
|
94
|
+
const left = Math.min(x0, x1) - (leftFromScale ? bandPadding : 0);
|
|
95
|
+
const right = Math.max(x0, x1) + (rightFromScale ? bandStep - bandPadding : 0);
|
|
96
|
+
|
|
86
97
|
return {
|
|
87
|
-
x:
|
|
98
|
+
x: left,
|
|
88
99
|
y: Math.min(y0, y1),
|
|
89
|
-
width:
|
|
100
|
+
width: right - left,
|
|
90
101
|
height: Math.abs(y1 - y0),
|
|
91
102
|
} satisfies ComponentProps<typeof Rect>;
|
|
92
103
|
});
|
|
@@ -301,9 +301,9 @@
|
|
|
301
301
|
pathData={seg.d}
|
|
302
302
|
stroke={seg.stroke}
|
|
303
303
|
fill={seg.fill}
|
|
304
|
+
opacity={seg.opacity ?? seriesOpacity}
|
|
304
305
|
{...series?.props}
|
|
305
306
|
{...restProps}
|
|
306
|
-
opacity={seg.opacity ?? seriesOpacity}
|
|
307
307
|
/>
|
|
308
308
|
{/each}
|
|
309
309
|
{:else}
|
|
@@ -311,8 +311,8 @@
|
|
|
311
311
|
pathData={isTweened ? tweenState.current : d}
|
|
312
312
|
stroke={(typeof stroke === 'string' ? stroke : undefined) ?? series?.color}
|
|
313
313
|
fill={typeof fill === 'string' ? fill : undefined}
|
|
314
|
+
opacity={(typeof opacity === 'number' ? opacity : undefined) ?? seriesOpacity}
|
|
314
315
|
{...series?.props}
|
|
315
316
|
{...restProps}
|
|
316
|
-
opacity={(typeof opacity === 'number' ? opacity : undefined) ?? seriesOpacity}
|
|
317
317
|
/>
|
|
318
318
|
{/if}
|
|
@@ -678,8 +678,13 @@ export class ChartState {
|
|
|
678
678
|
rDomain = $derived(calcDomain('r', this.extents, this.props.rDomain));
|
|
679
679
|
x1Domain = $derived.by(() => {
|
|
680
680
|
if (this.props.x1Domain) {
|
|
681
|
-
|
|
682
|
-
|
|
681
|
+
// Only filter by visible series when series are configured — otherwise the
|
|
682
|
+
// full x1Domain is used as-is (composable charts without series).
|
|
683
|
+
if (this.seriesState.series.length > 0) {
|
|
684
|
+
const visibleKeys = new Set(this.seriesState.visibleSeries.map((s) => s.key));
|
|
685
|
+
return this.props.x1Domain.filter((key) => visibleKeys.has(key));
|
|
686
|
+
}
|
|
687
|
+
return this.props.x1Domain;
|
|
683
688
|
}
|
|
684
689
|
// Auto-derive for grouped series when x is the category axis
|
|
685
690
|
if (this.props.seriesLayout === 'group' && this.valueAxis === 'y') {
|
|
@@ -692,8 +697,13 @@ export class ChartState {
|
|
|
692
697
|
});
|
|
693
698
|
y1Domain = $derived.by(() => {
|
|
694
699
|
if (this.props.y1Domain) {
|
|
695
|
-
|
|
696
|
-
|
|
700
|
+
// Only filter by visible series when series are configured — otherwise the
|
|
701
|
+
// full y1Domain is used as-is (composable charts without series).
|
|
702
|
+
if (this.seriesState.series.length > 0) {
|
|
703
|
+
const visibleKeys = new Set(this.seriesState.visibleSeries.map((s) => s.key));
|
|
704
|
+
return this.props.y1Domain.filter((key) => visibleKeys.has(key));
|
|
705
|
+
}
|
|
706
|
+
return this.props.y1Domain;
|
|
697
707
|
}
|
|
698
708
|
// Auto-derive for grouped series when y is the category axis
|
|
699
709
|
if (this.props.seriesLayout === 'group' && this.valueAxis === 'x') {
|
|
@@ -1406,3 +1406,49 @@ describe('ChartState group layout auto-derives x1/y1', () => {
|
|
|
1406
1406
|
}
|
|
1407
1407
|
});
|
|
1408
1408
|
});
|
|
1409
|
+
describe('ChartState x1Domain/y1Domain without series', () => {
|
|
1410
|
+
const longData = [
|
|
1411
|
+
{ year: 2019, fruit: 'apples', value: 3840 },
|
|
1412
|
+
{ year: 2019, fruit: 'bananas', value: 1920 },
|
|
1413
|
+
{ year: 2018, fruit: 'apples', value: 1600 },
|
|
1414
|
+
{ year: 2018, fruit: 'bananas', value: 1440 },
|
|
1415
|
+
];
|
|
1416
|
+
it('should pass through explicit x1Domain when no series are configured', () => {
|
|
1417
|
+
const { state, cleanup } = createChartState({
|
|
1418
|
+
data: longData,
|
|
1419
|
+
x: 'year',
|
|
1420
|
+
xScale: scaleBand(),
|
|
1421
|
+
y: 'value',
|
|
1422
|
+
x1: 'fruit',
|
|
1423
|
+
x1Domain: ['apples', 'bananas'],
|
|
1424
|
+
x1Range: ({ xScale }) => [0, xScale.bandwidth()],
|
|
1425
|
+
});
|
|
1426
|
+
try {
|
|
1427
|
+
expect(state.seriesState.series).toHaveLength(0);
|
|
1428
|
+
expect(state.x1Domain).toEqual(['apples', 'bananas']);
|
|
1429
|
+
expect(state.x1Scale.domain()).toEqual(['apples', 'bananas']);
|
|
1430
|
+
}
|
|
1431
|
+
finally {
|
|
1432
|
+
cleanup();
|
|
1433
|
+
}
|
|
1434
|
+
});
|
|
1435
|
+
it('should pass through explicit y1Domain when no series are configured', () => {
|
|
1436
|
+
const { state, cleanup } = createChartState({
|
|
1437
|
+
data: longData,
|
|
1438
|
+
y: 'year',
|
|
1439
|
+
yScale: scaleBand(),
|
|
1440
|
+
x: 'value',
|
|
1441
|
+
y1: 'fruit',
|
|
1442
|
+
y1Domain: ['apples', 'bananas'],
|
|
1443
|
+
y1Range: ({ yScale }) => [0, yScale.bandwidth()],
|
|
1444
|
+
});
|
|
1445
|
+
try {
|
|
1446
|
+
expect(state.seriesState.series).toHaveLength(0);
|
|
1447
|
+
expect(state.y1Domain).toEqual(['apples', 'bananas']);
|
|
1448
|
+
expect(state.y1Scale.domain()).toEqual(['apples', 'bananas']);
|
|
1449
|
+
}
|
|
1450
|
+
finally {
|
|
1451
|
+
cleanup();
|
|
1452
|
+
}
|
|
1453
|
+
});
|
|
1454
|
+
});
|
package/package.json
CHANGED