@pond-ts/charts 0.42.0 → 0.44.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 +164 -1
- package/dist/BarChart.d.ts +24 -2
- package/dist/BarChart.js +106 -23
- package/dist/BoxPlot.d.ts +80 -28
- package/dist/BoxPlot.js +67 -40
- package/dist/CategoryAxis.d.ts +16 -0
- package/dist/CategoryAxis.js +19 -0
- package/dist/ChartContainer.d.ts +56 -1
- package/dist/ChartContainer.js +101 -3
- package/dist/Layers.js +77 -5
- package/dist/ScatterChart.d.ts +33 -6
- package/dist/ScatterChart.js +36 -16
- package/dist/XAxis.js +41 -2
- package/dist/annotations.d.ts +38 -1
- package/dist/annotations.js +68 -25
- package/dist/bandScale.d.ts +57 -0
- package/dist/bandScale.js +67 -0
- package/dist/bars.d.ts +23 -6
- package/dist/bars.js +47 -15
- package/dist/box.d.ts +26 -9
- package/dist/box.js +86 -42
- package/dist/context.d.ts +88 -13
- package/dist/data.d.ts +145 -30
- package/dist/data.js +146 -21
- package/dist/index.d.ts +5 -2
- package/dist/index.js +8 -1
- package/dist/scatter.d.ts +2 -2
- package/dist/scatter.js +8 -5
- package/dist/tracker.d.ts +37 -0
- package/dist/tracker.js +77 -6
- package/package.json +3 -3
package/dist/tracker.js
CHANGED
|
@@ -4,6 +4,72 @@
|
|
|
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
|
+
/**
|
|
8
|
+
* The interval in the sorted, non-overlapping `buckets` that contains `t`
|
|
9
|
+
* (`begin ≤ t < end`), or `undefined` if `t` falls in no bucket. Binary search —
|
|
10
|
+
* the `region` cursor uses it to find the bucket under the pointer.
|
|
11
|
+
*/
|
|
12
|
+
export function bucketAt(buckets, t) {
|
|
13
|
+
let lo = 0;
|
|
14
|
+
let hi = buckets.length - 1;
|
|
15
|
+
while (lo <= hi) {
|
|
16
|
+
const mid = (lo + hi) >> 1;
|
|
17
|
+
const b = buckets[mid];
|
|
18
|
+
if (t < b.begin())
|
|
19
|
+
hi = mid - 1;
|
|
20
|
+
else if (t >= b.end())
|
|
21
|
+
lo = mid + 1;
|
|
22
|
+
else
|
|
23
|
+
return b;
|
|
24
|
+
}
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The `[start, end)` **span** a region cursor covers, in axis units (not pixels —
|
|
29
|
+
* the drag-release callback reports this):
|
|
30
|
+
*
|
|
31
|
+
* - **Snapping** (`buckets` non-empty, `t1` in a bucket): the bucket at `t1`, or —
|
|
32
|
+
* with a drag anchor `t2` — the union of the `t1` and `t2` buckets, so a drag
|
|
33
|
+
* extends **bucket by bucket** either direction. A `t2` in no bucket is ignored.
|
|
34
|
+
* - **Freeform** (`t1` in no bucket — e.g. no `cursorSequence` at all): a drag
|
|
35
|
+
* spans the raw `[t1, t2]`; without a drag (`t2` omitted) there's nothing to
|
|
36
|
+
* shade (the cursor renders as a plain line), so it returns `null`.
|
|
37
|
+
*/
|
|
38
|
+
export function regionSpan(buckets, t1, t2) {
|
|
39
|
+
const a = bucketAt(buckets, t1);
|
|
40
|
+
if (a === undefined) {
|
|
41
|
+
// Freeform: no bucket under t1. A drag spans the raw [t1, t2]; a bare hover
|
|
42
|
+
// has nothing to shade (Layers draws a line for the degenerate region cursor).
|
|
43
|
+
return t2 === undefined
|
|
44
|
+
? null
|
|
45
|
+
: { start: Math.min(t1, t2), end: Math.max(t1, t2) };
|
|
46
|
+
}
|
|
47
|
+
if (t2 === undefined)
|
|
48
|
+
return { start: a.begin(), end: a.end() };
|
|
49
|
+
const b = bucketAt(buckets, t2);
|
|
50
|
+
if (b === undefined)
|
|
51
|
+
return { start: a.begin(), end: a.end() };
|
|
52
|
+
return {
|
|
53
|
+
start: Math.min(a.begin(), b.begin()),
|
|
54
|
+
end: Math.max(a.end(), b.end()),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The pixel band for the `region` cursor: the {@link regionSpan} for `t1` (and an
|
|
59
|
+
* optional drag anchor `t2`), its `[start, end)` mapped through `xScale` and
|
|
60
|
+
* clamped to `[0, plotWidth]`. Returns `null` when there's no span, or when the
|
|
61
|
+
* band has no width — including a span entirely in a **collapsed gap** on a
|
|
62
|
+
* trading-time scale (both edges map to the same pixel), so it draws nothing
|
|
63
|
+
* there rather than a zero-width sliver.
|
|
64
|
+
*/
|
|
65
|
+
export function bandRect(buckets, t1, xScale, plotWidth, t2) {
|
|
66
|
+
const span = regionSpan(buckets, t1, t2);
|
|
67
|
+
if (span === null)
|
|
68
|
+
return null;
|
|
69
|
+
const x0 = Math.max(0, xScale(span.start));
|
|
70
|
+
const x1 = Math.min(plotWidth, xScale(span.end));
|
|
71
|
+
return x1 > x0 ? { x0, x1 } : null;
|
|
72
|
+
}
|
|
7
73
|
/** Default cursor mode — the synced vertical line (cursor enabled on the
|
|
8
74
|
* container by default; pair with an off-chart readout via `onTrackerChanged`). */
|
|
9
75
|
export const DEFAULT_CURSOR_MODE = 'line';
|
|
@@ -15,22 +81,27 @@ export const DEFAULT_CURSOR_MODE = 'line';
|
|
|
15
81
|
* value flag stacked near the top of the row (drawn in `Layers`).
|
|
16
82
|
*/
|
|
17
83
|
export function cursorParts(mode) {
|
|
84
|
+
const base = { line: false, dots: false, chip: 'none', band: false };
|
|
18
85
|
switch (mode) {
|
|
19
86
|
case 'line':
|
|
20
|
-
return { line: true
|
|
87
|
+
return { ...base, line: true };
|
|
21
88
|
case 'point':
|
|
22
|
-
return {
|
|
89
|
+
return { ...base, dots: true };
|
|
23
90
|
case 'inline':
|
|
24
|
-
return {
|
|
91
|
+
return { ...base, dots: true, chip: 'inline' };
|
|
25
92
|
case 'flag':
|
|
26
|
-
return {
|
|
93
|
+
return { ...base, dots: true, chip: 'flag' };
|
|
27
94
|
case 'crosshair':
|
|
28
95
|
// A single reticle (not per-series): `Layers` draws the dashed vertical +
|
|
29
96
|
// full-width horizontal lines, the centre dot, and one value pill itself
|
|
30
97
|
// (so no generic line/dots here); the x-time pill is on `<XAxis>`.
|
|
31
|
-
return {
|
|
98
|
+
return { ...base, chip: 'axis' };
|
|
99
|
+
case 'region':
|
|
100
|
+
// A shaded band over the bucket under the pointer — `Layers` resolves the
|
|
101
|
+
// bucket from `cursorBuckets` and draws the rect (cropped through xScale).
|
|
102
|
+
return { ...base, band: true };
|
|
32
103
|
case 'none':
|
|
33
|
-
return {
|
|
104
|
+
return { ...base };
|
|
34
105
|
}
|
|
35
106
|
}
|
|
36
107
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pond-ts/charts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Canvas-rendered, streaming-first time-series charts for pond-ts",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"perf": "PERF_BENCH=1 playwright test perf.spec.ts --workers=1"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"@pond-ts/react": "^0.
|
|
42
|
-
"pond-ts": "^0.
|
|
41
|
+
"@pond-ts/react": "^0.44.0",
|
|
42
|
+
"pond-ts": "^0.44.0",
|
|
43
43
|
"react": "^18.0.0 || ^19.0.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|