@pond-ts/charts 0.70.0 → 0.72.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.
@@ -227,9 +227,8 @@ export interface MultiSelectorProps {
227
227
  *
228
228
  * - The shared brush band becomes the **resting cursor**, spanning the snap
229
229
  * block under the pointer (the `sequence` bucket, else the layer's own
230
- * bin/slot), replacing the container's implicit `'line'` default. An
231
- * explicitly chosen cursor — a mounted component, or a legacy `cursor`
232
- * string the consumer actually set — still wins the surface.
230
+ * bin/slot), when no cursor component is mounted for the row. A mounted
231
+ * cursor still wins the surface.
233
232
  * - Hover is **block-scoped**: pointing at any one mark of a block lights
234
233
  * (and reports) every mark in it. Rest and drag share one code path — the
235
234
  * same snap buckets, the same layer session — so what the rest previews and
package/dist/selectors.js CHANGED
@@ -173,9 +173,8 @@ export function Selector({ enabled = true, selected, hovered, onHover, onSelect,
173
173
  *
174
174
  * - The shared brush band becomes the **resting cursor**, spanning the snap
175
175
  * block under the pointer (the `sequence` bucket, else the layer's own
176
- * bin/slot), replacing the container's implicit `'line'` default. An
177
- * explicitly chosen cursor — a mounted component, or a legacy `cursor`
178
- * string the consumer actually set — still wins the surface.
176
+ * bin/slot), when no cursor component is mounted for the row. A mounted
177
+ * cursor still wins the surface.
179
178
  * - Hover is **block-scoped**: pointing at any one mark of a block lights
180
179
  * (and reports) every mark in it. Rest and drag share one code path — the
181
180
  * same snap buckets, the same layer session — so what the rest previews and
package/dist/tracker.d.ts CHANGED
@@ -1,11 +1,10 @@
1
1
  /**
2
- * Cursor geometry helpers — pure functions deciding *what* the cursor draws
3
- * ({@link cursorParts}) and *where* it sits ({@link resolveCursorX}). The marks
2
+ * Cursor geometry helpers — pure functions deciding *where* the cursor sits
3
+ * ({@link resolveCursorX}) and which bucket it shades. The marks
4
4
  * themselves render as an SVG overlay in `Layers` (no cursor canvas); these
5
5
  * helpers stay pure, so they're unit-tested directly.
6
6
  */
7
- import type { Interval } from 'pond-ts';
8
- import type { CursorMode } from './context.js';
7
+ import { Interval } from 'pond-ts';
9
8
  /**
10
9
  * The interval in the sorted, non-overlapping `buckets` that contains `t`
11
10
  * (`begin ≤ t < end`), or `undefined` if `t` falls in no bucket. Binary search —
@@ -39,30 +38,13 @@ export declare function bandRect(buckets: readonly Interval[], t1: number, xScal
39
38
  x0: number;
40
39
  x1: number;
41
40
  } | null;
42
- /** Default cursor mode — the synced vertical line (cursor enabled on the
43
- * container by default; pair with an off-chart readout via `onTrackerChanged`). */
44
- export declare const DEFAULT_CURSOR_MODE: CursorMode;
45
41
  /**
46
- * Decompose a {@link CursorMode} into what it draws: the shared vertical line,
47
- * the per-series dots, and which value chip (if any). The modes are exclusive
48
- * presets — `line` is line-only, `point` / `inline` / `flag` are dot-based with
49
- * no line, `none` draws nothing. `flag` raises a staff from each point to a
50
- * value flag stacked near the top of the row (drawn in `Layers`).
51
- *
52
- * **Superseded by the mounted cursor presets** (`cursors.tsx` — each mode's
53
- * drawing now lives in its component's registered spec): `Layers` no longer
54
- * reads this. Kept, with its tests, for the life of the `cursor` string-prop
55
- * deprecation window as the pinned record of what each mode drew; delete both
56
- * when the modes go.
42
+ * The unit slots `[i, i+1)` of a category axis, from its band scale's domain
43
+ * (`[0, n]`) — the buckets a `<RangeCursor>` snaps to there when no bar layer
44
+ * has published its own (a bar layer's are the same slots). Empty for an
45
+ * empty axis.
57
46
  */
58
- export declare function cursorParts(mode: CursorMode): {
59
- readonly line: boolean;
60
- readonly dots: boolean;
61
- readonly chip: 'none' | 'inline' | 'flag' | 'axis';
62
- /** `region` mode: a shaded **band** over the bucket under the pointer (from
63
- * `cursorSequence`), drawn by `Layers`; no line/dots/chip of its own. */
64
- readonly band: boolean;
65
- };
47
+ export declare function categorySlots(domain: readonly unknown[]): Interval[];
66
48
  /**
67
49
  * The crosshair's plot-pixel x from the tracker inputs. **A live local pointer
68
50
  * always wins:** a chart the user is actively hovering (`hoverX` non-null) shows
@@ -79,8 +61,8 @@ export declare function cursorParts(mode: CursorMode): {
79
61
  *
80
62
  * `null` and `undefined` are **equivalent** — both mean "no controlled position"
81
63
  * (a hovered chart still tracks its pointer; a non-hovered one shows nothing). To
82
- * force a chart to never show a cursor at all, use `cursor="none"`, not
83
- * `trackerPosition={null}`.
64
+ * force a chart to never show a cursor at all, mount no cursor component, rather
65
+ * than relying on `trackerPosition={null}`.
84
66
  */
85
67
  export declare function resolveCursorX(trackerPosition: number | null | undefined, hoverX: number | null, xScale: (time: number) => number): number | null;
86
68
  //# sourceMappingURL=tracker.d.ts.map
package/dist/tracker.js CHANGED
@@ -1,9 +1,10 @@
1
1
  /**
2
- * Cursor geometry helpers — pure functions deciding *what* the cursor draws
3
- * ({@link cursorParts}) and *where* it sits ({@link resolveCursorX}). The marks
2
+ * Cursor geometry helpers — pure functions deciding *where* the cursor sits
3
+ * ({@link resolveCursorX}) and which bucket it shades. The marks
4
4
  * themselves render as an SVG overlay in `Layers` (no cursor canvas); these
5
5
  * helpers stay pure, so they're unit-tested directly.
6
6
  */
7
+ import { Interval } from 'pond-ts';
7
8
  /**
8
9
  * The interval in the sorted, non-overlapping `buckets` that contains `t`
9
10
  * (`begin ≤ t < end`), or `undefined` if `t` falls in no bucket. Binary search —
@@ -70,45 +71,21 @@ export function bandRect(buckets, t1, xScale, plotWidth, t2) {
70
71
  const x1 = Math.min(plotWidth, xScale(span.end));
71
72
  return x1 > x0 ? { x0, x1 } : null;
72
73
  }
73
- /** Default cursor mode — the synced vertical line (cursor enabled on the
74
- * container by default; pair with an off-chart readout via `onTrackerChanged`). */
75
- export const DEFAULT_CURSOR_MODE = 'line';
76
74
  /**
77
- * Decompose a {@link CursorMode} into what it draws: the shared vertical line,
78
- * the per-series dots, and which value chip (if any). The modes are exclusive
79
- * presets — `line` is line-only, `point` / `inline` / `flag` are dot-based with
80
- * no line, `none` draws nothing. `flag` raises a staff from each point to a
81
- * value flag stacked near the top of the row (drawn in `Layers`).
82
- *
83
- * **Superseded by the mounted cursor presets** (`cursors.tsx` — each mode's
84
- * drawing now lives in its component's registered spec): `Layers` no longer
85
- * reads this. Kept, with its tests, for the life of the `cursor` string-prop
86
- * deprecation window as the pinned record of what each mode drew; delete both
87
- * when the modes go.
75
+ * The unit slots `[i, i+1)` of a category axis, from its band scale's domain
76
+ * (`[0, n]`) — the buckets a `<RangeCursor>` snaps to there when no bar layer
77
+ * has published its own (a bar layer's are the same slots). Empty for an
78
+ * empty axis.
88
79
  */
89
- export function cursorParts(mode) {
90
- const base = { line: false, dots: false, chip: 'none', band: false };
91
- switch (mode) {
92
- case 'line':
93
- return { ...base, line: true };
94
- case 'point':
95
- return { ...base, dots: true };
96
- case 'inline':
97
- return { ...base, dots: true, chip: 'inline' };
98
- case 'flag':
99
- return { ...base, dots: true, chip: 'flag' };
100
- case 'crosshair':
101
- // A single reticle (not per-series): `Layers` draws the dashed vertical +
102
- // full-width horizontal lines, the centre dot, and one value pill itself
103
- // (so no generic line/dots here); the x-time pill is on `<XAxis>`.
104
- return { ...base, chip: 'axis' };
105
- case 'region':
106
- // A shaded band over the bucket under the pointer — `Layers` resolves the
107
- // bucket from `cursorBuckets` and draws the rect (cropped through xScale).
108
- return { ...base, band: true };
109
- case 'none':
110
- return { ...base };
80
+ export function categorySlots(domain) {
81
+ const lo = Number(domain[0]);
82
+ const n = Math.max(0, Math.round(Number(domain[1]) - lo));
83
+ const out = [];
84
+ for (let i = 0; i < n; i += 1) {
85
+ const b = lo + i;
86
+ out.push(new Interval({ value: b, start: b, end: b + 1 }));
111
87
  }
88
+ return out;
112
89
  }
113
90
  /**
114
91
  * The crosshair's plot-pixel x from the tracker inputs. **A live local pointer
@@ -126,8 +103,8 @@ export function cursorParts(mode) {
126
103
  *
127
104
  * `null` and `undefined` are **equivalent** — both mean "no controlled position"
128
105
  * (a hovered chart still tracks its pointer; a non-hovered one shows nothing). To
129
- * force a chart to never show a cursor at all, use `cursor="none"`, not
130
- * `trackerPosition={null}`.
106
+ * force a chart to never show a cursor at all, mount no cursor component, rather
107
+ * than relying on `trackerPosition={null}`.
131
108
  */
132
109
  export function resolveCursorX(trackerPosition, hoverX, xScale) {
133
110
  if (hoverX !== null)
@@ -183,13 +183,13 @@ export interface TradingTimeScale {
183
183
  * `02 AM`; a sub-day axis reads date **+** clock). This is the grain-aware
184
184
  * default the crosshair pill, marker indicators, and annotation auto-labels
185
185
  * use — replacing d3's multi-scale default, which showed local time-of-day
186
- * for any off-local-midnight instant. A container `cursorFormat` overrides it.
186
+ * for any off-local-midnight instant. A cursor's `format` overrides it.
187
187
  */
188
188
  readoutFormat(count?: number): (value: number) => string;
189
189
  /**
190
190
  * The axis's resolved **coarse grain** ({@link TimeGrain}) at `count` — the
191
191
  * unit the ticks currently sit on (`year` … `second`), strides collapsed. A
192
- * `cursorFormat` callback receives this so it can branch on the zoom level
192
+ * cursor `format` callback receives this so it can branch on the zoom level
193
193
  * (return a year when zoomed out, a clock when zoomed in) without
194
194
  * re-deriving the ladder the axis already ran.
195
195
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pond-ts/charts",
3
- "version": "0.70.0",
3
+ "version": "0.72.0",
4
4
  "private": false,
5
5
  "description": "Canvas-rendered, streaming-first React time-series charts for pond-ts: line, area, band, bar, scatter, box, candlestick, with cursors, selection and annotations",
6
6
  "keywords": [
@@ -62,8 +62,8 @@
62
62
  "perf": "PERF_BENCH=1 playwright test perf.spec.ts --workers=1"
63
63
  },
64
64
  "peerDependencies": {
65
- "@pond-ts/react": "^0.70.0",
66
- "pond-ts": "^0.70.0",
65
+ "@pond-ts/react": "^0.72.0",
66
+ "pond-ts": "^0.72.0",
67
67
  "react": "^18.0.0 || ^19.0.0"
68
68
  },
69
69
  "devDependencies": {