@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,668 @@
|
|
|
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 { View } from "@perspective-dev/client";
|
|
14
|
+
import type {
|
|
15
|
+
HTMLPerspectiveViewerElement,
|
|
16
|
+
IPerspectiveViewerPlugin,
|
|
17
|
+
PluginStaticConfig,
|
|
18
|
+
} from "@perspective-dev/viewer";
|
|
19
|
+
import { ChartTypeConfig, PluginConfigField } from "./charts";
|
|
20
|
+
import style from "../../css/perspective-viewer-charts.css";
|
|
21
|
+
import {
|
|
22
|
+
DEFAULT_FACET_CONFIG,
|
|
23
|
+
DEFAULT_PLUGIN_CONFIG,
|
|
24
|
+
type FacetConfig,
|
|
25
|
+
type PluginConfig,
|
|
26
|
+
} from "../charts/chart";
|
|
27
|
+
import { RawEventForwarder } from "../interaction/raw-event-forwarder";
|
|
28
|
+
import { RendererTransport } from "../transport/renderer-transport";
|
|
29
|
+
import { RENDER_BLIT_MODE } from "../config";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Facet-rendering defaults shared by every chart. Per-chart overrides
|
|
33
|
+
* arrive through `plugin_config` (`facet_mode` + `facet_zoom_mode`);
|
|
34
|
+
* the remaining fields (`shared_x_axis`, `shared_y_axis`,
|
|
35
|
+
* `coordinated_tooltip`, `facet_padding`) are not yet user-configurable
|
|
36
|
+
* — flip the defaults in `DEFAULT_FACET_CONFIG` to change globally.
|
|
37
|
+
*/
|
|
38
|
+
const FACET_CONFIG_DEFAULTS: FacetConfig = { ...DEFAULT_FACET_CONFIG };
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Build a UI control spec for one plugin-config field. Mirrors the
|
|
42
|
+
* shape `column_config_schema` already returns (datagrid). Numeric
|
|
43
|
+
* fields get a `Number` control with min/max clamps; fractions get a
|
|
44
|
+
* 0..1 range; enums + booleans pass through their variant list.
|
|
45
|
+
*/
|
|
46
|
+
function fieldSpec(
|
|
47
|
+
key: PluginConfigField,
|
|
48
|
+
defaults: PluginConfig,
|
|
49
|
+
): Record<string, unknown> & { kind: string } {
|
|
50
|
+
switch (key) {
|
|
51
|
+
case "auto_alt_y_axis":
|
|
52
|
+
return { kind: "Bool", key, default: defaults.auto_alt_y_axis };
|
|
53
|
+
case "include_zero":
|
|
54
|
+
return { kind: "Bool", key, default: defaults.include_zero };
|
|
55
|
+
case "domain_mode":
|
|
56
|
+
return {
|
|
57
|
+
kind: "Enum",
|
|
58
|
+
key,
|
|
59
|
+
default: defaults.domain_mode,
|
|
60
|
+
variants: [
|
|
61
|
+
{ value: "fit", label: "Fit" },
|
|
62
|
+
{ value: "expand", label: "Expand" },
|
|
63
|
+
],
|
|
64
|
+
};
|
|
65
|
+
case "facet_mode":
|
|
66
|
+
return {
|
|
67
|
+
kind: "Enum",
|
|
68
|
+
key,
|
|
69
|
+
default: DEFAULT_PLUGIN_CONFIG.facet_mode,
|
|
70
|
+
variants: [
|
|
71
|
+
{ value: "grid", label: "Grid" },
|
|
72
|
+
{ value: "overlay", label: "Overlay" },
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
case "facet_zoom_mode":
|
|
76
|
+
return {
|
|
77
|
+
kind: "Enum",
|
|
78
|
+
key,
|
|
79
|
+
default: DEFAULT_PLUGIN_CONFIG.facet_zoom_mode,
|
|
80
|
+
variants: [
|
|
81
|
+
{ value: "shared", label: "Shared" },
|
|
82
|
+
{ value: "independent", label: "Independent" },
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
case "series_zoom_mode":
|
|
86
|
+
return {
|
|
87
|
+
kind: "Enum",
|
|
88
|
+
key,
|
|
89
|
+
default: DEFAULT_PLUGIN_CONFIG.series_zoom_mode,
|
|
90
|
+
variants: [
|
|
91
|
+
{ value: "dynamic", label: "Dynamic" },
|
|
92
|
+
{ value: "fixed", label: "Fixed" },
|
|
93
|
+
],
|
|
94
|
+
};
|
|
95
|
+
case "line_width_px":
|
|
96
|
+
return {
|
|
97
|
+
kind: "Number",
|
|
98
|
+
key,
|
|
99
|
+
default: DEFAULT_PLUGIN_CONFIG.line_width_px,
|
|
100
|
+
min: 0.5,
|
|
101
|
+
step: 0.5,
|
|
102
|
+
max: 16,
|
|
103
|
+
};
|
|
104
|
+
case "point_size_px":
|
|
105
|
+
return {
|
|
106
|
+
kind: "Number",
|
|
107
|
+
key,
|
|
108
|
+
default: DEFAULT_PLUGIN_CONFIG.point_size_px,
|
|
109
|
+
min: 1,
|
|
110
|
+
max: 32,
|
|
111
|
+
};
|
|
112
|
+
case "band_inner_frac":
|
|
113
|
+
return {
|
|
114
|
+
kind: "Number",
|
|
115
|
+
key,
|
|
116
|
+
default: DEFAULT_PLUGIN_CONFIG.band_inner_frac,
|
|
117
|
+
min: 0.1,
|
|
118
|
+
max: 1,
|
|
119
|
+
step: 0.01,
|
|
120
|
+
};
|
|
121
|
+
case "bar_inner_pad":
|
|
122
|
+
return {
|
|
123
|
+
kind: "Number",
|
|
124
|
+
key,
|
|
125
|
+
default: DEFAULT_PLUGIN_CONFIG.bar_inner_pad,
|
|
126
|
+
min: 0,
|
|
127
|
+
max: 0.9,
|
|
128
|
+
step: 0.01,
|
|
129
|
+
};
|
|
130
|
+
case "wick_width_px":
|
|
131
|
+
return {
|
|
132
|
+
kind: "Number",
|
|
133
|
+
key,
|
|
134
|
+
default: DEFAULT_PLUGIN_CONFIG.wick_width_px,
|
|
135
|
+
min: 0.5,
|
|
136
|
+
step: 0.5,
|
|
137
|
+
max: 8,
|
|
138
|
+
};
|
|
139
|
+
case "ohlc_line_width_px":
|
|
140
|
+
return {
|
|
141
|
+
kind: "Number",
|
|
142
|
+
key,
|
|
143
|
+
default: DEFAULT_PLUGIN_CONFIG.ohlc_line_width_px,
|
|
144
|
+
min: 0.5,
|
|
145
|
+
step: 0.5,
|
|
146
|
+
max: 8,
|
|
147
|
+
};
|
|
148
|
+
case "gradient_radius_px":
|
|
149
|
+
return {
|
|
150
|
+
kind: "Number",
|
|
151
|
+
key,
|
|
152
|
+
default: DEFAULT_PLUGIN_CONFIG.gradient_radius_px,
|
|
153
|
+
min: 2,
|
|
154
|
+
step: 1,
|
|
155
|
+
max: 256,
|
|
156
|
+
};
|
|
157
|
+
case "gradient_intensity":
|
|
158
|
+
return {
|
|
159
|
+
kind: "Number",
|
|
160
|
+
key,
|
|
161
|
+
default: DEFAULT_PLUGIN_CONFIG.gradient_intensity,
|
|
162
|
+
min: 0.05,
|
|
163
|
+
step: 0.05,
|
|
164
|
+
max: 4,
|
|
165
|
+
};
|
|
166
|
+
case "gradient_heat_max":
|
|
167
|
+
return {
|
|
168
|
+
kind: "Number",
|
|
169
|
+
key,
|
|
170
|
+
default: DEFAULT_PLUGIN_CONFIG.gradient_heat_max,
|
|
171
|
+
min: 0.1,
|
|
172
|
+
step: 0.1,
|
|
173
|
+
max: 64,
|
|
174
|
+
};
|
|
175
|
+
case "gradient_color_mode":
|
|
176
|
+
return {
|
|
177
|
+
kind: "Enum",
|
|
178
|
+
key,
|
|
179
|
+
default: DEFAULT_PLUGIN_CONFIG.gradient_color_mode,
|
|
180
|
+
variants: [
|
|
181
|
+
{ value: "mean", label: "Mean (density-weighted)" },
|
|
182
|
+
{ value: "density", label: "Density only" },
|
|
183
|
+
{ value: "extreme", label: "Extremes" },
|
|
184
|
+
{ value: "signed", label: "Signed sum" },
|
|
185
|
+
],
|
|
186
|
+
};
|
|
187
|
+
case "map_tile_provider":
|
|
188
|
+
return {
|
|
189
|
+
kind: "Enum",
|
|
190
|
+
key,
|
|
191
|
+
default: DEFAULT_PLUGIN_CONFIG.map_tile_provider,
|
|
192
|
+
variants: [
|
|
193
|
+
{ value: "carto-positron", label: "Light (Positron)" },
|
|
194
|
+
{ value: "carto-dark-matter", label: "Dark Matter" },
|
|
195
|
+
{ value: "carto-voyager", label: "Voyager" },
|
|
196
|
+
],
|
|
197
|
+
};
|
|
198
|
+
case "map_tile_alpha":
|
|
199
|
+
return {
|
|
200
|
+
kind: "Number",
|
|
201
|
+
key,
|
|
202
|
+
default: DEFAULT_PLUGIN_CONFIG.map_tile_alpha,
|
|
203
|
+
min: 0,
|
|
204
|
+
max: 1,
|
|
205
|
+
step: 0.05,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const GLOBAL_STYLES = (() => {
|
|
211
|
+
const sheet = new CSSStyleSheet();
|
|
212
|
+
sheet.replaceSync(style);
|
|
213
|
+
return [sheet];
|
|
214
|
+
})();
|
|
215
|
+
|
|
216
|
+
export class HTMLPerspectiveViewerWebGLPluginElement
|
|
217
|
+
extends HTMLElement
|
|
218
|
+
implements IPerspectiveViewerPlugin
|
|
219
|
+
{
|
|
220
|
+
declare _chartType: ChartTypeConfig;
|
|
221
|
+
|
|
222
|
+
private _initialized = false;
|
|
223
|
+
private _glCanvas!: HTMLCanvasElement;
|
|
224
|
+
private _gridlineCanvas!: HTMLCanvasElement;
|
|
225
|
+
private _chromeCanvas!: HTMLCanvasElement;
|
|
226
|
+
private _renderer: RendererTransport | null = null;
|
|
227
|
+
private _rendererPromise: Promise<RendererTransport> | null = null;
|
|
228
|
+
private _rawEventForwarder: RawEventForwarder | null = null;
|
|
229
|
+
private _generation = 0;
|
|
230
|
+
private _renderBlitMode: "direct" | "blit" = RENDER_BLIT_MODE;
|
|
231
|
+
private _resetClickAbort: AbortController | null = null;
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Plugin-scoped global config. Seeded lazily from
|
|
235
|
+
* `_effectiveDefaults()` (which folds
|
|
236
|
+
* `_chartType.plugin_field_defaults` over `DEFAULT_PLUGIN_CONFIG`)
|
|
237
|
+
* because base-class field initializers run before the subclass
|
|
238
|
+
* `_chartType` assignment. `restore({ plugin_config })` merges
|
|
239
|
+
* incoming values on top of the same effective defaults so fields
|
|
240
|
+
* the host omits fall back to the chart-type default
|
|
241
|
+
* (`include_zero = true` for Y Bar / Y Area / X Bar, `false`
|
|
242
|
+
* elsewhere). Held on the element (not just inside the worker) so
|
|
243
|
+
* a `_buildRenderer` triggered after a `restore` ships the
|
|
244
|
+
* resolved values in the `InitMsg`.
|
|
245
|
+
*/
|
|
246
|
+
private _pluginConfigStore: PluginConfig | null = null;
|
|
247
|
+
|
|
248
|
+
private get _pluginConfig(): PluginConfig {
|
|
249
|
+
if (!this._pluginConfigStore) {
|
|
250
|
+
this._pluginConfigStore = this._effectiveDefaults();
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return this._pluginConfigStore;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
private set _pluginConfig(value: PluginConfig) {
|
|
257
|
+
this._pluginConfigStore = value;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
private _effectiveDefaults(): PluginConfig {
|
|
261
|
+
return {
|
|
262
|
+
...DEFAULT_PLUGIN_CONFIG,
|
|
263
|
+
...(this._chartType.plugin_field_defaults ?? {}),
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
connectedCallback() {
|
|
268
|
+
if (!this._initialized) {
|
|
269
|
+
this.attachShadow({ mode: "open" });
|
|
270
|
+
for (const sheet of GLOBAL_STYLES) {
|
|
271
|
+
this.shadowRoot!.adoptedStyleSheets.push(sheet);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
this.shadowRoot!.innerHTML =
|
|
275
|
+
`<div class="webgl-container">` +
|
|
276
|
+
`<div class="zoom-controls">` +
|
|
277
|
+
`<button class="zoom-reset">Reset Zoom</button>` +
|
|
278
|
+
`</div>` +
|
|
279
|
+
`</div>`;
|
|
280
|
+
|
|
281
|
+
this._initialized = true;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (!this._glCanvas?.isConnected) {
|
|
285
|
+
this._buildCanvasStack();
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
private _buildCanvasStack(): void {
|
|
290
|
+
const container = this.shadowRoot!.querySelector(".webgl-container")!;
|
|
291
|
+
container.insertAdjacentHTML(
|
|
292
|
+
"afterbegin",
|
|
293
|
+
`<canvas class="webgl-gridlines"></canvas>` +
|
|
294
|
+
`<canvas class="webgl-canvas"></canvas>` +
|
|
295
|
+
`<canvas class="webgl-chrome"></canvas>`,
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
this._glCanvas =
|
|
299
|
+
container.querySelector<HTMLCanvasElement>(".webgl-canvas")!;
|
|
300
|
+
this._gridlineCanvas =
|
|
301
|
+
container.querySelector<HTMLCanvasElement>(".webgl-gridlines")!;
|
|
302
|
+
this._chromeCanvas =
|
|
303
|
+
container.querySelector<HTMLCanvasElement>(".webgl-chrome")!;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
private _clearCanvasStack(): void {
|
|
307
|
+
const container = this.shadowRoot?.querySelector(".webgl-container");
|
|
308
|
+
if (container) {
|
|
309
|
+
for (const c of Array.from(container.querySelectorAll("canvas"))) {
|
|
310
|
+
c.remove();
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
this._glCanvas = null!;
|
|
315
|
+
this._gridlineCanvas = null!;
|
|
316
|
+
this._chromeCanvas = null!;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Fires when the host (`<perspective-viewer>`) removes this plugin
|
|
321
|
+
* from the DOM on chart-type switch — see
|
|
322
|
+
* `renderer/activate.rs::remove_inactive_plugin`. Without this,
|
|
323
|
+
* inactive plugin instances retain their `RendererTransport`
|
|
324
|
+
* (worker + WebGL context + compiled shader programs) until the
|
|
325
|
+
* entire viewer is torn down, so a user cycling all 12 chart kinds
|
|
326
|
+
* holds 12 GL contexts per viewer and routinely exceeds the
|
|
327
|
+
* browser's per-page context cap (~16) in workspaces.
|
|
328
|
+
*/
|
|
329
|
+
disconnectedCallback() {
|
|
330
|
+
this.delete();
|
|
331
|
+
this._clearCanvasStack();
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Lazy renderer construction. Memoizes the in-flight `init()`
|
|
336
|
+
* promise so concurrent `draw()` calls during async setup await
|
|
337
|
+
* the same initialization rather than racing.
|
|
338
|
+
*/
|
|
339
|
+
private _ensureRenderer(view: View): Promise<RendererTransport> {
|
|
340
|
+
if (!this._initialized) {
|
|
341
|
+
this.connectedCallback();
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if (this._rendererPromise) {
|
|
345
|
+
return this._rendererPromise;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
this._rendererPromise = this._buildRenderer(view).then((r) => {
|
|
349
|
+
this._renderer = r;
|
|
350
|
+
this._setupInteraction(r);
|
|
351
|
+
return r;
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
return this._rendererPromise;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Capture raw DOM events on the GL canvas with `RawEventForwarder`
|
|
359
|
+
* and post them over the control channel. The renderer dispatches
|
|
360
|
+
* them through its own resolver + `applyWheel` / `applyPan` for
|
|
361
|
+
* zoom/pan, and through `TooltipController` virtual dispatch for
|
|
362
|
+
* hover/click; `zoomChanged` updates push back so the reset-zoom
|
|
363
|
+
* button visibility tracks the renderer-side state.
|
|
364
|
+
*
|
|
365
|
+
* The `zoomChanged` callback was wired at `RendererTransport`
|
|
366
|
+
* construction time; here we just attach the event forwarder and
|
|
367
|
+
* the reset-button click handler.
|
|
368
|
+
*/
|
|
369
|
+
private _setupInteraction(renderer: RendererTransport): void {
|
|
370
|
+
if (this._rawEventForwarder) {
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const zoomControls = this.shadowRoot!.querySelector(
|
|
375
|
+
".zoom-controls",
|
|
376
|
+
) as HTMLDivElement | null;
|
|
377
|
+
|
|
378
|
+
this._rawEventForwarder = new RawEventForwarder();
|
|
379
|
+
this._rawEventForwarder.attach(this._glCanvas, (event) => {
|
|
380
|
+
renderer.forwardInteraction(event);
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
const resetBtn = this.shadowRoot!.querySelector(".zoom-reset");
|
|
384
|
+
if (resetBtn) {
|
|
385
|
+
this._resetClickAbort = new AbortController();
|
|
386
|
+
resetBtn.addEventListener(
|
|
387
|
+
"click",
|
|
388
|
+
() => {
|
|
389
|
+
renderer.resetAllZooms();
|
|
390
|
+
if (zoomControls) {
|
|
391
|
+
zoomControls.classList.remove("visible");
|
|
392
|
+
}
|
|
393
|
+
},
|
|
394
|
+
{ signal: this._resetClickAbort.signal },
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
private async _buildRenderer(view: View): Promise<RendererTransport> {
|
|
400
|
+
const viewer = this.parentElement as HTMLPerspectiveViewerElement;
|
|
401
|
+
const client = await viewer.getClient();
|
|
402
|
+
const viewer_class = customElements.get("perspective-viewer");
|
|
403
|
+
const clientWasm = viewer_class.get_wasm_module();
|
|
404
|
+
const clientWorkerURL = viewer_class.get_worker_url();
|
|
405
|
+
const table = await viewer?.getTable?.();
|
|
406
|
+
const tableName: string | undefined = table
|
|
407
|
+
? await table.get_name()
|
|
408
|
+
: undefined;
|
|
409
|
+
|
|
410
|
+
const zoomControls = this.shadowRoot!.querySelector(
|
|
411
|
+
".zoom-controls",
|
|
412
|
+
) as HTMLDivElement | null;
|
|
413
|
+
|
|
414
|
+
const transport = new RendererTransport({
|
|
415
|
+
client,
|
|
416
|
+
view,
|
|
417
|
+
tableName,
|
|
418
|
+
clientWorkerURL,
|
|
419
|
+
clientWasm,
|
|
420
|
+
chartTag: this._chartType.tag,
|
|
421
|
+
maxCells: this._chartType.max_cells,
|
|
422
|
+
precompileShaders: true,
|
|
423
|
+
onZoomChanged: (isDefault: boolean) => {
|
|
424
|
+
if (zoomControls) {
|
|
425
|
+
zoomControls.classList.toggle("visible", !isDefault);
|
|
426
|
+
}
|
|
427
|
+
},
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
await transport.init({
|
|
431
|
+
gl: this._glCanvas,
|
|
432
|
+
gridlines: this._gridlineCanvas,
|
|
433
|
+
chrome: this._chromeCanvas,
|
|
434
|
+
facetConfig: {
|
|
435
|
+
...FACET_CONFIG_DEFAULTS,
|
|
436
|
+
facet_mode: this._pluginConfig.facet_mode,
|
|
437
|
+
zoom_mode: this._pluginConfig.facet_zoom_mode,
|
|
438
|
+
},
|
|
439
|
+
pluginConfig: this._pluginConfig,
|
|
440
|
+
defaultChartType: this._chartType.default_chart_type,
|
|
441
|
+
renderBlitMode: this._renderBlitMode,
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
return transport;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
setBlitMode(mode: "direct" | "blit") {
|
|
448
|
+
console.assert(this._initialized, "Already initialized");
|
|
449
|
+
this._renderBlitMode = mode;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
get_static_config(): PluginStaticConfig {
|
|
453
|
+
return {
|
|
454
|
+
name: this._chartType.name,
|
|
455
|
+
category: this._chartType.category,
|
|
456
|
+
select_mode: this._chartType.selectMode,
|
|
457
|
+
min_config_columns: this._chartType.initial.count,
|
|
458
|
+
config_column_names: this._chartType.initial.names,
|
|
459
|
+
max_cells: this._chartType.max_cells,
|
|
460
|
+
max_columns: this._chartType.max_columns,
|
|
461
|
+
group_rollup_modes: ["flat"],
|
|
462
|
+
priority: 0,
|
|
463
|
+
can_render_column_styles:
|
|
464
|
+
!!this._chartType.default_chart_type ||
|
|
465
|
+
this._chartType.category === "Cartesian Charts",
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
column_config_schema(
|
|
470
|
+
column_type: string,
|
|
471
|
+
_group: string | undefined,
|
|
472
|
+
_column_name: string,
|
|
473
|
+
current_value: Record<string, unknown> | null,
|
|
474
|
+
_viewer_config?: { group_by?: string[]; group_rollup_mode?: string },
|
|
475
|
+
) {
|
|
476
|
+
const fields: Array<Record<string, unknown> & { kind: string }> = [];
|
|
477
|
+
|
|
478
|
+
// Y-series plugins expose the per-column chart_type picker; non-Y
|
|
479
|
+
// plugins leave `default_chart_type` unset.
|
|
480
|
+
const def = this._chartType.default_chart_type;
|
|
481
|
+
if (def && (column_type === "integer" || column_type === "float")) {
|
|
482
|
+
fields.push({
|
|
483
|
+
kind: "Enum",
|
|
484
|
+
key: "chart_type",
|
|
485
|
+
default: def,
|
|
486
|
+
variants: [
|
|
487
|
+
{ value: "bar", label: "Bar" },
|
|
488
|
+
{ value: "line", label: "Line" },
|
|
489
|
+
{ value: "scatter", label: "Scatter" },
|
|
490
|
+
{ value: "area", label: "Area" },
|
|
491
|
+
],
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
const effective_chart_type =
|
|
495
|
+
(current_value?.chart_type as string | undefined) ?? def;
|
|
496
|
+
|
|
497
|
+
const supports_stack =
|
|
498
|
+
effective_chart_type === "bar" ||
|
|
499
|
+
effective_chart_type === "area";
|
|
500
|
+
|
|
501
|
+
if (supports_stack) {
|
|
502
|
+
fields.push({
|
|
503
|
+
kind: "Bool",
|
|
504
|
+
key: "stack",
|
|
505
|
+
default: supports_stack,
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
const is_series_glyph =
|
|
510
|
+
def === "bar" ||
|
|
511
|
+
def === "line" ||
|
|
512
|
+
def === "scatter" ||
|
|
513
|
+
def === "area";
|
|
514
|
+
|
|
515
|
+
if (is_series_glyph) {
|
|
516
|
+
fields.push({
|
|
517
|
+
kind: "Bool",
|
|
518
|
+
key: "alt_axis",
|
|
519
|
+
default: false,
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// Per-column formatter widgets. Surfaced for every chart type so
|
|
525
|
+
// axes / tooltips / legends honor the user's format choice.
|
|
526
|
+
if (column_type === "integer" || column_type === "float") {
|
|
527
|
+
fields.push({ kind: "NumberFormat" });
|
|
528
|
+
} else if (column_type === "date" || column_type === "datetime") {
|
|
529
|
+
fields.push({ kind: "DatetimeFormat" });
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
return { fields };
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
plugin_config_schema(_view_config?: {
|
|
536
|
+
group_by?: string[];
|
|
537
|
+
group_rollup_mode?: string;
|
|
538
|
+
}) {
|
|
539
|
+
const defaults = this._effectiveDefaults();
|
|
540
|
+
const fields = this._chartType.applicable_plugin_fields.map((key) =>
|
|
541
|
+
fieldSpec(key, defaults),
|
|
542
|
+
);
|
|
543
|
+
|
|
544
|
+
return { fields };
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
async draw(view: View): Promise<void> {
|
|
548
|
+
// `draw` always indicates a view-level change (pivots, columns,
|
|
549
|
+
// filters, sorts, schema, …) — invalidate the `domain_mode:
|
|
550
|
+
// "expand"` accumulator so the new view's extent starts fresh.
|
|
551
|
+
// `update` (data-only redraw on the same view) shares
|
|
552
|
+
// `_drawImpl` but skips this reset.
|
|
553
|
+
this._renderer?.resetExpandedDomain();
|
|
554
|
+
this._renderer?.resetAllZooms();
|
|
555
|
+
return this._drawImpl(view);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
async update(view: View): Promise<void> {
|
|
559
|
+
return this._drawImpl(view);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
private async _drawImpl(view: View): Promise<void> {
|
|
563
|
+
const gen = ++this._generation;
|
|
564
|
+
const renderer = await this._ensureRenderer(view);
|
|
565
|
+
if (this._generation !== gen) {
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
renderer.setView(view);
|
|
570
|
+
renderer.setBufferMaxCapacity(this._chartType.max_cells);
|
|
571
|
+
const viewer = this
|
|
572
|
+
.parentElement as HTMLPerspectiveViewerElement | null;
|
|
573
|
+
const viewerConfig = (await viewer?.getViewConfig?.()) ?? {};
|
|
574
|
+
if (this._generation !== gen) {
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
await renderer.loadAndRender({
|
|
579
|
+
viewerConfig: {
|
|
580
|
+
group_by: viewerConfig?.group_by ?? [],
|
|
581
|
+
split_by: viewerConfig?.split_by ?? [],
|
|
582
|
+
columns: viewerConfig?.columns ?? [],
|
|
583
|
+
},
|
|
584
|
+
options: { float32: true },
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
async clear(): Promise<void> {
|
|
589
|
+
this._generation++;
|
|
590
|
+
this._renderer?.clear();
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
async resize(): Promise<void> {
|
|
594
|
+
this._renderer?.resize();
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
restyle() {
|
|
598
|
+
this._renderer?.invalidateTheme();
|
|
599
|
+
return 5;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
save() {
|
|
603
|
+
const state: any = {};
|
|
604
|
+
const zoom = this._renderer?.saveZoom();
|
|
605
|
+
if (zoom) {
|
|
606
|
+
state.zoom = zoom;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// Only emit the keys this chart actually consumes.
|
|
610
|
+
const cfg: Partial<PluginConfig> = {};
|
|
611
|
+
for (const key of this._chartType.applicable_plugin_fields) {
|
|
612
|
+
// `key` is `PluginConfigField` = `keyof PluginConfig`, so this
|
|
613
|
+
// indexed assignment is type-safe without a cast.
|
|
614
|
+
(cfg[key] as PluginConfig[typeof key]) = this._pluginConfig[key];
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
if (Object.keys(cfg).length > 0) {
|
|
618
|
+
state.plugin_config = cfg;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
return state;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
async render(view: View): Promise<Blob> {
|
|
625
|
+
await this._ensureRenderer(view);
|
|
626
|
+
await this.draw(view);
|
|
627
|
+
return this._renderer!.snapshotPng();
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
restore(config: any, columns_config?: Record<string, any>) {
|
|
631
|
+
if (config?.zoom) {
|
|
632
|
+
this._renderer?.restoreZoom(config.zoom);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// Merge incoming plugin_config on top of the `chart_type`
|
|
636
|
+
// effective defaults so a partial restore (UI emits only
|
|
637
|
+
// changed fields) keeps untouched defaults in place — and
|
|
638
|
+
// chart-type overrides (e.g. `include_zero=true` for Y Bar /
|
|
639
|
+
// Y Area / X Bar) survive when the host elides their values.
|
|
640
|
+
this._pluginConfig = {
|
|
641
|
+
...this._effectiveDefaults(),
|
|
642
|
+
...config,
|
|
643
|
+
};
|
|
644
|
+
|
|
645
|
+
this._renderer?.setPluginConfig(this._pluginConfig);
|
|
646
|
+
this._renderer?.setColumnsConfig(columns_config ?? {});
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
delete() {
|
|
650
|
+
this._generation++;
|
|
651
|
+
if (this._rawEventForwarder) {
|
|
652
|
+
this._rawEventForwarder.detach();
|
|
653
|
+
this._rawEventForwarder = null;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
if (this._resetClickAbort) {
|
|
657
|
+
this._resetClickAbort.abort();
|
|
658
|
+
this._resetClickAbort = null;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
if (this._renderer) {
|
|
662
|
+
this._renderer.destroy();
|
|
663
|
+
this._renderer = null;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
this._rendererPromise = null;
|
|
667
|
+
}
|
|
668
|
+
}
|