@pond-ts/charts 0.53.0 → 0.54.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 +900 -4
- package/dist/AreaChart.d.ts +9 -1
- package/dist/AreaChart.js +46 -5
- package/dist/BarChart.d.ts +17 -8
- package/dist/BarChart.js +17 -4
- package/dist/ChartContainer.js +10 -1
- package/dist/LineChart.d.ts +12 -1
- package/dist/LineChart.js +46 -5
- package/dist/XAxis.js +13 -1
- package/dist/affine.d.ts +35 -14
- package/dist/affine.js +34 -17
- package/dist/area.js +4 -4
- package/dist/bars.d.ts +42 -15
- package/dist/bars.js +97 -23
- package/dist/context.d.ts +39 -7
- package/dist/data.d.ts +58 -0
- package/dist/data.js +85 -22
- package/dist/decimate.js +7 -7
- package/dist/elapsed.js +43 -1
- package/dist/line.js +2 -2
- package/package.json +3 -3
package/dist/elapsed.js
CHANGED
|
@@ -94,6 +94,10 @@ export function durationStep(span, count) {
|
|
|
94
94
|
/** Backstop against a pathological (step, domain) pair flooding the axis; the
|
|
95
95
|
* step is derived from the domain span, so a real axis never comes close. */
|
|
96
96
|
const MAX_TICKS = 10_000;
|
|
97
|
+
/** Closest two ticks may sit in pixels before the second is dropped as a
|
|
98
|
+
* duplicate. Only ever fires where a discontinuous base scale collapses a span
|
|
99
|
+
* to a point — a continuous axis spaces its ticks tens of px apart. */
|
|
100
|
+
const MIN_TICK_PX = 1;
|
|
97
101
|
/**
|
|
98
102
|
* Tick values in **absolute axis units** at `origin + k·step`, covering
|
|
99
103
|
* `domain` — the anchored walk that makes `00:05` land exactly five minutes
|
|
@@ -214,6 +218,44 @@ export function scaleElapsed(base, options) {
|
|
|
214
218
|
: s.tickFormat(count);
|
|
215
219
|
return (v) => f(v - origin);
|
|
216
220
|
};
|
|
221
|
+
/**
|
|
222
|
+
* Drop ticks that land on a pixel another tick already claimed. The walk is in
|
|
223
|
+
* **wall-clock** ms, but the base scale need not be continuous: on a trading
|
|
224
|
+
* axis every instant inside a collapsed session maps to the one seam pixel, so
|
|
225
|
+
* a duration ladder striding through a closed market emits several ticks at
|
|
226
|
+
* the *same* x — labels stacked on labels, gridlines stroked on gridlines
|
|
227
|
+
* (issue #540, finding 1). A plain axis is untouched: its ticks are ~65px
|
|
228
|
+
* apart by construction, so nothing is ever within the gap.
|
|
229
|
+
*
|
|
230
|
+
* The survivor is the **last** tick of each pixel group, not the first. Ticks
|
|
231
|
+
* ascend, so a group spans a collapsed gap and ends at the first instant the
|
|
232
|
+
* axis actually draws — the session open. Keeping the first would label the
|
|
233
|
+
* seam with a moment the market was shut: on three 09:30–16:00 sessions the
|
|
234
|
+
* pixel would read `12:00` (21:30 that night) instead of `1d 00:00`, the
|
|
235
|
+
* Tuesday open that genuinely sits there (PR #541 review).
|
|
236
|
+
*/
|
|
237
|
+
const dedupeByPixel = (values) => {
|
|
238
|
+
const r = base.range();
|
|
239
|
+
// Pre-layout the whole range is one pixel wide; nothing is visible, and
|
|
240
|
+
// deduping there would collapse the axis to a single tick.
|
|
241
|
+
if (!(Math.abs(Number(r[1] ?? 0) - Number(r[0] ?? 0)) > 0))
|
|
242
|
+
return [...values];
|
|
243
|
+
const out = [];
|
|
244
|
+
let lastPx = 0;
|
|
245
|
+
for (const v of values) {
|
|
246
|
+
const px = base(v);
|
|
247
|
+
if (!Number.isFinite(px))
|
|
248
|
+
continue;
|
|
249
|
+
if (out.length > 0 && Math.abs(px - lastPx) < MIN_TICK_PX) {
|
|
250
|
+
out[out.length - 1] = v; // same pixel — the later instant wins
|
|
251
|
+
lastPx = px;
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
out.push(v);
|
|
255
|
+
lastPx = px;
|
|
256
|
+
}
|
|
257
|
+
return out;
|
|
258
|
+
};
|
|
217
259
|
const scale = ((value) => base(value));
|
|
218
260
|
Object.assign(scale, {
|
|
219
261
|
origin,
|
|
@@ -223,7 +265,7 @@ export function scaleElapsed(base, options) {
|
|
|
223
265
|
const r = base.range();
|
|
224
266
|
return [Number(r[0] ?? 0), Number(r[1] ?? 0)];
|
|
225
267
|
},
|
|
226
|
-
ticks: (count = DEFAULT_COUNT) => originTicks(bounds(), origin, stepFor(count)),
|
|
268
|
+
ticks: (count = DEFAULT_COUNT) => dedupeByPixel(originTicks(bounds(), origin, stepFor(count))),
|
|
227
269
|
tickFormat: (count = DEFAULT_COUNT, specifier) => {
|
|
228
270
|
if (kind === 'value')
|
|
229
271
|
return offsetFormat(count, specifier);
|
package/dist/line.js
CHANGED
|
@@ -26,8 +26,8 @@ export function strokeAffinePolyline(ctx, xs, ys, ax, ay) {
|
|
|
26
26
|
penDown = false;
|
|
27
27
|
continue;
|
|
28
28
|
}
|
|
29
|
-
const px = ax.
|
|
30
|
-
const py = ay.
|
|
29
|
+
const px = (xs[j] - ax.v0) * ax.k + ax.p0;
|
|
30
|
+
const py = (v - ay.v0) * ay.k + ay.p0;
|
|
31
31
|
if (penDown)
|
|
32
32
|
ctx.lineTo(px, py);
|
|
33
33
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pond-ts/charts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.54.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.54.0",
|
|
42
|
+
"pond-ts": "^0.54.0",
|
|
43
43
|
"react": "^18.0.0 || ^19.0.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|