graphein 0.20.0 → 0.22.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 (319) hide show
  1. package/dist/animation/animate.d.ts +6 -1
  2. package/dist/animation/animate.d.ts.map +1 -1
  3. package/dist/animation/animate.js +2 -2
  4. package/dist/animation/animate.js.map +2 -2
  5. package/dist/animation/env.d.ts +5 -0
  6. package/dist/animation/env.d.ts.map +1 -1
  7. package/dist/animation/env.js +4 -0
  8. package/dist/animation/env.js.map +2 -2
  9. package/dist/animation/index.d.ts +1 -0
  10. package/dist/animation/index.d.ts.map +1 -1
  11. package/dist/animation/index.js +1 -0
  12. package/dist/animation/index.js.map +2 -2
  13. package/dist/animation/stagger.d.ts +13 -0
  14. package/dist/animation/stagger.d.ts.map +1 -0
  15. package/dist/animation/stagger.js +13 -0
  16. package/dist/animation/stagger.js.map +7 -0
  17. package/dist/axes/draw.d.ts +5 -1
  18. package/dist/axes/draw.d.ts.map +1 -1
  19. package/dist/axes/draw.js +13 -1
  20. package/dist/axes/draw.js.map +2 -2
  21. package/dist/axes/morph.d.ts +111 -0
  22. package/dist/axes/morph.d.ts.map +1 -0
  23. package/dist/axes/morph.js +207 -0
  24. package/dist/axes/morph.js.map +7 -0
  25. package/dist/axes/overlay.d.ts.map +1 -1
  26. package/dist/axes/overlay.js +88 -25
  27. package/dist/axes/overlay.js.map +2 -2
  28. package/dist/axes/text.d.ts +2 -0
  29. package/dist/axes/text.d.ts.map +1 -1
  30. package/dist/axes/text.js +1 -0
  31. package/dist/axes/text.js.map +2 -2
  32. package/dist/axes/tickLabels.d.ts +2 -0
  33. package/dist/axes/tickLabels.d.ts.map +1 -1
  34. package/dist/axes/tickLabels.js +2 -2
  35. package/dist/axes/tickLabels.js.map +2 -2
  36. package/dist/charts/annotations.d.ts +9 -3
  37. package/dist/charts/annotations.d.ts.map +1 -1
  38. package/dist/charts/annotations.js +82 -27
  39. package/dist/charts/annotations.js.map +2 -2
  40. package/dist/charts/area.d.ts +37 -1
  41. package/dist/charts/area.d.ts.map +1 -1
  42. package/dist/charts/area.js +35 -17
  43. package/dist/charts/area.js.map +2 -2
  44. package/dist/charts/bar.d.ts +53 -0
  45. package/dist/charts/bar.d.ts.map +1 -1
  46. package/dist/charts/bar.js +117 -83
  47. package/dist/charts/bar.js.map +2 -2
  48. package/dist/charts/box.d.ts +31 -0
  49. package/dist/charts/box.d.ts.map +1 -1
  50. package/dist/charts/box.js +93 -70
  51. package/dist/charts/box.js.map +2 -2
  52. package/dist/charts/bubbleMap.d.ts +20 -0
  53. package/dist/charts/bubbleMap.d.ts.map +1 -0
  54. package/dist/charts/bubbleMap.js +951 -0
  55. package/dist/charts/bubbleMap.js.map +7 -0
  56. package/dist/charts/bullet.d.ts.map +1 -1
  57. package/dist/charts/bullet.js +69 -51
  58. package/dist/charts/bullet.js.map +2 -2
  59. package/dist/charts/calendarHeatmap.d.ts.map +1 -1
  60. package/dist/charts/calendarHeatmap.js +56 -19
  61. package/dist/charts/calendarHeatmap.js.map +2 -2
  62. package/dist/charts/candlestick.d.ts +40 -0
  63. package/dist/charts/candlestick.d.ts.map +1 -0
  64. package/dist/charts/candlestick.js +325 -0
  65. package/dist/charts/candlestick.js.map +7 -0
  66. package/dist/charts/choropleth.d.ts.map +1 -1
  67. package/dist/charts/choropleth.js +46 -67
  68. package/dist/charts/choropleth.js.map +2 -2
  69. package/dist/charts/combo.d.ts.map +1 -1
  70. package/dist/charts/combo.js +127 -27
  71. package/dist/charts/combo.js.map +3 -3
  72. package/dist/charts/dumbbell.d.ts.map +1 -1
  73. package/dist/charts/dumbbell.js +100 -31
  74. package/dist/charts/dumbbell.js.map +2 -2
  75. package/dist/charts/funnel.d.ts.map +1 -1
  76. package/dist/charts/funnel.js +93 -28
  77. package/dist/charts/funnel.js.map +3 -3
  78. package/dist/charts/gantt.d.ts +22 -0
  79. package/dist/charts/gantt.d.ts.map +1 -0
  80. package/dist/charts/gantt.js +564 -0
  81. package/dist/charts/gantt.js.map +7 -0
  82. package/dist/charts/gauge.d.ts.map +1 -1
  83. package/dist/charts/gauge.js +30 -4
  84. package/dist/charts/gauge.js.map +2 -2
  85. package/dist/charts/geo.d.ts +87 -0
  86. package/dist/charts/geo.d.ts.map +1 -0
  87. package/dist/charts/geo.js +140 -0
  88. package/dist/charts/geo.js.map +7 -0
  89. package/dist/charts/geometry.d.ts +20 -0
  90. package/dist/charts/geometry.d.ts.map +1 -0
  91. package/dist/charts/geometry.js +25 -0
  92. package/dist/charts/geometry.js.map +7 -0
  93. package/dist/charts/heatmap.d.ts.map +1 -1
  94. package/dist/charts/heatmap.js +58 -49
  95. package/dist/charts/heatmap.js.map +2 -2
  96. package/dist/charts/histogram.d.ts +1 -1
  97. package/dist/charts/histogram.d.ts.map +1 -1
  98. package/dist/charts/histogram.js +49 -31
  99. package/dist/charts/histogram.js.map +2 -2
  100. package/dist/charts/index.d.ts +35 -1
  101. package/dist/charts/index.d.ts.map +1 -1
  102. package/dist/charts/index.js +12 -0
  103. package/dist/charts/index.js.map +2 -2
  104. package/dist/charts/legibility.d.ts +38 -0
  105. package/dist/charts/legibility.d.ts.map +1 -0
  106. package/dist/charts/legibility.js +72 -0
  107. package/dist/charts/legibility.js.map +7 -0
  108. package/dist/charts/line.d.ts +39 -1
  109. package/dist/charts/line.d.ts.map +1 -1
  110. package/dist/charts/line.js +48 -16
  111. package/dist/charts/line.js.map +2 -2
  112. package/dist/charts/matrix.d.ts +2 -1
  113. package/dist/charts/matrix.d.ts.map +1 -1
  114. package/dist/charts/matrix.js +481 -319
  115. package/dist/charts/matrix.js.map +3 -3
  116. package/dist/charts/morphFrame.d.ts +83 -0
  117. package/dist/charts/morphFrame.d.ts.map +1 -0
  118. package/dist/charts/morphFrame.js +128 -0
  119. package/dist/charts/morphFrame.js.map +7 -0
  120. package/dist/charts/pie.d.ts.map +1 -1
  121. package/dist/charts/pie.js +89 -26
  122. package/dist/charts/pie.js.map +2 -2
  123. package/dist/charts/pieState.d.ts +27 -0
  124. package/dist/charts/pieState.d.ts.map +1 -0
  125. package/dist/charts/pieState.js +55 -0
  126. package/dist/charts/pieState.js.map +7 -0
  127. package/dist/charts/radar.d.ts +62 -0
  128. package/dist/charts/radar.d.ts.map +1 -0
  129. package/dist/charts/radar.js +912 -0
  130. package/dist/charts/radar.js.map +7 -0
  131. package/dist/charts/radialBar.d.ts +60 -0
  132. package/dist/charts/radialBar.d.ts.map +1 -0
  133. package/dist/charts/radialBar.js +708 -0
  134. package/dist/charts/radialBar.js.map +7 -0
  135. package/dist/charts/sankey.d.ts.map +1 -1
  136. package/dist/charts/sankey.js +223 -57
  137. package/dist/charts/sankey.js.map +3 -3
  138. package/dist/charts/scatter.d.ts +31 -0
  139. package/dist/charts/scatter.d.ts.map +1 -1
  140. package/dist/charts/scatter.js +48 -12
  141. package/dist/charts/scatter.js.map +2 -2
  142. package/dist/charts/slope.d.ts.map +1 -1
  143. package/dist/charts/slope.js +55 -3
  144. package/dist/charts/slope.js.map +2 -2
  145. package/dist/charts/sunburst.d.ts +14 -0
  146. package/dist/charts/sunburst.d.ts.map +1 -0
  147. package/dist/charts/sunburst.js +885 -0
  148. package/dist/charts/sunburst.js.map +7 -0
  149. package/dist/charts/table.d.ts +2 -1
  150. package/dist/charts/table.d.ts.map +1 -1
  151. package/dist/charts/table.js +214 -224
  152. package/dist/charts/table.js.map +3 -3
  153. package/dist/charts/tableView/canvas.d.ts +16 -1
  154. package/dist/charts/tableView/canvas.d.ts.map +1 -1
  155. package/dist/charts/tableView/canvas.js +361 -252
  156. package/dist/charts/tableView/canvas.js.map +3 -3
  157. package/dist/charts/tableView/conditional.d.ts +66 -40
  158. package/dist/charts/tableView/conditional.d.ts.map +1 -1
  159. package/dist/charts/tableView/conditional.js +163 -256
  160. package/dist/charts/tableView/conditional.js.map +3 -3
  161. package/dist/charts/tableView/dom.d.ts +26 -2
  162. package/dist/charts/tableView/dom.d.ts.map +1 -1
  163. package/dist/charts/tableView/dom.js +609 -269
  164. package/dist/charts/tableView/dom.js.map +3 -3
  165. package/dist/charts/tableView/layout.d.ts +22 -0
  166. package/dist/charts/tableView/layout.d.ts.map +1 -0
  167. package/dist/charts/tableView/layout.js +246 -0
  168. package/dist/charts/tableView/layout.js.map +7 -0
  169. package/dist/charts/tableView/sketch.d.ts +3 -2
  170. package/dist/charts/tableView/sketch.d.ts.map +1 -1
  171. package/dist/charts/tableView/sketch.js +2 -2
  172. package/dist/charts/tableView/sketch.js.map +2 -2
  173. package/dist/charts/tableView/sketchBar.d.ts +7 -0
  174. package/dist/charts/tableView/sketchBar.d.ts.map +1 -0
  175. package/dist/charts/tableView/sketchBar.js +32 -0
  176. package/dist/charts/tableView/sketchBar.js.map +7 -0
  177. package/dist/charts/tableView/sort.d.ts +9 -0
  178. package/dist/charts/tableView/sort.d.ts.map +1 -0
  179. package/dist/charts/tableView/sort.js +70 -0
  180. package/dist/charts/tableView/sort.js.map +7 -0
  181. package/dist/charts/tableView/sparkline.d.ts +30 -0
  182. package/dist/charts/tableView/sparkline.d.ts.map +1 -0
  183. package/dist/charts/tableView/sparkline.js +63 -0
  184. package/dist/charts/tableView/sparkline.js.map +7 -0
  185. package/dist/charts/tableView/style.d.ts +67 -0
  186. package/dist/charts/tableView/style.d.ts.map +1 -0
  187. package/dist/charts/tableView/style.js +131 -0
  188. package/dist/charts/tableView/style.js.map +7 -0
  189. package/dist/charts/tableView/types.d.ts +69 -46
  190. package/dist/charts/tableView/types.d.ts.map +1 -1
  191. package/dist/charts/tableView/types.js +22 -87
  192. package/dist/charts/tableView/types.js.map +2 -2
  193. package/dist/charts/tableView.d.ts +10 -5
  194. package/dist/charts/tableView.d.ts.map +1 -1
  195. package/dist/charts/tableView.js +12 -8
  196. package/dist/charts/tableView.js.map +2 -2
  197. package/dist/charts/treemap.d.ts.map +1 -1
  198. package/dist/charts/treemap.js +177 -68
  199. package/dist/charts/treemap.js.map +3 -3
  200. package/dist/charts/trendline.d.ts +13 -5
  201. package/dist/charts/trendline.d.ts.map +1 -1
  202. package/dist/charts/trendline.js +205 -56
  203. package/dist/charts/trendline.js.map +2 -2
  204. package/dist/charts/waterfall.d.ts.map +1 -1
  205. package/dist/charts/waterfall.js +76 -5
  206. package/dist/charts/waterfall.js.map +2 -2
  207. package/dist/index.d.ts +1 -1
  208. package/dist/index.js +1 -1
  209. package/dist/index.js.map +1 -1
  210. package/dist/interaction/cartesian.d.ts +4 -1
  211. package/dist/interaction/cartesian.d.ts.map +1 -1
  212. package/dist/interaction/cartesian.js +104 -34
  213. package/dist/interaction/cartesian.js.map +2 -2
  214. package/dist/interaction/controller.d.ts +29 -1
  215. package/dist/interaction/controller.d.ts.map +1 -1
  216. package/dist/interaction/controller.js +131 -8
  217. package/dist/interaction/controller.js.map +2 -2
  218. package/dist/interaction/focus.d.ts +23 -0
  219. package/dist/interaction/focus.d.ts.map +1 -0
  220. package/dist/interaction/focus.js +65 -0
  221. package/dist/interaction/focus.js.map +7 -0
  222. package/dist/interaction/tooltip.d.ts +6 -0
  223. package/dist/interaction/tooltip.d.ts.map +1 -1
  224. package/dist/interaction/tooltip.js +41 -16
  225. package/dist/interaction/tooltip.js.map +2 -2
  226. package/dist/interaction/types.d.ts +19 -0
  227. package/dist/interaction/types.d.ts.map +1 -1
  228. package/dist/interaction/veil.d.ts +25 -0
  229. package/dist/interaction/veil.d.ts.map +1 -0
  230. package/dist/interaction/veil.js +35 -0
  231. package/dist/interaction/veil.js.map +7 -0
  232. package/dist/pivot/pivot.d.ts +18 -0
  233. package/dist/pivot/pivot.d.ts.map +1 -1
  234. package/dist/pivot/pivot.js +46 -34
  235. package/dist/pivot/pivot.js.map +2 -2
  236. package/dist/render/chromeMotion.d.ts +65 -0
  237. package/dist/render/chromeMotion.d.ts.map +1 -0
  238. package/dist/render/chromeMotion.js +79 -0
  239. package/dist/render/chromeMotion.js.map +7 -0
  240. package/dist/render/pathSample.d.ts +24 -0
  241. package/dist/render/pathSample.d.ts.map +1 -0
  242. package/dist/render/pathSample.js +76 -0
  243. package/dist/render/pathSample.js.map +7 -0
  244. package/dist/render/transient.d.ts +18 -0
  245. package/dist/render/transient.d.ts.map +1 -0
  246. package/dist/render/transient.js +19 -0
  247. package/dist/render/transient.js.map +7 -0
  248. package/dist/runtime/candlestick.d.ts +112 -0
  249. package/dist/runtime/candlestick.d.ts.map +1 -0
  250. package/dist/runtime/candlestick.js +531 -0
  251. package/dist/runtime/candlestick.js.map +7 -0
  252. package/dist/runtime/cartesian.d.ts +14 -3
  253. package/dist/runtime/cartesian.d.ts.map +1 -1
  254. package/dist/runtime/cartesian.js.map +2 -2
  255. package/dist/runtime/chartAnimation.d.ts +54 -7
  256. package/dist/runtime/chartAnimation.d.ts.map +1 -1
  257. package/dist/runtime/chartAnimation.js +146 -28
  258. package/dist/runtime/chartAnimation.js.map +2 -2
  259. package/dist/runtime/chartRuntime.d.ts +42 -0
  260. package/dist/runtime/chartRuntime.d.ts.map +1 -1
  261. package/dist/runtime/chartRuntime.js +196 -30
  262. package/dist/runtime/chartRuntime.js.map +2 -2
  263. package/dist/runtime/dashboardDom.d.ts.map +1 -1
  264. package/dist/runtime/dashboardDom.js +45 -0
  265. package/dist/runtime/dashboardDom.js.map +2 -2
  266. package/dist/runtime/facet.d.ts +1 -1
  267. package/dist/runtime/facet.d.ts.map +1 -1
  268. package/dist/runtime/gantt.d.ts +137 -0
  269. package/dist/runtime/gantt.d.ts.map +1 -0
  270. package/dist/runtime/gantt.js +647 -0
  271. package/dist/runtime/gantt.js.map +7 -0
  272. package/dist/runtime/morph.d.ts +33 -0
  273. package/dist/runtime/morph.d.ts.map +1 -0
  274. package/dist/runtime/morph.js +332 -0
  275. package/dist/runtime/morph.js.map +7 -0
  276. package/dist/runtime/radar.d.ts +75 -0
  277. package/dist/runtime/radar.d.ts.map +1 -0
  278. package/dist/runtime/radar.js +201 -0
  279. package/dist/runtime/radar.js.map +7 -0
  280. package/dist/runtime/radialBar.d.ts +81 -0
  281. package/dist/runtime/radialBar.d.ts.map +1 -0
  282. package/dist/runtime/radialBar.js +125 -0
  283. package/dist/runtime/radialBar.js.map +7 -0
  284. package/dist/runtime/report/constants.d.ts +2 -2
  285. package/dist/runtime/report/constants.d.ts.map +1 -1
  286. package/dist/runtime/runtimeShared.d.ts +3 -3
  287. package/dist/runtime/runtimeShared.d.ts.map +1 -1
  288. package/dist/runtime/sunburst.d.ts +74 -0
  289. package/dist/runtime/sunburst.d.ts.map +1 -0
  290. package/dist/runtime/sunburst.js +150 -0
  291. package/dist/runtime/sunburst.js.map +7 -0
  292. package/dist/runtime/wire.d.ts.map +1 -1
  293. package/dist/runtime/wire.js +3 -1
  294. package/dist/runtime/wire.js.map +2 -2
  295. package/dist/shape/arc.d.ts +15 -2
  296. package/dist/shape/arc.d.ts.map +1 -1
  297. package/dist/shape/arc.js +204 -32
  298. package/dist/shape/arc.js.map +2 -2
  299. package/dist/spec/chartDefinitions.d.ts +6 -0
  300. package/dist/spec/chartDefinitions.d.ts.map +1 -1
  301. package/dist/spec/chartDefinitions.js +7 -1
  302. package/dist/spec/chartDefinitions.js.map +2 -2
  303. package/dist/spec/templates.d.ts.map +1 -1
  304. package/dist/spec/templates.js +177 -2
  305. package/dist/spec/templates.js.map +2 -2
  306. package/dist/spec/types.d.ts +258 -6
  307. package/dist/spec/types.d.ts.map +1 -1
  308. package/dist/spec/types.js +6 -0
  309. package/dist/spec/types.js.map +2 -2
  310. package/dist/spec/validate/charts.js +147 -15
  311. package/dist/spec/validate/charts.js.map +2 -2
  312. package/dist/spec/validate/common.d.ts +6 -0
  313. package/dist/spec/validate/common.d.ts.map +1 -1
  314. package/dist/spec/validate/overlays.js +2 -2
  315. package/dist/spec/validate/overlays.js.map +2 -2
  316. package/dist/spec/validate.data.d.ts.map +1 -1
  317. package/dist/spec/validate.data.js +8 -3
  318. package/dist/spec/validate.data.js.map +2 -2
  319. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/runtime/chartAnimation.ts"],
