@pond-ts/charts 0.56.2 → 0.58.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 +1218 -1
- package/dist/AreaChart.d.ts +12 -1
- package/dist/AreaChart.js +131 -13
- package/dist/BarChart.d.ts +84 -9
- package/dist/BarChart.js +295 -40
- package/dist/BarList.d.ts +85 -5
- package/dist/BarList.js +25 -4
- package/dist/BoxList.d.ts +70 -3
- package/dist/BoxList.js +21 -7
- package/dist/BoxPlot.d.ts +2 -1
- package/dist/BoxPlot.js +101 -9
- package/dist/Candlestick.d.ts +13 -1
- package/dist/Candlestick.js +89 -3
- package/dist/ChartContainer.d.ts +79 -48
- package/dist/ChartContainer.js +482 -60
- package/dist/ChartRow.d.ts +9 -2
- package/dist/ChartRow.js +86 -12
- package/dist/HeatMap.d.ts +176 -0
- package/dist/HeatMap.js +344 -0
- package/dist/Layers.d.ts +5 -1
- package/dist/Layers.js +1014 -253
- package/dist/Legend.js +8 -4
- package/dist/LineChart.d.ts +18 -1
- package/dist/LineChart.js +165 -4
- package/dist/ListTable.d.ts +30 -3
- package/dist/ListTable.js +381 -23
- package/dist/ScatterChart.d.ts +3 -2
- package/dist/ScatterChart.js +68 -4
- package/dist/XAxis.js +40 -22
- package/dist/YAxis.d.ts +28 -1
- package/dist/YAxis.js +24 -2
- package/dist/annotations.d.ts +74 -0
- package/dist/annotations.js +97 -7
- package/dist/area.d.ts +34 -1
- package/dist/area.js +88 -1
- package/dist/bars.d.ts +178 -5
- package/dist/bars.js +504 -46
- package/dist/box.d.ts +2 -2
- package/dist/box.js +158 -40
- package/dist/brush.d.ts +142 -0
- package/dist/brush.js +179 -0
- package/dist/child-index.d.ts +27 -0
- package/dist/child-index.js +57 -0
- package/dist/context.d.ts +871 -36
- package/dist/cursors.d.ts +161 -0
- package/dist/cursors.js +503 -0
- package/dist/decimate.d.ts +78 -1
- package/dist/decimate.js +157 -0
- package/dist/heat.d.ts +163 -0
- package/dist/heat.js +659 -0
- package/dist/index.d.ts +13 -4
- package/dist/index.js +25 -2
- package/dist/line.d.ts +137 -0
- package/dist/line.js +328 -0
- package/dist/ohlc.d.ts +16 -1
- package/dist/ohlc.js +93 -4
- package/dist/scatter.d.ts +17 -9
- package/dist/scatter.js +221 -33
- package/dist/select.d.ts +13 -5
- package/dist/select.js +14 -6
- package/dist/selection-fixtures.d.ts +174 -0
- package/dist/selection-fixtures.js +569 -0
- package/dist/selection-stories.d.ts +73 -0
- package/dist/selection-stories.js +301 -0
- package/dist/selectors.d.ts +316 -0
- package/dist/selectors.js +391 -0
- package/dist/span.d.ts +122 -0
- package/dist/span.js +203 -0
- package/dist/sweep.d.ts +154 -0
- package/dist/sweep.js +282 -0
- package/dist/theme.d.ts +517 -11
- package/dist/theme.js +220 -39
- package/dist/tracker.d.ts +6 -0
- package/dist/tracker.js +6 -0
- package/dist/tradingAxis.fixture.d.ts +78 -0
- package/dist/tradingAxis.fixture.js +215 -0
- package/dist/useChartLegend.js +18 -3
- package/package.json +3 -3
package/dist/bars.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { BarSeries, StackedBarSeries } from './data.js';
|
|
2
2
|
import type { Scale } from './line.js';
|
|
3
3
|
import type { BarStyle } from './theme.js';
|
|
4
|
-
import type { LayerDrawStats } from './context.js';
|
|
4
|
+
import type { LayerDrawStats, SpanSelection } from './context.js';
|
|
5
5
|
import { type DecimateOption } from './decimate.js';
|
|
6
6
|
/**
|
|
7
7
|
* Bar growth direction — the histogram orientation. `'vertical'` bars grow **up**
|
|
@@ -56,6 +56,84 @@ export declare function resolveBarBaseline(yScale: Scale): number;
|
|
|
56
56
|
* separates columns visually without carving a dead channel out of the target.
|
|
57
57
|
*/
|
|
58
58
|
export declare function barRect(cs: BarSeries, i: number, xScale: Scale, yScale: Scale, baseline: number, gapPx: number, minWidthPx: number): [x0: number, x1: number, yTop: number, yBottom: number] | null;
|
|
59
|
+
/**
|
|
60
|
+
* The value-space span `[lo, hi]` of **threshold band `k`** along a bar running
|
|
61
|
+
* from `base` to `v`, or `null` when the bar doesn't reach that band.
|
|
62
|
+
*
|
|
63
|
+
* A threshold ladder colours one bar **along its length** — neutral up to the
|
|
64
|
+
* first threshold, then warning, then alarm — so a long bar shows how far
|
|
65
|
+
* through the ladder it travelled rather than only which band it ended in. With
|
|
66
|
+
* `thresholds = [t0, t1]` there are three bands: `[0, t0)`, `[t0, t1)`,
|
|
67
|
+
* `[t1, ∞)`. Band `k` spans magnitudes `[thresholds[k-1] ?? 0, thresholds[k] ??
|
|
68
|
+
* ∞)`, each end clipped to the bar's own magnitude — so a bar that stops inside
|
|
69
|
+
* band 1 yields a truncated band 1 and `null` for band 2.
|
|
70
|
+
*
|
|
71
|
+
* **Breakpoints are absolute data values, not offsets from the baseline** — a
|
|
72
|
+
* `thresholds={[1, 2]}` ladder means "warning above 1, alarm above 2" in the
|
|
73
|
+
* axis's own units, which is what a threshold means everywhere else. They are
|
|
74
|
+
* matched on the **magnitude** and applied to whichever side of zero the bar
|
|
75
|
+
* is on, so a bar hanging below the baseline walks the same ladder downward
|
|
76
|
+
* and a ±3.5 diverging scale bands symmetrically without the caller supplying
|
|
77
|
+
* negative breakpoints. (An asymmetric ladder would need signed breakpoints;
|
|
78
|
+
* deferred until a consumer pulls — see [PND-BANDBAR2].)
|
|
79
|
+
*
|
|
80
|
+
* The painted span is then **clipped to what the bar actually draws**, which
|
|
81
|
+
* is what makes a domain that excludes zero behave: with `<YAxis min={10}>` a
|
|
82
|
+
* bar rests on 10, so a `[1, 2]` ladder leaves it entirely in the top band
|
|
83
|
+
* rather than banding at 11 and 12. Measuring the ladder from the *resolved
|
|
84
|
+
* baseline* instead would silently shift every breakpoint by the axis floor —
|
|
85
|
+
* exactly the class of quiet wrongness this feature exists to remove.
|
|
86
|
+
*
|
|
87
|
+
* Note this is **draw-only geometry**. Hit-testing still treats the bar as one
|
|
88
|
+
* target ({@link barSlotRect} / {@link barAt}), which is the whole reason this
|
|
89
|
+
* is a mark rather than the N-layer overpaint recipe it replaces: one bar keeps
|
|
90
|
+
* one hit region, one stable `mark`, and one legend row.
|
|
91
|
+
*
|
|
92
|
+
* `thresholds` is assumed ascending and finite — {@link normalizeThresholds}
|
|
93
|
+
* enforces that once at the prop boundary rather than per bar per frame.
|
|
94
|
+
*/
|
|
95
|
+
export declare function bandSpan(base: number, v: number, thresholds: readonly number[], k: number): [lo: number, hi: number] | null;
|
|
96
|
+
/**
|
|
97
|
+
* A resolved threshold ladder: ascending `thresholds` (from
|
|
98
|
+
* {@link normalizeThresholds}) paired with the `colors` each band draws in,
|
|
99
|
+
* `colors[k]` for the band above `thresholds[k - 1]`. Assembled by `BarChart`
|
|
100
|
+
* from `<BarChart bandColors>` → {@link BarStyle.bands}, so — like
|
|
101
|
+
* {@link StackStyle} — the draw layer stays theme-free and unit-testable.
|
|
102
|
+
*
|
|
103
|
+
* `colors` is guaranteed `thresholds.length + 1` long by the time it reaches a
|
|
104
|
+
* draw path; a short ladder is resolved (and warned about) at the boundary.
|
|
105
|
+
*/
|
|
106
|
+
export interface BandLadder {
|
|
107
|
+
readonly thresholds: readonly number[];
|
|
108
|
+
readonly colors: readonly string[];
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Validate + freeze a caller's threshold ladder once, at the prop boundary.
|
|
112
|
+
* Returns the ascending, strictly-positive, finite breakpoints — or `null` when
|
|
113
|
+
* there is no usable ladder left, so the caller keeps the flat path.
|
|
114
|
+
*
|
|
115
|
+
* Sorting rather than rejecting an out-of-order ladder is deliberate — the
|
|
116
|
+
* bands are defined by their boundaries, so `[2, 1]` and `[1, 2]` describe the
|
|
117
|
+
* same three bands and there is no second reading to guess at.
|
|
118
|
+
*
|
|
119
|
+
* Three kinds of entry are **dropped**:
|
|
120
|
+
*
|
|
121
|
+
* - **non-finite** — would swallow every band above it;
|
|
122
|
+
* - **negative** — the ladder is walked on the *magnitude* and mirrored onto
|
|
123
|
+
* whichever side of zero the bar is on, so a negative breakpoint has no
|
|
124
|
+
* meaning. Left in, `[-2, -1]` silently clipped every lower band away and
|
|
125
|
+
* painted the whole bar in the final colour — a one-colour bar that looks
|
|
126
|
+
* deliberate (Codex adversarial review). Signed breakpoints are the
|
|
127
|
+
* asymmetric-ladder feature deferred in [PND-BANDBAR2], not this;
|
|
128
|
+
* - **zero** — band 0 already starts at zero, so a `0` breakpoint describes an
|
|
129
|
+
* empty band and shifts every colour by one.
|
|
130
|
+
*
|
|
131
|
+
* Dropping rather than throwing matches how the rest of this prop behaves
|
|
132
|
+
* (a short colour ladder degrades, it doesn't fail), and `BarChart` dev-warns
|
|
133
|
+
* whenever normalization removed anything — a silently-ignored breakpoint is
|
|
134
|
+
* the failure mode this whole feature exists to avoid.
|
|
135
|
+
*/
|
|
136
|
+
export declare function normalizeThresholds(thresholds: readonly number[] | undefined): readonly number[] | null;
|
|
59
137
|
/**
|
|
60
138
|
* The narrowed selection / hover identity a **single-series** bar matches
|
|
61
139
|
* against: the layer's series `id`, the sample's `key` (its `begin`), and — when
|
|
@@ -68,6 +146,21 @@ export interface BarMark {
|
|
|
68
146
|
readonly key: number;
|
|
69
147
|
readonly mark?: string;
|
|
70
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* Stroke a selected mark's outline **inside** its ink rect. Canvas strokes
|
|
151
|
+
* centre on the path, so a plain `strokeRect(x0, yTop, …)` paints
|
|
152
|
+
* `lineWidth / 2` *outside* the rect — which, with the default
|
|
153
|
+
* `outlineWidth: 1.5` against the default `gap: 1`, is enough to bridge the
|
|
154
|
+
* whole inter-bar gap from both sides: a swept run of selected bars fused
|
|
155
|
+
* into one unreadable block (you could not count them). Insetting the path by
|
|
156
|
+
* half the line width keeps every stroked pixel within the bar's own ink, so
|
|
157
|
+
* adjacent selected marks stay separated by exactly the gap the resting bars
|
|
158
|
+
* show. A mark too thin to contain its outline (either dimension
|
|
159
|
+
* `<= lineWidth`) skips the stroke — the highlight fill is already the
|
|
160
|
+
* signal, and an outline wider than the bar would only smear into the
|
|
161
|
+
* neighbours this exists to keep distinct.
|
|
162
|
+
*/
|
|
163
|
+
export declare function strokeSelectedOutline(ctx: CanvasRenderingContext2D, x0: number, x1: number, yTop: number, yBottom: number, lineWidth: number): void;
|
|
71
164
|
/**
|
|
72
165
|
* Fill one rectangle per bar in `cs`, each spanning its key's `[begin, end]`
|
|
73
166
|
* (inset by `gapPx`) from the resolved `baseline` to the value.
|
|
@@ -120,7 +213,7 @@ export interface BarMark {
|
|
|
120
213
|
* repaint them one flat colour; per-bar-coloured layers draw every visible bar.
|
|
121
214
|
* Returns {@link LayerDrawStats} for `onDrawStats`.
|
|
122
215
|
*/
|
|
123
|
-
export declare function drawBars(ctx: CanvasRenderingContext2D, cs: BarSeries, xScale: Scale, yScale: Scale, style: BarStyle, baseline: number, gapPx: number, seriesId: string | undefined, selection: BarMark
|
|
216
|
+
export declare function drawBars(ctx: CanvasRenderingContext2D, cs: BarSeries, xScale: Scale, yScale: Scale, style: BarStyle, baseline: number, gapPx: number, seriesId: string | undefined, selection: readonly BarMark[], hovered: readonly BarMark[], decimate?: DecimateOption, binFills?: readonly (string | undefined)[], banding?: BandLadder, spans?: readonly SpanSelection[]): LayerDrawStats;
|
|
124
217
|
/**
|
|
125
218
|
* The index of the bar whose key span `[begin, end]` contains `time` — the bar
|
|
126
219
|
* **under the cursor** — or `-1` if `time` falls in no bar's span. This is the
|
|
@@ -222,6 +315,80 @@ export interface StackStyle {
|
|
|
222
315
|
* falls back to the group fill.
|
|
223
316
|
*/
|
|
224
317
|
readonly binFills?: readonly (string | undefined)[];
|
|
318
|
+
/**
|
|
319
|
+
* The **selected** segment's fill, and `hover` the pointer-over one — the
|
|
320
|
+
* three-step `fill → hover → highlight` emphasis {@link BarStyle} has always
|
|
321
|
+
* carried and this path used to ignore ([PND-CATEMPH]).
|
|
322
|
+
*
|
|
323
|
+
* **Only applied when there is no meaning-carrying colour to destroy**, i.e.
|
|
324
|
+
* when {@link binFills} is unset. A per-bin-coloured bar keeps its own colour
|
|
325
|
+
* and pops {@link emphasisOpacity} instead — swapping a zone-coloured or
|
|
326
|
+
* direction-coloured bar to one highlight hue would erase what the colour
|
|
327
|
+
* encodes, which is the one *design* exclusion rather than a path accident.
|
|
328
|
+
*
|
|
329
|
+
* The friction this closes wasn't the behaviour, which is defensible: it was
|
|
330
|
+
* that `theme.bar.hover` / `.highlight` were typed, settable, documented as
|
|
331
|
+
* the emphasis channel, and silently did nothing on the most common
|
|
332
|
+
* categorical chart. A theme author set them, saw no change, and had no way
|
|
333
|
+
* to tell whether they were wrong about the colour or about the mechanism.
|
|
334
|
+
*/
|
|
335
|
+
readonly highlight?: string;
|
|
336
|
+
/** See {@link highlight}. Falls back to `highlight` when unset. */
|
|
337
|
+
readonly hover?: string;
|
|
338
|
+
/**
|
|
339
|
+
* Stroke for the selected segment's outline. Defaults to the segment's own
|
|
340
|
+
* resolved fill (the shipped behaviour). Set it to give the category path a
|
|
341
|
+
* themed selection cue that works even where the fill can't change — the
|
|
342
|
+
* `binFills` case, where the alpha pop is otherwise the only signal.
|
|
343
|
+
*/
|
|
344
|
+
readonly selectedOutline?: string;
|
|
345
|
+
/**
|
|
346
|
+
* The alpha a hovered / selected segment pops to. **Default `1`** (the
|
|
347
|
+
* shipped behaviour). Lower it for a subtler emphasis on a dense stack —
|
|
348
|
+
* previously the pop was hard-coded and the only tunable was the resting
|
|
349
|
+
* {@link opacity}, so a theme could not adjust the *difference* between
|
|
350
|
+
* resting and live, only the floor.
|
|
351
|
+
*/
|
|
352
|
+
readonly emphasisOpacity?: number;
|
|
353
|
+
/**
|
|
354
|
+
* Fill for a segment **not** in a non-empty selection set — the themed
|
|
355
|
+
* de-emphasis ([PND-MULTISEL], RFC A2.3). Unset ⇒ nothing dims, so this is
|
|
356
|
+
* opt-in and back-compatible. Unlike {@link highlight}, this **does** apply
|
|
357
|
+
* over {@link binFills}: dimming is about recession, not identity, so a
|
|
358
|
+
* zone-coloured bar can recede without its colour changing meaning — the
|
|
359
|
+
* dimmed value simply replaces it while it is out of the set.
|
|
360
|
+
*/
|
|
361
|
+
readonly dimmed?: string;
|
|
362
|
+
/**
|
|
363
|
+
* Per-group {@link dimmed}, parallel to {@link fills} — the resolved
|
|
364
|
+
* `theme.bar.default.groupsDimmed` ramp. Set only for a **group-ramped**
|
|
365
|
+
* stack; `undefined` falls back to the flat {@link dimmed}.
|
|
366
|
+
*
|
|
367
|
+
* A stack dimmed to one colour stops being a stack — the segment boundaries
|
|
368
|
+
* vanish and the receded bins read as solid blocks, which is exactly the
|
|
369
|
+
* structure a selection wants to keep visible for comparison.
|
|
370
|
+
*/
|
|
371
|
+
readonly dimmedFills?: readonly string[];
|
|
372
|
+
/**
|
|
373
|
+
* Per-group {@link hover}, parallel to {@link fills} — the resolved
|
|
374
|
+
* `theme.bar.default.groupsHover` ramp. Set only for a **group-ramped**
|
|
375
|
+
* stack; `undefined` falls back to the flat {@link hover}.
|
|
376
|
+
*
|
|
377
|
+
* A single hover colour repaints the pointed-at segment in a hue belonging
|
|
378
|
+
* to another group, so hovering erases the ramp exactly where the reader is
|
|
379
|
+
* looking — and block-scoped hover erases the whole bin.
|
|
380
|
+
*/
|
|
381
|
+
readonly hoverFills?: readonly string[];
|
|
382
|
+
/**
|
|
383
|
+
* Whether {@link fills} carry **group identity** (a resolved group ramp)
|
|
384
|
+
* rather than being one repeated role colour.
|
|
385
|
+
*
|
|
386
|
+
* When they do, a selected segment keeps its own fill and the outline plus
|
|
387
|
+
* the receded neighbours are the cue — the same exclusion {@link binFills}
|
|
388
|
+
* already gets, and for the same reason: replacing a meaning-carrying colour
|
|
389
|
+
* with the flat `highlight` destroys the thing the selection is *about*.
|
|
390
|
+
*/
|
|
391
|
+
readonly groupColored?: boolean;
|
|
225
392
|
}
|
|
226
393
|
/** The narrowed selection / hover identity a stacked segment matches against:
|
|
227
394
|
* the series `id`, the bin's `begin` (its `key`), and the group (its `label`).
|
|
@@ -235,14 +402,20 @@ export interface StackMark {
|
|
|
235
402
|
}
|
|
236
403
|
/**
|
|
237
404
|
* The `[min, max]` extent of the **value (stacked) axis**. For a true multi-group
|
|
238
|
-
* stack it is `[
|
|
239
|
-
*
|
|
405
|
+
* stack it is `[minNegTotal, maxPosTotal]` — each bin's positive segments summed
|
|
406
|
+
* upward and its negative segments summed downward, tracked separately
|
|
407
|
+
* ([PND-SIGNSTACK]). For a **single-group** series (`G === 1` — the plain /
|
|
240
408
|
* categorical bar case) it spans the values' own `[min, max]`, so a **negative**
|
|
241
409
|
* bar's floor is in the domain (segments below the baseline stay visible). `0` is
|
|
242
410
|
* always pulled in so the bars rest on a visible baseline (the bar analog of
|
|
243
411
|
* {@link barExtent}). An empty / all-gap series returns `[0, 1]` so the axis still
|
|
244
412
|
* has a usable domain. Feeds the y auto-fit for a vertical histogram, the x
|
|
245
413
|
* auto-fit for a horizontal one.
|
|
414
|
+
*
|
|
415
|
+
* The negative half is new: this used to sum only positives, matching a draw
|
|
416
|
+
* path that dropped negative segments outright. Both halves changed together —
|
|
417
|
+
* an extent that stopped at `0` below would clip the very segments the draw
|
|
418
|
+
* path now emits.
|
|
246
419
|
*/
|
|
247
420
|
export declare function stackValueExtent(ss: StackedBarSeries): [number, number];
|
|
248
421
|
/**
|
|
@@ -299,7 +472,7 @@ export declare function segmentRect(ss: StackedBarSeries, b: number, g: number,
|
|
|
299
472
|
*
|
|
300
473
|
* O(N·G) over bins × groups, one fill (+ optional stroke) per drawn segment.
|
|
301
474
|
*/
|
|
302
|
-
export declare function drawStacks(ctx: CanvasRenderingContext2D, ss: StackedBarSeries, orientation: Orientation, xScale: Scale, yScale: Scale, style: StackStyle, gapPx: number, minSpanPx: number, seriesId: string | undefined, selection: StackMark
|
|
475
|
+
export declare function drawStacks(ctx: CanvasRenderingContext2D, ss: StackedBarSeries, orientation: Orientation, xScale: Scale, yScale: Scale, style: StackStyle, gapPx: number, minSpanPx: number, seriesId: string | undefined, selection: readonly StackMark[], hover: readonly StackMark[], banding?: BandLadder, spans?: readonly SpanSelection[]): void;
|
|
303
476
|
/**
|
|
304
477
|
* Hit-test plot-pixel `(px, py)` against `ss`'s stacked segments — the **first**
|
|
305
478
|
* segment whose rect contains the point, or `null`. The geometry is
|