@neural-charts/native 0.0.0-stage → 0.1.0-beta.1

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 (508) hide show
  1. package/README.md +58 -2
  2. package/THIRD-PARTY-NOTICES.md +15 -0
  3. package/docs/guide.md +783 -0
  4. package/library/annular-hit.d.ts +10 -0
  5. package/library/annular-hit.d.ts.map +1 -0
  6. package/library/annular-hit.js +43 -0
  7. package/library/annular-hit.js.map +1 -0
  8. package/library/chart-capabilities.d.ts +326 -0
  9. package/library/chart-capabilities.d.ts.map +1 -0
  10. package/library/chart-capabilities.js +39 -0
  11. package/library/chart-capabilities.js.map +1 -0
  12. package/library/circular-scene.d.ts +55 -0
  13. package/library/circular-scene.d.ts.map +1 -0
  14. package/library/circular-scene.js +39 -0
  15. package/library/circular-scene.js.map +1 -0
  16. package/library/comparison-render.d.ts +18 -0
  17. package/library/comparison-render.d.ts.map +1 -0
  18. package/library/comparison-render.js +33 -0
  19. package/library/comparison-render.js.map +1 -0
  20. package/library/comparison-scene.d.ts +40 -0
  21. package/library/comparison-scene.d.ts.map +1 -0
  22. package/library/comparison-scene.js +77 -0
  23. package/library/comparison-scene.js.map +1 -0
  24. package/library/composition-scene.d.ts +35 -0
  25. package/library/composition-scene.d.ts.map +1 -0
  26. package/library/composition-scene.js +55 -0
  27. package/library/composition-scene.js.map +1 -0
  28. package/library/contour-hit-index.d.ts +15 -0
  29. package/library/contour-hit-index.d.ts.map +1 -0
  30. package/library/contour-hit-index.js +75 -0
  31. package/library/contour-hit-index.js.map +1 -0
  32. package/library/contour-label-anchors.d.ts +9 -0
  33. package/library/contour-label-anchors.d.ts.map +1 -0
  34. package/library/contour-label-anchors.js +20 -0
  35. package/library/contour-label-anchors.js.map +1 -0
  36. package/library/contour-scene.d.ts +10 -0
  37. package/library/contour-scene.d.ts.map +1 -0
  38. package/library/contour-scene.js +76 -0
  39. package/library/contour-scene.js.map +1 -0
  40. package/library/contracts.d.ts +445 -0
  41. package/library/contracts.d.ts.map +1 -0
  42. package/library/contracts.js +2 -0
  43. package/library/contracts.js.map +1 -0
  44. package/library/dendrogram-scene.d.ts +7 -0
  45. package/library/dendrogram-scene.d.ts.map +1 -0
  46. package/library/dendrogram-scene.js +28 -0
  47. package/library/dendrogram-scene.js.map +1 -0
  48. package/library/empty-state.d.ts +8 -0
  49. package/library/empty-state.d.ts.map +1 -0
  50. package/library/empty-state.js +30 -0
  51. package/library/empty-state.js.map +1 -0
  52. package/library/heatmap-hit.d.ts +27 -0
  53. package/library/heatmap-hit.d.ts.map +1 -0
  54. package/library/heatmap-hit.js +56 -0
  55. package/library/heatmap-hit.js.map +1 -0
  56. package/library/heatmap-scene.d.ts +17 -0
  57. package/library/heatmap-scene.d.ts.map +1 -0
  58. package/library/heatmap-scene.js +85 -0
  59. package/library/heatmap-scene.js.map +1 -0
  60. package/library/index.d.ts +14 -0
  61. package/library/index.d.ts.map +1 -0
  62. package/library/index.js +4 -0
  63. package/library/index.js.map +1 -0
  64. package/library/interaction-content.d.ts +4 -0
  65. package/library/interaction-content.d.ts.map +1 -0
  66. package/library/interaction-content.js +28 -0
  67. package/library/interaction-content.js.map +1 -0
  68. package/library/interaction.d.ts +75 -0
  69. package/library/interaction.d.ts.map +1 -0
  70. package/library/interaction.js +523 -0
  71. package/library/interaction.js.map +1 -0
  72. package/library/marker-style.d.ts +24 -0
  73. package/library/marker-style.d.ts.map +1 -0
  74. package/library/marker-style.js +43 -0
  75. package/library/marker-style.js.map +1 -0
  76. package/library/parallel-scene.d.ts +11 -0
  77. package/library/parallel-scene.d.ts.map +1 -0
  78. package/library/parallel-scene.js +44 -0
  79. package/library/parallel-scene.js.map +1 -0
  80. package/library/path-validation.d.ts +3 -0
  81. package/library/path-validation.d.ts.map +1 -0
  82. package/library/path-validation.js +78 -0
  83. package/library/path-validation.js.map +1 -0
  84. package/library/pictorial-hit.d.ts +19 -0
  85. package/library/pictorial-hit.d.ts.map +1 -0
  86. package/library/pictorial-hit.js +73 -0
  87. package/library/pictorial-hit.js.map +1 -0
  88. package/library/pictorial-scene.d.ts +16 -0
  89. package/library/pictorial-scene.d.ts.map +1 -0
  90. package/library/pictorial-scene.js +73 -0
  91. package/library/pictorial-scene.js.map +1 -0
  92. package/library/point-label-placement.d.ts +34 -0
  93. package/library/point-label-placement.d.ts.map +1 -0
  94. package/library/point-label-placement.js +24 -0
  95. package/library/point-label-placement.js.map +1 -0
  96. package/library/polar-grid.d.ts +5 -0
  97. package/library/polar-grid.d.ts.map +1 -0
  98. package/library/polar-grid.js +28 -0
  99. package/library/polar-grid.js.map +1 -0
  100. package/library/polygon-hit.d.ts +18 -0
  101. package/library/polygon-hit.d.ts.map +1 -0
  102. package/library/polygon-hit.js +98 -0
  103. package/library/polygon-hit.js.map +1 -0
  104. package/library/profile-scene.d.ts +11 -0
  105. package/library/profile-scene.d.ts.map +1 -0
  106. package/library/profile-scene.js +51 -0
  107. package/library/profile-scene.js.map +1 -0
  108. package/library/relationship-hit-index.d.ts +12 -0
  109. package/library/relationship-hit-index.d.ts.map +1 -0
  110. package/library/relationship-hit-index.js +87 -0
  111. package/library/relationship-hit-index.js.map +1 -0
  112. package/library/relationship-scene.d.ts +12 -0
  113. package/library/relationship-scene.d.ts.map +1 -0
  114. package/library/relationship-scene.js +62 -0
  115. package/library/relationship-scene.js.map +1 -0
  116. package/library/scene-paint.d.ts +29 -0
  117. package/library/scene-paint.d.ts.map +1 -0
  118. package/library/scene-paint.js +123 -0
  119. package/library/scene-paint.js.map +1 -0
  120. package/library/scene-styles.d.ts +13 -0
  121. package/library/scene-styles.d.ts.map +1 -0
  122. package/library/scene-styles.js +135 -0
  123. package/library/scene-styles.js.map +1 -0
  124. package/library/scene.d.ts +49 -0
  125. package/library/scene.d.ts.map +1 -0
  126. package/library/scene.js +533 -0
  127. package/library/scene.js.map +1 -0
  128. package/library/temporal-hit-index.d.ts +13 -0
  129. package/library/temporal-hit-index.d.ts.map +1 -0
  130. package/library/temporal-hit-index.js +71 -0
  131. package/library/temporal-hit-index.js.map +1 -0
  132. package/library/temporal-scene.d.ts +6 -0
  133. package/library/temporal-scene.d.ts.map +1 -0
  134. package/library/temporal-scene.js +70 -0
  135. package/library/temporal-scene.js.map +1 -0
  136. package/library/tile-index.d.ts +11 -0
  137. package/library/tile-index.d.ts.map +1 -0
  138. package/library/tile-index.js +37 -0
  139. package/library/tile-index.js.map +1 -0
  140. package/library/tilemap-hit.d.ts +11 -0
  141. package/library/tilemap-hit.d.ts.map +1 -0
  142. package/library/tilemap-hit.js +63 -0
  143. package/library/tilemap-hit.js.map +1 -0
  144. package/library/tilemap-scene.d.ts +24 -0
  145. package/library/tilemap-scene.d.ts.map +1 -0
  146. package/library/tilemap-scene.js +125 -0
  147. package/library/tilemap-scene.js.map +1 -0
  148. package/library/uncertainty-scene.d.ts +11 -0
  149. package/library/uncertainty-scene.d.ts.map +1 -0
  150. package/library/uncertainty-scene.js +61 -0
  151. package/library/uncertainty-scene.js.map +1 -0
  152. package/library/venn-hit.d.ts +21 -0
  153. package/library/venn-hit.d.ts.map +1 -0
  154. package/library/venn-hit.js +37 -0
  155. package/library/venn-hit.js.map +1 -0
  156. package/library/venn-scene.d.ts +14 -0
  157. package/library/venn-scene.d.ts.map +1 -0
  158. package/library/venn-scene.js +84 -0
  159. package/library/venn-scene.js.map +1 -0
  160. package/library/wordcloud-scene.d.ts +19 -0
  161. package/library/wordcloud-scene.d.ts.map +1 -0
  162. package/library/wordcloud-scene.js +58 -0
  163. package/library/wordcloud-scene.js.map +1 -0
  164. package/native/activity.d.ts +14 -0
  165. package/native/activity.d.ts.map +1 -0
  166. package/native/activity.js +31 -0
  167. package/native/activity.js.map +1 -0
  168. package/native/bar-labels.d.ts +4 -0
  169. package/native/bar-labels.d.ts.map +1 -0
  170. package/native/bar-labels.js +16 -0
  171. package/native/bar-labels.js.map +1 -0
  172. package/native/bubble-entrance.d.ts +15 -0
  173. package/native/bubble-entrance.d.ts.map +1 -0
  174. package/native/bubble-entrance.js +27 -0
  175. package/native/bubble-entrance.js.map +1 -0
  176. package/native/chart-drilldown.d.ts +57 -0
  177. package/native/chart-drilldown.d.ts.map +1 -0
  178. package/native/chart-drilldown.js +118 -0
  179. package/native/chart-drilldown.js.map +1 -0
  180. package/native/chart-motion.d.ts +69 -0
  181. package/native/chart-motion.d.ts.map +1 -0
  182. package/native/chart-motion.js +165 -0
  183. package/native/chart-motion.js.map +1 -0
  184. package/native/chart-panels-options.d.ts +77 -0
  185. package/native/chart-panels-options.d.ts.map +1 -0
  186. package/native/chart-panels-options.js +2 -0
  187. package/native/chart-panels-options.js.map +1 -0
  188. package/native/chart-panels-state.d.ts +34 -0
  189. package/native/chart-panels-state.d.ts.map +1 -0
  190. package/native/chart-panels-state.js +198 -0
  191. package/native/chart-panels-state.js.map +1 -0
  192. package/native/chart-panels.d.ts +43 -0
  193. package/native/chart-panels.d.ts.map +1 -0
  194. package/native/chart-panels.js +107 -0
  195. package/native/chart-panels.js.map +1 -0
  196. package/native/chart-presentation.d.ts +40 -0
  197. package/native/chart-presentation.d.ts.map +1 -0
  198. package/native/chart-presentation.js +16 -0
  199. package/native/chart-presentation.js.map +1 -0
  200. package/native/chart-type.d.ts +65 -0
  201. package/native/chart-type.d.ts.map +1 -0
  202. package/native/chart-type.js +66 -0
  203. package/native/chart-type.js.map +1 -0
  204. package/native/chart.d.ts +571 -0
  205. package/native/chart.d.ts.map +1 -0
  206. package/native/chart.js +1417 -0
  207. package/native/chart.js.map +1 -0
  208. package/native/circular-options.d.ts +17 -0
  209. package/native/circular-options.d.ts.map +1 -0
  210. package/native/circular-options.js +2 -0
  211. package/native/circular-options.js.map +1 -0
  212. package/native/comparison-data.d.ts +64 -0
  213. package/native/comparison-data.d.ts.map +1 -0
  214. package/native/comparison-data.js +2 -0
  215. package/native/comparison-data.js.map +1 -0
  216. package/native/comparison-format.d.ts +16 -0
  217. package/native/comparison-format.d.ts.map +1 -0
  218. package/native/comparison-format.js +26 -0
  219. package/native/comparison-format.js.map +1 -0
  220. package/native/composition-options.d.ts +18 -0
  221. package/native/composition-options.d.ts.map +1 -0
  222. package/native/composition-options.js +2 -0
  223. package/native/composition-options.js.map +1 -0
  224. package/native/contour-data.d.ts +48 -0
  225. package/native/contour-data.d.ts.map +1 -0
  226. package/native/contour-data.js +2 -0
  227. package/native/contour-data.js.map +1 -0
  228. package/native/contour-format.d.ts +3 -0
  229. package/native/contour-format.d.ts.map +1 -0
  230. package/native/contour-format.js +11 -0
  231. package/native/contour-format.js.map +1 -0
  232. package/native/control-accessibility.d.ts +7 -0
  233. package/native/control-accessibility.d.ts.map +1 -0
  234. package/native/control-accessibility.js +9 -0
  235. package/native/control-accessibility.js.map +1 -0
  236. package/native/data-chart.d.ts +179 -0
  237. package/native/data-chart.d.ts.map +1 -0
  238. package/native/data-chart.js +415 -0
  239. package/native/data-chart.js.map +1 -0
  240. package/native/data-identities.d.ts +10 -0
  241. package/native/data-identities.d.ts.map +1 -0
  242. package/native/data-identities.js +50 -0
  243. package/native/data-identities.js.map +1 -0
  244. package/native/data-options.d.ts +566 -0
  245. package/native/data-options.d.ts.map +1 -0
  246. package/native/data-options.js +2 -0
  247. package/native/data-options.js.map +1 -0
  248. package/native/data-planning.d.ts +84 -0
  249. package/native/data-planning.d.ts.map +1 -0
  250. package/native/data-planning.js +174 -0
  251. package/native/data-planning.js.map +1 -0
  252. package/native/dendrogram-data.d.ts +27 -0
  253. package/native/dendrogram-data.d.ts.map +1 -0
  254. package/native/dendrogram-data.js +2 -0
  255. package/native/dendrogram-data.js.map +1 -0
  256. package/native/dendrogram-labels.d.ts +13 -0
  257. package/native/dendrogram-labels.d.ts.map +1 -0
  258. package/native/dendrogram-labels.js +12 -0
  259. package/native/dendrogram-labels.js.map +1 -0
  260. package/native/drilldown-options.d.ts +62 -0
  261. package/native/drilldown-options.d.ts.map +1 -0
  262. package/native/drilldown-options.js +2 -0
  263. package/native/drilldown-options.js.map +1 -0
  264. package/native/drilldown-state.d.ts +18 -0
  265. package/native/drilldown-state.d.ts.map +1 -0
  266. package/native/drilldown-state.js +130 -0
  267. package/native/drilldown-state.js.map +1 -0
  268. package/native/gauge-entrance.d.ts +8 -0
  269. package/native/gauge-entrance.d.ts.map +1 -0
  270. package/native/gauge-entrance.js +42 -0
  271. package/native/gauge-entrance.js.map +1 -0
  272. package/native/haptics.d.ts +21 -0
  273. package/native/haptics.d.ts.map +1 -0
  274. package/native/haptics.js +66 -0
  275. package/native/haptics.js.map +1 -0
  276. package/native/heatmap-data.d.ts +56 -0
  277. package/native/heatmap-data.d.ts.map +1 -0
  278. package/native/heatmap-data.js +2 -0
  279. package/native/heatmap-data.js.map +1 -0
  280. package/native/index.d.ts +26 -0
  281. package/native/index.d.ts.map +1 -0
  282. package/native/index.js +11 -0
  283. package/native/index.js.map +1 -0
  284. package/native/input-bridge.d.ts +32 -0
  285. package/native/input-bridge.d.ts.map +1 -0
  286. package/native/input-bridge.js +3 -0
  287. package/native/input-bridge.js.map +1 -0
  288. package/native/input-lease.d.ts +23 -0
  289. package/native/input-lease.d.ts.map +1 -0
  290. package/native/input-lease.js +28 -0
  291. package/native/input-lease.js.map +1 -0
  292. package/native/label-contrast.d.ts +7 -0
  293. package/native/label-contrast.d.ts.map +1 -0
  294. package/native/label-contrast.js +33 -0
  295. package/native/label-contrast.js.map +1 -0
  296. package/native/label-halo.d.ts +9 -0
  297. package/native/label-halo.d.ts.map +1 -0
  298. package/native/label-halo.js +23 -0
  299. package/native/label-halo.js.map +1 -0
  300. package/native/label-ink.d.ts +3 -0
  301. package/native/label-ink.d.ts.map +1 -0
  302. package/native/label-ink.js +6 -0
  303. package/native/label-ink.js.map +1 -0
  304. package/native/legend.d.ts +21 -0
  305. package/native/legend.d.ts.map +1 -0
  306. package/native/legend.js +66 -0
  307. package/native/legend.js.map +1 -0
  308. package/native/log-axis-labels.d.ts +6 -0
  309. package/native/log-axis-labels.d.ts.map +1 -0
  310. package/native/log-axis-labels.js +16 -0
  311. package/native/log-axis-labels.js.map +1 -0
  312. package/native/log-options.d.ts +5 -0
  313. package/native/log-options.d.ts.map +1 -0
  314. package/native/log-options.js +6 -0
  315. package/native/log-options.js.map +1 -0
  316. package/native/number-format.d.ts +5 -0
  317. package/native/number-format.d.ts.map +1 -0
  318. package/native/number-format.js +24 -0
  319. package/native/number-format.js.map +1 -0
  320. package/native/observation-format.d.ts +8 -0
  321. package/native/observation-format.d.ts.map +1 -0
  322. package/native/observation-format.js +80 -0
  323. package/native/observation-format.js.map +1 -0
  324. package/native/options-validation.d.ts +8 -0
  325. package/native/options-validation.d.ts.map +1 -0
  326. package/native/options-validation.js +612 -0
  327. package/native/options-validation.js.map +1 -0
  328. package/native/panel-viewport-contract.d.ts +15 -0
  329. package/native/panel-viewport-contract.d.ts.map +1 -0
  330. package/native/panel-viewport-contract.js +86 -0
  331. package/native/panel-viewport-contract.js.map +1 -0
  332. package/native/panel-viewport-sync.d.ts +27 -0
  333. package/native/panel-viewport-sync.d.ts.map +1 -0
  334. package/native/panel-viewport-sync.js +96 -0
  335. package/native/panel-viewport-sync.js.map +1 -0
  336. package/native/parallel-data.d.ts +49 -0
  337. package/native/parallel-data.d.ts.map +1 -0
  338. package/native/parallel-data.js +2 -0
  339. package/native/parallel-data.js.map +1 -0
  340. package/native/parallel-labels.d.ts +20 -0
  341. package/native/parallel-labels.d.ts.map +1 -0
  342. package/native/parallel-labels.js +54 -0
  343. package/native/parallel-labels.js.map +1 -0
  344. package/native/pictorial-data.d.ts +78 -0
  345. package/native/pictorial-data.d.ts.map +1 -0
  346. package/native/pictorial-data.js +2 -0
  347. package/native/pictorial-data.js.map +1 -0
  348. package/native/pictorial-format.d.ts +8 -0
  349. package/native/pictorial-format.d.ts.map +1 -0
  350. package/native/pictorial-format.js +14 -0
  351. package/native/pictorial-format.js.map +1 -0
  352. package/native/pictorial-options.d.ts +2 -0
  353. package/native/pictorial-options.d.ts.map +1 -0
  354. package/native/pictorial-options.js +61 -0
  355. package/native/pictorial-options.js.map +1 -0
  356. package/native/pictorial-paint.d.ts +19 -0
  357. package/native/pictorial-paint.d.ts.map +1 -0
  358. package/native/pictorial-paint.js +31 -0
  359. package/native/pictorial-paint.js.map +1 -0
  360. package/native/plan.d.ts +45 -0
  361. package/native/plan.d.ts.map +1 -0
  362. package/native/plan.js +109 -0
  363. package/native/plan.js.map +1 -0
  364. package/native/profile-data.d.ts +82 -0
  365. package/native/profile-data.d.ts.map +1 -0
  366. package/native/profile-data.js +2 -0
  367. package/native/profile-data.js.map +1 -0
  368. package/native/profile-labels.d.ts +5 -0
  369. package/native/profile-labels.d.ts.map +1 -0
  370. package/native/profile-labels.js +19 -0
  371. package/native/profile-labels.js.map +1 -0
  372. package/native/radial-entrance.d.ts +24 -0
  373. package/native/radial-entrance.d.ts.map +1 -0
  374. package/native/radial-entrance.js +25 -0
  375. package/native/radial-entrance.js.map +1 -0
  376. package/native/radial-layer.d.ts +26 -0
  377. package/native/radial-layer.d.ts.map +1 -0
  378. package/native/radial-layer.js +76 -0
  379. package/native/radial-layer.js.map +1 -0
  380. package/native/reference-labels.d.ts +21 -0
  381. package/native/reference-labels.d.ts.map +1 -0
  382. package/native/reference-labels.js +36 -0
  383. package/native/reference-labels.js.map +1 -0
  384. package/native/reference-options.d.ts +23 -0
  385. package/native/reference-options.d.ts.map +1 -0
  386. package/native/reference-options.js +58 -0
  387. package/native/reference-options.js.map +1 -0
  388. package/native/relationship-data.d.ts +63 -0
  389. package/native/relationship-data.d.ts.map +1 -0
  390. package/native/relationship-data.js +2 -0
  391. package/native/relationship-data.js.map +1 -0
  392. package/native/relationship-format.d.ts +13 -0
  393. package/native/relationship-format.d.ts.map +1 -0
  394. package/native/relationship-format.js +26 -0
  395. package/native/relationship-format.js.map +1 -0
  396. package/native/selection-outlines.d.ts +12 -0
  397. package/native/selection-outlines.d.ts.map +1 -0
  398. package/native/selection-outlines.js +20 -0
  399. package/native/selection-outlines.js.map +1 -0
  400. package/native/temporal-format.d.ts +29 -0
  401. package/native/temporal-format.d.ts.map +1 -0
  402. package/native/temporal-format.js +41 -0
  403. package/native/temporal-format.js.map +1 -0
  404. package/native/text-style.d.ts +16 -0
  405. package/native/text-style.d.ts.map +1 -0
  406. package/native/text-style.js +14 -0
  407. package/native/text-style.js.map +1 -0
  408. package/native/tilemap-color-axis.d.ts +23 -0
  409. package/native/tilemap-color-axis.d.ts.map +1 -0
  410. package/native/tilemap-color-axis.js +77 -0
  411. package/native/tilemap-color-axis.js.map +1 -0
  412. package/native/tilemap-data.d.ts +71 -0
  413. package/native/tilemap-data.d.ts.map +1 -0
  414. package/native/tilemap-data.js +2 -0
  415. package/native/tilemap-data.js.map +1 -0
  416. package/native/tilemap-format.d.ts +3 -0
  417. package/native/tilemap-format.d.ts.map +1 -0
  418. package/native/tilemap-format.js +14 -0
  419. package/native/tilemap-format.js.map +1 -0
  420. package/native/tilemap-selection.d.ts +12 -0
  421. package/native/tilemap-selection.d.ts.map +1 -0
  422. package/native/tilemap-selection.js +8 -0
  423. package/native/tilemap-selection.js.map +1 -0
  424. package/native/time-axis-labels.d.ts +5 -0
  425. package/native/time-axis-labels.d.ts.map +1 -0
  426. package/native/time-axis-labels.js +38 -0
  427. package/native/time-axis-labels.js.map +1 -0
  428. package/native/tooltip-layout.d.ts +16 -0
  429. package/native/tooltip-layout.d.ts.map +1 -0
  430. package/native/tooltip-layout.js +33 -0
  431. package/native/tooltip-layout.js.map +1 -0
  432. package/native/tooltip-metrics.d.ts +4 -0
  433. package/native/tooltip-metrics.d.ts.map +1 -0
  434. package/native/tooltip-metrics.js +11 -0
  435. package/native/tooltip-metrics.js.map +1 -0
  436. package/native/tooltip-motion.d.ts +35 -0
  437. package/native/tooltip-motion.d.ts.map +1 -0
  438. package/native/tooltip-motion.js +36 -0
  439. package/native/tooltip-motion.js.map +1 -0
  440. package/native/tooltip-occupancy.d.ts +21 -0
  441. package/native/tooltip-occupancy.d.ts.map +1 -0
  442. package/native/tooltip-occupancy.js +67 -0
  443. package/native/tooltip-occupancy.js.map +1 -0
  444. package/native/tooltip.d.ts +144 -0
  445. package/native/tooltip.d.ts.map +1 -0
  446. package/native/tooltip.js +146 -0
  447. package/native/tooltip.js.map +1 -0
  448. package/native/uncertainty-data.d.ts +110 -0
  449. package/native/uncertainty-data.d.ts.map +1 -0
  450. package/native/uncertainty-data.js +2 -0
  451. package/native/uncertainty-data.js.map +1 -0
  452. package/native/uncertainty-format.d.ts +3 -0
  453. package/native/uncertainty-format.d.ts.map +1 -0
  454. package/native/uncertainty-format.js +10 -0
  455. package/native/uncertainty-format.js.map +1 -0
  456. package/native/value-labels.d.ts +30 -0
  457. package/native/value-labels.d.ts.map +1 -0
  458. package/native/value-labels.js +206 -0
  459. package/native/value-labels.js.map +1 -0
  460. package/native/variwide-labels.d.ts +14 -0
  461. package/native/variwide-labels.d.ts.map +1 -0
  462. package/native/variwide-labels.js +22 -0
  463. package/native/variwide-labels.js.map +1 -0
  464. package/native/venn-data.d.ts +29 -0
  465. package/native/venn-data.d.ts.map +1 -0
  466. package/native/venn-data.js +2 -0
  467. package/native/venn-data.js.map +1 -0
  468. package/native/viewport-gestures.d.ts +32 -0
  469. package/native/viewport-gestures.d.ts.map +1 -0
  470. package/native/viewport-gestures.js +43 -0
  471. package/native/viewport-gestures.js.map +1 -0
  472. package/native/viewport-motion.d.ts +67 -0
  473. package/native/viewport-motion.d.ts.map +1 -0
  474. package/native/viewport-motion.js +182 -0
  475. package/native/viewport-motion.js.map +1 -0
  476. package/native/viewport-state.d.ts +20 -0
  477. package/native/viewport-state.d.ts.map +1 -0
  478. package/native/viewport-state.js +14 -0
  479. package/native/viewport-state.js.map +1 -0
  480. package/native/waterfall-appearance.d.ts +8 -0
  481. package/native/waterfall-appearance.d.ts.map +1 -0
  482. package/native/waterfall-appearance.js +18 -0
  483. package/native/waterfall-appearance.js.map +1 -0
  484. package/native/wordcloud-data.d.ts +40 -0
  485. package/native/wordcloud-data.d.ts.map +1 -0
  486. package/native/wordcloud-data.js +2 -0
  487. package/native/wordcloud-data.js.map +1 -0
  488. package/native/wordcloud-layer.d.ts +29 -0
  489. package/native/wordcloud-layer.d.ts.map +1 -0
  490. package/native/wordcloud-layer.js +58 -0
  491. package/native/wordcloud-layer.js.map +1 -0
  492. package/native/wordcloud-measurements.d.ts +47 -0
  493. package/native/wordcloud-measurements.d.ts.map +1 -0
  494. package/native/wordcloud-measurements.js +137 -0
  495. package/native/wordcloud-measurements.js.map +1 -0
  496. package/native/wordcloud-planning.d.ts +23 -0
  497. package/native/wordcloud-planning.d.ts.map +1 -0
  498. package/native/wordcloud-planning.js +25 -0
  499. package/native/wordcloud-planning.js.map +1 -0
  500. package/native/wordcloud-probes.d.ts +48 -0
  501. package/native/wordcloud-probes.d.ts.map +1 -0
  502. package/native/wordcloud-probes.js +111 -0
  503. package/native/wordcloud-probes.js.map +1 -0
  504. package/native/wordcloud-text-backend.d.ts +16 -0
  505. package/native/wordcloud-text-backend.d.ts.map +1 -0
  506. package/native/wordcloud-text-backend.js +3 -0
  507. package/native/wordcloud-text-backend.js.map +1 -0
  508. package/package.json +58 -4
