minerva-design 1.4.0 → 1.6.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 (824) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +21 -21
  3. package/custom-elements.json +3072 -611
  4. package/dist/angular/fesm2022/minerva-angular.mjs +1491 -5
  5. package/dist/angular/fesm2022/minerva-angular.mjs.map +1 -1
  6. package/dist/angular/types/minerva-angular.d.ts +595 -5
  7. package/dist/charts/canvas.d.cts +4 -3
  8. package/dist/charts/canvas.d.ts +4 -3
  9. package/dist/charts/core.cjs +1 -1
  10. package/dist/charts/core.d.cts +6 -4
  11. package/dist/charts/core.d.ts +6 -4
  12. package/dist/charts/core.js +24 -16
  13. package/dist/charts/engine/axis.cjs +1 -1
  14. package/dist/charts/engine/axis.cjs.map +1 -1
  15. package/dist/charts/engine/axis.js +42 -19
  16. package/dist/charts/engine/axis.js.map +1 -1
  17. package/dist/charts/engine/canvas.cjs +1 -1
  18. package/dist/charts/engine/canvas.cjs.map +1 -1
  19. package/dist/charts/engine/canvas.js +155 -127
  20. package/dist/charts/engine/canvas.js.map +1 -1
  21. package/dist/charts/engine/chart.cjs +1 -1
  22. package/dist/charts/engine/chart.cjs.map +1 -1
  23. package/dist/charts/engine/chart.js +370 -255
  24. package/dist/charts/engine/chart.js.map +1 -1
  25. package/dist/charts/engine/color.cjs +1 -1
  26. package/dist/charts/engine/color.cjs.map +1 -1
  27. package/dist/charts/engine/color.d.cts +18 -0
  28. package/dist/charts/engine/color.d.ts +18 -0
  29. package/dist/charts/engine/color.js +48 -2
  30. package/dist/charts/engine/color.js.map +1 -1
  31. package/dist/charts/engine/controller.cjs +2 -2
  32. package/dist/charts/engine/controller.cjs.map +1 -1
  33. package/dist/charts/engine/controller.d.cts +34 -1
  34. package/dist/charts/engine/controller.d.ts +34 -1
  35. package/dist/charts/engine/controller.js +318 -273
  36. package/dist/charts/engine/controller.js.map +1 -1
  37. package/dist/charts/engine/data.cjs +1 -1
  38. package/dist/charts/engine/data.cjs.map +1 -1
  39. package/dist/charts/engine/data.d.cts +3 -1
  40. package/dist/charts/engine/data.d.ts +3 -1
  41. package/dist/charts/engine/data.js +6 -4
  42. package/dist/charts/engine/data.js.map +1 -1
  43. package/dist/charts/engine/defaults.cjs +2 -0
  44. package/dist/charts/engine/defaults.cjs.map +1 -0
  45. package/dist/charts/engine/defaults.d.cts +20 -0
  46. package/dist/charts/engine/defaults.d.ts +20 -0
  47. package/dist/charts/engine/defaults.js +35 -0
  48. package/dist/charts/engine/defaults.js.map +1 -0
  49. package/dist/charts/engine/format.cjs +1 -1
  50. package/dist/charts/engine/format.cjs.map +1 -1
  51. package/dist/charts/engine/format.d.cts +6 -0
  52. package/dist/charts/engine/format.d.ts +6 -0
  53. package/dist/charts/engine/format.js +15 -2
  54. package/dist/charts/engine/format.js.map +1 -1
  55. package/dist/charts/engine/graph/chart.cjs +2 -0
  56. package/dist/charts/engine/graph/chart.cjs.map +1 -0
  57. package/dist/charts/engine/graph/chart.d.cts +3 -0
  58. package/dist/charts/engine/graph/chart.d.ts +3 -0
  59. package/dist/charts/engine/graph/chart.js +1708 -0
  60. package/dist/charts/engine/graph/chart.js.map +1 -0
  61. package/dist/charts/engine/graph/circular.cjs +2 -0
  62. package/dist/charts/engine/graph/circular.cjs.map +1 -0
  63. package/dist/charts/engine/graph/circular.d.cts +16 -0
  64. package/dist/charts/engine/graph/circular.d.ts +16 -0
  65. package/dist/charts/engine/graph/circular.js +62 -0
  66. package/dist/charts/engine/graph/circular.js.map +1 -0
  67. package/dist/charts/engine/graph/dag.cjs +2 -0
  68. package/dist/charts/engine/graph/dag.cjs.map +1 -0
  69. package/dist/charts/engine/graph/dag.d.cts +34 -0
  70. package/dist/charts/engine/graph/dag.d.ts +34 -0
  71. package/dist/charts/engine/graph/dag.js +339 -0
  72. package/dist/charts/engine/graph/dag.js.map +1 -0
  73. package/dist/charts/engine/graph/dom.cjs +2 -0
  74. package/dist/charts/engine/graph/dom.cjs.map +1 -0
  75. package/dist/charts/engine/graph/dom.d.cts +23 -0
  76. package/dist/charts/engine/graph/dom.d.ts +23 -0
  77. package/dist/charts/engine/graph/dom.js +158 -0
  78. package/dist/charts/engine/graph/dom.js.map +1 -0
  79. package/dist/charts/engine/graph/force.cjs +2 -0
  80. package/dist/charts/engine/graph/force.cjs.map +1 -0
  81. package/dist/charts/engine/graph/force.d.cts +76 -0
  82. package/dist/charts/engine/graph/force.d.ts +76 -0
  83. package/dist/charts/engine/graph/force.js +423 -0
  84. package/dist/charts/engine/graph/force.js.map +1 -0
  85. package/dist/charts/engine/graph/geometry.cjs +2 -0
  86. package/dist/charts/engine/graph/geometry.cjs.map +1 -0
  87. package/dist/charts/engine/graph/geometry.d.cts +50 -0
  88. package/dist/charts/engine/graph/geometry.d.ts +50 -0
  89. package/dist/charts/engine/graph/geometry.js +197 -0
  90. package/dist/charts/engine/graph/geometry.js.map +1 -0
  91. package/dist/charts/engine/graph/index.cjs +1 -0
  92. package/dist/charts/engine/graph/index.d.cts +6 -0
  93. package/dist/charts/engine/graph/index.d.ts +6 -0
  94. package/dist/charts/engine/graph/index.js +6 -0
  95. package/dist/charts/engine/graph/labels.cjs +2 -0
  96. package/dist/charts/engine/graph/labels.cjs.map +1 -0
  97. package/dist/charts/engine/graph/labels.d.cts +12 -0
  98. package/dist/charts/engine/graph/labels.d.ts +12 -0
  99. package/dist/charts/engine/graph/labels.js +128 -0
  100. package/dist/charts/engine/graph/labels.js.map +1 -0
  101. package/dist/charts/engine/graph/model.cjs +2 -0
  102. package/dist/charts/engine/graph/model.cjs.map +1 -0
  103. package/dist/charts/engine/graph/model.d.cts +52 -0
  104. package/dist/charts/engine/graph/model.d.ts +52 -0
  105. package/dist/charts/engine/graph/model.js +108 -0
  106. package/dist/charts/engine/graph/model.js.map +1 -0
  107. package/dist/charts/engine/graph/sizing.cjs +2 -0
  108. package/dist/charts/engine/graph/sizing.cjs.map +1 -0
  109. package/dist/charts/engine/graph/sizing.d.cts +33 -0
  110. package/dist/charts/engine/graph/sizing.d.ts +33 -0
  111. package/dist/charts/engine/graph/sizing.js +60 -0
  112. package/dist/charts/engine/graph/sizing.js.map +1 -0
  113. package/dist/charts/engine/graph/tree.cjs +2 -0
  114. package/dist/charts/engine/graph/tree.cjs.map +1 -0
  115. package/dist/charts/engine/graph/tree.d.cts +30 -0
  116. package/dist/charts/engine/graph/tree.d.ts +30 -0
  117. package/dist/charts/engine/graph/tree.js +218 -0
  118. package/dist/charts/engine/graph/tree.js.map +1 -0
  119. package/dist/charts/engine/graph/types.d.cts +640 -0
  120. package/dist/charts/engine/graph/types.d.ts +640 -0
  121. package/dist/charts/engine/graph/worker.cjs +52 -0
  122. package/dist/charts/engine/graph/worker.cjs.map +1 -0
  123. package/dist/charts/engine/graph/worker.d.cts +36 -0
  124. package/dist/charts/engine/graph/worker.d.ts +36 -0
  125. package/dist/charts/engine/graph/worker.js +135 -0
  126. package/dist/charts/engine/graph/worker.js.map +1 -0
  127. package/dist/charts/engine/items.cjs +1 -1
  128. package/dist/charts/engine/items.cjs.map +1 -1
  129. package/dist/charts/engine/items.d.cts +15 -2
  130. package/dist/charts/engine/items.d.ts +15 -2
  131. package/dist/charts/engine/items.js +131 -112
  132. package/dist/charts/engine/items.js.map +1 -1
  133. package/dist/charts/engine/labels.cjs +1 -1
  134. package/dist/charts/engine/labels.cjs.map +1 -1
  135. package/dist/charts/engine/labels.d.cts +17 -0
  136. package/dist/charts/engine/labels.d.ts +17 -0
  137. package/dist/charts/engine/labels.js +28 -4
  138. package/dist/charts/engine/labels.js.map +1 -1
  139. package/dist/charts/engine/layout.cjs +1 -1
  140. package/dist/charts/engine/layout.cjs.map +1 -1
  141. package/dist/charts/engine/layout.d.cts +9 -0
  142. package/dist/charts/engine/layout.d.ts +9 -0
  143. package/dist/charts/engine/layout.js +11 -2
  144. package/dist/charts/engine/layout.js.map +1 -1
  145. package/dist/charts/engine/model.cjs +1 -1
  146. package/dist/charts/engine/model.cjs.map +1 -1
  147. package/dist/charts/engine/model.d.cts +73 -3
  148. package/dist/charts/engine/model.d.ts +73 -3
  149. package/dist/charts/engine/model.js +258 -154
  150. package/dist/charts/engine/model.js.map +1 -1
  151. package/dist/charts/engine/orderbook/field.cjs +37 -0
  152. package/dist/charts/engine/orderbook/field.cjs.map +1 -0
  153. package/dist/charts/engine/orderbook/field.d.cts +92 -0
  154. package/dist/charts/engine/orderbook/field.d.ts +92 -0
  155. package/dist/charts/engine/orderbook/field.js +297 -0
  156. package/dist/charts/engine/orderbook/field.js.map +1 -0
  157. package/dist/charts/engine/orderbook/format.cjs +1 -1
  158. package/dist/charts/engine/orderbook/format.cjs.map +1 -1
  159. package/dist/charts/engine/orderbook/format.d.cts +3 -2
  160. package/dist/charts/engine/orderbook/format.d.ts +3 -2
  161. package/dist/charts/engine/orderbook/format.js +5 -5
  162. package/dist/charts/engine/orderbook/format.js.map +1 -1
  163. package/dist/charts/engine/orderbook/heatmap.cjs +1 -1
  164. package/dist/charts/engine/orderbook/heatmap.cjs.map +1 -1
  165. package/dist/charts/engine/orderbook/heatmap.js +566 -475
  166. package/dist/charts/engine/orderbook/heatmap.js.map +1 -1
  167. package/dist/charts/engine/orderbook/host.cjs +1 -1
  168. package/dist/charts/engine/orderbook/host.cjs.map +1 -1
  169. package/dist/charts/engine/orderbook/host.d.cts +8 -1
  170. package/dist/charts/engine/orderbook/host.d.ts +8 -1
  171. package/dist/charts/engine/orderbook/host.js +27 -5
  172. package/dist/charts/engine/orderbook/host.js.map +1 -1
  173. package/dist/charts/engine/orderbook/ladder.cjs +1 -1
  174. package/dist/charts/engine/orderbook/ladder.cjs.map +1 -1
  175. package/dist/charts/engine/orderbook/ladder.js +1 -1
  176. package/dist/charts/engine/orderbook/ladder.js.map +1 -1
  177. package/dist/charts/engine/orderbook/layout.cjs +2 -0
  178. package/dist/charts/engine/orderbook/layout.cjs.map +1 -0
  179. package/dist/charts/engine/orderbook/layout.d.cts +42 -0
  180. package/dist/charts/engine/orderbook/layout.d.ts +42 -0
  181. package/dist/charts/engine/orderbook/layout.js +76 -0
  182. package/dist/charts/engine/orderbook/layout.js.map +1 -0
  183. package/dist/charts/engine/orderbook/tape.cjs +1 -1
  184. package/dist/charts/engine/orderbook/tape.cjs.map +1 -1
  185. package/dist/charts/engine/orderbook/tape.js +4 -4
  186. package/dist/charts/engine/orderbook/tape.js.map +1 -1
  187. package/dist/charts/engine/orderbook/types.d.cts +27 -3
  188. package/dist/charts/engine/orderbook/types.d.ts +27 -3
  189. package/dist/charts/engine/overlay.cjs +1 -1
  190. package/dist/charts/engine/overlay.cjs.map +1 -1
  191. package/dist/charts/engine/overlay.d.cts +27 -0
  192. package/dist/charts/engine/overlay.d.ts +27 -0
  193. package/dist/charts/engine/overlay.js +34 -12
  194. package/dist/charts/engine/overlay.js.map +1 -1
  195. package/dist/charts/engine/presets.cjs +2 -2
  196. package/dist/charts/engine/presets.cjs.map +1 -1
  197. package/dist/charts/engine/presets.d.cts +35 -3
  198. package/dist/charts/engine/presets.d.ts +35 -3
  199. package/dist/charts/engine/presets.js +121 -101
  200. package/dist/charts/engine/presets.js.map +1 -1
  201. package/dist/charts/engine/renderers/canvas2d.cjs +1 -1
  202. package/dist/charts/engine/renderers/canvas2d.cjs.map +1 -1
  203. package/dist/charts/engine/renderers/canvas2d.js +13 -9
  204. package/dist/charts/engine/renderers/canvas2d.js.map +1 -1
  205. package/dist/charts/engine/renderers/detect.cjs +1 -1
  206. package/dist/charts/engine/renderers/detect.cjs.map +1 -1
  207. package/dist/charts/engine/renderers/detect.d.cts +2 -1
  208. package/dist/charts/engine/renderers/detect.d.ts +2 -1
  209. package/dist/charts/engine/renderers/detect.js +23 -21
  210. package/dist/charts/engine/renderers/detect.js.map +1 -1
  211. package/dist/charts/engine/renderers/follow.cjs +2 -0
  212. package/dist/charts/engine/renderers/follow.cjs.map +1 -0
  213. package/dist/charts/engine/renderers/follow.d.cts +8 -0
  214. package/dist/charts/engine/renderers/follow.d.ts +8 -0
  215. package/dist/charts/engine/renderers/follow.js +10 -0
  216. package/dist/charts/engine/renderers/follow.js.map +1 -0
  217. package/dist/charts/engine/renderers/gl-budget.cjs +2 -0
  218. package/dist/charts/engine/renderers/gl-budget.cjs.map +1 -0
  219. package/dist/charts/engine/renderers/gl-budget.d.cts +32 -0
  220. package/dist/charts/engine/renderers/gl-budget.d.ts +32 -0
  221. package/dist/charts/engine/renderers/gl-budget.js +95 -0
  222. package/dist/charts/engine/renderers/gl-budget.js.map +1 -0
  223. package/dist/charts/engine/renderers/gl.cjs +1 -1
  224. package/dist/charts/engine/renderers/gl.cjs.map +1 -1
  225. package/dist/charts/engine/renderers/gl.js +1 -1
  226. package/dist/charts/engine/renderers/gl.js.map +1 -1
  227. package/dist/charts/engine/renderers/shaders.cjs +9 -6
  228. package/dist/charts/engine/renderers/shaders.cjs.map +1 -1
  229. package/dist/charts/engine/renderers/shaders.d.cts +1 -1
  230. package/dist/charts/engine/renderers/shaders.d.ts +1 -1
  231. package/dist/charts/engine/renderers/shaders.js +9 -6
  232. package/dist/charts/engine/renderers/shaders.js.map +1 -1
  233. package/dist/charts/engine/renderers/types.cjs.map +1 -1
  234. package/dist/charts/engine/renderers/types.d.cts +2 -0
  235. package/dist/charts/engine/renderers/types.d.ts +2 -0
  236. package/dist/charts/engine/renderers/types.js.map +1 -1
  237. package/dist/charts/engine/renderers/webgl.cjs +1 -1
  238. package/dist/charts/engine/renderers/webgl.cjs.map +1 -1
  239. package/dist/charts/engine/renderers/webgl.js +85 -64
  240. package/dist/charts/engine/renderers/webgl.js.map +1 -1
  241. package/dist/charts/engine/renderers/webgl2.cjs +1 -1
  242. package/dist/charts/engine/renderers/webgl2.cjs.map +1 -1
  243. package/dist/charts/engine/renderers/webgl2.js +72 -58
  244. package/dist/charts/engine/renderers/webgl2.js.map +1 -1
  245. package/dist/charts/engine/renderers/webgpu.cjs +1 -1
  246. package/dist/charts/engine/renderers/webgpu.cjs.map +1 -1
  247. package/dist/charts/engine/renderers/webgpu.js +1 -1
  248. package/dist/charts/engine/renderers/webgpu.js.map +1 -1
  249. package/dist/charts/engine/scene.cjs +1 -1
  250. package/dist/charts/engine/scene.cjs.map +1 -1
  251. package/dist/charts/engine/scene.d.cts +104 -4
  252. package/dist/charts/engine/scene.d.ts +104 -4
  253. package/dist/charts/engine/scene.js +412 -193
  254. package/dist/charts/engine/scene.js.map +1 -1
  255. package/dist/charts/engine/shapes/bullet.cjs +1 -1
  256. package/dist/charts/engine/shapes/bullet.cjs.map +1 -1
  257. package/dist/charts/engine/shapes/bullet.js +110 -110
  258. package/dist/charts/engine/shapes/bullet.js.map +1 -1
  259. package/dist/charts/engine/shapes/chart.cjs +1 -1
  260. package/dist/charts/engine/shapes/chart.cjs.map +1 -1
  261. package/dist/charts/engine/shapes/chart.js +4 -1
  262. package/dist/charts/engine/shapes/chart.js.map +1 -1
  263. package/dist/charts/engine/shapes/chord.cjs +2 -0
  264. package/dist/charts/engine/shapes/chord.cjs.map +1 -0
  265. package/dist/charts/engine/shapes/chord.d.cts +18 -0
  266. package/dist/charts/engine/shapes/chord.d.ts +18 -0
  267. package/dist/charts/engine/shapes/chord.js +419 -0
  268. package/dist/charts/engine/shapes/chord.js.map +1 -0
  269. package/dist/charts/engine/shapes/draw.cjs +1 -1
  270. package/dist/charts/engine/shapes/draw.cjs.map +1 -1
  271. package/dist/charts/engine/shapes/draw.d.cts +5 -1
  272. package/dist/charts/engine/shapes/draw.d.ts +5 -1
  273. package/dist/charts/engine/shapes/draw.js +47 -17
  274. package/dist/charts/engine/shapes/draw.js.map +1 -1
  275. package/dist/charts/engine/shapes/hit.cjs +1 -1
  276. package/dist/charts/engine/shapes/hit.cjs.map +1 -1
  277. package/dist/charts/engine/shapes/hit.d.cts +3 -1
  278. package/dist/charts/engine/shapes/hit.d.ts +3 -1
  279. package/dist/charts/engine/shapes/hit.js +75 -46
  280. package/dist/charts/engine/shapes/hit.js.map +1 -1
  281. package/dist/charts/engine/shapes/index.d.cts +3 -2
  282. package/dist/charts/engine/shapes/index.d.ts +3 -2
  283. package/dist/charts/engine/shapes/labels.cjs +1 -1
  284. package/dist/charts/engine/shapes/labels.cjs.map +1 -1
  285. package/dist/charts/engine/shapes/labels.js +12 -4
  286. package/dist/charts/engine/shapes/labels.js.map +1 -1
  287. package/dist/charts/engine/shapes/layout.cjs +2 -2
  288. package/dist/charts/engine/shapes/layout.cjs.map +1 -1
  289. package/dist/charts/engine/shapes/layout.d.cts +3 -1
  290. package/dist/charts/engine/shapes/layout.d.ts +3 -1
  291. package/dist/charts/engine/shapes/layout.js +106 -78
  292. package/dist/charts/engine/shapes/layout.js.map +1 -1
  293. package/dist/charts/engine/shapes/scene.cjs +1 -1
  294. package/dist/charts/engine/shapes/scene.cjs.map +1 -1
  295. package/dist/charts/engine/shapes/scene.d.cts +33 -3
  296. package/dist/charts/engine/shapes/scene.d.ts +33 -3
  297. package/dist/charts/engine/shapes/scene.js +62 -19
  298. package/dist/charts/engine/shapes/scene.js.map +1 -1
  299. package/dist/charts/engine/shapes/types.d.cts +121 -8
  300. package/dist/charts/engine/shapes/types.d.ts +121 -8
  301. package/dist/charts/engine/signature.cjs +1 -1
  302. package/dist/charts/engine/signature.cjs.map +1 -1
  303. package/dist/charts/engine/signature.js +1 -1
  304. package/dist/charts/engine/signature.js.map +1 -1
  305. package/dist/charts/engine/three-d/canvas2d.cjs +1 -1
  306. package/dist/charts/engine/three-d/canvas2d.cjs.map +1 -1
  307. package/dist/charts/engine/three-d/canvas2d.d.cts +41 -3
  308. package/dist/charts/engine/three-d/canvas2d.d.ts +41 -3
  309. package/dist/charts/engine/three-d/canvas2d.js +166 -67
  310. package/dist/charts/engine/three-d/canvas2d.js.map +1 -1
  311. package/dist/charts/engine/three-d/chart.cjs +1 -1
  312. package/dist/charts/engine/three-d/chart.cjs.map +1 -1
  313. package/dist/charts/engine/three-d/chart.js +219 -215
  314. package/dist/charts/engine/three-d/chart.js.map +1 -1
  315. package/dist/charts/engine/three-d/detect.cjs +1 -1
  316. package/dist/charts/engine/three-d/detect.cjs.map +1 -1
  317. package/dist/charts/engine/three-d/detect.d.cts +3 -2
  318. package/dist/charts/engine/three-d/detect.d.ts +3 -2
  319. package/dist/charts/engine/three-d/detect.js +22 -20
  320. package/dist/charts/engine/three-d/detect.js.map +1 -1
  321. package/dist/charts/engine/three-d/geometry.cjs +1 -1
  322. package/dist/charts/engine/three-d/geometry.cjs.map +1 -1
  323. package/dist/charts/engine/three-d/geometry.d.cts +6 -0
  324. package/dist/charts/engine/three-d/geometry.d.ts +6 -0
  325. package/dist/charts/engine/three-d/geometry.js +106 -90
  326. package/dist/charts/engine/three-d/geometry.js.map +1 -1
  327. package/dist/charts/engine/three-d/model.cjs +1 -1
  328. package/dist/charts/engine/three-d/model.cjs.map +1 -1
  329. package/dist/charts/engine/three-d/model.d.cts +2 -0
  330. package/dist/charts/engine/three-d/model.d.ts +2 -0
  331. package/dist/charts/engine/three-d/model.js +2 -0
  332. package/dist/charts/engine/three-d/model.js.map +1 -1
  333. package/dist/charts/engine/three-d/oit.cjs +109 -0
  334. package/dist/charts/engine/three-d/oit.cjs.map +1 -0
  335. package/dist/charts/engine/three-d/oit.d.cts +34 -0
  336. package/dist/charts/engine/three-d/oit.d.ts +34 -0
  337. package/dist/charts/engine/three-d/oit.js +111 -0
  338. package/dist/charts/engine/three-d/oit.js.map +1 -0
  339. package/dist/charts/engine/three-d/overlay.cjs +1 -1
  340. package/dist/charts/engine/three-d/overlay.cjs.map +1 -1
  341. package/dist/charts/engine/three-d/overlay.js +43 -36
  342. package/dist/charts/engine/three-d/overlay.js.map +1 -1
  343. package/dist/charts/engine/three-d/render-types.cjs +1 -1
  344. package/dist/charts/engine/three-d/render-types.cjs.map +1 -1
  345. package/dist/charts/engine/three-d/render-types.d.cts +37 -3
  346. package/dist/charts/engine/three-d/render-types.d.ts +37 -3
  347. package/dist/charts/engine/three-d/render-types.js +6 -10
  348. package/dist/charts/engine/three-d/render-types.js.map +1 -1
  349. package/dist/charts/engine/three-d/shaders.cjs +109 -48
  350. package/dist/charts/engine/three-d/shaders.cjs.map +1 -1
  351. package/dist/charts/engine/three-d/shaders.d.cts +12 -5
  352. package/dist/charts/engine/three-d/shaders.d.ts +12 -5
  353. package/dist/charts/engine/three-d/shaders.js +118 -55
  354. package/dist/charts/engine/three-d/shaders.js.map +1 -1
  355. package/dist/charts/engine/three-d/sort.cjs +1 -1
  356. package/dist/charts/engine/three-d/sort.cjs.map +1 -1
  357. package/dist/charts/engine/three-d/sort.d.cts +18 -5
  358. package/dist/charts/engine/three-d/sort.d.ts +18 -5
  359. package/dist/charts/engine/three-d/sort.js +129 -43
  360. package/dist/charts/engine/three-d/sort.js.map +1 -1
  361. package/dist/charts/engine/three-d/types.d.cts +36 -0
  362. package/dist/charts/engine/three-d/types.d.ts +36 -0
  363. package/dist/charts/engine/three-d/webgl.cjs +1 -1
  364. package/dist/charts/engine/three-d/webgl.cjs.map +1 -1
  365. package/dist/charts/engine/three-d/webgl.d.cts +9 -0
  366. package/dist/charts/engine/three-d/webgl.d.ts +9 -0
  367. package/dist/charts/engine/three-d/webgl.js +199 -74
  368. package/dist/charts/engine/three-d/webgl.js.map +1 -1
  369. package/dist/charts/engine/three-d/webgpu.cjs +1 -1
  370. package/dist/charts/engine/three-d/webgpu.cjs.map +1 -1
  371. package/dist/charts/engine/three-d/webgpu.js +231 -94
  372. package/dist/charts/engine/three-d/webgpu.js.map +1 -1
  373. package/dist/charts/engine/trading/chart.cjs +1 -1
  374. package/dist/charts/engine/trading/chart.cjs.map +1 -1
  375. package/dist/charts/engine/trading/chart.d.cts +10 -1
  376. package/dist/charts/engine/trading/chart.d.ts +10 -1
  377. package/dist/charts/engine/trading/chart.js +1677 -813
  378. package/dist/charts/engine/trading/chart.js.map +1 -1
  379. package/dist/charts/engine/trading/drawings.cjs +2 -1
  380. package/dist/charts/engine/trading/drawings.cjs.map +1 -1
  381. package/dist/charts/engine/trading/drawings.d.cts +53 -9
  382. package/dist/charts/engine/trading/drawings.d.ts +53 -9
  383. package/dist/charts/engine/trading/drawings.js +346 -71
  384. package/dist/charts/engine/trading/drawings.js.map +1 -1
  385. package/dist/charts/engine/trading/format.cjs +1 -1
  386. package/dist/charts/engine/trading/format.cjs.map +1 -1
  387. package/dist/charts/engine/trading/format.d.cts +19 -0
  388. package/dist/charts/engine/trading/format.d.ts +19 -0
  389. package/dist/charts/engine/trading/format.js +65 -21
  390. package/dist/charts/engine/trading/format.js.map +1 -1
  391. package/dist/charts/engine/trading/geometry.cjs +1 -1
  392. package/dist/charts/engine/trading/geometry.cjs.map +1 -1
  393. package/dist/charts/engine/trading/geometry.d.cts +16 -0
  394. package/dist/charts/engine/trading/geometry.d.ts +16 -0
  395. package/dist/charts/engine/trading/geometry.js +19 -4
  396. package/dist/charts/engine/trading/geometry.js.map +1 -1
  397. package/dist/charts/engine/trading/index.cjs +1 -1
  398. package/dist/charts/engine/trading/index.d.cts +2 -1
  399. package/dist/charts/engine/trading/index.d.ts +2 -1
  400. package/dist/charts/engine/trading/index.js +4 -3
  401. package/dist/charts/engine/trading/indicators.cjs +1 -1
  402. package/dist/charts/engine/trading/indicators.cjs.map +1 -1
  403. package/dist/charts/engine/trading/indicators.d.cts +180 -10
  404. package/dist/charts/engine/trading/indicators.d.ts +180 -10
  405. package/dist/charts/engine/trading/indicators.js +449 -173
  406. package/dist/charts/engine/trading/indicators.js.map +1 -1
  407. package/dist/charts/engine/trading/labels.cjs +1 -1
  408. package/dist/charts/engine/trading/labels.cjs.map +1 -1
  409. package/dist/charts/engine/trading/labels.js +104 -4
  410. package/dist/charts/engine/trading/labels.js.map +1 -1
  411. package/dist/charts/engine/trading/store.cjs +1 -1
  412. package/dist/charts/engine/trading/store.cjs.map +1 -1
  413. package/dist/charts/engine/trading/store.d.cts +21 -0
  414. package/dist/charts/engine/trading/store.d.ts +21 -0
  415. package/dist/charts/engine/trading/store.js +22 -1
  416. package/dist/charts/engine/trading/store.js.map +1 -1
  417. package/dist/charts/engine/trading/studies.cjs +1 -1
  418. package/dist/charts/engine/trading/studies.cjs.map +1 -1
  419. package/dist/charts/engine/trading/studies.d.cts +49 -8
  420. package/dist/charts/engine/trading/studies.d.ts +49 -8
  421. package/dist/charts/engine/trading/studies.js +352 -93
  422. package/dist/charts/engine/trading/studies.js.map +1 -1
  423. package/dist/charts/engine/trading/sync.cjs +2 -0
  424. package/dist/charts/engine/trading/sync.cjs.map +1 -0
  425. package/dist/charts/engine/trading/sync.d.cts +8 -0
  426. package/dist/charts/engine/trading/sync.d.ts +8 -0
  427. package/dist/charts/engine/trading/sync.js +25 -0
  428. package/dist/charts/engine/trading/sync.js.map +1 -0
  429. package/dist/charts/engine/trading/types.d.cts +514 -16
  430. package/dist/charts/engine/trading/types.d.ts +514 -16
  431. package/dist/charts/engine/types.d.cts +106 -11
  432. package/dist/charts/engine/types.d.ts +106 -11
  433. package/dist/charts/index.cjs +1 -1
  434. package/dist/charts/index.d.cts +3 -2
  435. package/dist/charts/index.d.ts +3 -2
  436. package/dist/charts/index.js +30 -22
  437. package/dist/charts/react/charts.cjs +1 -1
  438. package/dist/charts/react/charts.cjs.map +1 -1
  439. package/dist/charts/react/charts.js +51 -34
  440. package/dist/charts/react/charts.js.map +1 -1
  441. package/dist/charts/react/graph.cjs +2 -0
  442. package/dist/charts/react/graph.cjs.map +1 -0
  443. package/dist/charts/react/graph.d.cts +219 -0
  444. package/dist/charts/react/graph.d.ts +219 -0
  445. package/dist/charts/react/graph.js +160 -0
  446. package/dist/charts/react/graph.js.map +1 -0
  447. package/dist/charts/react/orderbook.cjs +1 -1
  448. package/dist/charts/react/orderbook.cjs.map +1 -1
  449. package/dist/charts/react/orderbook.d.cts +3 -1
  450. package/dist/charts/react/orderbook.d.ts +3 -1
  451. package/dist/charts/react/orderbook.js +1 -0
  452. package/dist/charts/react/orderbook.js.map +1 -1
  453. package/dist/charts/react/shapes.cjs +1 -1
  454. package/dist/charts/react/shapes.cjs.map +1 -1
  455. package/dist/charts/react/shapes.d.cts +88 -4
  456. package/dist/charts/react/shapes.d.ts +88 -4
  457. package/dist/charts/react/shapes.js +55 -12
  458. package/dist/charts/react/shapes.js.map +1 -1
  459. package/dist/charts/react/three-d.cjs +1 -1
  460. package/dist/charts/react/three-d.cjs.map +1 -1
  461. package/dist/charts/react/three-d.d.cts +7 -0
  462. package/dist/charts/react/three-d.d.ts +7 -0
  463. package/dist/charts/react/three-d.js +14 -13
  464. package/dist/charts/react/three-d.js.map +1 -1
  465. package/dist/charts/react/trading.cjs +1 -1
  466. package/dist/charts/react/trading.cjs.map +1 -1
  467. package/dist/charts/react/trading.d.cts +54 -2
  468. package/dist/charts/react/trading.d.ts +54 -2
  469. package/dist/charts/react/trading.js +68 -37
  470. package/dist/charts/react/trading.js.map +1 -1
  471. package/dist/charts/react/types.d.cts +11 -0
  472. package/dist/charts/react/types.d.ts +11 -0
  473. package/dist/core/contracts.cjs +1 -1
  474. package/dist/core/contracts.cjs.map +1 -1
  475. package/dist/core/contracts.js +1 -1
  476. package/dist/core/contracts.js.map +1 -1
  477. package/dist/native/charts/src/canvas.cjs +1 -1
  478. package/dist/native/charts/src/canvas.js +5 -4
  479. package/dist/native/charts/src/engine/axis.cjs +1 -1
  480. package/dist/native/charts/src/engine/axis.cjs.map +1 -1
  481. package/dist/native/charts/src/engine/axis.js +42 -19
  482. package/dist/native/charts/src/engine/axis.js.map +1 -1
  483. package/dist/native/charts/src/engine/color.cjs +1 -1
  484. package/dist/native/charts/src/engine/color.cjs.map +1 -1
  485. package/dist/native/charts/src/engine/color.js +47 -5
  486. package/dist/native/charts/src/engine/color.js.map +1 -1
  487. package/dist/native/charts/src/engine/controller.cjs +2 -2
  488. package/dist/native/charts/src/engine/controller.cjs.map +1 -1
  489. package/dist/native/charts/src/engine/controller.js +296 -251
  490. package/dist/native/charts/src/engine/controller.js.map +1 -1
  491. package/dist/native/charts/src/engine/data.cjs +1 -1
  492. package/dist/native/charts/src/engine/data.cjs.map +1 -1
  493. package/dist/native/charts/src/engine/data.js +6 -4
  494. package/dist/native/charts/src/engine/data.js.map +1 -1
  495. package/dist/native/charts/src/engine/format.cjs +1 -1
  496. package/dist/native/charts/src/engine/format.cjs.map +1 -1
  497. package/dist/native/charts/src/engine/format.js +15 -2
  498. package/dist/native/charts/src/engine/format.js.map +1 -1
  499. package/dist/native/charts/src/engine/labels.cjs +1 -1
  500. package/dist/native/charts/src/engine/labels.cjs.map +1 -1
  501. package/dist/native/charts/src/engine/labels.js +42 -5
  502. package/dist/native/charts/src/engine/labels.js.map +1 -1
  503. package/dist/native/charts/src/engine/layout.cjs +1 -1
  504. package/dist/native/charts/src/engine/layout.cjs.map +1 -1
  505. package/dist/native/charts/src/engine/layout.js +11 -2
  506. package/dist/native/charts/src/engine/layout.js.map +1 -1
  507. package/dist/native/charts/src/engine/model.cjs +1 -1
  508. package/dist/native/charts/src/engine/model.cjs.map +1 -1
  509. package/dist/native/charts/src/engine/model.js +278 -174
  510. package/dist/native/charts/src/engine/model.js.map +1 -1
  511. package/dist/native/charts/src/engine/overlay.cjs.map +1 -1
  512. package/dist/native/charts/src/engine/overlay.js.map +1 -1
  513. package/dist/native/charts/src/engine/presets.cjs +2 -2
  514. package/dist/native/charts/src/engine/presets.cjs.map +1 -1
  515. package/dist/native/charts/src/engine/presets.js +110 -90
  516. package/dist/native/charts/src/engine/presets.js.map +1 -1
  517. package/dist/native/charts/src/engine/scene.cjs +1 -1
  518. package/dist/native/charts/src/engine/scene.cjs.map +1 -1
  519. package/dist/native/charts/src/engine/scene.js +421 -202
  520. package/dist/native/charts/src/engine/scene.js.map +1 -1
  521. package/dist/native/charts/src/engine/shapes/bullet.cjs +1 -1
  522. package/dist/native/charts/src/engine/shapes/bullet.cjs.map +1 -1
  523. package/dist/native/charts/src/engine/shapes/bullet.js +110 -110
  524. package/dist/native/charts/src/engine/shapes/bullet.js.map +1 -1
  525. package/dist/native/charts/src/engine/shapes/calendar.cjs +1 -1
  526. package/dist/native/charts/src/engine/shapes/calendar.cjs.map +1 -1
  527. package/dist/native/charts/src/engine/shapes/calendar.js +21 -16
  528. package/dist/native/charts/src/engine/shapes/calendar.js.map +1 -1
  529. package/dist/native/charts/src/engine/shapes/chord.cjs +2 -0
  530. package/dist/native/charts/src/engine/shapes/chord.cjs.map +1 -0
  531. package/dist/native/charts/src/engine/shapes/chord.js +419 -0
  532. package/dist/native/charts/src/engine/shapes/chord.js.map +1 -0
  533. package/dist/native/charts/src/engine/shapes/draw.cjs +1 -1
  534. package/dist/native/charts/src/engine/shapes/draw.cjs.map +1 -1
  535. package/dist/native/charts/src/engine/shapes/draw.js +47 -17
  536. package/dist/native/charts/src/engine/shapes/draw.js.map +1 -1
  537. package/dist/native/charts/src/engine/shapes/hit.cjs +1 -1
  538. package/dist/native/charts/src/engine/shapes/hit.cjs.map +1 -1
  539. package/dist/native/charts/src/engine/shapes/hit.js +73 -44
  540. package/dist/native/charts/src/engine/shapes/hit.js.map +1 -1
  541. package/dist/native/charts/src/engine/shapes/labels.cjs +1 -1
  542. package/dist/native/charts/src/engine/shapes/labels.cjs.map +1 -1
  543. package/dist/native/charts/src/engine/shapes/labels.js +12 -4
  544. package/dist/native/charts/src/engine/shapes/labels.js.map +1 -1
  545. package/dist/native/charts/src/engine/shapes/layout.cjs +2 -2
  546. package/dist/native/charts/src/engine/shapes/layout.cjs.map +1 -1
  547. package/dist/native/charts/src/engine/shapes/layout.js +136 -94
  548. package/dist/native/charts/src/engine/shapes/layout.js.map +1 -1
  549. package/dist/native/charts/src/engine/shapes/scene.cjs +1 -1
  550. package/dist/native/charts/src/engine/shapes/scene.cjs.map +1 -1
  551. package/dist/native/charts/src/engine/shapes/scene.js +62 -19
  552. package/dist/native/charts/src/engine/shapes/scene.js.map +1 -1
  553. package/dist/native/components/Chart/ChartBase.cjs +1 -1
  554. package/dist/native/components/Chart/ChartBase.cjs.map +1 -1
  555. package/dist/native/components/Chart/ChartBase.js +127 -115
  556. package/dist/native/components/Chart/ChartBase.js.map +1 -1
  557. package/dist/native/components/Chart/charts.cjs +1 -1
  558. package/dist/native/components/Chart/charts.cjs.map +1 -1
  559. package/dist/native/components/Chart/charts.js +8 -5
  560. package/dist/native/components/Chart/charts.js.map +1 -1
  561. package/dist/native/components/Chart/scene.cjs +1 -1
  562. package/dist/native/components/Chart/scene.cjs.map +1 -1
  563. package/dist/native/components/Chart/scene.d.cts +6 -1
  564. package/dist/native/components/Chart/scene.d.ts +6 -1
  565. package/dist/native/components/Chart/scene.js +226 -108
  566. package/dist/native/components/Chart/scene.js.map +1 -1
  567. package/dist/native/components/Chart/types.d.cts +7 -1
  568. package/dist/native/components/Chart/types.d.ts +7 -1
  569. package/dist/native/components/Charts/charts.cjs +1 -1
  570. package/dist/native/components/Charts/charts.cjs.map +1 -1
  571. package/dist/native/components/Charts/charts.js +60 -43
  572. package/dist/native/components/Charts/charts.js.map +1 -1
  573. package/dist/native/components/Charts/types.d.cts +11 -0
  574. package/dist/native/components/Charts/types.d.ts +11 -0
  575. package/dist/native/components/ShapeChart/ShapeChartBase.cjs +1 -1
  576. package/dist/native/components/ShapeChart/ShapeChartBase.cjs.map +1 -1
  577. package/dist/native/components/ShapeChart/ShapeChartBase.d.cts +1 -1
  578. package/dist/native/components/ShapeChart/ShapeChartBase.d.ts +1 -1
  579. package/dist/native/components/ShapeChart/ShapeChartBase.js +97 -106
  580. package/dist/native/components/ShapeChart/ShapeChartBase.js.map +1 -1
  581. package/dist/native/components/ShapeChart/charts.cjs +1 -1
  582. package/dist/native/components/ShapeChart/charts.cjs.map +1 -1
  583. package/dist/native/components/ShapeChart/charts.d.cts +6 -1
  584. package/dist/native/components/ShapeChart/charts.d.ts +6 -1
  585. package/dist/native/components/ShapeChart/charts.js +138 -96
  586. package/dist/native/components/ShapeChart/charts.js.map +1 -1
  587. package/dist/native/components/ShapeChart/draw.cjs +1 -1
  588. package/dist/native/components/ShapeChart/draw.cjs.map +1 -1
  589. package/dist/native/components/ShapeChart/draw.d.cts +1 -1
  590. package/dist/native/components/ShapeChart/draw.d.ts +1 -1
  591. package/dist/native/components/ShapeChart/draw.js +26 -17
  592. package/dist/native/components/ShapeChart/draw.js.map +1 -1
  593. package/dist/native/components/ShapeChart/geometry.cjs +1 -1
  594. package/dist/native/components/ShapeChart/geometry.cjs.map +1 -1
  595. package/dist/native/components/ShapeChart/geometry.js +233 -70
  596. package/dist/native/components/ShapeChart/geometry.js.map +1 -1
  597. package/dist/native/components/ShapeChart/index.cjs +1 -1
  598. package/dist/native/components/ShapeChart/index.d.cts +1 -1
  599. package/dist/native/components/ShapeChart/index.d.ts +1 -1
  600. package/dist/native/components/ShapeChart/index.js +2 -2
  601. package/dist/native/components/ShapeChart/recorder.cjs +1 -1
  602. package/dist/native/components/ShapeChart/recorder.cjs.map +1 -1
  603. package/dist/native/components/ShapeChart/recorder.d.cts +10 -1
  604. package/dist/native/components/ShapeChart/recorder.d.ts +10 -1
  605. package/dist/native/components/ShapeChart/recorder.js +19 -10
  606. package/dist/native/components/ShapeChart/recorder.js.map +1 -1
  607. package/dist/native/components/ShapeChart/types.d.cts +95 -8
  608. package/dist/native/components/ShapeChart/types.d.ts +95 -8
  609. package/dist/native/index.cjs +1 -1
  610. package/dist/native/index.js +2 -2
  611. package/dist/native/source/components/Chart/ChartBase.tsx +19 -6
  612. package/dist/native/source/components/Chart/charts.tsx +10 -3
  613. package/dist/native/source/components/Chart/scene.tsx +243 -14
  614. package/dist/native/source/components/Chart/types.ts +7 -0
  615. package/dist/native/source/components/Charts/charts.tsx +37 -2
  616. package/dist/native/source/components/Charts/types.ts +11 -0
  617. package/dist/native/source/components/ShapeChart/ShapeChartBase.tsx +10 -34
  618. package/dist/native/source/components/ShapeChart/charts.tsx +91 -35
  619. package/dist/native/source/components/ShapeChart/draw.tsx +39 -8
  620. package/dist/native/source/components/ShapeChart/geometry.ts +376 -25
  621. package/dist/native/source/components/ShapeChart/index.ts +1 -0
  622. package/dist/native/source/components/ShapeChart/recorder.ts +20 -5
  623. package/dist/native/source/components/ShapeChart/types.ts +99 -6
  624. package/dist/native/source/manifest.ts +1 -0
  625. package/dist/taro/chart-a11y.d.ts +7 -0
  626. package/dist/taro/charts.d.ts +29 -6
  627. package/dist/taro/index.js +3129 -1902
  628. package/dist/taro/shape-charts.d.ts +99 -5
  629. package/dist/uni/AreaChart.vue +2 -1
  630. package/dist/uni/AreaChart.vue.d.ts +5 -1
  631. package/dist/uni/Badge.vue.d.ts +1 -1
  632. package/dist/uni/BarChart.vue +2 -1
  633. package/dist/uni/BarChart.vue.d.ts +5 -1
  634. package/dist/uni/BoxPlotChart.vue +2 -1
  635. package/dist/uni/BoxPlotChart.vue.d.ts +8 -0
  636. package/dist/uni/BubbleChart.vue +2 -1
  637. package/dist/uni/BubbleChart.vue.d.ts +4 -0
  638. package/dist/uni/BulletChart.vue.d.ts +4 -0
  639. package/dist/uni/CalendarHeatmap.vue.d.ts +2 -0
  640. package/dist/uni/CandlestickChart.vue +2 -1
  641. package/dist/uni/CandlestickChart.vue.d.ts +4 -0
  642. package/dist/uni/Chart.vue +2 -1
  643. package/dist/uni/Chart.vue.d.ts +4 -0
  644. package/dist/uni/ChordChart.vue +93 -0
  645. package/dist/uni/ChordChart.vue.d.ts +136 -0
  646. package/dist/uni/Divider.vue.d.ts +1 -1
  647. package/dist/uni/DonutChart.vue.d.ts +5 -1
  648. package/dist/uni/FunnelChart.vue.d.ts +4 -0
  649. package/dist/uni/GanttChart.vue +2 -1
  650. package/dist/uni/GanttChart.vue.d.ts +15 -0
  651. package/dist/uni/GaugeChart.vue.d.ts +5 -1
  652. package/dist/uni/HeatmapChart.vue +2 -1
  653. package/dist/uni/HeatmapChart.vue.d.ts +8 -2
  654. package/dist/uni/HistogramChart.vue +2 -1
  655. package/dist/uni/HistogramChart.vue.d.ts +4 -0
  656. package/dist/uni/HorizontalBarChart.vue +2 -1
  657. package/dist/uni/HorizontalBarChart.vue.d.ts +3 -1
  658. package/dist/uni/LineChart.vue +2 -1
  659. package/dist/uni/LineChart.vue.d.ts +4 -0
  660. package/dist/uni/MixedChart.vue +2 -1
  661. package/dist/uni/MixedChart.vue.d.ts +4 -0
  662. package/dist/uni/PieChart.vue.d.ts +5 -1
  663. package/dist/uni/QuadrantChart.vue +2 -1
  664. package/dist/uni/QuadrantChart.vue.d.ts +4 -0
  665. package/dist/uni/RadarChart.vue.d.ts +4 -0
  666. package/dist/uni/RadialBarChart.vue.d.ts +4 -0
  667. package/dist/uni/RangeAreaChart.vue +2 -1
  668. package/dist/uni/RangeAreaChart.vue.d.ts +4 -0
  669. package/dist/uni/SankeyChart.vue.d.ts +4 -0
  670. package/dist/uni/ScatterChart.vue +2 -1
  671. package/dist/uni/ScatterChart.vue.d.ts +4 -0
  672. package/dist/uni/Sparkline.vue +2 -1
  673. package/dist/uni/Sparkline.vue.d.ts +4 -0
  674. package/dist/uni/SunburstChart.vue.d.ts +4 -0
  675. package/dist/uni/ToastProvider.vue.d.ts +1 -1
  676. package/dist/uni/TreemapChart.vue.d.ts +4 -0
  677. package/dist/uni/WaterfallChart.vue +2 -1
  678. package/dist/uni/WaterfallChart.vue.d.ts +9 -0
  679. package/dist/uni/chart-a11y.d.ts +7 -0
  680. package/dist/uni/chart-a11y.js +29 -0
  681. package/dist/uni/chart-canvas.d.ts +12 -0
  682. package/dist/uni/chart-canvas.js +15 -1
  683. package/dist/uni/chart-types.d.ts +36 -5
  684. package/dist/uni/chart-types.js +31 -3
  685. package/dist/uni/charts-canvas.js +3 -2
  686. package/dist/uni/index.d.ts +2 -1
  687. package/dist/uni/index.js +1 -0
  688. package/dist/uni/manifest.d.ts +7 -0
  689. package/dist/uni/manifest.js +10 -0
  690. package/dist/uni/named-chart-options.d.ts +11 -2
  691. package/dist/uni/named-chart-options.js +21 -1
  692. package/dist/uni/shape-chart-canvas.d.ts +3 -3
  693. package/dist/uni/shape-chart-canvas.js +17 -58
  694. package/dist/uni/shape-chart-types.d.ts +53 -3
  695. package/dist/uni/shape-chart-types.js +45 -1
  696. package/dist/vue/charts-global.d.ts +48 -0
  697. package/dist/vue/charts.d.ts +18 -0
  698. package/dist/vue/charts.js +56 -0
  699. package/dist/vue/charts.js.map +1 -0
  700. package/dist/vue/components/Chart/Bar3DChart.vue.d.ts +2 -0
  701. package/dist/vue/components/Chart/BoxPlotChart.vue.d.ts +8 -0
  702. package/dist/vue/components/Chart/BoxPlotChart.vue.js.map +1 -1
  703. package/dist/vue/components/Chart/BoxPlotChart.vue_vue_type_script_setup_true_lang.js +8 -2
  704. package/dist/vue/components/Chart/BoxPlotChart.vue_vue_type_script_setup_true_lang.js.map +1 -1
  705. package/dist/vue/components/Chart/ChordChart.vue.d.ts +153 -0
  706. package/dist/vue/components/Chart/ChordChart.vue.js +7 -0
  707. package/dist/vue/components/Chart/ChordChart.vue.js.map +1 -0
  708. package/dist/vue/components/Chart/ChordChart.vue_vue_type_script_setup_true_lang.js +81 -0
  709. package/dist/vue/components/Chart/ChordChart.vue_vue_type_script_setup_true_lang.js.map +1 -0
  710. package/dist/vue/components/Chart/DependencyGraph.vue.d.ts +181 -0
  711. package/dist/vue/components/Chart/DependencyGraph.vue.js +7 -0
  712. package/dist/vue/components/Chart/DependencyGraph.vue.js.map +1 -0
  713. package/dist/vue/components/Chart/DependencyGraph.vue_vue_type_script_setup_true_lang.js +65 -0
  714. package/dist/vue/components/Chart/DependencyGraph.vue_vue_type_script_setup_true_lang.js.map +1 -0
  715. package/dist/vue/components/Chart/GanttChart.vue.d.ts +19 -0
  716. package/dist/vue/components/Chart/GanttChart.vue.js.map +1 -1
  717. package/dist/vue/components/Chart/GanttChart.vue_vue_type_script_setup_true_lang.js +12 -1
  718. package/dist/vue/components/Chart/GanttChart.vue_vue_type_script_setup_true_lang.js.map +1 -1
  719. package/dist/vue/components/Chart/GraphChart.vue.d.ts +186 -0
  720. package/dist/vue/components/Chart/GraphChart.vue.js +7 -0
  721. package/dist/vue/components/Chart/GraphChart.vue.js.map +1 -0
  722. package/dist/vue/components/Chart/GraphChart.vue_vue_type_script_setup_true_lang.js +62 -0
  723. package/dist/vue/components/Chart/GraphChart.vue_vue_type_script_setup_true_lang.js.map +1 -0
  724. package/dist/vue/components/Chart/HeatmapChart.vue.d.ts +9 -5
  725. package/dist/vue/components/Chart/HeatmapChart.vue.js.map +1 -1
  726. package/dist/vue/components/Chart/HeatmapChart.vue_vue_type_script_setup_true_lang.js +3 -1
  727. package/dist/vue/components/Chart/HeatmapChart.vue_vue_type_script_setup_true_lang.js.map +1 -1
  728. package/dist/vue/components/Chart/Line3DChart.vue.d.ts +2 -0
  729. package/dist/vue/components/Chart/OrderBookHeatmap.vue.d.ts +2 -0
  730. package/dist/vue/components/Chart/Scatter3DChart.vue.d.ts +2 -0
  731. package/dist/vue/components/Chart/Surface3DChart.vue.d.ts +2 -0
  732. package/dist/vue/components/Chart/TimeAndSales.vue.d.ts +2 -0
  733. package/dist/vue/components/Chart/TradingChart.vue.d.ts +58 -1
  734. package/dist/vue/components/Chart/TradingChart.vue.js.map +1 -1
  735. package/dist/vue/components/Chart/TradingChart.vue_vue_type_script_setup_true_lang.js +31 -0
  736. package/dist/vue/components/Chart/TradingChart.vue_vue_type_script_setup_true_lang.js.map +1 -1
  737. package/dist/vue/components/Chart/TreeChart.vue.d.ts +174 -0
  738. package/dist/vue/components/Chart/TreeChart.vue.js +7 -0
  739. package/dist/vue/components/Chart/TreeChart.vue.js.map +1 -0
  740. package/dist/vue/components/Chart/TreeChart.vue_vue_type_script_setup_true_lang.js +56 -0
  741. package/dist/vue/components/Chart/TreeChart.vue_vue_type_script_setup_true_lang.js.map +1 -0
  742. package/dist/vue/components/Chart/WaterfallChart.vue.d.ts +12 -1
  743. package/dist/vue/components/Chart/WaterfallChart.vue.js.map +1 -1
  744. package/dist/vue/components/Chart/WaterfallChart.vue_vue_type_script_setup_true_lang.js +8 -2
  745. package/dist/vue/components/Chart/WaterfallChart.vue_vue_type_script_setup_true_lang.js.map +1 -1
  746. package/dist/vue/components/Chart/graph.d.ts +156 -0
  747. package/dist/vue/components/Chart/graph.js +137 -0
  748. package/dist/vue/components/Chart/graph.js.map +1 -0
  749. package/dist/vue/components/Chart/index.d.ts +5 -1
  750. package/dist/vue/components/Chart/index.js +5 -1
  751. package/dist/vue/components/Chart/orderbook.d.ts +5 -1
  752. package/dist/vue/components/Chart/orderbook.js +2 -0
  753. package/dist/vue/components/Chart/orderbook.js.map +1 -1
  754. package/dist/vue/components/Chart/three-d.d.ts +3 -0
  755. package/dist/vue/components/Chart/three-d.js +2 -0
  756. package/dist/vue/components/Chart/three-d.js.map +1 -1
  757. package/dist/vue/components/Chart/trading.d.ts +30 -3
  758. package/dist/vue/components/Chart/trading.js +9 -0
  759. package/dist/vue/components/Chart/trading.js.map +1 -1
  760. package/dist/vue/components/Chart/types.d.ts +74 -2
  761. package/dist/vue/global.d.ts +2 -38
  762. package/dist/vue/groups/charts.js +10 -2
  763. package/dist/vue/groups/charts.js.map +1 -1
  764. package/dist/vue/index.js +6 -2
  765. package/dist/vue/internal/register.d.ts +7 -0
  766. package/dist/vue/internal/register.js +14 -0
  767. package/dist/vue/internal/register.js.map +1 -0
  768. package/dist/vue/plugin.d.ts +9 -4
  769. package/dist/vue/plugin.js +6 -11
  770. package/dist/vue/plugin.js.map +1 -1
  771. package/dist/weapp/area-chart/index.wxml +1 -1
  772. package/dist/weapp/bar-chart/index.wxml +1 -1
  773. package/dist/weapp/box-plot-chart/index.wxml +1 -1
  774. package/dist/weapp/bubble-chart/index.wxml +1 -1
  775. package/dist/weapp/candlestick-chart/index.wxml +1 -1
  776. package/dist/weapp/chart/index.wxml +1 -1
  777. package/dist/weapp/charts/canvas.js +1987 -175
  778. package/dist/weapp/charts/core.js +3 -0
  779. package/dist/weapp/chord-chart/index.js +1 -0
  780. package/dist/weapp/chord-chart/index.json +1 -0
  781. package/dist/weapp/chord-chart/index.wxml +1 -0
  782. package/dist/weapp/chord-chart/index.wxss +1 -0
  783. package/dist/weapp/controls.js +148 -57
  784. package/dist/weapp/gantt-chart/index.wxml +1 -1
  785. package/dist/weapp/heatmap-chart/index.wxml +1 -1
  786. package/dist/weapp/histogram-chart/index.wxml +1 -1
  787. package/dist/weapp/horizontal-bar-chart/index.wxml +1 -1
  788. package/dist/weapp/line-chart/index.wxml +1 -1
  789. package/dist/weapp/mixed-chart/index.wxml +1 -1
  790. package/dist/weapp/quadrant-chart/index.wxml +1 -1
  791. package/dist/weapp/range-area-chart/index.wxml +1 -1
  792. package/dist/weapp/scatter-chart/index.wxml +1 -1
  793. package/dist/weapp/sparkline/index.wxml +1 -1
  794. package/dist/weapp/types.d.ts +96 -4
  795. package/dist/weapp/waterfall-chart/index.wxml +1 -1
  796. package/dist/web-components/components/chart/charts.d.ts +4 -2
  797. package/dist/web-components/components/chart/charts.js +8 -1
  798. package/dist/web-components/components/chart/charts.js.map +1 -1
  799. package/dist/web-components/components/chart/extended.d.ts +21 -7
  800. package/dist/web-components/components/chart/extended.js +29 -9
  801. package/dist/web-components/components/chart/extended.js.map +1 -1
  802. package/dist/web-components/components/chart/shapes-extended.d.ts +37 -1
  803. package/dist/web-components/components/chart/shapes-extended.js +27 -1
  804. package/dist/web-components/components/chart/shapes-extended.js.map +1 -1
  805. package/dist/web-components/components/chart-3d/chart-3d.d.ts +1 -1
  806. package/dist/web-components/components/chart-3d/chart-3d.js.map +1 -1
  807. package/dist/web-components/components/graph/graph.d.ts +156 -0
  808. package/dist/web-components/components/graph/graph.js +150 -0
  809. package/dist/web-components/components/graph/graph.js.map +1 -0
  810. package/dist/web-components/components/trading-chart/trading-chart.d.ts +49 -2
  811. package/dist/web-components/components/trading-chart/trading-chart.js +62 -0
  812. package/dist/web-components/components/trading-chart/trading-chart.js.map +1 -1
  813. package/dist/web-components/elements/chart.d.ts +1 -1
  814. package/dist/web-components/elements/chart.js +6 -5
  815. package/dist/web-components/elements/chart.js.map +1 -1
  816. package/dist/web-components/elements/graph.d.ts +2 -0
  817. package/dist/web-components/elements/graph.js +12 -0
  818. package/dist/web-components/elements/graph.js.map +1 -0
  819. package/dist/web-components/html-custom-data.json +318 -4
  820. package/dist/web-components/types/react.d.ts +63 -4
  821. package/dist/web-components/types/solid.d.ts +55 -8
  822. package/dist/web-components/types/svelte.d.ts +55 -8
  823. package/dist/web-components/types/vue.d.ts +55 -4
  824. package/package.json +16 -1