4
- "sourcesContent": ["import type { ChartSpec } from '../spec/types';\nimport type { Size } from '../types';\nimport { drawAxesUnderlay } from '../axes';\nimport { drawAnnotations, drawTrendlines, type CartesianRenderer, type CustomRenderer, type RenderContext } from '../charts';\nimport type { CanvasLayer } from '../render/canvasLayer';\nimport type { Surface } from '../render/surface';\nimport type { ThemeTokens } from '../theme';\nimport { animate, type AnimationHandle, type ResolvedEntrance } from '../animation';\nimport type { CartesianModel } from './cartesian';\nimport { paintBackground } from './runtimeShared';\n\n/**\n * Cartesian entrance. Two modes: a left-to-right `wipe` with a brief fade\n * (line/area/scatter/box), or `grow` where the renderer re-runs each frame with\n * an `entranceProgress` so bars rise out of the value baseline. Gridlines + axis\n * baselines stay fully drawn throughout; the final frame is pixel-identical to a\n * static draw.\n */\nexport function runCartesianEntrance(\n surface: Surface,\n model: CartesianModel,\n renderer: CartesianRenderer,\n tokens: ThemeTokens,\n background: string | undefined,\n anim: ResolvedEntrance,\n onDone: () => void,\n mode: 'wipe' | 'grow' = 'wipe',\n): AnimationHandle {\n const ctx = surface.marks.ctx;\n const { plot } = model;\n const bg = background ?? tokens.color.background;\n const paintFrame = (t: number): void => {\n surface.marks.clear();\n surface.evidence.reset({ width: surface.width, height: surface.height }, model.spec.data?.length ?? 0, bg);\n ctx.save();\n ctx.fillStyle = bg;\n ctx.fillRect(0, 0, surface.width, surface.height);\n ctx.restore();\n drawAxesUnderlay(surface, model);\n if (mode === 'grow') return paintGrowFrame(surface, model, renderer, t);\n if (t <= 0) return;\n ctx.save();\n ctx.globalAlpha = Math.min(1, 0.2 + 0.8 * t);\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width * t, plot.height + 1);\n ctx.clip();\n renderer(surface, model);\n ctx.restore();\n drawTrendlines(surface, model);\n drawAnnotations(surface, model);\n };\n paintFrame(0);\n return animate({ duration: anim.duration, easing: anim.easing, onUpdate: paintFrame,\n onComplete: () => { paintFrame(1); onDone(); } });\n}\n\nfunction paintGrowFrame(surface: Surface, model: CartesianModel, renderer: CartesianRenderer, t: number): void {\n // Marks grow from the baseline; leave the shared model clean afterwards so\n // interaction/report code always sees the fully-drawn state.\n model.entranceProgress = t;\n renderer(surface, model);\n model.entranceProgress = undefined;\n drawTrendlines(surface, model);\n drawAnnotations(surface, model);\n}\n\n/**\n * Custom-chart entrance that re-renders the visual each frame with an\n * interpolation progress (0..1) mixed into its RenderContext \u2014 the number\n * roll-up (kpi) and arc sweep (pie/gauge). `paint` clears the layers and\n * repaints; the final frame (t=1) is pixel-identical to a static draw.\n *\n * Note we do *not* paint frame 0 synchronously: the caller already rendered the\n * final state, and `animate()` schedules the first frame via rAF (which runs\n * before the browser's first paint, so the roll still starts from ~0 with no\n * flash). This keeps the synchronous DOM \u2014 and thus SSR / no-rAF / test reads \u2014\n * showing the final value rather than 0.\n */\nfunction runCustomProgress(\n anim: ResolvedEntrance,\n onDone: () => void,\n paint: (t: number) => void,\n): AnimationHandle {\n return animate({ duration: anim.duration, easing: anim.easing, onUpdate: paint,\n onComplete: () => { paint(1); onDone(); } });\n}\n\nexport function runCustomRendererProgress(\n surface: Surface,\n renderer: CustomRenderer,\n spec: ChartSpec,\n tokens: ThemeTokens,\n size: Size,\n options: {\n anim: ResolvedEntrance;\n onDone: () => void;\n dataLength: number;\n background?: string;\n context: RenderContext;\n progressKey: 'valueProgress' | 'sweepProgress';\n extraContext?: Partial<RenderContext>;\n },\n): AnimationHandle {\n return runCustomProgress(options.anim, options.onDone, (t) => {\n surface.overlay.replaceChildren();\n surface.marks.clear();\n surface.labels.clear();\n surface.evidence.reset(size, options.dataLength, options.background ?? tokens.color.background);\n paintBackground(surface, tokens, options.background);\n renderer(surface, spec, tokens, size, { ...options.context, ...options.extraContext, [options.progressKey]: t });\n });\n}\n\n/**\n * Custom-chart entrance: a compositor-friendly opacity + slight upward rise of\n * the whole surface. Used for charts whose content is already fully painted\n * (pie/heatmap canvas, kpi/table/matrix DOM), so re-running the renderer per\n * frame isn't needed.\n */\nexport function runFadeEntrance(surface: Surface, anim: ResolvedEntrance, onDone: () => void): AnimationHandle {\n const apply = (t: number): void => {\n surface.root.style.opacity = String(t);\n const dy = (1 - t) * 8;\n surface.root.style.transform = dy > 0.02 ? `translateY(${dy.toFixed(2)}px)` : '';\n };\n apply(0);\n return animate({ duration: anim.duration, easing: anim.easing, onUpdate: apply,\n onComplete: () => { surface.root.style.opacity = ''; surface.root.style.transform = ''; onDone(); } });\n}\n\n/**\n * Copy a canvas layer's current backing store into a detached canvas so it can\n * be composited later (used to cross-fade the previous frame on update()).\n */\nexport function snapshotLayer(layer: CanvasLayer): HTMLCanvasElement {\n const off = document.createElement('canvas');\n off.width = layer.canvas.width;\n off.height = layer.canvas.height;\n if (off.width > 0 && off.height > 0) off.getContext('2d')?.drawImage(layer.canvas, 0, 0);\n return off;\n}\n\n/**\n * Update transition: cross-fade the marks layer from the previous frame to the\n * freshly drawn one. The new frame is already live on the canvas when this runs,\n * so we snapshot it and composite `new` under `old` with `old` fading out. The\n * final frame is pixel-identical to the static (instant) draw.\n */\nexport function runUpdateCrossfade(surface: Surface, before: HTMLCanvasElement, anim: ResolvedEntrance): AnimationHandle {\n const after = snapshotLayer(surface.marks);\n const ctx = surface.marks.ctx;\n const w = surface.marks.width;\n const h = surface.marks.height;\n const paint = (t: number): void => {\n surface.marks.clear();\n ctx.save();\n ctx.globalAlpha = 1;\n ctx.drawImage(after, 0, 0, w, h);\n if (t < 1) {\n ctx.globalAlpha = 1 - t;\n ctx.drawImage(before, 0, 0, w, h);\n }\n ctx.restore();\n };\n paint(0);\n return animate({ duration: anim.duration, easing: anim.easing, onUpdate: paint, onComplete: () => paint(1) });\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { ChartSpec, CurveType } from '../spec/types';\nimport type { Size } from '../types';\nimport { drawAxesUnderlay, drawOverlay } from '../axes';\nimport {\n drawAnnotationLabels,\n drawAnnotations,\n drawTrendlineLabels,\n drawTrendlines,\n type CartesianRenderer,\n type CustomRenderer,\n type RenderContext,\n} from '../charts';\nimport { paintGeometry, transientSurface } from '../charts/geometry';\nimport type { CanvasLayer } from '../render/canvasLayer';\nimport { CHROME_IN_FLIGHT, fadeChrome, revealAt, setChromeEntrance, setChromeMorph, type ChromeSnapshot } from '../render/chromeMotion';\nimport { ANNOTATION_LABELS } from '../charts/annotations';\nimport { TREND_LABELS } from '../charts/trendline';\nimport { PathSampler } from '../render/pathSample';\nimport type { Surface } from '../render/surface';\nimport { line } from '../shape';\nimport type { ThemeTokens } from '../theme';\nimport { withAlpha } from '../color';\nimport { animate, linear, type AnimationHandle, type ResolvedEntrance } from '../animation';\nimport { resolveCurve, type CartesianModel } from './cartesian';\nimport type { GeometryMorph } from './morph';\nimport { paintBackground } from './runtimeShared';\n\n/** Label stashes an entrance fades in place (their DOM is drawn once, then faded). */\nconst LATE_LABEL_STASHES = [ANNOTATION_LABELS, TREND_LABELS];\n\n/** Fraction of a staggered entrance spread across marks as a wave. */\nconst ENTRANCE_STAGGER = 0.4;\n/** Staggered entrances run a little longer so each mark keeps a full ease. */\nconst STAGGER_STRETCH = 1.35;\n\n/**\n * Cartesian entrance. Two modes:\n * - `wipe`: a left-to-right reveal. Lines and areas draw on at full strength\n * with a glowing head riding each series' leading edge; other charts (box)\n * reveal with a brief fade.\n * - `grow`: the renderer re-runs each frame with an `entranceProgress`, so bars\n * rise out of the value baseline and scatter points pop in \u2014 staggered as a\n * left-to-right wave, each mark easing on its own schedule.\n * Gridlines + axis baselines stay fully drawn throughout. Reference lines,\n * bands and trendlines draw in once the marks have mostly arrived, and their\n * labels (`lateLabels`) fade in last. The final frame is pixel-identical to a\n * static draw.\n */\nexport function runCartesianEntrance(\n surface: Surface,\n model: CartesianModel,\n renderer: CartesianRenderer,\n tokens: ThemeTokens,\n background: string | undefined,\n anim: ResolvedEntrance,\n onDone: () => void,\n mode: 'wipe' | 'grow' = 'wipe',\n lateLabels: readonly HTMLElement[] = [],\n): AnimationHandle {\n const ctx = surface.marks.ctx;\n const { plot } = model;\n const bg = background ?? tokens.color.background;\n const drawOn = model.spec.type === 'line' || model.spec.type === 'area';\n const staggered = mode === 'grow' && staggerable(model);\n // Chrome timing only moves forward and finishes with the entrance, so an\n // overshooting easing (backOut, elasticOut) can't flicker reference lines or labels.\n let shown = 0;\n const paintFrame = (t: number, done = false): void => {\n shown = done ? 1 : Math.min(CHROME_IN_FLIGHT, Math.max(shown, t));\n setChromeEntrance(surface, done ? null : shown);\n const labelReveal = done ? 1 : revealAt(shown, 0.78, 1);\n for (const el of lateLabels) el.style.opacity = done ? '' : String(labelReveal);\n // The late labels fade in place; an update that interrupts captures them as shown.\n for (const name of LATE_LABEL_STASHES) fadeChrome(surface, name, labelReveal);\n surface.marks.clear();\n surface.evidence.reset({ width: surface.width, height: surface.height }, model.spec.data?.length ?? 0, bg);\n ctx.save();\n ctx.fillStyle = bg;\n ctx.fillRect(0, 0, surface.width, surface.height);\n ctx.restore();\n drawAxesUnderlay(surface, model);\n if (mode === 'grow') return paintGrowFrame(surface, model, renderer, t, staggered ? anim.easing : undefined);\n if (t <= 0) return;\n ctx.save();\n ctx.globalAlpha = drawOn ? 1 : Math.min(1, 0.2 + 0.8 * t);\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width * t, plot.height + 1);\n ctx.clip();\n renderer(surface, model);\n ctx.restore();\n if (drawOn) paintDrawOnHeads(ctx, model, bg, t);\n drawTrendlines(surface, model);\n drawAnnotations(surface, model);\n };\n paintFrame(0);\n // A staggered grow runs on a linear clock; each mark applies the easing itself.\n return animate({\n duration: staggered ? anim.duration * STAGGER_STRETCH : anim.duration,\n easing: staggered ? linear : anim.easing,\n onUpdate: (t, raw) => paintFrame(t, raw >= 1),\n onComplete: () => { paintFrame(1, true); onDone(); },\n });\n}\n\n/** Staggering needs a few marks to read as a wave (and never applies to sketches). */\nfunction staggerable(model: CartesianModel): boolean {\n if (model.sketch) return false;\n if (model.spec.type === 'scatter') return true;\n return (model.x.categories?.length ?? 0) >= 3;\n}\n\nfunction paintGrowFrame(\n surface: Surface,\n model: CartesianModel,\n renderer: CartesianRenderer,\n t: number,\n staggerEase?: (t: number) => number,\n): void {\n // Marks grow from the baseline; leave the shared model clean afterwards so\n // interaction/report code always sees the fully-drawn state.\n model.entranceProgress = t;\n if (staggerEase) {\n model.entranceStagger = ENTRANCE_STAGGER;\n model.entranceEase = staggerEase;\n }\n try {\n renderer(surface, model);\n } finally {\n model.entranceProgress = undefined;\n model.entranceStagger = undefined;\n model.entranceEase = undefined;\n }\n drawTrendlines(surface, model);\n drawAnnotations(surface, model);\n}\n\n/**\n * Glowing heads that ride each line/area series' leading edge during the\n * draw-on reveal. They sit exactly on the stroke (sampled from the same curve\n * the renderer drew) and fade out before the final frame, which stays the\n * static draw.\n */\nfunction paintDrawOnHeads(ctx: CanvasRenderingContext2D, model: CartesianModel, background: string, t: number): void {\n const geometry = model.geometry;\n if (!geometry || (geometry.kind !== 'line' && geometry.kind !== 'area') || model.sketch) return;\n const fade = t < 0.72 ? 1 : Math.max(0, (1 - t) / 0.28);\n if (!(fade > 0)) return;\n const x = model.plot.x + model.plot.width * t;\n const path = line({ curve: resolveCurve((model.spec as { curve?: CurveType }).curve) });\n const strokeWidth = geometry.metrics.strokeWidth;\n const tracks =\n geometry.kind === 'line'\n ? geometry.series.map((s) => ({ color: s.series.color, alpha: s.alpha, points: s.points }))\n : geometry.bands.map((b) => ({ color: b.series.color, alpha: b.alpha, points: b.points.map((p) => ({ x: p.x, y: p.y1 })) }));\n ctx.save();\n for (const track of tracks) {\n const sampler = new PathSampler();\n path(track.points, sampler);\n const y = sampler.yAt(x);\n if (y === undefined || !Number.isFinite(y)) continue;\n const alpha = fade * track.alpha;\n const glow = strokeWidth * 5;\n const halo = ctx.createRadialGradient(x, y, 0, x, y, glow);\n halo.addColorStop(0, withAlpha(track.color, 0.45 * alpha));\n halo.addColorStop(1, withAlpha(track.color, 0));\n ctx.fillStyle = halo;\n ctx.beginPath();\n ctx.arc(x, y, glow, 0, Math.PI * 2);\n ctx.fill();\n ctx.globalAlpha = alpha;\n ctx.beginPath();\n ctx.arc(x, y, strokeWidth * 1.6, 0, Math.PI * 2);\n ctx.fillStyle = background;\n ctx.fill();\n ctx.beginPath();\n ctx.arc(x, y, strokeWidth * 1.05, 0, Math.PI * 2);\n ctx.fillStyle = track.color;\n ctx.fill();\n ctx.globalAlpha = 1;\n }\n ctx.restore();\n}\n\n/**\n * Custom-chart entrance that re-renders the visual each frame with an\n * interpolation progress (0..1) mixed into its RenderContext \u2014 the number\n * roll-up (kpi) and arc sweep (pie/gauge). `paint` clears the layers and\n * repaints; the final frame (t=1) is pixel-identical to a static draw.\n *\n * Note we do *not* paint frame 0 synchronously: the caller already rendered the\n * final state, and `animate()` schedules the first frame via rAF (which runs\n * before the browser's first paint, so the roll still starts from ~0 with no\n * flash). This keeps the synchronous DOM \u2014 and thus SSR / no-rAF / test reads \u2014\n * showing the final value rather than 0.\n */\nexport function runCustomRendererProgress(\n surface: Surface,\n renderer: CustomRenderer,\n spec: ChartSpec,\n tokens: ThemeTokens,\n size: Size,\n options: {\n anim: ResolvedEntrance;\n onDone: () => void;\n dataLength: number;\n background?: string;\n context: RenderContext;\n progressKey: 'valueProgress' | 'sweepProgress' | 'morphProgress' | 'entranceProgress';\n extraContext?: Partial<RenderContext>;\n /**\n * Paint frames on a transient view so they never reach the evidence ledger\n * (update transitions, whose static final frame was already drawn and reported).\n */\n transient?: boolean;\n /**\n * Paint the t = 0 frame synchronously, replacing the static final frame\n * before the browser can present it (update morphs start from what was on\n * screen, so showing the destination for a frame would flash).\n */\n paintInitial?: boolean;\n /** The chrome on screen when an update morph began, so axes and annotations glide too. */\n chrome?: ChromeSnapshot;\n /** An entrance: reference lines, trendlines and their labels draw in after the marks. */\n entranceChrome?: boolean;\n },\n): AnimationHandle {\n const target = options.transient ? transientSurface(surface) : surface;\n let shown = 0;\n const paint = (t: number, done = false): void => {\n // Chrome stays mid-morph / mid-entrance until the animation completes, even\n // when an overshooting easing passes 1 on the way.\n if (options.chrome) setChromeMorph(target, options.chrome, done ? 1 : Math.min(CHROME_IN_FLIGHT, t));\n if (options.entranceChrome) {\n shown = done ? 1 : Math.min(CHROME_IN_FLIGHT, Math.max(shown, t));\n setChromeEntrance(surface, done ? null : shown);\n }\n surface.overlay.replaceChildren();\n surface.marks.clear();\n target.labels.clear();\n if (!options.transient) surface.evidence.reset(size, options.dataLength, options.background ?? tokens.color.background);\n paintBackground(surface, tokens, options.background);\n renderer(target, spec, tokens, size, { ...options.context, ...options.extraContext, [options.progressKey]: t });\n };\n if (options.paintInitial) paint(0);\n return animate({ duration: options.anim.duration, easing: options.anim.easing, onUpdate: (t, raw) => paint(t, raw >= 1),\n onComplete: () => { paint(1, true); options.onDone(); } });\n}\n\n/**\n * Custom-chart entrance: a compositor-friendly opacity + slight upward rise of\n * the whole surface. Used for charts whose content is already fully painted\n * (pie/heatmap canvas, kpi/table/matrix DOM), so re-running the renderer per\n * frame isn't needed.\n */\nexport function runFadeEntrance(surface: Surface, anim: ResolvedEntrance, onDone: () => void): AnimationHandle {\n const apply = (t: number): void => {\n surface.root.style.opacity = String(t);\n const dy = (1 - t) * 8;\n surface.root.style.transform = dy > 0.02 ? `translateY(${dy.toFixed(2)}px)` : '';\n };\n apply(0);\n return animate({ duration: anim.duration, easing: anim.easing, onUpdate: apply,\n onComplete: () => { surface.root.style.opacity = ''; surface.root.style.transform = ''; onDone(); } });\n}\n\n/**\n * Update morph: repaint the marks layer each frame with geometry interpolated\n * from the outgoing frame to the incoming one. With the outgoing frame's\n * `chrome`, the axes, gridlines, tick labels, annotations and trendlines glide\n * from where they were too (the overlay text is rebuilt each frame); without it\n * they sit at the incoming frame's positions. The incoming frame has already\n * been drawn statically (so reports, SSR and test reads see the final state),\n * and the transient surface keeps tween frames out of the render-evidence\n * ledger. The last frame repaints the incoming frame itself, so it is the\n * static draw.\n */\nexport function runCartesianMorph(\n surface: Surface,\n model: CartesianModel,\n morph: GeometryMorph,\n tokens: ThemeTokens,\n background: string | undefined,\n anim: ResolvedEntrance,\n onFrame: (t: number) => void,\n onDone: () => void,\n chrome?: ChromeSnapshot,\n): AnimationHandle {\n const ctx = surface.marks.ctx;\n const bg = background ?? tokens.color.background;\n const transient = transientSurface(surface);\n const moveChrome = !!chrome && chrome.size > 0;\n const paint = (t: number, done = false): void => {\n onFrame(t);\n // Chrome stays mid-morph until the animation completes, even when an\n // overshooting easing passes 1 on the way; the final paint is the static chrome.\n setChromeMorph(transient, chrome, done ? 1 : Math.min(CHROME_IN_FLIGHT, t));\n surface.marks.clear();\n ctx.save();\n ctx.fillStyle = bg;\n ctx.fillRect(0, 0, surface.width, surface.height);\n ctx.restore();\n drawAxesUnderlay(transient, model);\n paintGeometry(transient, model, morph.at(t));\n drawTrendlines(transient, model);\n drawAnnotations(transient, model);\n if (!moveChrome) return;\n surface.overlay.replaceChildren();\n transient.labels.clear();\n drawOverlay(transient, model);\n drawAnnotationLabels(transient, model);\n drawTrendlineLabels(transient, model);\n };\n paint(0);\n return animate({ duration: anim.duration, easing: anim.easing, onUpdate: (t, raw) => paint(t, raw >= 1),\n onComplete: () => { paint(1, true); onDone(); } });\n}\n\n/**\n * Copy a canvas layer's current backing store into a detached canvas so it can\n * be composited later (used to cross-fade the previous frame on update()).\n */\nexport function snapshotLayer(layer: CanvasLayer): HTMLCanvasElement {\n const off = document.createElement('canvas');\n off.width = layer.canvas.width;\n off.height = layer.canvas.height;\n if (off.width > 0 && off.height > 0) off.getContext('2d')?.drawImage(layer.canvas, 0, 0);\n return off;\n}\n\n/**\n * Update transition: cross-fade the marks layer from the previous frame to the\n * freshly drawn one. The new frame is already live on the canvas when this runs,\n * so we snapshot it and composite `new` under `old` with `old` fading out. The\n * final frame is pixel-identical to the static (instant) draw.\n */\nexport function runUpdateCrossfade(surface: Surface, before: HTMLCanvasElement, anim: ResolvedEntrance): AnimationHandle {\n const after = snapshotLayer(surface.marks);\n const ctx = surface.marks.ctx;\n const w = surface.marks.width;\n const h = surface.marks.height;\n const paint = (t: number): void => {\n surface.marks.clear();\n ctx.save();\n ctx.globalAlpha = 1;\n ctx.drawImage(after, 0, 0, w, h);\n if (t < 1) {\n ctx.globalAlpha = 1 - t;\n ctx.drawImage(before, 0, 0, w, h);\n }\n ctx.restore();\n };\n paint(0);\n return animate({ duration: anim.duration, easing: anim.easing, onUpdate: paint, onComplete: () => paint(1) });\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -14,6 +14,12 @@ export declare class ChartRuntime {
14
14
  private interaction?;
15
15
  private entrance?;
16
16
  private updateTransition?;
17
+ private lastModel?;
18
+ private morphState?;
19
+ private pendingMorph?;
20
+ private pendingSliceMorph?;
21
+ private pendingCustomMorph?;
22
+ private pendingChrome?;
17
23
  private preview?;
18
24
  private destroyed;
19
25
  private lastValue;
@@ -55,7 +61,43 @@ export declare class ChartRuntime {
55
61
  private dispatchDebug;
56
62
  private dispatchFacet;
57
63
  private dispatchCartesian;
64
+ /**
65
+ * Start an update morph from `from` (the outgoing frame's geometry) to the
66
+ * frame just drawn statically. A no-op when the pair can't be morphed, which
67
+ * leaves update() free to fall back to its cross-fade.
68
+ */
69
+ private startMorph;
70
+ /** Update-transition timing for `spec` under the current motion environment. */
71
+ private updateMotion;
72
+ /**
73
+ * The geometry an update from `prev` to `next` should morph from — what is on
74
+ * screen right now, including a partially-played morph — or undefined when the
75
+ * transition shouldn't morph (different or non-cartesian types, sketch/facet/
76
+ * debug compositions, or motion disabled).
77
+ */
78
+ private morphSource;
58
79
  private dispatchCustom;
80
+ /**
81
+ * Custom-chart update morph: the renderer re-runs each frame with the marks
82
+ * that were on screen (`morphFrom`) and a morph progress, so bars, tiles,
83
+ * cells, nodes and links travel to the new data. The static draw above is
84
+ * the final frame; tween frames are transient, so reports stay on it.
85
+ */
86
+ private startCustomMorph;
87
+ /**
88
+ * The marks a custom chart's update from `prev` to `next` should travel from
89
+ * (including a partially-played morph), or undefined when it can't morph:
90
+ * a type change, pie (which re-balances slices instead), sketch/debug, or
91
+ * motion disabled. Renderers opt in by stashing their marks.
92
+ */
93
+ private customMorphSource;
94
+ /**
95
+ * Re-balance pie/donut slices from the ones on screen: the renderer re-runs
96
+ * each frame with a morph progress (the static draw above is the final frame).
97
+ */
98
+ private startSliceMorph;
99
+ /** The pie/donut slices an update from `prev` to `next` should re-balance from. */
100
+ private sliceMorphSource;
59
101
  private dispatchPlaceholder;
60
102
  private customContext;
61
103
  private startCustomEntrance;
@@ -1 +1 @@
1
- {"version":3,"file":"chartRuntime.d.ts","sourceRoot":"","sources":["../../src/runtime/chartRuntime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chartRuntime.d.ts","sourceRoot":"","sources":["../../src/runtime/chartRuntime.ts"],"names":[],"mappings":"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"}
@@ -48,7 +48,13 @@ import {
48
48
  specLegendParam,
49
49
  SWEEP_TYPES
50
50
  } from "./runtimeShared.js";
51
- import { runCartesianEntrance, runCustomRendererProgress, runFadeEntrance, runUpdateCrossfade, snapshotLayer } from "./chartAnimation.js";
51
+ import { runCartesianEntrance, runCartesianMorph, runCustomRendererProgress, runFadeEntrance, runUpdateCrossfade, snapshotLayer } from "./chartAnimation.js";
52
+ import { planGeometryMorph } from "./morph.js";
53
+ import { pieStateOf } from "../charts/pieState.js";
54
+ import { clearMorphFrame, morphFrameOf } from "../charts/morphFrame.js";
55
+ import { captureChrome, clearChrome, setChromeEntrance } from "../render/chromeMotion.js";
56
+ const MORPH_TYPES = /* @__PURE__ */ new Set(["bar", "line", "area", "scatter", "box"]);
57
+ const CUSTOM_MORPH_ROW_LIMIT = 5e3;
52
58
  class ChartRuntime {
53
59
  constructor(container, spec, options = {}) {
54
60
  __publicField(this, "container", container);
@@ -60,6 +66,22 @@ class ChartRuntime {
60
66
  __publicField(this, "interaction");
61
67
  __publicField(this, "entrance");
62
68
  __publicField(this, "updateTransition");
69
+ // The cartesian model behind the frame on screen; its `geometry` is where an
70
+ // update morph starts from. Cleared whenever a non-cartesian frame is drawn.
71
+ __publicField(this, "lastModel");
72
+ // The in-flight update morph and its latest eased progress, so an update that
73
+ // interrupts it morphs onward from what is actually on screen.
74
+ __publicField(this, "morphState");
75
+ // Outgoing geometry handed from update()/selection redraws to the next draw.
76
+ __publicField(this, "pendingMorph");
77
+ // Outgoing pie/donut slices handed to the next draw so slices re-balance.
78
+ __publicField(this, "pendingSliceMorph");
79
+ // Outgoing keyed marks (see charts/morphFrame) a custom renderer stashed,
80
+ // handed to the next draw so its marks travel instead of cross-fading.
81
+ __publicField(this, "pendingCustomMorph");
82
+ // The axes, annotations and trendlines on screen when an update began, so a
83
+ // morph moves them with the marks (see render/chromeMotion).
84
+ __publicField(this, "pendingChrome");
63
85
  // The nested chart instance backing the debug view's live preview (when
64
86
  // spec.debug is set). Destroyed and recreated on every draw() so it never
65
87
  // leaks observers/rAF when the overlay is cleared.
@@ -204,6 +226,8 @@ class ChartRuntime {
204
226
  this.entrance = void 0;
205
227
  this.updateTransition?.cancel();
206
228
  this.updateTransition = void 0;
229
+ this.morphState = void 0;
230
+ setChromeEntrance(this.surface, null);
207
231
  this.preview?.destroy();
208
232
  this.preview = void 0;
209
233
  }
@@ -246,6 +270,9 @@ class ChartRuntime {
246
270
  this.lastSparkline = prepared.type === "kpi" ? kpiSparklineSeries(prepared.effectiveSpec, data) : null;
247
271
  }
248
272
  dispatch(frame, prepared, valueFrom, compareFrom, sparklineFrom) {
273
+ this.lastModel = void 0;
274
+ clearMorphFrame(this.surface);
275
+ clearChrome(this.surface);
249
276
  const facet = !this.currentSpec.debug && isFaceted(prepared.effectiveSpec) ? buildFacetModels(prepared.effectiveSpec, frame.tokens, frame.size, prepared.colorDomain) : null;
250
277
  if (this.currentSpec.debug) return this.dispatchDebug(frame, prepared);
251
278
  if (facet) return this.dispatchFacet(frame, prepared, facet);
@@ -285,8 +312,7 @@ class ChartRuntime {
285
312
  drawAnnotations(this.surface, model);
286
313
  }
287
314
  drawOverlay(this.surface, model);
288
- drawAnnotationLabels(this.surface, model);
289
- drawTrendlineLabels(this.surface, model);
315
+ const lateLabels = [...drawAnnotationLabels(this.surface, model), ...drawTrendlineLabels(this.surface, model)];
290
316
  const override = cartesianInteractionBuilders[prepared.type];
291
317
  const interactionModel = override ? override(model) ?? null : buildCartesianInteraction(model);
292
318
  if (frame.anim.enabled && renderer) this.entrance = runCartesianEntrance(
@@ -297,19 +323,143 @@ class ChartRuntime {
297
323
  this.currentSpec.background,
298
324
  frame.anim,
299
325
  () => this.finishEntrance(),
300
- chartDefinition(prepared.type).entrance === "grow" ? "grow" : "wipe"
326
+ chartDefinition(prepared.type).entrance === "grow" ? "grow" : "wipe",
327
+ lateLabels
301
328
  );
329
+ this.lastModel = model;
330
+ const morphFrom = this.pendingMorph;
331
+ this.pendingMorph = void 0;
332
+ if (morphFrom && !frame.anim.enabled) this.startMorph(frame, model, morphFrom);
302
333
  return { interactionModel, reportModel: model, legendSelect };
303
334
  }
335
+ /**
336
+ * Start an update morph from `from` (the outgoing frame's geometry) to the
337
+ * frame just drawn statically. A no-op when the pair can't be morphed, which
338
+ * leaves update() free to fall back to its cross-fade.
339
+ */
340
+ startMorph(frame, model, from) {
341
+ const to = model.geometry;
342
+ const anim = this.updateMotion(this.currentSpec);
343
+ if (!to || !anim.enabled) return;
344
+ const morph = planGeometryMorph(from, to);
345
+ if (!morph) return;
346
+ const timing = morph.durationScale ? { ...anim, duration: anim.duration * morph.durationScale } : anim;
347
+ this.updateTransition = runCartesianMorph(
348
+ this.surface,
349
+ model,
350
+ morph,
351
+ frame.tokens,
352
+ this.currentSpec.background,
353
+ timing,
354
+ (t) => {
355
+ this.morphState = { morph, t };
356
+ },
357
+ () => {
358
+ this.morphState = void 0;
359
+ this.updateTransition = void 0;
360
+ this.interaction?.refresh();
361
+ },
362
+ this.pendingChrome
363
+ );
364
+ }
365
+ /** Update-transition timing for `spec` under the current motion environment. */
366
+ updateMotion(spec) {
367
+ return resolveUpdate(spec.animation, {
368
+ reducedMotion: prefersReducedMotion(),
369
+ disabled: this.options.synchronous === true || globalThis.__GRAPHEIN_DISABLE_ANIM === true
370
+ });
371
+ }
372
+ /**
373
+ * The geometry an update from `prev` to `next` should morph from — what is on
374
+ * screen right now, including a partially-played morph — or undefined when the
375
+ * transition shouldn't morph (different or non-cartesian types, sketch/facet/
376
+ * debug compositions, or motion disabled).
377
+ */
378
+ morphSource(prev, next) {
379
+ if (prev.type !== next.type || !MORPH_TYPES.has(next.type)) return void 0;
380
+ if (prev.debug || next.debug || isFaceted(prev) || isFaceted(next)) return void 0;
381
+ if (resolveSketch(prev) || resolveSketch(next)) return void 0;
382
+ if (!this.updateMotion(next).enabled) return void 0;
383
+ if (this.morphState) return this.morphState.morph.at(this.morphState.t);
384
+ return this.lastModel?.geometry;
385
+ }
304
386
  dispatchCustom(frame, prepared, valueFrom, compareFrom, sparklineFrom) {
305
387
  const renderer = customRenderers[prepared.type];
306
388
  if (!renderer) return this.dispatchPlaceholder(frame, prepared.type);
307
389
  const ctx = this.customContext(frame, prepared);
308
390
  const interactionModel = renderer(this.surface, prepared.effectiveSpec, frame.tokens, frame.size, ctx) ?? null;
391
+ const sliceFrom = this.pendingSliceMorph;
392
+ this.pendingSliceMorph = void 0;
393
+ const morphFrom = this.pendingCustomMorph;
394
+ this.pendingCustomMorph = void 0;
309
395
  if (frame.anim.enabled) this.startCustomEntrance(frame, prepared, renderer, ctx);
310
- else this.startValueTween(frame, prepared, renderer, ctx, valueFrom, compareFrom, sparklineFrom);
396
+ else if (sliceFrom && prepared.type === "pie") this.startSliceMorph(frame, prepared, renderer, ctx, sliceFrom);
397
+ else if (morphFrom !== void 0 && morphFrameOf(this.surface, prepared.type) !== void 0) {
398
+ this.startCustomMorph(frame, prepared, renderer, ctx, morphFrom);
399
+ } else this.startValueTween(frame, prepared, renderer, ctx, valueFrom, compareFrom, sparklineFrom);
311
400
  return { interactionModel };
312
401
  }
402
+ /**
403
+ * Custom-chart update morph: the renderer re-runs each frame with the marks
404
+ * that were on screen (`morphFrom`) and a morph progress, so bars, tiles,
405
+ * cells, nodes and links travel to the new data. The static draw above is
406
+ * the final frame; tween frames are transient, so reports stay on it.
407
+ */
408
+ startCustomMorph(frame, prepared, renderer, ctx, morphFrom) {
409
+ const tween = this.updateMotion(this.currentSpec);
410
+ if (!tween.enabled) return;
411
+ this.entrance = runCustomRendererProgress(this.surface, renderer, prepared.effectiveSpec, frame.tokens, frame.size, {
412
+ anim: tween,
413
+ onDone: () => this.finishEntrance(),
414
+ dataLength: prepared.filtered.length,
415
+ background: this.currentSpec.background,
416
+ context: ctx,
417
+ progressKey: "morphProgress",
418
+ extraContext: { morphFrom },
419
+ transient: true,
420
+ paintInitial: true,
421
+ chrome: this.pendingChrome
422
+ });
423
+ }
424
+ /**
425
+ * The marks a custom chart's update from `prev` to `next` should travel from
426
+ * (including a partially-played morph), or undefined when it can't morph:
427
+ * a type change, pie (which re-balances slices instead), sketch/debug, or
428
+ * motion disabled. Renderers opt in by stashing their marks.
429
+ */
430
+ customMorphSource(prev, next) {
431
+ if (prev.type !== next.type || next.type === "pie" || CARTESIAN_TYPES.has(next.type)) return void 0;
432
+ if (prev.debug || next.debug || resolveSketch(prev) || resolveSketch(next)) return void 0;
433
+ if ((prev.data?.length ?? 0) > CUSTOM_MORPH_ROW_LIMIT || (next.data?.length ?? 0) > CUSTOM_MORPH_ROW_LIMIT) return void 0;
434
+ if (!this.updateMotion(next).enabled) return void 0;
435
+ return morphFrameOf(this.surface, next.type);
436
+ }
437
+ /**
438
+ * Re-balance pie/donut slices from the ones on screen: the renderer re-runs
439
+ * each frame with a morph progress (the static draw above is the final frame).
440
+ */
441
+ startSliceMorph(frame, prepared, renderer, ctx, sliceFrom) {
442
+ const tween = this.updateMotion(this.currentSpec);
443
+ if (!tween.enabled) return;
444
+ this.entrance = runCustomRendererProgress(this.surface, renderer, prepared.effectiveSpec, frame.tokens, frame.size, {
445
+ anim: tween,
446
+ onDone: () => this.finishEntrance(),
447
+ dataLength: prepared.filtered.length,
448
+ background: this.currentSpec.background,
449
+ context: ctx,
450
+ progressKey: "morphProgress",
451
+ extraContext: { sliceFrom },
452
+ transient: true,
453
+ paintInitial: true
454
+ });
455
+ }
456
+ /** The pie/donut slices an update from `prev` to `next` should re-balance from. */
457
+ sliceMorphSource(prev, next) {
458
+ if (prev.type !== "pie" || next.type !== "pie" || prev.debug || next.debug) return void 0;
459
+ if (resolveSketch(prev) || resolveSketch(next) || !this.updateMotion(next).enabled) return void 0;
460
+ const slices = pieStateOf(this.surface);
461
+ return slices?.length ? slices : void 0;
462
+ }
313
463
  dispatchPlaceholder(frame, type) {
314
464
  drawPlaceholder(this.surface, frame.tokens, `\u201C${type}\u201D renderer not yet registered`);
315
465
  if (frame.anim.enabled) this.entrance = runFadeEntrance(this.surface, frame.anim, () => this.finishEntrance());
@@ -330,26 +480,24 @@ class ChartRuntime {
330
480
  };
331
481
  }
332
482
  startCustomEntrance(frame, prepared, renderer, ctx) {
333
- if (!COUNT_UP_TYPES.has(prepared.type) && !SWEEP_TYPES.has(prepared.type)) {
483
+ const key = COUNT_UP_TYPES.has(prepared.type) ? "valueProgress" : SWEEP_TYPES.has(prepared.type) ? "sweepProgress" : chartDefinition(prepared.type).entrance === "grow" ? "entranceProgress" : null;
484
+ if (!key) {
334
485
  this.entrance = runFadeEntrance(this.surface, frame.anim, () => this.finishEntrance());
335
486
  return;
336
487
  }
337
- const key = COUNT_UP_TYPES.has(prepared.type) ? "valueProgress" : "sweepProgress";
338
488
  this.entrance = runCustomRendererProgress(this.surface, renderer, prepared.effectiveSpec, frame.tokens, frame.size, {
339
489
  anim: frame.anim,
340
490
  onDone: () => this.finishEntrance(),
341
491
  dataLength: prepared.filtered.length,
342
492
  background: this.currentSpec.background,
343
493
  context: ctx,
344
- progressKey: key
494
+ progressKey: key,
495
+ entranceChrome: true
345
496
  });
346
497
  }
347
498
  startValueTween(frame, prepared, renderer, ctx, valueFrom, compareFrom, sparklineFrom) {
348
499
  if (valueFrom === void 0 && sparklineFrom === void 0 || !COUNT_UP_TYPES.has(prepared.type) && !SWEEP_TYPES.has(prepared.type)) return;
349
- const tween = resolveUpdate(this.currentSpec.animation, {
350
- reducedMotion: prefersReducedMotion(),
351
- disabled: this.options.synchronous === true || globalThis.__GRAPHEIN_DISABLE_ANIM === true
352
- });
500
+ const tween = this.updateMotion(this.currentSpec);
353
501
  if (!tween.enabled) return;
354
502
  const key = COUNT_UP_TYPES.has(prepared.type) ? "valueProgress" : "sweepProgress";
355
503
  this.entrance = runCustomRendererProgress(this.surface, renderer, prepared.effectiveSpec, frame.tokens, frame.size, {
@@ -403,6 +551,7 @@ class ChartRuntime {
403
551
  finishEntrance() {
404
552
  if (this.refreshReport) this.lastReport = this.refreshReport();
405
553
  signalReady(this.surface);
554
+ this.interaction?.refresh();
406
555
  if (this.pendingFontRefresh && !this.destroyed) {
407
556
  this.pendingFontRefresh = false;
408
557
  this.draw(false);
@@ -467,6 +616,9 @@ class ChartRuntime {
467
616
  this.invalidateTransforms();
468
617
  this.seedParams(next);
469
618
  const prevType = this.currentSpec.type;
619
+ const morphFrom = this.morphSource(this.currentSpec, next);
620
+ const sliceFrom = this.sliceMorphSource(this.currentSpec, next);
621
+ const customFrom = this.customMorphSource(this.currentSpec, next);
470
622
  const before = this.updateSnapshot(prevType, next);
471
623
  const prevW = this.surface.width;
472
624
  const prevH = this.surface.height;
@@ -474,29 +626,32 @@ class ChartRuntime {
474
626
  this.currentSpec = next;
475
627
  const wantValue = prevType === next.type && (COUNT_UP_TYPES.has(next.type) || SWEEP_TYPES.has(next.type)) && prev.value != null;
476
628
  const wantSparkline = prevType === next.type && next.type === "kpi" && !!prev.sparkline?.length;
477
- this.draw(
478
- false,
479
- wantValue ? prev.value ?? void 0 : void 0,
480
- wantValue ? prev.compare ?? void 0 : void 0,
481
- wantValue || wantSparkline ? prev.sparkline ?? void 0 : void 0
482
- );
483
- this.startUpdateCrossfade(before, prevW, prevH, next);
629
+ this.pendingMorph = morphFrom;
630
+ this.pendingSliceMorph = sliceFrom;
631
+ this.pendingCustomMorph = customFrom;
632
+ this.pendingChrome = captureChrome(this.surface);
633
+ try {
634
+ this.draw(
635
+ false,
636
+ wantValue ? prev.value ?? void 0 : void 0,
637
+ wantValue ? prev.compare ?? void 0 : void 0,
638
+ wantValue || wantSparkline ? prev.sparkline ?? void 0 : void 0
639
+ );
640
+ } finally {
641
+ this.pendingMorph = void 0;
642
+ this.pendingSliceMorph = void 0;
643
+ this.pendingCustomMorph = void 0;
644
+ this.pendingChrome = void 0;
645
+ }
646
+ if (!this.morphState && !this.entrance) this.startUpdateCrossfade(before, prevW, prevH, next);
484
647
  }
485
648
  updateSnapshot(prevType, next) {
486
- const anim = resolveUpdate(next.animation, {
487
- reducedMotion: prefersReducedMotion(),
488
- disabled: this.options.synchronous === true || globalThis.__GRAPHEIN_DISABLE_ANIM === true
489
- });
490
- const wantFade = anim.enabled && CANVAS_MARK_TYPES.has(prevType) && CANVAS_MARK_TYPES.has(next.type);
649
+ const wantFade = this.updateMotion(next).enabled && CANVAS_MARK_TYPES.has(prevType) && CANVAS_MARK_TYPES.has(next.type);
491
650
  return wantFade ? snapshotLayer(this.surface.marks) : void 0;
492
651
  }
493
652
  startUpdateCrossfade(before, prevW, prevH, next) {
494
653
  if (!before || this.surface.width !== prevW || this.surface.height !== prevH || this.surface.marks.canvas.width !== before.width || this.surface.marks.canvas.height !== before.height) return;
495
- const anim = resolveUpdate(next.animation, {
496
- reducedMotion: prefersReducedMotion(),
497
- disabled: this.options.synchronous === true || globalThis.__GRAPHEIN_DISABLE_ANIM === true
498
- });
499
- this.updateTransition = runUpdateCrossfade(this.surface, before, anim);
654
+ this.updateTransition = runUpdateCrossfade(this.surface, before, this.updateMotion(next));
500
655
  }
501
656
  resize() {
502
657
  if (!this.destroyed) this.draw(false);
@@ -556,7 +711,18 @@ class ChartRuntime {
556
711
  if (!this.pendingSelectionRedraw || this.destroyed) return;
557
712
  this.pendingSelectionRedraw = false;
558
713
  this.selectionRedrawQueued = false;
559
- this.draw(false);
714
+ this.pendingMorph = this.morphSource(this.currentSpec, this.currentSpec);
715
+ this.pendingSliceMorph = this.sliceMorphSource(this.currentSpec, this.currentSpec);
716
+ this.pendingCustomMorph = this.customMorphSource(this.currentSpec, this.currentSpec);
717
+ this.pendingChrome = captureChrome(this.surface);
718
+ try {
719
+ this.draw(false);
720
+ } finally {
721
+ this.pendingMorph = void 0;
722
+ this.pendingSliceMorph = void 0;
723
+ this.pendingCustomMorph = void 0;
724
+ this.pendingChrome = void 0;
725
+ }
560
726
  }
561
727
  applyExternalEdit(config) {
562
728
  if (this.destroyed) return;