@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.
Files changed (258) hide show
  1. package/LICENSE.md +193 -0
  2. package/dist/cdn/perspective-viewer-charts.js +3 -0
  3. package/dist/cdn/perspective-viewer-charts.js.map +7 -0
  4. package/dist/esm/axis/axis-primitives.d.ts +24 -0
  5. package/dist/esm/axis/bar-axis.d.ts +51 -0
  6. package/dist/esm/axis/canvas.d.ts +24 -0
  7. package/dist/esm/axis/categorical-axis-core.d.ts +42 -0
  8. package/dist/esm/axis/categorical-axis.d.ts +27 -0
  9. package/dist/esm/axis/facet-chrome.d.ts +13 -0
  10. package/dist/esm/axis/label-geometry.d.ts +41 -0
  11. package/dist/esm/axis/legend.d.ts +44 -0
  12. package/dist/esm/axis/numeric-axis.d.ts +20 -0
  13. package/dist/esm/charts/candlestick/candlestick-build.d.ts +129 -0
  14. package/dist/esm/charts/candlestick/candlestick-interact.d.ts +10 -0
  15. package/dist/esm/charts/candlestick/candlestick-render.d.ts +24 -0
  16. package/dist/esm/charts/candlestick/candlestick.d.ts +144 -0
  17. package/dist/esm/charts/candlestick/glyphs/draw-candlesticks.d.ts +36 -0
  18. package/dist/esm/charts/candlestick/glyphs/draw-ohlc.d.ts +33 -0
  19. package/dist/esm/charts/canvas-types.d.ts +15 -0
  20. package/dist/esm/charts/cartesian/cartesian-build.d.ts +14 -0
  21. package/dist/esm/charts/cartesian/cartesian-interact.d.ts +20 -0
  22. package/dist/esm/charts/cartesian/cartesian-render.d.ts +26 -0
  23. package/dist/esm/charts/cartesian/cartesian.d.ts +239 -0
  24. package/dist/esm/charts/cartesian/glyph.d.ts +53 -0
  25. package/dist/esm/charts/cartesian/glyphs/density.d.ts +142 -0
  26. package/dist/esm/charts/cartesian/glyphs/lines.d.ts +23 -0
  27. package/dist/esm/charts/cartesian/glyphs/points.d.ts +24 -0
  28. package/dist/esm/charts/cartesian/label-interner.d.ts +21 -0
  29. package/dist/esm/charts/cartesian/tooltip-lines.d.ts +11 -0
  30. package/dist/esm/charts/chart-base.d.ts +402 -0
  31. package/dist/esm/charts/chart.d.ts +338 -0
  32. package/dist/esm/charts/common/band-layout.d.ts +32 -0
  33. package/dist/esm/charts/common/categorical-y-chart.d.ts +53 -0
  34. package/dist/esm/charts/common/category-axis-resolver.d.ts +90 -0
  35. package/dist/esm/charts/common/chrome-cache.d.ts +18 -0
  36. package/dist/esm/charts/common/draw-tooltip-box.d.ts +9 -0
  37. package/dist/esm/charts/common/leaf-color.d.ts +33 -0
  38. package/dist/esm/charts/common/node-store.d.ts +81 -0
  39. package/dist/esm/charts/common/tree-chart.d.ts +48 -0
  40. package/dist/esm/charts/common/tree-chrome.d.ts +31 -0
  41. package/dist/esm/charts/common/tree-data.d.ts +54 -0
  42. package/dist/esm/charts/common/visible-extent.d.ts +51 -0
  43. package/dist/esm/charts/heatmap/heatmap-build.d.ts +86 -0
  44. package/dist/esm/charts/heatmap/heatmap-interact.d.ts +19 -0
  45. package/dist/esm/charts/heatmap/heatmap-render.d.ts +19 -0
  46. package/dist/esm/charts/heatmap/heatmap-y-axis.d.ts +46 -0
  47. package/dist/esm/charts/heatmap/heatmap.d.ts +117 -0
  48. package/dist/esm/charts/map/map.d.ts +67 -0
  49. package/dist/esm/charts/registry.d.ts +14 -0
  50. package/dist/esm/charts/series/glyphs/draw-areas.d.ts +30 -0
  51. package/dist/esm/charts/series/glyphs/draw-bars.d.ts +15 -0
  52. package/dist/esm/charts/series/glyphs/draw-lines.d.ts +34 -0
  53. package/dist/esm/charts/series/glyphs/draw-scatter.d.ts +33 -0
  54. package/dist/esm/charts/series/series-build.d.ts +228 -0
  55. package/dist/esm/charts/series/series-interact.d.ts +35 -0
  56. package/dist/esm/charts/series/series-render.d.ts +41 -0
  57. package/dist/esm/charts/series/series-type.d.ts +49 -0
  58. package/dist/esm/charts/series/series.d.ts +317 -0
  59. package/dist/esm/charts/sunburst/sunburst-interact.d.ts +7 -0
  60. package/dist/esm/charts/sunburst/sunburst-layout.d.ts +33 -0
  61. package/dist/esm/charts/sunburst/sunburst-render.d.ts +22 -0
  62. package/dist/esm/charts/sunburst/sunburst.d.ts +85 -0
  63. package/dist/esm/charts/treemap/treemap-interact.d.ts +12 -0
  64. package/dist/esm/charts/treemap/treemap-layout.d.ts +28 -0
  65. package/dist/esm/charts/treemap/treemap-render.d.ts +18 -0
  66. package/dist/esm/charts/treemap/treemap.d.ts +74 -0
  67. package/dist/esm/config.d.ts +27 -0
  68. package/dist/esm/data/lazy-row.d.ts +32 -0
  69. package/dist/esm/data/split-groups.d.ts +20 -0
  70. package/dist/esm/data/view-reader.d.ts +35 -0
  71. package/dist/esm/event-detail.d.ts +28 -0
  72. package/dist/esm/index.d.ts +3 -0
  73. package/dist/esm/interaction/hit-test.d.ts +30 -0
  74. package/dist/esm/interaction/host-sink-dom.d.ts +19 -0
  75. package/dist/esm/interaction/host-sink-message.d.ts +46 -0
  76. package/dist/esm/interaction/lazy-tooltip.d.ts +61 -0
  77. package/dist/esm/interaction/raw-event-forwarder.d.ts +27 -0
  78. package/dist/esm/interaction/spatial-grid.d.ts +15 -0
  79. package/dist/esm/interaction/tooltip-controller.d.ts +193 -0
  80. package/dist/esm/interaction/zoom-controller.d.ts +106 -0
  81. package/dist/esm/interaction/zoom-router.d.ts +48 -0
  82. package/dist/esm/layout/facet-grid.d.ts +126 -0
  83. package/dist/esm/layout/plot-layout.d.ts +104 -0
  84. package/dist/esm/layout/ticks.d.ts +17 -0
  85. package/dist/esm/map/mercator.d.ts +102 -0
  86. package/dist/esm/map/tile-cache.d.ts +38 -0
  87. package/dist/esm/map/tile-layer.d.ts +66 -0
  88. package/dist/esm/map/tile-loader.d.ts +52 -0
  89. package/dist/esm/map/tile-source.d.ts +66 -0
  90. package/dist/esm/perspective-viewer-charts.js +3 -0
  91. package/dist/esm/perspective-viewer-charts.js.map +7 -0
  92. package/dist/esm/plugin/charts.d.ts +40 -0
  93. package/dist/esm/plugin/plugin.d.ts +95 -0
  94. package/dist/esm/render/scheduler.d.ts +41 -0
  95. package/dist/esm/theme/gradient.d.ts +48 -0
  96. package/dist/esm/theme/palette.d.ts +13 -0
  97. package/dist/esm/theme/theme-snapshot.d.ts +7 -0
  98. package/dist/esm/theme/theme.d.ts +53 -0
  99. package/dist/esm/transport/protocol.d.ts +430 -0
  100. package/dist/esm/transport/renderer-transport.d.ts +201 -0
  101. package/dist/esm/utils/css.d.ts +1 -0
  102. package/dist/esm/utils/font-snapshot.d.ts +50 -0
  103. package/dist/esm/webgl/buffer-pool.d.ts +62 -0
  104. package/dist/esm/webgl/context-manager.d.ts +184 -0
  105. package/dist/esm/webgl/gradient-texture.d.ts +17 -0
  106. package/dist/esm/webgl/instanced-attrs.d.ts +44 -0
  107. package/dist/esm/webgl/plot-frame.d.ts +39 -0
  108. package/dist/esm/webgl/program-cache.d.ts +13 -0
  109. package/dist/esm/webgl/shader-manifest.d.ts +53 -0
  110. package/dist/esm/webgl/shader-registry.d.ts +22 -0
  111. package/dist/esm/worker/boot.d.ts +0 -0
  112. package/dist/esm/worker/dispatch.d.ts +9 -0
  113. package/dist/esm/worker/font-loader.d.ts +2 -0
  114. package/dist/esm/worker/renderer.worker.d.ts +115 -0
  115. package/dist/esm/worker/session-host.d.ts +26 -0
  116. package/package.json +47 -0
  117. package/src/css/perspective-viewer-charts.css +95 -0
  118. package/src/ts/axis/axis-primitives.ts +125 -0
  119. package/src/ts/axis/bar-axis.ts +345 -0
  120. package/src/ts/axis/canvas.ts +64 -0
  121. package/src/ts/axis/categorical-axis-core.ts +125 -0
  122. package/src/ts/axis/categorical-axis.ts +716 -0
  123. package/src/ts/axis/facet-chrome.ts +42 -0
  124. package/src/ts/axis/label-geometry.ts +188 -0
  125. package/src/ts/axis/legend.ts +218 -0
  126. package/src/ts/axis/numeric-axis.ts +353 -0
  127. package/src/ts/charts/candlestick/candlestick-build.ts +516 -0
  128. package/src/ts/charts/candlestick/candlestick-interact.ts +256 -0
  129. package/src/ts/charts/candlestick/candlestick-render.ts +387 -0
  130. package/src/ts/charts/candlestick/candlestick.ts +367 -0
  131. package/src/ts/charts/candlestick/glyphs/draw-candlesticks.ts +432 -0
  132. package/src/ts/charts/candlestick/glyphs/draw-ohlc.ts +317 -0
  133. package/src/ts/charts/canvas-types.ts +30 -0
  134. package/src/ts/charts/cartesian/cartesian-build.ts +616 -0
  135. package/src/ts/charts/cartesian/cartesian-interact.ts +355 -0
  136. package/src/ts/charts/cartesian/cartesian-render.ts +948 -0
  137. package/src/ts/charts/cartesian/cartesian.ts +469 -0
  138. package/src/ts/charts/cartesian/glyph.ts +81 -0
  139. package/src/ts/charts/cartesian/glyphs/density.ts +1263 -0
  140. package/src/ts/charts/cartesian/glyphs/lines.ts +320 -0
  141. package/src/ts/charts/cartesian/glyphs/points.ts +239 -0
  142. package/src/ts/charts/cartesian/label-interner.ts +56 -0
  143. package/src/ts/charts/cartesian/tooltip-lines.ts +80 -0
  144. package/src/ts/charts/chart-base.ts +840 -0
  145. package/src/ts/charts/chart.ts +427 -0
  146. package/src/ts/charts/common/band-layout.ts +63 -0
  147. package/src/ts/charts/common/categorical-y-chart.ts +81 -0
  148. package/src/ts/charts/common/category-axis-resolver.ts +314 -0
  149. package/src/ts/charts/common/chrome-cache.ts +79 -0
  150. package/src/ts/charts/common/draw-tooltip-box.ts +84 -0
  151. package/src/ts/charts/common/leaf-color.ts +92 -0
  152. package/src/ts/charts/common/node-store.ts +235 -0
  153. package/src/ts/charts/common/tree-chart.ts +76 -0
  154. package/src/ts/charts/common/tree-chrome.ts +123 -0
  155. package/src/ts/charts/common/tree-data.ts +623 -0
  156. package/src/ts/charts/common/visible-extent.ts +112 -0
  157. package/src/ts/charts/heatmap/heatmap-build.ts +426 -0
  158. package/src/ts/charts/heatmap/heatmap-interact.ts +274 -0
  159. package/src/ts/charts/heatmap/heatmap-render.ts +815 -0
  160. package/src/ts/charts/heatmap/heatmap-y-axis.ts +351 -0
  161. package/src/ts/charts/heatmap/heatmap.ts +368 -0
  162. package/src/ts/charts/map/map.ts +201 -0
  163. package/src/ts/charts/registry.ts +65 -0
  164. package/src/ts/charts/series/glyphs/draw-areas.ts +331 -0
  165. package/src/ts/charts/series/glyphs/draw-bars.ts +113 -0
  166. package/src/ts/charts/series/glyphs/draw-lines.ts +320 -0
  167. package/src/ts/charts/series/glyphs/draw-scatter.ts +328 -0
  168. package/src/ts/charts/series/series-build.ts +848 -0
  169. package/src/ts/charts/series/series-interact.ts +604 -0
  170. package/src/ts/charts/series/series-render.ts +1109 -0
  171. package/src/ts/charts/series/series-type.ts +99 -0
  172. package/src/ts/charts/series/series.ts +794 -0
  173. package/src/ts/charts/sunburst/sunburst-interact.ts +460 -0
  174. package/src/ts/charts/sunburst/sunburst-layout.ts +238 -0
  175. package/src/ts/charts/sunburst/sunburst-render.ts +887 -0
  176. package/src/ts/charts/sunburst/sunburst.ts +248 -0
  177. package/src/ts/charts/treemap/treemap-interact.ts +445 -0
  178. package/src/ts/charts/treemap/treemap-layout.ts +328 -0
  179. package/src/ts/charts/treemap/treemap-render.ts +886 -0
  180. package/src/ts/charts/treemap/treemap.ts +247 -0
  181. package/src/ts/config.ts +41 -0
  182. package/src/ts/data/lazy-row.ts +140 -0
  183. package/src/ts/data/split-groups.ts +97 -0
  184. package/src/ts/data/view-reader.ts +107 -0
  185. package/src/ts/event-detail.ts +44 -0
  186. package/src/ts/index.ts +53 -0
  187. package/src/ts/interaction/hit-test.ts +106 -0
  188. package/src/ts/interaction/host-sink-dom.ts +85 -0
  189. package/src/ts/interaction/host-sink-message.ts +75 -0
  190. package/src/ts/interaction/lazy-tooltip.ts +102 -0
  191. package/src/ts/interaction/raw-event-forwarder.ts +175 -0
  192. package/src/ts/interaction/spatial-grid.ts +100 -0
  193. package/src/ts/interaction/tooltip-controller.ts +407 -0
  194. package/src/ts/interaction/zoom-controller.ts +468 -0
  195. package/src/ts/interaction/zoom-router.ts +230 -0
  196. package/src/ts/layout/facet-grid.ts +346 -0
  197. package/src/ts/layout/plot-layout.ts +277 -0
  198. package/src/ts/layout/ticks.ts +168 -0
  199. package/src/ts/map/mercator.ts +204 -0
  200. package/src/ts/map/tile-cache.ts +96 -0
  201. package/src/ts/map/tile-layer.ts +382 -0
  202. package/src/ts/map/tile-loader.ts +143 -0
  203. package/src/ts/map/tile-source.ts +156 -0
  204. package/src/ts/plugin/charts.ts +286 -0
  205. package/src/ts/plugin/plugin.ts +668 -0
  206. package/src/ts/render/scheduler.ts +339 -0
  207. package/src/ts/shaders/area.frag.glsl +20 -0
  208. package/src/ts/shaders/area.vert.glsl +19 -0
  209. package/src/ts/shaders/bar.frag.glsl +25 -0
  210. package/src/ts/shaders/bar.vert.glsl +60 -0
  211. package/src/ts/shaders/candlestick-body.frag.glsl +19 -0
  212. package/src/ts/shaders/candlestick-body.vert.glsl +34 -0
  213. package/src/ts/shaders/density-extreme.frag.glsl +30 -0
  214. package/src/ts/shaders/density-mrt.frag.glsl +44 -0
  215. package/src/ts/shaders/density-mrt.vert.glsl +48 -0
  216. package/src/ts/shaders/density-resolve.frag.glsl +89 -0
  217. package/src/ts/shaders/density-resolve.vert.glsl +23 -0
  218. package/src/ts/shaders/density-splat.frag.glsl +34 -0
  219. package/src/ts/shaders/density-splat.vert.glsl +52 -0
  220. package/src/ts/shaders/gridline.frag.glsl +18 -0
  221. package/src/ts/shaders/gridline.vert.glsl +18 -0
  222. package/src/ts/shaders/heatmap.frag.glsl +23 -0
  223. package/src/ts/shaders/heatmap.vert.glsl +42 -0
  224. package/src/ts/shaders/line-uniform.frag.glsl +26 -0
  225. package/src/ts/shaders/line-uniform.vert.glsl +54 -0
  226. package/src/ts/shaders/line.frag.glsl +28 -0
  227. package/src/ts/shaders/line.vert.glsl +87 -0
  228. package/src/ts/shaders/scatter.frag.glsl +39 -0
  229. package/src/ts/shaders/scatter.vert.glsl +67 -0
  230. package/src/ts/shaders/sunburst-arc.frag.glsl +19 -0
  231. package/src/ts/shaders/sunburst-arc.vert.glsl +79 -0
  232. package/src/ts/shaders/tile.frag.glsl +27 -0
  233. package/src/ts/shaders/tile.vert.glsl +35 -0
  234. package/src/ts/shaders/treemap.frag.glsl +19 -0
  235. package/src/ts/shaders/treemap.vert.glsl +25 -0
  236. package/src/ts/shaders/y-scatter.frag.glsl +30 -0
  237. package/src/ts/shaders/y-scatter.vert.glsl +31 -0
  238. package/src/ts/theme/gradient.ts +312 -0
  239. package/src/ts/theme/palette.ts +64 -0
  240. package/src/ts/theme/theme-snapshot.ts +66 -0
  241. package/src/ts/theme/theme.ts +166 -0
  242. package/src/ts/transport/protocol.ts +497 -0
  243. package/src/ts/transport/renderer-transport.ts +788 -0
  244. package/src/ts/utils/css.ts +36 -0
  245. package/src/ts/utils/font-snapshot.ts +159 -0
  246. package/src/ts/webgl/buffer-pool.ts +163 -0
  247. package/src/ts/webgl/context-manager.ts +414 -0
  248. package/src/ts/webgl/gradient-texture.ts +84 -0
  249. package/src/ts/webgl/instanced-attrs.ts +139 -0
  250. package/src/ts/webgl/plot-frame.ts +91 -0
  251. package/src/ts/webgl/program-cache.ts +46 -0
  252. package/src/ts/webgl/shader-manifest.ts +148 -0
  253. package/src/ts/webgl/shader-registry.ts +97 -0
  254. package/src/ts/worker/boot.ts +22 -0
  255. package/src/ts/worker/dispatch.ts +99 -0
  256. package/src/ts/worker/font-loader.ts +89 -0
  257. package/src/ts/worker/renderer.worker.ts +734 -0
  258. package/src/ts/worker/session-host.ts +118 -0
