@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,20 @@
|
|
|
1
|
+
import type { ColumnDataMap } from "./view-reader";
|
|
2
|
+
export interface SplitGroup {
|
|
3
|
+
/**
|
|
4
|
+
* Composite prefix (e.g., "East", "East|Enterprise" for multi-level).
|
|
5
|
+
*/
|
|
6
|
+
prefix: string;
|
|
7
|
+
/**
|
|
8
|
+
* Map of base column name → full Arrow column name ("prefix|base").
|
|
9
|
+
*/
|
|
10
|
+
colNames: Map<string, string>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Group Arrow column names by their split prefix (everything before the
|
|
14
|
+
* last "|"). A split exists for a prefix only when every `requiredBases`
|
|
15
|
+
* entry has a non-empty column present for that prefix. `optionalBases`
|
|
16
|
+
* are included when present but do not gate group inclusion.
|
|
17
|
+
*
|
|
18
|
+
* Empty/falsy entries in either base list are skipped.
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildSplitGroups(columns: ColumnDataMap, requiredBases: string[], optionalBases?: string[]): SplitGroup[];
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { View } from "@perspective-dev/client";
|
|
2
|
+
export interface ColumnData {
|
|
3
|
+
type: "float32" | "float64" | "int32" | "string";
|
|
4
|
+
values?: Float32Array | Float64Array | Int32Array;
|
|
5
|
+
/**
|
|
6
|
+
* Dictionary key indices for string columns.
|
|
7
|
+
*/
|
|
8
|
+
indices?: Int32Array;
|
|
9
|
+
/**
|
|
10
|
+
* Dictionary values for string columns.
|
|
11
|
+
*/
|
|
12
|
+
dictionary?: string[];
|
|
13
|
+
/**
|
|
14
|
+
* Arrow validity bitfield (1 bit per row).
|
|
15
|
+
*/
|
|
16
|
+
valid?: Uint8Array;
|
|
17
|
+
}
|
|
18
|
+
export type ColumnDataMap = Map<string, ColumnData>;
|
|
19
|
+
export interface TypedArrayWindowOptions {
|
|
20
|
+
start_row?: number;
|
|
21
|
+
end_row?: number;
|
|
22
|
+
start_col?: number;
|
|
23
|
+
end_col?: number;
|
|
24
|
+
float32?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Fetches all columns from a View using `with_typed_arrays` and
|
|
28
|
+
* builds a `ColumnDataMap`. The `values` typed arrays and `valid`
|
|
29
|
+
* bitmaps are zero-copy views into WASM memory and remain valid only
|
|
30
|
+
* for the duration of the `render` callback — if `render` returns a
|
|
31
|
+
* `Promise`, the underlying `with_typed_arrays` call awaits it before
|
|
32
|
+
* releasing the backing Arrow buffer. Callers must not retain any
|
|
33
|
+
* `ColumnData` reference past `render`'s resolution.
|
|
34
|
+
*/
|
|
35
|
+
export declare function viewToColumnDataMap(view: View, render: (data: ColumnDataMap) => void | Promise<void>, options?: TypedArrayWindowOptions): Promise<void>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ViewConfig } from "@perspective-dev/client";
|
|
2
|
+
/**
|
|
3
|
+
* Detail payload for the `perspective-click` CustomEvent dispatched on
|
|
4
|
+
* the `<perspective-viewer>` host when the user clicks a chart glyph.
|
|
5
|
+
* Shape matches the equivalent type in `@perspective-dev/viewer-datagrid`
|
|
6
|
+
* so consumers can listen to either plugin uniformly.
|
|
7
|
+
*/
|
|
8
|
+
export interface PerspectiveClickDetail {
|
|
9
|
+
/**
|
|
10
|
+
* Source-view row data — keys are column names, values are scalar
|
|
11
|
+
* cell values. Empty `{}` when the click hit a non-leaf aggregate
|
|
12
|
+
* (e.g. a treemap branch).
|
|
13
|
+
*/
|
|
14
|
+
row: Record<string, unknown>;
|
|
15
|
+
/**
|
|
16
|
+
* Aggregate column(s) the click targeted. Single-entry for series /
|
|
17
|
+
* heatmap / tree charts; multi-entry would only appear for plugins
|
|
18
|
+
* that surface multiple measures per glyph (none today).
|
|
19
|
+
*/
|
|
20
|
+
column_names: string[];
|
|
21
|
+
/**
|
|
22
|
+
* Pre-built `viewer.restore({ filter })` patch — concatenates the
|
|
23
|
+
* group_by and split_by pivot values at the click target as
|
|
24
|
+
* `[<col>, "==", <value>]` clauses.
|
|
25
|
+
*/
|
|
26
|
+
config: Partial<ViewConfig>;
|
|
27
|
+
}
|
|
28
|
+
export { PerspectiveSelectDetail } from "@perspective-dev/viewer/src/ts/extensions.js";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface HitBounds {
|
|
2
|
+
xMin: number;
|
|
3
|
+
xMax: number;
|
|
4
|
+
yMin: number;
|
|
5
|
+
yMax: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Wraps SpatialGrid with dirty-flag bookkeeping + the cell-size heuristic
|
|
9
|
+
* (~√n cells), so chart code no longer repeats the insertion loop scaffold.
|
|
10
|
+
* Callers drive the iteration through `rebuild` and the `visit` callback,
|
|
11
|
+
* which lets scatter (flat array) and line (series-indexed array) share
|
|
12
|
+
* the same code path.
|
|
13
|
+
*/
|
|
14
|
+
export declare class SpatialHitTester {
|
|
15
|
+
private _grid;
|
|
16
|
+
private _dirty;
|
|
17
|
+
markDirty(): void;
|
|
18
|
+
get isDirty(): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Rebuild the grid. `forEachPoint` is called once with an insert
|
|
21
|
+
* function; the caller drives iteration. Cleared when `pointCount`
|
|
22
|
+
* is zero.
|
|
23
|
+
*/
|
|
24
|
+
rebuild(bounds: HitBounds, pointCount: number, forEachPoint: (insert: (idx: number, x: number, y: number) => void) => void): void;
|
|
25
|
+
/**
|
|
26
|
+
* Query the nearest point within `radiusPx` of (dataX, dataY).
|
|
27
|
+
*/
|
|
28
|
+
query(dataX: number, dataY: number, radiusPx: number, pxPerDataX: number, pxPerDataY: number, xData: Float32Array | null, yData: Float32Array | null): number;
|
|
29
|
+
clear(): void;
|
|
30
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CssBounds, HostSink } from "./tooltip-controller";
|
|
2
|
+
/**
|
|
3
|
+
* Host-side `HostSink` that materializes pinned tooltips as a `<div>`
|
|
4
|
+
* next to the GL canvas, and applies cursor changes to the canvas's
|
|
5
|
+
* own `style.cursor`. Host-only — depends on `document` /
|
|
6
|
+
* `getComputedStyle`.
|
|
7
|
+
*/
|
|
8
|
+
export declare class DomHostSink implements HostSink {
|
|
9
|
+
private _glCanvas;
|
|
10
|
+
private _parent;
|
|
11
|
+
private _div;
|
|
12
|
+
constructor(glCanvas: HTMLCanvasElement, parent: HTMLElement);
|
|
13
|
+
pin(lines: string[], pos: {
|
|
14
|
+
px: number;
|
|
15
|
+
py: number;
|
|
16
|
+
}, bounds: CssBounds): void;
|
|
17
|
+
dismiss(): void;
|
|
18
|
+
setCursor(cursor: string): void;
|
|
19
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { CssBounds, HostSink, UserClickPayload, UserSelectPayload } from "./tooltip-controller";
|
|
2
|
+
/**
|
|
3
|
+
* Envelope shape sent by `MessageHostSink`. The transport translates
|
|
4
|
+
* each one into a corresponding `WorkerMsg` (`pinTooltip` /
|
|
5
|
+
* `dismissTooltip` / `setCursor` / `userClick` / `userSelect`).
|
|
6
|
+
*/
|
|
7
|
+
export type HostSinkEnvelope = {
|
|
8
|
+
kind: "pin";
|
|
9
|
+
payload: {
|
|
10
|
+
lines: string[];
|
|
11
|
+
pos: {
|
|
12
|
+
px: number;
|
|
13
|
+
py: number;
|
|
14
|
+
};
|
|
15
|
+
bounds: CssBounds;
|
|
16
|
+
};
|
|
17
|
+
} | {
|
|
18
|
+
kind: "dismiss";
|
|
19
|
+
} | {
|
|
20
|
+
kind: "setCursor";
|
|
21
|
+
cursor: string;
|
|
22
|
+
} | {
|
|
23
|
+
kind: "userClick";
|
|
24
|
+
payload: UserClickPayload;
|
|
25
|
+
} | {
|
|
26
|
+
kind: "userSelect";
|
|
27
|
+
payload: UserSelectPayload;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* `HostSink` that posts pin / dismiss / setCursor / user-event intents
|
|
31
|
+
* over a `postMessage`-style channel. The host-side transport listens
|
|
32
|
+
* for these envelopes and drives a `DomHostSink` for pin/dismiss and
|
|
33
|
+
* dispatches `CustomEvent`s on the viewer for user events.
|
|
34
|
+
*/
|
|
35
|
+
export declare class MessageHostSink implements HostSink {
|
|
36
|
+
private _send;
|
|
37
|
+
constructor(send: (msg: HostSinkEnvelope) => void);
|
|
38
|
+
pin(lines: string[], pos: {
|
|
39
|
+
px: number;
|
|
40
|
+
py: number;
|
|
41
|
+
}, bounds: CssBounds): void;
|
|
42
|
+
dismiss(): void;
|
|
43
|
+
setCursor(cursor: string): void;
|
|
44
|
+
emitUserClick(payload: UserClickPayload): void;
|
|
45
|
+
emitUserSelect(payload: UserSelectPayload): void;
|
|
46
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serial-checked async tooltip cache.
|
|
3
|
+
*
|
|
4
|
+
* Every chart family that paints tooltip text from a lazy row fetch
|
|
5
|
+
* needs the same dance: each hover (or pin) bumps a serial; the async
|
|
6
|
+
* line-build resolves later; if the user has moved on by then the
|
|
7
|
+
* resolved lines must be discarded so we don't paint stale text.
|
|
8
|
+
*
|
|
9
|
+
* Hit-test logic stays per-chart — that genuinely diverges (spatial
|
|
10
|
+
* grid for cartesian, walk-visible-nodes for treemap, angular for
|
|
11
|
+
* sunburst). The serial discipline is what was getting copy-pasted.
|
|
12
|
+
*
|
|
13
|
+
* `Target` is whatever identity the chart uses for hover/pin (flat
|
|
14
|
+
* slot index, node id, etc.); it's stored on `hoveredTarget` so the
|
|
15
|
+
* render path can tell whether cached `lines` belong to the currently
|
|
16
|
+
* hovered entity (some charts paint tooltip text only when both
|
|
17
|
+
* agree).
|
|
18
|
+
*/
|
|
19
|
+
export declare class LazyTooltip<Target> {
|
|
20
|
+
/**
|
|
21
|
+
* Cached lines for the latest committed hover, or `null`.
|
|
22
|
+
*/
|
|
23
|
+
lines: string[] | null;
|
|
24
|
+
/**
|
|
25
|
+
* Identity of the entity `lines` describe. `null` when cleared.
|
|
26
|
+
*/
|
|
27
|
+
hoveredTarget: Target | null;
|
|
28
|
+
private _hoverSerial;
|
|
29
|
+
private _pinSerial;
|
|
30
|
+
/**
|
|
31
|
+
* Begin a new hover. Call this only when the hovered entity has
|
|
32
|
+
* actually changed. Clears the cached lines, records the new
|
|
33
|
+
* target, bumps the hover serial, and returns the new value — pass
|
|
34
|
+
* it back to {@link commitHover} from your async resolver to gate
|
|
35
|
+
* the write.
|
|
36
|
+
*/
|
|
37
|
+
beginHover(target: Target): number;
|
|
38
|
+
/**
|
|
39
|
+
* Commit a freshly-resolved line list for `serial`. Returns true
|
|
40
|
+
* when the write happened (caller should repaint), false when the
|
|
41
|
+
* serial was stale.
|
|
42
|
+
*/
|
|
43
|
+
commitHover(serial: number, lines: string[]): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Clear hover state (mouse left, view changed, etc.).
|
|
46
|
+
*/
|
|
47
|
+
clearHover(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Begin a pin operation. Returns the serial; pass it to
|
|
50
|
+
* {@link isPinFresh} from your async resolver.
|
|
51
|
+
*/
|
|
52
|
+
beginPin(): number;
|
|
53
|
+
/**
|
|
54
|
+
* True when `serial` still names the latest pin attempt.
|
|
55
|
+
*/
|
|
56
|
+
isPinFresh(serial: number): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Bump the pin serial without starting a new pin (e.g. dismiss).
|
|
59
|
+
*/
|
|
60
|
+
invalidatePin(): void;
|
|
61
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { InteractionEvent } from "../transport/protocol";
|
|
2
|
+
/**
|
|
3
|
+
* Worker-mode counterpart to {@link ZoomRouter}. Captures wheel /
|
|
4
|
+
* pointer events on the GL canvas, normalizes coords to canvas-relative
|
|
5
|
+
* CSS pixels, and emits semantic {@link InteractionEvent}s to the
|
|
6
|
+
* Renderer over its transport. The Renderer (running in a Web Worker)
|
|
7
|
+
* owns the `ZoomController`s and runs the actual hit-test + apply
|
|
8
|
+
* logic — see `applyWheel` / `applyPan` in `zoom-router.ts`.
|
|
9
|
+
*
|
|
10
|
+
* Pointer capture is set on `pointerdown` and released on `pointerup`
|
|
11
|
+
* so drags continue to deliver `pointermove` events when the cursor
|
|
12
|
+
* leaves the canvas, matching the in-process `ZoomRouter` behavior.
|
|
13
|
+
*/
|
|
14
|
+
export declare class RawEventForwarder {
|
|
15
|
+
private _element;
|
|
16
|
+
private _emit;
|
|
17
|
+
private _pointerId;
|
|
18
|
+
private _onWheel;
|
|
19
|
+
private _onPointerDown;
|
|
20
|
+
private _onPointerMove;
|
|
21
|
+
private _onPointerUp;
|
|
22
|
+
private _onPointerLeave;
|
|
23
|
+
private _onClick;
|
|
24
|
+
private _onDblClick;
|
|
25
|
+
attach(element: HTMLElement, emit: (e: InteractionEvent) => void): void;
|
|
26
|
+
detach(): void;
|
|
27
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare class SpatialGrid {
|
|
2
|
+
private _cells;
|
|
3
|
+
private _xMin;
|
|
4
|
+
private _yMin;
|
|
5
|
+
private _cellSize;
|
|
6
|
+
private _cols;
|
|
7
|
+
constructor(xMin: number, xMax: number, yMin: number, yMax: number, cellSize: number);
|
|
8
|
+
private _cellKey;
|
|
9
|
+
insert(index: number, x: number, y: number): void;
|
|
10
|
+
/**
|
|
11
|
+
* Find the nearest point to (dataX, dataY) within the given radius,
|
|
12
|
+
* measured in pixel distance using the provided scale factors.
|
|
13
|
+
*/
|
|
14
|
+
query(dataX: number, dataY: number, radiusPx: number, pxPerDataX: number, pxPerDataY: number, xData: Float32Array, yData: Float32Array): number;
|
|
15
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import type { Canvas2D } from "../charts/canvas-types";
|
|
2
|
+
import type { PlotLayout } from "../layout/plot-layout";
|
|
3
|
+
import type { Theme } from "../theme/theme";
|
|
4
|
+
/**
|
|
5
|
+
* Minimal positioning input — PlotLayout satisfies this.
|
|
6
|
+
*/
|
|
7
|
+
export interface CssBounds {
|
|
8
|
+
cssWidth: number;
|
|
9
|
+
cssHeight: number;
|
|
10
|
+
}
|
|
11
|
+
export interface TooltipCallbacks {
|
|
12
|
+
/**
|
|
13
|
+
* RAF-throttled mouse position in CSS pixels, relative to the GL
|
|
14
|
+
* canvas (host already subtracted `getBoundingClientRect`).
|
|
15
|
+
*/
|
|
16
|
+
onHover(mx: number, my: number): void;
|
|
17
|
+
/**
|
|
18
|
+
* Fires on mouseleave; skipped while a pinned tooltip is active.
|
|
19
|
+
*/
|
|
20
|
+
onLeave(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Fires on click with mouse position. Return true to consume the click
|
|
23
|
+
* (skipping the default pin/dismiss flow — used for legend clicks).
|
|
24
|
+
*/
|
|
25
|
+
onClickPre?(mx: number, my: number): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Fires when a click should pin the current hover target.
|
|
28
|
+
*/
|
|
29
|
+
onPin?(mx: number, my: number): void;
|
|
30
|
+
/**
|
|
31
|
+
* Fires on dblclick (treemap drill-up gesture). Optional — charts
|
|
32
|
+
* that don't bind a handler simply ignore the event.
|
|
33
|
+
*/
|
|
34
|
+
onDblClick?(mx: number, my: number): void;
|
|
35
|
+
/**
|
|
36
|
+
* Fires when an active pin is dismissed by a click on the
|
|
37
|
+
* already-pinned target (the "click again to unpin" gesture in
|
|
38
|
+
* `dispatchClick`). Chart impls hook this to emit a
|
|
39
|
+
* `perspective-global-filter` with `selected: false`. Does *not*
|
|
40
|
+
* fire on the implicit dismiss inside `pin()` that replaces an
|
|
41
|
+
* existing pin — that path is followed by a fresh `onPin` which
|
|
42
|
+
* emits its own `selected: true`.
|
|
43
|
+
*/
|
|
44
|
+
onUnpin?(): void;
|
|
45
|
+
}
|
|
46
|
+
export interface RenderTooltipOptions {
|
|
47
|
+
/**
|
|
48
|
+
* Draw a dashed crosshair at `pos`. Used by scatter/line.
|
|
49
|
+
*/
|
|
50
|
+
crosshair?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Draw a ring of `radius` CSS pixels at `pos`. Used to highlight a
|
|
53
|
+
* hovered point. Omit for bars (where the bar itself highlights).
|
|
54
|
+
*/
|
|
55
|
+
highlightRadius?: number;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Side-channel from the chart back to the host's DOM. The chart calls
|
|
59
|
+
* into a sink rather than touching the DOM itself; the host
|
|
60
|
+
* materializes the actual visual (`<div>` for pinned tooltip, cursor
|
|
61
|
+
* mutation on the GL canvas).
|
|
62
|
+
*
|
|
63
|
+
* - `MessageHostSink` (in worker/) — forwards calls over a
|
|
64
|
+
* `postMessage`-shaped channel back to
|
|
65
|
+
* the host.
|
|
66
|
+
* - `DomHostSink` (in host transport) — receives the matching
|
|
67
|
+
* envelopes and applies them to the DOM.
|
|
68
|
+
*
|
|
69
|
+
* The controller's `_pinned` flag is the source of truth for whether
|
|
70
|
+
* hover updates are gated; the sink only owns the visual artifact.
|
|
71
|
+
*/
|
|
72
|
+
export interface HostSink {
|
|
73
|
+
pin(lines: string[], pos: {
|
|
74
|
+
px: number;
|
|
75
|
+
py: number;
|
|
76
|
+
}, bounds: CssBounds): void;
|
|
77
|
+
dismiss(): void;
|
|
78
|
+
setCursor(cursor: string): void;
|
|
79
|
+
/**
|
|
80
|
+
* Forward a `perspective-click` to the host. Optional — only the
|
|
81
|
+
* worker-bound `MessageHostSink` implements it; `DomHostSink` (the
|
|
82
|
+
* host-side consumer of pin/dismiss) never sees user-event calls,
|
|
83
|
+
* so omits the implementation.
|
|
84
|
+
*/
|
|
85
|
+
emitUserClick?(detail: UserClickPayload): void;
|
|
86
|
+
/**
|
|
87
|
+
* Forward a `perspective-global-filter` to the host with the
|
|
88
|
+
* `selected: true` / `selected: false` semantics. The host owns the
|
|
89
|
+
* `removeConfigs` history (mirrors datagrid's
|
|
90
|
+
* `model._last_insert_configs`); the sink only ships the new state.
|
|
91
|
+
*/
|
|
92
|
+
emitUserSelect?(payload: UserSelectPayload): void;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Plain-object payload for `HostSink.emitUserClick`. Matches
|
|
96
|
+
* `PerspectiveClickDetail` byte-for-byte; defined locally to avoid a
|
|
97
|
+
* cycle through `event-detail.ts`.
|
|
98
|
+
*/
|
|
99
|
+
export interface UserClickPayload {
|
|
100
|
+
row: Record<string, unknown>;
|
|
101
|
+
column_names: string[];
|
|
102
|
+
config: {
|
|
103
|
+
filter?: unknown[];
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Plain-object payload for `HostSink.emitUserSelect`. The host
|
|
108
|
+
* transport reconstructs a `PerspectiveSelectDetail` class instance
|
|
109
|
+
* from this plus its cached `_lastInsertConfig`.
|
|
110
|
+
*/
|
|
111
|
+
export interface UserSelectPayload {
|
|
112
|
+
selected: boolean;
|
|
113
|
+
row: Record<string, unknown>;
|
|
114
|
+
column_names: string[];
|
|
115
|
+
insertConfig: {
|
|
116
|
+
filter?: unknown[];
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Owns the hover/click/dblclick state machine and the pinned-tooltip
|
|
121
|
+
* lifecycle. The renderer drives this purely through
|
|
122
|
+
* `dispatchHover` / `dispatchLeave` / `dispatchClick` /
|
|
123
|
+
* `dispatchDblClick` — the host's `RawEventForwarder` captures DOM
|
|
124
|
+
* events on the GL canvas and posts them as `InteractionEvent`s.
|
|
125
|
+
*
|
|
126
|
+
* Pinning + cursor changes go through a {@link HostSink} so the actual
|
|
127
|
+
* DOM mutations happen host-side regardless of where the chart runs.
|
|
128
|
+
*/
|
|
129
|
+
export declare class TooltipController {
|
|
130
|
+
private _callbacks;
|
|
131
|
+
private _hoverRAFId;
|
|
132
|
+
private _hoverTimeoutId;
|
|
133
|
+
private _host;
|
|
134
|
+
private _pinned;
|
|
135
|
+
get isPinned(): boolean;
|
|
136
|
+
/**
|
|
137
|
+
* Replace the active host sink. Dismisses any existing pin via the
|
|
138
|
+
* prior sink so we never leak a pinned artifact across resets —
|
|
139
|
+
* though in practice each chart instance uses one sink for its
|
|
140
|
+
* lifetime.
|
|
141
|
+
*/
|
|
142
|
+
setHost(sink: HostSink): void;
|
|
143
|
+
/**
|
|
144
|
+
* Forward a cursor change to the host. No-op when no host sink is
|
|
145
|
+
* installed (chart constructed without a transport).
|
|
146
|
+
*/
|
|
147
|
+
setCursor(cursor: string): void;
|
|
148
|
+
/**
|
|
149
|
+
* Install the chart's tooltip callbacks. The renderer drives the
|
|
150
|
+
* controller via `dispatchHover` / `dispatchLeave` /
|
|
151
|
+
* `dispatchClick` / `dispatchDblClick`; this controller never
|
|
152
|
+
* touches the DOM directly.
|
|
153
|
+
*/
|
|
154
|
+
attach(callbacks: TooltipCallbacks): void;
|
|
155
|
+
detach(): void;
|
|
156
|
+
/**
|
|
157
|
+
* Schedule an `onHover` callback for the given canvas-relative
|
|
158
|
+
* coords. Coalesces multiple calls within one animation frame so
|
|
159
|
+
* pointer streams don't backlog the chart's hit-test path.
|
|
160
|
+
*
|
|
161
|
+
* Workers ship with `requestAnimationFrame` (DedicatedWorkerGlobalScope
|
|
162
|
+
* exposes it for OffscreenCanvas painting), so the same coalescer
|
|
163
|
+
* works in both modes. We fall back to setTimeout if RAF is missing
|
|
164
|
+
* (e.g. node tests without a polyfill).
|
|
165
|
+
*/
|
|
166
|
+
dispatchHover(mx: number, my: number): void;
|
|
167
|
+
dispatchLeave(): void;
|
|
168
|
+
dispatchClick(mx: number, my: number): void;
|
|
169
|
+
dispatchDblClick(mx: number, my: number): void;
|
|
170
|
+
/**
|
|
171
|
+
* Pin a tooltip (or replace an active one). Forwards through the
|
|
172
|
+
* configured sink and flips the controller's pinned flag so hover
|
|
173
|
+
* dispatch is suppressed until dismissal.
|
|
174
|
+
*/
|
|
175
|
+
pin(lines: string[], pos: {
|
|
176
|
+
px: number;
|
|
177
|
+
py: number;
|
|
178
|
+
}, bounds: CssBounds): void;
|
|
179
|
+
dismiss(): void;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Paint a canvas tooltip (crosshair, highlight ring, box + text) onto
|
|
183
|
+
* `canvas`. The helper normalizes the 2D context to a DPR-scaled
|
|
184
|
+
* identity transform on entry and restores prior state on exit, so it
|
|
185
|
+
* composes cleanly with other chrome painters that may have already
|
|
186
|
+
* called `initCanvas` on the same canvas — re-applying `scale(dpr,dpr)`
|
|
187
|
+
* blind would double-scale in that case, misplacing the tooltip
|
|
188
|
+
* proportionally to its distance from the origin.
|
|
189
|
+
*/
|
|
190
|
+
export declare function renderCanvasTooltip(canvas: Canvas2D | null, pos: {
|
|
191
|
+
px: number;
|
|
192
|
+
py: number;
|
|
193
|
+
}, lines: string[], layout: PlotLayout, theme: Theme, dpr: number, options?: RenderTooltipOptions): void;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { PlotLayout } from "../layout/plot-layout";
|
|
2
|
+
export interface ZoomState {
|
|
3
|
+
scaleX: number;
|
|
4
|
+
scaleY: number;
|
|
5
|
+
normTranslateX: number;
|
|
6
|
+
normTranslateY: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Runtime config for `ZoomController`. Not part of `ZoomState` — wired
|
|
10
|
+
* by the owning chart at construction, not serialized with zoom level.
|
|
11
|
+
*
|
|
12
|
+
* `lockAxis` pins one axis at `scale=1, translate=0` and suppresses
|
|
13
|
+
* wheel / pan updates on that axis, leaving the other axis fully
|
|
14
|
+
* zoomable. Categorical axes are the typical candidates.
|
|
15
|
+
*
|
|
16
|
+
* `lockAspect` keeps `dataPerPixel` equal on both axes by padding the
|
|
17
|
+
* narrower axis of the rendered domain to match the plot rect's aspect
|
|
18
|
+
* ratio. Required by map plugins (Mercator preserves local angle, so
|
|
19
|
+
* map glyphs distort under independent X/Y zoom), and useful for any
|
|
20
|
+
* cartesian view where stretching points along one axis would lie
|
|
21
|
+
* about the data.
|
|
22
|
+
*/
|
|
23
|
+
export interface ZoomConfig {
|
|
24
|
+
lockAxis?: "x" | "y" | null;
|
|
25
|
+
lockAspect?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare const MAX_ZOOM = 100000;
|
|
28
|
+
export declare const MIN_ZOOM = 1;
|
|
29
|
+
export declare class ZoomController {
|
|
30
|
+
private _scaleX;
|
|
31
|
+
private _scaleY;
|
|
32
|
+
private _normTX;
|
|
33
|
+
private _normTY;
|
|
34
|
+
private _baseXMin;
|
|
35
|
+
private _baseXMax;
|
|
36
|
+
private _baseYMin;
|
|
37
|
+
private _baseYMax;
|
|
38
|
+
private _lockAxis;
|
|
39
|
+
private _lockAspect;
|
|
40
|
+
private _element;
|
|
41
|
+
private _layout;
|
|
42
|
+
private _onUpdate;
|
|
43
|
+
private _pointerDown;
|
|
44
|
+
private _lastPointerX;
|
|
45
|
+
private _lastPointerY;
|
|
46
|
+
private _onWheel;
|
|
47
|
+
private _onPointerDown;
|
|
48
|
+
private _onPointerMove;
|
|
49
|
+
private _onPointerUp;
|
|
50
|
+
get lockedAxis(): "x" | "y" | null;
|
|
51
|
+
get scaleX(): number;
|
|
52
|
+
get scaleY(): number;
|
|
53
|
+
set scaleX(v: number);
|
|
54
|
+
set scaleY(v: number);
|
|
55
|
+
get normTranslateX(): number;
|
|
56
|
+
get normTranslateY(): number;
|
|
57
|
+
set normTranslateX(v: number);
|
|
58
|
+
set normTranslateY(v: number);
|
|
59
|
+
get baseXRange(): number;
|
|
60
|
+
get baseYRange(): number;
|
|
61
|
+
/**
|
|
62
|
+
* Update the base (full-data) domain that this controller's
|
|
63
|
+
* normalized translate is interpreted against, while preserving
|
|
64
|
+
* the *absolute* center of any user-applied pan.
|
|
65
|
+
*
|
|
66
|
+
* `_normTX` / `_normTY` are stored as fractions of the base
|
|
67
|
+
* range, not absolute coordinates. A naive "swap base, keep
|
|
68
|
+
* normTranslate" update reinterprets the same fraction against a
|
|
69
|
+
* new range, so when an external `draw()` updates the extent
|
|
70
|
+
* (via `processCartesianChunk` → `setZoomBaseDomain`) the user's
|
|
71
|
+
* pan-offset visible center jumps to a different absolute
|
|
72
|
+
* position. With concurrent pan events feeding in offsets that
|
|
73
|
+
* were computed against the old base, the jump can project the
|
|
74
|
+
* visible center past the data entirely, leaving `_fullRender`
|
|
75
|
+
* to draw zero glyphs onto a freshly-cleared canvas — a blank
|
|
76
|
+
* bitmap reaches the host as a flicker.
|
|
77
|
+
*
|
|
78
|
+
* When the user is in default state (no pan, no zoom — fresh
|
|
79
|
+
* controller, or just-reset), no rebase is needed; just swap the
|
|
80
|
+
* base and let the chart auto-fit to the new data. Otherwise
|
|
81
|
+
* recompute `_normTX` / `_normTY` so the visible center stays at
|
|
82
|
+
* the same absolute (data-coordinate) position before and after
|
|
83
|
+
* the swap.
|
|
84
|
+
*/
|
|
85
|
+
setBaseDomain(xMin: number, xMax: number, yMin: number, yMax: number): void;
|
|
86
|
+
/**
|
|
87
|
+
* Apply config. Called once by the chart during `setZoomController`.
|
|
88
|
+
* Locking an axis snaps its `scale`/`translate` to identity so any
|
|
89
|
+
* pre-existing state on that axis is cleared; subsequent wheel /
|
|
90
|
+
* pan events leave the locked axis alone.
|
|
91
|
+
*/
|
|
92
|
+
configure(config: ZoomConfig): void;
|
|
93
|
+
isDefault(): boolean;
|
|
94
|
+
getVisibleDomain(): {
|
|
95
|
+
xMin: number;
|
|
96
|
+
xMax: number;
|
|
97
|
+
yMin: number;
|
|
98
|
+
yMax: number;
|
|
99
|
+
};
|
|
100
|
+
attach(element: HTMLElement, layout: PlotLayout, onUpdate: () => void): void;
|
|
101
|
+
updateLayout(layout: PlotLayout): void;
|
|
102
|
+
detach(): void;
|
|
103
|
+
reset(): void;
|
|
104
|
+
serialize(): ZoomState;
|
|
105
|
+
restore(state: ZoomState): void;
|
|
106
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { PlotLayout } from "../layout/plot-layout";
|
|
2
|
+
import { type ZoomController } from "./zoom-controller";
|
|
3
|
+
/**
|
|
4
|
+
* Resolver that maps a cursor position to `{ controller, layout }` —
|
|
5
|
+
* returns `null` when the cursor is not inside any facet. In
|
|
6
|
+
* independent-zoom mode the facet under the cursor owns its events; in
|
|
7
|
+
* shared-zoom mode the resolver always returns the same controller for
|
|
8
|
+
* every plot rect in the grid.
|
|
9
|
+
*/
|
|
10
|
+
export interface ZoomTarget {
|
|
11
|
+
controller: ZoomController;
|
|
12
|
+
layout: PlotLayout;
|
|
13
|
+
}
|
|
14
|
+
export type ZoomTargetResolver = (mx: number, my: number) => ZoomTarget | null;
|
|
15
|
+
/**
|
|
16
|
+
* One set of wheel / pointer listeners on the GL canvas that dispatches
|
|
17
|
+
* zoom + pan events to a {@link ZoomController} resolved from the
|
|
18
|
+
* cursor position. Replaces `ZoomController.attach` so multiple
|
|
19
|
+
* controllers (one per facet) can coexist on a single canvas.
|
|
20
|
+
*/
|
|
21
|
+
export declare class ZoomRouter {
|
|
22
|
+
private _element;
|
|
23
|
+
private _resolve;
|
|
24
|
+
private _onUpdate;
|
|
25
|
+
private _pointerDown;
|
|
26
|
+
private _pointerTarget;
|
|
27
|
+
private _lastPointerX;
|
|
28
|
+
private _lastPointerY;
|
|
29
|
+
private _onWheel;
|
|
30
|
+
private _onPointerDown;
|
|
31
|
+
private _onPointerMove;
|
|
32
|
+
private _onPointerUp;
|
|
33
|
+
attach(element: HTMLElement, resolve: ZoomTargetResolver, onUpdate: () => void): void;
|
|
34
|
+
detach(): void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Apply a wheel-zoom delta to the resolved target. Exported for
|
|
38
|
+
* re-use inside the worker, where the renderer dispatches interaction
|
|
39
|
+
* events forwarded from the host's `RawEventForwarder` instead of
|
|
40
|
+
* receiving DOM events directly.
|
|
41
|
+
*/
|
|
42
|
+
export declare function applyWheel(target: ZoomTarget, mouseX: number, mouseY: number, deltaY: number): void;
|
|
43
|
+
/**
|
|
44
|
+
* Apply a drag-pan delta to the resolved target. Exported for the
|
|
45
|
+
* same reason as {@link applyWheel}: worker-mode interaction
|
|
46
|
+
* dispatch reuses the math without owning DOM listeners.
|
|
47
|
+
*/
|
|
48
|
+
export declare function applyPan(target: ZoomTarget, dx: number, dy: number): void;
|