basalt-ui 1.16.0 → 1.17.0
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/CHANGELOG.md +7 -0
- package/agent/rules/basalt-charts.md +46 -4
- package/dist/charts/cursor/resolve.d.ts +29 -5
- package/dist/charts/cursor/resolve.d.ts.map +1 -1
- package/dist/charts/cursor/resolve.js +25 -4
- package/dist/charts/hooks/useChartCursor.d.ts +8 -1
- package/dist/charts/hooks/useChartCursor.d.ts.map +1 -1
- package/dist/charts/hooks/useChartCursor.js +6 -2
- package/dist/charts/index.d.ts +1 -0
- package/dist/charts/index.d.ts.map +1 -1
- package/dist/charts/kinds/Bars.d.ts +9 -0
- package/dist/charts/kinds/Bars.d.ts.map +1 -1
- package/dist/charts/kinds/Bars.js +4 -0
- package/dist/charts/kinds/DualPanel.d.ts +17 -0
- package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
- package/dist/charts/kinds/DualPanel.js +29 -6
- package/dist/charts/kinds/MultiLine.d.ts +9 -0
- package/dist/charts/kinds/MultiLine.d.ts.map +1 -1
- package/dist/charts/kinds/MultiLine.js +10 -8
- package/dist/charts/kinds/StackedArea.d.ts +9 -0
- package/dist/charts/kinds/StackedArea.d.ts.map +1 -1
- package/dist/charts/kinds/StackedArea.js +16 -1
- package/dist/charts/kinds/StackedArea.test.d.ts +2 -0
- package/dist/charts/kinds/StackedArea.test.d.ts.map +1 -0
- package/dist/charts/kinds/ZonedLine.d.ts +9 -0
- package/dist/charts/kinds/ZonedLine.d.ts.map +1 -1
- package/dist/charts/kinds/ZonedLine.js +4 -0
- package/dist/charts/primitives/CartesianChart.d.ts +23 -2
- package/dist/charts/primitives/CartesianChart.d.ts.map +1 -1
- package/dist/charts/primitives/CartesianChart.js +11 -4
- package/dist/charts/primitives/ChartFrame.d.ts +8 -1
- package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
- package/dist/charts/primitives/ChartFrame.js +1 -1
- package/dist/charts/primitives/ChartTooltip.d.ts +6 -1
- package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
- package/dist/charts/primitives/ChartTooltip.js +3 -2
- package/dist/charts/primitives/ChartTooltip.test.d.ts +2 -0
- package/dist/charts/primitives/ChartTooltip.test.d.ts.map +1 -0
- package/dist/charts/series.d.ts +4 -1
- package/dist/charts/series.d.ts.map +1 -1
- package/dist/charts/utils/domain.d.ts +15 -0
- package/dist/charts/utils/domain.d.ts.map +1 -1
- package/dist/charts/utils/domain.js +6 -1
- package/llms.txt +2 -2
- package/package.json +1 -1
- package/src/charts/cursor/resolve.test.ts +62 -0
- package/src/charts/cursor/resolve.ts +71 -7
- package/src/charts/hooks/useChartCursor.ts +12 -1
- package/src/charts/index.ts +1 -0
- package/src/charts/kinds/Bars.test.tsx +85 -0
- package/src/charts/kinds/Bars.tsx +13 -0
- package/src/charts/kinds/DualPanel.test.tsx +310 -0
- package/src/charts/kinds/DualPanel.tsx +48 -4
- package/src/charts/kinds/MultiLine.test.tsx +181 -0
- package/src/charts/kinds/MultiLine.tsx +19 -8
- package/src/charts/kinds/StackedArea.test.tsx +114 -0
- package/src/charts/kinds/StackedArea.tsx +25 -1
- package/src/charts/kinds/ZonedLine.test.tsx +110 -0
- package/src/charts/kinds/ZonedLine.tsx +13 -0
- package/src/charts/primitives/CartesianChart.test.tsx +111 -2
- package/src/charts/primitives/CartesianChart.tsx +35 -7
- package/src/charts/primitives/ChartFrame.test.tsx +42 -0
- package/src/charts/primitives/ChartFrame.tsx +9 -2
- package/src/charts/primitives/ChartTooltip.test.tsx +23 -0
- package/src/charts/primitives/ChartTooltip.tsx +7 -1
- package/src/charts/series.ts +3 -2
- package/src/charts/utils/domain.test.ts +31 -1
- package/src/charts/utils/domain.ts +19 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [1.17.0](https://github.com/jkrumm/basalt-ui/compare/v1.16.0...v1.17.0) (2026-08-18)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* fix seven chart defects, six of them found by consumers ([c3df0b8](https://github.com/jkrumm/basalt-ui/commit/c3df0b8439c51effaf425c54644cd9a15328ef12))
|
|
7
|
+
|
|
1
8
|
# [1.16.0](https://github.com/jkrumm/basalt-ui/compare/v1.15.0...v1.16.0) (2026-08-18)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -137,7 +137,14 @@ ships no map kind.
|
|
|
137
137
|
`tickFormat` (`TickFormatter<string>`, defaults to `fmtAxisDate` — `DD.MM`) — the only supported
|
|
138
138
|
exit for a sub-day window, where the default collapses every tick to the same label and a raw
|
|
139
139
|
`<AxisBottom>` isn't an option. `CartesianChart`'s own `formatX` prop is the higher-level way to
|
|
140
|
-
set this without touching the axis component at all
|
|
140
|
+
set this without touching the axis component at all — and every cartesian kind (`Bars`/
|
|
141
|
+
`MultiLine`/`StackedArea`/`ZonedLine`/`DualPanel`) forwards its own `formatX?: (key) => string`
|
|
142
|
+
now too, not just `CartesianChart` itself. Without it, the only route to a custom x label was
|
|
143
|
+
pre-formatting it into the domain key, which makes one string serve as display value, scale
|
|
144
|
+
identity, AND cursor key simultaneously — and a truncating formatter then collapses two points
|
|
145
|
+
onto one domain value, silently dropping one from the plot (see #6 below for why that's the
|
|
146
|
+
cursor's problem too). `Heatmap` is deliberately excluded: its existing `colLabel`/`rowLabel`
|
|
147
|
+
already are that seam, and a second prop over one concern would fork them.
|
|
141
148
|
6. **The cursor is shared by default.** No provider needed — `useChartCursor` reads a module-level
|
|
142
149
|
external store (`useSyncExternalStore`), so every `CartesianChart`/`ChartFrame`-composed chart on
|
|
143
150
|
the page shares one cursor out of the box. `ChartCursorScope` **isolates** a subtree onto a
|
|
@@ -160,10 +167,26 @@ ships no map kind.
|
|
|
160
167
|
into weekly buckets still tracks a hover from a sibling plotting daily points, with no extra
|
|
161
168
|
wiring — `resolveKey` no longer exists because there is nothing left for it to patch.
|
|
162
169
|
|
|
170
|
+
`CursorResolution = 'nearest' | 'leading'` (exported from `basalt-ui/charts`) picks WHICH own
|
|
171
|
+
point wins that resolution, reachable as `cursorResolution` on `CartesianChart`/every cartesian
|
|
172
|
+
kind/`DualPanel` and as `useChartCursor`'s `resolution` option — default `'nearest'`, unchanged.
|
|
173
|
+
Reach for `'leading'` when `getX` returns a bucket's LEADING EDGE (a weekly series keyed by its
|
|
174
|
+
Monday, a monthly series keyed by its 1st): under `'nearest'`, a hover landing in the back half
|
|
175
|
+
of a bucket resolves to the FOLLOWING bucket instead of the one it's actually inside, so the
|
|
176
|
+
shared crosshair sits one column right of the data being pointed at — reproducibly, for every
|
|
177
|
+
back-half hover.
|
|
178
|
+
|
|
163
179
|
7. **Keyboard-operable by construction.** The hover overlay `CartesianChart` renders is focusable;
|
|
164
180
|
`←`/`→` scrub the shared cursor one point at a time, `Escape` clears it. The tooltip is
|
|
165
181
|
`aria-live="polite"`. This comes for free from composing `CartesianChart`/`ChartFrame` — nothing
|
|
166
|
-
to wire per chart.
|
|
182
|
+
to wire per chart. That's exactly why `ChartFrame`'s outer container uses `role="group"` on its
|
|
183
|
+
`ariaLabel`, **never** `role="img"`: per the ARIA spec every descendant of a `role="img"`
|
|
184
|
+
element is presentational, which would erase the hover overlay's `role="slider"` from the
|
|
185
|
+
accessibility tree entirely — the label still announces, but the keyboard-scrubbable control
|
|
186
|
+
underneath it becomes unreachable, silently, with no error anywhere. jsdom does not implement
|
|
187
|
+
that pruning, so no `getByRole` test can ever catch this regression; it is a structural rule, not
|
|
188
|
+
a test-covered one. Do not "simplify" `ChartFrame`'s container role back to `img` — it looks like
|
|
189
|
+
a no-op refactor and it is not.
|
|
167
190
|
8. **Theme-aware colors** via `VX.*` tokens + `alpha()`. **Never** a raw hex literal in a chart file.
|
|
168
191
|
**Never** `localStorage.getItem('theme')` — the scheme resolves via CSS vars (see Dark/light
|
|
169
192
|
below).
|
|
@@ -197,6 +220,13 @@ and its crosshair dots entirely):
|
|
|
197
220
|
the crosshair at the plot's top edge instead, which reads better across a column of charts sharing
|
|
198
221
|
one cursor (every tooltip lines up on the same x). Anchoring costs one `getBoundingClientRect` per
|
|
199
222
|
hovered frame, which is why following is the default.
|
|
223
|
+
- `formatHeader?: (key, d) => string` — overrides the tooltip header's date text (also
|
|
224
|
+
`TooltipHeader`'s own `format` prop directly, and the identical seam on `DualPanel`'s
|
|
225
|
+
`formatHeader`, so the two never diverge). Default: today's `fmtTooltipDate` behavior, unchanged.
|
|
226
|
+
The seam exists because `fmtTooltipDate` regexes `YYYY-MM-DD` out of the domain key and builds a
|
|
227
|
+
LOCAL `Date` from it — a UTC ISO key then names a different day than `formatX`, the tooltip badge,
|
|
228
|
+
and every sibling chart, all of which resolve locally; the only prior workaround was carrying a
|
|
229
|
+
local-offset ISO key. Receives the raw `getX` key alongside the hovered datum.
|
|
200
230
|
|
|
201
231
|
Per-series, `SeriesStyle.tooltip: false` means "draw the mark and legend it, but never give it a
|
|
202
232
|
tooltip row" — it lives on the series, not on the kind. `ChartSeries.formatValue` is
|
|
@@ -261,7 +291,10 @@ per-series `getValue` accessors on `ChartSeries<T>`):
|
|
|
261
291
|
- **`MultiLine`** — N series on a shared y-axis (or two, via `y2`): legend-hover dimming, per-series
|
|
262
292
|
synced dots, dashed companion (MA) lines, per-point markers (PR stars / status dots), zones +
|
|
263
293
|
refLines, fixed or auto domain (covers z-score/σ via a fixed symmetric domain + zero refLine).
|
|
264
|
-
Composes `CartesianChart`.
|
|
294
|
+
Composes `CartesianChart`. `ChartSeries.getMarker` returns `{ color?, r?, fillOpacity?, ring? }`
|
|
295
|
+
— `ring` defaults `true` (today's punched-out stroke, unchanged), `ring: false` omits the stroke
|
|
296
|
+
entirely, `fillOpacity` defaults `1`. Existed because a consumer's plain `fillOpacity: 0.7` dots
|
|
297
|
+
were unreproducible after moving their chart onto the kind — the old shape had no seam for either.
|
|
265
298
|
- **`DualPanel`** — top line-pane + bottom signed-histogram pane sharing one x-scale and one cursor;
|
|
266
299
|
optional fill-between two top lines, zones, refLines, per-point markers on the top pane
|
|
267
300
|
(`ChartSeries.getMarker`). Composes `ChartFrame` directly (two panes, not one plot rect). The
|
|
@@ -311,7 +344,7 @@ One object per axis on `CartesianChart` and every kind that composes it — this
|
|
|
311
344
|
```tsx
|
|
312
345
|
y={{
|
|
313
346
|
domain: 'auto', // 'auto' (default) | [min, max] | (data, visible) => [min, max]
|
|
314
|
-
autoMaxFloor: 100, // when 'auto': upper bound is at least this
|
|
347
|
+
autoMaxFloor: 100, // when 'auto': raw upper bound is at least this, clamped BEFORE padding
|
|
315
348
|
autoMinCeil: 0, // when 'auto': lower bound is at most this (Infinity = pad from raw min)
|
|
316
349
|
autoPad: 1.1, // when 'auto': padding multiplier away from the data
|
|
317
350
|
ticks: 5,
|
|
@@ -321,6 +354,15 @@ y={{
|
|
|
321
354
|
}}
|
|
322
355
|
```
|
|
323
356
|
|
|
357
|
+
**Behavior change (2026-08-19) — the one item in this doc that can move an existing chart's
|
|
358
|
+
rendering:** `autoMaxFloor` now clamps the raw upper bound BEFORE padding, mirroring `autoMinCeil`,
|
|
359
|
+
which has always clamped first and padded second — two different laws used to live in one function.
|
|
360
|
+
The old order padded the raw max, then applied the floor last, so when the floor won it landed
|
|
361
|
+
exactly on the axis top with zero headroom: a target line sitting at precisely the floor value was
|
|
362
|
+
glued to the plot edge. Measured case: dataMax 3.2, pad 1.1, floor 6 → axis top was 6.0, is now
|
|
363
|
+
6.6. A consumer relying on the old ordering will see their axis top move — lower the floor or pin
|
|
364
|
+
`domain` explicitly to opt back out.
|
|
365
|
+
|
|
324
366
|
`nice` defaults `false` deliberately: flipping the default would move the domain of every
|
|
325
367
|
already-migrated chart, so it's opt-in per axis.
|
|
326
368
|
|
|
@@ -13,6 +13,26 @@
|
|
|
13
13
|
* since "nearest category" is meaningless.
|
|
14
14
|
*/
|
|
15
15
|
export declare function parseKey(key: string): number | null;
|
|
16
|
+
/**
|
|
17
|
+
* How a foreign key maps onto a chart's own points.
|
|
18
|
+
*
|
|
19
|
+
* `'nearest'` (default) treats every key as a POINT — the foreign key resolves to whichever own
|
|
20
|
+
* point sits closest to it. Correct when a chart's x-domain is a set of instants.
|
|
21
|
+
*
|
|
22
|
+
* `'leading'` treats every key as the LEADING EDGE of a bucket covering `[key, nextKey)` — the
|
|
23
|
+
* foreign key resolves to the LAST own key `<=` it. Use this when a chart's keys are bucket
|
|
24
|
+
* starts (a weekly series keyed by the Monday of each week, a monthly series keyed by the 1st):
|
|
25
|
+
* under `'nearest'`, a target landing in the back half of a bucket resolves to the FOLLOWING
|
|
26
|
+
* bucket instead of the one it's actually inside, and the shared crosshair lands one column off
|
|
27
|
+
* for every back-half hover.
|
|
28
|
+
*
|
|
29
|
+
* The two modes differ at the DOMAIN EDGES too, and deliberately: `'nearest'` tolerates one step
|
|
30
|
+
* past each end (the target is an instant, so the closest point is still a defensible answer),
|
|
31
|
+
* while `'leading'` bounds strictly to `[first, last + step)` — outside that range no bucket
|
|
32
|
+
* CONTAINS the key, and answering with the nearest one would paint a crosshair on a bucket that
|
|
33
|
+
* provably excludes it.
|
|
34
|
+
*/
|
|
35
|
+
export type CursorResolution = 'nearest' | 'leading';
|
|
16
36
|
export type DomainIndex<T> = {
|
|
17
37
|
byKey: Map<string, T>;
|
|
18
38
|
/** Parsed positions, ascending. Empty when the domain isn't parseable. */
|
|
@@ -21,13 +41,17 @@ export type DomainIndex<T> = {
|
|
|
21
41
|
points: T[];
|
|
22
42
|
/** Median spacing — the tolerance within which a foreign key still resolves. */
|
|
23
43
|
step: number;
|
|
44
|
+
/** The resolution strategy this index was built for. */
|
|
45
|
+
resolution: CursorResolution;
|
|
24
46
|
};
|
|
25
47
|
/** Build the lookup structure once per `data` identity. */
|
|
26
|
-
export declare function buildDomainIndex<T>(data: readonly T[], getKey: (d: T) => string): DomainIndex<T>;
|
|
48
|
+
export declare function buildDomainIndex<T>(data: readonly T[], getKey: (d: T) => string, resolution?: CursorResolution): DomainIndex<T>;
|
|
27
49
|
/**
|
|
28
|
-
* The own point a broadcast `key` maps to: exact match first, else
|
|
29
|
-
*
|
|
30
|
-
*
|
|
50
|
+
* The own point a broadcast `key` maps to: exact match first, else — per `index.resolution` — the
|
|
51
|
+
* nearest parsed position or the last position at/before the target, both within one domain step.
|
|
52
|
+
* Out of range → null, so charts over unrelated domains never paint a cursor for each other —
|
|
53
|
+
* which is what makes "shared by default" safe. A categorical (unparseable) domain falls back to
|
|
54
|
+
* exact-match-only in BOTH resolutions, since "nearest"/"leading" over a category is meaningless.
|
|
31
55
|
*/
|
|
32
|
-
export declare function resolveCursorPoint<T>(index: DomainIndex<T>, key: string): T | null;
|
|
56
|
+
export declare function resolveCursorPoint<T>(index: DomainIndex<T>, key: string, resolution?: CursorResolution): T | null;
|
|
33
57
|
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/charts/cursor/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOnD;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;IACrB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,mCAAmC;IACnC,MAAM,EAAE,CAAC,EAAE,CAAA;IACX,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/charts/cursor/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOnD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,SAAS,CAAA;AAEpD,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;IACrB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,mCAAmC;IACnC,MAAM,EAAE,CAAC,EAAE,CAAA;IACX,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAA;IACZ,wDAAwD;IACxD,UAAU,EAAE,gBAAgB,CAAA;CAC7B,CAAA;AAED,2DAA2D;AAC3D,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,IAAI,EAAE,SAAS,CAAC,EAAE,EAClB,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,EACxB,UAAU,GAAE,gBAA4B,GACvC,WAAW,CAAC,CAAC,CAAC,CA8BhB;AAoBD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,EACrB,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,gBAAmC,GAC9C,CAAC,GAAG,IAAI,CA0CV"}
|
|
@@ -6,7 +6,7 @@ function parseKey(key) {
|
|
|
6
6
|
const t = Date.parse(key);
|
|
7
7
|
return Number.isNaN(t) ? null : t;
|
|
8
8
|
}
|
|
9
|
-
function buildDomainIndex(data, getKey) {
|
|
9
|
+
function buildDomainIndex(data, getKey, resolution = "nearest") {
|
|
10
10
|
const byKey = /* @__PURE__ */ new Map();
|
|
11
11
|
const parsed = [];
|
|
12
12
|
let parseable = true;
|
|
@@ -17,7 +17,9 @@ function buildDomainIndex(data, getKey) {
|
|
|
17
17
|
if (value === null) parseable = false;
|
|
18
18
|
else parsed.push({ value, point: d });
|
|
19
19
|
}
|
|
20
|
-
if (!parseable || parsed.length < 2)
|
|
20
|
+
if (!parseable || parsed.length < 2) {
|
|
21
|
+
return { byKey, values: [], points: [], step: 0, resolution };
|
|
22
|
+
}
|
|
21
23
|
parsed.sort((a, b) => a.value - b.value);
|
|
22
24
|
const values = parsed.map((p) => p.value);
|
|
23
25
|
const points = parsed.map((p) => p.point);
|
|
@@ -26,15 +28,34 @@ function buildDomainIndex(data, getKey) {
|
|
|
26
28
|
diffs.push(values[i] - values[i - 1]);
|
|
27
29
|
}
|
|
28
30
|
diffs.sort((a, b) => a - b);
|
|
29
|
-
return { byKey, values, points, step: diffs[Math.floor(diffs.length / 2)] ?? 0 };
|
|
31
|
+
return { byKey, values, points, step: diffs[Math.floor(diffs.length / 2)] ?? 0, resolution };
|
|
32
|
+
}
|
|
33
|
+
function resolveLeading(index, target) {
|
|
34
|
+
let lo = 0;
|
|
35
|
+
let hi = index.values.length - 1;
|
|
36
|
+
let result = 0;
|
|
37
|
+
while (lo <= hi) {
|
|
38
|
+
const mid = lo + hi >> 1;
|
|
39
|
+
if (index.values[mid] <= target) {
|
|
40
|
+
result = mid;
|
|
41
|
+
lo = mid + 1;
|
|
42
|
+
} else {
|
|
43
|
+
hi = mid - 1;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return index.points[result];
|
|
30
47
|
}
|
|
31
|
-
function resolveCursorPoint(index, key) {
|
|
48
|
+
function resolveCursorPoint(index, key, resolution = index.resolution) {
|
|
32
49
|
const exact = index.byKey.get(key);
|
|
33
50
|
if (exact !== void 0) return exact;
|
|
34
51
|
const target = parseKey(key);
|
|
35
52
|
if (target === null || index.values.length === 0) return null;
|
|
36
53
|
const first = index.values[0];
|
|
37
54
|
const last = index.values[index.values.length - 1];
|
|
55
|
+
if (resolution === "leading") {
|
|
56
|
+
if (target < first || target >= last + index.step) return null;
|
|
57
|
+
return resolveLeading(index, target);
|
|
58
|
+
}
|
|
38
59
|
if (target < first - index.step || target > last + index.step) return null;
|
|
39
60
|
let lo = 0;
|
|
40
61
|
let hi = index.values.length - 1;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { KeyboardEvent, PointerEvent } from 'react';
|
|
2
|
+
import type { CursorResolution } from '../cursor/resolve.js';
|
|
2
3
|
/** Viewport-space pointer anchor the tooltip positions against. */
|
|
3
4
|
export type CursorAnchor = {
|
|
4
5
|
x: number;
|
|
@@ -28,12 +29,18 @@ export type ChartCursor<T> = {
|
|
|
28
29
|
* costs nothing while a real bucket change reaches siblings on the same tick rather than a frame
|
|
29
30
|
* late.
|
|
30
31
|
*/
|
|
31
|
-
export declare function useChartCursor<T>({ data, chartId, getKey, xScale, marginLeft, }: {
|
|
32
|
+
export declare function useChartCursor<T>({ data, chartId, getKey, xScale, marginLeft, resolution, }: {
|
|
32
33
|
data: readonly T[];
|
|
33
34
|
chartId: string;
|
|
34
35
|
getKey: (d: T) => string;
|
|
35
36
|
/** Own x scale — maps a domain key to a plot-local x offset. */
|
|
36
37
|
xScale: (key: string) => number | undefined;
|
|
37
38
|
marginLeft: number;
|
|
39
|
+
/**
|
|
40
|
+
* How a sibling's broadcast key resolves against this chart's own points. Default `'nearest'`
|
|
41
|
+
* (point domains). Pass `'leading'` when `getKey` returns a bucket's leading edge (a weekly
|
|
42
|
+
* series keyed by its Monday, a monthly series keyed by its 1st) — see {@link CursorResolution}.
|
|
43
|
+
*/
|
|
44
|
+
resolution?: CursorResolution;
|
|
38
45
|
}): ChartCursor<T>;
|
|
39
46
|
//# sourceMappingURL=useChartCursor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChartCursor.d.ts","sourceRoot":"","sources":["../../../src/charts/hooks/useChartCursor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"useChartCursor.d.ts","sourceRoot":"","sources":["../../../src/charts/hooks/useChartCursor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAIzD,mEAAmE;AACnE,MAAM,MAAM,YAAY,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEnD,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,kGAAkG;IAClG,KAAK,EAAE,CAAC,GAAG,IAAI,CAAA;IACf,kGAAkG;IAClG,QAAQ,EAAE,OAAO,CAAA;IACjB,4EAA4E;IAC5E,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;IAC3B,aAAa,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,cAAc,CAAC,KAAK,IAAI,CAAA;IAC5D,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B,SAAS,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,cAAc,CAAC,KAAK,IAAI,CAAA;IACzD,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB,CAAA;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,EAChC,IAAI,EACJ,OAAO,EACP,MAAM,EACN,MAAM,EACN,UAAU,EACV,UAAsB,GACvB,EAAE;IACD,IAAI,EAAE,SAAS,CAAC,EAAE,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACxB,gEAAgE;IAChE,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;IAC3C,UAAU,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAA;CAC9B,GAAG,WAAW,CAAC,CAAC,CAAC,CAsHjB"}
|
|
@@ -7,7 +7,8 @@ function useChartCursor({
|
|
|
7
7
|
chartId,
|
|
8
8
|
getKey,
|
|
9
9
|
xScale,
|
|
10
|
-
marginLeft
|
|
10
|
+
marginLeft,
|
|
11
|
+
resolution = "nearest"
|
|
11
12
|
}) {
|
|
12
13
|
const store = useCursorStore();
|
|
13
14
|
const cursor = useCursorState();
|
|
@@ -16,7 +17,10 @@ function useChartCursor({
|
|
|
16
17
|
getKeyRef.current = getKey;
|
|
17
18
|
const xScaleRef = useRef(xScale);
|
|
18
19
|
xScaleRef.current = xScale;
|
|
19
|
-
const index = useMemo(
|
|
20
|
+
const index = useMemo(
|
|
21
|
+
() => buildDomainIndex(data, getKeyRef.current, resolution),
|
|
22
|
+
[data, resolution]
|
|
23
|
+
);
|
|
20
24
|
const frameRef = useRef(null);
|
|
21
25
|
const pendingRef = useRef(null);
|
|
22
26
|
useEffect(
|
package/dist/charts/index.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ export { ZoneRects, type ZoneSpec } from './primitives/ZoneRects.js';
|
|
|
29
29
|
export { XZoneRects, type XZoneSpec } from './primitives/XZoneRects.js';
|
|
30
30
|
export { AreaGradient, areaFillUrl } from './primitives/AreaGradient.js';
|
|
31
31
|
export { useChartCursor, type ChartCursor, type CursorAnchor } from './hooks/useChartCursor.js';
|
|
32
|
+
export type { CursorResolution } from './cursor/resolve.js';
|
|
32
33
|
export { useChartSize, type UseChartSizeResult, type ChartSize } from './hooks/useChartSize.js';
|
|
33
34
|
export { fmtAxisDate, fmtTooltipDate } from './utils/format.js';
|
|
34
35
|
export { smartTicks, smartTicksEvery } from './utils/ticks.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/charts/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EACL,EAAE,EACF,KAAK,EACL,KAAK,SAAS,EACd,KAAK,SAAS,EACd,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,WAAW,EACX,KAAK,WAAW,GACjB,MAAM,WAAW,CAAA;AAGlB,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAG5C,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAA;AACnE,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC7F,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EACL,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,YAAY,EACZ,iBAAiB,GAClB,MAAM,UAAU,CAAA;AAGjB,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAC/B,KAAK,UAAU,EACf,KAAK,WAAW,GACjB,MAAM,6BAA6B,CAAA;AACpC,OAAO,EACL,UAAU,EACV,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,QAAQ,EACb,aAAa,GACd,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,WAAW,EACX,KAAK,gBAAgB,EACrB,YAAY,EACZ,KAAK,iBAAiB,GACvB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACxE,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,UAAU,EACV,WAAW,GACZ,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACrF,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,EAAE,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACjE,OAAO,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACpE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAGrE,OAAO,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAC5F,OAAO,EAAE,YAAY,EAAE,KAAK,kBAAkB,EAAE,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAG5F,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC5D,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACxF,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAGhE,OAAO,EACL,SAAS,EACT,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,GACtB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EACL,IAAI,EACJ,KAAK,SAAS,EACd,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,WAAW,GACjB,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACxE,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAA;AAEvE,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAG5D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAM1D,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC3E,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACjG,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EACL,cAAc,EACd,WAAW,EACX,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/charts/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CursorResolution } from '../cursor/resolve.js';
|
|
1
2
|
import type { ChartMargin } from '../../tokens/index.js';
|
|
2
3
|
import type { AxisConfig, CartesianTooltipConfig } from '../primitives/CartesianChart.js';
|
|
3
4
|
import type { ZoneSpec } from '../primitives/ZoneRects.js';
|
|
@@ -88,6 +89,14 @@ export type BarsProps<T> = {
|
|
|
88
89
|
barOpacity?: (d: T, key: string) => number;
|
|
89
90
|
/** X tick count override. Default: as many as fit. */
|
|
90
91
|
xTicks?: number;
|
|
92
|
+
/** X tick label formatter. Default `fmtAxisDate` (DD.MM). */
|
|
93
|
+
formatX?: (key: string) => string;
|
|
94
|
+
/**
|
|
95
|
+
* How a sibling chart's broadcast cursor key resolves against this chart's points. Default
|
|
96
|
+
* `'nearest'`. Pass `'leading'` when `getX` returns a bucket's leading edge (a weekly series
|
|
97
|
+
* keyed by its Monday) — see `CursorResolution`.
|
|
98
|
+
*/
|
|
99
|
+
cursorResolution?: CursorResolution;
|
|
91
100
|
/** `false` disables the tooltip entirely (and with it the crosshair dots). */
|
|
92
101
|
tooltip?: CartesianTooltipConfig<T> | false;
|
|
93
102
|
/** Per-side overrides of the measured margins — the escape hatch, applied last. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Bars.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/Bars.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Bars.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/Bars.tsx"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,8 @@ function BarsInner(props) {
|
|
|
24
24
|
barLayout = "stacked",
|
|
25
25
|
barOpacity,
|
|
26
26
|
xTicks,
|
|
27
|
+
formatX,
|
|
28
|
+
cursorResolution,
|
|
27
29
|
tooltip,
|
|
28
30
|
margin,
|
|
29
31
|
legend,
|
|
@@ -126,6 +128,8 @@ function BarsInner(props) {
|
|
|
126
128
|
y: yConfig,
|
|
127
129
|
...y2 !== void 0 && { y2 },
|
|
128
130
|
...xTicks !== void 0 && { xTicks },
|
|
131
|
+
...formatX !== void 0 && { formatX },
|
|
132
|
+
...cursorResolution !== void 0 && { cursorResolution },
|
|
129
133
|
...zones !== void 0 && { zones },
|
|
130
134
|
...mappedRefLines !== void 0 && { refLines: mappedRefLines },
|
|
131
135
|
...height !== void 0 && { height },
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ZoneSpec } from '../primitives/ZoneRects.js';
|
|
2
|
+
import type { CursorResolution } from '../cursor/resolve.js';
|
|
2
3
|
import type { ChartLegendConfig, ChartSeries } from '../series.js';
|
|
3
4
|
export type DualPanelProps<T> = {
|
|
4
5
|
data: T[];
|
|
@@ -6,6 +7,15 @@ export type DualPanelProps<T> = {
|
|
|
6
7
|
height?: number;
|
|
7
8
|
chartId: string;
|
|
8
9
|
getX: (d: T) => string;
|
|
10
|
+
/** X tick label formatter. Default `fmtAxisDate` (DD.MM) — same default `CartesianChart` uses,
|
|
11
|
+
* so omitting it is byte-identical to today's rendering. */
|
|
12
|
+
formatX?: (key: string) => string;
|
|
13
|
+
/**
|
|
14
|
+
* How a sibling chart's broadcast cursor key resolves against this chart's points. Default
|
|
15
|
+
* `'nearest'`. Pass `'leading'` when `getX` returns a bucket's leading edge (a weekly series
|
|
16
|
+
* keyed by its Monday) — see `CursorResolution`.
|
|
17
|
+
*/
|
|
18
|
+
cursorResolution?: CursorResolution;
|
|
9
19
|
/** 1+ line series in the top pane — the single source of truth for color, dash, legend, and
|
|
10
20
|
* tooltip rows. E.g. acute (solid) / chronic (dashed). */
|
|
11
21
|
series: ChartSeries<T>[];
|
|
@@ -52,6 +62,13 @@ export type DualPanelProps<T> = {
|
|
|
52
62
|
text: string;
|
|
53
63
|
color: string;
|
|
54
64
|
} | null;
|
|
65
|
+
/**
|
|
66
|
+
* Overrides the tooltip header's date text — the same seam `CartesianChart`'s
|
|
67
|
+
* `CartesianTooltipConfig.formatHeader` exposes, so the two don't diverge. Default:
|
|
68
|
+
* `TooltipHeader`'s own `fmtTooltipDate` behavior, unchanged. Receives the raw `getX` key
|
|
69
|
+
* alongside the hovered datum.
|
|
70
|
+
*/
|
|
71
|
+
formatHeader?: (key: string, d: T) => string;
|
|
55
72
|
/** Legend config forwarded to `ChartFrame`; `false` disables the legend (sparkline escape).
|
|
56
73
|
* Default `{ placement: 'bottom' }`. */
|
|
57
74
|
legend?: ChartLegendConfig | false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DualPanel.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/DualPanel.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"DualPanel.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/DualPanel.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAIzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAe,MAAM,WAAW,CAAA;AAK5E,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,IAAI,EAAE,CAAC,EAAE,CAAA;IACT,mFAAmF;IACnF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;gEAC4D;IAC5D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IACjC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC;8DAC0D;IAC1D,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACxB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAA;IACtC,2EAA2E;IAC3E,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACxD,wGAAwG;IACxG,WAAW,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;IAClE,oDAAoD;IACpD,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAA;IACrB,8DAA8D;IAC9D,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,GAAG,IAAI,CAAA;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,gBAAgB,EAAE,MAAM,CAAA;IACxB,gBAAgB,EAAE,MAAM,CAAA;IACxB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;IAChC,+FAA+F;IAC/F,YAAY,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;IACnC;;yFAEqF;IACrF,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACvC;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAA;IACzC;iGAC6F;IAC7F,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,kEAAkE;IAClE,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IAC/D;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IAC5C;4CACwC;IACxC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC,+FAA+F;IAC/F,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4FAA4F;IAC5F,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAID;;;;;;;;;;;GAWG;AACH,iBAAS,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,+BAmClD;AAifD;;;GAGG;AACH,eAAO,MAAM,SAAS,EAA2B,OAAO,cAAc,CAAA"}
|
|
@@ -55,6 +55,9 @@ function DualPanelPlot(props) {
|
|
|
55
55
|
data,
|
|
56
56
|
chartId,
|
|
57
57
|
getX,
|
|
58
|
+
formatX = fmtAxisDate,
|
|
59
|
+
cursorResolution,
|
|
60
|
+
ariaLabel,
|
|
58
61
|
series,
|
|
59
62
|
topYDomain = "auto",
|
|
60
63
|
fillBetween,
|
|
@@ -71,6 +74,7 @@ function DualPanelPlot(props) {
|
|
|
71
74
|
bottomYDomain = "auto",
|
|
72
75
|
bottomMaxAbsFloor,
|
|
73
76
|
tooltipLabel,
|
|
77
|
+
formatHeader,
|
|
74
78
|
plot
|
|
75
79
|
} = props;
|
|
76
80
|
const { hidden } = plot;
|
|
@@ -126,7 +130,7 @@ function DualPanelPlot(props) {
|
|
|
126
130
|
}).labels,
|
|
127
131
|
[bottomDomain, formatBottom, useNiceBottom]
|
|
128
132
|
);
|
|
129
|
-
const xLabelsAll = useMemo(() => data.map((d) =>
|
|
133
|
+
const xLabelsAll = useMemo(() => data.map((d) => formatX(getX(d))), [data, getX, formatX]);
|
|
130
134
|
const margin = useMemo(
|
|
131
135
|
() => autoMargin({ left: [...topLabels, ...bottomLabels], bottom: xLabelsAll }),
|
|
132
136
|
[topLabels, bottomLabels, xLabelsAll]
|
|
@@ -162,7 +166,8 @@ function DualPanelPlot(props) {
|
|
|
162
166
|
chartId,
|
|
163
167
|
getKey: getX,
|
|
164
168
|
xScale,
|
|
165
|
-
marginLeft: margin.left
|
|
169
|
+
marginLeft: margin.left,
|
|
170
|
+
...cursorResolution !== void 0 && { resolution: cursorResolution }
|
|
166
171
|
});
|
|
167
172
|
const tickValues = useMemo(() => smartTicks(data.map(getX), xMax), [data, xMax, getX]);
|
|
168
173
|
const barWidth = data.length > 0 ? Math.max(xMax / data.length * 0.6, 2) : 2;
|
|
@@ -234,6 +239,7 @@ function DualPanelPlot(props) {
|
|
|
234
239
|
if (m === null) continue;
|
|
235
240
|
const cx = xScale(getX(p.__d)) ?? 0;
|
|
236
241
|
const cy = topYScale(p.__y);
|
|
242
|
+
const ring = m.ring ?? true;
|
|
237
243
|
markers.push(
|
|
238
244
|
/* @__PURE__ */ jsx(
|
|
239
245
|
"circle",
|
|
@@ -242,8 +248,8 @@ function DualPanelPlot(props) {
|
|
|
242
248
|
cy,
|
|
243
249
|
r: m.r ?? VX.dotR,
|
|
244
250
|
fill: m.color ?? s.color,
|
|
245
|
-
|
|
246
|
-
strokeWidth: 2
|
|
251
|
+
fillOpacity: m.fillOpacity ?? 1,
|
|
252
|
+
...ring && { stroke: VX.dotStroke, strokeWidth: 2 }
|
|
247
253
|
},
|
|
248
254
|
`mk-${s.key}-${getX(p.__d)}`
|
|
249
255
|
)
|
|
@@ -321,7 +327,13 @@ function DualPanelPlot(props) {
|
|
|
321
327
|
onMove: cursor.onPointerMove,
|
|
322
328
|
onLeave: cursor.onPointerLeave,
|
|
323
329
|
onKeyDown: cursor.onKeyDown,
|
|
324
|
-
onBlur: cursor.onBlur
|
|
330
|
+
onBlur: cursor.onBlur,
|
|
331
|
+
valueMax: Math.max(data.length - 1, 0),
|
|
332
|
+
...point !== null && {
|
|
333
|
+
valueNow: data.indexOf(point),
|
|
334
|
+
valueText: formatX(getX(point))
|
|
335
|
+
},
|
|
336
|
+
...ariaLabel !== void 0 && { ariaLabel }
|
|
325
337
|
}
|
|
326
338
|
)
|
|
327
339
|
] }),
|
|
@@ -359,7 +371,15 @@ function DualPanelPlot(props) {
|
|
|
359
371
|
}
|
|
360
372
|
),
|
|
361
373
|
/* @__PURE__ */ jsx(AxisLeftNumeric, { scale: bottomYScale, numTicks: 3, tickFormat: formatBottom }),
|
|
362
|
-
/* @__PURE__ */ jsx(
|
|
374
|
+
/* @__PURE__ */ jsx(
|
|
375
|
+
AxisBottomDate,
|
|
376
|
+
{
|
|
377
|
+
top: bottomH,
|
|
378
|
+
scale: xScale,
|
|
379
|
+
tickValues,
|
|
380
|
+
tickFormat: formatX
|
|
381
|
+
}
|
|
382
|
+
),
|
|
363
383
|
/* @__PURE__ */ jsx(
|
|
364
384
|
HoverOverlay,
|
|
365
385
|
{
|
|
@@ -377,6 +397,9 @@ function DualPanelPlot(props) {
|
|
|
377
397
|
TooltipHeader,
|
|
378
398
|
{
|
|
379
399
|
date: getX(point),
|
|
400
|
+
...formatHeader !== void 0 && {
|
|
401
|
+
format: (key) => formatHeader(key, point)
|
|
402
|
+
},
|
|
380
403
|
...(() => {
|
|
381
404
|
const lbl = tooltipLabel?.(point) ?? null;
|
|
382
405
|
return lbl !== null ? { label: lbl.text, labelColor: lbl.color } : {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CursorResolution } from '../cursor/resolve.js';
|
|
1
2
|
import type { CartesianTooltipConfig, AxisConfig } from '../primitives/CartesianChart.js';
|
|
2
3
|
import type { XZoneSpec } from '../primitives/XZoneRects.js';
|
|
3
4
|
import type { ZoneSpec } from '../primitives/ZoneRects.js';
|
|
@@ -31,6 +32,14 @@ export type MultiLineProps<T> = {
|
|
|
31
32
|
}[];
|
|
32
33
|
/** Exact number of x ticks. Default: as many as fit. */
|
|
33
34
|
xTicks?: number;
|
|
35
|
+
/** X tick label formatter. Default `fmtAxisDate` (DD.MM). */
|
|
36
|
+
formatX?: (key: string) => string;
|
|
37
|
+
/**
|
|
38
|
+
* How a sibling chart's broadcast cursor key resolves against this chart's points. Default
|
|
39
|
+
* `'nearest'`. Pass `'leading'` when `getX` returns a bucket's leading edge (a weekly series
|
|
40
|
+
* keyed by its Monday) — see `CursorResolution`.
|
|
41
|
+
*/
|
|
42
|
+
cursorResolution?: CursorResolution;
|
|
34
43
|
/** Tooltip config — `label` for a right-aligned header badge, `extraRows` for rows appended
|
|
35
44
|
* after the derived per-series rows. `false` disables the tooltip entirely. */
|
|
36
45
|
tooltip?: CartesianTooltipConfig<T> | false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiLine.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/MultiLine.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sBAAsB,EAAE,UAAU,EAAe,MAAM,8BAA8B,CAAA;AAEnG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAEvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAG/D,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,IAAI,EAAE,CAAC,EAAE,CAAA;IACT,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,oEAAoE;IACpE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;mFAC+E;IAC/E,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACxB;gEAC4D;IAC5D,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;IACjB;kEAC8D;IAC9D,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;IAClB,iFAAiF;IACjF,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAA;IAClB;sBACkB;IAClB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAA;IACpB,wFAAwF;IACxF,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;IAC/D,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;mFAC+E;IAC/E,OAAO,CAAC,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;IAC3C,4DAA4D;IAC5D,WAAW,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAA;IAC/B;4CACwC;IACxC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC,mGAAmG;IACnG,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gGAAgG;IAChG,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AA4BD;;;;;;;;;;;;GAYG;AACH,iBAAS,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,+
|
|
1
|
+
{"version":3,"file":"MultiLine.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/MultiLine.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,KAAK,EAAE,sBAAsB,EAAE,UAAU,EAAe,MAAM,8BAA8B,CAAA;AAEnG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAEvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAG/D,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,IAAI,EAAE,CAAC,EAAE,CAAA;IACT,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,oEAAoE;IACpE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;mFAC+E;IAC/E,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACxB;gEAC4D;IAC5D,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;IACjB;kEAC8D;IAC9D,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;IAClB,iFAAiF;IACjF,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAA;IAClB;sBACkB;IAClB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAA;IACpB,wFAAwF;IACxF,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;IAC/D,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6DAA6D;IAC7D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IACjC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC;mFAC+E;IAC/E,OAAO,CAAC,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;IAC3C,4DAA4D;IAC5D,WAAW,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAA;IAC/B;4CACwC;IACxC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC,mGAAmG;IACnG,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gGAAgG;IAChG,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AA4BD;;;;;;;;;;;;GAYG;AACH,iBAAS,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,+BAoDlD;AAmHD;;;GAGG;AACH,eAAO,MAAM,SAAS,EAA2B,OAAO,cAAc,CAAA"}
|
|
@@ -36,6 +36,8 @@ function MultiLineInner(props) {
|
|
|
36
36
|
xZones,
|
|
37
37
|
refLines,
|
|
38
38
|
xTicks,
|
|
39
|
+
formatX,
|
|
40
|
+
cursorResolution,
|
|
39
41
|
tooltip,
|
|
40
42
|
markerShape = "circle",
|
|
41
43
|
height,
|
|
@@ -60,6 +62,8 @@ function MultiLineInner(props) {
|
|
|
60
62
|
...xZones !== void 0 && { xZones },
|
|
61
63
|
...refLines !== void 0 && { refLines },
|
|
62
64
|
...xTicks !== void 0 && { xTicks },
|
|
65
|
+
...formatX !== void 0 && { formatX },
|
|
66
|
+
...cursorResolution !== void 0 && { cursorResolution },
|
|
63
67
|
...tooltip !== void 0 && { tooltip },
|
|
64
68
|
...height !== void 0 && { height },
|
|
65
69
|
...legend !== void 0 && { legend },
|
|
@@ -102,16 +106,16 @@ function MultiLineMarks({
|
|
|
102
106
|
const cy = scale(p.__y);
|
|
103
107
|
const color = m.color ?? s.color;
|
|
104
108
|
const r = m.r ?? (markerShape === "star" ? STAR_R : VX.dotR);
|
|
109
|
+
const ring = m.ring ?? true;
|
|
110
|
+
const fillOpacity = (m.fillOpacity ?? 1) * op;
|
|
105
111
|
markers.push(
|
|
106
112
|
markerShape === "star" ? /* @__PURE__ */ jsx(
|
|
107
113
|
"path",
|
|
108
114
|
{
|
|
109
115
|
d: starPath(cx, cy, r),
|
|
110
116
|
fill: color,
|
|
111
|
-
|
|
112
|
-
strokeWidth: 1.5,
|
|
113
|
-
fillOpacity: op,
|
|
114
|
-
strokeOpacity: op
|
|
117
|
+
fillOpacity,
|
|
118
|
+
...ring && { stroke: VX.dotStroke, strokeWidth: 1.5, strokeOpacity: op }
|
|
115
119
|
},
|
|
116
120
|
`mk-${s.key}-${getX(p.__d)}`
|
|
117
121
|
) : /* @__PURE__ */ jsx(
|
|
@@ -121,10 +125,8 @@ function MultiLineMarks({
|
|
|
121
125
|
cy,
|
|
122
126
|
r,
|
|
123
127
|
fill: color,
|
|
124
|
-
|
|
125
|
-
strokeWidth: 2,
|
|
126
|
-
fillOpacity: op,
|
|
127
|
-
strokeOpacity: op
|
|
128
|
+
fillOpacity,
|
|
129
|
+
...ring && { stroke: VX.dotStroke, strokeWidth: 2, strokeOpacity: op }
|
|
128
130
|
},
|
|
129
131
|
`mk-${s.key}-${getX(p.__d)}`
|
|
130
132
|
)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CursorResolution } from '../cursor/resolve.js';
|
|
1
2
|
import type { AxisConfig } from '../primitives/CartesianChart.js';
|
|
2
3
|
import type { ChartLegendConfig, ChartSeries } from '../series.js';
|
|
3
4
|
export type StackedAreaProps<T> = {
|
|
@@ -16,6 +17,14 @@ export type StackedAreaProps<T> = {
|
|
|
16
17
|
y?: AxisConfig<T>;
|
|
17
18
|
/** X tick count override. Default: as many as fit. */
|
|
18
19
|
xTicks?: number;
|
|
20
|
+
/** X tick label formatter. Default `fmtAxisDate` (DD.MM). */
|
|
21
|
+
formatX?: (key: string) => string;
|
|
22
|
+
/**
|
|
23
|
+
* How a sibling chart's broadcast cursor key resolves against this chart's points. Default
|
|
24
|
+
* `'nearest'`. Pass `'leading'` when `getX` returns a bucket's leading edge (a weekly series
|
|
25
|
+
* keyed by its Monday) — see `CursorResolution`.
|
|
26
|
+
*/
|
|
27
|
+
cursorResolution?: CursorResolution;
|
|
19
28
|
/** Legend config forwarded to `CartesianChart`; `false` disables the legend (sparkline escape).
|
|
20
29
|
* Default `{ placement: 'bottom' }`. */
|
|
21
30
|
legend?: ChartLegendConfig | false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StackedArea.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/StackedArea.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"StackedArea.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/StackedArea.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,8BAA8B,CAAA;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAE/D,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAChC,IAAI,EAAE,CAAC,EAAE,CAAA;IACT,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;4FACwF;IACxF,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACxB;;;qEAGiE;IACjE,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;IACjB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6DAA6D;IAC7D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IACjC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC;4CACwC;IACxC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gGAAgG;IAChG,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,iBAAS,gBAAgB,CAAC,CAAC,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,+BA+EtD;AA+CD;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAA6B,OAAO,gBAAgB,CAAA"}
|