@@ -163,12 +163,84 @@ var unpackColor = (packed) => [
163
163
  (packed >>> 16 & 255) / 255,
164
164
  (packed >>> 24 & 255) / 255
165
165
  ];
166
- /** Color at `t` (0-1) of a ramp through `stops` */
167
- var rampColor = (stops, t) => {
168
- if (stops.length === 1) return stops[0];
169
- const p = clamp01(t) * (stops.length - 1);
170
- const i = Math.min(stops.length - 2, Math.floor(p));
171
- return mix(stops[i], stops[i + 1], p - i);
166
+ /** Relative luminance (sRGB approximation) */
167
+ var luminance = (c) => .2126 * c[0] + .7152 * c[1] + .0722 * c[2];
168
+ var toLinear = (v) => v <= .04045 ? v / 12.92 : ((v + .055) / 1.055) ** 2.4;
169
+ var toGamma = (v) => v <= .0031308 ? v * 12.92 : 1.055 * Math.max(0, v) ** (1 / 2.4) - .055;
170
+ /** sRGB -> OKLab (perceptually uniform: even steps look even) */
171
+ var toOklab = (c) => {
172
+ const r = toLinear(c[0]);
173
+ const g = toLinear(c[1]);
174
+ const b = toLinear(c[2]);
175
+ const l = Math.cbrt(.4122214708 * r + .5363325363 * g + .0514459929 * b);
176
+ const m = Math.cbrt(.2119034982 * r + .6806995451 * g + .1073969566 * b);
177
+ const s = Math.cbrt(.0883024619 * r + .2817188376 * g + .6299787005 * b);
178
+ return [
179
+ .2104542553 * l + .793617785 * m - .0040720468 * s,
180
+ 1.9779984951 * l - 2.428592205 * m + .4505937099 * s,
181
+ .0259040371 * l + .7827717662 * m - .808675766 * s,
182
+ c[3]
183
+ ];
184
+ };
185
+ /** OKLab -> sRGB, clamped to the gamut */
186
+ var fromOklab = (c) => {
187
+ const l = (c[0] + .3963377774 * c[1] + .2158037573 * c[2]) ** 3;
188
+ const m = (c[0] - .1055613458 * c[1] - .0638541728 * c[2]) ** 3;
189
+ const s = (c[0] - .0894841775 * c[1] - 1.291485548 * c[2]) ** 3;
190
+ return [
191
+ clamp01(toGamma(4.0767416621 * l - 3.3077115913 * m + .2309699292 * s)),
192
+ clamp01(toGamma(-1.2684380046 * l + 2.6097574011 * m - .3413193965 * s)),
193
+ clamp01(toGamma(-.0041960863 * l - .7034186147 * m + 1.707614701 * s)),
194
+ c[3]
195
+ ];
196
+ };
197
+ /** Mixes two colors in OKLab (no muddy gray middle) */
198
+ var mixOklab = (a, b, t) => {
199
+ const p = toOklab(a);
200
+ const q = toOklab(b);
201
+ return fromOklab([
202
+ p[0] + (q[0] - p[0]) * t,
203
+ p[1] + (q[1] - p[1]) * t,
204
+ p[2] + (q[2] - p[2]) * t,
205
+ p[3] + (q[3] - p[3]) * t
206
+ ]);
207
+ };
208
+ /**
209
+ * A color with another OKLab lightness (0-1) and its chroma scaled by
210
+ * `chroma` (the hue is kept)
211
+ */
212
+ var withLightness = (c, lightness, chroma = 1) => {
213
+ const [, a, b, alpha] = toOklab(c);
214
+ return fromOklab([
215
+ lightness,
216
+ a * chroma,
217
+ b * chroma,
218
+ alpha
219
+ ]);
220
+ };
221
+ /**
222
+ * Packed colors (`packColor`) of `size` even steps along a ramp through
223
+ * `stops`, interpolated in OKLab: a lookup table for many values
224
+ */
225
+ var oklabRamp = (stops, size = 256) => {
226
+ const lut = new Uint32Array(size);
227
+ if (!stops.length) return lut;
228
+ const lab = stops.map(toOklab);
229
+ for (let k = 0; k < size; k++) {
230
+ const p = k / Math.max(1, size - 1) * (lab.length - 1);
231
+ const i = Math.min(lab.length - 2, Math.floor(p));
232
+ const a = lab[Math.max(0, i)];
233
+ const b = lab[Math.min(lab.length - 1, i + 1)];
234
+ const t = lab.length === 1 ? 0 : p - i;
235
+ const c = fromOklab([
236
+ a[0] + (b[0] - a[0]) * t,
237
+ a[1] + (b[1] - a[1]) * t,
238
+ a[2] + (b[2] - a[2]) * t,
239
+ a[3] + (b[3] - a[3]) * t
240
+ ]);
241
+ lut[k] = packColor(c) || 1;
242
+ }
243
+ return lut;
172
244
  };
173
245
  /**
174
246
  * Points of the curve through `x[i], y[i]` (`i` in `[start, end)`), as
@@ -422,7 +494,8 @@ var normalizeData = (data, resolveX, resolveY = toNumber) => {
422
494
  y0: null,
423
495
  q1: null,
424
496
  q3: null,
425
- outliers: null
497
+ outliers: null,
498
+ details: null
426
499
  };
427
500
  if (isColumns(data)) {
428
501
  const count = data.y.length;
@@ -472,6 +545,7 @@ var normalizeData = (data, resolveX, resolveY = toNumber) => {
472
545
  let q1 = null;
473
546
  let q3 = null;
474
547
  let outliers = null;
548
+ let details = null;
475
549
  const nanColumn = () => new Float64Array(count).fill(NaN);
476
550
  for (let i = 0; i < count; i++) {
477
551
  const item = list[i];
@@ -508,6 +582,10 @@ var normalizeData = (data, resolveX, resolveY = toNumber) => {
508
582
  outliers ??= new Array(count);
509
583
  outliers[i] = d.outliers;
510
584
  }
585
+ if (d.details !== void 0 && d.details.length) {
586
+ details ??= new Array(count);
587
+ details[i] = d.details;
588
+ }
511
589
  } else {
512
590
  x[i] = i;
513
591
  y[i] = NaN;
@@ -524,7 +602,8 @@ var normalizeData = (data, resolveX, resolveY = toNumber) => {
524
602
  y0,
525
603
  q1,
526
604
  q3,
527
- outliers
605
+ outliers,
606
+ details
528
607
  });
529
608
  };
530
609
  /** First index whose x is >= value (sorted x) */
@@ -691,6 +770,22 @@ var screenRect = (s, xa, xb, ya, yb) => {
691
770
  height: d - c
692
771
  };
693
772
  };
