@perspective-dev/viewer-charts 4.3.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/LICENSE.md +193 -0
- package/dist/cdn/perspective-viewer-charts.js +3 -0
- package/dist/cdn/perspective-viewer-charts.js.map +7 -0
- package/dist/esm/axis/axis-primitives.d.ts +24 -0
- package/dist/esm/axis/bar-axis.d.ts +51 -0
- package/dist/esm/axis/canvas.d.ts +24 -0
- package/dist/esm/axis/categorical-axis-core.d.ts +42 -0
- package/dist/esm/axis/categorical-axis.d.ts +27 -0
- package/dist/esm/axis/facet-chrome.d.ts +13 -0
- package/dist/esm/axis/label-geometry.d.ts +41 -0
- package/dist/esm/axis/legend.d.ts +44 -0
- package/dist/esm/axis/numeric-axis.d.ts +20 -0
- package/dist/esm/charts/candlestick/candlestick-build.d.ts +129 -0
- package/dist/esm/charts/candlestick/candlestick-interact.d.ts +10 -0
- package/dist/esm/charts/candlestick/candlestick-render.d.ts +24 -0
- package/dist/esm/charts/candlestick/candlestick.d.ts +144 -0
- package/dist/esm/charts/candlestick/glyphs/draw-candlesticks.d.ts +36 -0
- package/dist/esm/charts/candlestick/glyphs/draw-ohlc.d.ts +33 -0
- package/dist/esm/charts/canvas-types.d.ts +15 -0
- package/dist/esm/charts/cartesian/cartesian-build.d.ts +14 -0
- package/dist/esm/charts/cartesian/cartesian-interact.d.ts +20 -0
- package/dist/esm/charts/cartesian/cartesian-render.d.ts +26 -0
- package/dist/esm/charts/cartesian/cartesian.d.ts +239 -0
- package/dist/esm/charts/cartesian/glyph.d.ts +53 -0
- package/dist/esm/charts/cartesian/glyphs/density.d.ts +142 -0
- package/dist/esm/charts/cartesian/glyphs/lines.d.ts +23 -0
- package/dist/esm/charts/cartesian/glyphs/points.d.ts +24 -0
- package/dist/esm/charts/cartesian/label-interner.d.ts +21 -0
- package/dist/esm/charts/cartesian/tooltip-lines.d.ts +11 -0
- package/dist/esm/charts/chart-base.d.ts +402 -0
- package/dist/esm/charts/chart.d.ts +338 -0
- package/dist/esm/charts/common/band-layout.d.ts +32 -0
- package/dist/esm/charts/common/categorical-y-chart.d.ts +53 -0
- package/dist/esm/charts/common/category-axis-resolver.d.ts +90 -0
- package/dist/esm/charts/common/chrome-cache.d.ts +18 -0
- package/dist/esm/charts/common/draw-tooltip-box.d.ts +9 -0
- package/dist/esm/charts/common/leaf-color.d.ts +33 -0
- package/dist/esm/charts/common/node-store.d.ts +81 -0
- package/dist/esm/charts/common/tree-chart.d.ts +48 -0
- package/dist/esm/charts/common/tree-chrome.d.ts +31 -0
- package/dist/esm/charts/common/tree-data.d.ts +54 -0
- package/dist/esm/charts/common/visible-extent.d.ts +51 -0
- package/dist/esm/charts/heatmap/heatmap-build.d.ts +86 -0
- package/dist/esm/charts/heatmap/heatmap-interact.d.ts +19 -0
- package/dist/esm/charts/heatmap/heatmap-render.d.ts +19 -0
- package/dist/esm/charts/heatmap/heatmap-y-axis.d.ts +46 -0
- package/dist/esm/charts/heatmap/heatmap.d.ts +117 -0
- package/dist/esm/charts/map/map.d.ts +67 -0
- package/dist/esm/charts/registry.d.ts +14 -0
- package/dist/esm/charts/series/glyphs/draw-areas.d.ts +30 -0
- package/dist/esm/charts/series/glyphs/draw-bars.d.ts +15 -0
- package/dist/esm/charts/series/glyphs/draw-lines.d.ts +34 -0
- package/dist/esm/charts/series/glyphs/draw-scatter.d.ts +33 -0
- package/dist/esm/charts/series/series-build.d.ts +228 -0
- package/dist/esm/charts/series/series-interact.d.ts +35 -0
- package/dist/esm/charts/series/series-render.d.ts +41 -0
- package/dist/esm/charts/series/series-type.d.ts +49 -0
- package/dist/esm/charts/series/series.d.ts +317 -0
- package/dist/esm/charts/sunburst/sunburst-interact.d.ts +7 -0
- package/dist/esm/charts/sunburst/sunburst-layout.d.ts +33 -0
- package/dist/esm/charts/sunburst/sunburst-render.d.ts +22 -0
- package/dist/esm/charts/sunburst/sunburst.d.ts +85 -0
- package/dist/esm/charts/treemap/treemap-interact.d.ts +12 -0
- package/dist/esm/charts/treemap/treemap-layout.d.ts +28 -0
- package/dist/esm/charts/treemap/treemap-render.d.ts +18 -0
- package/dist/esm/charts/treemap/treemap.d.ts +74 -0
- package/dist/esm/config.d.ts +27 -0
- package/dist/esm/data/lazy-row.d.ts +32 -0
- package/dist/esm/data/split-groups.d.ts +20 -0
- package/dist/esm/data/view-reader.d.ts +35 -0
- package/dist/esm/event-detail.d.ts +28 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/interaction/hit-test.d.ts +30 -0
- package/dist/esm/interaction/host-sink-dom.d.ts +19 -0
- package/dist/esm/interaction/host-sink-message.d.ts +46 -0
- package/dist/esm/interaction/lazy-tooltip.d.ts +61 -0
- package/dist/esm/interaction/raw-event-forwarder.d.ts +27 -0
- package/dist/esm/interaction/spatial-grid.d.ts +15 -0
- package/dist/esm/interaction/tooltip-controller.d.ts +193 -0
- package/dist/esm/interaction/zoom-controller.d.ts +106 -0
- package/dist/esm/interaction/zoom-router.d.ts +48 -0
- package/dist/esm/layout/facet-grid.d.ts +126 -0
- package/dist/esm/layout/plot-layout.d.ts +104 -0
- package/dist/esm/layout/ticks.d.ts +17 -0
- package/dist/esm/map/mercator.d.ts +102 -0
- package/dist/esm/map/tile-cache.d.ts +38 -0
- package/dist/esm/map/tile-layer.d.ts +66 -0
- package/dist/esm/map/tile-loader.d.ts +52 -0
- package/dist/esm/map/tile-source.d.ts +66 -0
- package/dist/esm/perspective-viewer-charts.js +3 -0
- package/dist/esm/perspective-viewer-charts.js.map +7 -0
- package/dist/esm/plugin/charts.d.ts +40 -0
- package/dist/esm/plugin/plugin.d.ts +95 -0
- package/dist/esm/render/scheduler.d.ts +41 -0
- package/dist/esm/theme/gradient.d.ts +48 -0
- package/dist/esm/theme/palette.d.ts +13 -0
- package/dist/esm/theme/theme-snapshot.d.ts +7 -0
- package/dist/esm/theme/theme.d.ts +53 -0
- package/dist/esm/transport/protocol.d.ts +430 -0
- package/dist/esm/transport/renderer-transport.d.ts +201 -0
- package/dist/esm/utils/css.d.ts +1 -0
- package/dist/esm/utils/font-snapshot.d.ts +50 -0
- package/dist/esm/webgl/buffer-pool.d.ts +62 -0
- package/dist/esm/webgl/context-manager.d.ts +184 -0
- package/dist/esm/webgl/gradient-texture.d.ts +17 -0
- package/dist/esm/webgl/instanced-attrs.d.ts +44 -0
- package/dist/esm/webgl/plot-frame.d.ts +39 -0
- package/dist/esm/webgl/program-cache.d.ts +13 -0
- package/dist/esm/webgl/shader-manifest.d.ts +53 -0
- package/dist/esm/webgl/shader-registry.d.ts +22 -0
- package/dist/esm/worker/boot.d.ts +0 -0
- package/dist/esm/worker/dispatch.d.ts +9 -0
- package/dist/esm/worker/font-loader.d.ts +2 -0
- package/dist/esm/worker/renderer.worker.d.ts +115 -0
- package/dist/esm/worker/session-host.d.ts +26 -0
- package/package.json +47 -0
- package/src/css/perspective-viewer-charts.css +95 -0
- package/src/ts/axis/axis-primitives.ts +125 -0
- package/src/ts/axis/bar-axis.ts +345 -0
- package/src/ts/axis/canvas.ts +64 -0
- package/src/ts/axis/categorical-axis-core.ts +125 -0
- package/src/ts/axis/categorical-axis.ts +716 -0
- package/src/ts/axis/facet-chrome.ts +42 -0
- package/src/ts/axis/label-geometry.ts +188 -0
- package/src/ts/axis/legend.ts +218 -0
- package/src/ts/axis/numeric-axis.ts +353 -0
- package/src/ts/charts/candlestick/candlestick-build.ts +516 -0
- package/src/ts/charts/candlestick/candlestick-interact.ts +256 -0
- package/src/ts/charts/candlestick/candlestick-render.ts +387 -0
- package/src/ts/charts/candlestick/candlestick.ts +367 -0
- package/src/ts/charts/candlestick/glyphs/draw-candlesticks.ts +432 -0
- package/src/ts/charts/candlestick/glyphs/draw-ohlc.ts +317 -0
- package/src/ts/charts/canvas-types.ts +30 -0
- package/src/ts/charts/cartesian/cartesian-build.ts +616 -0
- package/src/ts/charts/cartesian/cartesian-interact.ts +355 -0
- package/src/ts/charts/cartesian/cartesian-render.ts +948 -0
- package/src/ts/charts/cartesian/cartesian.ts +469 -0
- package/src/ts/charts/cartesian/glyph.ts +81 -0
- package/src/ts/charts/cartesian/glyphs/density.ts +1263 -0
- package/src/ts/charts/cartesian/glyphs/lines.ts +320 -0
- package/src/ts/charts/cartesian/glyphs/points.ts +239 -0
- package/src/ts/charts/cartesian/label-interner.ts +56 -0
- package/src/ts/charts/cartesian/tooltip-lines.ts +80 -0
- package/src/ts/charts/chart-base.ts +840 -0
- package/src/ts/charts/chart.ts +427 -0
- package/src/ts/charts/common/band-layout.ts +63 -0
- package/src/ts/charts/common/categorical-y-chart.ts +81 -0
- package/src/ts/charts/common/category-axis-resolver.ts +314 -0
- package/src/ts/charts/common/chrome-cache.ts +79 -0
- package/src/ts/charts/common/draw-tooltip-box.ts +84 -0
- package/src/ts/charts/common/leaf-color.ts +92 -0
- package/src/ts/charts/common/node-store.ts +235 -0
- package/src/ts/charts/common/tree-chart.ts +76 -0
- package/src/ts/charts/common/tree-chrome.ts +123 -0
- package/src/ts/charts/common/tree-data.ts +623 -0
- package/src/ts/charts/common/visible-extent.ts +112 -0
- package/src/ts/charts/heatmap/heatmap-build.ts +426 -0
- package/src/ts/charts/heatmap/heatmap-interact.ts +274 -0
- package/src/ts/charts/heatmap/heatmap-render.ts +815 -0
- package/src/ts/charts/heatmap/heatmap-y-axis.ts +351 -0
- package/src/ts/charts/heatmap/heatmap.ts +368 -0
- package/src/ts/charts/map/map.ts +201 -0
- package/src/ts/charts/registry.ts +65 -0
- package/src/ts/charts/series/glyphs/draw-areas.ts +331 -0
- package/src/ts/charts/series/glyphs/draw-bars.ts +113 -0
- package/src/ts/charts/series/glyphs/draw-lines.ts +320 -0
- package/src/ts/charts/series/glyphs/draw-scatter.ts +328 -0
- package/src/ts/charts/series/series-build.ts +848 -0
- package/src/ts/charts/series/series-interact.ts +604 -0
- package/src/ts/charts/series/series-render.ts +1109 -0
- package/src/ts/charts/series/series-type.ts +99 -0
- package/src/ts/charts/series/series.ts +794 -0
- package/src/ts/charts/sunburst/sunburst-interact.ts +460 -0
- package/src/ts/charts/sunburst/sunburst-layout.ts +238 -0
- package/src/ts/charts/sunburst/sunburst-render.ts +887 -0
- package/src/ts/charts/sunburst/sunburst.ts +248 -0
- package/src/ts/charts/treemap/treemap-interact.ts +445 -0
- package/src/ts/charts/treemap/treemap-layout.ts +328 -0
- package/src/ts/charts/treemap/treemap-render.ts +886 -0
- package/src/ts/charts/treemap/treemap.ts +247 -0
- package/src/ts/config.ts +41 -0
- package/src/ts/data/lazy-row.ts +140 -0
- package/src/ts/data/split-groups.ts +97 -0
- package/src/ts/data/view-reader.ts +107 -0
- package/src/ts/event-detail.ts +44 -0
- package/src/ts/index.ts +53 -0
- package/src/ts/interaction/hit-test.ts +106 -0
- package/src/ts/interaction/host-sink-dom.ts +85 -0
- package/src/ts/interaction/host-sink-message.ts +75 -0
- package/src/ts/interaction/lazy-tooltip.ts +102 -0
- package/src/ts/interaction/raw-event-forwarder.ts +175 -0
- package/src/ts/interaction/spatial-grid.ts +100 -0
- package/src/ts/interaction/tooltip-controller.ts +407 -0
- package/src/ts/interaction/zoom-controller.ts +468 -0
- package/src/ts/interaction/zoom-router.ts +230 -0
- package/src/ts/layout/facet-grid.ts +346 -0
- package/src/ts/layout/plot-layout.ts +277 -0
- package/src/ts/layout/ticks.ts +168 -0
- package/src/ts/map/mercator.ts +204 -0
- package/src/ts/map/tile-cache.ts +96 -0
- package/src/ts/map/tile-layer.ts +382 -0
- package/src/ts/map/tile-loader.ts +143 -0
- package/src/ts/map/tile-source.ts +156 -0
- package/src/ts/plugin/charts.ts +286 -0
- package/src/ts/plugin/plugin.ts +668 -0
- package/src/ts/render/scheduler.ts +339 -0
- package/src/ts/shaders/area.frag.glsl +20 -0
- package/src/ts/shaders/area.vert.glsl +19 -0
- package/src/ts/shaders/bar.frag.glsl +25 -0
- package/src/ts/shaders/bar.vert.glsl +60 -0
- package/src/ts/shaders/candlestick-body.frag.glsl +19 -0
- package/src/ts/shaders/candlestick-body.vert.glsl +34 -0
- package/src/ts/shaders/density-extreme.frag.glsl +30 -0
- package/src/ts/shaders/density-mrt.frag.glsl +44 -0
- package/src/ts/shaders/density-mrt.vert.glsl +48 -0
- package/src/ts/shaders/density-resolve.frag.glsl +89 -0
- package/src/ts/shaders/density-resolve.vert.glsl +23 -0
- package/src/ts/shaders/density-splat.frag.glsl +34 -0
- package/src/ts/shaders/density-splat.vert.glsl +52 -0
- package/src/ts/shaders/gridline.frag.glsl +18 -0
- package/src/ts/shaders/gridline.vert.glsl +18 -0
- package/src/ts/shaders/heatmap.frag.glsl +23 -0
- package/src/ts/shaders/heatmap.vert.glsl +42 -0
- package/src/ts/shaders/line-uniform.frag.glsl +26 -0
- package/src/ts/shaders/line-uniform.vert.glsl +54 -0
- package/src/ts/shaders/line.frag.glsl +28 -0
- package/src/ts/shaders/line.vert.glsl +87 -0
- package/src/ts/shaders/scatter.frag.glsl +39 -0
- package/src/ts/shaders/scatter.vert.glsl +67 -0
- package/src/ts/shaders/sunburst-arc.frag.glsl +19 -0
- package/src/ts/shaders/sunburst-arc.vert.glsl +79 -0
- package/src/ts/shaders/tile.frag.glsl +27 -0
- package/src/ts/shaders/tile.vert.glsl +35 -0
- package/src/ts/shaders/treemap.frag.glsl +19 -0
- package/src/ts/shaders/treemap.vert.glsl +25 -0
- package/src/ts/shaders/y-scatter.frag.glsl +30 -0
- package/src/ts/shaders/y-scatter.vert.glsl +31 -0
- package/src/ts/theme/gradient.ts +312 -0
- package/src/ts/theme/palette.ts +64 -0
- package/src/ts/theme/theme-snapshot.ts +66 -0
- package/src/ts/theme/theme.ts +166 -0
- package/src/ts/transport/protocol.ts +497 -0
- package/src/ts/transport/renderer-transport.ts +788 -0
- package/src/ts/utils/css.ts +36 -0
- package/src/ts/utils/font-snapshot.ts +159 -0
- package/src/ts/webgl/buffer-pool.ts +163 -0
- package/src/ts/webgl/context-manager.ts +414 -0
- package/src/ts/webgl/gradient-texture.ts +84 -0
- package/src/ts/webgl/instanced-attrs.ts +139 -0
- package/src/ts/webgl/plot-frame.ts +91 -0
- package/src/ts/webgl/program-cache.ts +46 -0
- package/src/ts/webgl/shader-manifest.ts +148 -0
- package/src/ts/webgl/shader-registry.ts +97 -0
- package/src/ts/worker/boot.ts +22 -0
- package/src/ts/worker/dispatch.ts +99 -0
- package/src/ts/worker/font-loader.ts +89 -0
- package/src/ts/worker/renderer.worker.ts +734 -0
- package/src/ts/worker/session-host.ts +118 -0
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
2
|
+
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
|
3
|
+
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
|
4
|
+
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
|
5
|
+
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
|
6
|
+
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
7
|
+
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
|
8
|
+
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
|
9
|
+
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
|
10
|
+
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
|
+
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
|
+
|
|
13
|
+
import type { ColumnDataMap } from "../../data/view-reader";
|
|
14
|
+
import type { WebGLContextManager } from "../../webgl/context-manager";
|
|
15
|
+
import { CategoricalYChart } from "../common/categorical-y-chart";
|
|
16
|
+
import {
|
|
17
|
+
buildCandlestickPipeline,
|
|
18
|
+
emptyCandleColumns,
|
|
19
|
+
type CandleColumns,
|
|
20
|
+
type CandleSeriesInfo,
|
|
21
|
+
type NumericCategoryDomain,
|
|
22
|
+
} from "./candlestick-build";
|
|
23
|
+
import {
|
|
24
|
+
renderCandlestickFrame,
|
|
25
|
+
renderCandlestickChromeOverlay,
|
|
26
|
+
invalidateGlyphBuffers,
|
|
27
|
+
rebuildGlyphBuffers,
|
|
28
|
+
ensureUpDownColors,
|
|
29
|
+
} from "./candlestick-render";
|
|
30
|
+
import {
|
|
31
|
+
handleCandlestickHover,
|
|
32
|
+
showCandlestickPinnedTooltip,
|
|
33
|
+
} from "./candlestick-interact";
|
|
34
|
+
import { BodyWickGlyph } from "./glyphs/draw-candlesticks";
|
|
35
|
+
import { OHLCGlyph } from "./glyphs/draw-ohlc";
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Per-frame memo of the auto-fit Y extent for a {@link CandlestickChart},
|
|
39
|
+
* keyed on the visible X window. Hover-only redraws hit the cache.
|
|
40
|
+
*/
|
|
41
|
+
export interface CandlestickAutoFitCache {
|
|
42
|
+
// Cache key — the categorical (X) window.
|
|
43
|
+
xMin: number;
|
|
44
|
+
xMax: number;
|
|
45
|
+
|
|
46
|
+
// VisibleExtent payload — value axis min/max + hasFit flag.
|
|
47
|
+
min: number;
|
|
48
|
+
max: number;
|
|
49
|
+
hasFit: boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface CandlestickLocations {
|
|
53
|
+
u_proj_left: WebGLUniformLocation | null;
|
|
54
|
+
u_proj_right: WebGLUniformLocation | null;
|
|
55
|
+
u_hover_series: WebGLUniformLocation | null;
|
|
56
|
+
a_corner: number;
|
|
57
|
+
a_x_center: number;
|
|
58
|
+
a_half_width: number;
|
|
59
|
+
a_y0: number;
|
|
60
|
+
a_y1: number;
|
|
61
|
+
a_color: number;
|
|
62
|
+
a_series_id: number;
|
|
63
|
+
a_axis: number;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Candlestick / OHLC chart. Both plugins (`y-candlestick`, `y-ohlc`)
|
|
68
|
+
* share this class — the only per-plugin difference is
|
|
69
|
+
* `_defaultChartType` (`"candlestick"` vs `"ohlc"`), which
|
|
70
|
+
* {@link renderCandlestickFrame} uses to pick the glyph draw function.
|
|
71
|
+
*
|
|
72
|
+
* Fields are package-internal (no `private`) so helper modules in this
|
|
73
|
+
* folder can read/write them.
|
|
74
|
+
*/
|
|
75
|
+
export class CandlestickChart extends CategoricalYChart {
|
|
76
|
+
_locations: CandlestickLocations | null = null;
|
|
77
|
+
|
|
78
|
+
// `_rowPaths`, `_numCategories`, `_rowOffset`, `_program`,
|
|
79
|
+
// `_cornerBuffer`, `_lastLayout`, `_lastXDomain`, `_lastYDomain`,
|
|
80
|
+
// and `_lastYTicks` all live on `CategoricalYChart`.
|
|
81
|
+
_splitPrefixes: string[] = [];
|
|
82
|
+
_series: CandleSeriesInfo[] = [];
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Columnar candle records. Indexed in `[0, _candles.count)`.
|
|
86
|
+
* Replaces the legacy `CandleRecord[]` to avoid per-record POJO
|
|
87
|
+
* allocation on data load.
|
|
88
|
+
*/
|
|
89
|
+
_candles: CandleColumns = emptyCandleColumns();
|
|
90
|
+
|
|
91
|
+
_yDomain: { min: number; max: number } = { min: 0, max: 1 };
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* `domain_mode: "expand"` accumulators. Hold the running union of
|
|
95
|
+
* the value-axis (and, in numeric-category mode, category-axis)
|
|
96
|
+
* extent across data loads. Cleared in `resetExpandedDomain` —
|
|
97
|
+
* wired from the worker's `resetAllZooms` and from view-config
|
|
98
|
+
* mutations on `AbstractChart`. `null` whenever the option is
|
|
99
|
+
* `"fit"` or the accumulator has just been cleared.
|
|
100
|
+
*/
|
|
101
|
+
_expandedYDomain: { min: number; max: number } | null = null;
|
|
102
|
+
_expandedCategoryDomain: { min: number; max: number } | null = null;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Numeric category-axis state (single non-string group_by).
|
|
106
|
+
*/
|
|
107
|
+
_categoryAxisMode: "category" | "numeric" = "category";
|
|
108
|
+
_numericCategoryDomain: NumericCategoryDomain | null = null;
|
|
109
|
+
_categoryPositions: Float64Array | null = null;
|
|
110
|
+
_lastCatTicks: number[] | null = null;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Origin used to rebase candle xCenters before f32 narrowing — see {@link SeriesChart._categoryOrigin}.
|
|
114
|
+
*/
|
|
115
|
+
_categoryOrigin = 0;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Gradient-sampled colors for the up (close ≥ open) / down sides.
|
|
119
|
+
* Cached via `_upDownColorKey` — only `restyle()` (which clears the
|
|
120
|
+
* theme cache) or a data load forces re-sampling.
|
|
121
|
+
*/
|
|
122
|
+
_upColor: [number, number, number] = [0, 0.8, 0.4];
|
|
123
|
+
_downColor: [number, number, number] = [0.8, 0.2, 0.2];
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Identity of the gradient-stops reference last used to sample the
|
|
127
|
+
* up/down colors. When this matches the current `theme.gradientStops`
|
|
128
|
+
* reference, `ensureUpDownColors` short-circuits.
|
|
129
|
+
*/
|
|
130
|
+
_upDownColorKey: unknown = null;
|
|
131
|
+
|
|
132
|
+
_hoveredIdx = -1;
|
|
133
|
+
_pinnedIdx = -1;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Typed glyph composition. Each glyph owns its own program cache
|
|
137
|
+
* and persistent vertex buffers privately; the chart routes
|
|
138
|
+
* draw/rebuild/invalidate via `_glyphs`. `_defaultChartType`
|
|
139
|
+
* (`"candlestick"` vs `"ohlc"`) selects which glyph the frame
|
|
140
|
+
* builder dispatches to.
|
|
141
|
+
*/
|
|
142
|
+
readonly _glyphs = {
|
|
143
|
+
bodyWick: new BodyWickGlyph(),
|
|
144
|
+
ohlc: new OHLCGlyph(),
|
|
145
|
+
} as const;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Auto-fit the price (Y) axis to the `low`/`high` extent of
|
|
149
|
+
* candles whose `xCenter` falls inside the visible X window. Pairs
|
|
150
|
+
* with the locked Y axis: the lock means user input can't zoom Y
|
|
151
|
+
* directly, auto-fit is what actually moves it as the user scrolls
|
|
152
|
+
* through time. Default: on (financial-chart convention).
|
|
153
|
+
*/
|
|
154
|
+
override _autoFitValue = true;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Per-frame memo of the auto-fit Y extent keyed on the visible X
|
|
158
|
+
* window. Hover-only redraws (X window unchanged) hit the cache.
|
|
159
|
+
* Reset to null on data upload.
|
|
160
|
+
*/
|
|
161
|
+
_autoFitCache: CandlestickAutoFitCache | null = null;
|
|
162
|
+
|
|
163
|
+
protected override tooltipCallbacks() {
|
|
164
|
+
return {
|
|
165
|
+
onHover: (mx: number, my: number) =>
|
|
166
|
+
handleCandlestickHover(this, mx, my),
|
|
167
|
+
onLeave: () => {
|
|
168
|
+
if (this._hoveredIdx !== -1) {
|
|
169
|
+
this._hoveredIdx = -1;
|
|
170
|
+
|
|
171
|
+
// Hover state only affects the chrome overlay
|
|
172
|
+
// (tooltip box) — the WebGL pass is unchanged. Skip
|
|
173
|
+
// the full repaint (which would rebuild glyph
|
|
174
|
+
// buffers and shake out one more frame of latency).
|
|
175
|
+
renderCandlestickChromeOverlay(this);
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
onPin: (mx: number, my: number) => {
|
|
179
|
+
// Refresh the hit-test at the click coords so the pin
|
|
180
|
+
// path doesn't depend on the RAF-throttled hover state
|
|
181
|
+
// — see comment in `series.ts` `onPin`.
|
|
182
|
+
handleCandlestickHover(this, mx, my);
|
|
183
|
+
if (this._hoveredIdx >= 0) {
|
|
184
|
+
const idx = this._hoveredIdx;
|
|
185
|
+
showCandlestickPinnedTooltip(this, idx);
|
|
186
|
+
void this._emitCandleClickSelect(idx);
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
onUnpin: () => {
|
|
190
|
+
this.emitUnselect();
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Resolve a clicked candle into a `PerspectiveClickDetail` and
|
|
197
|
+
* emit both `perspective-click` and
|
|
198
|
+
* `perspective-global-filter selected:true`.
|
|
199
|
+
*
|
|
200
|
+
* One candle per (catIdx, splitIdx). Like the series pipeline,
|
|
201
|
+
* `catIdx + _rowOffset` is the source-view row; the column name is
|
|
202
|
+
* the Close column (the canonical "y" target for OHLC). Group-by
|
|
203
|
+
* values come from `_rowPaths`; split-by values come from
|
|
204
|
+
* `_splitPrefixes[splitIdx]` split on `|`.
|
|
205
|
+
*/
|
|
206
|
+
private async _emitCandleClickSelect(idx: number): Promise<void> {
|
|
207
|
+
if (idx < 0 || idx >= this._candles.count) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const catIdx = this._candles.catIdx[idx];
|
|
212
|
+
const splitIdx = this._candles.splitIdx[idx];
|
|
213
|
+
const groupByValues: (string | null)[] = this._rowPaths.map(
|
|
214
|
+
(level) => level.labels[catIdx] ?? null,
|
|
215
|
+
);
|
|
216
|
+
const splitKey = this._splitPrefixes[splitIdx] ?? "";
|
|
217
|
+
const splitByValues =
|
|
218
|
+
this._splitBy.length > 0 && splitKey !== ""
|
|
219
|
+
? splitKey.split("|")
|
|
220
|
+
: [];
|
|
221
|
+
|
|
222
|
+
// OHLC plugins put Close in slot 1 (FIN_NAMES = ["Open",
|
|
223
|
+
// "Close", "High", "Low", "Tooltip"]). Fall back to the first
|
|
224
|
+
// non-null slot if Close isn't configured.
|
|
225
|
+
const columnName =
|
|
226
|
+
this._columnSlots[1] ||
|
|
227
|
+
this._columnSlots.find((s): s is string => !!s) ||
|
|
228
|
+
"";
|
|
229
|
+
|
|
230
|
+
await this.emitClickAndSelect({
|
|
231
|
+
rowIdx: catIdx + this._rowOffset,
|
|
232
|
+
columnName,
|
|
233
|
+
groupByValues,
|
|
234
|
+
splitByValues,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
override invalidateTheme(): void {
|
|
239
|
+
super.invalidateTheme();
|
|
240
|
+
|
|
241
|
+
// Up/down colors are sampled from `theme.gradientStops`. Drop the
|
|
242
|
+
// identity key so the next render re-samples after a `restyle()`.
|
|
243
|
+
this._upDownColorKey = null;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
async uploadAndRender(
|
|
247
|
+
glManager: WebGLContextManager,
|
|
248
|
+
columns: ColumnDataMap,
|
|
249
|
+
startRow: number,
|
|
250
|
+
endRow: number,
|
|
251
|
+
): Promise<void> {
|
|
252
|
+
this._glManager = glManager;
|
|
253
|
+
if (startRow !== 0) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const result = buildCandlestickPipeline({
|
|
258
|
+
columns,
|
|
259
|
+
numRows: endRow,
|
|
260
|
+
columnSlots: this._columnSlots,
|
|
261
|
+
groupBy: this._groupBy,
|
|
262
|
+
splitBy: this._splitBy,
|
|
263
|
+
groupByTypes: this._groupByTypes,
|
|
264
|
+
bandInnerFrac: this._pluginConfig.band_inner_frac,
|
|
265
|
+
barInnerPad: this._pluginConfig.bar_inner_pad,
|
|
266
|
+
scratchCandles: this._candles,
|
|
267
|
+
});
|
|
268
|
+
// `domain_mode: "expand"` post-build union — mirrors the series
|
|
269
|
+
// pipeline. Mutate the pipeline result in place so the
|
|
270
|
+
// assignments below pick up the grown extent automatically.
|
|
271
|
+
if (this._pluginConfig.domain_mode === "expand") {
|
|
272
|
+
if (this._expandedYDomain) {
|
|
273
|
+
result.yDomain.min = Math.min(
|
|
274
|
+
this._expandedYDomain.min,
|
|
275
|
+
result.yDomain.min,
|
|
276
|
+
);
|
|
277
|
+
result.yDomain.max = Math.max(
|
|
278
|
+
this._expandedYDomain.max,
|
|
279
|
+
result.yDomain.max,
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
this._expandedYDomain = { ...result.yDomain };
|
|
284
|
+
|
|
285
|
+
if (result.numericCategoryDomain) {
|
|
286
|
+
if (this._expandedCategoryDomain) {
|
|
287
|
+
result.numericCategoryDomain.min = Math.min(
|
|
288
|
+
this._expandedCategoryDomain.min,
|
|
289
|
+
result.numericCategoryDomain.min,
|
|
290
|
+
);
|
|
291
|
+
result.numericCategoryDomain.max = Math.max(
|
|
292
|
+
this._expandedCategoryDomain.max,
|
|
293
|
+
result.numericCategoryDomain.max,
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
this._expandedCategoryDomain = {
|
|
298
|
+
min: result.numericCategoryDomain.min,
|
|
299
|
+
max: result.numericCategoryDomain.max,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
} else {
|
|
303
|
+
this._expandedYDomain = null;
|
|
304
|
+
this._expandedCategoryDomain = null;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
this._rowPaths = result.rowPaths;
|
|
308
|
+
this._numCategories = result.numCategories;
|
|
309
|
+
this._rowOffset = result.rowOffset;
|
|
310
|
+
this._splitPrefixes = result.splitPrefixes;
|
|
311
|
+
this._series = result.series;
|
|
312
|
+
this._candles = result.candles;
|
|
313
|
+
this._yDomain = result.yDomain;
|
|
314
|
+
this._categoryAxisMode = result.axisMode.mode;
|
|
315
|
+
this._numericCategoryDomain = result.numericCategoryDomain;
|
|
316
|
+
this._categoryPositions = result.categoryPositions;
|
|
317
|
+
this._categoryOrigin = result.numericCategoryDomain?.min ?? 0;
|
|
318
|
+
|
|
319
|
+
// New candles invalidate any auto-fit extent memo. Color key
|
|
320
|
+
// stays — gradient stops are theme-bound, not data-bound — but
|
|
321
|
+
// the persistent vertex buffers must be rebuilt to reflect the
|
|
322
|
+
// new candle set.
|
|
323
|
+
this._autoFitCache = null;
|
|
324
|
+
|
|
325
|
+
// Resolve up/down colors (cheap on cache hit) before rebuilding
|
|
326
|
+
// glyph buffers so the persistent body buffer captures the
|
|
327
|
+
// correct per-candle RGB. Then rebuild buffers.
|
|
328
|
+
ensureUpDownColors(this);
|
|
329
|
+
invalidateGlyphBuffers(this);
|
|
330
|
+
rebuildGlyphBuffers(this, glManager);
|
|
331
|
+
|
|
332
|
+
await this.requestRender(glManager);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
_fullRender(glManager: WebGLContextManager): void {
|
|
336
|
+
this._glManager = glManager;
|
|
337
|
+
renderCandlestickFrame(this, glManager);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
override resetExpandedDomain(): void {
|
|
341
|
+
this._expandedYDomain = null;
|
|
342
|
+
this._expandedCategoryDomain = null;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
protected destroyInternal(): void {
|
|
346
|
+
if (this._glManager) {
|
|
347
|
+
const gl = this._glManager.gl;
|
|
348
|
+
if (this._cornerBuffer) {
|
|
349
|
+
gl.deleteBuffer(this._cornerBuffer);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Each glyph owns its program-local GPU resources +
|
|
353
|
+
// persistent vertex buffers; `destroy` frees both.
|
|
354
|
+
this._glyphs.bodyWick.destroy(this);
|
|
355
|
+
this._glyphs.ohlc.destroy(this);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
this._program = null;
|
|
359
|
+
this._locations = null;
|
|
360
|
+
this._cornerBuffer = null;
|
|
361
|
+
this._candles = emptyCandleColumns();
|
|
362
|
+
this._series = [];
|
|
363
|
+
this._rowPaths = [];
|
|
364
|
+
this._numCategories = 0;
|
|
365
|
+
this._upDownColorKey = null;
|
|
366
|
+
}
|
|
367
|
+
}
|