@@ -0,0 +1,368 @@
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 { AbstractChart } from "../chart-base";
16
+ import { PlotLayout } from "../../layout/plot-layout";
17
+ import type { CategoricalLevel } from "../../axis/categorical-axis";
18
+ import type { FacetGrid } from "../../layout/facet-grid";
19
+ import type {
20
+ AxisMode,
21
+ NumericCategoryDomain,
22
+ } from "../common/category-axis-resolver";
23
+ import {
24
+ buildHeatmapPipeline,
25
+ partitionColumnsPerFacet,
26
+ type HeatmapCell,
27
+ type HeatmapPipelineResult,
28
+ } from "./heatmap-build";
29
+ import {
30
+ renderHeatmapFrame,
31
+ renderHeatmapChromeOverlay,
32
+ type HeatmapLocations,
33
+ } from "./heatmap-render";
34
+ import { handleHeatmapHover } from "./heatmap-interact";
35
+
36
+ /**
37
+ * One heatmap in a facet-grid layout. Each facet corresponds to one
38
+ * user-selected column in the `Color` slot; its `pipeline` holds the
39
+ * cell data, and `layout` is the cell's `PlotLayout` from `buildFacetGrid`.
40
+ * `instanceStart`/`instanceCount` give the range of the packed
41
+ * cell/colorT buffers that belong to this facet.
42
+ */
43
+ export interface HeatmapFacet {
44
+ label: string;
45
+ pipeline: HeatmapPipelineResult;
46
+ layout: PlotLayout;
47
+ instanceStart: number;
48
+ instanceCount: number;
49
+
50
+ /**
51
+ * Origins used to rebase cell positions before f32 narrowing —
52
+ * matches the per-axis convention in `SeriesChart._categoryOrigin`.
53
+ * `0` for non-numeric axes; for numeric (especially datetime) axes
54
+ * pinned to `xNumericDomain.min` / `yNumericDomain.min` so the
55
+ * shader's projection matrix can be built in rebased space.
56
+ */
57
+ xOrigin: number;
58
+ yOrigin: number;
59
+ }
60
+
61
+ /**
62
+ * Heatmap chart. `yIdx` maps 1:1 to the arrow column iteration order
63
+ * (after skipping `__ROW_PATH_N__` metadata). `xIdx` is the row index
64
+ * post-`rowOffset`.
65
+ *
66
+ * With one user column in the `Color` slot the chart renders a single
67
+ * heatmap filling the canvas. With more than one, each column becomes
68
+ * its own heatmap in a facet grid; all facets share a common color
69
+ * scale and a single legend.
70
+ */
71
+ export class HeatmapChart extends AbstractChart {
72
+ _program: WebGLProgram | null = null;
73
+ _locations: HeatmapLocations | null = null;
74
+ _cornerBuffer: WebGLBuffer | null = null;
75
+ _gradientCache:
76
+ | import("../../webgl/gradient-texture").GradientTextureCache
77
+ | null = null;
78
+
79
+ _xLevels: CategoricalLevel[] = [];
80
+ _yLevels: CategoricalLevel[] = [];
81
+ _yColumnNames: string[] = [];
82
+ _numX = 0;
83
+ _numY = 0;
84
+ _rowOffset = 0;
85
+
86
+ _xAxisMode: AxisMode = { mode: "category" };
87
+ _yAxisMode: AxisMode = { mode: "category" };
88
+ _xPositions: Float64Array | null = null;
89
+ _yPositions: Float64Array | null = null;
90
+ _xNumericDomain: NumericCategoryDomain | null = null;
91
+ _yNumericDomain: NumericCategoryDomain | null = null;
92
+
93
+ /**
94
+ * Single-plot rebase origins. Datetime numeric axes carry ~1.7e12
95
+ * timestamps which the f32 GPU pipeline cannot resolve below
96
+ * ~256ms; the cell upload subtracts these and the projection
97
+ * matrix is built with the same values so its `tx`/`ty` terms stay
98
+ * small enough for f32 cancellation in the shader. `0` for
99
+ * categorical or numeric-non-date axes.
100
+ */
101
+ _xOrigin = 0;
102
+ _yOrigin = 0;
103
+
104
+ _cells: HeatmapCell[] = [];
105
+ _cells2D: (HeatmapCell | null)[] = [];
106
+ _uploadedCells = 0;
107
+
108
+ _colorMin = 0;
109
+ _colorMax = 1;
110
+ _aggName = "";
111
+
112
+ _hoveredCell: HeatmapCell | null = null;
113
+ _lastLayout: PlotLayout | null = null;
114
+
115
+ /**
116
+ * Last cursor position (canvas-CSS pixels) recorded by
117
+ * `handleHeatmapHover`. Used as the tooltip anchor instead of the
118
+ * cell center so the hover label tracks the mouse — necessary
119
+ * because heatmap cells can be many pixels wide and a center-anchored
120
+ * tooltip drifts away from the cursor.
121
+ */
122
+ _hoveredMouseX = 0;
123
+ _hoveredMouseY = 0;
124
+
125
+ _facets: HeatmapFacet[] = [];
126
+ _facetGrid: FacetGrid | null = null;
127
+ _hoveredFacetIdx = -1;
128
+
129
+ /**
130
+ * Bound accessor so the interact module can trigger a chrome redraw.
131
+ */
132
+ _renderChromeOverlay = () => renderHeatmapChromeOverlay(this);
133
+
134
+ protected override tooltipCallbacks() {
135
+ return {
136
+ onHover: (mx: number, my: number) =>
137
+ handleHeatmapHover(this, mx, my),
138
+ onLeave: () => {
139
+ if (this._hoveredCell) {
140
+ this._hoveredCell = null;
141
+ this._renderChromeOverlay();
142
+ }
143
+ },
144
+ onPin: (mx: number, my: number) => {
145
+ // Refresh the hit-test at the click coords so the pin
146
+ // path doesn't depend on the RAF-throttled hover state
147
+ // — see comment in `series.ts` `onPin`.
148
+ handleHeatmapHover(this, mx, my);
149
+ if (this._hoveredCell) {
150
+ void this._emitHeatmapClickSelect(
151
+ this._hoveredCell.xIdx,
152
+ this._hoveredCell.yIdx,
153
+ );
154
+ }
155
+ },
156
+ onUnpin: () => {
157
+ this.emitUnselect();
158
+ },
159
+ };
160
+ }
161
+
162
+ /**
163
+ * Resolve a clicked heatmap cell into a `PerspectiveClickDetail`
164
+ * and emit both `perspective-click` and
165
+ * `perspective-global-filter selected:true`. `xIdx` indexes the
166
+ * outer (group-by) hierarchy; `yIdx` indexes the column-side
167
+ * hierarchy (split-by + value-column splits). Each level is read
168
+ * directly from the pre-resolved `_xLevels` / `_yLevels` labels.
169
+ *
170
+ * Representative source row: `xIdx + _rowOffset` — the row in the
171
+ * pivoted view that owns this category. Sufficient for the
172
+ * `row.{col}` lookups consumers typically do; not authoritative for
173
+ * cells that aggregate across many source rows.
174
+ */
175
+ private async _emitHeatmapClickSelect(
176
+ xIdx: number,
177
+ yIdx: number,
178
+ ): Promise<void> {
179
+ const groupByValues: (string | null)[] = this._xLevels.map(
180
+ (level) => level.labels[xIdx] ?? null,
181
+ );
182
+ const splitByValues: (string | null)[] = this._yLevels
183
+ .slice(0, this._splitBy.length)
184
+ .map((level) => level.labels[yIdx] ?? null);
185
+
186
+ const colorColumn = this._columnSlots[0] ?? "";
187
+ await this.emitClickAndSelect({
188
+ rowIdx: xIdx + this._rowOffset,
189
+ columnName: colorColumn,
190
+ groupByValues,
191
+ splitByValues,
192
+ });
193
+ }
194
+
195
+ async uploadAndRender(
196
+ glManager: WebGLContextManager,
197
+ columns: ColumnDataMap,
198
+ startRow: number,
199
+ endRow: number,
200
+ ): Promise<void> {
201
+ this._glManager = glManager;
202
+
203
+ if (startRow !== 0) {
204
+ // Heatmap renders a single consolidated pass; the viewer
205
+ // should not chunk this but guard defensively.
206
+ return;
207
+ }
208
+
209
+ const userColumns = this._columnSlots.filter((s): s is string => !!s);
210
+
211
+ if (userColumns.length > 1) {
212
+ const partitions = partitionColumnsPerFacet(columns, userColumns);
213
+ const facets: HeatmapFacet[] = [];
214
+ const allCells: HeatmapCell[] = [];
215
+ let globalMin = Infinity;
216
+ let globalMax = -Infinity;
217
+ for (const part of partitions) {
218
+ const pipeline = buildHeatmapPipeline({
219
+ columns: part.columns,
220
+ numRows: endRow,
221
+ groupBy: this._groupBy,
222
+ splitBy: this._splitBy,
223
+ groupByTypes: this._groupByTypes,
224
+ });
225
+ const instanceStart = allCells.length;
226
+
227
+ // Re-stamp each cell with its facet offset so the packed
228
+ // instance buffer can be drawn in one sweep; the facet's
229
+ // own `pipeline.cells` keeps its original indices for
230
+ // hit-testing via `cells2D`.
231
+ for (const c of pipeline.cells) {
232
+ allCells.push({
233
+ xIdx: c.xIdx,
234
+ yIdx: c.yIdx,
235
+ value: c.value,
236
+ });
237
+ }
238
+
239
+ facets.push({
240
+ label: part.label,
241
+ pipeline,
242
+ layout: new PlotLayout(1, 1, {
243
+ hasXLabel: false,
244
+ hasYLabel: false,
245
+ hasLegend: false,
246
+ }),
247
+ instanceStart,
248
+ instanceCount: pipeline.cells.length,
249
+ xOrigin: pipeline.xNumericDomain?.min ?? 0,
250
+ yOrigin: pipeline.yNumericDomain?.min ?? 0,
251
+ });
252
+ if (
253
+ isFinite(pipeline.colorMin) &&
254
+ pipeline.colorMin < globalMin
255
+ ) {
256
+ globalMin = pipeline.colorMin;
257
+ }
258
+
259
+ if (
260
+ isFinite(pipeline.colorMax) &&
261
+ pipeline.colorMax > globalMax
262
+ ) {
263
+ globalMax = pipeline.colorMax;
264
+ }
265
+ }
266
+
267
+ if (!isFinite(globalMin) || !isFinite(globalMax)) {
268
+ globalMin = 0;
269
+ globalMax = 1;
270
+ } else if (globalMin === globalMax) {
271
+ globalMax = globalMin + 1;
272
+ }
273
+
274
+ // Reset single-plot state so render-time dispatch on
275
+ // `_facets.length > 0` is unambiguous.
276
+ this._xLevels = [];
277
+ this._yLevels = [];
278
+ this._yColumnNames = [];
279
+ this._numX = 0;
280
+ this._numY = 0;
281
+ this._rowOffset = 0;
282
+ this._cells2D = [];
283
+ this._lastLayout = null;
284
+ this._xAxisMode = { mode: "category" };
285
+ this._yAxisMode = { mode: "category" };
286
+ this._xPositions = null;
287
+ this._yPositions = null;
288
+ this._xNumericDomain = null;
289
+ this._yNumericDomain = null;
290
+ this._xOrigin = 0;
291
+ this._yOrigin = 0;
292
+
293
+ this._facets = facets;
294
+ this._cells = allCells;
295
+ this._colorMin = globalMin;
296
+ this._colorMax = globalMax;
297
+ this._aggName = userColumns.join(", ");
298
+ } else {
299
+ const result = buildHeatmapPipeline({
300
+ columns,
301
+ numRows: endRow,
302
+ groupBy: this._groupBy,
303
+ splitBy: this._splitBy,
304
+ groupByTypes: this._groupByTypes,
305
+ });
306
+
307
+ this._facets = [];
308
+ this._facetGrid = null;
309
+ this._xLevels = result.xLevels;
310
+ this._yLevels = result.yLevels;
311
+ this._yColumnNames = result.yColumnNames;
312
+ this._numX = result.numX;
313
+ this._numY = result.numY;
314
+ this._rowOffset = result.rowOffset;
315
+ this._cells = result.cells;
316
+ this._cells2D = result.cells2D;
317
+ this._colorMin = result.colorMin;
318
+ this._colorMax = result.colorMax;
319
+ this._aggName = userColumns[0] ?? "Color";
320
+ this._xAxisMode = result.xAxisMode;
321
+ this._yAxisMode = result.yAxisMode;
322
+ this._xPositions = result.xPositions;
323
+ this._yPositions = result.yPositions;
324
+ this._xNumericDomain = result.xNumericDomain;
325
+ this._yNumericDomain = result.yNumericDomain;
326
+ this._xOrigin = result.xNumericDomain?.min ?? 0;
327
+ this._yOrigin = result.yNumericDomain?.min ?? 0;
328
+ }
329
+
330
+ await this.requestRender(glManager);
331
+ }
332
+
333
+ _fullRender(glManager: WebGLContextManager): void {
334
+ this._glManager = glManager;
335
+ const hasSingle = this._numX > 0 && this._numY > 0;
336
+ const hasFacets = this._facets.length > 0;
337
+ if (!hasSingle && !hasFacets) {
338
+ return;
339
+ }
340
+
341
+ renderHeatmapFrame(this, glManager);
342
+ }
343
+
344
+ protected destroyInternal(): void {
345
+ if (this._cornerBuffer && this._glManager) {
346
+ this._glManager.gl.deleteBuffer(this._cornerBuffer);
347
+ }
348
+
349
+ this._program = null;
350
+ this._locations = null;
351
+ this._cornerBuffer = null;
352
+ this._xLevels = [];
353
+ this._yLevels = [];
354
+ this._yColumnNames = [];
355
+ this._cells = [];
356
+ this._cells2D = [];
357
+ this._hoveredCell = null;
358
+ this._facets = [];
359
+ this._facetGrid = null;
360
+ this._hoveredFacetIdx = -1;
361
+ this._xAxisMode = { mode: "category" };
362
+ this._yAxisMode = { mode: "category" };
363
+ this._xPositions = null;
364
+ this._yPositions = null;
365
+ this._xNumericDomain = null;
366
+ this._yNumericDomain = null;
367
+ }
368
+ }
@@ -0,0 +1,201 @@
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 { CartesianChart } from "../cartesian/cartesian";
14
+ import { PointGlyph } from "../cartesian/glyphs/points";
15
+ import { LineGlyph } from "../cartesian/glyphs/lines";
16
+ import { DensityGlyph } from "../cartesian/glyphs/density";
17
+ import type { Glyph } from "../cartesian/glyph";
18
+ import type { WebGLContextManager } from "../../webgl/context-manager";
19
+ import type { PlotLayout } from "../../layout/plot-layout";
20
+ import type { Theme } from "../../theme/theme";
21
+ import type { Canvas2D, Context2D } from "../canvas-types";
22
+ import type { ZoomConfig } from "../../interaction/zoom-controller";
23
+ import type { PluginConfig } from "../chart";
24
+ import { TileLayer } from "../../map/tile-layer";
25
+ import { tileSourceFor, type TileProviderId } from "../../map/tile-source";
26
+ import { lonLatToMercator } from "../../map/mercator";
27
+ import { getScaledContext } from "../../axis/canvas";
28
+
29
+ /**
30
+ * Map-mode base for cartesian charts. Reuses the entire cartesian
31
+ * pipeline (build, hit-test, zoom controller, lazy tooltips, faceting,
32
+ * theme, gradient texture) and swaps three behaviors:
33
+ *
34
+ * - `projectPoint(lon, lat)` Mercator-projects incoming columns so
35
+ * the rest of the pipeline operates in meter-space (linear
36
+ * projection matrix, screen-space splat radius, hit-test grid all
37
+ * "just work").
38
+ * - `_renderMode = "map"` flips the render-frame branches to skip
39
+ * cartesian gridlines and axes, insert a basemap layer before the
40
+ * glyph draw, and use the map-specific chrome (attribution).
41
+ * - `getZoomConfig()` returns `lockAspect: true` so wheel zoom keeps
42
+ * `dataPerPixel` uniform on both axes (required: Mercator
43
+ * preserves angle, glyphs distort otherwise).
44
+ *
45
+ * Concrete map plugin tags (`map-scatter`, `map-line`, `map-density`)
46
+ * pin a glyph in their nullary constructor exactly like the cartesian
47
+ * convenience subclasses.
48
+ */
49
+ export class MapChart extends CartesianChart {
50
+ override _renderMode = "map" as const;
51
+
52
+ private _tileLayer: TileLayer;
53
+
54
+ constructor(glyph: Glyph) {
55
+ super(glyph);
56
+ this._tileLayer = new TileLayer();
57
+ this._tileLayer.setOnTileLoad(() => {
58
+ // Tile arrival schedules a fresh frame through the shared
59
+ // render scheduler; no-ops if a frame is already pending.
60
+ if (this._glManager) {
61
+ this.requestRender(this._glManager);
62
+ }
63
+ });
64
+ }
65
+
66
+ override projectPoint(lon: number, lat: number): [number, number] {
67
+ return lonLatToMercator(lon, lat);
68
+ }
69
+
70
+ protected override getZoomConfig(): ZoomConfig {
71
+ return { lockAspect: true };
72
+ }
73
+
74
+ override setPluginConfig(cfg: PluginConfig): void {
75
+ super.setPluginConfig(cfg);
76
+ if (this._glManager) {
77
+ this._tileLayer.setSource(
78
+ this._glManager.gl,
79
+ tileSourceFor(cfg.map_tile_provider as TileProviderId),
80
+ );
81
+ }
82
+
83
+ this._tileLayer.setAlpha(cfg.map_tile_alpha);
84
+ }
85
+
86
+ override renderBackground(
87
+ glManager: WebGLContextManager,
88
+ layout: PlotLayout,
89
+ projection: Float32Array,
90
+ domain: { xMin: number; xMax: number; yMin: number; yMax: number },
91
+ xOrigin: number,
92
+ yOrigin: number,
93
+ ): void {
94
+ // Lazy source bind — `setPluginConfig` runs before
95
+ // `_glManager` is wired in some host bootstraps, so we
96
+ // re-attempt on first render if needed.
97
+ if (!this._tileLayer.source) {
98
+ this._tileLayer.setSource(
99
+ glManager.gl,
100
+ tileSourceFor(
101
+ this._pluginConfig.map_tile_provider as TileProviderId,
102
+ ),
103
+ );
104
+ this._tileLayer.setAlpha(this._pluginConfig.map_tile_alpha);
105
+ }
106
+
107
+ this._tileLayer.render(
108
+ glManager,
109
+ layout,
110
+ projection,
111
+ domain,
112
+ xOrigin,
113
+ yOrigin,
114
+ );
115
+ }
116
+
117
+ override renderMapChrome(
118
+ canvas: Canvas2D | null,
119
+ layout: PlotLayout,
120
+ theme: Theme,
121
+ dpr: number,
122
+ ): void {
123
+ if (!canvas) {
124
+ return;
125
+ }
126
+
127
+ const ctx = getScaledContext(canvas, dpr) as Context2D | null;
128
+ if (!ctx) {
129
+ return;
130
+ }
131
+
132
+ const attribution = this._tileLayer.source?.attribution ?? "";
133
+ if (!attribution) {
134
+ return;
135
+ }
136
+
137
+ const plot = layout.plotRect;
138
+ ctx.save();
139
+ ctx.font = `10px ${theme.fontFamily}`;
140
+ ctx.textAlign = "right";
141
+ ctx.textBaseline = "bottom";
142
+
143
+ // Pill background so attribution stays legible over any tile.
144
+ const padding = 4;
145
+ const metrics = ctx.measureText(attribution);
146
+ const textW = metrics.width;
147
+ const textH = 12;
148
+ const x = plot.x + plot.width - 4;
149
+ const y = plot.y + plot.height - 4;
150
+ ctx.fillStyle = "rgba(255, 255, 255, 0.75)";
151
+ ctx.fillRect(
152
+ x - textW - padding * 2,
153
+ y - textH - padding,
154
+ textW + padding * 2,
155
+ textH + padding,
156
+ );
157
+ ctx.fillStyle = theme.labelColor;
158
+ ctx.fillText(attribution, x - padding, y - padding / 2);
159
+ ctx.restore();
160
+ }
161
+
162
+ protected override destroyInternal(): void {
163
+ if (this._glManager) {
164
+ this._tileLayer.destroy(this._glManager.gl);
165
+ }
166
+
167
+ super.destroyInternal();
168
+ }
169
+ }
170
+
171
+ /**
172
+ * Map Scatter — Mercator scatter on a raster basemap. Same glyph as
173
+ * `X/Y Scatter`; only projection and chrome differ.
174
+ */
175
+ export class MapScatterChart extends MapChart {
176
+ constructor() {
177
+ super(new PointGlyph());
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Map Line — Mercator polyline on a raster basemap. Same glyph as
183
+ * `X/Y Line`.
184
+ */
185
+ export class MapLineChart extends MapChart {
186
+ constructor() {
187
+ super(new LineGlyph());
188
+ }
189
+ }
190
+
191
+ /**
192
+ * Map Density — Mercator KDE on a raster basemap. Same glyph as
193
+ * `Density`; the four `gradient_color_mode` variants
194
+ * (density/mean/extreme/signed) are all available on the map too
195
+ * because the glyph reads `_pluginConfig` directly.
196
+ */
197
+ export class MapDensityChart extends MapChart {
198
+ constructor() {
199
+ super(new DensityGlyph());
200
+ }
201
+ }
@@ -0,0 +1,65 @@
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 { ScatterChart, LineChart, DensityChart } from "./cartesian/cartesian";
14
+ import { TreemapChart } from "./treemap/treemap";
15
+ import { SunburstChart } from "./sunburst/sunburst";
16
+ import { SeriesChart, XBarChart } from "./series/series";
17
+ import { HeatmapChart } from "./heatmap/heatmap";
18
+ import { CandlestickChart } from "./candlestick/candlestick";
19
+ import type { ChartImplementation } from "./chart";
20
+
21
+ type ChartImplCtor = new () => ChartImplementation;
22
+
23
+ /**
24
+ * Map from `ChartTypeConfig.tag` to a factory returning the chart-impl
25
+ * class. Consumed by `renderer.worker.ts` which `await`s the factory
26
+ * before constructing the impl.
27
+ *
28
+ * Eager chart types resolve immediately — `Promise.resolve(Class)` is
29
+ * a microtask, no I/O. Map plugins resolve via dynamic `import()` so
30
+ * the bundler emits the tile-rendering subsystem and the map-mode
31
+ * subclasses as a separate chunk; non-map users never fetch it.
32
+ */
33
+ export const CHART_IMPLS: Record<string, () => Promise<ChartImplCtor>> = {
34
+ scatter: async () => ScatterChart,
35
+ line: async () => LineChart,
36
+ density: async () => DensityChart,
37
+ treemap: async () => TreemapChart,
38
+ sunburst: async () => SunburstChart,
39
+ heatmap: async () => HeatmapChart,
40
+
41
+ // All four Y-series plugins share BarChart; they differ only in the
42
+ // per-plugin default `chart_type` forwarded via `setDefaultChartType`
43
+ // during plugin setup.
44
+ "y-bar": async () => SeriesChart,
45
+ "y-line": async () => SeriesChart,
46
+ "y-scatter": async () => SeriesChart,
47
+ "y-area": async () => SeriesChart,
48
+
49
+ // X Bar is the horizontal orientation of the same chart class.
50
+ "x-bar": async () => XBarChart,
51
+
52
+ // Both candlestick-family plugins share one impl; the render path
53
+ // branches on `_defaultChartType` (set from `default_chart_type` in
54
+ // the plugin config) to pick the glyph.
55
+ candlestick: async () => CandlestickChart,
56
+ ohlc: async () => CandlestickChart,
57
+
58
+ // Map plugins. Dynamic-imported so the bundler splits the
59
+ // `map/*` (tile fetch, cache, layer, shaders) and `charts/map/*`
60
+ // (MapChart + subclasses) modules into a chunk that loads only
61
+ // when the user activates one of these tags.
62
+ "map-scatter": async () => (await import("./map/map")).MapScatterChart,
63
+ "map-line": async () => (await import("./map/map")).MapLineChart,
64
+ "map-density": async () => (await import("./map/map")).MapDensityChart,
65
+ };