@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,432 @@
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 { WebGLContextManager } from "../../../webgl/context-manager";
14
+ import type { CandlestickChart } from "../candlestick";
15
+ import {
16
+ createLineCornerBuffer,
17
+ createQuadCornerBuffer,
18
+ getInstancing,
19
+ } from "../../../webgl/instanced-attrs";
20
+ import { compileProgram } from "../../../webgl/program-cache";
21
+ import bodyVert from "../../../shaders/candlestick-body.vert.glsl";
22
+ import bodyFrag from "../../../shaders/candlestick-body.frag.glsl";
23
+ import lineVert from "../../../shaders/line-uniform.vert.glsl";
24
+ import lineFrag from "../../../shaders/line-uniform.frag.glsl";
25
+
26
+ type GL = WebGL2RenderingContext | WebGLRenderingContext;
27
+
28
+ interface BodyCache {
29
+ program: WebGLProgram;
30
+ quadBuffer: WebGLBuffer;
31
+ instanceBuffer: WebGLBuffer;
32
+ u_projection: WebGLUniformLocation | null;
33
+ a_corner: number;
34
+ a_x_center: number;
35
+ a_half_width: number;
36
+ a_y0: number;
37
+ a_y1: number;
38
+ a_color: number;
39
+ }
40
+
41
+ interface WickCache {
42
+ program: WebGLProgram;
43
+ cornerBuffer: WebGLBuffer;
44
+ segmentBuffer: WebGLBuffer;
45
+ u_projection: WebGLUniformLocation | null;
46
+ u_color: WebGLUniformLocation | null;
47
+ u_resolution: WebGLUniformLocation | null;
48
+ u_line_width: WebGLUniformLocation | null;
49
+ a_corner: number;
50
+ a_start: number;
51
+ a_end: number;
52
+ }
53
+
54
+ interface ProgramCache {
55
+ body: BodyCache;
56
+ wick: WickCache;
57
+ }
58
+
59
+ /**
60
+ * Persistent body + wick vertex buffer state. Built once per data load
61
+ * by `rebuildBuffers`; pan/zoom redraws bind + dispatch with no uploads.
62
+ */
63
+ interface BodyWickBuffers {
64
+ bodyCount: number;
65
+ upWickCount: number;
66
+ downWickCount: number;
67
+
68
+ /**
69
+ * Persistent GPU buffer for up wicks. Layout: [x,low, x,high, ...].
70
+ */
71
+ upWickBuffer: WebGLBuffer;
72
+ downWickBuffer: WebGLBuffer;
73
+ }
74
+
75
+ /**
76
+ * Candlestick body + wick glyph. Owns the body and wick programs +
77
+ * their corner/segment/instance buffers, and the persistent up/down
78
+ * wick vertex buffers built per data load.
79
+ */
80
+ export class BodyWickGlyph {
81
+ private _program: ProgramCache | null = null;
82
+ private _buffers: BodyWickBuffers | null = null;
83
+
84
+ /**
85
+ * Lazily compile the body and wick programs and create their static
86
+ * GPU buffers (corner / quad). Cached for the lifetime of the chart.
87
+ */
88
+ private ensureProgram(glManager: WebGLContextManager): ProgramCache {
89
+ if (this._program) {
90
+ return this._program;
91
+ }
92
+
93
+ const gl = glManager.gl;
94
+
95
+ const quadBuffer = createQuadCornerBuffer(gl);
96
+ const bodyPartial = compileProgram<
97
+ Omit<BodyCache, "quadBuffer" | "instanceBuffer">
98
+ >(
99
+ glManager,
100
+ "candlestick-body",
101
+ bodyVert,
102
+ bodyFrag,
103
+ ["u_projection"],
104
+ [
105
+ "a_corner",
106
+ "a_x_center",
107
+ "a_half_width",
108
+ "a_y0",
109
+ "a_y1",
110
+ "a_color",
111
+ ],
112
+ );
113
+ const body: BodyCache = {
114
+ ...bodyPartial,
115
+ quadBuffer,
116
+ instanceBuffer: gl.createBuffer()!,
117
+ };
118
+
119
+ const cornerBuffer = createLineCornerBuffer(gl);
120
+ const wickPartial = compileProgram<
121
+ Omit<WickCache, "cornerBuffer" | "segmentBuffer">
122
+ >(
123
+ glManager,
124
+ "line-uniform",
125
+ lineVert,
126
+ lineFrag,
127
+ ["u_projection", "u_color", "u_resolution", "u_line_width"],
128
+ ["a_corner", "a_start", "a_end"],
129
+ );
130
+ const wick: WickCache = {
131
+ ...wickPartial,
132
+ cornerBuffer,
133
+ segmentBuffer: gl.createBuffer()!,
134
+ };
135
+
136
+ this._program = { body, wick };
137
+ return this._program;
138
+ }
139
+
140
+ /**
141
+ * Drop persistent body + wick vertex buffers. Called from data-load
142
+ * (before `rebuildBuffers`) and from chart-destroy paths.
143
+ */
144
+ invalidateBuffers(chart: CandlestickChart): void {
145
+ const buf = this._buffers;
146
+ if (!buf || !chart._glManager) {
147
+ this._buffers = null;
148
+ return;
149
+ }
150
+
151
+ const gl = chart._glManager.gl;
152
+ gl.deleteBuffer(buf.upWickBuffer);
153
+ gl.deleteBuffer(buf.downWickBuffer);
154
+ this._buffers = null;
155
+ }
156
+
157
+ /**
158
+ * Pre-build the per-instance body buffer (interleaved
159
+ * [xCenter, halfWidth, y0, y1, r, g, b]) and the up/down wick
160
+ * line-segment buffers. Single GPU upload per buffer per data load.
161
+ */
162
+ rebuildBuffers(
163
+ chart: CandlestickChart,
164
+ glManager: WebGLContextManager,
165
+ ): void {
166
+ const candles = chart._candles;
167
+ const cache = this.ensureProgram(glManager);
168
+ const gl = glManager.gl;
169
+ const xOrigin = chart._categoryOrigin;
170
+
171
+ if (candles.count === 0) {
172
+ const upBuf = gl.createBuffer()!;
173
+ const downBuf = gl.createBuffer()!;
174
+ this._buffers = {
175
+ bodyCount: 0,
176
+ upWickCount: 0,
177
+ downWickCount: 0,
178
+ upWickBuffer: upBuf,
179
+ downWickBuffer: downBuf,
180
+ };
181
+ return;
182
+ }
183
+
184
+ // Body buffer: 7 floats per candle (interleaved).
185
+ const data = new Float32Array(candles.count * 7);
186
+ let upCount = 0;
187
+ let downCount = 0;
188
+ const xC = candles.xCenter;
189
+ const hw = candles.halfWidth;
190
+ const open = candles.open;
191
+ const close = candles.close;
192
+ const isUp = candles.isUp;
193
+ const upColor = chart._upColor;
194
+ const downColor = chart._downColor;
195
+ for (let i = 0; i < candles.count; i++) {
196
+ const o = open[i];
197
+ const c = close[i];
198
+ const bodyLow = o < c ? o : c;
199
+ const bodyHigh = o < c ? c : o;
200
+ const up = isUp[i] !== 0;
201
+ const col = up ? upColor : downColor;
202
+ const off = i * 7;
203
+ data[off + 0] = xC[i] - xOrigin;
204
+ data[off + 1] = hw[i] * 0.7;
205
+ data[off + 2] = bodyLow;
206
+ data[off + 3] = bodyHigh;
207
+ data[off + 4] = col[0];
208
+ data[off + 5] = col[1];
209
+ data[off + 6] = col[2];
210
+
211
+ if (up) {
212
+ upCount++;
213
+ } else {
214
+ downCount++;
215
+ }
216
+ }
217
+
218
+ gl.bindBuffer(gl.ARRAY_BUFFER, cache.body.instanceBuffer);
219
+ gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
220
+
221
+ // Wick buffers: per-color, packed [x,low, x,high] segments.
222
+ const upWick = new Float32Array(upCount * 4);
223
+ const downWick = new Float32Array(downCount * 4);
224
+ let upW = 0;
225
+ let downW = 0;
226
+ const lows = candles.low;
227
+ const highs = candles.high;
228
+ for (let i = 0; i < candles.count; i++) {
229
+ const x = xC[i] - xOrigin;
230
+ const lo = lows[i];
231
+ const hi = highs[i];
232
+ if (isUp[i] !== 0) {
233
+ upWick[upW + 0] = x;
234
+ upWick[upW + 1] = lo;
235
+ upWick[upW + 2] = x;
236
+ upWick[upW + 3] = hi;
237
+ upW += 4;
238
+ } else {
239
+ downWick[downW + 0] = x;
240
+ downWick[downW + 1] = lo;
241
+ downWick[downW + 2] = x;
242
+ downWick[downW + 3] = hi;
243
+ downW += 4;
244
+ }
245
+ }
246
+
247
+ // Reuse existing wick GL buffers when available; otherwise allocate.
248
+ const prev = this._buffers;
249
+ const upBuf = prev?.upWickBuffer ?? gl.createBuffer()!;
250
+ const downBuf = prev?.downWickBuffer ?? gl.createBuffer()!;
251
+ gl.bindBuffer(gl.ARRAY_BUFFER, upBuf);
252
+ gl.bufferData(gl.ARRAY_BUFFER, upWick, gl.STATIC_DRAW);
253
+ gl.bindBuffer(gl.ARRAY_BUFFER, downBuf);
254
+ gl.bufferData(gl.ARRAY_BUFFER, downWick, gl.STATIC_DRAW);
255
+
256
+ this._buffers = {
257
+ bodyCount: candles.count,
258
+ upWickCount: upCount,
259
+ downWickCount: downCount,
260
+ upWickBuffer: upBuf,
261
+ downWickBuffer: downBuf,
262
+ };
263
+ }
264
+
265
+ draw(
266
+ chart: CandlestickChart,
267
+ gl: GL,
268
+ glManager: WebGLContextManager,
269
+ projection: Float32Array,
270
+ ): void {
271
+ const buf = this._buffers;
272
+ if (!buf || buf.bodyCount === 0) {
273
+ return;
274
+ }
275
+
276
+ const cache = this.ensureProgram(glManager);
277
+ drawBodies(gl, glManager, cache.body, buf.bodyCount, projection);
278
+ drawWicks(chart, gl, glManager, cache.wick, buf, projection);
279
+ }
280
+
281
+ /**
282
+ * Free program-local GPU buffers + persistent vertex buffers. The
283
+ * shader programs themselves are owned by `WebGLContextManager.shaders`
284
+ * and not freed here.
285
+ */
286
+ destroy(chart: CandlestickChart): void {
287
+ const gl = chart._glManager?.gl;
288
+ if (gl) {
289
+ this.invalidateBuffers(chart);
290
+ const cache = this._program;
291
+ if (cache) {
292
+ gl.deleteBuffer(cache.body.quadBuffer);
293
+ gl.deleteBuffer(cache.body.instanceBuffer);
294
+ gl.deleteBuffer(cache.wick.cornerBuffer);
295
+ gl.deleteBuffer(cache.wick.segmentBuffer);
296
+ }
297
+ }
298
+
299
+ this._program = null;
300
+ this._buffers = null;
301
+ }
302
+ }
303
+
304
+ /**
305
+ * Bind the persistent body buffer and issue one instanced draw.
306
+ */
307
+ function drawBodies(
308
+ gl: GL,
309
+ glManager: WebGLContextManager,
310
+ cache: BodyCache,
311
+ instanceCount: number,
312
+ projection: Float32Array,
313
+ ): void {
314
+ if (instanceCount === 0) {
315
+ return;
316
+ }
317
+
318
+ const stride = 7 * Float32Array.BYTES_PER_ELEMENT;
319
+
320
+ gl.useProgram(cache.program);
321
+ gl.uniformMatrix4fv(cache.u_projection, false, projection);
322
+
323
+ const instancing = getInstancing(glManager);
324
+ const { setDivisor } = instancing;
325
+
326
+ // Per-vertex corner.
327
+ gl.bindBuffer(gl.ARRAY_BUFFER, cache.quadBuffer);
328
+ gl.enableVertexAttribArray(cache.a_corner);
329
+ gl.vertexAttribPointer(cache.a_corner, 2, gl.FLOAT, false, 0, 0);
330
+ setDivisor(cache.a_corner, 0);
331
+
332
+ // Per-instance attributes from the persistent interleaved buffer.
333
+ gl.bindBuffer(gl.ARRAY_BUFFER, cache.instanceBuffer);
334
+ const f = Float32Array.BYTES_PER_ELEMENT;
335
+ const bind = (loc: number, size: number, offset: number) => {
336
+ gl.enableVertexAttribArray(loc);
337
+ gl.vertexAttribPointer(loc, size, gl.FLOAT, false, stride, offset);
338
+ setDivisor(loc, 1);
339
+ };
340
+
341
+ bind(cache.a_x_center, 1, 0);
342
+ bind(cache.a_half_width, 1, 1 * f);
343
+ bind(cache.a_y0, 1, 2 * f);
344
+ bind(cache.a_y1, 1, 3 * f);
345
+ bind(cache.a_color, 3, 4 * f);
346
+
347
+ instancing.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, instanceCount);
348
+
349
+ setDivisor(cache.a_x_center, 0);
350
+ setDivisor(cache.a_half_width, 0);
351
+ setDivisor(cache.a_y0, 0);
352
+ setDivisor(cache.a_y1, 0);
353
+ setDivisor(cache.a_color, 0);
354
+ }
355
+
356
+ /**
357
+ * Bind the persistent up/down wick buffers and dispatch one
358
+ * instanced draw per color group. No per-frame allocations.
359
+ */
360
+ function drawWicks(
361
+ chart: CandlestickChart,
362
+ gl: GL,
363
+ glManager: WebGLContextManager,
364
+ cache: WickCache,
365
+ buf: BodyWickBuffers,
366
+ projection: Float32Array,
367
+ ): void {
368
+ if (buf.upWickCount === 0 && buf.downWickCount === 0) {
369
+ return;
370
+ }
371
+
372
+ const dpr = glManager.dpr;
373
+ gl.useProgram(cache.program);
374
+ gl.uniformMatrix4fv(cache.u_projection, false, projection);
375
+ gl.uniform2f(cache.u_resolution, gl.canvas.width, gl.canvas.height);
376
+ gl.uniform1f(cache.u_line_width, chart._pluginConfig.wick_width_px * dpr);
377
+
378
+ const instancing = getInstancing(glManager);
379
+ const { setDivisor } = instancing;
380
+
381
+ gl.bindBuffer(gl.ARRAY_BUFFER, cache.cornerBuffer);
382
+ gl.enableVertexAttribArray(cache.a_corner);
383
+ gl.vertexAttribPointer(cache.a_corner, 1, gl.FLOAT, false, 0, 0);
384
+ setDivisor(cache.a_corner, 0);
385
+
386
+ drawWickGroup(
387
+ gl,
388
+ instancing,
389
+ cache,
390
+ buf.upWickBuffer,
391
+ buf.upWickCount,
392
+ chart._upColor,
393
+ );
394
+ drawWickGroup(
395
+ gl,
396
+ instancing,
397
+ cache,
398
+ buf.downWickBuffer,
399
+ buf.downWickCount,
400
+ chart._downColor,
401
+ );
402
+
403
+ setDivisor(cache.a_start, 0);
404
+ setDivisor(cache.a_end, 0);
405
+ }
406
+
407
+ function drawWickGroup(
408
+ gl: GL,
409
+ instancing: ReturnType<typeof getInstancing>,
410
+ cache: WickCache,
411
+ segmentBuffer: WebGLBuffer,
412
+ count: number,
413
+ color: [number, number, number],
414
+ ): void {
415
+ if (count === 0) {
416
+ return;
417
+ }
418
+
419
+ const stride = 2 * Float32Array.BYTES_PER_ELEMENT;
420
+ const { setDivisor } = instancing;
421
+
422
+ gl.uniform4f(cache.u_color, color[0], color[1], color[2], 1.0);
423
+ gl.bindBuffer(gl.ARRAY_BUFFER, segmentBuffer);
424
+ gl.enableVertexAttribArray(cache.a_start);
425
+ gl.vertexAttribPointer(cache.a_start, 2, gl.FLOAT, false, 2 * stride, 0);
426
+ setDivisor(cache.a_start, 1);
427
+ gl.enableVertexAttribArray(cache.a_end);
428
+ gl.vertexAttribPointer(cache.a_end, 2, gl.FLOAT, false, 2 * stride, stride);
429
+ setDivisor(cache.a_end, 1);
430
+
431
+ instancing.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, count);
432
+ }