@sentropic/design-system-svelte 0.34.24 → 0.34.25
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.
- package/dist/AreaChart.svelte +61 -4
- package/dist/AreaChart.svelte.d.ts +14 -0
- package/dist/AreaChart.svelte.d.ts.map +1 -1
- package/dist/BarChart.svelte +59 -4
- package/dist/BarChart.svelte.d.ts +14 -0
- package/dist/BarChart.svelte.d.ts.map +1 -1
- package/dist/LineChart.svelte +60 -4
- package/dist/LineChart.svelte.d.ts +14 -0
- package/dist/LineChart.svelte.d.ts.map +1 -1
- package/dist/chartCrosshair.d.ts +19 -0
- package/dist/chartCrosshair.d.ts.map +1 -0
- package/dist/chartCrosshair.js +51 -0
- package/package.json +1 -1
package/dist/AreaChart.svelte
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
type ChartAnnotation
|
|
25
25
|
} from "./chartAnnotations.js";
|
|
26
26
|
import { formatDataLabel, normalizeDataLabels, type DataLabelsProp } from "./chartDataLabels.js";
|
|
27
|
+
import { keyForX, resolveActiveIndex } from "./chartCrosshair.js";
|
|
27
28
|
|
|
28
29
|
type AreaChartProps = {
|
|
29
30
|
data: (number | AreaChartDatum)[];
|
|
@@ -46,6 +47,20 @@
|
|
|
46
47
|
* ChartDataList.
|
|
47
48
|
*/
|
|
48
49
|
dataLabels?: DataLabelsProp;
|
|
50
|
+
/**
|
|
51
|
+
* CONTROLLED synchronised hover key (FR-3). A datum's key is `String(x)`. When
|
|
52
|
+
* provided (string or null), the crosshair + tooltip track this key instead of
|
|
53
|
+
* the chart's internal pointer hover (null ⇒ nothing shown), letting a parent
|
|
54
|
+
* share one hover channel across several aligned charts. Absent (`undefined`)
|
|
55
|
+
* keeps the legacy uncontrolled behaviour.
|
|
56
|
+
*/
|
|
57
|
+
hoverKey?: string | null;
|
|
58
|
+
/**
|
|
59
|
+
* Emitted when the user hovers a datum (its key) or leaves the plot (`null`).
|
|
60
|
+
* Always fired on pointer move/leave — even while CONTROLLED — so dataviz can
|
|
61
|
+
* keep the shared hover channel in sync.
|
|
62
|
+
*/
|
|
63
|
+
onHoverKeyChange?: (key: string | null) => void;
|
|
49
64
|
class?: string;
|
|
50
65
|
};
|
|
51
66
|
|
|
@@ -58,6 +73,8 @@
|
|
|
58
73
|
label,
|
|
59
74
|
annotations,
|
|
60
75
|
dataLabels,
|
|
76
|
+
hoverKey,
|
|
77
|
+
onHoverKeyChange,
|
|
61
78
|
class: className
|
|
62
79
|
}: AreaChartProps = $props();
|
|
63
80
|
|
|
@@ -271,19 +288,34 @@
|
|
|
271
288
|
return entries;
|
|
272
289
|
});
|
|
273
290
|
|
|
291
|
+
// Stable key per datum (FR-3): `String(x)` of the normalised datum (a bare
|
|
292
|
+
// number becomes its index). Resolves a controlled `hoverKey` to an index and
|
|
293
|
+
// feeds `onHoverKeyChange` from pointer events.
|
|
294
|
+
const hoverKeys = $derived(normalizedData.map((d) => keyForX(d.x)));
|
|
295
|
+
function emitHoverKey(index: number | null) {
|
|
296
|
+
onHoverKeyChange?.(index == null ? null : hoverKeys[index] ?? null);
|
|
297
|
+
}
|
|
274
298
|
function handleLeave() {
|
|
275
299
|
hoveredIndex = null;
|
|
300
|
+
emitHoverKey(null);
|
|
276
301
|
}
|
|
277
302
|
function handleVisualPointerMove(event: PointerEvent) {
|
|
278
303
|
const target = event.target;
|
|
279
304
|
if (!(target instanceof Element)) {
|
|
280
305
|
hoveredIndex = null;
|
|
306
|
+
emitHoverKey(null);
|
|
281
307
|
return;
|
|
282
308
|
}
|
|
283
|
-
const
|
|
284
|
-
|
|
309
|
+
const raw = Number(target.getAttribute("data-chart-index"));
|
|
310
|
+
const index = Number.isInteger(raw) ? raw : null;
|
|
311
|
+
hoveredIndex = index;
|
|
312
|
+
emitHoverKey(index);
|
|
285
313
|
}
|
|
286
314
|
|
|
315
|
+
// Index whose crosshair/tooltip is DISPLAYED: the controlled `hoverKey` when
|
|
316
|
+
// provided (resolved against `hoverKeys`), else the internal pointer index.
|
|
317
|
+
const activeIndex = $derived(resolveActiveIndex(hoverKey, hoveredIndex, hoverKeys));
|
|
318
|
+
|
|
287
319
|
// Generates a unique gradient id to avoid conflicts when rendering multiple charts on the same page
|
|
288
320
|
const gradientId = $derived.by(() => {
|
|
289
321
|
return `st-areachart-gradient-${Math.random().toString(36).substring(2, 9)}`;
|
|
@@ -441,13 +473,23 @@
|
|
|
441
473
|
{/each}
|
|
442
474
|
</g>
|
|
443
475
|
{/if}
|
|
476
|
+
|
|
477
|
+
<!-- Crosshair (FR-3) — a tokenised vertical line + marker at the active key.
|
|
478
|
+
Decorative (aria-hidden); the value is in the tooltip + ChartDataList. -->
|
|
479
|
+
{#if activeIndex >= 0 && points[activeIndex]}
|
|
480
|
+
{@const cp = points[activeIndex]}
|
|
481
|
+
<g class="st-areaChart__crosshair" aria-hidden="true">
|
|
482
|
+
<line class="st-areaChart__crosshairLine" x1={cp.x} x2={cp.x} y1={MARGIN.top} y2={MARGIN.top + plotHeight} />
|
|
483
|
+
<circle class="st-areaChart__crosshairMarker" cx={cp.x} cy={cp.y} r="5" />
|
|
484
|
+
</g>
|
|
485
|
+
{/if}
|
|
444
486
|
</svg>
|
|
445
487
|
</div>
|
|
446
488
|
|
|
447
489
|
<ChartDataList {label} items={dataValueItems} />
|
|
448
490
|
|
|
449
|
-
{#if
|
|
450
|
-
{@const p = points[
|
|
491
|
+
{#if activeIndex >= 0 && points[activeIndex]}
|
|
492
|
+
{@const p = points[activeIndex]}
|
|
451
493
|
<div
|
|
452
494
|
class="st-areaChart__tooltip"
|
|
453
495
|
role="presentation"
|
|
@@ -588,4 +630,19 @@
|
|
|
588
630
|
font-size: 0.6875rem;
|
|
589
631
|
font-weight: 600;
|
|
590
632
|
}
|
|
633
|
+
|
|
634
|
+
/* --- Crosshair layer (FR-3) ----------------------------------------------
|
|
635
|
+
A tokenised dashed vertical line at the active (hovered/controlled) key,
|
|
636
|
+
plus an emphasised marker on the point. Decorative (aria-hidden). */
|
|
637
|
+
.st-areaChart__crosshairLine {
|
|
638
|
+
stroke: var(--st-semantic-border-strong);
|
|
639
|
+
stroke-width: 1;
|
|
640
|
+
stroke-dasharray: 3 3;
|
|
641
|
+
opacity: 0.7;
|
|
642
|
+
}
|
|
643
|
+
.st-areaChart__crosshairMarker {
|
|
644
|
+
fill: currentColor;
|
|
645
|
+
stroke: var(--st-semantic-surface-default);
|
|
646
|
+
stroke-width: 2;
|
|
647
|
+
}
|
|
591
648
|
</style>
|
|
@@ -26,6 +26,20 @@ type AreaChartProps = {
|
|
|
26
26
|
* ChartDataList.
|
|
27
27
|
*/
|
|
28
28
|
dataLabels?: DataLabelsProp;
|
|
29
|
+
/**
|
|
30
|
+
* CONTROLLED synchronised hover key (FR-3). A datum's key is `String(x)`. When
|
|
31
|
+
* provided (string or null), the crosshair + tooltip track this key instead of
|
|
32
|
+
* the chart's internal pointer hover (null ⇒ nothing shown), letting a parent
|
|
33
|
+
* share one hover channel across several aligned charts. Absent (`undefined`)
|
|
34
|
+
* keeps the legacy uncontrolled behaviour.
|
|
35
|
+
*/
|
|
36
|
+
hoverKey?: string | null;
|
|
37
|
+
/**
|
|
38
|
+
* Emitted when the user hovers a datum (its key) or leaves the plot (`null`).
|
|
39
|
+
* Always fired on pointer move/leave — even while CONTROLLED — so dataviz can
|
|
40
|
+
* keep the shared hover channel in sync.
|
|
41
|
+
*/
|
|
42
|
+
onHoverKeyChange?: (key: string | null) => void;
|
|
29
43
|
class?: string;
|
|
30
44
|
};
|
|
31
45
|
declare const AreaChart: import("svelte").Component<AreaChartProps, {}, "">;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AreaChart.svelte.d.ts","sourceRoot":"","sources":["../src/lib/AreaChart.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,cAAc,GAAG;IAC3B,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAIJ,OAAO,EAIH,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AACjC,OAAO,EAAwC,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"AreaChart.svelte.d.ts","sourceRoot":"","sources":["../src/lib/AreaChart.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,cAAc,GAAG;IAC3B,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAIJ,OAAO,EAIH,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AACjC,OAAO,EAAwC,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAI/F,KAAK,cAAc,GAAG;IACpB,IAAI,EAAE,CAAC,MAAM,GAAG,cAAc,CAAC,EAAE,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAkYJ,QAAA,MAAM,SAAS,oDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
|
package/dist/BarChart.svelte
CHANGED
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
type ChartAnnotation
|
|
58
58
|
} from "./chartAnnotations.js";
|
|
59
59
|
import { formatDataLabel, normalizeDataLabels, type DataLabelsProp } from "./chartDataLabels.js";
|
|
60
|
+
import { resolveActiveIndex } from "./chartCrosshair.js";
|
|
60
61
|
|
|
61
62
|
type BarChartProps = {
|
|
62
63
|
data: BarChartDatum[];
|
|
@@ -124,6 +125,20 @@
|
|
|
124
125
|
* cross-chart parity and otherwise ignored.
|
|
125
126
|
*/
|
|
126
127
|
showLegend?: boolean;
|
|
128
|
+
/**
|
|
129
|
+
* CONTROLLED synchronised hover key (FR-3). A bar's key is its `label`. When
|
|
130
|
+
* provided (string or null), the crosshair + tooltip track this key instead of
|
|
131
|
+
* the chart's internal pointer hover (null ⇒ nothing shown), letting a parent
|
|
132
|
+
* share one hover channel across several aligned charts. Absent (`undefined`)
|
|
133
|
+
* keeps the legacy uncontrolled behaviour. Independent of `selectedKeys`.
|
|
134
|
+
*/
|
|
135
|
+
hoverKey?: string | null;
|
|
136
|
+
/**
|
|
137
|
+
* Emitted when the user hovers a bar (its `label`) or leaves the plot (`null`).
|
|
138
|
+
* Always fired on pointer move/leave — even while CONTROLLED — so dataviz can
|
|
139
|
+
* keep the shared hover channel in sync.
|
|
140
|
+
*/
|
|
141
|
+
onHoverKeyChange?: (key: string | null) => void;
|
|
127
142
|
class?: string;
|
|
128
143
|
};
|
|
129
144
|
|
|
@@ -144,6 +159,8 @@
|
|
|
144
159
|
scale = "linear",
|
|
145
160
|
invertAxis = false,
|
|
146
161
|
showLegend,
|
|
162
|
+
hoverKey,
|
|
163
|
+
onHoverKeyChange,
|
|
147
164
|
class: className
|
|
148
165
|
}: BarChartProps = $props();
|
|
149
166
|
|
|
@@ -599,19 +616,33 @@
|
|
|
599
616
|
}));
|
|
600
617
|
});
|
|
601
618
|
|
|
619
|
+
// Stable key per bar (FR-3): its `label`. Resolves a controlled `hoverKey` to
|
|
620
|
+
// an index and feeds `onHoverKeyChange` from pointer events.
|
|
621
|
+
const hoverKeys = $derived(bars.map((b) => b.datum.label));
|
|
622
|
+
function emitHoverKey(index: number | null) {
|
|
623
|
+
onHoverKeyChange?.(index == null ? null : hoverKeys[index] ?? null);
|
|
624
|
+
}
|
|
602
625
|
function handleLeave() {
|
|
603
626
|
hoveredIndex = null;
|
|
627
|
+
emitHoverKey(null);
|
|
604
628
|
}
|
|
605
629
|
function handleVisualPointerMove(event: PointerEvent) {
|
|
606
630
|
const target = event.target;
|
|
607
631
|
if (!(target instanceof Element)) {
|
|
608
632
|
hoveredIndex = null;
|
|
633
|
+
emitHoverKey(null);
|
|
609
634
|
return;
|
|
610
635
|
}
|
|
611
|
-
const
|
|
612
|
-
|
|
636
|
+
const raw = Number(target.getAttribute("data-chart-index"));
|
|
637
|
+
const index = Number.isInteger(raw) ? raw : null;
|
|
638
|
+
hoveredIndex = index;
|
|
639
|
+
emitHoverKey(index);
|
|
613
640
|
}
|
|
614
641
|
|
|
642
|
+
// Index whose crosshair/tooltip is DISPLAYED: the controlled `hoverKey` when
|
|
643
|
+
// provided (resolved against `hoverKeys`), else the internal pointer index.
|
|
644
|
+
const activeIndex = $derived(resolveActiveIndex(hoverKey, hoveredIndex, hoverKeys));
|
|
645
|
+
|
|
615
646
|
const classes = () => ["st-barChart", className].filter(Boolean).join(" ");
|
|
616
647
|
</script>
|
|
617
648
|
|
|
@@ -836,6 +867,20 @@
|
|
|
836
867
|
{/each}
|
|
837
868
|
</g>
|
|
838
869
|
{/if}
|
|
870
|
+
|
|
871
|
+
<!-- Crosshair (FR-3) — a tokenised dashed line on the CATEGORY axis at the
|
|
872
|
+
active bar: vertical (vertical bars) / horizontal (horizontal bars).
|
|
873
|
+
Decorative (aria-hidden); the value is in the tooltip + ChartDataList. -->
|
|
874
|
+
{#if activeIndex >= 0 && bars[activeIndex]}
|
|
875
|
+
{@const cb = bars[activeIndex]}
|
|
876
|
+
<g class="st-barChart__crosshair" aria-hidden="true">
|
|
877
|
+
{#if isVertical}
|
|
878
|
+
<line class="st-barChart__crosshairLine" x1={cb.cx} x2={cb.cx} y1={MARGIN.top} y2={MARGIN.top + scales.plotHeight} />
|
|
879
|
+
{:else}
|
|
880
|
+
<line class="st-barChart__crosshairLine" x1={MARGIN.left} x2={MARGIN.left + scales.plotWidth} y1={cb.cy} y2={cb.cy} />
|
|
881
|
+
{/if}
|
|
882
|
+
</g>
|
|
883
|
+
{/if}
|
|
839
884
|
</svg>
|
|
840
885
|
</div>
|
|
841
886
|
|
|
@@ -861,8 +906,8 @@
|
|
|
861
906
|
|
|
862
907
|
<ChartDataList {label} items={dataValueItems} />
|
|
863
908
|
|
|
864
|
-
{#if
|
|
865
|
-
{@const bar = bars[
|
|
909
|
+
{#if activeIndex >= 0 && bars[activeIndex]}
|
|
910
|
+
{@const bar = bars[activeIndex]}
|
|
866
911
|
<div
|
|
867
912
|
class="st-barChart__tooltip"
|
|
868
913
|
role="presentation"
|
|
@@ -1124,4 +1169,14 @@
|
|
|
1124
1169
|
font-size: 0.6875rem;
|
|
1125
1170
|
font-weight: 600;
|
|
1126
1171
|
}
|
|
1172
|
+
|
|
1173
|
+
/* --- Crosshair layer (FR-3) ----------------------------------------------
|
|
1174
|
+
A tokenised dashed line on the CATEGORY axis at the active (hovered/
|
|
1175
|
+
controlled) bar. Decorative (aria-hidden). */
|
|
1176
|
+
.st-barChart__crosshairLine {
|
|
1177
|
+
stroke: var(--st-semantic-border-strong);
|
|
1178
|
+
stroke-width: 1;
|
|
1179
|
+
stroke-dasharray: 3 3;
|
|
1180
|
+
opacity: 0.7;
|
|
1181
|
+
}
|
|
1127
1182
|
</style>
|
|
@@ -99,6 +99,20 @@ type BarChartProps = {
|
|
|
99
99
|
* cross-chart parity and otherwise ignored.
|
|
100
100
|
*/
|
|
101
101
|
showLegend?: boolean;
|
|
102
|
+
/**
|
|
103
|
+
* CONTROLLED synchronised hover key (FR-3). A bar's key is its `label`. When
|
|
104
|
+
* provided (string or null), the crosshair + tooltip track this key instead of
|
|
105
|
+
* the chart's internal pointer hover (null ⇒ nothing shown), letting a parent
|
|
106
|
+
* share one hover channel across several aligned charts. Absent (`undefined`)
|
|
107
|
+
* keeps the legacy uncontrolled behaviour. Independent of `selectedKeys`.
|
|
108
|
+
*/
|
|
109
|
+
hoverKey?: string | null;
|
|
110
|
+
/**
|
|
111
|
+
* Emitted when the user hovers a bar (its `label`) or leaves the plot (`null`).
|
|
112
|
+
* Always fired on pointer move/leave — even while CONTROLLED — so dataviz can
|
|
113
|
+
* keep the shared hover channel in sync.
|
|
114
|
+
*/
|
|
115
|
+
onHoverKeyChange?: (key: string | null) => void;
|
|
102
116
|
class?: string;
|
|
103
117
|
};
|
|
104
118
|
declare const BarChart: import("svelte").Component<BarChartProps, {}, "">;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BarChart.svelte.d.ts","sourceRoot":"","sources":["../src/lib/BarChart.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,MAAM,YAAY,GACpB,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAEpF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,IAAI,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,sEAAsE;AACtE,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,KAAK,CAAC;AAI5C,OAAO,EAIH,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AACjC,OAAO,EAAwC,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"BarChart.svelte.d.ts","sourceRoot":"","sources":["../src/lib/BarChart.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,MAAM,YAAY,GACpB,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAEpF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,IAAI,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,sEAAsE;AACtE,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,KAAK,CAAC;AAI5C,OAAO,EAIH,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AACjC,OAAO,EAAwC,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAI/F,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,+DAA+D;IAC/D,cAAc,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACtC,oDAAoD;IACpD,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IACpB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AA8qBJ,QAAA,MAAM,QAAQ,mDAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
|
package/dist/LineChart.svelte
CHANGED
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
type ChartAnnotation
|
|
61
61
|
} from "./chartAnnotations.js";
|
|
62
62
|
import { formatDataLabel, normalizeDataLabels, type DataLabelsProp } from "./chartDataLabels.js";
|
|
63
|
+
import { keyForX, resolveActiveIndex } from "./chartCrosshair.js";
|
|
63
64
|
|
|
64
65
|
type LineChartProps = {
|
|
65
66
|
data: LineChartDatum[];
|
|
@@ -111,6 +112,20 @@
|
|
|
111
112
|
* no legend surface, so this prop is accepted for parity and otherwise ignored.
|
|
112
113
|
*/
|
|
113
114
|
showLegend?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* CONTROLLED synchronised hover key (FR-3). A datum's key is `String(x)`. When
|
|
117
|
+
* provided (string or null), the crosshair + tooltip track this key instead of
|
|
118
|
+
* the chart's internal pointer hover (null ⇒ nothing shown), letting a parent
|
|
119
|
+
* share one hover channel across several aligned charts. Absent (`undefined`)
|
|
120
|
+
* keeps the legacy uncontrolled behaviour.
|
|
121
|
+
*/
|
|
122
|
+
hoverKey?: string | null;
|
|
123
|
+
/**
|
|
124
|
+
* Emitted when the user hovers a datum (its key) or leaves the plot (`null`).
|
|
125
|
+
* Always fired on pointer move/leave — even while CONTROLLED — so dataviz can
|
|
126
|
+
* keep the shared hover channel in sync.
|
|
127
|
+
*/
|
|
128
|
+
onHoverKeyChange?: (key: string | null) => void;
|
|
114
129
|
class?: string;
|
|
115
130
|
};
|
|
116
131
|
|
|
@@ -132,6 +147,8 @@
|
|
|
132
147
|
scale = "linear",
|
|
133
148
|
invertAxis = false,
|
|
134
149
|
showLegend,
|
|
150
|
+
hoverKey,
|
|
151
|
+
onHoverKeyChange,
|
|
135
152
|
class: className
|
|
136
153
|
}: LineChartProps = $props();
|
|
137
154
|
|
|
@@ -617,19 +634,33 @@
|
|
|
617
634
|
return entries;
|
|
618
635
|
});
|
|
619
636
|
|
|
637
|
+
// Stable key per datum (FR-3): `String(x)`. Resolves a controlled `hoverKey`
|
|
638
|
+
// to an index and feeds `onHoverKeyChange` from pointer events.
|
|
639
|
+
const hoverKeys = $derived(data.map((d) => keyForX(d.x)));
|
|
640
|
+
function emitHoverKey(index: number | null) {
|
|
641
|
+
onHoverKeyChange?.(index == null ? null : hoverKeys[index] ?? null);
|
|
642
|
+
}
|
|
620
643
|
function handleLeave() {
|
|
621
644
|
hoveredIndex = null;
|
|
645
|
+
emitHoverKey(null);
|
|
622
646
|
}
|
|
623
647
|
function handleVisualPointerMove(event: PointerEvent) {
|
|
624
648
|
const target = event.target;
|
|
625
649
|
if (!(target instanceof Element)) {
|
|
626
650
|
hoveredIndex = null;
|
|
651
|
+
emitHoverKey(null);
|
|
627
652
|
return;
|
|
628
653
|
}
|
|
629
|
-
const
|
|
630
|
-
|
|
654
|
+
const raw = Number(target.getAttribute("data-chart-index"));
|
|
655
|
+
const index = Number.isInteger(raw) ? raw : null;
|
|
656
|
+
hoveredIndex = index;
|
|
657
|
+
emitHoverKey(index);
|
|
631
658
|
}
|
|
632
659
|
|
|
660
|
+
// Index whose crosshair/tooltip is DISPLAYED: the controlled `hoverKey` when
|
|
661
|
+
// provided (resolved against `hoverKeys`), else the internal pointer index.
|
|
662
|
+
const activeIndex = $derived(resolveActiveIndex(hoverKey, hoveredIndex, hoverKeys));
|
|
663
|
+
|
|
633
664
|
const classes = () =>
|
|
634
665
|
["st-lineChart", `st-lineChart--${tone}`, className].filter(Boolean).join(" ");
|
|
635
666
|
</script>
|
|
@@ -820,13 +851,23 @@
|
|
|
820
851
|
{/each}
|
|
821
852
|
</g>
|
|
822
853
|
{/if}
|
|
854
|
+
|
|
855
|
+
<!-- Crosshair (FR-3) — a tokenised vertical line + marker at the active key.
|
|
856
|
+
Decorative (aria-hidden); the value is in the tooltip + ChartDataList. -->
|
|
857
|
+
{#if activeIndex >= 0 && points[activeIndex]}
|
|
858
|
+
{@const cp = points[activeIndex]}
|
|
859
|
+
<g class="st-lineChart__crosshair" aria-hidden="true">
|
|
860
|
+
<line class="st-lineChart__crosshairLine" x1={cp.x} x2={cp.x} y1={MARGIN.top} y2={MARGIN.top + plotHeight} />
|
|
861
|
+
<circle class="st-lineChart__crosshairMarker" cx={cp.x} cy={cp.y} r="5" />
|
|
862
|
+
</g>
|
|
863
|
+
{/if}
|
|
823
864
|
</svg>
|
|
824
865
|
</div>
|
|
825
866
|
|
|
826
867
|
<ChartDataList {label} items={dataValueItems} />
|
|
827
868
|
|
|
828
|
-
{#if
|
|
829
|
-
{@const p = points[
|
|
869
|
+
{#if activeIndex >= 0 && points[activeIndex]}
|
|
870
|
+
{@const p = points[activeIndex]}
|
|
830
871
|
<div
|
|
831
872
|
class="st-lineChart__tooltip"
|
|
832
873
|
role="presentation"
|
|
@@ -1028,4 +1069,19 @@
|
|
|
1028
1069
|
font-size: 0.6875rem;
|
|
1029
1070
|
font-weight: 600;
|
|
1030
1071
|
}
|
|
1072
|
+
|
|
1073
|
+
/* --- Crosshair layer (FR-3) ----------------------------------------------
|
|
1074
|
+
A tokenised dashed vertical line at the active (hovered/controlled) key,
|
|
1075
|
+
plus an emphasised marker on the point. Decorative (aria-hidden). */
|
|
1076
|
+
.st-lineChart__crosshairLine {
|
|
1077
|
+
stroke: var(--st-semantic-border-strong);
|
|
1078
|
+
stroke-width: 1;
|
|
1079
|
+
stroke-dasharray: 3 3;
|
|
1080
|
+
opacity: 0.7;
|
|
1081
|
+
}
|
|
1082
|
+
.st-lineChart__crosshairMarker {
|
|
1083
|
+
fill: currentColor;
|
|
1084
|
+
stroke: var(--st-semantic-surface-default);
|
|
1085
|
+
stroke-width: 2;
|
|
1086
|
+
}
|
|
1031
1087
|
</style>
|
|
@@ -86,6 +86,20 @@ type LineChartProps = {
|
|
|
86
86
|
* no legend surface, so this prop is accepted for parity and otherwise ignored.
|
|
87
87
|
*/
|
|
88
88
|
showLegend?: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* CONTROLLED synchronised hover key (FR-3). A datum's key is `String(x)`. When
|
|
91
|
+
* provided (string or null), the crosshair + tooltip track this key instead of
|
|
92
|
+
* the chart's internal pointer hover (null ⇒ nothing shown), letting a parent
|
|
93
|
+
* share one hover channel across several aligned charts. Absent (`undefined`)
|
|
94
|
+
* keeps the legacy uncontrolled behaviour.
|
|
95
|
+
*/
|
|
96
|
+
hoverKey?: string | null;
|
|
97
|
+
/**
|
|
98
|
+
* Emitted when the user hovers a datum (its key) or leaves the plot (`null`).
|
|
99
|
+
* Always fired on pointer move/leave — even while CONTROLLED — so dataviz can
|
|
100
|
+
* keep the shared hover channel in sync.
|
|
101
|
+
*/
|
|
102
|
+
onHoverKeyChange?: (key: string | null) => void;
|
|
89
103
|
class?: string;
|
|
90
104
|
};
|
|
91
105
|
declare const LineChart: import("svelte").Component<LineChartProps, {}, "">;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LineChart.svelte.d.ts","sourceRoot":"","sources":["../src/lib/LineChart.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,cAAc,GAAG;IAC3B,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAEpF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,IAAI,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,sEAAsE;AACtE,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,KAAK,CAAC;AAI5C,OAAO,EAIH,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AACjC,OAAO,EAAwC,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"LineChart.svelte.d.ts","sourceRoot":"","sources":["../src/lib/LineChart.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,cAAc,GAAG;IAC3B,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAEpF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,IAAI,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,sEAAsE;AACtE,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,KAAK,CAAC;AAI5C,OAAO,EAIH,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AACjC,OAAO,EAAwC,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAI/F,KAAK,cAAc,GAAG;IACpB,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,cAAc,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACtC,oDAAoD;IACpD,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IACpB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,qDAAqD;IACrD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1B;;;;OAIG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,iDAAiD;IACjD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AA+qBJ,QAAA,MAAM,SAAS,oDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Serialises a Line/Area datum's `x` to its stable hover key. */
|
|
2
|
+
export declare function keyForX(x: number | string): string;
|
|
3
|
+
/**
|
|
4
|
+
* Resolves the hover key to a datum index within `keys` (the ordered list of
|
|
5
|
+
* every datum's key). Returns -1 when the key is null/undefined or unmatched.
|
|
6
|
+
*/
|
|
7
|
+
export declare function indexForHoverKey(hoverKey: string | null | undefined, keys: string[]): number;
|
|
8
|
+
/**
|
|
9
|
+
* Picks the datum index to DISPLAY the crosshair/tooltip at.
|
|
10
|
+
* - Controlled (`hoverKey !== undefined`): the index of `hoverKey` in `keys`
|
|
11
|
+
* (or -1 when null/unmatched). The internal pointer index is ignored for
|
|
12
|
+
* display.
|
|
13
|
+
* - Uncontrolled (`hoverKey === undefined`): the internal pointer index.
|
|
14
|
+
* Returns -1 when nothing should be shown.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveActiveIndex(hoverKey: string | null | undefined, internalIndex: number | null, keys: string[]): number;
|
|
17
|
+
/** True when the chart is CONTROLLED (the parent supplied `hoverKey`). */
|
|
18
|
+
export declare function isControlled(hoverKey: string | null | undefined): boolean;
|
|
19
|
+
//# sourceMappingURL=chartCrosshair.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chartCrosshair.d.ts","sourceRoot":"","sources":["../src/lib/chartCrosshair.ts"],"names":[],"mappings":"AAsBA,kEAAkE;AAClE,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAElD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAG5F;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,IAAI,EAAE,MAAM,EAAE,GACb,MAAM,CAGR;AAED,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAEzE"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// --- Chart crosshair / synchronised hover layer (shared, framework-agnostic) -
|
|
2
|
+
//
|
|
3
|
+
// FR-3: a CONTROLLED crosshair + tooltip whose position is driven by a `hoverKey`
|
|
4
|
+
// string the parent owns, so dataviz can share one hover channel across several
|
|
5
|
+
// aligned panels (a "linked" tooltip). The DS stays presentational: it resolves
|
|
6
|
+
// the key to a datum index, draws a tokenised vertical line at that x (plus a
|
|
7
|
+
// marker on the point for Line/Area), and reuses the existing tooltip surface.
|
|
8
|
+
//
|
|
9
|
+
// The "key" is the stable identifier of a datum on the categorical/x axis:
|
|
10
|
+
// - Bar: the bar's `label`.
|
|
11
|
+
// - Line/Area: the point's `x`, serialised with `String(x)`.
|
|
12
|
+
//
|
|
13
|
+
// Behaviour:
|
|
14
|
+
// - `hoverKey === undefined` → UNCONTROLLED (internal hover, unchanged, fully
|
|
15
|
+
// backward compatible).
|
|
16
|
+
// - `hoverKey` provided (string or null) → CONTROLLED: the displayed
|
|
17
|
+
// crosshair/tooltip tracks `hoverKey` (null = nothing shown), the chart's own
|
|
18
|
+
// pointer hover no longer drives the DISPLAY, but `onHoverKeyChange` is still
|
|
19
|
+
// emitted so the parent can keep the shared channel in sync.
|
|
20
|
+
//
|
|
21
|
+
// Purely additive: a chart that passes neither prop renders exactly as before.
|
|
22
|
+
/** Serialises a Line/Area datum's `x` to its stable hover key. */
|
|
23
|
+
export function keyForX(x) {
|
|
24
|
+
return String(x);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Resolves the hover key to a datum index within `keys` (the ordered list of
|
|
28
|
+
* every datum's key). Returns -1 when the key is null/undefined or unmatched.
|
|
29
|
+
*/
|
|
30
|
+
export function indexForHoverKey(hoverKey, keys) {
|
|
31
|
+
if (hoverKey == null)
|
|
32
|
+
return -1;
|
|
33
|
+
return keys.indexOf(hoverKey);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Picks the datum index to DISPLAY the crosshair/tooltip at.
|
|
37
|
+
* - Controlled (`hoverKey !== undefined`): the index of `hoverKey` in `keys`
|
|
38
|
+
* (or -1 when null/unmatched). The internal pointer index is ignored for
|
|
39
|
+
* display.
|
|
40
|
+
* - Uncontrolled (`hoverKey === undefined`): the internal pointer index.
|
|
41
|
+
* Returns -1 when nothing should be shown.
|
|
42
|
+
*/
|
|
43
|
+
export function resolveActiveIndex(hoverKey, internalIndex, keys) {
|
|
44
|
+
if (hoverKey !== undefined)
|
|
45
|
+
return indexForHoverKey(hoverKey, keys);
|
|
46
|
+
return internalIndex == null ? -1 : internalIndex;
|
|
47
|
+
}
|
|
48
|
+
/** True when the chart is CONTROLLED (the parent supplied `hoverKey`). */
|
|
49
|
+
export function isControlled(hoverKey) {
|
|
50
|
+
return hoverKey !== undefined;
|
|
51
|
+
}
|