@@ -0,0 +1,533 @@
1
+ import { ownFan, ownFanValue, ownRegression, ownRegressionValue } from './uncertainty-scene.js';
2
+ import { ownStackGroups, ownMixedAxes, ownMixedRanges } from './composition-scene.js';
3
+ import { ownCircular, ownRadialSummary } from './circular-scene.js';
4
+ import { ownFlame, ownFlameValue, ownViolin, ownViolinValue } from './profile-scene.js';
5
+ import { ownDendrogram, ownDendrogramValue } from './dendrogram-scene.js';
6
+ import { ownParallel, ownParallelValue, parallelGridSvg } from './parallel-scene.js';
7
+ import { ownHeatmapScene, ownHeatmapPoint } from './heatmap-scene.js';
8
+ import { ownVennScene, ownVennPoint } from './venn-scene.js';
9
+ import { ownWordCloud, ownWordCloudGlyphs } from './wordcloud-scene.js';
10
+ import { ownTilemapScene, ownTilemapCells, ownTilemapPoint, tilemapCellsSvg } from './tilemap-scene.js';
11
+ import { ownContourSource, ownContourPoint, validateContourScene } from './contour-scene.js';
12
+ import { relationshipFamily, ownRelationshipPoint, validateRelationshipScene, relationshipAnnotations } from './relationship-scene.js';
13
+ import { ownTemporalObservation, ownTemporalSource } from './temporal-scene.js';
14
+ import { ownPictorialScene, ownPictorialPoint } from './pictorial-scene.js';
15
+ import { ownPictorialHit } from './pictorial-hit.js';
16
+ import { ownPolygon } from './polygon-hit.js';
17
+ import { ownPolarGrid, polarGridSvg } from './polar-grid.js';
18
+ import { ownComparisonScene, ownComparisonPoint } from './comparison-scene.js';
19
+ import { comparisonBackground, comparisonForeground, comparisonGrid } from './comparison-render.js';
20
+ import { identityKey } from './contracts.js';
21
+ import { validateNativePath } from './path-validation.js';
22
+ import { markerSvg, markerBatchSvg, resolveMarkerStyle } from './marker-style.js';
23
+ import { ownReferences, ownReferenceStyles, ownReferenceBands, ownReferenceBandStyles, ownPointAppearance, ownPrimitiveId, samePointAppearance, sameReferenceStyle, sameReferencePaint, sameReferenceBandStyle, sameReferenceBandPaint } from './scene-styles.js';
24
+ import { pointPaint, barPaintBatches, circlePaintBatches, referencePaint } from './scene-paint.js';
25
+ function ownTickValue({ value, type }) {
26
+ if (value !== undefined && !Number.isFinite(value) || type !== undefined && type !== 'number' && type !== 'time')
27
+ throw Error('Invalid axis tick value');
28
+ return { ...(value === undefined ? {} : { value }), ...(type === undefined ? {} : { type }) };
29
+ }
30
+ function ownSecondaryGrid(scene) {
31
+ if (scene.family !== 'pareto' && !(scene.family === 'mixed' && scene.mixedAxes) || !Array.isArray(scene.secondaryGrid) || scene.secondaryGrid.length > 32)
32
+ throw Error('Invalid secondary axis');
33
+ return scene.secondaryGrid.map(g => { if (!Number.isFinite(g.y) || g.y < 0 || g.y > scene.height || typeof g.label !== 'string' || g.label.length > 64)
34
+ throw Error('Invalid secondary tick'); return { y: g.y, label: g.label, ...ownTickValue(g) }; });
35
+ }
36
+ const color = /^#[\da-f]{6}$/i;
37
+ const path = /^[MLHVCSQTAZmlhvcsqtaz\d.,+\-\seE]*$/;
38
+ const owned = new WeakSet();
39
+ const revisions = new WeakMap();
40
+ const paintRevisions = new WeakMap();
41
+ /** Validate and own transport data once, never during each touch frame. */
42
+ export function ownScene(input) {
43
+ if (owned.has(input))
44
+ return input;
45
+ if (input.observations.length > 10000 || input.series.length > 16 || (input.legend?.length ?? 0) > 16 || input.grid.length > (input.family === 'xrange' ? 256 : 32) || input.labels.length > 64
46
+ || (input.annotations?.length ?? 0) > (['sankey', 'timeline'].includes(input.family) ? 128 : 64) || (input.yLabels?.length ?? 0) > (input.family === 'xrange' ? 256 : 64)
47
+ || input.series.reduce((n, s) => n + (s.circles?.length ?? 0) + (s.bars?.length ?? 0), 0) > 10000
48
+ || input.series.some(s => (s.circles?.length ?? 0) > 10000 || (s.bars?.length ?? 0) > 10000 || ((s.path?.length ?? 0) + (s.areaPath?.length ?? 0) + (s.nodePath?.length ?? 0)) > 1000000)) {
49
+ throw new Error('Unbounded native scene');
50
+ }
51
+ if (input.series.reduce((n, s) => n + (s.path?.length ?? 0) + (s.areaPath?.length ?? 0) + (s.nodePath?.length ?? 0), 0) > 2000000)
52
+ throw Error('Unsupported or unbounded native scene');
53
+ if (['vector', 'windbarb'].includes(input.family) && input.observations.length > 2048)
54
+ throw Error('Directional point budget exceeded');
55
+ if (input.family === 'treemap' && (input.observations.length > 512 || input.series.reduce((n, s) => n + (s.bars?.length ?? 0), 0) > 512))
56
+ throw Error('Unbounded native hierarchy');
57
+ if (['funnel', 'pyramid'].includes(input.family) && input.observations.length > 16)
58
+ throw Error('Stage input limit');
59
+ if (input.family === 'sunburst' && input.observations.length > 512 || ['treegraph', 'organization', 'networkgraph'].includes(input.family) && input.observations.length > 128)
60
+ throw Error('Hierarchy node budget exceeded');
61
+ if (input.family === 'sankey' && (input.observations.length > 640 || input.observations.filter(point => point.sankey?.type === 'node').length > 128 || input.observations.filter(point => point.sankey?.type === 'link').length > 512))
62
+ throw Error('Sankey observation budget exceeded');
63
+ if (input.family === 'item' && (input.observations.length > 16 || input.series.reduce((n, s) => n + (s.circles?.length ?? 0), 0) > 256 || input.series.some(s => !!s.path || !!s.areaPath || !!s.bars?.length)))
64
+ throw Error('Item unit budget or geometry invalid');
65
+ const bandDescriptor = Object.getOwnPropertyDescriptor(input, 'referenceBands');
66
+ if (bandDescriptor?.get || bandDescriptor?.set)
67
+ throw Error('Invalid reference band property');
68
+ const mixedRanges = input.mixedRanges ? ownMixedRanges(input.mixedRanges, input) : undefined;
69
+ const circular = input.circular ? ownCircular(input.circular, input) : undefined, radialSummary = input.radialSummary ? ownRadialSummary(input.radialSummary, input) : undefined;
70
+ const stackGroups = input.stackGroups ? ownStackGroups(input.stackGroups, input) : undefined, mixedAxes = input.mixedAxes ? ownMixedAxes(input.mixedAxes, input) : undefined;
71
+ if (input.observations.some(p => p.valueAxis !== undefined && !mixedAxes) || input.secondaryUnit !== undefined && (!mixedAxes || typeof input.secondaryUnit !== 'string' || input.secondaryUnit.length > 64))
72
+ throw Error('Invalid mixed-axis presentation');
73
+ const fan = input.family === 'fan' ? ownFan(input.fan, input) : undefined, regression = input.family === 'regression' ? ownRegression(input.regression, input) : undefined;
74
+ if (input.family !== 'fan' && (input.fan || input.observations.some(p => p.fan)) || input.family !== 'regression' && (input.regression || input.observations.some(p => p.regression)))
75
+ throw Error('Uncertainty roles require their own family');
76
+ const flame = input.family === 'flame' ? ownFlame(input.flame, input) : undefined;
77
+ const violin = input.family === 'violin' ? ownViolin(input.violin, input) : undefined;
78
+ if (input.family !== 'flame' && (input.flame || input.observations.some(p => p.flame)) || input.family !== 'violin' && (input.violin || input.observations.some(p => p.violin)))
79
+ throw Error('Profile/distribution roles require their declared family');
80
+ const dendrogram = input.family === 'dendrogram' ? ownDendrogram(input.dendrogram, input) : undefined;
81
+ if (input.family !== 'dendrogram' && (input.dendrogram || input.observations.some(p => p.dendrogram)))
82
+ throw Error('Dendrogram roles require their own family');
83
+ const parallel = input.family === 'parallel' ? ownParallel(input.parallel, input) : undefined;
84
+ if (input.family !== 'parallel' && (input.parallel || input.observations.some(p => p.parallel)))
85
+ throw Error('Parallel roles require the parallel family');
86
+ const points = ownPointAppearance(input.points), pointColors = new Map((points ?? []).map(point => [identityKey(point), point.color]));
87
+ if (points !== undefined && !['waterfall', 'line', 'area', 'streamgraph', 'areaspline', 'spline', 'mixed', 'scatter', 'column', 'bar', 'bubble'].includes(input.family))
88
+ throw Error('Point colors require a cartesian chart');
89
+ const scene = {
90
+ ...(fan ? { fan } : {}), ...(regression ? { regression } : {}), ...(flame ? { flame } : {}), ...(violin ? { violin } : {}), ...(dendrogram ? { dendrogram } : {}), ...(parallel ? { parallel } : {}), ...ownHeatmapScene(input), ...ownVennScene(input), ...ownWordCloud(input),
91
+ ...ownContourSource(input),
92
+ ...ownComparisonScene(input),
93
+ ...ownPictorialScene(input),
94
+ ...ownTilemapScene(input),
95
+ ...ownTemporalSource(input),
96
+ schema: input.schema, family: input.family, title: input.title, description: input.description,
97
+ unit: input.unit, width: input.width, height: input.height,
98
+ ...(input.clip ? { clip: { x: input.clip.x, y: input.clip.y, width: input.clip.width, height: input.clip.height } } : {}),
99
+ ...(input.distribution ? { distribution: { derived: input.distribution.derived, sampleCount: input.distribution.sampleCount, ...(input.distribution.mean === undefined ? {} : { mean: input.distribution.mean }), ...(input.distribution.sampleStandardDeviation === undefined ? {} : { sampleStandardDeviation: input.distribution.sampleStandardDeviation }) } } : {}),
100
+ ...(circular ? { circular } : {}), ...(radialSummary ? { radialSummary } : {}), ...(stackGroups ? { stackGroups } : {}), ...(mixedAxes ? { mixedAxes } : {}), ...(mixedRanges ? { mixedRanges } : {}), ...(input.secondaryUnit === undefined ? {} : { secondaryUnit: input.secondaryUnit }),
101
+ ...(input.secondaryGrid ? { secondaryGrid: ownSecondaryGrid(input) } : {}),
102
+ ...(input.polarGrid ? { polarGrid: ownPolarGrid(input) } : {}),
103
+ ...(input.legend ? { legend: input.legend.map(s => ({ id: s.id, name: s.name, color: s.color, visible: s.visible })) } : {}),
104
+ series: input.series.map(s => ({ id: s.id, name: s.name, color: s.color, ...ownWordCloudGlyphs(s), ...ownTilemapCells(s, input),
105
+ ...(s.path === undefined ? {} : { path: s.path }),
106
+ ...(s.areaPath === undefined ? {} : { areaPath: s.areaPath }),
107
+ ...(s.nodePath === undefined ? {} : { nodePath: s.nodePath }),
108
+ ...(s.fill === undefined ? {} : { fill: s.fill }),
109
+ ...(s.circles === undefined ? {} : { circles: s.circles.map(c => { const pointId = ownPrimitiveId(c); return { ...(pointId === undefined ? {} : { pointId }), cx: c.cx, cy: c.cy, radius: c.radius }; }) }),
110
+ ...(s.bars === undefined ? {} : { bars: s.bars.map(r => { const pointId = ownPrimitiveId(r); return { ...(pointId === undefined ? {} : { pointId }), x: r.x, y: r.y, width: r.width, height: r.height }; }) }) })),
111
+ observations: input.observations.map(p => ({ ...(p.valueAxis === undefined ? {} : { valueAxis: p.valueAxis }), id: { seriesId: p.id.seriesId, pointId: p.id.pointId },
112
+ ...(p.vector ? { vector: { dx: p.vector.dx, dy: p.vector.dy } } : {}), ...(p.wind ? { wind: { direction: p.wind.direction } } : {}), ...(p.yValue === undefined ? {} : { yValue: p.yValue }),
113
+ label: p.label, seriesName: p.seriesName, value: p.value, ...(p.fan ? { fan: ownFanValue(p.fan) } : {}), ...(p.regression ? { regression: ownRegressionValue(p.regression) } : {}), ...(p.flame ? { flame: ownFlameValue(p.flame) } : {}), ...(p.violin ? { violin: ownViolinValue(p.violin) } : {}), ...(p.dendrogram ? { dendrogram: ownDendrogramValue(p.dendrogram) } : {}), ...(p.parallel ? { parallel: ownParallelValue(p.parallel) } : {}), ...ownHeatmapPoint(p, input.family), ...ownVennPoint(p, input.family), ...ownContourPoint(p, input.family), ...ownComparisonPoint(p, input.family), ...ownPictorialPoint(p, input.family), ...ownTilemapPoint(p, input.family), ...ownRelationshipPoint(p, input.family), ...ownTemporalObservation(p, input.family), ...(p.sankey ? { sankey: p.sankey.type === 'node' ? { type: 'node', incoming: p.sankey.incoming, outgoing: p.sankey.outgoing, ...(p.sankey.geometryOmitted ? { geometryOmitted: true } : {}) } : { type: 'link', from: p.sankey.from, to: p.sankey.to, fromLabel: p.sankey.fromLabel, toLabel: p.sankey.toLabel, ...(p.sankey.geometryOmitted ? { geometryOmitted: true } : {}) } } : {}), ...(p.node ? { node: p.node.directed === false ? { incoming: p.node.incoming, outgoing: p.node.outgoing, directed: false } : { incoming: p.node.incoming, outgoing: p.node.outgoing, depth: p.node.depth, ...(p.node.directed ? { directed: true } : {}) } } : {}), ...(p.stem ? { stem: { x: p.stem.x, startY: p.stem.startY, endY: p.stem.endY } } : {}), ...(p.minimumValue === undefined ? {} : { minimumValue: p.minimumValue }), ...(p.q1Value === undefined ? {} : { q1Value: p.q1Value }), ...(p.medianValue === undefined ? {} : { medianValue: p.medianValue }), ...(p.q3Value === undefined ? {} : { q3Value: p.q3Value }), ...(p.maximumValue === undefined ? {} : { maximumValue: p.maximumValue }), ...(p.lowValue === undefined ? {} : { lowValue: p.lowValue }), ...(p.highValue === undefined ? {} : { highValue: p.highValue }), x: p.x, y: p.y, color: pointColors.get(identityKey(p.id)) ?? p.color,
114
+ ...(p.hit ? { hit: p.hit.type === 'compoundPolygon' ? ownPictorialHit(p.hit, input.width, input.height) : p.hit.type === 'polygon' ? ownPolygon(p.hit, input) : p.hit.type === 'sector' ? { type: p.hit.type, cx: p.hit.cx, cy: p.hit.cy, radius: p.hit.radius, innerRadius: p.hit.innerRadius, start: p.hit.start, end: p.hit.end } : { type: p.hit.type, cx: p.hit.cx, cy: p.hit.cy, radius: p.hit.radius } } : {}), ...(p.sizeValue === undefined ? {} : { sizeValue: p.sizeValue }), ...(p.xValue === undefined ? {} : { xValue: p.xValue }), ...(p.percentage === undefined ? {} : { percentage: p.percentage }), ...(p.valueUnit === undefined ? {} : { valueUnit: p.valueUnit }), ...(p.computedKind === undefined ? {} : { computedKind: p.computedKind }), ...(p.subtotal === undefined ? {} : { subtotal: p.subtotal }), ...(p.incomplete === undefined ? {} : { incomplete: p.incomplete }), ...(p.group ? { group: { key: p.group.key, label: p.group.label, coordinate: p.group.coordinate } } : {}) })),
115
+ grid: input.grid.map(g => ({ y: g.y, label: g.label, ...ownTickValue(g) })), labels: input.labels.map(l => ({ x: l.x, label: l.label, ...ownTickValue(l) })),
116
+ ...(input.annotations ? { annotations: relationshipAnnotations(input).map(a => ({ x: a.x, y: a.y, text: a.text, role: a.role, ...(a.box ? { box: { width: a.box.width, height: a.box.height, seriesId: a.box.seriesId } } : {}), ...(a.stackTotal ? { stackTotal: { value: a.stackTotal.value, sign: a.stackTotal.sign, ...(a.stackTotal.percentage ? { percentage: true } : {}) } } : {}) })) } : {}),
117
+ ...(input.yLabels ? { yLabels: input.yLabels.map(l => ({ id: l.id, y: l.y, label: l.label })) } : {}),
118
+ ...(input.references === undefined ? {} : { references: ownReferences(input.references, input) }),
119
+ ...(bandDescriptor?.value === undefined ? {} : { referenceBands: ownReferenceBands(bandDescriptor.value, input) }),
120
+ ...(points === undefined ? {} : { points }),
121
+ };
122
+ const finite = (...xs) => xs.every(Number.isFinite);
123
+ const text = (value, max) => typeof value === 'string' && value.length <= max;
124
+ if (scene.clip && (!['sankey', 'treegraph', 'organization', 'networkgraph', 'packedbubble'].includes(scene.family) || !finite(scene.clip.x, scene.clip.y, scene.clip.width, scene.clip.height) || scene.clip.x < 0 || scene.clip.y < 0 || scene.clip.width <= 0 || scene.clip.height <= 0 || scene.clip.x + scene.clip.width > scene.width || scene.clip.y + scene.clip.height > scene.height))
125
+ throw Error('Invalid plot clip');
126
+ const summary = scene.distribution;
127
+ if (summary && (!['histogram', 'bellcurve'].includes(scene.family) || summary.derived !== true || !Number.isInteger(summary.sampleCount) || summary.sampleCount < 0 || summary.sampleCount > 10000 || summary.mean !== undefined && !Number.isFinite(summary.mean) || summary.sampleStandardDeviation !== undefined && (!Number.isFinite(summary.sampleStandardDeviation) || summary.sampleStandardDeviation < 0)))
128
+ throw Error('Invalid distribution summary');
129
+ if (scene.schema !== 'nc-native-scene/0' || !['fan', 'regression', 'flame', 'violin', 'dendrogram', 'parallel', 'heatmap', 'venn', 'wordcloud', 'pictorial', 'tilemap', 'contour', 'dependencywheel', 'arcdiagram', 'chord', 'bullet', 'variwide', 'xrange', 'timeline', 'sankey', 'vector', 'windbarb', 'networkgraph', 'packedbubble', 'sunburst', 'treegraph', 'organization', 'variablepie', 'item', 'polygon', 'areaspline', 'lollipop', 'dumbbell', 'columnpyramid', 'boxplot', 'errorbar', 'arearange', 'areasplinerange', 'columnrange', 'histogram', 'bellcurve', 'funnel', 'pyramid', 'pareto', 'radar', 'polar', 'windrose', 'radialbar', 'treemap', 'waterfall', 'line', 'area', 'streamgraph', 'areaspline', 'spline', 'mixed', 'scatter', 'column', 'bar', 'pie', 'donut', 'gauge', 'bubble'].includes(scene.family)
130
+ || !finite(scene.width, scene.height) || scene.width <= 0 || scene.height <= 0
131
+ || scene.width > 10000 || scene.height > 10000 || scene.observations.length > 10000
132
+ || scene.series.length > 16 || scene.grid.length > (scene.family === 'xrange' ? 256 : 32) || scene.labels.length > 64
133
+ || !text(scene.title, scene.family === 'pictorial' ? 512 : scene.family === 'tilemap' ? 512 : 200) || !text(scene.description, scene.family === 'pictorial' ? 2048 : scene.family === 'tilemap' ? 2048 : 1000) || !text(scene.unit, 64)
134
+ || scene.series.reduce((n, s) => n + ((s.path?.length ?? 0) + (s.areaPath?.length ?? 0) + (s.nodePath?.length ?? 0)), 0) > 2000000) {
135
+ throw new Error('Unsupported or unbounded native scene');
136
+ }
137
+ validateRelationshipScene(scene);
138
+ validateContourScene(scene);
139
+ const ids = new Set();
140
+ const groups = new Map();
141
+ const groupCoordinates = new Map();
142
+ const groupSeries = new Map();
143
+ const legendIds = new Set();
144
+ for (const item of scene.legend ?? []) {
145
+ if (!item.id || !text(item.id, ['pictorial', 'tilemap', 'contour', 'xrange', 'timeline'].includes(scene.family) ? 256 : 128) || legendIds.has(item.id) || !text(item.name, ['venn', 'wordcloud', 'pictorial', 'tilemap', 'xrange', 'timeline', 'sankey', 'dependencywheel', 'arcdiagram', 'chord'].includes(scene.family) ? 256 : 200) || !color.test(item.color) || typeof item.visible !== 'boolean')
146
+ throw new Error('Invalid native legend');
147
+ legendIds.add(item.id);
148
+ }
149
+ const seriesIds = new Set();
150
+ const primitiveIds = new Set();
151
+ const secondEndpoints = new Set();
152
+ const itemCounts = scene.family === 'item' ? new Map() : null;
153
+ const legacyPointSeries = new Set();
154
+ const validCircle = (c) => { if (!finite(c.cx, c.cy, c.radius) || c.radius < 0)
155
+ return false; const clip = scene.clip; if (scene.family === 'packedbubble' && clip)
156
+ return c.radius <= 8 * Math.max(scene.width, scene.height) && Math.hypot(c.cx - Math.max(clip.x, Math.min(clip.x + clip.width, c.cx)), c.cy - Math.max(clip.y, Math.min(clip.y + clip.height, c.cy))) <= c.radius; return c.cx >= 0 && c.cx <= scene.width && c.cy >= 0 && c.cy <= scene.height && c.radius <= Math.max(scene.width, scene.height); };
157
+ if (scene.family === 'windbarb' && scene.unit !== 'm/s')
158
+ throw Error('Wind speed unit must be m/s');
159
+ if (scene.family === 'packedbubble' && (scene.observations.length > 256 || scene.series.reduce((n, s) => n + (s.circles?.length ?? 0), 0) > 256))
160
+ throw Error('Packed bubble point budget exceeded');
161
+ const primitiveId = (seriesId, pointId, type) => { if (pointId === undefined) {
162
+ if (itemCounts)
163
+ throw Error('Item units require source identity');
164
+ return;
165
+ } if (!text(pointId, ['pictorial', 'tilemap', 'contour', 'xrange', 'timeline'].includes(scene.family) ? 256 : 128) || !pointId)
166
+ throw Error('Invalid primitive point ID'); const key = identityKey({ seriesId, pointId }); if (itemCounts) {
167
+ if (type !== 'circle')
168
+ throw Error('Item units must be circles');
169
+ itemCounts.set(key, (itemCounts.get(key) ?? 0) + 1);
170
+ } if (primitiveIds.has(key) && !itemCounts) {
171
+ if (scene.family !== 'dumbbell' || type !== 'circle' || secondEndpoints.has(key))
172
+ throw Error('Duplicate primitive point ID');
173
+ secondEndpoints.add(key);
174
+ } primitiveIds.add(key); };
175
+ for (const s of scene.series) {
176
+ if (!s.id || !text(s.id, ['pictorial', 'tilemap', 'contour', 'xrange', 'timeline'].includes(scene.family) ? 256 : 128) || !text(s.name, ['venn', 'wordcloud', 'pictorial', 'tilemap', 'xrange', 'timeline', 'sankey', 'dependencywheel', 'arcdiagram', 'chord'].includes(scene.family) ? 256 : 200) || seriesIds.has(s.id) || !color.test(s.color)
177
+ || (s.path !== undefined && (s.path.length > 1000000 || !path.test(s.path)))) {
178
+ throw new Error('Invalid native series');
179
+ }
180
+ seriesIds.add(s.id);
181
+ if (s.fill !== undefined && typeof s.fill !== 'boolean')
182
+ throw new Error('Invalid fill');
183
+ for (const c of s.circles ?? []) {
184
+ if (c.pointId === undefined)
185
+ legacyPointSeries.add(s.id);
186
+ primitiveId(s.id, c.pointId, 'circle');
187
+ if (!validCircle(c))
188
+ throw new Error('Invalid circle');
189
+ }
190
+ if (s.path)
191
+ validateNativePath(s.path, scene.width, scene.height);
192
+ if (s.nodePath !== undefined) {
193
+ if (!relationshipFamily(scene.family) || typeof s.nodePath !== 'string' || s.nodePath.length > 1000000 || !path.test(s.nodePath))
194
+ throw Error('Invalid relationship node path');
195
+ validateNativePath(s.nodePath, scene.width, scene.height);
196
+ }
197
+ if (s.areaPath !== undefined) {
198
+ if (!['fan', 'violin', 'pictorial', 'dependencywheel', 'arcdiagram', 'chord', 'sankey', 'vector', 'windbarb', 'polygon', 'radar', 'area', 'streamgraph', 'areaspline', 'arearange', 'areasplinerange', 'mixed'].includes(scene.family) || typeof s.areaPath !== 'string' || s.areaPath.length > 1000000 || !path.test(s.areaPath))
199
+ throw Error('Invalid area path');
200
+ validateNativePath(s.areaPath, scene.width, scene.height);
201
+ }
202
+ if ((s.bars?.length ?? 0) > 10000)
203
+ throw new Error('Unbounded bars');
204
+ for (const r of s.bars ?? []) {
205
+ primitiveId(s.id, r.pointId, 'bar');
206
+ if (r.pointId === undefined)
207
+ legacyPointSeries.add(s.id);
208
+ if (!finite(r.x, r.y, r.width, r.height) || r.x < 0 || r.y < 0 || r.width < 0 || r.height < 0
209
+ || r.x + r.width > scene.width || r.y + r.height > scene.height)
210
+ throw new Error('Invalid bar');
211
+ }
212
+ }
213
+ for (const p of scene.observations) {
214
+ const key = identityKey(p.id);
215
+ if (!p.id.pointId || !text(p.id.pointId, scene.family === 'contour' ? 1024 : ['pictorial', 'tilemap', 'xrange', 'timeline'].includes(scene.family) ? 256 : 128) || !text(p.label, ['heatmap', 'venn'].includes(scene.family) ? 1024 : scene.family === 'wordcloud' ? 512 : scene.family === 'pictorial' ? 256 : scene.family === 'tilemap' ? 512 : relationshipFamily(scene.family) ? 515 : scene.family === 'sankey' ? 2051 : scene.family === 'timeline' ? 512 : ['bullet', 'variwide', 'xrange'].includes(scene.family) ? 256 : 200) || !text(p.seriesName, scene.family === 'venn' ? 1024 : ['venn', 'wordcloud', 'pictorial', 'tilemap', 'xrange', 'timeline', 'sankey', 'dependencywheel', 'arcdiagram', 'chord'].includes(scene.family) ? 256 : 200)
216
+ || !seriesIds.has(p.id.seriesId) || ids.has(key) || !color.test(p.color)
217
+ || !finite(p.value, p.x, p.y) || p.x < 0 || p.x > scene.width || p.y < 0 || p.y > scene.height) {
218
+ throw new Error('Invalid or duplicate native observation');
219
+ }
220
+ ids.add(key);
221
+ if (['treegraph', 'organization', 'networkgraph'].includes(scene.family) || p.node !== undefined) {
222
+ const node = p.node;
223
+ if (!node || !['treegraph', 'organization', 'networkgraph'].includes(scene.family) || ![node.incoming, node.outgoing].every(Number.isInteger) || node.incoming < 0 || node.outgoing < 0 || node.incoming > 512 || node.outgoing > 512 || (scene.family === 'networkgraph' ? (node.directed !== false || node.depth !== undefined) : (node.directed === false || !Number.isInteger(node.depth) || node.depth < 0 || node.depth > 127)) || p.value !== node.incoming + node.outgoing)
224
+ throw Error('Invalid computed node metrics');
225
+ }
226
+ if (itemCounts && (!Number.isSafeInteger(p.value) || p.value < 0 || p.value > 256 || (itemCounts.get(key) ?? 0) !== p.value))
227
+ throw Error('Item count does not match exact units');
228
+ if (p.stem && (!['lollipop', 'dumbbell'].includes(scene.family) || !finite(p.stem.x, p.stem.startY, p.stem.endY) || p.stem.x < 0 || p.stem.x > scene.width || p.stem.startY < 0 || p.stem.startY > scene.height || p.stem.endY < 0 || p.stem.endY > scene.height))
229
+ throw Error('Invalid stem geometry');
230
+ if (scene.family === 'boxplot' || p.minimumValue !== undefined || p.q1Value !== undefined || p.medianValue !== undefined || p.q3Value !== undefined || p.maximumValue !== undefined) {
231
+ const five = [p.minimumValue, p.q1Value, p.medianValue, p.q3Value, p.maximumValue];
232
+ if (scene.family !== 'boxplot' || five.some(v => !Number.isFinite(v)) || five.some((v, i) => i > 0 && v < five[i - 1]) || p.lowValue !== p.minimumValue || p.highValue !== p.maximumValue || p.value !== p.medianValue)
233
+ throw Error('Invalid five-number semantics');
234
+ }
235
+ if ((p.lowValue !== undefined || p.highValue !== undefined) && (!(scene.mixedRanges && scene.family === 'mixed') && !['fan', 'dumbbell', 'boxplot', 'errorbar', 'arearange', 'areasplinerange', 'columnrange', 'histogram'].includes(scene.family) || !Number.isFinite(p.lowValue) || !Number.isFinite(p.highValue) || p.lowValue > p.highValue))
236
+ throw Error('Invalid interval semantics');
237
+ if (p.subtotal !== undefined && (!['treemap', 'sunburst'].includes(scene.family) || typeof p.subtotal !== 'boolean'))
238
+ throw Error('Invalid hierarchy semantics');
239
+ if (p.incomplete !== undefined && (!['windrose', 'pictorial', 'dependencywheel', 'arcdiagram', 'chord', 'sankey', 'treemap', 'sunburst'].includes(scene.family) || typeof p.incomplete !== 'boolean' || scene.family === 'sankey' && p.sankey?.type !== 'node'))
240
+ throw Error('Invalid incomplete semantics');
241
+ if (p.valueUnit !== undefined && (scene.family !== 'pareto' || p.valueUnit !== '%'))
242
+ throw Error('Invalid value unit');
243
+ if (p.computedKind !== undefined && (scene.family !== 'waterfall' || !['subtotal', 'total'].includes(p.computedKind)))
244
+ throw Error('Invalid computed flow value');
245
+ if (p.sizeValue !== undefined && (!Number.isFinite(p.sizeValue) || p.sizeValue < 0))
246
+ throw new Error('Invalid size');
247
+ if (scene.family === 'sankey' || p.sankey !== undefined) {
248
+ const flow = p.sankey;
249
+ if (scene.family !== 'sankey' || !flow || flow.geometryOmitted !== undefined && flow.geometryOmitted !== true || flow.geometryOmitted === true && p.hit !== undefined)
250
+ throw Error('Invalid Sankey semantics');
251
+ if (flow.type === 'node') {
252
+ if (!finite(flow.incoming, flow.outgoing) || flow.incoming < 0 || flow.outgoing < 0 || p.value !== Math.max(flow.incoming, flow.outgoing))
253
+ throw Error('Invalid Sankey throughput');
254
+ }
255
+ else if (flow.type !== 'link' || !text(flow.from, 128) || !text(flow.to, 128) || flow.from === flow.to || !text(flow.fromLabel, 1024) || !text(flow.toLabel, 1024) || p.value <= 0)
256
+ throw Error('Invalid Sankey link');
257
+ }
258
+ if (p.vector !== undefined && (scene.family !== 'vector' || !finite(p.vector.dx, p.vector.dy) || p.yValue === undefined || !Number.isFinite(p.yValue) || Math.hypot(p.vector.dx, p.vector.dy) !== p.value))
259
+ throw Error('Invalid vector semantics');
260
+ if (scene.family === 'vector' && !p.vector || p.yValue !== undefined && scene.family !== 'vector')
261
+ throw Error('Missing vector metadata');
262
+ if (p.wind !== undefined && (scene.family !== 'windbarb' || p.value < 0 || p.value > 150 || p.wind.direction !== null && (!finite(p.wind.direction) || p.wind.direction < 0 || p.wind.direction >= 360)))
263
+ throw Error('Invalid wind semantics');
264
+ if (scene.family === 'windbarb' && !p.wind)
265
+ throw Error('Missing wind metadata');
266
+ if (p.xValue !== undefined && !Number.isFinite(p.xValue))
267
+ throw new Error('Invalid x value');
268
+ if (p.percentage !== undefined && (!Number.isFinite(p.percentage) || p.percentage < 0 || p.percentage > 100))
269
+ throw new Error('Invalid percentage');
270
+ if (p.group && (!['fan', 'parallel', 'bullet', 'variwide', 'histogram', 'bellcurve', 'lollipop', 'dumbbell', 'columnpyramid', 'boxplot', 'errorbar', 'arearange', 'areasplinerange', 'columnrange', 'pareto', 'line', 'area', 'streamgraph', 'areaspline', 'spline', 'mixed', 'column', 'bar'].includes(scene.family) || !text(p.group.key, 256) || !p.group.key || !text(p.group.label, ['bullet', 'variwide'].includes(scene.family) ? 256 : 200) || !finite(p.group.coordinate) || p.group.coordinate < 0 || p.group.coordinate > ((scene.family === 'bar' || scene.family === 'bullet' && scene.bulletOrientation === 'horizontal') ? scene.height : scene.width)))
271
+ throw new Error('Invalid observation group');
272
+ if (p.group) {
273
+ const coordinateKey = groupCoordinates.get(p.group.coordinate);
274
+ if (coordinateKey !== undefined && coordinateKey !== p.group.key)
275
+ throw new Error('Ambiguous observation group coordinate');
276
+ groupCoordinates.set(p.group.coordinate, p.group.key);
277
+ const previous = groups.get(p.group.key);
278
+ if (previous && (previous.coordinate !== p.group.coordinate || previous.label !== p.group.label))
279
+ throw new Error('Inconsistent observation group');
280
+ groups.set(p.group.key, p.group);
281
+ const members = groupSeries.get(p.group.key) ?? new Set();
282
+ if (members.has(p.id.seriesId))
283
+ throw new Error('Duplicate series in observation group');
284
+ members.add(p.id.seriesId);
285
+ groupSeries.set(p.group.key, members);
286
+ }
287
+ const h = p.hit;
288
+ if (h && h.type !== 'polygon' && h.type !== 'compoundPolygon') {
289
+ if (!['circle', 'sector'].includes(h.type) || !validCircle(h))
290
+ throw new Error('Invalid hit region');
291
+ if (h.type === 'sector' && (!finite(h.innerRadius, h.start, h.end) || h.innerRadius < 0 || h.innerRadius > h.radius || h.end < h.start || h.end - h.start > Math.PI * 2 + 1e-10))
292
+ throw new Error('Invalid sector');
293
+ if (h.type === 'circle' && h.radius > 256 && scene.family !== 'packedbubble')
294
+ throw new Error('Unbounded circle hit region');
295
+ }
296
+ }
297
+ for (const key of primitiveIds)
298
+ if (!ids.has(key))
299
+ throw Error('Primitive point ID has no observation');
300
+ for (const point of points ?? []) {
301
+ if (!ids.has(identityKey(point)))
302
+ throw Error('Unknown point color identity');
303
+ if (legacyPointSeries.has(point.seriesId))
304
+ throw Error('Explicit primitive pointId is required for point colors');
305
+ }
306
+ if (['variablepie', 'pie', 'donut', 'gauge'].includes(scene.family)) {
307
+ const sectors = scene.observations.flatMap(p => p.hit?.type === 'sector' ? [p.hit] : []);
308
+ const frame = sectors[0];
309
+ if (frame && sectors.some(h => h.cx !== frame.cx || h.cy !== frame.cy || (scene.family !== 'variablepie' && h.radius !== frame.radius) || h.innerRadius !== frame.innerRadius))
310
+ throw new Error('Invalid shared radial frame');
311
+ const ordered = [...sectors].sort((a, b) => a.start - b.start);
312
+ if (ordered.some((h, i) => i > 0 && h.start < ordered[i - 1].end - 1e-10))
313
+ throw new Error('Overlapping sectors');
314
+ if (ordered.length && ordered.at(-1).end - ordered[0].start > Math.PI * 2 + 1e-10)
315
+ throw new Error('Invalid radial turn');
316
+ }
317
+ for (const a of scene.annotations ?? [])
318
+ if (a.stackTotal && (!['column', 'bar', 'area', 'areaspline'].includes(scene.family) || !Number.isFinite(a.stackTotal.value) || !['positive', 'negative'].includes(a.stackTotal.sign) || a.stackTotal.percentage !== undefined && a.stackTotal.percentage !== true))
319
+ throw Error('Invalid stack total');
320
+ for (const a of scene.annotations ?? [])
321
+ if (a.box && (!['flame', 'dendrogram', 'heatmap', 'venn', 'contour', 'dependencywheel', 'arcdiagram', 'chord', 'timeline', 'sankey', 'sunburst', 'treemap', 'treegraph', 'organization', 'networkgraph', 'packedbubble'].includes(scene.family) || !finite(a.box.width, a.box.height) || a.box.width <= 0 || a.box.height <= 0 || a.x - a.box.width / 2 < 0 || a.x + a.box.width / 2 > scene.width || a.y - a.box.height / 2 < 0 || a.y + a.box.height / 2 > scene.height || !seriesIds.has(a.box.seriesId)))
322
+ throw Error('Invalid annotation box');
323
+ for (const g of scene.grid)
324
+ if (!finite(g.y) || g.y < 0 || g.y > scene.height || !text(g.label, 128))
325
+ throw new Error('Invalid grid');
326
+ for (const l of scene.labels)
327
+ if (!finite(l.x) || l.x < 0 || l.x > scene.width || !text(l.label, scene.family === 'heatmap' ? 512 : ['pictorial', 'bullet', 'variwide'].includes(scene.family) ? 256 : 128))
328
+ throw new Error('Invalid label');
329
+ for (const a of scene.annotations ?? [])
330
+ if (!finite(a.x, a.y) || a.x < 0 || a.x > scene.width || a.y < 0 || a.y > scene.height || !text(a.text, 200) || !['value', 'label'].includes(a.role))
331
+ throw new Error('Invalid annotation');
332
+ const labelIds = new Set();
333
+ for (const l of scene.yLabels ?? []) {
334
+ if (!text(l.id, ['bullet', 'variwide', 'xrange', 'timeline'].includes(scene.family) ? 256 : 128) || !l.id || labelIds.has(l.id) || !finite(l.y) || l.y < 0 || l.y > scene.height || !text(l.label, scene.family === 'heatmap' ? 512 : ['bullet', 'variwide', 'xrange'].includes(scene.family) ? 256 : 128))
335
+ throw new Error('Invalid category label');
336
+ labelIds.add(l.id);
337
+ }
338
+ // Deep freeze only owned data. Consumer objects and arrays remain untouched.
339
+ const freeze = (value) => {
340
+ for (const child of Object.values(value))
341
+ if (child && typeof child === 'object')
342
+ freeze(child);
343
+ Object.freeze(value);
344
+ };
345
+ freeze(scene);
346
+ owned.add(scene);
347
+ revisions.set(scene, { interaction: {}, legacyPointSeries });
348
+ paintRevisions.set(scene, {});
349
+ return scene;
350
+ }
351
+ /** Internal revision tokens survive safe presentation updates, never untrusted input objects. */
352
+ export function sceneInteractionKey(scene) { return revisions.get(ownScene(scene)).interaction; }
353
+ /** Text-only revisions do not invalidate rendered geometry; colour changes still do. */
354
+ export function sameScenePaint(a, b) {
355
+ return sceneInteractionKey(a) === sceneInteractionKey(b) && paintRevisions.get(a) === paintRevisions.get(b);
356
+ }
357
+ export function sceneMotionSignature(scene) {
358
+ scene = ownScene(scene);
359
+ const revision = revisions.get(scene);
360
+ return revision.motion ??= JSON.stringify({ series: scene.series.map(({ path, areaPath, nodePath, bars, circles, fill, cells, textGlyphs }) => ({ path, areaPath, nodePath, bars, circles, fill, cells, textGlyphs })), bulletBands: scene.bulletBands, bulletTargets: scene.bulletTargets });
361
+ }
362
+ /** Update bounded presentation without planning, copying geometry or rebuilding hit indices. */
363
+ export function updateScenePresentation(input, patch) {
364
+ const scene = ownScene(input), validText = (v, max) => typeof v === 'string' && v.length <= max;
365
+ if ((patch.title !== undefined && !validText(patch.title, 200)) || (patch.description !== undefined && !validText(patch.description, 1000)) || (patch.unit !== undefined && !validText(patch.unit, 64)) || (patch.secondaryUnit !== undefined && (!scene.mixedAxes || !validText(patch.secondaryUnit, 64))) || (patch.series?.length ?? 0) > 16)
366
+ throw new Error('Invalid scene presentation');
367
+ const changes = new Map();
368
+ // Structural connectors are a stable paint role, even when filtering leaves no
369
+ // visible edges. They never become an independent legend or hidden-series ID.
370
+ const structuralLinks = ['treegraph', 'organization', 'networkgraph'].includes(scene.family);
371
+ for (const item of patch.series ?? []) {
372
+ const knownId = scene.series.some(series => series.id === item.id) || scene.legend?.some(series => series.id === item.id) || scene.regression?.models.some(m => m.fitSeriesId === item.id) || (structuralLinks && item.id === 'links');
373
+ if (changes.has(item.id) || !knownId || (item.name !== undefined && !validText(item.name, ['venn', 'pictorial'].includes(scene.family) ? 256 : 200)) || (item.color !== undefined && !color.test(item.color)))
374
+ throw new Error('Invalid series presentation');
375
+ changes.set(item.id, item);
376
+ }
377
+ const title = patch.title ?? scene.title, description = patch.description ?? scene.description, unit = patch.unit ?? scene.unit, secondaryUnit = patch.secondaryUnit ?? scene.secondaryUnit;
378
+ const radial = ['sunburst', 'variablepie', 'item', 'funnel', 'pyramid', 'polar', 'windrose', 'radialbar', 'pie', 'donut', 'gauge'].includes(scene.family);
379
+ if (patch.points !== undefined && (radial || scene.family === 'tilemap' || scene.family === 'heatmap'))
380
+ throw Error('Point colors require a cartesian chart');
381
+ const points = patch.points === undefined ? scene.points : ownPointAppearance(patch.points), pointsChanged = !samePointAppearance(points, scene.points);
382
+ if (points?.length) {
383
+ const revision = revisions.get(scene), ids = revision.pointIds ??= new Set(scene.observations.map(point => identityKey(point.id)));
384
+ for (const point of points) {
385
+ if (!ids.has(identityKey(point)))
386
+ throw Error('Unknown point color identity');
387
+ if (revision.legacyPointSeries?.has(point.seriesId))
388
+ throw Error('Explicit primitive pointId is required for point colors');
389
+ }
390
+ }
391
+ const referenceStyles = patch.referenceStyles === undefined ? undefined : ownReferenceStyles(patch.referenceStyles);
392
+ if (referenceStyles?.some(style => !scene.references?.some(reference => reference.id === style.id)))
393
+ throw Error('Unknown reference style ID');
394
+ const references = referenceStyles === undefined ? scene.references : scene.references?.map(reference => {
395
+ const style = referenceStyles.find(style => style.id === reference.id) ?? { id: reference.id };
396
+ const role = reference.valueAxis === undefined ? {} : { valueAxis: reference.valueAxis };
397
+ const next = reference.status === 'visible' ? { ...style, ...role, axis: reference.axis, status: 'visible', line: reference.line } : { ...style, ...role, axis: reference.axis, status: reference.status };
398
+ return sameReferenceStyle(reference, next) ? reference : Object.freeze(next);
399
+ });
400
+ const referencesChanged = references?.some((reference, index) => reference !== scene.references?.[index]) ?? false;
401
+ const bandStyles = patch.referenceBandStyles === undefined ? undefined : ownReferenceBandStyles(patch.referenceBandStyles);
402
+ if (bandStyles?.some(style => !scene.referenceBands?.some(band => band.id === style.id)))
403
+ throw Error('Unknown reference band style ID');
404
+ const referenceBands = bandStyles === undefined ? scene.referenceBands : scene.referenceBands?.map(band => {
405
+ const { label: _label, color: _color, opacity: _opacity, ...geometry } = band, style = bandStyles.find(style => style.id === band.id) ?? { id: band.id }, next = { ...geometry, ...style };
406
+ return sameReferenceBandStyle(band, next) ? band : Object.freeze(next);
407
+ });
408
+ const bandsChanged = referenceBands?.some((band, index) => band !== scene.referenceBands?.[index]) ?? false;
409
+ let changed = title !== scene.title || description !== scene.description || unit !== scene.unit || secondaryUnit !== scene.secondaryUnit || pointsChanged || referencesChanged || bandsChanged;
410
+ const series = scene.series.map(s => { const p = changes.get(s.id), name = p?.name ?? ((scene.family === 'flame' || scene.family === 'dendrogram' || scene.family === 'gauge') && s.name === scene.title ? title : s.name), nextColor = p?.color ?? s.color; if (name === s.name && nextColor === s.color)
411
+ return s; changed = true; return Object.freeze({ ...s, name, color: nextColor }); });
412
+ const legend = scene.legend?.map(s => { const p = changes.get(s.id), name = p?.name ?? s.name, nextColor = p?.color ?? s.color; if (name === s.name && nextColor === s.color)
413
+ return s; changed = true; return Object.freeze({ ...s, name, color: nextColor }); });
414
+ if (!changed)
415
+ return scene;
416
+ const byId = new Map(series.map(s => [s.id, s]));
417
+ const pointColors = new Map((points ?? []).map(point => [identityKey(point), point.color]));
418
+ const observations = !pointsChanged && ![...changes.values()].some(change => change.name !== undefined) && series.every((s, i) => s === scene.series[i]) && (!radial && scene.family !== 'flame' && scene.family !== 'dendrogram' || title === scene.title) ? scene.observations : scene.observations.map(p => { const s = byId.get(p.id.seriesId), label = p.venn ? p.venn.sets.map(id => legend?.find(set => set.id === id)?.name ?? id).join(' ∩ ') : scene.family === 'gauge' && p.label === scene.title ? title : p.label, seriesName = p.venn ? label : changes.get(p.id.seriesId)?.name ?? ((radial || scene.family === 'flame' || scene.family === 'dendrogram') && p.seriesName === scene.title ? title : p.seriesName), color = scene.family === 'tilemap' || scene.family === 'heatmap' ? p.color : pointColors.get(identityKey(p.id)) ?? s.color; return label === p.label && seriesName === p.seriesName && color === p.color ? p : Object.freeze({ ...p, label, seriesName, color }); });
419
+ const paintChanged = pointsChanged || series.some((item, index) => item.color !== scene.series[index].color) || !!references?.some((item, index) => !sameReferencePaint(item, scene.references[index])) || !!referenceBands?.some((item, index) => !sameReferenceBandPaint(item, scene.referenceBands[index]));
420
+ const result = Object.freeze({ ...scene, title, description, unit, ...(secondaryUnit === undefined ? {} : { secondaryUnit }), series: Object.freeze(series), observations: Object.freeze(observations), ...(legend ? { legend: Object.freeze(legend) } : {}), ...(points === undefined ? {} : { points: Object.freeze(points.map(point => Object.freeze(point))) }), ...(references === undefined ? {} : { references: Object.freeze(references) }), ...(referenceBands === undefined ? {} : { referenceBands: Object.freeze(referenceBands) }) });
421
+ const revision = revisions.get(scene);
422
+ let paintKey = paintRevisions.get(scene);
423
+ if (paintChanged) {
424
+ // One bounded latest presentation, not a history of user color edits.
425
+ // Reapplying metadata over the Core base must not repaint text-only changes.
426
+ const signature = JSON.stringify([series.map(s => [s.id, s.color]), points, references?.map(r => [r.id, r.color, r.width, r.dash]), referenceBands?.map(b => [b.id, b.color, b.opacity])]);
427
+ paintKey = revision.lastPaint?.signature === signature ? revision.lastPaint.key : {};
428
+ revision.lastPaint = { signature, key: paintKey };
429
+ }
430
+ owned.add(result);
431
+ revisions.set(result, revision);
432
+ paintRevisions.set(result, paintKey);
433
+ return result;
434
+ }
435
+ /** Geometry only: text is always a native Text view, never an SVG/DOM text surrogate. */
436
+ export function sceneTransform(scene, viewport = { width: scene.width, height: scene.height }) {
437
+ if (scene.circular) {
438
+ const b = scene.circular.bounds, scale = Math.min(viewport.width / b.width, viewport.height / b.height);
439
+ return { sx: scale, sy: scale, x: (viewport.width - b.width * scale) / 2 - b.x * scale, y: (viewport.height - b.height * scale) / 2 - b.y * scale };
440
+ }
441
+ if (scene.family === 'bubble' || scene.family === 'scatter') {
442
+ // Reserve the selected circle ring (three logical units on either side) and
443
+ // one physical pixel of antialiasing. Do not fit individual observations:
444
+ // zoomed data outside the frame must stay outside it.
445
+ const scale = Math.min(Math.max(1, viewport.width - 2) / (scene.width + 6), Math.max(1, viewport.height - 2) / (scene.height + 6));
446
+ return { sx: scale, sy: scale, x: (viewport.width - scene.width * scale) / 2, y: (viewport.height - scene.height * scale) / 2 };
447
+ }
448
+ if ((scene.family === 'fan' || scene.family === 'line' || scene.family === 'area' || scene.family === 'areaspline' || scene.family === 'arearange' || scene.family === 'areasplinerange' || scene.family === 'bellcurve' || scene.family === 'spline' || scene.family === 'mixed')) {
449
+ // Markers are physical-size symbols: reserve their maximum radius + border
450
+ // once for the whole frame, including axes and inverse hit coordinates.
451
+ // Presentation changes therefore never move points or recalculate data.
452
+ const x = Math.min(9, viewport.width / 4), y = Math.min(9, viewport.height / 4);
453
+ return { sx: (viewport.width - 2 * x) / scene.width, sy: (viewport.height - 2 * y) / scene.height, x, y };
454
+ }
455
+ if (scene.family === 'pie' || scene.family === 'donut' || scene.family === 'gauge') {
456
+ const region = scene.observations.find(point => point.hit?.type === 'sector' && point.hit.radius > 0)?.hit;
457
+ if (region?.type === 'sector') {
458
+ // The Core can reserve outer-label space that this native renderer does
459
+ // not paint. Fit the actual circle, with an 8% inset on each side.
460
+ const scale = Math.min(viewport.width, viewport.height) * .42 / region.radius;
461
+ return { sx: scale, sy: scale, x: viewport.width / 2 - region.cx * scale, y: viewport.height / 2 - region.cy * scale };
462
+ }
463
+ }
464
+ const uniform = scene.parallel?.coordinates === 'polar' || ['venn', 'wordcloud', 'pictorial', 'tilemap', 'packedbubble', 'networkgraph', 'treegraph', 'arcdiagram', 'dependencywheel', 'chord', 'vector', 'windbarb', 'sunburst', 'variablepie', 'item', 'radar', 'polar', 'windrose', 'radialbar', 'pie', 'donut', 'gauge', 'bubble', 'scatter'].includes(scene.family);
465
+ const scale = Math.min(viewport.width / scene.width, viewport.height / scene.height);
466
+ const sx = uniform ? scale : viewport.width / scene.width, sy = uniform ? scale : viewport.height / scene.height;
467
+ return { sx, sy, x: (viewport.width - scene.width * sx) / 2, y: (viewport.height - scene.height * sy) / 2 };
468
+ }
469
+ export function sceneSvg(scene, gridColor, viewport, showGrid = true, options = {}) {
470
+ scene = ownScene(scene);
471
+ if (!color.test(gridColor))
472
+ throw new Error('Invalid grid color');
473
+ if (options.surfaceColor !== undefined && !color.test(options.surfaceColor))
474
+ throw Error('Invalid surface color');
475
+ const width = viewport?.width ?? scene.width, height = viewport?.height ?? scene.height;
476
+ if (![width, height].every(Number.isFinite) || width <= 0 || height <= 0)
477
+ throw new Error('Invalid SVG viewport');
478
+ const transform = sceneTransform(scene, { width, height });
479
+ const offset = transform.x || transform.y ? `translate(${transform.x} ${transform.y}) ` : '';
480
+ // Prepare only the requested layer. In particular, every series redraw used
481
+ // to build backgrounds, grid and target strings which were then discarded.
482
+ const baseLayer = options.layer !== 'series';
483
+ const decorations = options.layer === 'grid' || options.layer === 'series' ? '' : comparisonForeground(scene, options.surfaceColor ?? '#FFFFFF', 2.5 / Math.sqrt(transform.sx * transform.sy));
484
+ if (options.layer === 'references')
485
+ return `<svg viewBox="0 0 ${width} ${height}">${referencePaint(scene.references, transform)}${decorations ? `<g transform="${offset}scale(${transform.sx} ${transform.sy})">${decorations}</g>` : ''}</svg>`;
486
+ const background = baseLayer ? comparisonBackground(scene, options.surfaceColor) + (scene.pictorial?.backgroundPath ? `<path d="${scene.pictorial.backgroundPath}" fill="${gridColor}" fill-opacity="0.42"/>` : '') : '';
487
+ let bandBackground = '';
488
+ if (baseLayer && scene.referenceBands?.length) {
489
+ const surface = options.surfaceColor ?? '#FFFFFF', surfaceLightness = parseInt(surface.slice(1, 3), 16) + parseInt(surface.slice(3, 5), 16) + parseInt(surface.slice(5, 7), 16), bandColor = surfaceLightness < 384 ? '#84B5FF' : '#2C6DCD';
490
+ bandBackground = scene.referenceBands.flatMap(band => band.status === 'visible' ? [`<rect x="${band.box.x}" y="${band.box.y}" width="${band.box.width}" height="${band.box.height}" fill="${band.color ?? bandColor}" fill-opacity="${band.opacity ?? .12}"/>`] : []).join('');
491
+ }
492
+ const grid = baseLayer && showGrid ? (scene.parallel ? (options.parallelAxes === false ? '' : parallelGridSvg(scene.parallel, gridColor, options.parallelTicks !== false)) : scene.family === 'bullet' ? comparisonGrid(scene, gridColor) : scene.polarGrid ? polarGridSvg(scene.polarGrid, gridColor) : (scene.family === 'bar' || scene.dendrogram?.orientation === 'horizontal' ? scene.labels.map(l => `<path d="M${l.x} 0V${scene.height}" stroke="${gridColor}" stroke-width="1.5"/>`) : scene.grid.map(g => `<path d="M0 ${g.y}H${scene.width}" stroke="${gridColor}" stroke-width="1.5"/>`)).join('')) : '';
493
+ if (options.layer === 'grid')
494
+ return `<svg viewBox="0 0 ${width} ${height}"><g transform="${offset}scale(${transform.sx} ${transform.sy})">${background}${bandBackground}${grid}</g></svg>`;
495
+ const strokeWidth = Math.max(1, Math.min(8, Number.isFinite(options.strokeWidth) ? options.strokeWidth : 2)) / Math.sqrt(transform.sx * transform.sy);
496
+ const markerSize = Math.max(2, Math.min(12, Number.isFinite(options.markerSize) ? options.markerSize : 6));
497
+ const markerStyle = resolveMarkerStyle(options.markerStyle);
498
+ const selected = options.seriesIds === undefined ? null : new Set(options.seriesIds), paintSeries = selected ? scene.series.filter(series => selected.has(series.id)) : scene.series;
499
+ const paintObservations = selected ? scene.observations.filter(point => selected.has(point.id.seriesId)) : scene.observations;
500
+ const barBorder = scene.family === 'histogram' || scene.family === 'variwide' ? ` stroke="${options.surfaceColor ?? '#FFFFFF'}" stroke-width="${1 / Math.sqrt(transform.sx * transform.sy)}" stroke-linejoin="miter"` : scene.family === 'treemap' ? ` stroke="${gridColor}" stroke-width="1"` : '';
501
+ const denseBars = paintSeries.reduce((n, s) => n + (s.bars?.length ?? 0), 0) > 256;
502
+ const overrides = pointPaint(scene), paintColor = (seriesId, base, pointId) => pointId === undefined ? base : overrides.get(identityKey({ seriesId, pointId })) ?? base;
503
+ const areaFills = paintSeries.map(s => s.areaPath ? `<path d="${s.areaPath}" fill="${s.color}" fill-opacity="${scene.family === 'pictorial' || scene.family === 'vector' || scene.family === 'windbarb' ? 1 : scene.family === 'sankey' || relationshipFamily(scene.family) ? 0.38 : 0.18}" stroke="none"/>` : '').join('');
504
+ const surface = options.surfaceColor ?? '#FFFFFF';
505
+ const connectorColor = parseInt(surface.slice(1, 3), 16) + parseInt(surface.slice(3, 5), 16) + parseInt(surface.slice(5, 7), 16) < 384 ? '#94A3B8' : '#64748B';
506
+ const series = paintSeries.map(s => {
507
+ const path = s.path === undefined ? '' : `<path d="${s.path}" fill="${s.fill ? s.color : 'none'}" stroke="${scene.family === 'waterfall' ? connectorColor : s.fill && scene.family === 'sunburst' ? (options.surfaceColor ?? '#FFFFFF') : s.color}" stroke-width="${scene.family === 'waterfall' ? 1.25 / Math.sqrt(transform.sx * transform.sy) : s.fill ? 1 : strokeWidth}" stroke-linecap="round" stroke-linejoin="round"/>`;
508
+ const bars = denseBars ? barPaintBatches(s.id, s.color, (s.bars ?? []).filter(bar => bar.width > 0 && bar.height > 0), overrides, scene.family === 'boxplot' || barBorder !== '', Math.max(1 / transform.sx, 1 / transform.sy)).map(([color, bars]) => `<path d="${bars.map(bar => `M${bar.x} ${bar.y}h${bar.width}v${bar.height}h${-bar.width}Z`).join('')}" fill="${color}"${scene.family === 'boxplot' ? ' fill-opacity="0.18"' : ''}${barBorder}/>`).join('') : (s.bars ?? []).map(bar => `<rect x="${bar.x}" y="${bar.y}" width="${bar.width}" height="${bar.height}" fill="${paintColor(s.id, s.color, bar.pointId)}"${scene.family === 'boxplot' ? ' fill-opacity="0.18"' : ''}${barBorder}/>`).join('');
509
+ const visibleCircles = (scene.family === 'fan' || scene.family === 'regression' || relationshipFamily(scene.family) ? [] : s.circles ?? []).filter(circle => circle.radius > 0);
510
+ const circleOpacity = scene.family === 'venn' ? .45 : .64;
511
+ const circleSvg = (circle, color) => `<circle cx="${circle.cx}" cy="${circle.cy}" r="${circle.radius}" fill="${color}" fill-opacity="${circleOpacity}" stroke="${color}" stroke-width="2"/>`;
512
+ const circles = visibleCircles.length > 256 ? circlePaintBatches(s.id, s.color, visibleCircles, overrides, 1 + Math.max(1 / transform.sx, 1 / transform.sy)).map(([color, circles]) => circles.length === 1 ? circleSvg(circles[0], color) : `<path d="${circles.map(circle => `M${circle.cx - circle.radius} ${circle.cy}A${circle.radius} ${circle.radius} 0 1 0 ${circle.cx + circle.radius} ${circle.cy}A${circle.radius} ${circle.radius} 0 1 0 ${circle.cx - circle.radius} ${circle.cy}Z`).join('')}" fill="${color}" fill-opacity="${circleOpacity}" stroke="${color}" stroke-width="2"/>`).join('') : visibleCircles.map(circle => circleSvg(circle, paintColor(s.id, s.color, circle.pointId))).join('');
513
+ return (s.cells ? tilemapCellsSvg(s.cells) : '') + (scene.family === 'boxplot' ? bars + path + circles : relationshipFamily(scene.family) ? path + bars : path + bars + circles);
514
+ }).join('');
515
+ // Dense line markers add nodes without adding readable information. The path and all hit
516
+ // observations remain intact; selection still paints its own full-size active marker.
517
+ const markerBudget = Math.max(24, Math.min(512, Math.floor(width / 8)));
518
+ const lineSeries = new Set(paintSeries.filter(s => s.path !== undefined).map(s => s.id));
519
+ const markerObservations = options.showMarkers === false ? [] : scene.family === 'fan' ? paintObservations.filter(p => p.fan?.type === 'center') : scene.family === 'regression' ? paintObservations.filter(p => p.regression?.type === 'sample') : scene.family === 'pareto' ? paintObservations.filter(p => p.id.seriesId === 'cumulative') : scene.family === 'mixed' ? paintObservations.filter(p => p.lowValue === undefined && lineSeries.has(p.id.seriesId)) : paintObservations;
520
+ const markers = (scene.family === 'fan' || scene.family === 'regression') ? (options.showMarkers === false ? '' : markerBatchSvg(markerObservations, transform, markerSize, markerStyle)) : (scene.family === 'pareto' || scene.family === 'radar' || scene.family === 'line' || scene.family === 'area' || scene.family === 'areaspline' || scene.family === 'spline' || scene.family === 'mixed') && options.showMarkers !== false && markerObservations.length <= markerBudget ? markerObservations.map(p => { const pointColor = overrides.get(identityKey(p.id)); return markerSvg(transform.x + p.x * transform.sx, transform.y + p.y * transform.sy, markerSize, p.color, pointColor === undefined ? markerStyle : { ...markerStyle, fillColor: pointColor }); }).join('') : '';
521
+ // NgIcon preserves its viewBox aspect ratio. Match the actual native viewport,
522
+ // then transform plot-local geometry so axes and hit coordinates stay aligned.
523
+ const relationshipNodes = relationshipFamily(scene.family) ? paintSeries.map(s => `<path d="${s.nodePath ?? ''}" fill="${s.color}"/>` + (s.circles ?? []).filter(c => c.radius > 0).map(c => `<circle cx="${c.cx}" cy="${c.cy}" r="${c.radius}" fill="${paintColor(s.id, s.color, c.pointId)}"/>`).join('')).join('') : '';
524
+ const sourceClip = ['sankey', 'treegraph', 'organization', 'networkgraph', 'packedbubble'].includes(scene.family) ? scene.clip : undefined;
525
+ // Paint may extend by half a node's stroke plus a physical antialias pixel.
526
+ // Keep the data window untouched and retain clipping of off-window nodes.
527
+ const bleed = ['treegraph', 'networkgraph', 'packedbubble'].includes(scene.family) ? 1 + 1 / Math.min(transform.sx, transform.sy) : 0;
528
+ const clip = sourceClip ? { x: sourceClip.x - bleed, y: sourceClip.y - bleed, width: sourceClip.width + 2 * bleed, height: sourceClip.height + 2 * bleed } : undefined;
529
+ const clipId = clip ? 'nc-plot-' + [clip.x, clip.y, clip.width, clip.height].join('_').replace(/\./g, 'd') : '';
530
+ const definition = clip ? `<defs><clipPath id="${clipId}"><rect x="${clip.x}" y="${clip.y}" width="${clip.width}" height="${clip.height}"/></clipPath></defs>` : '';
531
+ return `<svg viewBox="0 0 ${width} ${height}">${definition}<g transform="${offset}scale(${transform.sx} ${transform.sy})"${clip ? ` clip-path="url(#${clipId})"` : ''}>${options.layer === 'series' ? '' : background + bandBackground + grid}${areaFills}${series}${relationshipNodes}${options.layer === 'series' ? '' : decorations}</g>${markers}${options.layer === 'series' ? '' : referencePaint(scene.references, transform)}</svg>`;
532
+ }
533
+ //# sourceMappingURL=scene.js.map