@pibbl/core 0.0.2 → 0.0.3-alpha.90.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/THIRD_PARTY_NOTICES.txt +81 -0
- package/dist/features/textures/index.d.ts +12 -2
- package/dist/features/textures/index.js +33 -1
- package/dist/features/textures/index.js.map +2 -2
- package/dist/features/textures/lib/chemical-field.d.ts +56 -0
- package/dist/features/textures/lib/chemical-field.js +154 -0
- package/dist/features/textures/lib/chemical-field.js.map +7 -0
- package/dist/features/textures/lib/chemical-recipes.d.ts +119 -0
- package/dist/features/textures/lib/chemical-recipes.js +275 -0
- package/dist/features/textures/lib/chemical-recipes.js.map +7 -0
- package/dist/features/textures/lib/definitions.d.ts +3 -18
- package/dist/features/textures/lib/definitions.js +15 -20
- package/dist/features/textures/lib/definitions.js.map +2 -2
- package/dist/features/textures/lib/geometric-patterns.d.ts +149 -0
- package/dist/features/textures/lib/geometric-patterns.js +305 -0
- package/dist/features/textures/lib/geometric-patterns.js.map +7 -0
- package/dist/features/textures/lib/gray-scott.d.ts +55 -0
- package/dist/features/textures/lib/gray-scott.js +39 -0
- package/dist/features/textures/lib/gray-scott.js.map +7 -0
- package/dist/features/textures/lib/patterns.d.ts +123 -0
- package/dist/features/textures/lib/patterns.js +344 -0
- package/dist/features/textures/lib/patterns.js.map +7 -0
- package/dist/features/textures/lib/reaction-diffusion.d.ts +3 -2
- package/dist/features/textures/lib/reaction-diffusion.js +9 -20
- package/dist/features/textures/lib/reaction-diffusion.js.map +2 -2
- package/dist/features/textures/lib/simulation.d.ts +10 -4
- package/dist/features/textures/lib/simulation.js +23 -13
- package/dist/features/textures/lib/simulation.js.map +2 -2
- package/dist/features/viz/index.d.ts +68 -6
- package/dist/features/viz/index.js +164 -2
- package/dist/features/viz/index.js.map +2 -2
- package/dist/features/viz/inspection/bar.d.ts +79 -0
- package/dist/features/viz/inspection/bar.js +49 -0
- package/dist/features/viz/inspection/bar.js.map +7 -0
- package/dist/features/viz/inspection/candle.d.ts +156 -0
- package/dist/features/viz/inspection/candle.js +120 -0
- package/dist/features/viz/inspection/candle.js.map +7 -0
- package/dist/features/viz/inspection/capture-types.d.ts +65 -0
- package/dist/features/viz/inspection/capture.d.ts +16 -0
- package/dist/features/viz/inspection/capture.js +49 -0
- package/dist/features/viz/inspection/capture.js.map +7 -0
- package/dist/features/viz/inspection/handler.d.ts +36 -0
- package/dist/features/viz/inspection/handler.js +91 -0
- package/dist/features/viz/inspection/handler.js.map +7 -0
- package/dist/features/viz/inspection/ohlc-bar.d.ts +132 -0
- package/dist/features/viz/inspection/ohlc-bar.js +118 -0
- package/dist/features/viz/inspection/ohlc-bar.js.map +7 -0
- package/dist/features/viz/inspection/owned-ref.d.ts +16 -0
- package/dist/features/viz/inspection/owned-ref.js +99 -0
- package/dist/features/viz/inspection/owned-ref.js.map +7 -0
- package/dist/features/viz/inspection/painted-point.d.ts +22 -0
- package/dist/features/viz/inspection/painted-point.js +29 -0
- package/dist/features/viz/inspection/painted-point.js.map +7 -0
- package/dist/features/viz/inspection/queries.d.ts +100 -0
- package/dist/features/viz/inspection/queries.js +192 -0
- package/dist/features/viz/inspection/queries.js.map +7 -0
- package/dist/features/viz/inspection/query-types.d.ts +177 -0
- package/dist/features/viz/inspection/volume.d.ts +104 -0
- package/dist/features/viz/inspection/volume.js +95 -0
- package/dist/features/viz/inspection/volume.js.map +7 -0
- package/dist/features/viz/inspection.d.ts +19 -0
- package/dist/features/viz/inspection.js +54 -0
- package/dist/features/viz/inspection.js.map +7 -0
- package/dist/features/viz/inspection.mjs +1 -0
- package/dist/features/viz/lib/area-series.d.ts +62 -0
- package/dist/features/viz/lib/area-series.js +120 -0
- package/dist/features/viz/lib/area-series.js.map +7 -0
- package/dist/features/viz/lib/axis.js +1 -1
- package/dist/features/viz/lib/axis.js.map +2 -2
- package/dist/features/viz/lib/bar-series.d.ts +3 -1
- package/dist/features/viz/lib/bar-series.js +16 -1
- package/dist/features/viz/lib/bar-series.js.map +2 -2
- package/dist/features/viz/lib/baseline-series.d.ts +55 -0
- package/dist/features/viz/lib/baseline-series.js +136 -0
- package/dist/features/viz/lib/baseline-series.js.map +7 -0
- package/dist/features/viz/lib/candlestick-series.d.ts +62 -0
- package/dist/features/viz/lib/candlestick-series.js +150 -0
- package/dist/features/viz/lib/candlestick-series.js.map +7 -0
- package/dist/features/viz/lib/censored-point-series.d.ts +71 -0
- package/dist/features/viz/lib/censored-point-series.js +129 -0
- package/dist/features/viz/lib/censored-point-series.js.map +7 -0
- package/dist/features/viz/lib/color-context.d.ts +4 -0
- package/dist/features/viz/lib/color-context.js +41 -0
- package/dist/features/viz/lib/color-context.js.map +7 -0
- package/dist/features/viz/lib/color-math.d.ts +4 -0
- package/dist/features/viz/lib/color-math.js +31 -0
- package/dist/features/viz/lib/color-math.js.map +7 -0
- package/dist/features/viz/lib/color-types.d.ts +53 -0
- package/dist/features/viz/lib/curve-definition.d.ts +49 -0
- package/dist/features/viz/lib/curve-definition.js +148 -0
- package/dist/features/viz/lib/curve-definition.js.map +7 -0
- package/dist/features/viz/lib/diverging-color-scale.d.ts +11 -0
- package/dist/features/viz/lib/diverging-color-scale.js +51 -0
- package/dist/features/viz/lib/diverging-color-scale.js.map +7 -0
- package/dist/features/viz/lib/domain-navigation.d.ts +40 -0
- package/dist/features/viz/lib/domain-navigation.js +77 -0
- package/dist/features/viz/lib/domain-navigation.js.map +7 -0
- package/dist/features/viz/lib/editable-chart-elements.d.ts +178 -0
- package/dist/features/viz/lib/editable-chart-elements.js +733 -0
- package/dist/features/viz/lib/editable-chart-elements.js.map +7 -0
- package/dist/features/viz/lib/financial-aggregation.d.ts +127 -0
- package/dist/features/viz/lib/financial-aggregation.js +116 -0
- package/dist/features/viz/lib/financial-aggregation.js.map +7 -0
- package/dist/features/viz/lib/financial-autoscale.d.ts +64 -0
- package/dist/features/viz/lib/financial-autoscale.js +61 -0
- package/dist/features/viz/lib/financial-autoscale.js.map +7 -0
- package/dist/features/viz/lib/financial-comparison.d.ts +62 -0
- package/dist/features/viz/lib/financial-comparison.js +98 -0
- package/dist/features/viz/lib/financial-comparison.js.map +7 -0
- package/dist/features/viz/lib/financial-geometry.d.ts +77 -0
- package/dist/features/viz/lib/financial-geometry.js +67 -0
- package/dist/features/viz/lib/financial-geometry.js.map +7 -0
- package/dist/features/viz/lib/financial-indicators.d.ts +114 -0
- package/dist/features/viz/lib/financial-indicators.js +135 -0
- package/dist/features/viz/lib/financial-indicators.js.map +7 -0
- package/dist/features/viz/lib/financial-oscillators.d.ts +171 -0
- package/dist/features/viz/lib/financial-oscillators.js +265 -0
- package/dist/features/viz/lib/financial-oscillators.js.map +7 -0
- package/dist/features/viz/lib/graph/bipartite.d.ts +14 -0
- package/dist/features/viz/lib/graph/bipartite.js +250 -0
- package/dist/features/viz/lib/graph/bipartite.js.map +7 -0
- package/dist/features/viz/lib/graph/chord.d.ts +44 -0
- package/dist/features/viz/lib/graph/chord.js +348 -0
- package/dist/features/viz/lib/graph/chord.js.map +7 -0
- package/dist/features/viz/lib/graph/dependency.d.ts +26 -0
- package/dist/features/viz/lib/graph/dependency.js +141 -0
- package/dist/features/viz/lib/graph/dependency.js.map +7 -0
- package/dist/features/viz/lib/graph/force.d.ts +28 -0
- package/dist/features/viz/lib/graph/force.js +580 -0
- package/dist/features/viz/lib/graph/force.js.map +7 -0
- package/dist/features/viz/lib/graph/hierarchy.d.ts +21 -0
- package/dist/features/viz/lib/graph/hierarchy.js +112 -0
- package/dist/features/viz/lib/graph/hierarchy.js.map +7 -0
- package/dist/features/viz/lib/graph/icicle.d.ts +16 -0
- package/dist/features/viz/lib/graph/icicle.js +153 -0
- package/dist/features/viz/lib/graph/icicle.js.map +7 -0
- package/dist/features/viz/lib/graph/matrix.d.ts +30 -0
- package/dist/features/viz/lib/graph/matrix.js +243 -0
- package/dist/features/viz/lib/graph/matrix.js.map +7 -0
- package/dist/features/viz/lib/graph/neighborhood.d.ts +11 -0
- package/dist/features/viz/lib/graph/neighborhood.js +281 -0
- package/dist/features/viz/lib/graph/neighborhood.js.map +7 -0
- package/dist/features/viz/lib/graph/routes.d.ts +35 -0
- package/dist/features/viz/lib/graph/routes.js +102 -0
- package/dist/features/viz/lib/graph/routes.js.map +7 -0
- package/dist/features/viz/lib/graph/sankey.d.ts +44 -0
- package/dist/features/viz/lib/graph/sankey.js +341 -0
- package/dist/features/viz/lib/graph/sankey.js.map +7 -0
- package/dist/features/viz/lib/graph/shared.d.ts +59 -0
- package/dist/features/viz/lib/graph/shared.js +296 -0
- package/dist/features/viz/lib/graph/shared.js.map +7 -0
- package/dist/features/viz/lib/graph/tree.d.ts +11 -0
- package/dist/features/viz/lib/graph/tree.js +232 -0
- package/dist/features/viz/lib/graph/tree.js.map +7 -0
- package/dist/features/viz/lib/graph/treemap.d.ts +20 -0
- package/dist/features/viz/lib/graph/treemap.js +227 -0
- package/dist/features/viz/lib/graph/treemap.js.map +7 -0
- package/dist/features/viz/lib/graph/types.d.ts +1097 -0
- package/dist/features/viz/lib/hover-data.d.ts +1 -1
- package/dist/features/viz/lib/hover-data.js +5 -2
- package/dist/features/viz/lib/hover-data.js.map +2 -2
- package/dist/features/viz/lib/interval-band-series.d.ts +49 -0
- package/dist/features/viz/lib/interval-band-series.js +136 -0
- package/dist/features/viz/lib/interval-band-series.js.map +7 -0
- package/dist/features/viz/lib/interval-diamond-series.d.ts +43 -0
- package/dist/features/viz/lib/interval-diamond-series.js +124 -0
- package/dist/features/viz/lib/interval-diamond-series.js.map +7 -0
- package/dist/features/viz/lib/interval-series.d.ts +79 -0
- package/dist/features/viz/lib/interval-series.js +158 -0
- package/dist/features/viz/lib/interval-series.js.map +7 -0
- package/dist/features/viz/lib/line-series.d.ts +1 -1
- package/dist/features/viz/lib/line-series.js +47 -28
- package/dist/features/viz/lib/line-series.js.map +2 -2
- package/dist/features/viz/lib/linear-scale.js +1 -1
- package/dist/features/viz/lib/linear-scale.js.map +2 -2
- package/dist/features/viz/lib/monotone-curve.d.ts +11 -0
- package/dist/features/viz/lib/monotone-curve.js +63 -0
- package/dist/features/viz/lib/monotone-curve.js.map +7 -0
- package/dist/features/viz/lib/numeric-range-interpolation.d.ts +15 -0
- package/dist/features/viz/lib/numeric-range-interpolation.js +36 -0
- package/dist/features/viz/lib/numeric-range-interpolation.js.map +7 -0
- package/dist/features/viz/lib/ohlc-bar-series.d.ts +55 -0
- package/dist/features/viz/lib/ohlc-bar-series.js +168 -0
- package/dist/features/viz/lib/ohlc-bar-series.js.map +7 -0
- package/dist/features/viz/lib/paired-series.d.ts +44 -0
- package/dist/features/viz/lib/paired-series.js +93 -0
- package/dist/features/viz/lib/paired-series.js.map +7 -0
- package/dist/features/viz/lib/plot-series.js +11 -6
- package/dist/features/viz/lib/plot-series.js.map +2 -2
- package/dist/features/viz/lib/plot-types.d.ts +4 -3
- package/dist/features/viz/lib/point-series.d.ts +1 -1
- package/dist/features/viz/lib/point-series.js +36 -9
- package/dist/features/viz/lib/point-series.js.map +2 -2
- package/dist/features/viz/lib/point-types.d.ts +5 -2
- package/dist/features/viz/lib/scale-context.d.ts +1 -1
- package/dist/features/viz/lib/scale-ticks.js +21 -6
- package/dist/features/viz/lib/scale-ticks.js.map +2 -2
- package/dist/features/viz/lib/sequential-color-scale.d.ts +11 -0
- package/dist/features/viz/lib/sequential-color-scale.js +49 -0
- package/dist/features/viz/lib/sequential-color-scale.js.map +7 -0
- package/dist/features/viz/lib/series-position.d.ts +12 -0
- package/dist/features/viz/lib/series-position.js +44 -0
- package/dist/features/viz/lib/series-position.js.map +7 -0
- package/dist/features/viz/lib/step-curves.d.ts +19 -0
- package/dist/features/viz/lib/step-curves.js +53 -0
- package/dist/features/viz/lib/step-curves.js.map +7 -0
- package/dist/features/viz/lib/threshold-color-scale.d.ts +43 -0
- package/dist/features/viz/lib/threshold-color-scale.js +59 -0
- package/dist/features/viz/lib/threshold-color-scale.js.map +7 -0
- package/dist/features/viz/lib/trading-time-mapping.d.ts +32 -0
- package/dist/features/viz/lib/trading-time-mapping.js +89 -0
- package/dist/features/viz/lib/trading-time-mapping.js.map +7 -0
- package/dist/features/viz/lib/trading-time-scale.d.ts +83 -0
- package/dist/features/viz/lib/trading-time-scale.js +96 -0
- package/dist/features/viz/lib/trading-time-scale.js.map +7 -0
- package/dist/features/viz/lib/trajectory-series.d.ts +71 -0
- package/dist/features/viz/lib/trajectory-series.js +111 -0
- package/dist/features/viz/lib/trajectory-series.js.map +7 -0
- package/dist/features/viz/lib/types.d.ts +20 -4
- package/dist/features/viz/lib/use-continuous-scale.js +6 -1
- package/dist/features/viz/lib/use-continuous-scale.js.map +2 -2
- package/dist/features/viz/lib/volume-series.d.ts +59 -0
- package/dist/features/viz/lib/volume-series.js +117 -0
- package/dist/features/viz/lib/volume-series.js.map +7 -0
- package/dist/features/viz/lib/weighted-point-series.d.ts +71 -0
- package/dist/features/viz/lib/weighted-point-series.js +169 -0
- package/dist/features/viz/lib/weighted-point-series.js.map +7 -0
- package/dist/filters/backdrop-contrast-gpu.d.ts +5 -0
- package/dist/filters/backdrop-contrast-gpu.js +33 -0
- package/dist/filters/backdrop-contrast-gpu.js.map +7 -0
- package/dist/filters/backdrop-contrast.d.ts +21 -0
- package/dist/filters/backdrop-contrast.js +61 -0
- package/dist/filters/backdrop-contrast.js.map +7 -0
- package/dist/filters/emboss-gpu.d.ts +4 -0
- package/dist/filters/emboss-gpu.js +39 -0
- package/dist/filters/emboss-gpu.js.map +7 -0
- package/dist/filters/emboss.d.ts +32 -0
- package/dist/filters/emboss.js +106 -0
- package/dist/filters/emboss.js.map +7 -0
- package/dist/filters/filter-executor.d.ts +11 -4
- package/dist/filters/filter-executor.js +104 -49
- package/dist/filters/filter-executor.js.map +2 -2
- package/dist/filters/reflection-gpu.d.ts +3 -1
- package/dist/filters/reflection-gpu.js +5 -2
- package/dist/filters/reflection-gpu.js.map +2 -2
- package/dist/filters/render-backdrop-contrast-boundary.d.ts +31 -0
- package/dist/filters/render-backdrop-contrast-boundary.js +116 -0
- package/dist/filters/render-backdrop-contrast-boundary.js.map +7 -0
- package/dist/filters/render-emboss-boundary.d.ts +13 -0
- package/dist/filters/render-emboss-boundary.js +131 -0
- package/dist/filters/render-emboss-boundary.js.map +7 -0
- package/dist/filters.d.ts +9 -5
- package/dist/filters.js +4 -0
- package/dist/filters.js.map +2 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +2 -2
- package/dist/internal.d.ts +2 -0
- package/dist/internal.js +4 -0
- package/dist/internal.js.map +2 -2
- package/dist/lib/events/event-facade.d.ts +13 -0
- package/dist/lib/events/event-facade.js +23 -0
- package/dist/lib/events/event-facade.js.map +2 -2
- package/dist/lib/events/propagation.js +19 -14
- package/dist/lib/events/propagation.js.map +2 -2
- package/dist/lib/execute-render.js +13 -0
- package/dist/lib/execute-render.js.map +2 -2
- package/dist/lib/recording/recording.d.ts +43 -0
- package/dist/lib/recording/recording.js +555 -0
- package/dist/lib/recording/recording.js.map +7 -0
- package/dist/lib/recording/types.d.ts +118 -0
- package/dist/lib/recording/wasm-bytes.d.ts +1 -0
- package/dist/lib/recording/wasm-bytes.js +5 -0
- package/dist/lib/recording/wasm-bytes.js.map +7 -0
- package/dist/lib/recording/worker-source.d.ts +1 -0
- package/dist/lib/recording/worker-source.js +5 -0
- package/dist/lib/recording/worker-source.js.map +7 -0
- package/dist/lib/render-transaction.d.ts +5 -2
- package/dist/lib/render-transaction.js +23 -1
- package/dist/lib/render-transaction.js.map +2 -2
- package/dist/lib/series-inspection-frame.d.ts +18 -0
- package/dist/lib/series-inspection-frame.js +70 -0
- package/dist/lib/series-inspection-frame.js.map +7 -0
- package/dist/lib/types.d.ts +6 -0
- package/package.json +10 -2
|
@@ -1,21 +1,35 @@
|
|
|
1
1
|
import { resolveSignalValue } from "@pibbl/core";
|
|
2
2
|
function ticks(scale, props) {
|
|
3
3
|
if (props.tickValues !== void 0 && props.tickCount !== void 0)
|
|
4
|
-
throw new TypeError(
|
|
4
|
+
throw new TypeError(
|
|
5
|
+
"Axis tickValues and tickCount are mutually exclusive."
|
|
6
|
+
);
|
|
5
7
|
const explicit = props.tickValues === void 0 ? void 0 : resolveSignalValue(props.tickValues);
|
|
6
8
|
if (explicit !== void 0) {
|
|
7
9
|
if (!Array.isArray(explicit) || explicit.length > 100)
|
|
8
|
-
throw new RangeError(
|
|
10
|
+
throw new RangeError(
|
|
11
|
+
"Axis tickValues must be an array with at most 100 values."
|
|
12
|
+
);
|
|
9
13
|
const seen = /* @__PURE__ */ new Set();
|
|
10
14
|
for (const value of explicit) {
|
|
11
|
-
if (seen.has(value))
|
|
15
|
+
if (seen.has(value))
|
|
16
|
+
throw new RangeError("Axis tickValues must not contain duplicates.");
|
|
12
17
|
seen.add(value);
|
|
13
|
-
if (scale.type
|
|
18
|
+
if (scale.type === "trading-time") {
|
|
19
|
+
if (typeof value !== "number" || scale.slotAtTime(value) === void 0)
|
|
20
|
+
throw new RangeError(
|
|
21
|
+
"Axis trading-time ticks must be supplied timestamps."
|
|
22
|
+
);
|
|
23
|
+
} else if (scale.type !== "band" && scale.type !== "point") {
|
|
14
24
|
if (typeof value !== "number" || !Number.isFinite(value))
|
|
15
|
-
throw new TypeError(
|
|
25
|
+
throw new TypeError(
|
|
26
|
+
"Axis tickValues for a continuous scale must be finite numbers."
|
|
27
|
+
);
|
|
16
28
|
const [a, b] = scale.domain;
|
|
17
29
|
if (value < Math.min(a, b) || value > Math.max(a, b))
|
|
18
|
-
throw new RangeError(
|
|
30
|
+
throw new RangeError(
|
|
31
|
+
"Axis tickValues must be within the scale domain."
|
|
32
|
+
);
|
|
19
33
|
} else if (typeof value !== "string" && (typeof value !== "number" || !Number.isFinite(value)) || scale.map(value) === void 0) {
|
|
20
34
|
throw new RangeError("Axis tickValues must be known band categories.");
|
|
21
35
|
}
|
|
@@ -26,6 +40,7 @@ function ticks(scale, props) {
|
|
|
26
40
|
if (!Number.isInteger(count) || count < 0 || count > 100)
|
|
27
41
|
throw new RangeError("Axis tickCount must be an integer from 0 to 100.");
|
|
28
42
|
if (count === 0) return [];
|
|
43
|
+
if (scale.type === "trading-time") return scale.ticks(count);
|
|
29
44
|
if (scale.type !== "band" && scale.type !== "point")
|
|
30
45
|
return count === 1 ? [scale.domain[0]] : scale.ticks(count);
|
|
31
46
|
const n = scale.domain.length;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/features/viz/lib/scale-ticks.ts"],
|
|
4
|
-
"sourcesContent": ["import { resolveSignalValue } from \"@pibbl/core\";\nimport type { AxisProps, BandCategory, ResolvedScale } from \"./types.js\";\ntype Tick = number | string;\n\nexport function ticks(scale: ResolvedScale
|
|
5
|
-
"mappings": "AAAA,SAAS,0BAA0B;AAI5B,SAAS,
|
|
4
|
+
"sourcesContent": ["import { resolveSignalValue } from \"@pibbl/core\";\nimport type { AxisProps, BandCategory, ResolvedScale } from \"./types.js\";\ntype Tick = number | string;\n\nexport function ticks(\n scale: ResolvedScale,\n props: Pick<AxisProps, \"tickValues\" | \"tickCount\">,\n): readonly Tick[] {\n if (props.tickValues !== undefined && props.tickCount !== undefined)\n throw new TypeError(\n \"Axis tickValues and tickCount are mutually exclusive.\",\n );\n const explicit =\n props.tickValues === undefined\n ? undefined\n : resolveSignalValue(props.tickValues);\n if (explicit !== undefined) {\n if (!Array.isArray(explicit) || explicit.length > 100)\n throw new RangeError(\n \"Axis tickValues must be an array with at most 100 values.\",\n );\n const seen = new Set<Tick>();\n for (const value of explicit) {\n if (seen.has(value))\n throw new RangeError(\"Axis tickValues must not contain duplicates.\");\n seen.add(value);\n if (scale.type === \"trading-time\") {\n if (typeof value !== \"number\" || scale.slotAtTime(value) === undefined)\n throw new RangeError(\n \"Axis trading-time ticks must be supplied timestamps.\",\n );\n } else if (scale.type !== \"band\" && scale.type !== \"point\") {\n if (typeof value !== \"number\" || !Number.isFinite(value))\n throw new TypeError(\n \"Axis tickValues for a continuous scale must be finite numbers.\",\n );\n const [a, b] = scale.domain;\n if (value < Math.min(a, b) || value > Math.max(a, b))\n throw new RangeError(\n \"Axis tickValues must be within the scale domain.\",\n );\n } else if (\n (typeof value !== \"string\" &&\n (typeof value !== \"number\" || !Number.isFinite(value))) ||\n scale.map(value as BandCategory) === undefined\n ) {\n throw new RangeError(\"Axis tickValues must be known band categories.\");\n }\n }\n return explicit;\n }\n const count = resolveSignalValue(props.tickCount ?? 5);\n if (!Number.isInteger(count) || count < 0 || count > 100)\n throw new RangeError(\"Axis tickCount must be an integer from 0 to 100.\");\n if (count === 0) return [];\n if (scale.type === \"trading-time\") return scale.ticks(count);\n if (scale.type !== \"band\" && scale.type !== \"point\")\n return count === 1 ? [scale.domain[0]] : scale.ticks(count);\n const n = scale.domain.length;\n if (n === 0) return [];\n if (count === 1) return [scale.domain[0]];\n const m = Math.min(count, n);\n if (m === 1) return [scale.domain[0]];\n return Array.from(\n { length: m },\n (_, index) => scale.domain[Math.round((index * (n - 1)) / (m - 1))]!,\n );\n}\n\nexport function position(scale: ResolvedScale, value: Tick): number {\n if (scale.type === \"point\") return scale.map(value as BandCategory)!;\n return scale.type === \"band\"\n ? scale.map(value as BandCategory)! + scale.bandwidth / 2\n : scale.map(value as number);\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,0BAA0B;AAI5B,SAAS,MACd,OACA,OACiB;AACjB,MAAI,MAAM,eAAe,UAAa,MAAM,cAAc;AACxD,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AACF,QAAM,WACJ,MAAM,eAAe,SACjB,SACA,mBAAmB,MAAM,UAAU;AACzC,MAAI,aAAa,QAAW;AAC1B,QAAI,CAAC,MAAM,QAAQ,QAAQ,KAAK,SAAS,SAAS;AAChD,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AACF,UAAM,OAAO,oBAAI,IAAU;AAC3B,eAAW,SAAS,UAAU;AAC5B,UAAI,KAAK,IAAI,KAAK;AAChB,cAAM,IAAI,WAAW,8CAA8C;AACrE,WAAK,IAAI,KAAK;AACd,UAAI,MAAM,SAAS,gBAAgB;AACjC,YAAI,OAAO,UAAU,YAAY,MAAM,WAAW,KAAK,MAAM;AAC3D,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,MACJ,WAAW,MAAM,SAAS,UAAU,MAAM,SAAS,SAAS;AAC1D,YAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK;AACrD,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AACF,cAAM,CAAC,GAAG,CAAC,IAAI,MAAM;AACrB,YAAI,QAAQ,KAAK,IAAI,GAAG,CAAC,KAAK,QAAQ,KAAK,IAAI,GAAG,CAAC;AACjD,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,MACJ,WACG,OAAO,UAAU,aACf,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,MACtD,MAAM,IAAI,KAAqB,MAAM,QACrC;AACA,cAAM,IAAI,WAAW,gDAAgD;AAAA,MACvE;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,mBAAmB,MAAM,aAAa,CAAC;AACrD,MAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,KAAK,QAAQ;AACnD,UAAM,IAAI,WAAW,kDAAkD;AACzE,MAAI,UAAU,EAAG,QAAO,CAAC;AACzB,MAAI,MAAM,SAAS,eAAgB,QAAO,MAAM,MAAM,KAAK;AAC3D,MAAI,MAAM,SAAS,UAAU,MAAM,SAAS;AAC1C,WAAO,UAAU,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC,IAAI,MAAM,MAAM,KAAK;AAC5D,QAAM,IAAI,MAAM,OAAO;AACvB,MAAI,MAAM,EAAG,QAAO,CAAC;AACrB,MAAI,UAAU,EAAG,QAAO,CAAC,MAAM,OAAO,CAAC,CAAC;AACxC,QAAM,IAAI,KAAK,IAAI,OAAO,CAAC;AAC3B,MAAI,MAAM,EAAG,QAAO,CAAC,MAAM,OAAO,CAAC,CAAC;AACpC,SAAO,MAAM;AAAA,IACX,EAAE,QAAQ,EAAE;AAAA,IACZ,CAAC,GAAG,UAAU,MAAM,OAAO,KAAK,MAAO,SAAS,IAAI,MAAO,IAAI,EAAE,CAAC;AAAA,EACpE;AACF;AAEO,SAAS,SAAS,OAAsB,OAAqB;AAClE,MAAI,MAAM,SAAS,QAAS,QAAO,MAAM,IAAI,KAAqB;AAClE,SAAO,MAAM,SAAS,SAClB,MAAM,IAAI,KAAqB,IAAK,MAAM,YAAY,IACtD,MAAM,IAAI,KAAe;AAC/B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Signal } from "@pibbl/core";
|
|
2
|
+
import type { SequentialColorScaleProps, ResolvedSequentialColorScale } from "./color-types.js";
|
|
3
|
+
import type { ScaleId } from "./types.js";
|
|
4
|
+
/** Provides an allocation-independent sequential color mapping.
|
|
5
|
+
* @param props - Explicit domain, colors, identity, and children. See {@link SequentialColorScaleProps}.
|
|
6
|
+
* @returns Descendant content. */
|
|
7
|
+
export declare function SequentialColorScale(props: SequentialColorScaleProps): import("@pibbl/core").PibblNode;
|
|
8
|
+
/** Reads the dedicated ancestor sequential mapping.
|
|
9
|
+
* @param id - Color-scale identity. See {@link ScaleId}.
|
|
10
|
+
* @returns Shared readonly mapping signal. See {@link ResolvedSequentialColorScale}. */
|
|
11
|
+
export declare function useSequentialColorScale(id: ScaleId): Signal<ResolvedSequentialColorScale>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { resolveSignalValue } from "@pibbl/core";
|
|
2
|
+
import { provideColor, useColor } from "./color-context.js";
|
|
3
|
+
import {
|
|
4
|
+
colorMix,
|
|
5
|
+
colorPosition,
|
|
6
|
+
finiteColorValue,
|
|
7
|
+
hexColor
|
|
8
|
+
} from "./color-math.js";
|
|
9
|
+
function resolve(props) {
|
|
10
|
+
const input = resolveSignalValue(props.domain), paint = resolveSignalValue(props.colors);
|
|
11
|
+
if (!Array.isArray(input) || input.length !== 2 || !Array.isArray(paint) || paint.length !== 2)
|
|
12
|
+
throw new RangeError(
|
|
13
|
+
"Sequential color scales require two domain endpoints and two colors."
|
|
14
|
+
);
|
|
15
|
+
const domain = Object.freeze(
|
|
16
|
+
Array.from(input, finiteColorValue)
|
|
17
|
+
), colors = Object.freeze(Array.from(paint, hexColor));
|
|
18
|
+
const stops = Object.freeze(
|
|
19
|
+
domain.map((value, i) => Object.freeze({ value, color: colors[i] }))
|
|
20
|
+
);
|
|
21
|
+
return Object.freeze({
|
|
22
|
+
domain,
|
|
23
|
+
colors,
|
|
24
|
+
stops,
|
|
25
|
+
map(value) {
|
|
26
|
+
finiteColorValue(value);
|
|
27
|
+
return colorMix(
|
|
28
|
+
colors[0],
|
|
29
|
+
colors[1],
|
|
30
|
+
colorPosition(value, domain[0], domain[1])
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function SequentialColorScale(props) {
|
|
36
|
+
provideColor(props.id, "sequential", () => resolve(props), [
|
|
37
|
+
props.domain,
|
|
38
|
+
props.colors
|
|
39
|
+
]);
|
|
40
|
+
return props.children;
|
|
41
|
+
}
|
|
42
|
+
function useSequentialColorScale(id) {
|
|
43
|
+
return useColor(id, "sequential");
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
SequentialColorScale,
|
|
47
|
+
useSequentialColorScale
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=sequential-color-scale.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/features/viz/lib/sequential-color-scale.ts"],
|
|
4
|
+
"sourcesContent": ["import { resolveSignalValue, type Signal } from \"@pibbl/core\";\nimport type {\n SequentialColorScaleProps,\n ResolvedSequentialColorScale,\n} from \"./color-types.js\";\nimport type { ScaleId } from \"./types.js\";\nimport { provideColor, useColor } from \"./color-context.js\";\nimport {\n colorMix,\n colorPosition,\n finiteColorValue,\n hexColor,\n} from \"./color-math.js\";\nfunction resolve(\n props: SequentialColorScaleProps,\n): ResolvedSequentialColorScale {\n const input = resolveSignalValue(props.domain),\n paint = resolveSignalValue(props.colors);\n if (\n !Array.isArray(input) ||\n input.length !== 2 ||\n !Array.isArray(paint) ||\n paint.length !== 2\n )\n throw new RangeError(\n \"Sequential color scales require two domain endpoints and two colors.\",\n );\n const domain = Object.freeze(\n Array.from(input, finiteColorValue),\n ) as readonly [number, number],\n colors = Object.freeze(Array.from(paint, hexColor)) as readonly [\n string,\n string,\n ];\n const stops = Object.freeze(\n domain.map((value, i) => Object.freeze({ value, color: colors[i] })),\n );\n return Object.freeze({\n domain,\n colors,\n stops,\n map(value: number) {\n finiteColorValue(value);\n return colorMix(\n colors[0],\n colors[1],\n colorPosition(value, domain[0], domain[1]),\n );\n },\n });\n}\n/** Provides an allocation-independent sequential color mapping.\n * @param props - Explicit domain, colors, identity, and children. See {@link SequentialColorScaleProps}.\n * @returns Descendant content. */\nexport function SequentialColorScale(props: SequentialColorScaleProps) {\n provideColor(props.id, \"sequential\", () => resolve(props), [\n props.domain,\n props.colors,\n ]);\n return props.children;\n}\n/** Reads the dedicated ancestor sequential mapping.\n * @param id - Color-scale identity. See {@link ScaleId}.\n * @returns Shared readonly mapping signal. See {@link ResolvedSequentialColorScale}. */\nexport function useSequentialColorScale(\n id: ScaleId,\n): Signal<ResolvedSequentialColorScale> {\n return useColor(id, \"sequential\");\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,0BAAuC;AAMhD,SAAS,cAAc,gBAAgB;AACvC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,QACP,OAC8B;AAC9B,QAAM,QAAQ,mBAAmB,MAAM,MAAM,GAC3C,QAAQ,mBAAmB,MAAM,MAAM;AACzC,MACE,CAAC,MAAM,QAAQ,KAAK,KACpB,MAAM,WAAW,KACjB,CAAC,MAAM,QAAQ,KAAK,KACpB,MAAM,WAAW;AAEjB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AACF,QAAM,SAAS,OAAO;AAAA,IAClB,MAAM,KAAK,OAAO,gBAAgB;AAAA,EACpC,GACA,SAAS,OAAO,OAAO,MAAM,KAAK,OAAO,QAAQ,CAAC;AAIpD,QAAM,QAAQ,OAAO;AAAA,IACnB,OAAO,IAAI,CAAC,OAAO,MAAM,OAAO,OAAO,EAAE,OAAO,OAAO,OAAO,CAAC,EAAE,CAAC,CAAC;AAAA,EACrE;AACA,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,IAAI,OAAe;AACjB,uBAAiB,KAAK;AACtB,aAAO;AAAA,QACL,OAAO,CAAC;AAAA,QACR,OAAO,CAAC;AAAA,QACR,cAAc,OAAO,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,MAC3C;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAIO,SAAS,qBAAqB,OAAkC;AACrE,eAAa,MAAM,IAAI,cAAc,MAAM,QAAQ,KAAK,GAAG;AAAA,IACzD,MAAM;AAAA,IACN,MAAM;AAAA,EACR,CAAC;AACD,SAAO,MAAM;AACf;AAIO,SAAS,wBACd,IACsC;AACtC,SAAO,SAAS,IAAI,YAAY;AAClC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ResolvedContinuousScale, ResolvedPointScale, ScaleId, SeriesAccessor, SeriesCoordinate } from "./types.js";
|
|
2
|
+
export type NumericPositionScale = ResolvedContinuousScale | import("./trading-time-scale.js").ResolvedTradingTimeScale;
|
|
3
|
+
type PositionScale = NumericPositionScale | ResolvedPointScale;
|
|
4
|
+
/** Private position receiver; public scale hooks retain their dedicated contracts. */
|
|
5
|
+
export declare function useSeriesPosition(id: ScaleId): PositionScale;
|
|
6
|
+
export declare function seriesAccessor<D>(input: SeriesAccessor<D>): (datum: D, index: number, data: readonly D[]) => SeriesCoordinate;
|
|
7
|
+
export declare function mapSeriesPosition(scale: PositionScale, value: SeriesCoordinate): number | undefined;
|
|
8
|
+
/** Private numeric/trading receiver; public continuous hook stays unchanged. */
|
|
9
|
+
export declare function useNumericPosition(id: ScaleId): NumericPositionScale;
|
|
10
|
+
/** Returns explicit supplied time for trading positions, continuous inverse otherwise. */
|
|
11
|
+
export declare function invertNumericPosition(scale: NumericPositionScale, position: number): number | undefined;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { scaleView } from "./scale-view.js";
|
|
2
|
+
const views = /* @__PURE__ */ new WeakMap();
|
|
3
|
+
function useSeriesPosition(id) {
|
|
4
|
+
return scaleView(views, id, "Series", (kind) => kind !== "band").get();
|
|
5
|
+
}
|
|
6
|
+
function seriesAccessor(input) {
|
|
7
|
+
return typeof input === "function" ? input : (datum) => datum[input];
|
|
8
|
+
}
|
|
9
|
+
function mapSeriesPosition(scale, value) {
|
|
10
|
+
if (value == null || typeof value === "number" && !Number.isFinite(value))
|
|
11
|
+
return void 0;
|
|
12
|
+
if (scale.type === "point") {
|
|
13
|
+
const mapped = scale.map(value);
|
|
14
|
+
if (mapped === void 0)
|
|
15
|
+
throw new RangeError(
|
|
16
|
+
`Series: unknown point category ${String(value)} (${typeof value}).`
|
|
17
|
+
);
|
|
18
|
+
return mapped;
|
|
19
|
+
}
|
|
20
|
+
if (typeof value !== "number")
|
|
21
|
+
throw new TypeError(
|
|
22
|
+
"Series: continuous coordinates must be numbers; use PointScale for categories."
|
|
23
|
+
);
|
|
24
|
+
return scale.map(value);
|
|
25
|
+
}
|
|
26
|
+
function useNumericPosition(id) {
|
|
27
|
+
const value = useSeriesPosition(id);
|
|
28
|
+
if (value.type === "point")
|
|
29
|
+
throw new TypeError(
|
|
30
|
+
"Numeric position requires a numeric or trading-time scale."
|
|
31
|
+
);
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
function invertNumericPosition(scale, position) {
|
|
35
|
+
return scale.type === "trading-time" ? scale.nearestTimeAtPosition(position) : scale.invert(position);
|
|
36
|
+
}
|
|
37
|
+
export {
|
|
38
|
+
invertNumericPosition,
|
|
39
|
+
mapSeriesPosition,
|
|
40
|
+
seriesAccessor,
|
|
41
|
+
useNumericPosition,
|
|
42
|
+
useSeriesPosition
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=series-position.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/features/viz/lib/series-position.ts"],
|
|
4
|
+
"sourcesContent": ["import type { Signal } from \"@pibbl/core\";\nimport { scaleView } from \"./scale-view.js\";\nimport type {\n ResolvedScale,\n ResolvedContinuousScale,\n ResolvedPointScale,\n ScaleId,\n SeriesAccessor,\n SeriesCoordinate,\n} from \"./types.js\";\nexport type NumericPositionScale =\n | ResolvedContinuousScale\n | import(\"./trading-time-scale.js\").ResolvedTradingTimeScale;\ntype PositionScale = NumericPositionScale | ResolvedPointScale;\nconst views = new WeakMap<Signal<ResolvedScale>, Signal<PositionScale>>();\n/** Private position receiver; public scale hooks retain their dedicated contracts. */\nexport function useSeriesPosition(id: ScaleId): PositionScale {\n return scaleView(views, id, \"Series\", (kind) => kind !== \"band\").get();\n}\nexport function seriesAccessor<D>(\n input: SeriesAccessor<D>,\n): (datum: D, index: number, data: readonly D[]) => SeriesCoordinate {\n return typeof input === \"function\"\n ? input\n : (datum) => datum[input] as SeriesCoordinate;\n}\nexport function mapSeriesPosition(\n scale: PositionScale,\n value: SeriesCoordinate,\n): number | undefined {\n if (value == null || (typeof value === \"number\" && !Number.isFinite(value)))\n return undefined;\n if (scale.type === \"point\") {\n const mapped = scale.map(value);\n if (mapped === undefined)\n throw new RangeError(\n `Series: unknown point category ${String(value)} (${typeof value}).`,\n );\n return mapped;\n }\n if (typeof value !== \"number\")\n throw new TypeError(\n \"Series: continuous coordinates must be numbers; use PointScale for categories.\",\n );\n return scale.map(value);\n}\n\n/** Private numeric/trading receiver; public continuous hook stays unchanged. */\nexport function useNumericPosition(id: ScaleId): NumericPositionScale {\n const value = useSeriesPosition(id);\n if (value.type === \"point\")\n throw new TypeError(\n \"Numeric position requires a numeric or trading-time scale.\",\n );\n return value;\n}\n/** Returns explicit supplied time for trading positions, continuous inverse otherwise. */\nexport function invertNumericPosition(\n scale: NumericPositionScale,\n position: number,\n): number | undefined {\n return scale.type === \"trading-time\"\n ? scale.nearestTimeAtPosition(position)\n : scale.invert(position);\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,iBAAiB;AAa1B,MAAM,QAAQ,oBAAI,QAAsD;AAEjE,SAAS,kBAAkB,IAA4B;AAC5D,SAAO,UAAU,OAAO,IAAI,UAAU,CAAC,SAAS,SAAS,MAAM,EAAE,IAAI;AACvE;AACO,SAAS,eACd,OACmE;AACnE,SAAO,OAAO,UAAU,aACpB,QACA,CAAC,UAAU,MAAM,KAAK;AAC5B;AACO,SAAS,kBACd,OACA,OACoB;AACpB,MAAI,SAAS,QAAS,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK;AACvE,WAAO;AACT,MAAI,MAAM,SAAS,SAAS;AAC1B,UAAM,SAAS,MAAM,IAAI,KAAK;AAC9B,QAAI,WAAW;AACb,YAAM,IAAI;AAAA,QACR,kCAAkC,OAAO,KAAK,CAAC,KAAK,OAAO,KAAK;AAAA,MAClE;AACF,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU;AACnB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AACF,SAAO,MAAM,IAAI,KAAK;AACxB;AAGO,SAAS,mBAAmB,IAAmC;AACpE,QAAM,QAAQ,kBAAkB,EAAE;AAClC,MAAI,MAAM,SAAS;AACjB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AACF,SAAO;AACT;AAEO,SAAS,sBACd,OACA,UACoB;AACpB,SAAO,MAAM,SAAS,iBAClB,MAAM,sBAAsB,QAAQ,IACpC,MAAM,OAAO,QAAQ;AAC3B;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type SeriesCurve } from "./curve-definition.js";
|
|
2
|
+
/**
|
|
3
|
+
* Returns the immutable definition that jumps to the next value at the prior x coordinate.
|
|
4
|
+
*
|
|
5
|
+
* @returns The named {@link SeriesCurve} definition.
|
|
6
|
+
*/
|
|
7
|
+
export declare function stepBefore(): SeriesCurve;
|
|
8
|
+
/**
|
|
9
|
+
* Returns the immutable definition that holds the prior value until the next x coordinate.
|
|
10
|
+
*
|
|
11
|
+
* @returns The named {@link SeriesCurve} definition.
|
|
12
|
+
*/
|
|
13
|
+
export declare function stepAfter(): SeriesCurve;
|
|
14
|
+
/**
|
|
15
|
+
* Returns the immutable definition that places each value transition halfway between x values.
|
|
16
|
+
*
|
|
17
|
+
* @returns The named {@link SeriesCurve} definition.
|
|
18
|
+
*/
|
|
19
|
+
export declare function stepMidpoint(): SeriesCurve;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createSeriesCurve
|
|
3
|
+
} from "./curve-definition.js";
|
|
4
|
+
function segment(end) {
|
|
5
|
+
return Object.freeze({ end });
|
|
6
|
+
}
|
|
7
|
+
function stepBeforeSegments(points) {
|
|
8
|
+
const segments = [];
|
|
9
|
+
for (let i = 1; i < points.length; i++) {
|
|
10
|
+
const previous = points[i - 1], next = points[i];
|
|
11
|
+
segments.push(segment([previous[0], next[1]]), segment(next));
|
|
12
|
+
}
|
|
13
|
+
return segments;
|
|
14
|
+
}
|
|
15
|
+
function stepAfterSegments(points) {
|
|
16
|
+
const segments = [];
|
|
17
|
+
for (let i = 1; i < points.length; i++) {
|
|
18
|
+
const previous = points[i - 1], next = points[i];
|
|
19
|
+
segments.push(segment([next[0], previous[1]]), segment(next));
|
|
20
|
+
}
|
|
21
|
+
return segments;
|
|
22
|
+
}
|
|
23
|
+
function stepMidpointSegments(points) {
|
|
24
|
+
const segments = [];
|
|
25
|
+
for (let i = 1; i < points.length; i++) {
|
|
26
|
+
const previous = points[i - 1], next = points[i];
|
|
27
|
+
const midpoint2 = previous[0] / 2 + next[0] / 2;
|
|
28
|
+
segments.push(
|
|
29
|
+
segment([midpoint2, previous[1]]),
|
|
30
|
+
segment([midpoint2, next[1]]),
|
|
31
|
+
segment(next)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
return segments;
|
|
35
|
+
}
|
|
36
|
+
const before = /* @__PURE__ */ createSeriesCurve(stepBeforeSegments);
|
|
37
|
+
const after = /* @__PURE__ */ createSeriesCurve(stepAfterSegments);
|
|
38
|
+
const midpoint = /* @__PURE__ */ createSeriesCurve(stepMidpointSegments);
|
|
39
|
+
function stepBefore() {
|
|
40
|
+
return before;
|
|
41
|
+
}
|
|
42
|
+
function stepAfter() {
|
|
43
|
+
return after;
|
|
44
|
+
}
|
|
45
|
+
function stepMidpoint() {
|
|
46
|
+
return midpoint;
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
stepAfter,
|
|
50
|
+
stepBefore,
|
|
51
|
+
stepMidpoint
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=step-curves.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/features/viz/lib/step-curves.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n createSeriesCurve,\n type SeriesCurve,\n type SeriesCurvePoint,\n} from \"./curve-definition.js\";\n\nfunction segment(end: SeriesCurvePoint) {\n return Object.freeze({ end });\n}\n\nfunction stepBeforeSegments(points: readonly SeriesCurvePoint[]) {\n const segments = [];\n for (let i = 1; i < points.length; i++) {\n const previous = points[i - 1],\n next = points[i];\n segments.push(segment([previous[0], next[1]]), segment(next));\n }\n return segments;\n}\n\nfunction stepAfterSegments(points: readonly SeriesCurvePoint[]) {\n const segments = [];\n for (let i = 1; i < points.length; i++) {\n const previous = points[i - 1],\n next = points[i];\n segments.push(segment([next[0], previous[1]]), segment(next));\n }\n return segments;\n}\n\nfunction stepMidpointSegments(points: readonly SeriesCurvePoint[]) {\n const segments = [];\n for (let i = 1; i < points.length; i++) {\n const previous = points[i - 1],\n next = points[i];\n const midpoint = previous[0] / 2 + next[0] / 2;\n segments.push(\n segment([midpoint, previous[1]]),\n segment([midpoint, next[1]]),\n segment(next),\n );\n }\n return segments;\n}\n\nconst before = /* @__PURE__ */ createSeriesCurve(stepBeforeSegments);\nconst after = /* @__PURE__ */ createSeriesCurve(stepAfterSegments);\nconst midpoint = /* @__PURE__ */ createSeriesCurve(stepMidpointSegments);\n\n/**\n * Returns the immutable definition that jumps to the next value at the prior x coordinate.\n *\n * @returns The named {@link SeriesCurve} definition.\n */\nexport function stepBefore(): SeriesCurve {\n return before;\n}\n\n/**\n * Returns the immutable definition that holds the prior value until the next x coordinate.\n *\n * @returns The named {@link SeriesCurve} definition.\n */\nexport function stepAfter(): SeriesCurve {\n return after;\n}\n\n/**\n * Returns the immutable definition that places each value transition halfway between x values.\n *\n * @returns The named {@link SeriesCurve} definition.\n */\nexport function stepMidpoint(): SeriesCurve {\n return midpoint;\n}\n"],
|
|
5
|
+
"mappings": "AAAA;AAAA,EACE;AAAA,OAGK;AAEP,SAAS,QAAQ,KAAuB;AACtC,SAAO,OAAO,OAAO,EAAE,IAAI,CAAC;AAC9B;AAEA,SAAS,mBAAmB,QAAqC;AAC/D,QAAM,WAAW,CAAC;AAClB,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,WAAW,OAAO,IAAI,CAAC,GAC3B,OAAO,OAAO,CAAC;AACjB,aAAS,KAAK,QAAQ,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,CAAC;AAAA,EAC9D;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,QAAqC;AAC9D,QAAM,WAAW,CAAC;AAClB,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,WAAW,OAAO,IAAI,CAAC,GAC3B,OAAO,OAAO,CAAC;AACjB,aAAS,KAAK,QAAQ,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,CAAC;AAAA,EAC9D;AACA,SAAO;AACT;AAEA,SAAS,qBAAqB,QAAqC;AACjE,QAAM,WAAW,CAAC;AAClB,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,WAAW,OAAO,IAAI,CAAC,GAC3B,OAAO,OAAO,CAAC;AACjB,UAAMA,YAAW,SAAS,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;AAC7C,aAAS;AAAA,MACP,QAAQ,CAACA,WAAU,SAAS,CAAC,CAAC,CAAC;AAAA,MAC/B,QAAQ,CAACA,WAAU,KAAK,CAAC,CAAC,CAAC;AAAA,MAC3B,QAAQ,IAAI;AAAA,IACd;AAAA,EACF;AACA,SAAO;AACT;AAEA,MAAM,SAAyB,kCAAkB,kBAAkB;AACnE,MAAM,QAAwB,kCAAkB,iBAAiB;AACjE,MAAM,WAA2B,kCAAkB,oBAAoB;AAOhE,SAAS,aAA0B;AACxC,SAAO;AACT;AAOO,SAAS,YAAyB;AACvC,SAAO;AACT;AAOO,SAAS,eAA4B;AAC1C,SAAO;AACT;",
|
|
6
|
+
"names": ["midpoint"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type PibblNode, type Signal, type SignalValue } from "@pibbl/core";
|
|
2
|
+
import type { ScaleId } from "./types.js";
|
|
3
|
+
/** One lower-inclusive, upper-exclusive threshold color bucket. @see {@link ResolvedThresholdColorScale} */
|
|
4
|
+
export interface ThresholdColorBand {
|
|
5
|
+
/** Lower inclusive boundary, omitted for the first bucket. */
|
|
6
|
+
readonly lower: number | undefined;
|
|
7
|
+
/** Upper exclusive boundary, omitted for the last bucket. */
|
|
8
|
+
readonly upper: number | undefined;
|
|
9
|
+
/** Validated #RRGGBB paint for this bucket. */
|
|
10
|
+
readonly color: string;
|
|
11
|
+
}
|
|
12
|
+
/** Immutable resolved threshold mapping shared with descendant marks. @see {@link ThresholdColorScaleProps} */
|
|
13
|
+
export interface ResolvedThresholdColorScale {
|
|
14
|
+
/** Strictly ascending finite authored bucket boundaries. */
|
|
15
|
+
readonly thresholds: readonly number[];
|
|
16
|
+
/** One validated color for every bucket. */
|
|
17
|
+
readonly colors: readonly string[];
|
|
18
|
+
/** Readable bucket descriptions in authored order. */
|
|
19
|
+
readonly bands: readonly ThresholdColorBand[];
|
|
20
|
+
/** Maps a finite numeric value to its containing bucket paint.
|
|
21
|
+
* @param value - Finite input.
|
|
22
|
+
* @returns Canonical lowercase #rrggbb color. */
|
|
23
|
+
readonly map: (value: number) => string;
|
|
24
|
+
}
|
|
25
|
+
/** Authored threshold boundaries, bucket colors, identity, and descendant content. @see {@link ResolvedThresholdColorScale} */
|
|
26
|
+
export interface ThresholdColorScaleProps {
|
|
27
|
+
/** Stable provider identity. */
|
|
28
|
+
readonly id: ScaleId;
|
|
29
|
+
/** Strictly ascending finite boundaries; each equality belongs to the upper bucket. */
|
|
30
|
+
readonly thresholds: SignalValue<readonly number[]>;
|
|
31
|
+
/** Exactly one #RRGGBB color per bucket. */
|
|
32
|
+
readonly colors: SignalValue<readonly string[]>;
|
|
33
|
+
/** Descendant content using this dedicated color context. */
|
|
34
|
+
readonly children?: PibblNode;
|
|
35
|
+
}
|
|
36
|
+
/** Provides a lazy, discrete threshold-to-color mapping for descendants.
|
|
37
|
+
* @param props - Boundaries, colors, identity and descendants. See {@link ThresholdColorScaleProps}.
|
|
38
|
+
* @returns Descendant content. */
|
|
39
|
+
export declare function ThresholdColorScale(props: ThresholdColorScaleProps): PibblNode;
|
|
40
|
+
/** Reads the matching ancestor threshold color mapping.
|
|
41
|
+
* @param id - Provider identity. See {@link ScaleId}.
|
|
42
|
+
* @returns Shared readonly mapping signal. See {@link ResolvedThresholdColorScale}. */
|
|
43
|
+
export declare function useThresholdColorScale(id: ScaleId): Signal<ResolvedThresholdColorScale>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveSignalValue
|
|
3
|
+
} from "@pibbl/core";
|
|
4
|
+
import { provideColor, useColor } from "./color-context.js";
|
|
5
|
+
import { finiteColorValue, hexColor } from "./color-math.js";
|
|
6
|
+
function resolve(props) {
|
|
7
|
+
const input = resolveSignalValue(props.thresholds);
|
|
8
|
+
const paint = resolveSignalValue(props.colors);
|
|
9
|
+
if (!Array.isArray(input) || !Array.isArray(paint))
|
|
10
|
+
throw new TypeError(
|
|
11
|
+
"Threshold color scales require threshold and color arrays."
|
|
12
|
+
);
|
|
13
|
+
const thresholds = Object.freeze(Array.from(input, finiteColorValue));
|
|
14
|
+
for (let index = 1; index < thresholds.length; index++)
|
|
15
|
+
if (!(thresholds[index - 1] < thresholds[index]))
|
|
16
|
+
throw new RangeError(
|
|
17
|
+
"Threshold color boundaries must be strictly ascending."
|
|
18
|
+
);
|
|
19
|
+
if (paint.length !== thresholds.length + 1)
|
|
20
|
+
throw new RangeError(
|
|
21
|
+
"Threshold color scales require one more color than thresholds."
|
|
22
|
+
);
|
|
23
|
+
const colors = Object.freeze(Array.from(paint, hexColor));
|
|
24
|
+
const bands = Object.freeze(
|
|
25
|
+
colors.map(
|
|
26
|
+
(color, index) => Object.freeze({
|
|
27
|
+
lower: index === 0 ? void 0 : thresholds[index - 1],
|
|
28
|
+
upper: index === thresholds.length ? void 0 : thresholds[index],
|
|
29
|
+
color
|
|
30
|
+
})
|
|
31
|
+
)
|
|
32
|
+
);
|
|
33
|
+
return Object.freeze({
|
|
34
|
+
thresholds,
|
|
35
|
+
colors,
|
|
36
|
+
bands,
|
|
37
|
+
map(value) {
|
|
38
|
+
finiteColorValue(value);
|
|
39
|
+
let index = 0;
|
|
40
|
+
while (index < thresholds.length && value >= thresholds[index]) index++;
|
|
41
|
+
return colors[index];
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function ThresholdColorScale(props) {
|
|
46
|
+
provideColor(props.id, "threshold", () => resolve(props), [
|
|
47
|
+
props.thresholds,
|
|
48
|
+
props.colors
|
|
49
|
+
]);
|
|
50
|
+
return props.children;
|
|
51
|
+
}
|
|
52
|
+
function useThresholdColorScale(id) {
|
|
53
|
+
return useColor(id, "threshold");
|
|
54
|
+
}
|
|
55
|
+
export {
|
|
56
|
+
ThresholdColorScale,
|
|
57
|
+
useThresholdColorScale
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=threshold-color-scale.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/features/viz/lib/threshold-color-scale.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n resolveSignalValue,\n type PibblNode,\n type Signal,\n type SignalValue,\n} from \"@pibbl/core\";\nimport { provideColor, useColor } from \"./color-context.js\";\nimport { finiteColorValue, hexColor } from \"./color-math.js\";\nimport type { ScaleId } from \"./types.js\";\n\n/** One lower-inclusive, upper-exclusive threshold color bucket. @see {@link ResolvedThresholdColorScale} */\nexport interface ThresholdColorBand {\n /** Lower inclusive boundary, omitted for the first bucket. */\n readonly lower: number | undefined;\n /** Upper exclusive boundary, omitted for the last bucket. */\n readonly upper: number | undefined;\n /** Validated #RRGGBB paint for this bucket. */\n readonly color: string;\n}\n\n/** Immutable resolved threshold mapping shared with descendant marks. @see {@link ThresholdColorScaleProps} */\nexport interface ResolvedThresholdColorScale {\n /** Strictly ascending finite authored bucket boundaries. */\n readonly thresholds: readonly number[];\n /** One validated color for every bucket. */\n readonly colors: readonly string[];\n /** Readable bucket descriptions in authored order. */\n readonly bands: readonly ThresholdColorBand[];\n /** Maps a finite numeric value to its containing bucket paint.\n * @param value - Finite input.\n * @returns Canonical lowercase #rrggbb color. */\n readonly map: (value: number) => string;\n}\n\n/** Authored threshold boundaries, bucket colors, identity, and descendant content. @see {@link ResolvedThresholdColorScale} */\nexport interface ThresholdColorScaleProps {\n /** Stable provider identity. */\n readonly id: ScaleId;\n /** Strictly ascending finite boundaries; each equality belongs to the upper bucket. */\n readonly thresholds: SignalValue<readonly number[]>;\n /** Exactly one #RRGGBB color per bucket. */\n readonly colors: SignalValue<readonly string[]>;\n /** Descendant content using this dedicated color context. */\n readonly children?: PibblNode;\n}\n\nfunction resolve(props: ThresholdColorScaleProps): ResolvedThresholdColorScale {\n const input = resolveSignalValue(props.thresholds);\n const paint = resolveSignalValue(props.colors);\n if (!Array.isArray(input) || !Array.isArray(paint))\n throw new TypeError(\n \"Threshold color scales require threshold and color arrays.\",\n );\n const thresholds = Object.freeze(Array.from(input, finiteColorValue));\n for (let index = 1; index < thresholds.length; index++)\n if (!(thresholds[index - 1] < thresholds[index]))\n throw new RangeError(\n \"Threshold color boundaries must be strictly ascending.\",\n );\n if (paint.length !== thresholds.length + 1)\n throw new RangeError(\n \"Threshold color scales require one more color than thresholds.\",\n );\n const colors = Object.freeze(Array.from(paint, hexColor));\n const bands = Object.freeze(\n colors.map((color, index) =>\n Object.freeze({\n lower: index === 0 ? undefined : thresholds[index - 1],\n upper: index === thresholds.length ? undefined : thresholds[index],\n color,\n }),\n ),\n );\n return Object.freeze({\n thresholds,\n colors,\n bands,\n map(value: number) {\n finiteColorValue(value);\n let index = 0;\n while (index < thresholds.length && value >= thresholds[index]) index++;\n return colors[index];\n },\n });\n}\n\n/** Provides a lazy, discrete threshold-to-color mapping for descendants.\n * @param props - Boundaries, colors, identity and descendants. See {@link ThresholdColorScaleProps}.\n * @returns Descendant content. */\nexport function ThresholdColorScale(props: ThresholdColorScaleProps) {\n provideColor(props.id, \"threshold\", () => resolve(props), [\n props.thresholds,\n props.colors,\n ]);\n return props.children;\n}\n\n/** Reads the matching ancestor threshold color mapping.\n * @param id - Provider identity. See {@link ScaleId}.\n * @returns Shared readonly mapping signal. See {@link ResolvedThresholdColorScale}. */\nexport function useThresholdColorScale(\n id: ScaleId,\n): Signal<ResolvedThresholdColorScale> {\n return useColor(id, \"threshold\");\n}\n"],
|
|
5
|
+
"mappings": "AAAA;AAAA,EACE;AAAA,OAIK;AACP,SAAS,cAAc,gBAAgB;AACvC,SAAS,kBAAkB,gBAAgB;AAuC3C,SAAS,QAAQ,OAA8D;AAC7E,QAAM,QAAQ,mBAAmB,MAAM,UAAU;AACjD,QAAM,QAAQ,mBAAmB,MAAM,MAAM;AAC7C,MAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,CAAC,MAAM,QAAQ,KAAK;AAC/C,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AACF,QAAM,aAAa,OAAO,OAAO,MAAM,KAAK,OAAO,gBAAgB,CAAC;AACpE,WAAS,QAAQ,GAAG,QAAQ,WAAW,QAAQ;AAC7C,QAAI,EAAE,WAAW,QAAQ,CAAC,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AACJ,MAAI,MAAM,WAAW,WAAW,SAAS;AACvC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AACF,QAAM,SAAS,OAAO,OAAO,MAAM,KAAK,OAAO,QAAQ,CAAC;AACxD,QAAM,QAAQ,OAAO;AAAA,IACnB,OAAO;AAAA,MAAI,CAAC,OAAO,UACjB,OAAO,OAAO;AAAA,QACZ,OAAO,UAAU,IAAI,SAAY,WAAW,QAAQ,CAAC;AAAA,QACrD,OAAO,UAAU,WAAW,SAAS,SAAY,WAAW,KAAK;AAAA,QACjE;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,IAAI,OAAe;AACjB,uBAAiB,KAAK;AACtB,UAAI,QAAQ;AACZ,aAAO,QAAQ,WAAW,UAAU,SAAS,WAAW,KAAK,EAAG;AAChE,aAAO,OAAO,KAAK;AAAA,IACrB;AAAA,EACF,CAAC;AACH;AAKO,SAAS,oBAAoB,OAAiC;AACnE,eAAa,MAAM,IAAI,aAAa,MAAM,QAAQ,KAAK,GAAG;AAAA,IACxD,MAAM;AAAA,IACN,MAAM;AAAA,EACR,CAAC;AACD,SAAO,MAAM;AACf;AAKO,SAAS,uBACd,IACqC;AACrC,SAAO,SAAS,IAAI,WAAW;AACjC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Input used to resolve gapless trading-time coordinates. */
|
|
2
|
+
export interface TradingTimeMappingInput {
|
|
3
|
+
/** Strictly increasing, unique UTC millisecond observations. */
|
|
4
|
+
readonly timestamps: readonly number[];
|
|
5
|
+
/** Visible logical slot endpoints; fractional values reserve viewport whitespace. */
|
|
6
|
+
readonly logicalRange: readonly [number, number];
|
|
7
|
+
/** Physical local-coordinate endpoints. */
|
|
8
|
+
readonly range: readonly [number, number];
|
|
9
|
+
}
|
|
10
|
+
/** Immutable conversion operations for one owned trading-time observation list. */
|
|
11
|
+
export interface TradingTimeMapping {
|
|
12
|
+
/** Maps an exact supplied timestamp to its physical local coordinate. */
|
|
13
|
+
mapTime(time: number): number;
|
|
14
|
+
/** Finds an exact supplied timestamp's consecutive logical slot. */
|
|
15
|
+
slotAtTime(time: number): number | undefined;
|
|
16
|
+
/** Finds the supplied timestamp at an exact integer logical slot. */
|
|
17
|
+
timeAtSlot(slot: number): number | undefined;
|
|
18
|
+
/** Selects the nearest supplied timestamp to a physical coordinate. */
|
|
19
|
+
nearestTimeAtPosition(position: number): number | undefined;
|
|
20
|
+
/** Inverts a physical coordinate to a possibly fractional logical slot. */
|
|
21
|
+
slotAtPosition(position: number): number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Creates pure mappings between exact supplied UTC observations, logical slots, and local positions.
|
|
25
|
+
*
|
|
26
|
+
* The mapping owns a frozen copy of timestamps. It creates no timestamps for gaps: exact mapping
|
|
27
|
+
* rejects unknown values, while inverse position mapping can intentionally produce fractional slots.
|
|
28
|
+
*
|
|
29
|
+
* @param input - Observation timestamps plus logical and physical viewport endpoints.
|
|
30
|
+
* @returns Immutable mapping operations with logarithmic timestamp lookup and constant-time slot lookup.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createTradingTimeMapping(input: TradingTimeMappingInput): TradingTimeMapping;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const DATE_LIMIT = 864e13;
|
|
2
|
+
function finite(value, name) {
|
|
3
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
4
|
+
throw new RangeError(`${name} must be finite.`);
|
|
5
|
+
return value;
|
|
6
|
+
}
|
|
7
|
+
function endpointPair(value, name) {
|
|
8
|
+
const first = finite(value[0], `${name}[0]`);
|
|
9
|
+
const second = finite(value[1], `${name}[1]`);
|
|
10
|
+
if (first === second) throw new RangeError(`${name} endpoints must differ.`);
|
|
11
|
+
return Object.freeze([first, second]);
|
|
12
|
+
}
|
|
13
|
+
function timestamp(value, index) {
|
|
14
|
+
if (!Number.isSafeInteger(value) || Math.abs(value) > DATE_LIMIT)
|
|
15
|
+
throw new RangeError(
|
|
16
|
+
`timestamps[${index}] must be safe integers within Date range UTC milliseconds.`
|
|
17
|
+
);
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
function indexOf(timestamps, time) {
|
|
21
|
+
let first = 0;
|
|
22
|
+
let last = timestamps.length - 1;
|
|
23
|
+
while (first <= last) {
|
|
24
|
+
const middle = first + Math.floor((last - first) / 2);
|
|
25
|
+
const candidate = timestamps[middle];
|
|
26
|
+
if (candidate === time) return middle;
|
|
27
|
+
if (candidate < time) first = middle + 1;
|
|
28
|
+
else last = middle - 1;
|
|
29
|
+
}
|
|
30
|
+
return -1;
|
|
31
|
+
}
|
|
32
|
+
function createTradingTimeMapping(input) {
|
|
33
|
+
const timestamps = input.timestamps.map(
|
|
34
|
+
(value, index) => timestamp(value, index)
|
|
35
|
+
);
|
|
36
|
+
for (let index = 1; index < timestamps.length; index++) {
|
|
37
|
+
if (timestamps[index - 1] >= timestamps[index])
|
|
38
|
+
throw new RangeError(
|
|
39
|
+
"timestamps must be strictly increasing and unique."
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
Object.freeze(timestamps);
|
|
43
|
+
const logicalRange = endpointPair(input.logicalRange, "logicalRange");
|
|
44
|
+
const range = endpointPair(input.range, "range");
|
|
45
|
+
const slotAtPosition = (position) => {
|
|
46
|
+
finite(position, "position");
|
|
47
|
+
return logicalRange[0] + (position - range[0]) * (logicalRange[1] - logicalRange[0]) / (range[1] - range[0]);
|
|
48
|
+
};
|
|
49
|
+
const positionAtSlot = (slot) => range[0] + (slot - logicalRange[0]) * (range[1] - range[0]) / (logicalRange[1] - logicalRange[0]);
|
|
50
|
+
const slotAtTime = (time) => {
|
|
51
|
+
if (!Number.isSafeInteger(time) || Math.abs(time) > DATE_LIMIT)
|
|
52
|
+
return void 0;
|
|
53
|
+
const index = indexOf(timestamps, time);
|
|
54
|
+
return index < 0 ? void 0 : index;
|
|
55
|
+
};
|
|
56
|
+
return Object.freeze({
|
|
57
|
+
mapTime(time) {
|
|
58
|
+
const slot = slotAtTime(time);
|
|
59
|
+
if (slot === void 0)
|
|
60
|
+
throw new RangeError(
|
|
61
|
+
"TradingTimeScale cannot map an unknown timestamp."
|
|
62
|
+
);
|
|
63
|
+
return positionAtSlot(slot);
|
|
64
|
+
},
|
|
65
|
+
slotAtTime,
|
|
66
|
+
timeAtSlot(slot) {
|
|
67
|
+
if (!Number.isInteger(slot)) return void 0;
|
|
68
|
+
return timestamps[slot];
|
|
69
|
+
},
|
|
70
|
+
nearestTimeAtPosition(position) {
|
|
71
|
+
if (timestamps.length === 0) return void 0;
|
|
72
|
+
const slot = slotAtPosition(position);
|
|
73
|
+
const earlier = Math.floor(slot);
|
|
74
|
+
const index = Math.max(
|
|
75
|
+
0,
|
|
76
|
+
Math.min(
|
|
77
|
+
timestamps.length - 1,
|
|
78
|
+
earlier + (slot - earlier > 0.5 ? 1 : 0)
|
|
79
|
+
)
|
|
80
|
+
);
|
|
81
|
+
return timestamps[index];
|
|
82
|
+
},
|
|
83
|
+
slotAtPosition
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
export {
|
|
87
|
+
createTradingTimeMapping
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=trading-time-mapping.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/features/viz/lib/trading-time-mapping.ts"],
|
|
4
|
+
"sourcesContent": ["const DATE_LIMIT = 8_640_000_000_000_000;\n\n/** Input used to resolve gapless trading-time coordinates. */\nexport interface TradingTimeMappingInput {\n /** Strictly increasing, unique UTC millisecond observations. */\n readonly timestamps: readonly number[];\n /** Visible logical slot endpoints; fractional values reserve viewport whitespace. */\n readonly logicalRange: readonly [number, number];\n /** Physical local-coordinate endpoints. */\n readonly range: readonly [number, number];\n}\n\n/** Immutable conversion operations for one owned trading-time observation list. */\nexport interface TradingTimeMapping {\n /** Maps an exact supplied timestamp to its physical local coordinate. */\n mapTime(time: number): number;\n /** Finds an exact supplied timestamp's consecutive logical slot. */\n slotAtTime(time: number): number | undefined;\n /** Finds the supplied timestamp at an exact integer logical slot. */\n timeAtSlot(slot: number): number | undefined;\n /** Selects the nearest supplied timestamp to a physical coordinate. */\n nearestTimeAtPosition(position: number): number | undefined;\n /** Inverts a physical coordinate to a possibly fractional logical slot. */\n slotAtPosition(position: number): number;\n}\n\nfunction finite(value: number, name: string): number {\n if (typeof value !== \"number\" || !Number.isFinite(value))\n throw new RangeError(`${name} must be finite.`);\n return value;\n}\n\nfunction endpointPair(\n value: readonly [number, number],\n name: string,\n): readonly [number, number] {\n const first = finite(value[0], `${name}[0]`);\n const second = finite(value[1], `${name}[1]`);\n if (first === second) throw new RangeError(`${name} endpoints must differ.`);\n return Object.freeze([first, second]);\n}\n\nfunction timestamp(value: number, index: number): number {\n if (!Number.isSafeInteger(value) || Math.abs(value) > DATE_LIMIT)\n throw new RangeError(\n `timestamps[${index}] must be safe integers within Date range UTC milliseconds.`,\n );\n return value;\n}\n\nfunction indexOf(timestamps: readonly number[], time: number): number {\n let first = 0;\n let last = timestamps.length - 1;\n while (first <= last) {\n const middle = first + Math.floor((last - first) / 2);\n const candidate = timestamps[middle]!;\n if (candidate === time) return middle;\n if (candidate < time) first = middle + 1;\n else last = middle - 1;\n }\n return -1;\n}\n\n/**\n * Creates pure mappings between exact supplied UTC observations, logical slots, and local positions.\n *\n * The mapping owns a frozen copy of timestamps. It creates no timestamps for gaps: exact mapping\n * rejects unknown values, while inverse position mapping can intentionally produce fractional slots.\n *\n * @param input - Observation timestamps plus logical and physical viewport endpoints.\n * @returns Immutable mapping operations with logarithmic timestamp lookup and constant-time slot lookup.\n */\nexport function createTradingTimeMapping(\n input: TradingTimeMappingInput,\n): TradingTimeMapping {\n const timestamps = input.timestamps.map((value, index) =>\n timestamp(value, index),\n );\n for (let index = 1; index < timestamps.length; index++) {\n if (timestamps[index - 1]! >= timestamps[index]!)\n throw new RangeError(\n \"timestamps must be strictly increasing and unique.\",\n );\n }\n Object.freeze(timestamps);\n const logicalRange = endpointPair(input.logicalRange, \"logicalRange\");\n const range = endpointPair(input.range, \"range\");\n const slotAtPosition = (position: number): number => {\n finite(position, \"position\");\n return (\n logicalRange[0] +\n ((position - range[0]) * (logicalRange[1] - logicalRange[0])) /\n (range[1] - range[0])\n );\n };\n const positionAtSlot = (slot: number): number =>\n range[0] +\n ((slot - logicalRange[0]) * (range[1] - range[0])) /\n (logicalRange[1] - logicalRange[0]);\n const slotAtTime = (time: number): number | undefined => {\n if (!Number.isSafeInteger(time) || Math.abs(time) > DATE_LIMIT)\n return undefined;\n const index = indexOf(timestamps, time);\n return index < 0 ? undefined : index;\n };\n return Object.freeze({\n mapTime(time: number): number {\n const slot = slotAtTime(time);\n if (slot === undefined)\n throw new RangeError(\n \"TradingTimeScale cannot map an unknown timestamp.\",\n );\n return positionAtSlot(slot);\n },\n slotAtTime,\n timeAtSlot(slot: number): number | undefined {\n if (!Number.isInteger(slot)) return undefined;\n return timestamps[slot];\n },\n nearestTimeAtPosition(position: number): number | undefined {\n if (timestamps.length === 0) return undefined;\n const slot = slotAtPosition(position);\n const earlier = Math.floor(slot);\n const index = Math.max(\n 0,\n Math.min(\n timestamps.length - 1,\n earlier + (slot - earlier > 0.5 ? 1 : 0),\n ),\n );\n return timestamps[index];\n },\n slotAtPosition,\n });\n}\n"],
|
|
5
|
+
"mappings": "AAAA,MAAM,aAAa;AA0BnB,SAAS,OAAO,OAAe,MAAsB;AACnD,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK;AACrD,UAAM,IAAI,WAAW,GAAG,IAAI,kBAAkB;AAChD,SAAO;AACT;AAEA,SAAS,aACP,OACA,MAC2B;AAC3B,QAAM,QAAQ,OAAO,MAAM,CAAC,GAAG,GAAG,IAAI,KAAK;AAC3C,QAAM,SAAS,OAAO,MAAM,CAAC,GAAG,GAAG,IAAI,KAAK;AAC5C,MAAI,UAAU,OAAQ,OAAM,IAAI,WAAW,GAAG,IAAI,yBAAyB;AAC3E,SAAO,OAAO,OAAO,CAAC,OAAO,MAAM,CAAC;AACtC;AAEA,SAAS,UAAU,OAAe,OAAuB;AACvD,MAAI,CAAC,OAAO,cAAc,KAAK,KAAK,KAAK,IAAI,KAAK,IAAI;AACpD,UAAM,IAAI;AAAA,MACR,cAAc,KAAK;AAAA,IACrB;AACF,SAAO;AACT;AAEA,SAAS,QAAQ,YAA+B,MAAsB;AACpE,MAAI,QAAQ;AACZ,MAAI,OAAO,WAAW,SAAS;AAC/B,SAAO,SAAS,MAAM;AACpB,UAAM,SAAS,QAAQ,KAAK,OAAO,OAAO,SAAS,CAAC;AACpD,UAAM,YAAY,WAAW,MAAM;AACnC,QAAI,cAAc,KAAM,QAAO;AAC/B,QAAI,YAAY,KAAM,SAAQ,SAAS;AAAA,QAClC,QAAO,SAAS;AAAA,EACvB;AACA,SAAO;AACT;AAWO,SAAS,yBACd,OACoB;AACpB,QAAM,aAAa,MAAM,WAAW;AAAA,IAAI,CAAC,OAAO,UAC9C,UAAU,OAAO,KAAK;AAAA,EACxB;AACA,WAAS,QAAQ,GAAG,QAAQ,WAAW,QAAQ,SAAS;AACtD,QAAI,WAAW,QAAQ,CAAC,KAAM,WAAW,KAAK;AAC5C,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,EACJ;AACA,SAAO,OAAO,UAAU;AACxB,QAAM,eAAe,aAAa,MAAM,cAAc,cAAc;AACpE,QAAM,QAAQ,aAAa,MAAM,OAAO,OAAO;AAC/C,QAAM,iBAAiB,CAAC,aAA6B;AACnD,WAAO,UAAU,UAAU;AAC3B,WACE,aAAa,CAAC,KACZ,WAAW,MAAM,CAAC,MAAM,aAAa,CAAC,IAAI,aAAa,CAAC,MACvD,MAAM,CAAC,IAAI,MAAM,CAAC;AAAA,EAEzB;AACA,QAAM,iBAAiB,CAAC,SACtB,MAAM,CAAC,KACL,OAAO,aAAa,CAAC,MAAM,MAAM,CAAC,IAAI,MAAM,CAAC,MAC5C,aAAa,CAAC,IAAI,aAAa,CAAC;AACrC,QAAM,aAAa,CAAC,SAAqC;AACvD,QAAI,CAAC,OAAO,cAAc,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI;AAClD,aAAO;AACT,UAAM,QAAQ,QAAQ,YAAY,IAAI;AACtC,WAAO,QAAQ,IAAI,SAAY;AAAA,EACjC;AACA,SAAO,OAAO,OAAO;AAAA,IACnB,QAAQ,MAAsB;AAC5B,YAAM,OAAO,WAAW,IAAI;AAC5B,UAAI,SAAS;AACX,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AACF,aAAO,eAAe,IAAI;AAAA,IAC5B;AAAA,IACA;AAAA,IACA,WAAW,MAAkC;AAC3C,UAAI,CAAC,OAAO,UAAU,IAAI,EAAG,QAAO;AACpC,aAAO,WAAW,IAAI;AAAA,IACxB;AAAA,IACA,sBAAsB,UAAsC;AAC1D,UAAI,WAAW,WAAW,EAAG,QAAO;AACpC,YAAM,OAAO,eAAe,QAAQ;AACpC,YAAM,UAAU,KAAK,MAAM,IAAI;AAC/B,YAAM,QAAQ,KAAK;AAAA,QACjB;AAAA,QACA,KAAK;AAAA,UACH,WAAW,SAAS;AAAA,UACpB,WAAW,OAAO,UAAU,MAAM,IAAI;AAAA,QACxC;AAAA,MACF;AACA,aAAO,WAAW,KAAK;AAAA,IACzB;AAAA,IACA;AAAA,EACF,CAAC;AACH;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|