773
+ /**
774
+ * Inset (per side) and corner radius of heatmap cells of `width` ×
775
+ * `height` CSS pixels: a hairline apart (1px, 2px on large cells), corners
776
+ * of `radius` at most 20% of the cell; tiny cells touch
777
+ */
778
+ var heatCellStyle = (width, height, radius) => {
779
+ const size = Math.min(Math.abs(width), Math.abs(height));
780
+ if (!(size >= 4)) return {
781
+ inset: 0,
782
+ radius: 0
783
+ };
784
+ return {
785
+ inset: Math.round(Math.min(1, .5 + size / 96) * 4) / 4,
786
+ radius: Math.round(Math.max(0, Math.min(radius, size * .2)) * 4) / 4
787
+ };
788
+ };
694
789
  /** Room for the axes, then the plot area */
695
790
  var computePlot = (input) => {
696
791
  const { width, height, padding, fontSize } = input;
@@ -941,6 +1036,31 @@ var formatValue = (value, locale) => {
941
1036
  };
942
1037
  /** `formatValue` bound to a locale */
943
1038
  var valueFormatter = (locale) => (value) => formatValue(value, locale);
1039
+ var MINUTE$1 = 6e4;
1040
+ var HOUR$1 = 36e5;
1041
+ var DAY$1 = 864e5;
1042
+ /**
1043
+ * Length of a time range in its natural unit, in the words of a locale:
1044
+ * whole weeks (`4 weeks`, `4周`), else days (`26 days`, `26 jours`), hours
1045
+ * or minutes
1046
+ */
1047
+ var formatDuration = (ms, locale) => {
1048
+ if (!Number.isFinite(ms)) return "–";
1049
+ const abs = Math.abs(ms);
1050
+ const days = abs / DAY$1;
1051
+ const weeks = days / 7;
1052
+ const [value, unit] = days >= 7 && Math.abs(weeks - Math.round(weeks)) < 1e-6 ? [Math.round(weeks), "week"] : days >= 1 ? [Math.round(days * 10) / 10, "day"] : abs >= HOUR$1 ? [Math.round(abs / HOUR$1 * 10) / 10, "hour"] : [Math.round(abs / MINUTE$1), "minute"];
1053
+ try {
1054
+ return numberFormat(locale, {
1055
+ style: "unit",
1056
+ unit,
1057
+ unitDisplay: "long",
1058
+ maximumFractionDigits: 1
1059
+ }).format(value);
1060
+ } catch {
1061
+ return `${value} ${unit}${value === 1 ? "" : "s"}`;
1062
+ }
1063
+ };
944
1064
  /**
945
1065
  * `12.5` -> `12.5%` (`12,5 %` in French): one decimal at most, exactly one
946
1066
  * with `fixed` (`75.0%`)
@@ -969,7 +1089,13 @@ var CHART_LABELS = {
969
1089
  y: "y",
970
1090
  series: "Series",
971
1091
  chart: "Chart",
972
- chartOf: "Chart: {series}"
1092
+ chartOf: "Chart: {series}",
1093
+ start: "Start",
1094
+ end: "End",
1095
+ duration: "Duration",
1096
+ progress: "Progress",
1097
+ dependencies: "Depends on",
1098
+ outlier: "Outlier"
973
1099
  },
974
1100
  zh: {
975
1101
  open: "开盘",
@@ -985,7 +1111,13 @@ var CHART_LABELS = {
985
1111
  value: "数值",
986
1112
  series: "系列",
987
1113
  chart: "图表",
988
- chartOf: "图表:{series}"
1114
+ chartOf: "图表:{series}",
1115
+ start: "开始",
1116
+ end: "结束",
1117
+ duration: "时长",
1118
+ progress: "进度",
1119
+ dependencies: "前置任务",
1120
+ outlier: "异常值"
989
1121
  },
990
1122
  ja: {
991
1123
  open: "始値",
@@ -1001,7 +1133,13 @@ var CHART_LABELS = {
1001
1133
  value: "値",
1002
1134
  series: "系列",
1003
1135
  chart: "グラフ",
1004
- chartOf: "グラフ:{series}"
1136
+ chartOf: "グラフ:{series}",
1137
+ start: "開始",
1138
+ end: "終了",
1139
+ duration: "期間",
1140
+ progress: "進捗",
1141
+ dependencies: "先行タスク",
1142
+ outlier: "外れ値"
1005
1143
  },
1006
1144
  fr: {
1007
1145
  open: "Ouverture",
@@ -1017,7 +1155,13 @@ var CHART_LABELS = {
1017
1155
  value: "Valeur",
1018
1156
  series: "Série",
1019
1157
  chart: "Graphique",
1020
- chartOf: "Graphique : {series}"
1158
+ chartOf: "Graphique : {series}",
1159
+ start: "Début",
1160
+ end: "Fin",
1161
+ duration: "Durée",
1162
+ progress: "Avancement",
1163
+ dependencies: "Dépend de",
1164
+ outlier: "Valeur aberrante"
1021
1165
  }
1022
1166
  };
1023
1167
  /** Texts of a locale with the overrides */
@@ -1026,6 +1170,29 @@ var chartLabels = (locale, overrides) => localeLabels(CHART_LABELS, locale, over
1026
1170
  var listSeparator = (locale) => /^(zh|ja)\b/i.test(locale) ? "、" : ", ";
1027
1171
  /** Default accessible name of a chart model: "Chart: Revenue, Costs" */
1028
1172
  var chartAriaLabel = (model) => model.series.length ? model.labels.chartOf.replace("{series}", model.series.map((s) => s.name).join(listSeparator(model.locale))) : model.labels.chart;
1173
+ /**
1174
+ * Localized accessible description of a chart, for platforms that build their
1175
+ * own accessible name ("Chart: Revenue, Costs", "营收:营收、成本").
1176
+ * With a `title`, the title replaces the generic "Chart" word.
1177
+ */
1178
+ function describeChart$1(input) {
1179
+ const locale = input.locale ?? "en";
1180
+ const labels = chartLabels(locale, input.labels);
1181
+ const series = input.series ?? [];
1182
+ const title = input.title?.trim();
1183
+ const generic = chartAriaLabel({
1184
+ labels,
1185
+ locale,
1186
+ series
1187
+ });
1188
+ if (!title) return generic;
1189
+ if (!series.length) return title;
1190
+ const index = labels.chartOf.indexOf(labels.chart);
1191
+ if (index < 0 || !labels.chart) return `${title}. ${generic}`;
1192
+ const names = series.map((s) => s.name).join(listSeparator(locale));
1193
+ const fill = (part) => part.split("{series}").join(names);
1194
+ return fill(labels.chartOf.slice(0, index)) + title + fill(labels.chartOf.slice(index + labels.chart.length));
1195
+ }
1029
1196
  //#endregion
1030
1197
  //#region ../charts/src/engine/spatial.ts
1031
1198
  var GridIndex = class {
@@ -1100,6 +1267,12 @@ var GridIndex = class {
1100
1267
  };
1101
1268
  //#endregion
1102
1269
  //#region ../charts/src/engine/model.ts
1270
+ /** Plotted units of a log axis: the base-10 logarithm of the values */
1271
+ var LOG_MAP = {
1272
+ scale: 1,
1273
+ offset: 0,
1274
+ log: true
1275
+ };
1103
1276
  var firstX = (data) => {
1104
1277
  if (typeof data === "object" && data !== null && !("length" in data)) {
1105
1278
  const xs = data.x;
@@ -1281,14 +1454,13 @@ var alignedDomain = (lo, hi, left, count) => {
1281
1454
  };
1282
1455
  var mapped = /* @__PURE__ */ new WeakMap();
1283
1456
  /** Columns of a right-axis series in left axis units (cached with the data) */
1284
- var mapColumns = (raw, map) => {
1285
- const key = `${map.scale},${map.offset}`;
1286
- const hit = mapped.get(raw);
1457
+ var mapColumns = (src, map) => {
1458
+ const key = `${map.scale},${map.offset},${!!map.log}`;
1459
+ const hit = mapped.get(src);
1287
1460
  if (hit && hit.key === key) return hit.cols;
1288
- const f = (v) => v * map.scale + map.offset;
1461
+ const f = mapper(map);
1289
1462
  const column = (a) => a ? a.map(f) : null;
1290
- const lo = f(raw.yMin);
1291
- const hi = f(raw.yMax);
1463
+ const raw = src;
1292
1464
  const cols = {
1293
1465
  ...raw,
1294
1466
  y: raw.y.map(f),
@@ -1298,16 +1470,159 @@ var mapColumns = (raw, map) => {
1298
1470
  y0: column(raw.y0),
1299
1471
  q1: column(raw.q1),
1300
1472
  q3: column(raw.q3),
1301
- outliers: raw.outliers ? raw.outliers.map((list) => list?.map(f)) : null,
1302
- yMin: Math.min(lo, hi),
1303
- yMax: Math.max(lo, hi)
1304
- };
1305
- mapped.set(raw, {
1473
+ outliers: raw.outliers ? raw.outliers.map((list) => list?.map(f)) : null
1474
+ };
1475
+ if (map.log) {
1476
+ const range = [Infinity, -Infinity];
1477
+ const add = (a) => {
1478
+ if (!a) return;
1479
+ for (let i = 0; i < a.length; i++) {
1480
+ const v = a[i];
1481
+ if (!Number.isFinite(v)) continue;
1482
+ if (v < range[0]) range[0] = v;
1483
+ if (v > range[1]) range[1] = v;
1484
+ }
1485
+ };
1486
+ for (const c of [
1487
+ cols.y,
1488
+ cols.y0,
1489
+ cols.high,
1490
+ cols.low,
1491
+ cols.q1,
1492
+ cols.q3
1493
+ ]) add(c);
1494
+ cols.outliers?.forEach((list) => add(list));
1495
+ cols.yMin = range[0] <= range[1] ? range[0] : NaN;
1496
+ cols.yMax = range[0] <= range[1] ? range[1] : NaN;
1497
+ } else {
1498
+ const lo = f(raw.yMin);
1499
+ const hi = f(raw.yMax);
1500
+ cols.yMin = Math.min(lo, hi);
1501
+ cols.yMax = Math.max(lo, hi);
1502
+ }
1503
+ mapped.set(src, {
1306
1504
  key,
1307
1505
  cols
1308
1506
  });
1309
1507
  return cols;
1310
1508
  };
1509
+ /** A log range widened to whole decades (`[0.3, 2.4]` -> `[0, 3]`) */
1510
+ var decades = (range) => {
1511
+ const lo = Math.floor(range[0] + 1e-9);
1512
+ const hi = Math.ceil(range[1] - 1e-9);
1513
+ return [lo, hi > lo ? hi : lo + 1];
1514
+ };
1515
+ /**
1516
+ * Plots a series through a map: its columns, bars, stacks and lower
1517
+ * edges (bars / areas of the right axis start at `zero`)
1518
+ */
1519
+ var logColumns = (s, map, zero = -Infinity) => {
1520
+ const f = mapper(map);
1521
+ const column = (a) => a ? a.map(f) : null;
1522
+ const rawBase = s.stackBase;
1523
+ s.cols = mapColumns(s.cols, map);
1524
+ s.barBase = s.barBase && !s.floating ? s.barBase.map((v) => v === 0 ? map.log ? -Infinity : f(0) : f(v)) : column(s.barBase);
1525
+ s.barTop = column(s.barTop);
1526
+ s.stackTop = column(s.stackTop);
1527
+ s.stackBase = rawBase && rawBase === s.raw.y0 ? s.cols.y0 : rawBase ? column(rawBase) : s.type === "area" ? new Float64Array(s.cols.count).fill(zero) : null;
1528
+ };
1529
+ /** Value -> plotted units of a map (`-Infinity` for 0 on log axes) */
1530
+ var mapper = (map) => (v) => (map.log ? Math.log10(v) : v) * map.scale + map.offset;
1531
+ /** Value of the y axis -> plotted y (the logarithm on log axes) */
1532
+ var toPlotY = (model, value) => model.y.type === "log" ? Math.log10(value) : value;
1533
+ /** Plotted y -> value of the y axis */
1534
+ var fromPlotY = (model, value) => model.y.type === "log" ? 10 ** value : value;
1535
+ /** Value of the x axis -> plotted x (the logarithm on log axes) */
1536
+ var toPlotX = (model, value) => model.x.type === "log" ? Math.log10(value) : value;
1537
+ /** Plotted x -> value of the x axis */
1538
+ var fromPlotX = (model, value) => model.x.type === "log" ? 10 ** value : value;
1539
+ /** A view in plotted units -> the values of the axes (zoom events, `getView`) */
1540
+ var viewToValues = (model, view) => ({
1541
+ x: [fromPlotX(model, view.x[0]), fromPlotX(model, view.x[1])],
1542
+ y: [fromPlotY(model, view.y[0]), fromPlotY(model, view.y[1])]
1543
+ });
1544
+ /** Values of the axes -> a view in plotted units (`setView`); missing axes keep `current` */
1545
+ var viewFromValues = (model, next, current) => ({
1546
+ x: next.x ? [toPlotX(model, next.x[0]), toPlotX(model, next.x[1])] : current.x,
1547
+ y: next.y ? [toPlotY(model, next.y[0]), toPlotY(model, next.y[1])] : current.y
1548
+ });
1549
+ var logXCache = /* @__PURE__ */ new WeakMap();
1550
+ /**
1551
+ * Columns plotted on a log x axis: the logarithms of the x values; points
1552
+ * without one (x <= 0) become gaps (cached with the data)
1553
+ */
1554
+ var logXColumns = (raw) => {
1555
+ const hit = logXCache.get(raw);
1556
+ if (hit) return hit;
1557
+ const x = raw.x.map((v) => v > 0 ? Math.log10(v) : NaN);
1558
+ let y = raw.y;
1559
+ let gaps = false;
1560
+ for (let i = 0; i < raw.count; i++) {
1561
+ if (Number.isFinite(x[i])) continue;
1562
+ if (!gaps) y = Float64Array.from(raw.y);
1563
+ gaps = true;
1564
+ y[i] = NaN;
1565
+ }
1566
+ const [xMin, xMax] = extent(x);
1567
+ const cols = {
1568
+ ...raw,
1569
+ x,
1570
+ y,
1571
+ xMin,
1572
+ xMax,
1573
+ sorted: raw.sorted && !gaps
1574
+ };
1575
+ logXCache.set(raw, cols);
1576
+ return cols;
1577
+ };
1578
+ /** Replaces the bases of bars / areas on log axes (`-Infinity`) by the bottom of the axis */
1579
+ var floorBases = (s, floor) => {
1580
+ for (const a of [s.barBase, s.stackBase]) {
1581
+ if (!a) continue;
1582
+ for (let i = 0; i < a.length; i++) if (a[i] === -Infinity) a[i] = floor;
1583
+ }
1584
+ };
1585
+ /** Position (0-1) of a heatmap value on its color ramp */
1586
+ var heatPosition = (s, v) => {
1587
+ const [lo, hi] = s.valueRange;
1588
+ const mid = s.colorMidpoint;
1589
+ let t;
1590
+ if (mid !== null && mid > lo && mid < hi) t = v < mid ? (v - lo) / (mid - lo) * .5 : .5 + (v - mid) / (hi - mid) * .5;
1591
+ else t = (v - lo) / (hi - lo || 1);
1592
+ return t < 0 ? 0 : t > 1 ? 1 : t;
1593
+ };
1594
+ /**
1595
+ * Built-in ramps of heatmaps, perceptual (OKLab) and theme-aware: light
1596
+ * themes go from a near-white tint to a deep hue, dark themes from a dark
1597
+ * tint of the surface to a bright saturated hue; diverging ramps meet in a
1598
+ * neutral middle
1599
+ */
1600
+ var heatmapStops = (scheme, color, theme, negative) => {
1601
+ const dark = luminance(theme.background) < .4;
1602
+ if (scheme === "diverging") {
1603
+ const neutral = mixOklab(theme.surface, theme.textMuted, dark ? .12 : .08);
1604
+ const end = (c) => dark ? withLightness(c, .7, 1.25) : withLightness(c, .5, 1.05);
1605
+ const side = (c) => mixOklab(neutral, end(c), .5);
1606
+ return [
1607
+ end(negative),
1608
+ side(negative),
1609
+ neutral,
1610
+ side(color),
1611
+ end(color)
1612
+ ];
1613
+ }
1614
+ return dark ? [
1615
+ mixOklab(theme.surface, color, .14),
1616
+ withLightness(color, .46, .95),
1617
+ withLightness(color, .64, 1.2),
1618
+ withLightness(color, .8, 1.15)
1619
+ ] : [
1620
+ mixOklab(theme.surface, color, .06),
1621
+ withLightness(color, .8, .6),
1622
+ withLightness(color, .58, 1),
1623
+ withLightness(color, .36, .9)
1624
+ ];
1625
+ };
1311
1626
  var buildModel = (options, theme, hidden, cache, resolver = null) => {
1312
1627
  const resolve = resolver ?? theme.resolve ?? ((value, fallback) => resolveStaticColor(value, {}, fallback));
1313
1628
  const input = options.series;
@@ -1325,7 +1640,8 @@ var buildModel = (options, theme, hidden, cache, resolver = null) => {
1325
1640
  const yOpts = options.yAxis;
1326
1641
  const heatmapData = input.filter((s) => s.type === "heatmap").map((s) => s.data);
1327
1642
  const yCategories = yOpts?.type === "category" || !yOpts?.type && heatmapData.length ? [...yOpts?.categories ?? collectYCategories(heatmapData)] : [];
1328
- const yType = yOpts?.type === "category" || yCategories.length ? "category" : yOpts?.type === "time" || !yOpts?.type && hasDateY(datas) ? "time" : "linear";
1643
+ const yType = yOpts?.type === "category" || yCategories.length ? "category" : yOpts?.type === "time" || !yOpts?.type && hasDateY(datas) ? "time" : yOpts?.type === "log" ? "log" : "linear";
1644
+ const yLog = yType === "log";
1329
1645
  const yCategoryMap = new Map(yCategories.map((c, i) => [c, i]));
1330
1646
  const resolveY = (v) => typeof v === "number" ? v : typeof v === "string" ? yType === "category" ? yCategoryMap.get(v) ?? NaN : yType === "time" ? Date.parse(v) : Number(v) : v instanceof Date ? v.getTime() : NaN;
1331
1647
  const resolverKey = `${xType}|${categories.join("")}|${yType}|${yCategories.join("")}`;
@@ -1362,20 +1678,36 @@ var buildModel = (options, theme, hidden, cache, resolver = null) => {
1362
1678
  let colorScale = [];
1363
1679
  let valueRange = [0, 1];
1364
1680
  let cellColors = null;
1681
+ let colorMidpoint = null;
1682
+ let colorLut = null;
1365
1683
  if (type === "heatmap") {
1366
- colorScale = s.colorScale && s.colorScale.length ? s.colorScale.map((c) => resolve(c, color)) : [mix(theme.background, color, .08), color];
1684
+ const scale = s.colorScale;
1685
+ const scheme = scale === "diverging" ? "diverging" : "sequential";
1686
+ colorScale = typeof scale === "object" && scale.length ? scale.map((c) => resolve(c, color)) : heatmapStops(scheme, color, theme, resolve(DEFAULT_DOWN, [
1687
+ .86,
1688
+ .15,
1689
+ .15,
1690
+ 1
1691
+ ]));
1367
1692
  valueRange = s.valueRange ? [s.valueRange[0], s.valueRange[1]] : [cols.valueMin, cols.valueMax];
1368
1693
  if (!Number.isFinite(valueRange[0])) valueRange = [0, 1];
1369
- const values = cols.value ?? cols.y;
1370
1694
  const [lo, hi] = valueRange;
1371
- const span = hi - lo || 1;
1695
+ colorMidpoint = s.colorMidpoint ?? (scheme === "diverging" && typeof scale !== "object" ? lo < 0 && hi > 0 ? 0 : (lo + hi) / 2 : null);
1696
+ const lut = oklabRamp(colorScale);
1697
+ colorLut = lut;
1698
+ const values = cols.value ?? cols.y;
1699
+ const ramp = {
1700
+ valueRange,
1701
+ colorMidpoint
1702
+ };
1372
1703
  cellColors = new Uint32Array(cols.count);
1373
1704
  for (let i = 0; i < cols.count; i++) {
1374
1705
  const v = values[i];
1375
1706
  if (!Number.isFinite(v) || !Number.isFinite(cols.y[i])) continue;
1376
- cellColors[i] = packColor(rampColor(colorScale, (v - lo) / span));
1707
+ cellColors[i] = lut[Math.round(heatPosition(ramp, v) * 255)];
1377
1708
  }
1378
1709
  }
1710
+ const connector = s.connector ? typeof s.connector === "object" ? s.connector : {} : null;
1379
1711
  const id = s.id ?? String(index);
1380
1712
  return {
1381
1713
  index,
@@ -1421,12 +1753,24 @@ var buildModel = (options, theme, hidden, cache, resolver = null) => {
1421
1753
  },
1422
1754
  colorScale,
1423
1755
  valueRange,
1756
+ colorMidpoint,
1757
+ colorLut,
1758
+ tooltip: s.tooltip !== false,
1759
+ outlierShape: s.outlierShape ?? "hollow",
1760
+ outlierSize: s.outlierSize ?? s.pointSize ?? 7,
1761
+ connector: connector && type === "bar" ? {
1762
+ color: connector.color ? resolve(connector.color, theme.textMuted) : theme.textMuted,
1763
+ dash: [...connector.dash ?? [3, 3]],
1764
+ width: connector.width ?? 1
1765
+ } : null,
1424
1766
  radius: s.radius ?? (type === "heatmap" ? 2 : type === "boxplot" ? 0 : 3),
1425
1767
  format: s.format,
1426
1768
  valueName: s.valueName
1427
1769
  };
1428
1770
  });
1429
1771
  const visible = series.filter((s) => !s.hidden);
1772
+ const xLog = xType === "log";
1773
+ if (xLog) for (const s of series) s.cols = logXColumns(s.raw);
1430
1774
  const allScatter = series.length > 0 && series.every((s) => s.type === "scatter" || s.type === "heatmap");
1431
1775
  const slotted = visible.filter((s) => s.type === "bar" || s.type === "boxplot");
1432
1776
  const bars = visible.filter((s) => s.type === "bar");
@@ -1517,18 +1861,24 @@ var buildModel = (options, theme, hidden, cache, resolver = null) => {
1517
1861
  xRange = [xRange[0] - pad, xRange[1] + pad];
1518
1862
  }
1519
1863
  if ((xOpts?.nice ?? (pointsOnly && xType === "linear")) && xType === "linear") xRange = niceDomain(xRange[0], xRange[1], xOpts?.tickCount ?? 6);
1864
+ if (xLog && xOpts?.nice !== false) xRange = decades(xRange);
1520
1865
  }
1521
- if (xOpts?.min !== void 0) xRange[0] = xOpts.min;
1522
- if (xOpts?.max !== void 0) xRange[1] = xOpts.max;
1866
+ const xBound = (v) => xLog ? Math.log10(v) : v;
1867
+ if (xOpts?.min !== void 0) xRange[0] = xBound(xOpts.min);
1868
+ if (xOpts?.max !== void 0) xRange[1] = xBound(xOpts.max);
1523
1869
  xRange = ensureSpan(xRange[0], xRange[1]);
1524
- const valuesOf = (list, zero) => {
1870
+ if (yLog) for (const s of series) {
1871
+ if (s.yAxis === "right" || s.type === "heatmap") continue;
1872
+ logColumns(s, LOG_MAP);
1873
+ }
1874
+ const valuesOf = (list, zero, log = false) => {
1525
1875
  const values = [];
1526
1876
  for (const s of list) if (s.type === "bar" && s.barBase && s.barTop) values.push(...extent(s.barBase), ...extent(s.barTop));
1527
1877
  else if (s.stackBase && s.stackTop) values.push(...extent(s.stackBase), ...extent(s.stackTop));
1528
1878
  else if (s.type === "heatmap") values.push(s.cols.yMin - s.cellHalf.y, s.cols.yMax + s.cellHalf.y);
1529
1879
  else values.push(s.cols.yMin, s.cols.yMax);
1530
1880
  const listBars = list.filter((s) => s.type === "bar");
1531
- if (listBars.some((s) => !s.floating) || zero) values.push(0);
1881
+ if (!log && (listBars.some((s) => !s.floating) || zero)) values.push(0);
1532
1882
  if (listBars.some((s) => s.showLabels)) {
1533
1883
  const [lo, hi] = extent(values);
1534
1884
  if (hi > 0) values.push(hi + (hi - Math.min(0, lo)) * .1);
@@ -1542,7 +1892,7 @@ var buildModel = (options, theme, hidden, cache, resolver = null) => {
1542
1892
  let yRange;
1543
1893
  if (yType === "category") yRange = [-.5, Math.max(1, yCategories.length) - .5];
1544
1894
  else {
1545
- const yValues = valuesOf(leftSeries, yOpts?.zero);
1895
+ const yValues = valuesOf(leftSeries, yOpts?.zero, yLog);
1546
1896
  const filled = leftBars.length > 0 || leftSeries.some((s) => s.type === "area");
1547
1897
  yRange = ensureSpan(...extent(yValues));
1548
1898
  if (series.every((s) => s.type === "scatter")) {
@@ -1553,43 +1903,50 @@ var buildModel = (options, theme, hidden, cache, resolver = null) => {
1553
1903
  yRange = [yRange[0] - pad, yRange[1] + pad];
1554
1904
  }
1555
1905
  if ((yOpts?.nice ?? !heatmaps.length) && yType === "linear") yRange = niceDomain(yRange[0], yRange[1], yOpts?.tickCount ?? 5);
1906
+ if (yLog && yOpts?.nice !== false) yRange = decades(yRange);
1556
1907
  if (percent && (bars.length || stackedLines.length)) yRange = [extent(yValues)[0] < 0 ? -100 : 0, 100];
1557
- if (filled && !yOpts?.zero) {
1908
+ if (filled && !yOpts?.zero && !yLog) {
1558
1909
  if (yRange[0] < 0 && extent(yValues)[0] >= 0) yRange[0] = 0;
1559
1910
  }
1560
1911
  }
1561
- if (yOpts?.min !== void 0) yRange[0] = yOpts.min;
1562
- if (yOpts?.max !== void 0) yRange[1] = yOpts.max;
1912
+ const yBound = (v) => yLog ? Math.log10(v) : v;
1913
+ if (yOpts?.min !== void 0) yRange[0] = yBound(yOpts.min);
1914
+ if (yOpts?.max !== void 0) yRange[1] = yBound(yOpts.max);
1563
1915
  yRange = ensureSpan(yRange[0], yRange[1]);
1916
+ if (yLog) {
1917
+ for (const s of series) if (s.yAxis === "left") floorBases(s, yRange[0]);
1918
+ }
1564
1919
  const y2Opts = options.yAxis2;
1565
1920
  let y2 = null;
1566
1921
  let y2Map = null;
1567
1922
  const rightSeries = series.filter((s) => s.yAxis === "right");
1568
1923
  if (rightSeries.length && yType !== "category") {
1569
- const [lo, hi] = ensureSpan(...extent(valuesOf(rightSeries.filter((s) => !s.hidden), y2Opts?.zero)));
1570
- let domain = y2Opts?.nice === false ? [lo, hi] : alignedDomain(lo, hi, yRange, yOpts?.tickCount ?? 5);
1571
- if (y2Opts?.min !== void 0) domain[0] = y2Opts.min;
1572
- if (y2Opts?.max !== void 0) domain[1] = y2Opts.max;
1924
+ const y2Log = y2Opts?.type === "log";
1925
+ const rightVisible = rightSeries.filter((s) => !s.hidden);
1926
+ const [lo, hi] = ensureSpan(...extent(y2Log ? rightVisible.flatMap((s) => {
1927
+ const c = mapColumns(s.raw, LOG_MAP);
1928
+ return [c.yMin, c.yMax];
1929
+ }) : valuesOf(rightVisible, y2Opts?.zero)));
1930
+ let domain = y2Opts?.nice === false ? [lo, hi] : y2Log ? decades([lo, hi]) : alignedDomain(lo, hi, yRange, yOpts?.tickCount ?? 5);
1931
+ const y2Bound = (v) => y2Log ? Math.log10(v) : v;
1932
+ if (y2Opts?.min !== void 0) domain[0] = y2Bound(y2Opts.min);
1933
+ if (y2Opts?.max !== void 0) domain[1] = y2Bound(y2Opts.max);
1573
1934
  domain = ensureSpan(domain[0], domain[1]);
1574
1935
  const scale = (yRange[1] - yRange[0]) / (domain[1] - domain[0]);
1575
1936
  const map = {
1576
1937
  scale,
1577
- offset: yRange[0] - domain[0] * scale
1938
+ offset: yRange[0] - domain[0] * scale,
1939
+ log: y2Log
1578
1940
  };
1579
1941
  y2Map = map;
1580
- const f = (v) => v * map.scale + map.offset;
1581
- const column = (a) => a ? a.map(f) : null;
1582
- const zero = f(Math.min(Math.max(0, domain[0]), domain[1]));
1942
+ const zero = y2Log ? yRange[0] : mapper(map)(Math.min(Math.max(0, domain[0]), domain[1]));
1583
1943
  for (const s of rightSeries) {
1584
- const rawBase = s.stackBase;
1585
- s.cols = mapColumns(s.raw, map);
1586
- s.barBase = column(s.barBase);
1587
- s.barTop = column(s.barTop);
1588
- s.stackTop = column(s.stackTop);
1589
- s.stackBase = rawBase && rawBase === s.raw.y0 ? s.cols.y0 : rawBase ? column(rawBase) : s.type === "area" ? new Float64Array(s.cols.count).fill(zero) : null;
1944
+ logColumns(s, map, zero);
1945
+ floorBases(s, yRange[0]);
1590
1946
  }
1591
- y2 = axisModel(y2Opts, "linear", [], false, locale);
1947
+ y2 = axisModel(y2Opts, y2Log ? "log" : "linear", [], false, locale);
1592
1948
  }
1949
+ const timeline = yType === "time" && series.some((s) => s.type === "bar") && series.every((s) => s.type === "bar" ? s.floating : s.type === "scatter");
1593
1950
  const zoomOption = options.interaction === false ? false : options.interaction === true || options.interaction === void 0 ? true : options.interaction.zoom ?? true;
1594
1951
  const zoomAxes = zoomOption === false ? {
1595
1952
  x: false,
@@ -1621,8 +1978,8 @@ var buildModel = (options, theme, hidden, cache, resolver = null) => {
1621
1978
  },
1622
1979
  allScatter,
1623
1980
  zoom: zoomAxes,
1624
- tooltipMode: tooltipOptions?.mode ?? (allScatter ? "nearest" : "axis"),
1625
- baseline: Math.min(Math.max(0, yRange[0]), yRange[1]),
1981
+ tooltipMode: tooltipOptions?.mode ?? (allScatter ? "nearest" : timeline ? "item" : "axis"),
1982
+ baseline: yLog ? yRange[0] : Math.min(Math.max(0, yRange[0]), yRange[1]),
1626
1983
  minSpan: {
1627
1984
  x: xType === "category" ? 1 : (xRange[1] - xRange[0]) * 1e-7,
1628
1985
  y: yType === "category" ? 1 : (yRange[1] - yRange[0]) * 1e-7
@@ -1884,6 +2241,40 @@ var placeLabels = (labels, plot, measure, height, occupied = []) => {
1884
2241
  }
1885
2242
  return placed;
1886
2243
  };
2244
+ /** Elbow arrows: polylines with rounded corners and filled heads */
2245
+ var drawArrows = (ctx, arrows) => {
2246
+ for (const a of arrows) {
2247
+ const pts = a.points;
2248
+ const first = pts[0];
2249
+ if (!first) continue;
2250
+ ctx.strokeStyle = a.color;
2251
+ ctx.fillStyle = a.color;
2252
+ ctx.lineWidth = a.width;
2253
+ ctx.lineJoin = "round";
2254
+ ctx.setLineDash([]);
2255
+ ctx.beginPath();
2256
+ ctx.moveTo(first.x, first.y);
2257
+ for (let i = 1; i < pts.length; i++) {
2258
+ const p = pts[i];
2259
+ const next = pts[i + 1];
2260
+ const prev = pts[i - 1];
2261
+ if (next && typeof ctx.arcTo === "function") {
2262
+ const r = Math.min(4, Math.hypot(p.x - prev.x, p.y - prev.y) / 2, Math.hypot(next.x - p.x, next.y - p.y) / 2);
2263
+ ctx.arcTo(p.x, p.y, next.x, next.y, r);
2264
+ } else ctx.lineTo(p.x, p.y);
2265
+ }
2266
+ ctx.stroke();
2267
+ const [tip, b0, b1] = a.head;
2268
+ if (tip && b0 && b1) {
2269
+ ctx.beginPath();
2270
+ ctx.moveTo(tip.x, tip.y);
2271
+ ctx.lineTo(b0.x, b0.y);
2272
+ ctx.lineTo(b1.x, b1.y);
2273
+ ctx.closePath();
2274
+ ctx.fill();
2275
+ }
2276
+ }
2277
+ };
1887
2278
  var drawForeground = (ctx, input) => {
1888
2279
  const { scales, theme } = input;
1889
2280
  const { plot } = scales;
@@ -1892,6 +2283,20 @@ var drawForeground = (ctx, input) => {
1892
2283
  ctx.beginPath();
1893
2284
  ctx.rect(plot.x, plot.y, plot.width, plot.height);
1894
2285
  ctx.clip();
2286
+ for (const c of input.connectors ?? []) {
2287
+ ctx.strokeStyle = c.color;
2288
+ ctx.lineWidth = c.width;
2289
+ ctx.setLineDash([...c.dash]);
2290
+ ctx.beginPath();
2291
+ const along = c.y0 === c.y1;
2292
+ const x0 = along ? c.x0 : crisp(c.x0);
2293
+ const y0 = along ? crisp(c.y0) : c.y0;
2294
+ ctx.moveTo(x0, y0);
2295
+ ctx.lineTo(along ? c.x1 : x0, along ? y0 : c.y1);
2296
+ ctx.stroke();
2297
+ }
2298
+ ctx.setLineDash([]);
2299
+ if (input.arrows?.length) drawArrows(ctx, input.arrows);
1895
2300
  const halo = toCss(theme.background, .9);
1896
2301
  const occupied = [];
1897
2302
  const labelHeight = theme.fontSize + 4;
@@ -2302,6 +2707,7 @@ var axisTicks = (axis, range, count) => {
2302
2707
  }
2303
2708
  const values = linearTicks(min, max, count);
2304
2709
  const step = tickStep(min, max, count);
2710
+ if (axis.type === "log") return logTicks(axis, min, max, count);
2305
2711
  const tick = axis.format ?? tickFormatter(step, Math.max(Math.abs(min), Math.abs(max)), axis.locale);
2306
2712
  return {
2307
2713
  values,
@@ -2309,6 +2715,41 @@ var axisTicks = (axis, range, count) => {
2309
2715
  formatValue: axis.format ?? ((value) => formatValue(value, axis.locale))
2310
2716
  };
2311
2717
  };
2718
+ /**
2719
+ * Ticks of a log axis (`min` / `max` are exponents): every decade, with 2
2720
+ * and 5 between them on short ranges, every few decades on long ones;
2721
+ * labelled with the values (`1k`, `10k`)
2722
+ */
2723
+ var logTicks = (axis, min, max, count) => {
2724
+ const span = max - min;
2725
+ const values = [];
2726
+ const raw = [];
2727
+ const push = (v) => {
2728
+ const e = Math.log10(v);
2729
+ if (e >= min - 1e-9 && e <= max + 1e-9) {
2730
+ values.push(e);
2731
+ raw.push(v);
2732
+ }
2733
+ };
2734
+ if (span < 1) {
2735
+ for (const v of linearTicks(10 ** min, 10 ** max, count)) if (v > 0) push(v);
2736
+ } else {
2737
+ const every = Math.max(1, Math.ceil(span / Math.max(1, count)));
2738
+ const between = span * 3 <= count * 1.6 ? [2, 5] : [];
2739
+ for (let e = Math.floor(min); e <= Math.ceil(max); e++) {
2740
+ if (e % every !== 0) continue;
2741
+ const decade = Number((10 ** e).toPrecision(12));
2742
+ push(decade);
2743
+ for (const m of between) push(Number((m * decade).toPrecision(12)));
2744
+ }
2745
+ }
2746
+ const label = axis.format ?? ((v) => formatCompact(v, 2, axis.locale));
2747
+ return {
2748
+ values,
2749
+ labels: raw.map(label),
2750
+ formatValue: axis.format ?? ((value) => formatValue(value, axis.locale))
2751
+ };
2752
+ };
2312
2753
  var DEFAULT_PADDING = {
2313
2754
  top: 12,
2314
2755
  right: 16,
@@ -2316,18 +2757,23 @@ var DEFAULT_PADDING = {
2316
2757
  left: 4
2317
2758
  };
2318
2759
  var fallbackResolve = (_value, fallback) => fallback;
2319
- /** Annotation colors resolved against the theme */
2320
- var resolveAnnotations = (annotations, theme) => {
2760
+ /**
2761
+ * Annotation colors resolved against the theme; `mapY` / `mapX` turn values
2762
+ * into plotted units (log axes)
2763
+ */
2764
+ var resolveAnnotations = (annotations, theme, mapY, mapX) => {
2321
2765
  const resolve = theme.resolve ?? fallbackResolve;
2766
+ const y = (v) => mapY && v !== void 0 ? mapY(v) : v;
2767
+ const x = (v) => mapX && v !== void 0 ? mapX(v) : v;
2322
2768
  return (annotations ?? []).map((a) => {
2323
2769
  if (a.type === "rect") {
2324
2770
  const color = a.color ? resolve(a.color, theme.primary) : theme.primary;
2325
2771
  return {
2326
2772
  type: "rect",
2327
- x0: a.x0,
2328
- x1: a.x1,
2329
- y0: a.y0,
2330
- y1: a.y1,
2773
+ x0: x(a.x0),
2774
+ x1: x(a.x1),
2775
+ y0: y(a.y0),
2776
+ y1: y(a.y1),
2331
2777
  color,
2332
2778
  opacity: a.opacity ?? .08,
2333
2779
  label: a.label,
@@ -2337,8 +2783,8 @@ var resolveAnnotations = (annotations, theme) => {
2337
2783
  }
2338
2784
  if (a.type === "text") return {
2339
2785
  type: "text",
2340
- x: a.x,
2341
- y: a.y,
2786
+ x: x(a.x),
2787
+ y: y(a.y),
2342
2788
  text: a.text,
2343
2789
  anchor: a.anchor ?? "center",
2344
2790
  color: a.color ? resolve(a.color, theme.textMuted) : theme.textMuted,
@@ -2347,7 +2793,7 @@ var resolveAnnotations = (annotations, theme) => {
2347
2793
  return {
2348
2794
  type: "line",
2349
2795
  axis: a.axis,
2350
- value: a.value,
2796
+ value: a.axis === "y" ? y(a.value) : x(a.value),
2351
2797
  color: a.color ? resolve(a.color, theme.textMuted) : theme.textMuted,
2352
2798
  width: a.width ?? 1,
2353
2799
  dash: [...a.dash ?? [4, 4]],
@@ -2363,7 +2809,7 @@ var layoutChart = (input) => {
2363
2809
  const yTicks = axisTicks(model.y, view.y, yCount);
2364
2810
  let yLabelWidth = 0;
2365
2811
  if (model.y.visible) for (const label of yTicks.labels) yLabelWidth = Math.max(yLabelWidth, measure(label));
2366
- const y2Ticks = rightTicks(model, yTicks);
2812
+ const y2Ticks = rightTicks(model, yTicks, view.y, yCount);
2367
2813
  let y2LabelWidth = 0;
2368
2814
  if (y2Ticks && model.y2?.visible) for (const label of y2Ticks.labels) y2LabelWidth = Math.max(y2LabelWidth, measure(label));
2369
2815
  let categoryWidth = 48;
@@ -2398,11 +2844,23 @@ var layoutChart = (input) => {
2398
2844
  y2Ticks
2399
2845
  };
2400
2846
  };
2401
- /** Right axis ticks: the left ticks labelled in right axis units */
2402
- var rightTicks = (model, yTicks) => {
2847
+ /**
2848
+ * Right axis ticks: the left ticks labelled in right axis units; log axes
2849
+ * get their own decades
2850
+ */
2851
+ var rightTicks = (model, yTicks, view, count) => {
2403
2852
  const axis = model.y2;
2404
2853
  const map = model.y2Map;
2405
2854
  if (!axis || !map || !map.scale) return null;
2855
+ if (map.log) {
2856
+ const a = (view[0] - map.offset) / map.scale;
2857
+ const b = (view[1] - map.offset) / map.scale;
2858
+ const ticks = axisTicks(axis, [Math.min(a, b), Math.max(a, b)], count);
2859
+ return {
2860
+ ...ticks,
2861
+ values: ticks.values.map((e) => e * map.scale + map.offset)
2862
+ };
2863
+ }
2406
2864
  const raw = yTicks.values.map((v) => (v - map.offset) / map.scale);
2407
2865
  const step = raw.length > 1 ? Math.abs(raw[1] - raw[0]) : 1;
2408
2866
  let maxAbs = 0;
@@ -2546,6 +3004,25 @@ var candidateOf = (s, i, px, py, sc) => {
2546
3004
  inside
2547
3005
  };
2548
3006
  };
3007
+ /** Outlier of a box under a pixel (`undefined` when none is in reach) */
3008
+ var outlierAt = (s, i, px, py, sc, slop) => {
3009
+ const list = s.cols.outliers?.[i];
3010
+ if (!list) return void 0;
3011
+ const center = sc.xToPx(s.cols.x[i] + slotOffset(s));
3012
+ const ax = alongX(sc, px, py) - center;
3013
+ const ay = alongY(sc, px, py);
3014
+ const reach = s.outlierSize / 2 + 4 + slop;
3015
+ let best;
3016
+ let bestDist = reach;
3017
+ list.forEach((v, k) => {
3018
+ const d = Math.hypot(ax, sc.yToPx(v) - ay);
3019
+ if (d <= bestDist) {
3020
+ bestDist = d;
3021
+ best = s.raw.outliers?.[i]?.[k] ?? v;
3022
+ }
3023
+ });
3024
+ return best;
3025
+ };
2549
3026
  /** Diameter of a scatter dot */
2550
3027
  var dotSize = (s, i) => s.cols.size && s.cols.size[i] > 0 ? s.cols.size[i] : s.pointSize;
2551
3028
  var maxSizes = /* @__PURE__ */ new WeakMap();
@@ -2648,7 +3125,11 @@ var hoverItemOf = (s, index) => {
2648
3125
  var eventOf = (candidates, xTicks) => {
2649
3126
  if (!candidates.length) return null;
2650
3127
  candidates.sort((a, b) => a.series.index - b.series.index);
2651
- const items = candidates.map((c) => hoverItemOf(c.series, c.index));
3128
+ const items = candidates.map((c) => {
3129
+ const item = hoverItemOf(c.series, c.index);
3130
+ if (c.outlier !== void 0) item.outlier = c.outlier;
3131
+ return item;
3132
+ });
2652
3133
  const x = items[0].x;
2653
3134
  return {
2654
3135
  items,
@@ -2669,7 +3150,7 @@ var hitTest = (model, sc, xTicks, px, py, slop = 0) => {
2669
3150
  const scatter = [];
2670
3151
  const others = [];
2671
3152
  for (const s of model.series) {
2672
- if (s.hidden || s.cols.count === 0) continue;
3153
+ if (s.hidden || !s.tooltip || s.cols.count === 0) continue;
2673
3154
  if (s.type === "scatter") {
2674
3155
  const i = nearestScatter(s, px, py, sc, slop);
2675
3156
  if (i >= 0) scatter.push(candidateOf(s, i, px, py, sc));
@@ -2683,9 +3164,23 @@ var hitTest = (model, sc, xTicks, px, py, slop = 0) => {
2683
3164
  }
2684
3165
  } else {
2685
3166
  const i = nearestX(s, at.x);
2686
- if (i >= 0) others.push(candidateOf(s, i, px, py, sc));
3167
+ if (i < 0) continue;
3168
+ const c = candidateOf(s, i, px, py, sc);
3169
+ if (s.type === "boxplot") {
3170
+ c.outlier = outlierAt(s, i, px, py, sc, slop);
3171
+ if (c.outlier !== void 0) {
3172
+ c.inside = true;
3173
+ c.dist = 0;
3174
+ }
3175
+ }
3176
+ others.push(c);
2687
3177
  }
2688
3178
  }
3179
+ if (model.tooltipMode === "item") {
3180
+ const all = [...scatter, ...others].filter((c) => c.inside || c.series.type === "scatter" || (c.series.type === "line" || c.series.type === "area") && c.dist <= 8 + slop);
3181
+ if (!all.length) return null;
3182
+ return eventOf([all.reduce((a, b) => b.dist < a.dist || b.dist === a.dist && b.series.index > a.series.index ? b : a)], xTicks);
3183
+ }
2689
3184
  if (model.tooltipMode === "nearest") {
2690
3185
  const all = [...scatter, ...others].filter((c) => c.inside || c.series.type === "scatter" || c.dist <= 32 + slop);
2691
3186
  if (!all.length) return null;
@@ -2718,6 +3213,12 @@ var CHANGE_PERCENT = {
2718
3213
  minimumFractionDigits: 2,
2719
3214
  maximumFractionDigits: 2
2720
3215
  };
3216
+ /** Extra rows of a point (`details` of its datum) */
3217
+ var detailRows = (s, index) => s.raw.details?.[index]?.map((d) => ({
3218
+ color: null,
3219
+ name: d.name,
3220
+ value: d.value
3221
+ })) ?? [];
2721
3222
  /**
2722
3223
  * Default tooltip content of a hover payload; `y2Ticks` formats the values
2723
3224
  * of the right axis series
@@ -2728,6 +3229,32 @@ var tooltipContent$1 = (model, event, yTicks, y2Ticks = null) => {
2728
3229
  const names = model.labels;
2729
3230
  const first = event.items[0];
2730
3231
  const firstSeries = first ? model.series[first.seriesIndex] : null;
3232
+ if (event.items.length === 1 && first && firstSeries?.type === "bar" && first.y0 !== void 0 && model.y.type === "time") {
3233
+ const format = formatOf(firstSeries);
3234
+ return {
3235
+ title: first.label ?? event.xLabel,
3236
+ titleColor: first.color,
3237
+ subtitle: first.label !== void 0 ? `${event.xLabel} · ${firstSeries.name}` : firstSeries.name,
3238
+ rows: [
3239
+ {
3240
+ color: null,
3241
+ name: names.start,
3242
+ value: format(first.y0)
3243
+ },
3244
+ {
3245
+ color: null,
3246
+ name: names.end,
3247
+ value: format(first.y)
3248
+ },
3249
+ {
3250
+ color: null,
3251
+ name: names.duration,
3252
+ value: formatDuration(first.y - first.y0, model.locale)
3253
+ },
3254
+ ...detailRows(firstSeries, first.index)
3255
+ ]
3256
+ };
3257
+ }
2731
3258
  if (event.items.length === 1 && firstSeries?.type === "heatmap") {
2732
3259
  const yName = model.y.type === "category" ? model.y.categories[Math.round(first.y)] ?? yFormat(first.y) : yFormat(first.y);
2733
3260
  return {
@@ -2737,7 +3264,7 @@ var tooltipContent$1 = (model, event, yTicks, y2Ticks = null) => {
2737
3264
  color: first.color,
2738
3265
  name: first.label ?? firstSeries.name,
2739
3266
  value: first.value === void 0 ? "–" : (firstSeries.format ?? model.formatValue)(first.value)
2740
- }]
3267
+ }, ...detailRows(firstSeries, first.index)]
2741
3268
  };
2742
3269
  }
2743
3270
  if (event.items.every((it) => model.series[it.seriesIndex].type === "scatter") && event.items.length === 1) {
@@ -2751,12 +3278,17 @@ var tooltipContent$1 = (model, event, yTicks, y2Ticks = null) => {
2751
3278
  if (model.x.type === "category") return {
2752
3279
  title: it.label ?? event.xLabel,
2753
3280
  titleColor: null,
2754
- rows: [{
2755
- color: it.color,
2756
- name: it.seriesName,
2757
- value: formatOf(s)(it.y)
2758
- }, ...valueRow]
3281
+ rows: [
3282
+ {
3283
+ color: it.color,
3284
+ name: it.seriesName,
3285
+ value: formatOf(s)(it.y)
3286
+ },
3287
+ ...valueRow,
3288
+ ...detailRows(s, it.index)
3289
+ ]
2759
3290
  };
3291
+ const yAxisFormat = s.yAxis === "right" ? y2Ticks?.formatValue ?? model.y2?.format ?? model.formatValue : yFormat;
2760
3292
  const rows = [
2761
3293
  {
2762
3294
  color: null,
@@ -2766,18 +3298,15 @@ var tooltipContent$1 = (model, event, yTicks, y2Ticks = null) => {
2766
3298
  {
2767
3299
  color: null,
2768
3300
  name: (s.yAxis === "right" ? model.y2?.title : model.y.title) ?? names.y,
2769
- value: formatOf(s)(it.y)
3301
+ value: (it.value !== void 0 ? yAxisFormat : formatOf(s))(it.y)
2770
3302
  },
2771
- ...valueRow
3303
+ ...valueRow,
3304
+ ...detailRows(s, it.index)
2772
3305
  ];
2773
- if (it.label !== void 0 && model.series.length > 1) rows.push({
2774
- color: null,
2775
- name: "",
2776
- value: it.seriesName
2777
- });
2778
3306
  return {
2779
3307
  title: it.label ?? it.seriesName,
2780
3308
  titleColor: it.color,
3309
+ ...it.label !== void 0 && model.series.length > 1 ? { subtitle: it.seriesName } : {},
2781
3310
  rows
2782
3311
  };
2783
3312
  }
@@ -2810,6 +3339,18 @@ var tooltipContent$1 = (model, event, yTicks, y2Ticks = null) => {
2810
3339
  continue;
2811
3340
  }
2812
3341
  if (s.type === "boxplot") {
3342
+ if (it.outlier !== void 0) {
3343
+ rows.push({
3344
+ color: it.color,
3345
+ name: it.label ? `${it.seriesName} · ${it.label}` : it.seriesName,
3346
+ value: ""
3347
+ }, {
3348
+ color: null,
3349
+ name: names.outlier,
3350
+ value: format(it.outlier)
3351
+ });
3352
+ continue;
3353
+ }
2813
3354
  rows.push({
2814
3355
  color: it.color,
2815
3356
  name: it.label ? `${it.seriesName} · ${it.label}` : it.seriesName,
@@ -2844,6 +3385,7 @@ var tooltipContent$1 = (model, event, yTicks, y2Ticks = null) => {
2844
3385
  name: it.label && binTitle === null ? `${it.seriesName} · ${it.label}` : it.seriesName,
2845
3386
  value
2846
3387
  });
3388
+ rows.push(...detailRows(s, it.index));
2847
3389
  }
2848
3390
  if (model.percent) {
2849
3391
  const totals = /* @__PURE__ */ new Map();
@@ -2874,21 +3416,62 @@ var hoverMarks = (model, sc, event) => {
2874
3416
  let bandHi = -Infinity;
2875
3417
  for (const it of event.items) {
2876
3418
  const s = model.series[it.seriesIndex];
3419
+ const itX = s.cols.x[it.index] ?? it.x;
3420
+ if (s.type === "boxplot" && it.outlier !== void 0) {
3421
+ const p = toScreen(sc, itX + slotOffset(s), plottedOutlier(s, it));
3422
+ marks.push({
3423
+ kind: "dot",
3424
+ x: p.x,
3425
+ y: p.y,
3426
+ size: s.outlierSize + 3,
3427
+ color: it.color,
3428
+ halo: toCss(s.pointColors?.[it.index] ?? s.color, .2)
3429
+ });
3430
+ continue;
3431
+ }
2877
3432
  if (s.type === "bar" || s.type === "candlestick" || s.type === "boxplot") {
2878
- const c = sc.xToPx(it.x + slotOffset(s));
3433
+ const c = sc.xToPx(itX + slotOffset(s));
2879
3434
  const half = Math.max(s.barHalfWidth / Math.abs(sc.xPerPx), 1);
2880
3435
  bandLo = Math.min(bandLo, c - half);
2881
3436
  bandHi = Math.max(bandHi, c + half);
2882
3437
  continue;
2883
3438
  }
2884
3439
  if (s.type === "heatmap") {
2885
- const cx = sc.xToPx(it.x);
3440
+ const cx = sc.xToPx(itX);
2886
3441
  const cy = sc.yToPx(it.y);
2887
3442
  const hw = Math.abs(s.cellHalf.x / sc.xPerPx);
2888
3443
  const hh = Math.abs(s.cellHalf.y / sc.yPerPx);
3444
+ const cell = screenRect(sc, cx - hw, cx + hw, cy - hh, cy + hh);
3445
+ const style = heatCellStyle(cell.width, cell.height, s.radius);
3446
+ const top = Math.max(plot.y, cell.y);
3447
+ const bottom = Math.min(plot.y + plot.height, cell.y + cell.height);
3448
+ const left = Math.max(plot.x, cell.x);
3449
+ const right = Math.min(plot.x + plot.width, cell.x + cell.width);
3450
+ if (bottom > top) marks.push({
3451
+ kind: "guide",
3452
+ x: plot.x,
3453
+ y: top,
3454
+ width: plot.width,
3455
+ height: bottom - top
3456
+ });
3457
+ if (right > left) marks.push({
3458
+ kind: "guide",
3459
+ x: left,
3460
+ y: plot.y,
3461
+ width: right - left,
3462
+ height: plot.height
3463
+ });
3464
+ const packed = s.cellColors?.[it.index];
3465
+ const fill = packed ? unpackColor(packed) : s.color;
2889
3466
  marks.push({
2890
3467
  kind: "cell",
2891
- ...screenRect(sc, cx - hw, cx + hw, cy - hh, cy + hh)
3468
+ x: cell.x + style.inset,
3469
+ y: cell.y + style.inset,
3470
+ width: Math.max(1, cell.width - style.inset * 2),
3471
+ height: Math.max(1, cell.height - style.inset * 2),
3472
+ color: it.color,
3473
+ ring: contrastRing(fill),
3474
+ radius: style.radius
2892
3475
  });
2893
3476
  continue;
2894
3477
  }
@@ -2928,6 +3511,190 @@ var hoverMarks = (model, sc, event) => {
2928
3511
  }
2929
3512
  return marks;
2930
3513
  };
3514
+ /** Ring of a hovered cell: light on dark fills, dark on light ones */
3515
+ var contrastRing = (fill) => luminance(fill) > .45 ? "rgba(15, 23, 42, 0.78)" : "rgba(255, 255, 255, 0.9)";
3516
+ /** Plotted value of the hovered outlier of a box */
3517
+ var plottedOutlier = (s, it) => {
3518
+ const raw = s.raw.outliers?.[it.index];
3519
+ const k = raw ? raw.indexOf(it.outlier ?? NaN) : -1;
3520
+ return (k >= 0 ? s.cols.outliers?.[it.index]?.[k] : void 0) ?? it.outlier ?? 0;
3521
+ };
3522
+ /**
3523
+ * Connectors of the bar series (`connector`, waterfalls): from the end of
3524
+ * every bar to the next bar, at the value where the next one starts
3525
+ */
3526
+ var connectorSegments = (model, sc) => {
3527
+ const out = [];
3528
+ for (const s of model.series) {
3529
+ const c = s.connector;
3530
+ if (!c || s.hidden || s.type !== "bar" || !s.barTop) continue;
3531
+ const { x, count } = s.cols;
3532
+ const top = s.barTop;
3533
+ const half = s.barHalfWidth;
3534
+ const [v0, v1] = sc.view.x[0] <= sc.view.x[1] ? sc.view.x : [sc.view.x[1], sc.view.x[0]];
3535
+ const color = toCss(c.color, .75);
3536
+ let prev = -1;
3537
+ for (let i = 0; i < count && out.length < 1200; i++) {
3538
+ if (!Number.isFinite(top[i]) || !Number.isFinite(x[i])) continue;
3539
+ if (prev >= 0 && x[i] + half >= v0 && x[prev] - half <= v1) {
3540
+ const a = toScreen(sc, x[prev] + s.barOffset + half, top[prev]);
3541
+ const b = toScreen(sc, x[i] + s.barOffset - half, top[prev]);
3542
+ out.push({
3543
+ x0: a.x,
3544
+ y0: a.y,
3545
+ x1: b.x,
3546
+ y1: b.y,
3547
+ color,
3548
+ width: c.width,
3549
+ dash: c.dash
3550
+ });
3551
+ }
3552
+ prev = i;
3553
+ }
3554
+ }
3555
+ return out;
3556
+ };
3557
+ /** Colors of the dependency arrows (resolved once per options / theme) */
3558
+ var resolveDependencies = (dependencies, theme) => {
3559
+ const resolve = theme.resolve ?? fallbackResolve;
3560
+ const muted = toCss(theme.textMuted, .85);
3561
+ return (dependencies ?? []).map((d) => ({
3562
+ from: d.from,
3563
+ to: d.to,
3564
+ color: d.color ? toCss(resolve(d.color, theme.textMuted)) : muted
3565
+ }));
3566
+ };
3567
+ /** Length and half width of the arrowheads, in CSS pixels */
3568
+ var ARROW_HEAD = {
3569
+ length: 6,
3570
+ half: 3.5
3571
+ };
3572
+ /** Bars (or dots) of every category, the first visible one per category */
3573
+ var rowSpans = (model, sc) => {
3574
+ const rows = /* @__PURE__ */ new Map();
3575
+ for (const s of model.series) {
3576
+ if (s.hidden || !s.tooltip) continue;
3577
+ if (s.type !== "bar" && s.type !== "scatter") continue;
3578
+ const { x, y, count } = s.cols;
3579
+ const bar = s.type === "bar" && s.barBase && s.barTop;
3580
+ const half = bar ? s.barHalfWidth / Math.abs(sc.xPerPx) : dotSize(s, 0) / 2;
3581
+ for (let i = 0; i < count; i++) {
3582
+ const k = Math.round(x[i]);
3583
+ if (rows.has(k)) continue;
3584
+ const start = bar ? s.barBase[i] : y[i];
3585
+ const end = bar ? s.barTop[i] : y[i];
3586
+ if (!Number.isFinite(start) || !Number.isFinite(end)) continue;
3587
+ rows.set(k, {
3588
+ at: x[i] + slotOffset(s),
3589
+ start: Math.min(start, end),
3590
+ end: Math.max(start, end),
3591
+ half,
3592
+ dot: !bar
3593
+ });
3594
+ }
3595
+ }
3596
+ return rows;
3597
+ };
3598
+ /**
3599
+ * Dependency arrows (`dependencies`, Gantt charts): from the end of the
3600
+ * predecessor to the start of the successor; when the successor starts
3601
+ * too early the line turns around between the rows
3602
+ */
3603
+ var dependencyArrows = (model, sc, dependencies) => {
3604
+ if (!dependencies.length || model.x.type !== "category") return [];
3605
+ const rows = rowSpans(model, sc);
3606
+ const index = /* @__PURE__ */ new Map();
3607
+ model.x.categories.forEach((c, i) => {
3608
+ if (!index.has(c)) index.set(c, i);
3609
+ });
3610
+ const horizontal = sc.horizontal;
3611
+ const pt = (v, c) => horizontal ? {
3612
+ x: v,
3613
+ y: c
3614
+ } : {
3615
+ x: c,
3616
+ y: v
3617
+ };
3618
+ const valuePx = (value) => {
3619
+ const p = toScreen(sc, 0, value);
3620
+ return horizontal ? p.x : p.y;
3621
+ };
3622
+ const categoryPx = (at) => {
3623
+ const p = toScreen(sc, at, 0);
3624
+ return horizontal ? p.y : p.x;
3625
+ };
3626
+ const dir = Math.sign(valuePx(sc.view.y[1]) - valuePx(sc.view.y[0])) || 1;
3627
+ const rowPx = Math.abs(categoryPx(1) - categoryPx(0));
3628
+ const { length, half } = ARROW_HEAD;
3629
+ const gap = 8;
3630
+ const out = [];
3631
+ for (const d of dependencies) {
3632
+ const a = rows.get(index.get(d.from) ?? NaN);
3633
+ const b = rows.get(index.get(d.to) ?? NaN);
3634
+ if (!a || !b || a === b) continue;
3635
+ const ev = valuePx(a.end) + (a.dot ? dir * a.half : 0);
3636
+ const ca = categoryPx(a.at);
3637
+ const sv = valuePx(b.start) - dir * (b.dot ? b.half + 1 : 1);
3638
+ const cb = categoryPx(b.at);
3639
+ const base = sv - dir * length;
3640
+ const points = [pt(ev, ca)];
3641
+ const exit = ev + dir * gap;
3642
+ if (dir * (base - exit) >= 0) points.push(pt(exit, ca), pt(exit, cb), pt(base, cb));
3643
+ else {
3644
+ const between = ca + (Math.sign(cb - ca) || 1) * Math.max(a.half + 3, rowPx / 2);
3645
+ const back = base - dir * gap;
3646
+ points.push(pt(exit, ca), pt(exit, between), pt(back, between), pt(back, cb), pt(base, cb));
3647
+ }
3648
+ out.push({
3649
+ points,
3650
+ head: [
3651
+ pt(sv, cb),
3652
+ pt(base, cb - half),
3653
+ pt(base, cb + half)
3654
+ ],
3655
+ color: d.color,
3656
+ width: 1.25
3657
+ });
3658
+ }
3659
+ return out;
3660
+ };
3661
+ var COLOR_STOPS = 12;
3662
+ /**
3663
+ * Color legend of a heatmap chart (every series is a heatmap; the first
3664
+ * visible one), `null` otherwise
3665
+ */
3666
+ var colorLegend = (model) => {
3667
+ if (!model.series.length || model.series.some((s) => s.type !== "heatmap")) return null;
3668
+ const s = model.series.find((it) => !it.hidden && it.colorLut);
3669
+ const lut = s?.colorLut;
3670
+ if (!s || !lut) return null;
3671
+ const stops = [];
3672
+ for (let k = 0; k < COLOR_STOPS; k++) {
3673
+ const packed = lut[Math.round(k / 11 * (lut.length - 1))];
3674
+ stops.push(toCss(unpackColor(packed ?? 0)));
3675
+ }
3676
+ const format = s.format ?? model.formatValue;
3677
+ const [lo, hi] = s.valueRange;
3678
+ const labels = [{
3679
+ at: 0,
3680
+ text: format(lo)
3681
+ }, {
3682
+ at: 1,
3683
+ text: format(hi)
3684
+ }];
3685
+ const mid = s.colorMidpoint;
3686
+ if (mid !== null && mid > lo && mid < hi) labels.splice(1, 0, {
3687
+ at: .5,
3688
+ text: format(mid)
3689
+ });
3690
+ return {
3691
+ seriesIndex: s.index,
3692
+ stops,
3693
+ labels
3694
+ };
3695
+ };
3696
+ /** Whether the legend shows (`legend` option; heatmaps get their color legend) */
3697
+ var legendShown = (option, model, named) => option === void 0 ? named > 1 || colorLegend(model) !== null : !!option;
2931
3698
  /** Swatch of a series in the legend */
2932
3699
  var legendShape = (type) => type === "scatter" ? "dot" : type === "line" ? "line" : "square";
2933
3700
  /** Whether the guide line follows the pointer */
@@ -2941,7 +3708,8 @@ var showsCrosshair = (model, event, crosshair) => crosshair ?? (model.tooltipMod
2941
3708
  /** Pixel of the guide line along the x axis (`null` when hidden / outside the plot) */
2942
3709
  var crosshairAt = (model, sc, event, crosshair) => {
2943
3710
  if (!showsCrosshair(model, event, crosshair)) return null;
2944
- const c = sc.xToPx(event.items[0].x);
3711
+ const first = event.items[0];
3712
+ const c = sc.xToPx(model.series[first.seriesIndex]?.cols.x[first.index] ?? toPlotX(model, first.x));
2945
3713
  const lo = sc.horizontal ? sc.plot.y : sc.plot.x;
2946
3714
  const hi = lo + (sc.horizontal ? sc.plot.height : sc.plot.width);
2947
3715
  return c >= lo && c <= hi ? c : null;
@@ -3072,6 +3840,7 @@ var createChartController = (config) => {
3072
3840
  let width = 0;
3073
3841
  let height = 0;
3074
3842
  let annotations = [];
3843
+ let dependencies = [];
3075
3844
  let scene = null;
3076
3845
  let sceneDirty = true;
3077
3846
  let lastPlot = "";
@@ -3112,7 +3881,8 @@ var createChartController = (config) => {
3112
3881
  };
3113
3882
  zoomed = !sameRange(view.x, base.x) || !sameRange(view.y, base.y);
3114
3883
  }
3115
- annotations = resolveAnnotations(options.annotations, theme);
3884
+ annotations = resolveAnnotations(options.annotations, theme, model.y.type === "log" ? Math.log10 : void 0, model.x.type === "log" ? Math.log10 : void 0);
3885
+ dependencies = resolveDependencies(options.dependencies, theme);
3116
3886
  if (hover) {
3117
3887
  if (!hover.event.items.every((it) => model.series[it.seriesIndex] && !model.series[it.seriesIndex].hidden && it.index < model.series[it.seriesIndex].cols.count)) setHover(null);
3118
3888
  }
@@ -3121,9 +3891,46 @@ var createChartController = (config) => {
3121
3891
  const legendLayout = () => {
3122
3892
  const option = options.legend;
3123
3893
  const named = options.series.filter((s) => s.name).length;
3124
- if (!(option === void 0 ? named > 1 : !!option)) return null;
3894
+ if (!legendShown(option, model, named)) return null;
3125
3895
  const cfg = typeof option === "object" ? option : {};
3126
3896
  const position = cfg.position === "bottom" ? "bottom" : "top";
3897
+ const ramp = colorLegend(model);
3898
+ if (ramp) {
3899
+ const first = ramp.labels[0]?.text ?? "";
3900
+ const last = ramp.labels[ramp.labels.length - 1]?.text ?? "";
3901
+ const barWidth = Math.max(60, Math.min(160, width * .32));
3902
+ const right = width - 4 - measure(last, 11) - 8;
3903
+ const barX = right - barWidth;
3904
+ const cy = (position === "bottom" ? height - LEGEND_ROW$1 : 0) + LEGEND_ROW$1 / 2;
3905
+ return {
3906
+ entries: [],
3907
+ colors: {
3908
+ bar: {
3909
+ x: barX,
3910
+ y: cy - 4,
3911
+ width: barWidth,
3912
+ height: 8
3913
+ },
3914
+ stops: ramp.stops,
3915
+ labels: [{
3916
+ text: first,
3917
+ x: barX - 8,
3918
+ y: cy,
3919
+ align: "right"
3920
+ }, {
3921
+ text: last,
3922
+ x: right + 8,
3923
+ y: cy,
3924
+ align: "left"
3925
+ }],
3926
+ ticks: ramp.labels.filter((l) => l.at > 0 && l.at < 1).map((l) => barX + l.at * barWidth),
3927
+ caret: null
3928
+ },
3929
+ position,
3930
+ toggle: false,
3931
+ height: 26
3932
+ };
3933
+ }
3127
3934
  const entries = [];
3128
3935
  let x = 4;
3129
3936
  let row = 0;
@@ -3152,6 +3959,7 @@ var createChartController = (config) => {
3152
3959
  if (position === "bottom") for (const e of entries) e.box.y += height - legendHeight + 6;
3153
3960
  return {
3154
3961
  entries,
3962
+ colors: null,
3155
3963
  position,
3156
3964
  toggle: cfg.toggle ?? true,
3157
3965
  height: legendHeight
@@ -3172,13 +3980,21 @@ var createChartController = (config) => {
3172
3980
  const padding = 8;
3173
3981
  let w = 0;
3174
3982
  let lines;
3983
+ const swatchWidth = content.rows.some((row) => row.color) ? 14 : 0;
3175
3984
  if (text) {
3176
3985
  for (const line of text) w = Math.max(w, measure(line, 12));
3177
3986
  lines = text.length;
3178
3987
  } else {
3179
3988
  w = measure(content.title, 12, 600) + (content.titleColor ? 14 : 0);
3180
- for (const row of content.rows) w = Math.max(w, (row.color ? 14 : 0) + measure(row.name, 12) + 16 + measure(row.value, 12, 600));
3181
- lines = 1 + content.rows.length;
3989
+ if (content.subtitle) w = Math.max(w, measure(content.subtitle, 11) + (content.titleColor ? 14 : 0));
3990
+ let names = 0;
3991
+ let values = 0;
3992
+ for (const row of content.rows) {
3993
+ names = Math.max(names, measure(row.name, 12));
3994
+ values = Math.max(values, measure(row.value, 12, 600));
3995
+ }
3996
+ if (content.rows.length) w = Math.max(w, swatchWidth + names + 16 + values);
3997
+ lines = 1 + (content.subtitle ? 1 : 0) + content.rows.length;
3182
3998
  }
3183
3999
  const boxW = Math.ceil(Math.max(w, 96) + 16 + 4);
3184
4000
  const boxH = lines * lineHeight + 16;
@@ -3196,7 +4012,8 @@ var createChartController = (config) => {
3196
4012
  height: boxH
3197
4013
  },
3198
4014
  lineHeight,
3199
- padding
4015
+ padding,
4016
+ swatchWidth
3200
4017
  };
3201
4018
  };
3202
4019
  const computeScene = () => {
@@ -3245,7 +4062,9 @@ var createChartController = (config) => {
3245
4062
  pointLabels,
3246
4063
  legend,
3247
4064
  hover: null,
3248
- dragging: null
4065
+ dragging: null,
4066
+ connectors: connectorSegments(model, layout.scales),
4067
+ arrows: dependencyArrows(model, layout.scales, dependencies)
3249
4068
  };
3250
4069
  scene = next;
3251
4070
  if (hover) {
@@ -3258,6 +4077,10 @@ var createChartController = (config) => {
3258
4077
  crosshairY: horizontal ? guide : null,
3259
4078
  tooltip: gesture?.kind === "pan" || gesture?.kind === "point" ? null : tooltipLayout(hover.event, hover.x, hover.y)
3260
4079
  };
4080
+ const colors = legend?.colors;
4081
+ const it = hover.event.items[0];
4082
+ const s = it ? model.series[it.seriesIndex] : void 0;
4083
+ if (colors && it && s?.type === "heatmap" && it.value !== void 0) colors.caret = colors.bar.x + heatPosition(s, it.value) * colors.bar.width;
3261
4084
  }
3262
4085
  if (gesture?.kind === "point") {
3263
4086
  const s = model.series[gesture.item.seriesIndex];
@@ -3302,7 +4125,11 @@ var createChartController = (config) => {
3302
4125
  const sc = scales();
3303
4126
  if (!sc) return null;
3304
4127
  const { plot } = sc;
3305
- return toData(sc, Math.max(plot.x, Math.min(plot.x + plot.width, x)), Math.max(plot.y, Math.min(plot.y + plot.height, y)));
4128
+ const p = toData(sc, Math.max(plot.x, Math.min(plot.x + plot.width, x)), Math.max(plot.y, Math.min(plot.y + plot.height, y)));
4129
+ return {
4130
+ x: fromPlotX(model, p.x),
4131
+ y: fromPlotY(model, p.y)
4132
+ };
3306
4133
  };
3307
4134
  const setViewInternal = (next, notify) => {
3308
4135
  const { base, minSpan } = model;
@@ -3311,7 +4138,7 @@ var createChartController = (config) => {
3311
4138
  y: clampRange(next.y, base.y, minSpan.y)
3312
4139
  };
3313
4140
  zoomed = !sameRange(view.x, base.x) || !sameRange(view.y, base.y);
3314
- if (notify) emit("zoom", copyView(view));
4141
+ if (notify) emit("zoom", viewToValues(model, view));
3315
4142
  invalidate();
3316
4143
  };
3317
4144
  const zoomAt = (x, y, factor) => {
@@ -3574,13 +4401,10 @@ var createChartController = (config) => {
3574
4401
  },
3575
4402
  zoomAt,
3576
4403
  resetZoom,
3577
- getView: () => copyView(view),
4404
+ getView: () => viewToValues(model, view),
3578
4405
  setView(next) {
3579
4406
  if (destroyed) return;
3580
- setViewInternal({
3581
- x: next.x ?? view.x,
3582
- y: next.y ?? view.y
3583
- }, false);
4407
+ setViewInternal(viewFromValues(model, next, view), false);
3584
4408
  },
3585
4409
  toggleSeries,
3586
4410
  clearHover() {
@@ -3592,11 +4416,16 @@ var createChartController = (config) => {
3592
4416
  },
3593
4417
  toPixel(x, y) {
3594
4418
  const sc = scales();
3595
- return sc ? toScreen(sc, x, y) : null;
4419
+ return sc ? toScreen(sc, toPlotX(model, x), toPlotY(model, y)) : null;
3596
4420
  },
3597
4421
  fromPixel(x, y) {
3598
4422
  const sc = scales();
3599
- return sc ? toData(sc, x, y) : null;
4423
+ if (!sc) return null;
4424
+ const p = toData(sc, x, y);
4425
+ return {
4426
+ x: fromPlotX(model, p.x),
4427
+ y: fromPlotY(model, p.y)
4428
+ };
3600
4429
  },
3601
4430
  on(type, listener) {
3602
4431
  let set = listeners[type];
@@ -3853,7 +4682,8 @@ var scenePrimitives = (scene, limits = {}) => {
3853
4682
  const hh = Math.abs(s.cellHalf.y / sc.yPerPx);
3854
4683
  const rects = [];
3855
4684
  const colors = [];
3856
- const inset = hw > 3 && hh > 3 ? 1 : 0;
4685
+ const style = heatCellStyle(hw * 2, hh * 2, s.radius);
4686
+ const inset = style.inset;
3857
4687
  for (let i = 0; i < count && rects.length / 4 < maxBars * 4; i++) {
3858
4688
  const c = s.cellColors?.[i];
3859
4689
  if (!c) continue;
@@ -3868,7 +4698,7 @@ var scenePrimitives = (scene, limits = {}) => {
3868
4698
  color: s.colorCss,
3869
4699
  rects,
3870
4700
  colors,
3871
- radius: s.radius
4701
+ radius: style.radius
3872
4702
  });
3873
4703
  continue;
3874
4704
  }
@@ -3970,7 +4800,7 @@ var boxPrimitives = (s, sc, range, xLo, xHi, maxBars) => {
3970
4800
  x: cx,
3971
4801
  y: sc.yToPx(v)
3972
4802
  };
3973
- dots.push(p.x, p.y, s.pointSize);
4803
+ dots.push(p.x, p.y, s.outlierSize);
3974
4804
  dotColors.push(color);
3975
4805
  }
3976
4806
  }
@@ -3991,9 +4821,10 @@ var boxPrimitives = (s, sc, range, xLo, xHi, maxBars) => {
3991
4821
  if (dots.length) prims.push({
3992
4822
  kind: "dots",
3993
4823
  seriesIndex: s.index,
3994
- opacity: .85,
4824
+ opacity: s.outlierShape === "hollow" ? 0 : .85,
3995
4825
  dots,
3996
- colors: dotColors
4826
+ colors: dotColors,
4827
+ stroke: 1.25
3997
4828
  });
3998
4829
  return prims;
3999
4830
  };
@@ -4049,8 +4880,39 @@ var barItem = (key, version, s, count, write, extra) => {
4049
4880
  ...extra
4050
4881
  };
4051
4882
  };
4052
- /** Render items of the visible series, back to front */
4053
- var buildItems = (model, origin, version) => {
4883
+ /**
4884
+ * Inset and radius of the cells of a heatmap at a pixel density; the
4885
+ * renderers fade small insets out and overlap tiny cells (no seams)
4886
+ */
4887
+ var cellStyleOf = (s, density) => {
4888
+ if (!density) return {
4889
+ inset: .5,
4890
+ radius: Math.min(s.radius, 2)
4891
+ };
4892
+ const style = heatCellStyle(s.cellHalf.x * 2 * density.x, s.cellHalf.y * 2 * density.y, s.radius);
4893
+ return {
4894
+ inset: Math.max(.5, style.inset),
4895
+ radius: style.radius
4896
+ };
4897
+ };
4898
+ /**
4899
+ * What the heatmap items depend on besides the model: their cell style at
4900
+ * the current pixel density (`""` without heatmaps)
4901
+ */
4902
+ var cellStyleKey = (model, density) => {
4903
+ let key = "";
4904
+ for (const s of model.series) {
4905
+ if (s.type !== "heatmap" || s.hidden) continue;
4906
+ const style = cellStyleOf(s, density);
4907
+ key += `${style.inset}/${style.radius};`;
4908
+ }
4909
+ return key;
4910
+ };
4911
+ /**
4912
+ * Render items of the visible series, back to front; `density` sizes the
4913
+ * gaps and corners of heatmap cells
4914
+ */
4915
+ var buildItems = (model, origin, version, density) => {
4054
4916
  const items = [];
4055
4917
  /** Outlines of the areas are drawn with the lines, above the bars */
4056
4918
  const outlines = [];
@@ -4195,6 +5057,7 @@ var buildItems = (model, origin, version) => {
4195
5057
  case "heatmap": {
4196
5058
  const colors = s.cellColors;
4197
5059
  const hy = s.cellHalf.y;
5060
+ const style = cellStyleOf(s, density);
4198
5061
  items.push(barItem(`${s.key}:cells`, version, s, count, (i, f, u) => {
4199
5062
  const c = colors ? colors[i] : 0;
4200
5063
  const valid = c !== 0 && Number.isFinite(x[i]);
@@ -4204,8 +5067,8 @@ var buildItems = (model, origin, version) => {
4204
5067
  u[i * 4 + 3] = c;
4205
5068
  }, {
4206
5069
  halfWidth: s.cellHalf.x,
4207
- radius: s.radius,
4208
- inset: 1,
5070
+ radius: style.radius,
5071
+ inset: style.inset,
4209
5072
  minHalf: 0,
4210
5073
  sorted
4211
5074
  }));
@@ -4395,7 +5258,7 @@ var boxItems = (s, origin, version) => {
4395
5258
  const valid = Number.isFinite(v) && Number.isFinite(x[i]);
4396
5259
  f[j * 4] = valid ? ox(i) : GAP;
4397
5260
  f[j * 4 + 1] = valid ? oy(v) : GAP;
4398
- f[j * 4 + 2] = s.pointSize;
5261
+ f[j * 4 + 2] = s.outlierSize;
4399
5262
  u[j * 4 + 3] = colorAt(i);
4400
5263
  j++;
4401
5264
  }
@@ -4407,8 +5270,8 @@ var boxItems = (s, origin, version) => {
4407
5270
  color: s.color,
4408
5271
  instances: buffer,
4409
5272
  count: n,
4410
- opacity: .85,
4411
- stroke: n <= 5e3 ? 1.25 : 0
5273
+ opacity: s.outlierShape === "hollow" ? 0 : .85,
5274
+ stroke: s.outlierShape === "hollow" || n <= 5e3 ? 1.25 : 0
4412
5275
  });
4413
5276
  }
4414
5277
  }
@@ -4556,10 +5419,13 @@ var createCanvas2dPainter = (ctx, scratchCanvas) => {
4556
5419
  const end = Math.min(item.count, lowerBoundX(item.points, item.count, x1, 3) + 1);
4557
5420
  ({points, length} = decimateArea(item.points, start, end, m.px));
4558
5421
  }
4559
- const gradient = ctx.createLinearGradient(0, 0, 0, frame.height);
4560
- gradient.addColorStop(0, rgba(item.color, item.opacity));
4561
- gradient.addColorStop(1, rgba(item.color, item.opacity * .25));
4562
- ctx.fillStyle = gradient;
5422
+ if (item.flat) ctx.fillStyle = rgba(item.color, item.opacity);
5423
+ else {
5424
+ const gradient = ctx.createLinearGradient(0, 0, 0, frame.height);
5425
+ gradient.addColorStop(0, rgba(item.color, item.opacity));
5426
+ gradient.addColorStop(1, rgba(item.color, item.opacity * .25));
5427
+ ctx.fillStyle = gradient;
5428
+ }
4563
5429
  ctx.beginPath();
4564
5430
  let runStart = -1;
4565
5431
  const close = (end) => {
@@ -4806,7 +5672,8 @@ var itemsSignature = (model, themeKey, stackOf) => {
4806
5672
  for (const s of model.series) {
4807
5673
  signature += `\n${s.key}|${s.type}|${idOf(s.cols)}|${s.colorCss}|${s.hidden}|${s.lineWidth}|${s.pointSize}|${s.opacity}|${s.barOffset}|${s.barHalfWidth}|${stackOf(s.index) ?? ""}|${s.curve}|${s.radius}`;
4808
5674
  if (s.type === "candlestick") signature += `|${s.upColor}/${s.downColor}`;
4809
- else if (s.type === "heatmap") signature += `|${s.colorScale.join(";")}/${s.valueRange[0]},${s.valueRange[1]}/${s.cellHalf.x},${s.cellHalf.y}`;
5675
+ else if (s.type === "heatmap") signature += `|${s.colorScale.join(";")}/${s.valueRange[0]},${s.valueRange[1]}/${s.colorMidpoint}/${s.cellHalf.x},${s.cellHalf.y}`;
5676
+ else if (s.type === "boxplot") signature += `|${s.outlierShape}/${s.outlierSize}`;
4810
5677
  }
4811
5678
  return signature;
4812
5679
  };
@@ -4882,17 +5749,64 @@ var drawPrimitives = (ctx, primitives, plot) => {
4882
5749
  }
4883
5750
  ctx.globalAlpha = 1;
4884
5751
  } else {
4885
- ctx.globalAlpha = p.opacity;
5752
+ const stroke = p.stroke ?? 0;
4886
5753
  for (let k = 0; k < p.dots.length; k += 3) {
4887
- ctx.fillStyle = p.colors[k / 3] ?? "#888";
5754
+ const color = p.colors[k / 3] ?? "#888";
5755
+ const r = p.dots[k + 2] / 2;
4888
5756
  ctx.beginPath();
4889
- ctx.arc(p.dots[k], p.dots[k + 1], p.dots[k + 2] / 2, 0, Math.PI * 2);
4890
- ctx.fill();
5757
+ ctx.arc(p.dots[k], p.dots[k + 1], Math.max(0, r - stroke / 2), 0, Math.PI * 2);
5758
+ if (p.opacity > 0) {
5759
+ ctx.globalAlpha = p.opacity;
5760
+ ctx.fillStyle = color;
5761
+ ctx.fill();
5762
+ }
5763
+ if (stroke > 0) {
5764
+ ctx.globalAlpha = 1;
5765
+ ctx.lineWidth = stroke;
5766
+ ctx.strokeStyle = color;
5767
+ ctx.stroke();
5768
+ }
4891
5769
  }
4892
5770
  ctx.globalAlpha = 1;
4893
5771
  }
4894
5772
  ctx.restore();
4895
5773
  };
5774
+ /** The visual map of a heatmap: gradient bar, value labels, hover caret */
5775
+ var drawColorLegend = (ctx, ramp, scene) => {
5776
+ const { theme } = scene;
5777
+ const { bar, stops } = ramp;
5778
+ const n = stops.length;
5779
+ if (typeof ctx.createLinearGradient === "function") {
5780
+ const gradient = ctx.createLinearGradient(bar.x, 0, bar.x + bar.width, 0);
5781
+ stops.forEach((c, k) => gradient.addColorStop(k / Math.max(1, n - 1), c));
5782
+ ctx.fillStyle = gradient;
5783
+ roundedRect(ctx, bar.x, bar.y, bar.width, bar.height, bar.height / 2);
5784
+ ctx.fill();
5785
+ } else {
5786
+ const w = bar.width / n;
5787
+ stops.forEach((c, k) => {
5788
+ ctx.fillStyle = c;
5789
+ ctx.fillRect(bar.x + k * w, bar.y, w + .5, bar.height);
5790
+ });
5791
+ }
5792
+ ctx.fillStyle = toCss(theme.text, .35);
5793
+ for (const t of ramp.ticks) ctx.fillRect(Math.round(t), bar.y - 2, 1, bar.height + 4);
5794
+ ctx.font = font(theme, 11);
5795
+ ctx.textBaseline = "middle";
5796
+ ctx.fillStyle = toCss(theme.textMuted);
5797
+ for (const l of ramp.labels) {
5798
+ ctx.textAlign = l.align;
5799
+ ctx.fillText(l.text, l.x, l.y);
5800
+ }
5801
+ if (ramp.caret !== null) {
5802
+ roundedRect(ctx, ramp.caret - 2, bar.y - 3, 4, bar.height + 6, 2);
5803
+ ctx.fillStyle = toCss(theme.text);
5804
+ ctx.fill();
5805
+ ctx.lineWidth = 1.5;
5806
+ ctx.strokeStyle = toCss(theme.background);
5807
+ ctx.stroke();
5808
+ }
5809
+ };
4896
5810
  /** Draws a scene (legend, axes, data, labels, hover) on a 2D context */
4897
5811
  var drawScene = (ctx, scene, items, origin, pixelRatio, painter = createCanvas2dPainter(ctx)) => {
4898
5812
  const { width, height, theme, model, view, layout } = scene;
@@ -4914,6 +5828,8 @@ var drawScene = (ctx, scene, items, origin, pixelRatio, painter = createCanvas2d
4914
5828
  theme,
4915
5829
  annotations: scene.annotations
4916
5830
  });
5831
+ const ramp = scene.legend?.colors;
5832
+ if (ramp) drawColorLegend(ctx, ramp, scene);
4917
5833
  if (scene.legend) {
4918
5834
  ctx.font = font(theme, 12);
4919
5835
  ctx.textBaseline = "middle";
@@ -4966,6 +5882,11 @@ var drawScene = (ctx, scene, items, origin, pixelRatio, painter = createCanvas2d
4966
5882
  }, Math.round(plot.x * dpr), Math.round(plot.y * dpr));
4967
5883
  }
4968
5884
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
5885
+ for (const mark of scene.hover?.marks ?? []) {
5886
+ if (mark.kind !== "guide") continue;
5887
+ ctx.fillStyle = toCss(theme.text, .06);
5888
+ ctx.fillRect(mark.x, mark.y, mark.width, mark.height);
5889
+ }
4969
5890
  drawForeground(ctx, {
4970
5891
  width,
4971
5892
  height,
@@ -4973,7 +5894,9 @@ var drawScene = (ctx, scene, items, origin, pixelRatio, painter = createCanvas2d
4973
5894
  theme,
4974
5895
  annotations: scene.annotations,
4975
5896
  pointLabels: [],
4976
- clear: false
5897
+ clear: false,
5898
+ connectors: scene.connectors,
5899
+ arrows: scene.arrows
4977
5900
  });
4978
5901
  if (scene.pointLabels.length) {
4979
5902
  ctx.save();
@@ -5017,15 +5940,25 @@ var drawScene = (ctx, scene, items, origin, pixelRatio, painter = createCanvas2d
5017
5940
  ctx.restore();
5018
5941
  }
5019
5942
  for (const mark of hover.marks) {
5020
- if (mark.kind === "band") continue;
5943
+ if (mark.kind === "band" || mark.kind === "guide") continue;
5021
5944
  if (mark.kind === "cell") {
5022
- roundedRect(ctx, mark.x, mark.y, mark.width, mark.height, 3);
5023
- ctx.lineWidth = 3;
5024
- ctx.strokeStyle = toCss(theme.background);
5025
- ctx.stroke();
5026
- ctx.lineWidth = 1.5;
5027
- ctx.strokeStyle = toCss(theme.text, .55);
5028
- ctx.stroke();
5945
+ const grow = Math.min(3, mark.width * .06, mark.height * .06);
5946
+ const r = Math.max(2, mark.radius);
5947
+ ctx.save();
5948
+ ctx.shadowColor = "rgba(15, 23, 42, 0.4)";
5949
+ ctx.shadowBlur = 12;
5950
+ ctx.shadowOffsetY = 4;
5951
+ roundedRect(ctx, mark.x - grow, mark.y - grow, mark.width + grow * 2, mark.height + grow * 2, r);
5952
+ ctx.fillStyle = mark.color;
5953
+ ctx.fill();
5954
+ ctx.restore();
5955
+ const inset = Math.min(2.75, mark.width / 5, mark.height / 5);
5956
+ if (mark.width > 8 && mark.height > 8) {
5957
+ roundedRect(ctx, mark.x + inset, mark.y + inset, mark.width - inset * 2, mark.height - inset * 2, Math.max(1, r - inset / 2));
5958
+ ctx.lineWidth = 1.5;
5959
+ ctx.strokeStyle = mark.ring;
5960
+ ctx.stroke();
5961
+ }
5029
5962
  continue;
5030
5963
  }
5031
5964
  ctx.beginPath();
@@ -5095,6 +6028,12 @@ var drawScene = (ctx, scene, items, origin, pixelRatio, painter = createCanvas2d
5095
6028
  ctx.textAlign = "left";
5096
6029
  ctx.fillText(content.title, x, y);
5097
6030
  y += lineHeight;
6031
+ if (content.subtitle) {
6032
+ ctx.font = font(theme, 11);
6033
+ ctx.fillStyle = toCss(theme.textMuted);
6034
+ ctx.fillText(content.subtitle, x, y - 2);
6035
+ y += lineHeight;
6036
+ }
5098
6037
  for (const row of content.rows) {
5099
6038
  x = left;
5100
6039
  if (row.color) {
@@ -5102,8 +6041,8 @@ var drawScene = (ctx, scene, items, origin, pixelRatio, painter = createCanvas2d
5102
6041
  ctx.beginPath();
5103
6042
  ctx.arc(x + 4, y, 4, 0, Math.PI * 2);
5104
6043
  ctx.fill();
5105
- x += 14;
5106
6044
  }
6045
+ x += tip.swatchWidth;
5107
6046
  ctx.font = font(theme, 12);
5108
6047
  ctx.textAlign = "left";
5109
6048
  ctx.fillStyle = toCss(theme.textMuted);
@@ -5133,6 +6072,7 @@ var createCanvasChart = (config) => {
5133
6072
  let frameId = null;
5134
6073
  let items = [];
5135
6074
  let itemsModel = null;
6075
+ let itemsKey0 = "";
5136
6076
  let itemsKey = "";
5137
6077
  let options = config.options;
5138
6078
  /** Ids of the themes seen (the controller replaces its theme on changes) */
@@ -5171,15 +6111,21 @@ var createCanvasChart = (config) => {
5171
6111
  fontSet = "";
5172
6112
  if (itemsModel !== scene.model) {
5173
6113
  itemsModel = scene.model;
5174
- const key = itemsSignature(scene.model, themeId(scene.theme), (index) => options.series[index]?.stack);
5175
- if (key !== itemsKey) {
5176
- itemsKey = key;
5177
- origin = {
5178
- x: mid(scene.model.base.x),
5179
- y: mid(scene.model.base.y)
5180
- };
5181
- items = buildItems(scene.model, origin, ++version);
5182
- }
6114
+ itemsKey0 = itemsSignature(scene.model, themeId(scene.theme), (index) => options.series[index]?.stack);
6115
+ }
6116
+ const sc = scene.layout.scales;
6117
+ const density = {
6118
+ x: 1 / Math.abs(sc.xPerPx),
6119
+ y: 1 / Math.abs(sc.yPerPx)
6120
+ };
6121
+ const key = `${itemsKey0}|${cellStyleKey(scene.model, density)}`;
6122
+ if (key !== itemsKey) {
6123
+ itemsKey = key;
6124
+ origin = {
6125
+ x: mid(scene.model.base.x),
6126
+ y: mid(scene.model.base.y)
6127
+ };
6128
+ items = buildItems(scene.model, origin, ++version, density);
5183
6129
  }
5184
6130
  drawScene(ctx, scene, items, origin, dpr, painter);
5185
6131
  fontSet = "";
@@ -5347,6 +6293,7 @@ var heatmapChartOptions = (config, base = {}) => {
5347
6293
  })),
5348
6294
  colorScale: config.colorScale,
5349
6295
  valueRange: config.valueRange,
6296
+ colorMidpoint: config.colorMidpoint,
5350
6297
  radius: config.radius,
5351
6298
  format: config.format
5352
6299
  }],
@@ -5366,7 +6313,7 @@ var heatmapChartOptions = (config, base = {}) => {
5366
6313
  grid: false,
5367
6314
  ...base.yAxis
5368
6315
  },
5369
- legend: base.legend ?? false,
6316
+ legend: base.legend ?? true,
5370
6317
  interaction: base.interaction ?? { zoom: false },
5371
6318
  tooltip: base.tooltip ?? { mode: "nearest" }
5372
6319
  };
@@ -5811,7 +6758,8 @@ var waterfallSeries = (steps, options = {}) => {
5811
6758
  color: total,
5812
6759
  data,
5813
6760
  showLabels: options.labels ?? false,
5814
- format: options.format
6761
+ format: options.format,
6762
+ connector: options.connector ?? true
5815
6763
  };
5816
6764
  };
5817
6765
  /**
@@ -5920,7 +6868,10 @@ var time = (v) => v instanceof Date ? v.getTime() : v === void 0 ? NaN : v;
5920
6868
  var ganttSeries = (tasks, options = {}) => {
5921
6869
  const locale = resolveLocale(options.locale);
5922
6870
  const names = presetLabels(locale);
6871
+ const rows = chartLabels(locale);
5923
6872
  const taskName = options.taskName ?? names.tasks;
6873
+ const progressName = options.progressName ?? names.progress;
6874
+ const separator = /^(zh|ja)\b/i.test(locale) ? "、" : ", ";
5924
6875
  const groups = [];
5925
6876
  for (const t of tasks) {
5926
6877
  const g = t.group ?? taskName;
@@ -5943,19 +6894,32 @@ var ganttSeries = (tasks, options = {}) => {
5943
6894
  opacity: .3,
5944
6895
  barWidth: .62,
5945
6896
  radius: 4,
5946
- data: tasks.filter((t) => !t.milestone && (t.group ?? taskName) === g).map((t) => ({
5947
- x: t.name,
5948
- y0: time(t.start),
5949
- y: time(t.end ?? t.start),
5950
- ...t.color ? { color: t.color } : {}
5951
- }))
6897
+ data: tasks.filter((t) => !t.milestone && (t.group ?? taskName) === g).map((t) => {
6898
+ const details = [];
6899
+ if (t.progress !== void 0) details.push({
6900
+ name: progressName,
6901
+ value: formatProgress(Math.min(1, Math.max(0, t.progress)))
6902
+ });
6903
+ if (t.dependencies?.length) details.push({
6904
+ name: options.dependenciesName ?? rows.dependencies,
6905
+ value: t.dependencies.join(separator)
6906
+ });
6907
+ return {
6908
+ x: t.name,
6909
+ y0: time(t.start),
6910
+ y: time(t.end ?? t.start),
6911
+ ...t.color ? { color: t.color } : {},
6912
+ ...details.length ? { details } : {}
6913
+ };
6914
+ })
5952
6915
  }));
5953
6916
  const progress = tasks.filter((t) => !t.milestone && t.progress !== void 0 && t.progress > 0);
5954
6917
  if (progress.length) series.push({
5955
6918
  id: "gantt:progress",
5956
- name: options.progressName ?? names.progress,
6919
+ name: progressName,
5957
6920
  type: "bar",
5958
6921
  stack: "gantt",
6922
+ tooltip: false,
5959
6923
  color: "var(--text-secondary-color, #6b7280)",
5960
6924
  radius: 4,
5961
6925
  data: progress.map((t) => {
@@ -5992,10 +6956,21 @@ var ganttSeries = (tasks, options = {}) => {
5992
6956
  if (v > hi) hi = v;
5993
6957
  }
5994
6958
  const pad = Number.isFinite(hi - lo) ? Math.max((hi - lo) * .025, 1) : 0;
6959
+ const known = new Set(tasks.map((t) => t.name));
6960
+ const dependencies = [];
6961
+ if (options.dependencyArrows !== false) for (const t of tasks) for (const from of t.dependencies ?? []) {
6962
+ if (from === t.name || !known.has(from)) continue;
6963
+ dependencies.push({
6964
+ from,
6965
+ to: t.name,
6966
+ ...options.dependencyColor ? { color: options.dependencyColor } : {}
6967
+ });
6968
+ }
5995
6969
  return {
5996
6970
  series,
5997
6971
  categories: tasks.map((t) => t.name),
5998
- domain: Number.isFinite(lo) ? [lo - pad, hi + pad] : [0, 1]
6972
+ domain: Number.isFinite(lo) ? [lo - pad, hi + pad] : [0, 1],
6973
+ dependencies
5999
6974
  };
6000
6975
  };
6001
6976
  /** Series of a RangeAreaChart: bands between `y0` and `y` (thin edges) */
@@ -6055,6 +7030,65 @@ var ellipsize = (text, max, font, measure) => {
6055
7030
  }
6056
7031
  return lo ? text.slice(0, lo).trimEnd() + "…" : "";
6057
7032
  };
7033
+ /** Characters that must not start a line (closing brackets and punctuation) */
7034
+ var NO_LINE_START = /^[)\]}、。,.:;!?)」』】》〉,.:;!?%…]/;
7035
+ /** Greedy line breaking at `max` pixels, without a line limit */
7036
+ var breakLines = (text, max, font, measure) => {
7037
+ const lines = [];
7038
+ let rest = text.trim();
7039
+ while (rest) {
7040
+ if (measure(rest, font) <= max) {
7041
+ lines.push(rest);
7042
+ break;
7043
+ }
7044
+ let lo = 0;
7045
+ let hi = rest.length;
7046
+ while (lo < hi) {
7047
+ const mid = lo + hi + 1 >> 1;
7048
+ if (measure(rest.slice(0, mid), font) <= max) lo = mid;
7049
+ else hi = mid - 1;
7050
+ }
7051
+ if (!lo) return null;
7052
+ let cut = lo;
7053
+ if (rest[lo] !== " ") {
7054
+ const space = rest.lastIndexOf(" ", lo);
7055
+ if (space > lo * .4) cut = space;
7056
+ else while (cut > 1 && NO_LINE_START.test(rest.slice(cut))) cut--;
7057
+ }
7058
+ lines.push(rest.slice(0, cut).trimEnd());
7059
+ rest = rest.slice(cut).trimStart();
7060
+ }
7061
+ return lines;
7062
+ };
7063
+ /**
7064
+ * Breaks a text into at most `maxLines` lines of `max` pixels, at spaces when
7065
+ * possible (anywhere otherwise, e.g. CJK, never before closing punctuation);
7066
+ * a text that fits is balanced across its lines, one that does not ends the
7067
+ * last line with an ellipsis
7068
+ */
7069
+ var wrapText = (text, max, font, measure, maxLines = 2) => {
7070
+ const whole = text.trim();
7071
+ if (!whole || maxLines < 1) return [];
7072
+ const lines = breakLines(whole, max, font, measure);
7073
+ if (!lines) {
7074
+ const last = ellipsize(whole, max, font, measure);
7075
+ return last ? [last] : [];
7076
+ }
7077
+ if (lines.length > maxLines) {
7078
+ const head = lines.slice(0, maxLines - 1);
7079
+ let rest = whole;
7080
+ for (const line of head) rest = rest.slice(line.length).trimStart();
7081
+ const tail = ellipsize(rest, max, font, measure);
7082
+ return tail ? [...head, tail] : head;
7083
+ }
7084
+ if (lines.length < 2) return lines;
7085
+ const lo = measure(whole, font) / lines.length;
7086
+ for (let k = 0; k <= 8; k++) {
7087
+ const balanced = breakLines(whole, lo + (max - lo) * k / 8, font, measure);
7088
+ if (balanced && balanced.length <= lines.length) return balanced;
7089
+ }
7090
+ return lines;
7091
+ };
6058
7092
  /** Stable keys of named values: the name, `name#2` for duplicates */
6059
7093
  var uniqueKeys = (names) => {
6060
7094
  const seen = /* @__PURE__ */ new Map();
@@ -6342,6 +7376,56 @@ var linkStyle = (ctx, node) => {
6342
7376
  gradient.addColorStop(1, node.color1);
6343
7377
  return gradient;
6344
7378
  };
7379
+ /** Whether a chord ribbon joins an arc to itself (a self flow) */
7380
+ var ribbonIsLoop = (node) => Math.abs(node.s0 - node.t0) < 1e-9 && Math.abs(node.s1 - node.t1) < 1e-9;
7381
+ /** Control point of the inward bulge of a self-flow ribbon */
7382
+ var loopControl = (node) => {
7383
+ const m = (node.s0 + node.s1) / 2;
7384
+ return [node.cx + node.r * .4 * Math.cos(m), node.cy + node.r * .4 * Math.sin(m)];
7385
+ };
7386
+ /** Outline of a chord ribbon: source arc, curve, target arc or arrowhead, curve */
7387
+ var ribbonPath = (ctx, node) => {
7388
+ const { cx, cy, r } = node;
7389
+ const at = (a, radius = r) => [cx + radius * Math.cos(a), cy + radius * Math.sin(a)];
7390
+ ctx.beginPath();
7391
+ const s = at(node.s0);
7392
+ ctx.moveTo(s[0], s[1]);
7393
+ if (node.s1 > node.s0) ctx.arc(cx, cy, r, node.s0, node.s1);
7394
+ if (ribbonIsLoop(node)) {
7395
+ const [qx, qy] = loopControl(node);
7396
+ ctx.quadraticCurveTo(qx, qy, s[0], s[1]);
7397
+ ctx.closePath();
7398
+ return;
7399
+ }
7400
+ if (node.head > 0) {
7401
+ const p0 = at(node.t0, r - node.head);
7402
+ const tip = at((node.t0 + node.t1) / 2);
7403
+ const p1 = at(node.t1, r - node.head);
7404
+ ctx.quadraticCurveTo(cx, cy, p0[0], p0[1]);
7405
+ ctx.lineTo(tip[0], tip[1]);
7406
+ ctx.lineTo(p1[0], p1[1]);
7407
+ } else {
7408
+ const t = at(node.t0);
7409
+ ctx.quadraticCurveTo(cx, cy, t[0], t[1]);
7410
+ if (node.t1 > node.t0) ctx.arc(cx, cy, r, node.t0, node.t1);
7411
+ }
7412
+ ctx.quadraticCurveTo(cx, cy, s[0], s[1]);
7413
+ ctx.closePath();
7414
+ };
7415
+ var ribbonStyle = (ctx, node) => {
7416
+ if (node.color0 === node.color1 || typeof ctx.createLinearGradient !== "function") return node.color0;
7417
+ const ms = (node.s0 + node.s1) / 2;
7418
+ const mt = (node.t0 + node.t1) / 2;
7419
+ const x0 = node.cx + node.r * Math.cos(ms);
7420
+ const y0 = node.cy + node.r * Math.sin(ms);
7421
+ const x1 = node.cx + node.r * Math.cos(mt);
7422
+ const y1 = node.cy + node.r * Math.sin(mt);
7423
+ if (Math.hypot(x1 - x0, y1 - y0) < 1) return node.color0;
7424
+ const gradient = ctx.createLinearGradient(x0, y0, x1, y1);
7425
+ gradient.addColorStop(0, node.color0);
7426
+ gradient.addColorStop(1, node.color1);
7427
+ return gradient;
7428
+ };
6345
7429
  /**
6346
7430
  * Draws a scene in CSS pixels (the caller sets the pixel-ratio transform and
6347
7431
  * clears the canvas). `hover` emphasizes an item and dims the others.
@@ -6494,6 +7578,17 @@ var drawShapeScene = (ctx, scene, hover) => {
6494
7578
  ctx.stroke();
6495
7579
  ctx.lineCap = "round";
6496
7580
  break;
7581
+ case "ribbon":
7582
+ if (active && node.activeAlpha !== void 0) ctx.globalAlpha = base * node.activeAlpha;
7583
+ ribbonPath(ctx, node);
7584
+ ctx.fillStyle = ribbonStyle(ctx, node);
7585
+ ctx.fill();
7586
+ if (focused) {
7587
+ ctx.strokeStyle = node.color0;
7588
+ ctx.lineWidth = 1;
7589
+ ctx.stroke();
7590
+ }
7591
+ break;
6497
7592
  case "guide": {
6498
7593
  const k = hover?.indicator;
6499
7594
  if (k === void 0 || !node.ends[k]) break;
@@ -6571,8 +7666,10 @@ var drawShapeTooltip = (ctx, theme, box) => {
6571
7666
  ctx.font = font(theme, 12, 600);
6572
7667
  ctx.fillStyle = toCss(theme.text);
6573
7668
  ctx.textAlign = "left";
6574
- ctx.fillText(content.title, x, y);
6575
- y += lineHeight;
7669
+ for (const line of box.titleLines ?? [content.title]) {
7670
+ ctx.fillText(line, x, y);
7671
+ y += lineHeight;
7672
+ }
6576
7673
  for (const row of content.rows) {
6577
7674
  x = left;
6578
7675
  if (row.color) {
@@ -6656,6 +7753,7 @@ var nodeContains = (node, x, y) => {
6656
7753
  return wrapFrom(Math.atan2(y - node.cy, x - node.cx), node.a0) <= node.a1;
6657
7754
  }
6658
7755
  case "link": return pointNearLink(x, y, node);
7756
+ case "ribbon": return Math.hypot(x - node.cx, y - node.cy) <= node.r + 1 && pointInPolygon(x, y, ribbonOutline(node));
6659
7757
  default: return false;
6660
7758
  }
6661
7759
  };
@@ -6691,6 +7789,46 @@ var pointNearLink = (x, y, node) => {
6691
7789
  return false;
6692
7790
  };
6693
7791
  var clampUnit = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
7792
+ /** Polygon (flat x, y list) approximating a chord ribbon, as drawn */
7793
+ var ribbonOutline = (node) => {
7794
+ const { cx, cy, r } = node;
7795
+ const pts = [];
7796
+ const arc = (a0, a1, radius = r) => {
7797
+ const steps = Math.max(1, Math.ceil((a1 - a0) / .06));
7798
+ for (let k = 0; k <= steps; k++) {
7799
+ const a = a0 + (a1 - a0) * k / steps;
7800
+ pts.push(cx + radius * Math.cos(a), cy + radius * Math.sin(a));
7801
+ }
7802
+ };
7803
+ const quad = (qx, qy, x, y) => {
7804
+ const x0 = pts[pts.length - 2];
7805
+ const y0 = pts[pts.length - 1];
7806
+ for (let k = 1; k <= 16; k++) {
7807
+ const t = k / 16;
7808
+ const u = 1 - t;
7809
+ pts.push(u * u * x0 + 2 * u * t * qx + t * t * x, u * u * y0 + 2 * u * t * qy + t * t * y);
7810
+ }
7811
+ };
7812
+ const at = (a, radius = r) => [cx + radius * Math.cos(a), cy + radius * Math.sin(a)];
7813
+ arc(node.s0, Math.max(node.s0, node.s1));
7814
+ const s = at(node.s0);
7815
+ if (ribbonIsLoop(node)) {
7816
+ const [qx, qy] = loopControl(node);
7817
+ quad(qx, qy, s[0], s[1]);
7818
+ return pts;
7819
+ }
7820
+ if (node.head > 0) {
7821
+ const p0 = at(node.t0, r - node.head);
7822
+ quad(cx, cy, p0[0], p0[1]);
7823
+ pts.push(...at((node.t0 + node.t1) / 2), ...at(node.t1, r - node.head));
7824
+ } else {
7825
+ const t = at(node.t0);
7826
+ quad(cx, cy, t[0], t[1]);
7827
+ arc(node.t0, Math.max(node.t0, node.t1));
7828
+ }
7829
+ quad(cx, cy, s[0], s[1]);
7830
+ return pts;
7831
+ };
6694
7832
  /** Radar: the vertex under the pointer, else the smallest polygon containing it */
6695
7833
  var hitRadar = (scene, x, y) => {
6696
7834
  const radar = scene.radar;
@@ -6811,6 +7949,8 @@ var rangeFills = (o, c, count) => {
6811
7949
  return own ? resolveWith(theme, own, gray) : gray;
6812
7950
  });
6813
7951
  };
7952
+ /** Line height of the wrapped names */
7953
+ var NAME_LINE = 15;
6814
7954
  var layoutBullet = (o, c) => {
6815
7955
  const { theme, area, measure, hidden } = c;
6816
7956
  const keys = keysOf$3(o);
@@ -6834,9 +7974,14 @@ var layoutBullet = (o, c) => {
6834
7974
  const items = [];
6835
7975
  const hasSubtitle = o.data.some((d, i) => !!d.subtitle && weights[i] > 0);
6836
7976
  const valueText = o.data.map((d) => c.format(finite(d.value)));
6837
- const labelW = vertical ? 0 : Math.min(area.width * .32, Math.max(0, ...o.data.map((d) => Math.max(measure(d.name, nameFont), d.subtitle ? measure(d.subtitle, subFont) : 0))) + 14);
7977
+ const nameW = o.data.map((d) => measure(d.name, nameFont));
7978
+ const labelCap = area.width * (area.width < 420 ? .34 : .4);
7979
+ const lineW = o.data.map((d, i) => nameW[i] <= labelCap - 14 ? nameW[i] : Math.max(0, ...wrapText(d.name, labelCap - 14, nameFont, measure, 2).map((l) => measure(l, nameFont))));
7980
+ const labelW = vertical ? 0 : Math.min(labelCap, Math.max(0, ...o.data.map((d, i) => Math.max(lineW[i], d.subtitle ? measure(d.subtitle, subFont) : 0))) + 14);
6838
7981
  const valueW = vertical ? 0 : Math.min(area.width * .2, Math.max(0, ...valueText.map((t) => measure(t, valueFont))) + 12);
6839
- const labelH = vertical ? 22 + (hasSubtitle ? 14 : 0) : 0;
7982
+ const columnW = area.width / total;
7983
+ const wraps = vertical && o.data.some((_, i) => weights[i] > 0 && nameW[i] > columnW - 8);
7984
+ const labelH = vertical ? 22 + (wraps ? NAME_LINE : 0) + (hasSubtitle ? 14 : 0) : 0;
6840
7985
  const valueH = vertical ? 20 : 0;
6841
7986
  const unit = (vertical ? area.width : area.height) / total;
6842
7987
  let offset = 0;
@@ -6970,25 +8115,25 @@ var layoutBullet = (o, c) => {
6970
8115
  }
6971
8116
  if (vertical) {
6972
8117
  const room = Math.max(0, slot - 8);
6973
- const name = ellipsize(d.name, room, nameFont, measure);
8118
+ const lines = wrapText(d.name, room, nameFont, measure, wraps ? 2 : 1);
6974
8119
  const bottom = area.y + area.height;
6975
- if (name) nodes.push({
8120
+ lines.forEach((line, k) => nodes.push({
6976
8121
  kind: "text",
6977
8122
  x: mid,
6978
- y: bottom - labelH + 16,
6979
- text: name,
8123
+ y: bottom - labelH + 16 + k * NAME_LINE,
8124
+ text: line,
6980
8125
  font: nameFont,
6981
8126
  color: text,
6982
8127
  align: "center",
6983
8128
  baseline: "middle",
6984
8129
  hit: i,
6985
8130
  alpha
6986
- });
8131
+ }));
6987
8132
  const sub = d.subtitle ? ellipsize(d.subtitle, room, subFont, measure) : "";
6988
8133
  if (sub) nodes.push({
6989
8134
  kind: "text",
6990
8135
  x: mid,
6991
- y: bottom - labelH + 31,
8136
+ y: bottom - labelH + 31 + (wraps ? NAME_LINE : 0),
6992
8137
  text: sub,
6993
8138
  font: subFont,
6994
8139
  color: muted,
@@ -7012,25 +8157,28 @@ var layoutBullet = (o, c) => {
7012
8157
  });
7013
8158
  } else {
7014
8159
  const room = Math.max(0, labelW - 14);
7015
- const name = ellipsize(d.name, room, nameFont, measure);
7016
- const sub = d.subtitle && slot >= 34 ? ellipsize(d.subtitle, room, subFont, measure) : "";
8160
+ const avail = slot - 4;
8161
+ const sub = d.subtitle && avail >= 29 ? ellipsize(d.subtitle, room, subFont, measure) : "";
8162
+ const subH = sub ? 13 : 0;
8163
+ const lines = wrapText(d.name, room, nameFont, measure, avail >= 30 + subH ? 2 : 1);
8164
+ const top = mid - (lines.length * NAME_LINE + subH) / 2;
7017
8165
  const x = area.x + labelW - 14;
7018
- if (name) nodes.push({
8166
+ lines.forEach((line, k) => nodes.push({
7019
8167
  kind: "text",
7020
8168
  x,
7021
- y: sub ? mid - 7 : mid,
7022
- text: name,
8169
+ y: top + NAME_LINE / 2 + k * NAME_LINE,
8170
+ text: line,
7023
8171
  font: nameFont,
7024
8172
  color: text,
7025
8173
  align: "right",
7026
8174
  baseline: "middle",
7027
8175
  hit: i,
7028
8176
  alpha
7029
- });
8177
+ }));
7030
8178
  if (sub) nodes.push({
7031
8179
  kind: "text",
7032
8180
  x,
7033
- y: mid + 8,
8181
+ y: top + lines.length * NAME_LINE + subH / 2,
7034
8182
  text: sub,
7035
8183
  font: subFont,
7036
8184
  color: muted,
@@ -7112,6 +8260,7 @@ var SHAPE_LABELS = {
7112
8260
  target: "Target",
7113
8261
  ofTarget: "Of target",
7114
8262
  range: "Range",
8263
+ reverse: "Reverse",
7115
8264
  series: "Series {index}",
7116
8265
  pieChart: "Pie chart",
7117
8266
  donutChart: "Donut chart",
@@ -7125,7 +8274,8 @@ var SHAPE_LABELS = {
7125
8274
  sunburstChart: "Sunburst chart",
7126
8275
  radialBarChart: "Radial bar chart",
7127
8276
  calendarHeatmap: "Calendar heatmap",
7128
- bulletChart: "Bullet chart"
8277
+ bulletChart: "Bullet chart",
8278
+ chordChart: "Chord diagram"
7129
8279
  },
7130
8280
  zh: {
7131
8281
  noData: "暂无数据",
@@ -7142,6 +8292,7 @@ var SHAPE_LABELS = {
7142
8292
  target: "目标",
7143
8293
  ofTarget: "目标达成",
7144
8294
  range: "区间",
8295
+ reverse: "反向",
7145
8296
  series: "系列 {index}",
7146
8297
  pieChart: "饼图",
7147
8298
  donutChart: "环形图",
@@ -7155,7 +8306,8 @@ var SHAPE_LABELS = {
7155
8306
  sunburstChart: "旭日图",
7156
8307
  radialBarChart: "径向条形图",
7157
8308
  calendarHeatmap: "日历热力图",
7158
- bulletChart: "子弹图"
8309
+ bulletChart: "子弹图",
8310
+ chordChart: "弦图"
7159
8311
  },
7160
8312
  ja: {
7161
8313
  noData: "データなし",
@@ -7172,6 +8324,7 @@ var SHAPE_LABELS = {
7172
8324
  target: "目標",
7173
8325
  ofTarget: "目標達成率",
7174
8326
  range: "範囲",
8327
+ reverse: "逆方向",
7175
8328
  series: "系列 {index}",
7176
8329
  pieChart: "円グラフ",
7177
8330
  donutChart: "ドーナツグラフ",
@@ -7185,7 +8338,8 @@ var SHAPE_LABELS = {
7185
8338
  sunburstChart: "サンバースト図",
7186
8339
  radialBarChart: "円形棒グラフ",
7187
8340
  calendarHeatmap: "カレンダーヒートマップ",
7188
- bulletChart: "ブレットグラフ"
8341
+ bulletChart: "ブレットグラフ",
8342
+ chordChart: "コードダイアグラム"
7189
8343
  },
7190
8344
  fr: {
7191
8345
  noData: "Aucune donnée",
@@ -7202,6 +8356,7 @@ var SHAPE_LABELS = {
7202
8356
  target: "Objectif",
7203
8357
  ofTarget: "Atteinte de l’objectif",
7204
8358
  range: "Plage",
8359
+ reverse: "Sens inverse",
7205
8360
  series: "Série {index}",
7206
8361
  pieChart: "Graphique circulaire",
7207
8362
  donutChart: "Graphique en anneau",
@@ -7215,7 +8370,8 @@ var SHAPE_LABELS = {
7215
8370
  sunburstChart: "Diagramme en rayons de soleil",
7216
8371
  radialBarChart: "Graphique à barres radiales",
7217
8372
  calendarHeatmap: "Calendrier thermique",
7218
- bulletChart: "Graphique à puces"
8373
+ bulletChart: "Graphique à puces",
8374
+ chordChart: "Diagramme d’accords"
7219
8375
  }
7220
8376
  };
7221
8377
  /** Texts of a chart: its `locale` (the page language by default) and `texts` overrides */
@@ -7787,6 +8943,599 @@ var layoutCalendar = (o, c) => {
7787
8943
  };
7788
8944
  };
7789
8945
  //#endregion
8946
+ //#region ../charts/src/engine/shapes/chord.ts
8947
+ /**
8948
+ * Resolves the groups (declared, then the ones only named by links) and
8949
+ * the square flow matrix (from `links`, else `matrix`)
8950
+ */
8951
+ var resolveChord = (o) => {
8952
+ const names = [];
8953
+ const colors = [];
8954
+ const byName = /* @__PURE__ */ new Map();
8955
+ for (const g of o.groups ?? []) {
8956
+ const group = typeof g === "string" ? { name: g } : g;
8957
+ if (!group || typeof group.name !== "string") continue;
8958
+ if (!byName.has(group.name)) byName.set(group.name, names.length);
8959
+ names.push(group.name);
8960
+ colors.push(group.color);
8961
+ }
8962
+ const cellColors = /* @__PURE__ */ new Map();
8963
+ if (o.links) {
8964
+ const declared = names.length;
8965
+ const resolve = (end) => {
8966
+ if (typeof end === "number") return Number.isInteger(end) && end >= 0 && end < declared ? end : -1;
8967
+ if (typeof end !== "string") return -1;
8968
+ const known = byName.get(end);
8969
+ if (known !== void 0) return known;
8970
+ byName.set(end, names.length);
8971
+ names.push(end);
8972
+ colors.push(void 0);
8973
+ return names.length - 1;
8974
+ };
8975
+ const flows = [];
8976
+ for (const l of o.links) {
8977
+ if (!l) continue;
8978
+ const s = resolve(l.source);
8979
+ const t = resolve(l.target);
8980
+ if (s < 0 || t < 0) continue;
8981
+ flows.push([
8982
+ s,
8983
+ t,
8984
+ positive(l.value),
8985
+ l.color
8986
+ ]);
8987
+ }
8988
+ const n = names.length;
8989
+ const matrix = names.map(() => new Array(n).fill(0));
8990
+ for (const [s, t, v, color] of flows) {
8991
+ matrix[s][t] += v;
8992
+ if (color) cellColors.set(s * n + t, color);
8993
+ }
8994
+ return {
8995
+ names,
8996
+ colors,
8997
+ matrix,
8998
+ cellColors
8999
+ };
9000
+ }
9001
+ const rows = o.matrix ?? [];
9002
+ const n = Math.max(names.length, rows.length);
9003
+ for (let i = names.length; i < n; i++) {
9004
+ names.push(String(i + 1));
9005
+ colors.push(void 0);
9006
+ }
9007
+ return {
9008
+ names,
9009
+ colors,
9010
+ matrix: names.map((_, i) => names.map((__, j) => positive(rows[i]?.[j]))),
9011
+ cellColors
9012
+ };
9013
+ };
9014
+ /** Keys of the animated quantities: `~group` (shown 0-1) and `group→group` */
9015
+ var chordKeys = (m) => {
9016
+ const keys = uniqueKeys(m.names);
9017
+ return {
9018
+ group: (i) => `~${keys[i]}`,
9019
+ cell: (i, j) => `${keys[i]}\u2192${keys[j]}`
9020
+ };
9021
+ };
9022
+ /** Whether a cell is a flow of the diagram (directed: self flows are ignored) */
9023
+ var isFlow = (m, directed, i, j) => m.matrix[i][j] > 0 && !(directed && i === j);
9024
+ var chordValues = (o, hidden, out) => {
9025
+ const m = resolveChord(o);
9026
+ const k = chordKeys(m);
9027
+ const directed = !!o.directed;
9028
+ m.names.forEach((_, i) => {
9029
+ out.set(k.group(i), hidden.has(i) ? 0 : 1);
9030
+ m.names.forEach((__, j) => {
9031
+ if (isFlow(m, directed, i, j)) out.set(k.cell(i, j), hidden.has(i) || hidden.has(j) ? 0 : m.matrix[i][j]);
9032
+ });
9033
+ });
9034
+ };
9035
+ /** Whether a matrix is symmetric (up to rounding) */
9036
+ var isSymmetric = (m) => m.every((row, i) => row.every((v, j) => {
9037
+ const w = m[j]?.[i] ?? 0;
9038
+ return Math.abs(v - w) <= 1e-9 * Math.max(1, Math.abs(v), Math.abs(w));
9039
+ }));
9040
+ /**
9041
+ * Undirected size of the ribbon joining `i` and `j`: a symmetric matrix holds
9042
+ * every relation in both cells (counted once), otherwise the flows of both
9043
+ * directions add up, so that a group with only incoming flows keeps its arc
9044
+ */
9045
+ var pairValue = (m, symmetric, i, j) => i === j || symmetric ? m[i][j] : m[i][j] + m[j][i];
9046
+ /**
9047
+ * Totals of a matrix: outgoing, incoming and arc value of every group. The
9048
+ * arc holds the ends of all the ribbons of the group: both directions when
9049
+ * directed, the undirected pair sizes ({@link pairValue}) otherwise
9050
+ */
9051
+ var totals = (matrix, directed, symmetric) => {
9052
+ const n = matrix.length;
9053
+ const out = new Array(n).fill(0);
9054
+ const inc = new Array(n).fill(0);
9055
+ for (let i = 0; i < n; i++) for (let j = 0; j < n; j++) {
9056
+ if (directed && i === j) continue;
9057
+ out[i] += matrix[i][j];
9058
+ inc[j] += matrix[i][j];
9059
+ }
9060
+ return {
9061
+ out,
9062
+ inc,
9063
+ value: out.map((v, i) => directed ? v + inc[i] : symmetric ? v : Math.max(0, v + inc[i] - matrix[i][i]))
9064
+ };
9065
+ };
9066
+ /** Smallest of 1, 2, 5 × 10^k not below `raw` */
9067
+ var niceCeil = (raw) => {
9068
+ if (!(raw > 0) || !Number.isFinite(raw)) return 0;
9069
+ const base = Math.pow(10, Math.floor(Math.log10(raw)));
9070
+ for (const f of [
9071
+ 1,
9072
+ 2,
9073
+ 5,
9074
+ 10
9075
+ ]) if (f * base >= raw * (1 - 1e-9)) return f * base;
9076
+ return 10 * base;
9077
+ };
9078
+ var LABEL_FONT_SIZE = 12;
9079
+ var TICK_BAND = 22;
9080
+ var layoutChord = (o, c) => {
9081
+ const { theme, area, measure, hidden } = c;
9082
+ const model = resolveChord(o);
9083
+ const { names, matrix: raw } = model;
9084
+ const n = names.length;
9085
+ if (!n) return emptyLayout(c);
9086
+ const directed = !!o.directed;
9087
+ const keys = chordKeys(model);
9088
+ const flow = (i, j) => isFlow(model, directed, i, j);
9089
+ const shown = raw.map((row, i) => row.map((v, j) => flow(i, j) ? Math.max(0, c.value(keys.cell(i, j), hidden.has(i) || hidden.has(j) ? 0 : v)) : 0));
9090
+ const target = raw.map((row, i) => row.map((v, j) => flow(i, j) && !hidden.has(i) && !hidden.has(j) ? v : 0));
9091
+ const symmetric = !directed && isSymmetric(raw.map((row, i) => row.map((v, j) => flow(i, j) ? v : 0)));
9092
+ const pair = (m, i, j) => pairValue(m, symmetric, i, j);
9093
+ const now = totals(shown, directed, symmetric);
9094
+ const goal = totals(target, directed, symmetric);
9095
+ const whole = goal.value.reduce((a, b) => a + b, 0);
9096
+ const visibleWeight = names.map((_, i) => goal.value[i] > 0 || now.value[i] > 1e-9 ? clamp(c.value(keys.group(i), hidden.has(i) ? 0 : 1), 0, 1) : 0);
9097
+ const sumNow = now.value.reduce((a, b) => a + b, 0);
9098
+ if (sumNow <= 1e-12) return emptyLayout(c);
9099
+ const allGoal = totals(raw.map((row, i) => row.map((v, j) => flow(i, j) ? v : 0)), directed, symmetric).value;
9100
+ const order = names.map((_, i) => i);
9101
+ if (o.sortGroups === "ascending" || o.sortGroups === "descending") {
9102
+ const sign = o.sortGroups === "ascending" ? 1 : -1;
9103
+ order.sort((a, b) => sign * (allGoal[a] - allGoal[b]) || a - b);
9104
+ }
9105
+ const pos = new Array(n);
9106
+ order.forEach((g, p) => pos[g] = p);
9107
+ const cx = area.x + area.width / 2;
9108
+ const cy = area.y + area.height / 2;
9109
+ const half = Math.min(area.width, area.height) / 2;
9110
+ const labelMode = o.labels ?? "auto";
9111
+ const nameFont = font(theme, LABEL_FONT_SIZE, 500);
9112
+ const tickFont = font(theme, 10);
9113
+ const tickOption = o.ticks;
9114
+ const showTicks = tickOption === false ? false : typeof tickOption === "number" ? tickOption > 0 : half >= 150;
9115
+ const tickBand = showTicks ? TICK_BAND : 0;
9116
+ const pad = clamp(finite(o.padAngle, 2), 0, 45) * (Math.PI / 180);
9117
+ const padTotal = pad * visibleWeight.reduce((a, b) => a + b, 0);
9118
+ const padScale = padTotal > TAU * .5 ? TAU * .5 / padTotal : 1;
9119
+ const k = (TAU - padTotal * padScale) / sumNow;
9120
+ const start = -Math.PI / 2 + finite(o.startAngle) * Math.PI / 180;
9121
+ const arcs = new Array(n);
9122
+ {
9123
+ let a = start + pad * padScale * (visibleWeight[order[0]] ?? 0) / 2;
9124
+ for (const g of order) {
9125
+ const a0 = a;
9126
+ const a1 = a0 + now.value[g] * k;
9127
+ arcs[g] = {
9128
+ a0,
9129
+ a1
9130
+ };
9131
+ a = a1 + pad * padScale * visibleWeight[g];
9132
+ }
9133
+ }
9134
+ const drawnGroup = (g) => arcs[g].a1 - arcs[g].a0 > 1e-6;
9135
+ const nameW = names.map((name) => measure(name, nameFont));
9136
+ const fitsTangential = (r) => order.every((g) => !drawnGroup(g) || nameW[g] + 6 <= (arcs[g].a1 - arcs[g].a0 + pad * padScale * .8) * r);
9137
+ let mode = labelMode === "none" ? "none" : labelMode === "radial" ? "radial" : "tangential";
9138
+ const tangentialRoom = 22;
9139
+ if (labelMode === "auto" && !fitsTangential(Math.max(1, half - 12))) mode = "radial";
9140
+ const reach = (a) => {
9141
+ const cos = Math.abs(Math.cos(a));
9142
+ const sin = Math.abs(Math.sin(a));
9143
+ return Math.min(cos > 1e-6 ? (area.width / 2 - 2) / cos : Infinity, sin > 1e-6 ? (area.height / 2 - LABEL_FONT_SIZE / 2 - 1) / sin : Infinity);
9144
+ };
9145
+ const midOf = (g) => (arcs[g].a0 + arcs[g].a1) / 2;
9146
+ const horizontal = (a) => Math.abs(Math.sin(a)) > .92;
9147
+ let outer;
9148
+ if (mode === "radial") {
9149
+ outer = half - tickBand - 8;
9150
+ for (const g of order) if (drawnGroup(g) && visibleWeight[g] > .5) {
9151
+ const a = midOf(g);
9152
+ const need = horizontal(a) ? 14 : nameW[g];
9153
+ outer = Math.min(outer, reach(a) - need - tickBand - 10);
9154
+ }
9155
+ outer = Math.max(half * .5, outer);
9156
+ } else outer = half - tickBand - (mode === "none" ? 0 : tangentialRoom) - 2;
9157
+ outer = Math.max(16, outer);
9158
+ const arcWidth = clamp(finite(o.arcWidth, clamp(outer * .06, 8, 18)), 2, outer * .5);
9159
+ const inner = outer - arcWidth;
9160
+ const ribbonR = Math.max(4, inner - 2);
9161
+ const segments = names.map(() => []);
9162
+ for (let i = 0; i < n; i++) for (let j = 0; j < n; j++) if (directed) {
9163
+ if (flow(i, j)) {
9164
+ segments[i].push({
9165
+ j,
9166
+ dir: "out",
9167
+ raw: raw[i][j],
9168
+ a0: 0,
9169
+ a1: 0
9170
+ });
9171
+ segments[j].push({
9172
+ j: i,
9173
+ dir: "in",
9174
+ raw: raw[i][j],
9175
+ a0: 0,
9176
+ a1: 0
9177
+ });
9178
+ }
9179
+ } else if (flow(i, j) || flow(j, i)) segments[i].push({
9180
+ j,
9181
+ dir: "out",
9182
+ raw: raw[i][j],
9183
+ a0: 0,
9184
+ a1: 0
9185
+ });
9186
+ const sortSub = o.sortSubgroups ?? "auto";
9187
+ segments.forEach((list, i) => {
9188
+ const offset = (j) => {
9189
+ const d = (pos[j] - pos[i] + n) % n;
9190
+ return d === 0 ? n / 2 : d;
9191
+ };
9192
+ list.sort((a, b) => {
9193
+ const dir = Number(a.dir === "in") - Number(b.dir === "in");
9194
+ if (sortSub === "ascending" || sortSub === "descending") return (sortSub === "ascending" ? 1 : -1) * (a.raw - b.raw) || pos[a.j] - pos[b.j] || dir;
9195
+ if (sortSub === "none") return pos[a.j] - pos[b.j] || dir;
9196
+ return offset(b.j) - offset(a.j) || dir;
9197
+ });
9198
+ let a = arcs[i].a0;
9199
+ for (const s of list) {
9200
+ const v = !directed ? pair(shown, i, s.j) : s.dir === "out" ? shown[i][s.j] : shown[s.j][i];
9201
+ s.a0 = a;
9202
+ s.a1 = a + v * k;
9203
+ a = s.a1;
9204
+ }
9205
+ });
9206
+ const segment = (g, j, dir) => segments[g].find((s) => s.j === j && s.dir === dir);
9207
+ const css = names.map((_, i) => c.color(model.colors[i], i)).map((col) => toCss(col));
9208
+ const neutral = toCss(mix(theme.grid, theme.textMuted, .45));
9209
+ const colorMode = o.ribbonColor ?? "gradient";
9210
+ const opacity = clamp(finite(o.ribbonOpacity, .65), .02, 1);
9211
+ const activeAlpha = Math.min(1, opacity + .25);
9212
+ const head = o.arrows ?? directed ? clamp(ribbonR * .07, 5, 12) : 0;
9213
+ const ribbons = [];
9214
+ const ribbonIndex = (s, t) => n + s * n + t;
9215
+ for (let i = 0; i < n; i++) for (let j = directed ? 0 : i; j < n; j++) if (directed) {
9216
+ if (!flow(i, j)) continue;
9217
+ const src = segment(i, j, "out");
9218
+ const tgt = segment(j, i, "in");
9219
+ if (src && tgt) ribbons.push({
9220
+ index: ribbonIndex(i, j),
9221
+ s: i,
9222
+ t: j,
9223
+ src,
9224
+ tgt
9225
+ });
9226
+ } else {
9227
+ if (!flow(i, j) && !flow(j, i)) continue;
9228
+ const [s, t] = raw[j][i] > raw[i][j] ? [j, i] : [i, j];
9229
+ const src = segment(s, t, "out");
9230
+ const tgt = segment(t, s, "out");
9231
+ if (src && tgt) ribbons.push({
9232
+ index: ribbonIndex(s, t),
9233
+ s,
9234
+ t,
9235
+ src,
9236
+ tgt
9237
+ });
9238
+ }
9239
+ const ribbonsOf = names.map(() => []);
9240
+ for (const r of ribbons) {
9241
+ ribbonsOf[r.s].push(r.index);
9242
+ if (r.t !== r.s) ribbonsOf[r.t].push(r.index);
9243
+ }
9244
+ const nodes = [];
9245
+ const width = (r) => r.src.a1 - r.src.a0 + (r.tgt.a1 - r.tgt.a0);
9246
+ for (const r of ribbons.slice().sort((a, b) => width(b) - width(a))) {
9247
+ if (width(r) <= 1e-6) continue;
9248
+ const own = model.cellColors.get(r.s * n + r.t) ?? (directed ? void 0 : model.cellColors.get(r.t * n + r.s));
9249
+ let c0;
9250
+ let c1;
9251
+ if (own) c0 = c1 = toCss(c.color(own, r.s));
9252
+ else if (colorMode === "source") c0 = c1 = css[r.s];
9253
+ else if (colorMode === "target") c0 = c1 = css[r.t];
9254
+ else if (colorMode === "neutral") c0 = c1 = neutral;
9255
+ else {
9256
+ c0 = css[r.s];
9257
+ c1 = css[r.t];
9258
+ }
9259
+ nodes.push({
9260
+ kind: "ribbon",
9261
+ cx,
9262
+ cy,
9263
+ r: ribbonR,
9264
+ s0: r.src.a0,
9265
+ s1: r.src.a1,
9266
+ t0: r.tgt.a0,
9267
+ t1: r.tgt.a1,
9268
+ head: r.s === r.t ? 0 : head,
9269
+ color0: c0,
9270
+ color1: c1,
9271
+ alpha: opacity,
9272
+ activeAlpha,
9273
+ hit: r.index,
9274
+ also: r.s === r.t ? [r.s] : [r.s, r.t]
9275
+ });
9276
+ }
9277
+ for (const g of order) {
9278
+ if (!drawnGroup(g)) continue;
9279
+ nodes.push({
9280
+ kind: "sector",
9281
+ cx,
9282
+ cy,
9283
+ r0: inner,
9284
+ r1: outer,
9285
+ a0: arcs[g].a0,
9286
+ a1: arcs[g].a1,
9287
+ pad: 0,
9288
+ corner: Math.min(2, arcWidth / 4),
9289
+ fill: css[g],
9290
+ hit: g,
9291
+ also: ribbonsOf[g],
9292
+ alpha: visibleWeight[g]
9293
+ });
9294
+ }
9295
+ const muted = toCss(theme.textMuted);
9296
+ const tickColor = toCss(theme.textMuted, .7);
9297
+ if (showTicks) {
9298
+ const unitPx = k * outer;
9299
+ const tickFormat = o.tickFormat ?? localeFormat(c.locale);
9300
+ const labelPx = measure(tickFormat(Math.max(...allGoal)), tickFont) + 14;
9301
+ let major = typeof tickOption === "number" ? tickOption : niceCeil(labelPx / Math.max(unitPx, 1e-12));
9302
+ const count = sumNow / Math.max(major, 1e-12);
9303
+ if (!(major > 0) || count > 240) major = niceCeil(sumNow / 240);
9304
+ const minor = major / 5 * unitPx >= 5 ? major / 5 : major / 2 * unitPx >= 5 ? major / 2 : major;
9305
+ const perMajor = Math.round(major / minor);
9306
+ const tickR = outer + 2;
9307
+ const labelR = outer + 15;
9308
+ let lastEnd = -Infinity;
9309
+ let firstStart = null;
9310
+ for (const g of order) {
9311
+ if (!drawnGroup(g)) continue;
9312
+ const { a0, a1 } = arcs[g];
9313
+ const also = ribbonsOf[g];
9314
+ for (let m = 0;; m++) {
9315
+ const a = a0 + m * minor * k;
9316
+ if (a > a1 + 1e-9) break;
9317
+ const isMajor = m % perMajor === 0;
9318
+ const len = isMajor ? 5 : 3;
9319
+ if (unitPx * minor >= 3 || isMajor) nodes.push({
9320
+ kind: "line",
9321
+ points: [
9322
+ cx + tickR * Math.cos(a),
9323
+ cy + tickR * Math.sin(a),
9324
+ cx + (tickR + len) * Math.cos(a),
9325
+ cy + (tickR + len) * Math.sin(a)
9326
+ ],
9327
+ color: tickColor,
9328
+ width: 1,
9329
+ hit: g,
9330
+ also
9331
+ });
9332
+ if (!isMajor) continue;
9333
+ const text = tickFormat(m * minor);
9334
+ const halfAngle = (measure(text, tickFont) / 2 + 3) / labelR;
9335
+ if (a - halfAngle < lastEnd) continue;
9336
+ if (firstStart !== null && a + halfAngle > firstStart + TAU) continue;
9337
+ if (firstStart === null) firstStart = a - halfAngle;
9338
+ lastEnd = a + halfAngle;
9339
+ nodes.push({
9340
+ kind: "text",
9341
+ x: cx + labelR * Math.cos(a),
9342
+ y: cy + labelR * Math.sin(a),
9343
+ text,
9344
+ font: tickFont,
9345
+ color: muted,
9346
+ align: "center",
9347
+ baseline: "middle",
9348
+ rotate: upright(a + Math.PI / 2),
9349
+ hit: g,
9350
+ also
9351
+ });
9352
+ }
9353
+ }
9354
+ }
9355
+ if (mode !== "none") {
9356
+ const nameR = outer + tickBand + 6;
9357
+ const color = toCss(theme.text);
9358
+ const placed = [];
9359
+ const lineGap = 15;
9360
+ const samples = (x, y, dx, dy, length) => {
9361
+ const pts = [];
9362
+ const steps = Math.max(1, Math.ceil(length / 6));
9363
+ for (let s = 0; s <= steps; s++) pts.push([x + dx * length * s / steps, y + dy * length * s / steps]);
9364
+ return pts;
9365
+ };
9366
+ const collides = (pts) => placed.some((other) => other.some(([x, y]) => pts.some(([u, v]) => Math.hypot(x - u, y - v) < lineGap)));
9367
+ const byValue = order.filter((g) => drawnGroup(g) && visibleWeight[g] > .5).sort((a, b) => now.value[b] - now.value[a]);
9368
+ for (const g of byValue) {
9369
+ const { a0, a1 } = arcs[g];
9370
+ const mid = (a0 + a1) / 2;
9371
+ if (mode === "tangential") {
9372
+ const room = (a1 - a0 + pad * padScale * .8) * (nameR + 6) - 6;
9373
+ const text = ellipsize(names[g], room, nameFont, measure);
9374
+ if (!text) continue;
9375
+ nodes.push({
9376
+ kind: "text",
9377
+ x: cx + (nameR + 6) * Math.cos(mid),
9378
+ y: cy + (nameR + 6) * Math.sin(mid),
9379
+ text,
9380
+ font: nameFont,
9381
+ color,
9382
+ align: "center",
9383
+ baseline: "middle",
9384
+ rotate: upright(mid + Math.PI / 2),
9385
+ hit: g,
9386
+ also: ribbonsOf[g]
9387
+ });
9388
+ continue;
9389
+ }
9390
+ const ax = cx + nameR * Math.cos(mid);
9391
+ const ay = cy + nameR * Math.sin(mid);
9392
+ if (horizontal(mid)) {
9393
+ const y = ay + Math.sign(Math.sin(mid)) * 7;
9394
+ const outward = Math.cos(mid) >= 0 ? "left" : "right";
9395
+ const aligns = [
9396
+ "center",
9397
+ outward,
9398
+ outward === "left" ? "right" : "left"
9399
+ ];
9400
+ const clear = (pts) => pts.every(([x, py]) => Math.hypot(x - cx, py - cy) >= nameR + 2);
9401
+ for (const align of aligns) {
9402
+ const room = align === "center" ? 2 * Math.min(ax - area.x, area.x + area.width - ax) - 4 : align === "left" ? area.x + area.width - ax - 2 : ax - area.x - 2;
9403
+ const text = ellipsize(names[g], room, nameFont, measure);
9404
+ if (!text) continue;
9405
+ const w = measure(text, nameFont);
9406
+ const pts = samples(align === "left" ? ax : align === "right" ? ax - w : ax - w / 2, y, 1, 0, w);
9407
+ if (!clear(pts) || collides(pts)) continue;
9408
+ placed.push(pts);
9409
+ nodes.push({
9410
+ kind: "text",
9411
+ x: ax,
9412
+ y,
9413
+ text,
9414
+ font: nameFont,
9415
+ color,
9416
+ align,
9417
+ baseline: "middle",
9418
+ hit: g,
9419
+ also: ribbonsOf[g]
9420
+ });
9421
+ break;
9422
+ }
9423
+ continue;
9424
+ }
9425
+ const text = ellipsize(names[g], reach(mid) - nameR - 2, nameFont, measure);
9426
+ if (!text) continue;
9427
+ const pts = samples(ax, ay, Math.cos(mid), Math.sin(mid), measure(text, nameFont));
9428
+ if (collides(pts)) continue;
9429
+ placed.push(pts);
9430
+ const right = Math.cos(mid) >= 0;
9431
+ nodes.push({
9432
+ kind: "text",
9433
+ x: ax,
9434
+ y: ay,
9435
+ text,
9436
+ font: nameFont,
9437
+ color,
9438
+ align: right ? "left" : "right",
9439
+ baseline: "middle",
9440
+ rotate: right ? mid : mid + Math.PI,
9441
+ hit: g,
9442
+ also: ribbonsOf[g]
9443
+ });
9444
+ }
9445
+ }
9446
+ const items = [];
9447
+ for (const g of order) {
9448
+ const value = goal.value[g];
9449
+ if (!(value > 0) || hidden.has(g)) continue;
9450
+ const percent = whole > 0 ? value / whole : 0;
9451
+ const mid = (arcs[g].a0 + arcs[g].a1) / 2;
9452
+ items.push({
9453
+ index: g,
9454
+ name: names[g],
9455
+ value,
9456
+ percent,
9457
+ share: c.percent(percent),
9458
+ color: css[g],
9459
+ x: cx + outer * Math.cos(mid),
9460
+ y: cy + outer * Math.sin(mid),
9461
+ rows: [
9462
+ {
9463
+ name: c.labels.value,
9464
+ value: c.format(value)
9465
+ },
9466
+ ...!symmetric ? [{
9467
+ name: c.labels.outgoing,
9468
+ value: c.format(goal.out[g])
9469
+ }, {
9470
+ name: c.labels.incoming,
9471
+ value: c.format(goal.inc[g])
9472
+ }] : [],
9473
+ {
9474
+ name: c.labels.share,
9475
+ value: c.percent(percent)
9476
+ }
9477
+ ]
9478
+ });
9479
+ }
9480
+ const ribbonSize = (s, t) => directed ? target[s][t] : pair(target, s, t);
9481
+ let flowTotal = 0;
9482
+ for (let i = 0; i < n; i++) for (let j = directed ? 0 : i; j < n; j++) flowTotal += ribbonSize(i, j);
9483
+ const ribbonItems = ribbons.filter((r) => target[r.s][r.t] > 0 || target[r.t][r.s] > 0).sort((a, b) => pos[a.s] - pos[b.s] || a.src.a0 - b.src.a0 || pos[a.t] - pos[b.t]);
9484
+ for (const r of ribbonItems) {
9485
+ const value = target[r.s][r.t];
9486
+ const reverse = r.s !== r.t && target[r.s][r.t] + target[r.t][r.s] > 0 ? raw[r.t][r.s] : 0;
9487
+ const percent = flowTotal > 0 ? ribbonSize(r.s, r.t) / flowTotal : 0;
9488
+ const source = names[r.s];
9489
+ const tgt = names[r.t];
9490
+ const ms = (r.src.a0 + r.src.a1) / 2;
9491
+ const mt = (r.tgt.a0 + r.tgt.a1) / 2;
9492
+ const x = r.s === r.t ? cx + ribbonR * .7 * Math.cos(ms) : .25 * (cx + ribbonR * Math.cos(ms)) + .5 * cx + .25 * (cx + ribbonR * Math.cos(mt));
9493
+ const y = r.s === r.t ? cy + ribbonR * .7 * Math.sin(ms) : .25 * (cy + ribbonR * Math.sin(ms)) + .5 * cy + .25 * (cy + ribbonR * Math.sin(mt));
9494
+ items.push({
9495
+ index: r.index,
9496
+ name: r.s === r.t ? source : `${source} \u2192 ${tgt}`,
9497
+ value,
9498
+ percent,
9499
+ share: c.percent(percent),
9500
+ color: css[r.s],
9501
+ x,
9502
+ y,
9503
+ rows: [
9504
+ {
9505
+ name: c.labels.value,
9506
+ value: c.format(value)
9507
+ },
9508
+ ...r.s !== r.t && (directed ? reverse > 0 : !symmetric) ? [{
9509
+ name: c.labels.reverse,
9510
+ value: c.format(reverse)
9511
+ }] : [],
9512
+ {
9513
+ name: c.labels.share,
9514
+ value: c.percent(percent)
9515
+ }
9516
+ ],
9517
+ event: {
9518
+ source,
9519
+ target: tgt,
9520
+ reverseValue: reverse
9521
+ }
9522
+ });
9523
+ }
9524
+ const enter = clamp(c.enter, 0, 1);
9525
+ return {
9526
+ nodes,
9527
+ items,
9528
+ dim: .25,
9529
+ empty: false,
9530
+ ...enter < 1 ? { enter: {
9531
+ alpha: enter,
9532
+ scale: .94 + .06 * enter,
9533
+ cx,
9534
+ cy
9535
+ } } : {}
9536
+ };
9537
+ };
9538
+ //#endregion
7790
9539
  //#region ../charts/src/engine/shapes/funnel.ts
7791
9540
  var keysOf$2 = (o) => uniqueKeys(o.data.map((d) => d.name));
7792
9541
  var funnelValues = (o, hidden, out) => {
@@ -10430,6 +12179,9 @@ var layoutShapeScene = (input) => {
10430
12179
  case "bullet":
10431
12180
  result = layoutBullet(o, c);
10432
12181
  break;
12182
+ case "chord":
12183
+ result = layoutChord(o, c);
12184
+ break;
10433
12185
  default: result = layoutTreemap(o, c);
10434
12186
  }
10435
12187
  return {
@@ -10472,6 +12224,9 @@ var shapeValues = (o, hidden = NO_HIDDEN, focus = NO_FOCUS) => {
10472
12224
  case "bullet":
10473
12225
  bulletValues(o, hidden, out);
10474
12226
  break;
12227
+ case "chord":
12228
+ chordValues(o, hidden, out);
12229
+ break;
10475
12230
  default: treemapValues(o, hidden, out);
10476
12231
  }
10477
12232
  return out;
@@ -10575,12 +12330,24 @@ var shapeLegend = (o, theme, hidden = NO_HIDDEN) => {
10575
12330
  case "calendarHeatmap":
10576
12331
  shown = true;
10577
12332
  entries = calendarLegend(o, theme, hidden);
12333
+ break;
12334
+ case "chord": {
12335
+ shown = true;
12336
+ const m = resolveChord(o);
12337
+ entries = m.names.map((name, i) => ({
12338
+ index: i,
12339
+ name,
12340
+ color: color(m.colors[i], i),
12341
+ hidden: hidden.has(i)
12342
+ }));
12343
+ break;
12344
+ }
10578
12345
  }
10579
12346
  return shown && entries.length ? entries : null;
10580
12347
  };
10581
12348
  /**
10582
12349
  * Number of toggleable entries (slices, stages, series, top-level nodes,
10583
- * sankey nodes, bars, rows, calendar levels)
12350
+ * sankey nodes, bars, rows, calendar levels, chord groups)
10584
12351
  */
10585
12352
  var toggleCount = (o) => {
10586
12353
  switch (o.type) {
@@ -10588,6 +12355,7 @@ var toggleCount = (o) => {
10588
12355
  case "gauge": return 0;
10589
12356
  case "sankey": return resolveSankey(o).names.length;
10590
12357
  case "calendarHeatmap": return calendarModel(o)?.count ?? 0;
12358
+ case "chord": return resolveChord(o).names.length;
10591
12359
  default: return o.data.length;
10592
12360
  }
10593
12361
  };
@@ -10633,6 +12401,23 @@ var tooltipContent = (scene, hover) => {
10633
12401
  rows
10634
12402
  };
10635
12403
  };
12404
+ /** Default accessible name of a chart (in its `locale`) */
12405
+ var describeChart = (o) => {
12406
+ const l = shapeLabels(o);
12407
+ switch (o.type) {
12408
+ case "pie": return o.rose ? l.roseChart : (o.innerRadius ?? 0) > 0 ? l.donutChart : l.pieChart;
12409
+ case "radar": return l.radarChart;
12410
+ case "gauge": return o.label ? interpolate(l.gaugeChartNamed, { label: o.label }) : l.gaugeChart;
12411
+ case "funnel": return l.funnelChart;
12412
+ case "sankey": return l.sankeyChart;
12413
+ case "sunburst": return l.sunburstChart;
12414
+ case "radialBar": return l.radialBarChart;
12415
+ case "calendarHeatmap": return l.calendarHeatmap;
12416
+ case "bullet": return l.bulletChart;
12417
+ case "chord": return l.chordChart;
12418
+ default: return l.treemapChart;
12419
+ }
12420
+ };
10636
12421
  var LEGEND_ROW = 20;
10637
12422
  /** Centered legend rows drawn on a canvas; `height` includes the gap with the chart */
10638
12423
  var layoutShapeLegend = (entries, width, position, chartHeight, theme, measure) => {
@@ -10758,6 +12543,7 @@ var layoutShapeTooltip = (value, anchorX, anchorY, width, height, theme, measure
10758
12543
  let lines;
10759
12544
  let content;
10760
12545
  let text;
12546
+ let titleLines;
10761
12547
  if (typeof value === "string") {
10762
12548
  text = value.split("\n");
10763
12549
  const f = font(theme, 12);
@@ -10765,9 +12551,14 @@ var layoutShapeTooltip = (value, anchorX, anchorY, width, height, theme, measure
10765
12551
  lines = text.length;
10766
12552
  } else {
10767
12553
  content = value;
10768
- w = (value.color ? 14 : 0) + measure(value.title, font(theme, 12, 600));
12554
+ const titleFont = font(theme, 12, 600);
12555
+ const dot = value.color ? 14 : 0;
12556
+ const maxTitle = Math.max(60, Math.min(260, width - 16 - 18) - dot);
12557
+ titleLines = wrapText(value.title, maxTitle, titleFont, measure, 3);
12558
+ if (!titleLines.length) titleLines = [value.title];
12559
+ for (const line of titleLines) w = Math.max(w, dot + measure(line, titleFont));
10769
12560
  for (const row of value.rows) w = Math.max(w, (row.color ? 14 : 0) + measure(row.name, font(theme, 12)) + 16 + measure(row.value, font(theme, 12, 600)));
10770
- lines = 1 + value.rows.length;
12561
+ lines = titleLines.length + value.rows.length;
10771
12562
  }
10772
12563
  const bw = Math.max(96, Math.ceil(w + 18 + 4));
10773
12564
  const bh = lines * lineHeight + 18;
@@ -10782,7 +12573,10 @@ var layoutShapeTooltip = (value, anchorX, anchorY, width, height, theme, measure
10782
12573
  height: bh,
10783
12574
  padding,
10784
12575
  lineHeight,
10785
- ...content ? { content } : {},
12576
+ ...content ? {
12577
+ content,
12578
+ titleLines
12579
+ } : {},
10786
12580
  ...text ? { text } : {}
10787
12581
  };
10788
12582
  };
@@ -11284,6 +13078,18 @@ Object.defineProperty(exports, "createChartController", {
11284
13078
  return createChartController;
11285
13079
  }
11286
13080
  });
13081
+ Object.defineProperty(exports, "describeChart", {
13082
+ enumerable: true,
13083
+ get: function() {
13084
+ return describeChart;
13085
+ }
13086
+ });
13087
+ Object.defineProperty(exports, "describeChart$1", {
13088
+ enumerable: true,
13089
+ get: function() {
13090
+ return describeChart$1;
13091
+ }
13092
+ });
11287
13093
  Object.defineProperty(exports, "drawPrimitives", {
11288
13094
  enumerable: true,
11289
13095
  get: function() {
@@ -11308,6 +13114,12 @@ Object.defineProperty(exports, "formatCompact", {
11308
13114
  return formatCompact;
11309
13115
  }
11310
13116
  });
13117
+ Object.defineProperty(exports, "formatDuration", {
13118
+ enumerable: true,
13119
+ get: function() {
13120
+ return formatDuration;
13121
+ }
13122
+ });
11311
13123
  Object.defineProperty(exports, "formatValue", {
11312
13124
  enumerable: true,
11313
13125
  get: function() {