pond-ts 0.47.0 → 0.48.1
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 +45 -1
- package/dist/batch/time-series.js +13 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,7 +8,9 @@ The `@pond-ts` packages — `pond-ts`, `@pond-ts/react`, `@pond-ts/charts`,
|
|
|
8
8
|
tag, so this file covers them all. Pre-1.0: minor bumps may include new features
|
|
9
9
|
and type-level changes; patch bumps are strictly additive.
|
|
10
10
|
|
|
11
|
-
[Unreleased]: https://github.com/pond-ts/pond/compare/v0.
|
|
11
|
+
[Unreleased]: https://github.com/pond-ts/pond/compare/v0.48.1...HEAD
|
|
12
|
+
[0.48.1]: https://github.com/pond-ts/pond/compare/v0.48.0...v0.48.1
|
|
13
|
+
[0.48.0]: https://github.com/pond-ts/pond/compare/v0.47.0...v0.48.0
|
|
12
14
|
[0.47.0]: https://github.com/pond-ts/pond/compare/v0.46.0...v0.47.0
|
|
13
15
|
[0.46.0]: https://github.com/pjm17971/pond-ts/compare/v0.45.0...v0.46.0
|
|
14
16
|
[0.45.0]: https://github.com/pjm17971/pond-ts/compare/v0.44.1...v0.45.0
|
|
@@ -46,6 +48,48 @@ and type-level changes; patch bumps are strictly additive.
|
|
|
46
48
|
|
|
47
49
|
## [Unreleased]
|
|
48
50
|
|
|
51
|
+
## [0.48.1] — 2026-07-19
|
|
52
|
+
|
|
53
|
+
### Fixed
|
|
54
|
+
|
|
55
|
+
- `smooth(column, 'loess', …)` is now numerically stable on absolute epoch-ms
|
|
56
|
+
timestamps. The local weighted regression is now conditioned on `x` centred at
|
|
57
|
+
the query point; previously the un-centred normal equations lost precision to
|
|
58
|
+
floating-point cancellation (anchors ~1.7e12 → `x²` terms ~3e24). Severity
|
|
59
|
+
scales with (anchor magnitude / window width)²: on finely-spaced series
|
|
60
|
+
(second-level cadence) the fit overshot wildly outside the data range instead
|
|
61
|
+
of smoothing, while coarser day-spaced series erred only subtly. Output is now
|
|
62
|
+
shift-invariant to the time origin. Series built from small integer anchors
|
|
63
|
+
(e.g. in unit tests) were unaffected, which is why this hid.
|
|
64
|
+
|
|
65
|
+
## [0.48.0] — 2026-07-17
|
|
66
|
+
|
|
67
|
+
### Added
|
|
68
|
+
|
|
69
|
+
- **charts:** `<ChartContainer>` gains **`cursorFormat`** — an independent
|
|
70
|
+
format for the **cursor / marker readout** (the crosshair time pill, marker
|
|
71
|
+
axis indicators, annotation auto-labels), separate from the tick-label
|
|
72
|
+
`timeFormat` / `format`. Unlike `timeFormat` (which _owns the labels_ and so
|
|
73
|
+
opts the axis out of the `dateStyle` ladder by design), `cursorFormat` shapes
|
|
74
|
+
only the readout and **keeps the flat / stacked date style** — resolving the
|
|
75
|
+
"one knob, two concerns" bind where the only way to fix the pill was to give
|
|
76
|
+
up the styled axis. A d3 specifier **string** formats uniformly; a
|
|
77
|
+
**function** `(epochMs, { grain, defaultText }) => string` is handed the
|
|
78
|
+
axis's resolved coarse **`TimeGrain`** (`year` … `second`) and the
|
|
79
|
+
grain-aware default text, so it can branch on zoom and pass the default
|
|
80
|
+
through — no re-deriving the grain from the range. New public types
|
|
81
|
+
**`CursorFormat`** / **`TimeGrain`**; `TradingTimeScale` gains
|
|
82
|
+
`readoutFormat(count)` and `grain(count)`.
|
|
83
|
+
|
|
84
|
+
### Fixed
|
|
85
|
+
|
|
86
|
+
- **charts:** the cursor / marker time readout now formats at the axis's
|
|
87
|
+
**own grain** by default instead of d3's multi-scale default — a
|
|
88
|
+
day-or-coarser axis reads a **date** (`Sep 14, 2026`), a sub-day axis reads
|
|
89
|
+
date + clock. Fixes the 0.47.0 flat-axis regression where a daily bar at a
|
|
90
|
+
foreign-timezone midnight rendered as a bare time-of-day (`02 AM`) in the
|
|
91
|
+
crosshair pill (Tidal F-charts-7). Tick labels are unchanged.
|
|
92
|
+
|
|
49
93
|
## [0.47.0] — 2026-07-17
|
|
50
94
|
|
|
51
95
|
### Added
|
|
@@ -187,10 +187,16 @@ function loessAt(x, anchors, values, span) {
|
|
|
187
187
|
let sumWY = 0;
|
|
188
188
|
let sumWXX = 0;
|
|
189
189
|
let sumWXY = 0;
|
|
190
|
+
// Regress in local coordinates centred on the query point (`dx = pointX - x`).
|
|
191
|
+
// Anchors are typically absolute epoch-ms (~1.7e12), so accumulating
|
|
192
|
+
// `pointX * pointX` (~3e24) into the normal equations loses all precision to
|
|
193
|
+
// floating-point cancellation and the fit overshoots wildly. Centring keeps
|
|
194
|
+
// every term small; the fitted value at the query point is then just the
|
|
195
|
+
// intercept, since `dx = 0` there.
|
|
190
196
|
for (let index = start; index < end; index++) {
|
|
191
|
-
const
|
|
197
|
+
const dx = anchors[index] - x;
|
|
192
198
|
const pointY = values[index];
|
|
193
|
-
const distance = Math.abs(
|
|
199
|
+
const distance = Math.abs(dx);
|
|
194
200
|
const ratio = distance / bandwidth;
|
|
195
201
|
const weight = ratio >= 1 ? 0 : (1 - ratio ** 3) ** 3;
|
|
196
202
|
if (weight === 0) {
|
|
@@ -198,10 +204,10 @@ function loessAt(x, anchors, values, span) {
|
|
|
198
204
|
}
|
|
199
205
|
weightedCount += 1;
|
|
200
206
|
sumW += weight;
|
|
201
|
-
sumWX += weight *
|
|
207
|
+
sumWX += weight * dx;
|
|
202
208
|
sumWY += weight * pointY;
|
|
203
|
-
sumWXX += weight *
|
|
204
|
-
sumWXY += weight *
|
|
209
|
+
sumWXX += weight * dx * dx;
|
|
210
|
+
sumWXY += weight * dx * pointY;
|
|
205
211
|
}
|
|
206
212
|
if (weightedCount === 0 || sumW === 0) {
|
|
207
213
|
return undefined;
|
|
@@ -210,9 +216,8 @@ function loessAt(x, anchors, values, span) {
|
|
|
210
216
|
if (Math.abs(denominator) < Number.EPSILON) {
|
|
211
217
|
return sumWY / sumW;
|
|
212
218
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
return intercept + slope * x;
|
|
219
|
+
// Value at the query point: intercept + slope * dx, with dx = 0.
|
|
220
|
+
return (sumWY * sumWXX - sumWX * sumWXY) / denominator;
|
|
216
221
|
}
|
|
217
222
|
function lowerBound(values, target) {
|
|
218
223
|
let low = 0;
|