minerva-design 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/charts/canvas.d.cts +4 -1
  3. package/dist/charts/canvas.d.ts +4 -1
  4. package/dist/charts/core.cjs +1 -1
  5. package/dist/charts/core.d.cts +5 -2
  6. package/dist/charts/core.d.ts +5 -2
  7. package/dist/charts/core.js +6 -4
  8. package/dist/charts/engine/canvas.cjs +1 -1
  9. package/dist/charts/engine/canvas.cjs.map +1 -1
  10. package/dist/charts/engine/canvas.js +65 -53
  11. package/dist/charts/engine/canvas.js.map +1 -1
  12. package/dist/charts/engine/chart.cjs +1 -2
  13. package/dist/charts/engine/chart.cjs.map +1 -1
  14. package/dist/charts/engine/chart.js +342 -323
  15. package/dist/charts/engine/chart.js.map +1 -1
  16. package/dist/charts/engine/color.cjs +1 -1
  17. package/dist/charts/engine/color.cjs.map +1 -1
  18. package/dist/charts/engine/color.d.cts +17 -0
  19. package/dist/charts/engine/color.d.ts +17 -0
  20. package/dist/charts/engine/color.js +27 -3
  21. package/dist/charts/engine/color.js.map +1 -1
  22. package/dist/charts/engine/controller.cjs +2 -2
  23. package/dist/charts/engine/controller.cjs.map +1 -1
  24. package/dist/charts/engine/controller.d.cts +6 -0
  25. package/dist/charts/engine/controller.d.ts +6 -0
  26. package/dist/charts/engine/controller.js +317 -253
  27. package/dist/charts/engine/controller.js.map +1 -1
  28. package/dist/charts/engine/curve.cjs +2 -0
  29. package/dist/charts/engine/curve.cjs.map +1 -0
  30. package/dist/charts/engine/curve.d.cts +15 -0
  31. package/dist/charts/engine/curve.d.ts +15 -0
  32. package/dist/charts/engine/curve.js +56 -0
  33. package/dist/charts/engine/curve.js.map +1 -0
  34. package/dist/charts/engine/data.cjs +1 -1
  35. package/dist/charts/engine/data.cjs.map +1 -1
  36. package/dist/charts/engine/data.d.cts +15 -2
  37. package/dist/charts/engine/data.d.ts +15 -2
  38. package/dist/charts/engine/data.js +98 -38
  39. package/dist/charts/engine/data.js.map +1 -1
  40. package/dist/charts/engine/dom.cjs +1 -1
  41. package/dist/charts/engine/dom.cjs.map +1 -1
  42. package/dist/charts/engine/dom.d.cts +5 -3
  43. package/dist/charts/engine/dom.d.ts +5 -3
  44. package/dist/charts/engine/dom.js +27 -22
  45. package/dist/charts/engine/dom.js.map +1 -1
  46. package/dist/charts/engine/items.cjs +1 -1
  47. package/dist/charts/engine/items.cjs.map +1 -1
  48. package/dist/charts/engine/items.js +132 -61
  49. package/dist/charts/engine/items.js.map +1 -1
  50. package/dist/charts/engine/model.cjs +1 -1
  51. package/dist/charts/engine/model.cjs.map +1 -1
  52. package/dist/charts/engine/model.d.cts +30 -3
  53. package/dist/charts/engine/model.d.ts +30 -3
  54. package/dist/charts/engine/model.js +225 -108
  55. package/dist/charts/engine/model.js.map +1 -1
  56. package/dist/charts/engine/overlay.cjs +1 -1
  57. package/dist/charts/engine/overlay.cjs.map +1 -1
  58. package/dist/charts/engine/overlay.d.cts +2 -0
  59. package/dist/charts/engine/overlay.d.ts +2 -0
  60. package/dist/charts/engine/overlay.js +16 -16
  61. package/dist/charts/engine/overlay.js.map +1 -1
  62. package/dist/charts/engine/presets.cjs +2 -2
  63. package/dist/charts/engine/presets.cjs.map +1 -1
  64. package/dist/charts/engine/presets.d.cts +71 -5
  65. package/dist/charts/engine/presets.d.ts +71 -5
  66. package/dist/charts/engine/presets.js +120 -33
  67. package/dist/charts/engine/presets.js.map +1 -1
  68. package/dist/charts/engine/renderers/canvas2d.cjs +1 -1
  69. package/dist/charts/engine/renderers/canvas2d.cjs.map +1 -1
  70. package/dist/charts/engine/renderers/canvas2d.js +149 -111
  71. package/dist/charts/engine/renderers/canvas2d.js.map +1 -1
  72. package/dist/charts/engine/renderers/range.cjs +1 -1
  73. package/dist/charts/engine/renderers/range.cjs.map +1 -1
  74. package/dist/charts/engine/renderers/range.js +4 -4
  75. package/dist/charts/engine/renderers/range.js.map +1 -1
  76. package/dist/charts/engine/renderers/shaders.cjs +37 -19
  77. package/dist/charts/engine/renderers/shaders.cjs.map +1 -1
  78. package/dist/charts/engine/renderers/shaders.d.cts +2 -2
  79. package/dist/charts/engine/renderers/shaders.d.ts +2 -2
  80. package/dist/charts/engine/renderers/shaders.js +37 -19
  81. package/dist/charts/engine/renderers/shaders.js.map +1 -1
  82. package/dist/charts/engine/renderers/types.cjs.map +1 -1
  83. package/dist/charts/engine/renderers/types.d.cts +11 -4
  84. package/dist/charts/engine/renderers/types.d.ts +11 -4
  85. package/dist/charts/engine/renderers/types.js.map +1 -1
  86. package/dist/charts/engine/renderers/webgl2.cjs +1 -1
  87. package/dist/charts/engine/renderers/webgl2.cjs.map +1 -1
  88. package/dist/charts/engine/renderers/webgl2.js +33 -12
  89. package/dist/charts/engine/renderers/webgl2.js.map +1 -1
  90. package/dist/charts/engine/renderers/webgpu.cjs +1 -1
  91. package/dist/charts/engine/renderers/webgpu.cjs.map +1 -1
  92. package/dist/charts/engine/renderers/webgpu.js +18 -15
  93. package/dist/charts/engine/renderers/webgpu.js.map +1 -1
  94. package/dist/charts/engine/scene.cjs +1 -1
  95. package/dist/charts/engine/scene.cjs.map +1 -1
  96. package/dist/charts/engine/scene.d.cts +19 -6
  97. package/dist/charts/engine/scene.d.ts +19 -6
  98. package/dist/charts/engine/scene.js +201 -89
  99. package/dist/charts/engine/scene.js.map +1 -1
  100. package/dist/charts/engine/shapes/canvas.cjs +2 -0
  101. package/dist/charts/engine/shapes/canvas.cjs.map +1 -0
  102. package/dist/charts/engine/shapes/canvas.d.cts +58 -0
  103. package/dist/charts/engine/shapes/canvas.d.ts +58 -0
  104. package/dist/charts/engine/shapes/canvas.js +159 -0
  105. package/dist/charts/engine/shapes/canvas.js.map +1 -0
  106. package/dist/charts/engine/shapes/chart.cjs +2 -0
  107. package/dist/charts/engine/shapes/chart.cjs.map +1 -0
  108. package/dist/charts/engine/shapes/chart.d.cts +6 -0
  109. package/dist/charts/engine/shapes/chart.d.ts +6 -0
  110. package/dist/charts/engine/shapes/chart.js +273 -0
  111. package/dist/charts/engine/shapes/chart.js.map +1 -0
  112. package/dist/charts/engine/shapes/draw.cjs +2 -0
  113. package/dist/charts/engine/shapes/draw.cjs.map +1 -0
  114. package/dist/charts/engine/shapes/draw.d.cts +20 -0
  115. package/dist/charts/engine/shapes/draw.d.ts +20 -0
  116. package/dist/charts/engine/shapes/draw.js +152 -0
  117. package/dist/charts/engine/shapes/draw.js.map +1 -0
  118. package/dist/charts/engine/shapes/funnel.cjs +2 -0
  119. package/dist/charts/engine/shapes/funnel.cjs.map +1 -0
  120. package/dist/charts/engine/shapes/funnel.d.cts +6 -0
  121. package/dist/charts/engine/shapes/funnel.d.ts +6 -0
  122. package/dist/charts/engine/shapes/funnel.js +149 -0
  123. package/dist/charts/engine/shapes/funnel.js.map +1 -0
  124. package/dist/charts/engine/shapes/gauge.cjs +2 -0
  125. package/dist/charts/engine/shapes/gauge.cjs.map +1 -0
  126. package/dist/charts/engine/shapes/gauge.d.cts +7 -0
  127. package/dist/charts/engine/shapes/gauge.d.ts +7 -0
  128. package/dist/charts/engine/shapes/gauge.js +173 -0
  129. package/dist/charts/engine/shapes/gauge.js.map +1 -0
  130. package/dist/charts/engine/shapes/hit.cjs +2 -0
  131. package/dist/charts/engine/shapes/hit.cjs.map +1 -0
  132. package/dist/charts/engine/shapes/hit.d.cts +28 -0
  133. package/dist/charts/engine/shapes/hit.d.ts +28 -0
  134. package/dist/charts/engine/shapes/hit.js +124 -0
  135. package/dist/charts/engine/shapes/hit.js.map +1 -0
  136. package/dist/charts/engine/shapes/index.d.cts +9 -0
  137. package/dist/charts/engine/shapes/index.d.ts +9 -0
  138. package/dist/charts/engine/shapes/layout.cjs +3 -0
  139. package/dist/charts/engine/shapes/layout.cjs.map +1 -0
  140. package/dist/charts/engine/shapes/layout.d.cts +88 -0
  141. package/dist/charts/engine/shapes/layout.d.ts +88 -0
  142. package/dist/charts/engine/shapes/layout.js +266 -0
  143. package/dist/charts/engine/shapes/layout.js.map +1 -0
  144. package/dist/charts/engine/shapes/pie.cjs +2 -0
  145. package/dist/charts/engine/shapes/pie.cjs.map +1 -0
  146. package/dist/charts/engine/shapes/pie.d.cts +20 -0
  147. package/dist/charts/engine/shapes/pie.d.ts +20 -0
  148. package/dist/charts/engine/shapes/pie.js +302 -0
  149. package/dist/charts/engine/shapes/pie.js.map +1 -0
  150. package/dist/charts/engine/shapes/radar.cjs +2 -0
  151. package/dist/charts/engine/shapes/radar.cjs.map +1 -0
  152. package/dist/charts/engine/shapes/radar.d.cts +8 -0
  153. package/dist/charts/engine/shapes/radar.d.ts +8 -0
  154. package/dist/charts/engine/shapes/radar.js +197 -0
  155. package/dist/charts/engine/shapes/radar.js.map +1 -0
  156. package/dist/charts/engine/shapes/runtime.cjs +2 -0
  157. package/dist/charts/engine/shapes/runtime.cjs.map +1 -0
  158. package/dist/charts/engine/shapes/runtime.d.cts +29 -0
  159. package/dist/charts/engine/shapes/runtime.d.ts +29 -0
  160. package/dist/charts/engine/shapes/runtime.js +97 -0
  161. package/dist/charts/engine/shapes/runtime.js.map +1 -0
  162. package/dist/charts/engine/shapes/scene.cjs +2 -0
  163. package/dist/charts/engine/shapes/scene.cjs.map +1 -0
  164. package/dist/charts/engine/shapes/scene.d.cts +257 -0
  165. package/dist/charts/engine/shapes/scene.d.ts +257 -0
  166. package/dist/charts/engine/shapes/scene.js +123 -0
  167. package/dist/charts/engine/shapes/scene.js.map +1 -0
  168. package/dist/charts/engine/shapes/treemap.cjs +2 -0
  169. package/dist/charts/engine/shapes/treemap.cjs.map +1 -0
  170. package/dist/charts/engine/shapes/treemap.d.cts +14 -0
  171. package/dist/charts/engine/shapes/treemap.d.ts +14 -0
  172. package/dist/charts/engine/shapes/treemap.js +213 -0
  173. package/dist/charts/engine/shapes/treemap.js.map +1 -0
  174. package/dist/charts/engine/shapes/types.d.cts +292 -0
  175. package/dist/charts/engine/shapes/types.d.ts +292 -0
  176. package/dist/charts/engine/signature.cjs +2 -0
  177. package/dist/charts/engine/signature.cjs.map +1 -0
  178. package/dist/charts/engine/signature.d.cts +9 -0
  179. package/dist/charts/engine/signature.d.ts +9 -0
  180. package/dist/charts/engine/signature.js +13 -0
  181. package/dist/charts/engine/signature.js.map +1 -0
  182. package/dist/charts/engine/theme.cjs +1 -1
  183. package/dist/charts/engine/theme.cjs.map +1 -1
  184. package/dist/charts/engine/theme.d.cts +10 -1
  185. package/dist/charts/engine/theme.d.ts +10 -1
  186. package/dist/charts/engine/theme.js +40 -16
  187. package/dist/charts/engine/theme.js.map +1 -1
  188. package/dist/charts/engine/types.d.cts +70 -9
  189. package/dist/charts/engine/types.d.ts +70 -9
  190. package/dist/charts/index.cjs +1 -1
  191. package/dist/charts/index.d.cts +4 -2
  192. package/dist/charts/index.d.ts +4 -2
  193. package/dist/charts/index.js +8 -5
  194. package/dist/charts/react/Chart.cjs +1 -1
  195. package/dist/charts/react/Chart.cjs.map +1 -1
  196. package/dist/charts/react/Chart.d.cts +8 -1
  197. package/dist/charts/react/Chart.d.ts +8 -1
  198. package/dist/charts/react/Chart.js +66 -47
  199. package/dist/charts/react/Chart.js.map +1 -1
  200. package/dist/charts/react/charts.cjs +1 -1
  201. package/dist/charts/react/charts.cjs.map +1 -1
  202. package/dist/charts/react/charts.d.cts +10 -2
  203. package/dist/charts/react/charts.d.ts +10 -2
  204. package/dist/charts/react/charts.js +174 -51
  205. package/dist/charts/react/charts.js.map +1 -1
  206. package/dist/charts/react/shapes.cjs +2 -0
  207. package/dist/charts/react/shapes.cjs.map +1 -0
  208. package/dist/charts/react/shapes.d.cts +255 -0
  209. package/dist/charts/react/shapes.d.ts +255 -0
  210. package/dist/charts/react/shapes.js +242 -0
  211. package/dist/charts/react/shapes.js.map +1 -0
  212. package/dist/charts/react/types.d.cts +73 -4
  213. package/dist/charts/react/types.d.ts +73 -4
  214. package/dist/native/charts/src/engine/color.cjs +1 -1
  215. package/dist/native/charts/src/engine/color.cjs.map +1 -1
  216. package/dist/native/charts/src/engine/color.js +12 -3
  217. package/dist/native/charts/src/engine/color.js.map +1 -1
  218. package/dist/native/charts/src/engine/controller.cjs +2 -2
  219. package/dist/native/charts/src/engine/controller.cjs.map +1 -1
  220. package/dist/native/charts/src/engine/controller.js +334 -270
  221. package/dist/native/charts/src/engine/controller.js.map +1 -1
  222. package/dist/native/charts/src/engine/curve.cjs +2 -0
  223. package/dist/native/charts/src/engine/curve.cjs.map +1 -0
  224. package/dist/native/charts/src/engine/curve.js +56 -0
  225. package/dist/native/charts/src/engine/curve.js.map +1 -0
  226. package/dist/native/charts/src/engine/data.cjs +1 -1
  227. package/dist/native/charts/src/engine/data.cjs.map +1 -1
  228. package/dist/native/charts/src/engine/data.js +98 -38
  229. package/dist/native/charts/src/engine/data.js.map +1 -1
  230. package/dist/native/charts/src/engine/model.cjs +1 -1
  231. package/dist/native/charts/src/engine/model.cjs.map +1 -1
  232. package/dist/native/charts/src/engine/model.js +229 -112
  233. package/dist/native/charts/src/engine/model.js.map +1 -1
  234. package/dist/native/charts/src/engine/overlay.cjs +1 -1
  235. package/dist/native/charts/src/engine/overlay.cjs.map +1 -1
  236. package/dist/native/charts/src/engine/overlay.js +16 -16
  237. package/dist/native/charts/src/engine/overlay.js.map +1 -1
  238. package/dist/native/charts/src/engine/presets.cjs +1 -1
  239. package/dist/native/charts/src/engine/presets.cjs.map +1 -1
  240. package/dist/native/charts/src/engine/presets.js +11 -4
  241. package/dist/native/charts/src/engine/presets.js.map +1 -1
  242. package/dist/native/charts/src/engine/scene.cjs +1 -1
  243. package/dist/native/charts/src/engine/scene.cjs.map +1 -1
  244. package/dist/native/charts/src/engine/scene.js +209 -97
  245. package/dist/native/charts/src/engine/scene.js.map +1 -1
  246. package/dist/native/charts/src/engine/theme.cjs.map +1 -1
  247. package/dist/native/charts/src/engine/theme.js.map +1 -1
  248. package/dist/native/components/Chart/scene.cjs +1 -1
  249. package/dist/native/components/Chart/scene.cjs.map +1 -1
  250. package/dist/native/components/Chart/scene.js +31 -19
  251. package/dist/native/components/Chart/scene.js.map +1 -1
  252. package/dist/native/source/components/Chart/scene.tsx +54 -20
  253. package/dist/taro/index.js +1059 -579
  254. package/dist/uni/charts-canvas.js +3 -1
  255. package/dist/weapp/controls.js +966 -225
  256. package/package.json +1 -1
@@ -10,7 +10,17 @@ var e = (e, t = e.fontSize, n = 400) => `${n} ${t}px ${e.fontFamily}`, t = (e, t
10
10
  }, n = (e, t) => e.x < t.x + t.width && t.x < e.x + e.width && e.y < t.y + t.height && t.y < e.y + e.height, r = (e, t) => e.x >= t.x && e.y >= t.y && e.x + e.width <= t.x + t.width && e.y + e.height <= t.y + t.height, i = (e, t, i, a, o = []) => {
11
11
  let s = [];
12
12
  for (let c of e) {
13
- let e = i(c.text), l = c.r + 4, u = [
13
+ let e = i(c.text), l = c.r + 4, u = {
14
+ x: c.x - e / 2,
15
+ y: c.y - l - a,
16
+ width: e,
17
+ height: a
18
+ }, d = {
19
+ x: c.x - e / 2,
20
+ y: c.y + l,
21
+ width: e,
22
+ height: a
23
+ }, f = (c.placement === "above" ? [u] : c.placement === "below" ? [d] : [
14
24
  {
15
25
  x: c.x + l,
16
26
  y: c.y - a / 2,
@@ -23,22 +33,12 @@ var e = (e, t = e.fontSize, n = 400) => `${n} ${t}px ${e.fontFamily}`, t = (e, t
23
33
  width: e,
24
34
  height: a
25
35
  },
26
- {
27
- x: c.x - e / 2,
28
- y: c.y - l - a,
29
- width: e,
30
- height: a
31
- },
32
- {
33
- x: c.x - e / 2,
34
- y: c.y + l,
35
- width: e,
36
- height: a
37
- }
38
- ].find((e) => r(e, t) && !o.some((t) => n(t, e)));
39
- u && (o.push(u), s.push({
36
+ u,
37
+ d
38
+ ]).find((e) => r(e, t) && !o.some((t) => n(t, e)));
39
+ f && (o.push(f), s.push({
40
40
  label: c,
41
- box: u
41
+ box: f
42
42
  }));
43
43
  }
44
44
  return s;
@@ -1 +1 @@
1
- {"version":3,"file":"overlay.js","names":["font","theme","weight","size","textBox","s","px","a","plot","py","x","width","y","height","overlaps","b","inside","r","placeLabels","placed","label","labels","w","measure","gap","box","c","occupied","o"],"sources":["../../../../../../charts/src/engine/overlay.ts"],"sourcesContent":["// Canvas2D layers around the data: background (areas, grid, axes, tick\n// labels) and foreground (reference lines, annotation and point labels).\n\nimport { toCss, type Rgba } from \"./color\";\nimport type { AxisTicks } from \"./axis\";\nimport type { Rect, Scales } from \"./layout\";\nimport type { AxisModel } from \"./model\";\nimport type { ChartTheme } from \"./theme\";\nimport type { ChartLabelPosition } from \"./types\";\n\nexport interface ResolvedRect {\n type: \"rect\";\n x0?: number;\n x1?: number;\n y0?: number;\n y1?: number;\n color: Rgba;\n opacity: number;\n label?: string;\n labelPosition: ChartLabelPosition;\n labelColor: Rgba;\n}\n\nexport interface ResolvedLine {\n type: \"line\";\n axis: \"x\" | \"y\";\n value: number;\n color: Rgba;\n width: number;\n dash: number[];\n label?: string;\n}\n\nexport interface ResolvedText {\n type: \"text\";\n x?: number;\n y?: number;\n text: string;\n anchor: \"center\" | \"top\" | \"bottom\" | \"left\" | \"right\";\n color: Rgba;\n weight: number;\n}\n\nexport type ResolvedAnnotation = ResolvedRect | ResolvedLine | ResolvedText;\n\nexport interface PointLabel {\n x: number;\n y: number;\n /** Radius of the dot */\n r: number;\n text: string;\n}\n\nexport const font = (theme: ChartTheme, size = theme.fontSize, weight = 400) =>\n `${weight} ${size}px ${theme.fontFamily}`;\n\nconst crisp = (v: number) => Math.round(v) + 0.5;\n\n/** Box of a text annotation, kept inside the plot */\nexport const textBox = (\n a: ResolvedText,\n s: Scales,\n width: number,\n height: number,\n): Rect => {\n const { plot } = s;\n const px = a.x === undefined ? plot.x + plot.width / 2 : s.xToPx(a.x);\n const py = a.y === undefined ? plot.y + plot.height / 2 : s.yToPx(a.y);\n const gap = 6;\n let x = px - width / 2;\n let y = py - height / 2;\n if (a.anchor === \"top\") y = py + gap;\n else if (a.anchor === \"bottom\") y = py - gap - height;\n else if (a.anchor === \"left\") x = px + gap;\n else if (a.anchor === \"right\") x = px - gap - width;\n x = Math.max(plot.x + gap, Math.min(x, plot.x + plot.width - gap - width));\n y = Math.max(plot.y + 2, Math.min(y, plot.y + plot.height - 2 - height));\n return { x, y, width, height };\n};\n\nconst rectOf = (a: ResolvedRect, s: Scales): Rect => {\n const { plot } = s;\n const xa = a.x0 === undefined ? -Infinity : s.xToPx(a.x0);\n const xb = a.x1 === undefined ? Infinity : s.xToPx(a.x1);\n const ya = a.y0 === undefined ? Infinity : s.yToPx(a.y0);\n const yb = a.y1 === undefined ? -Infinity : s.yToPx(a.y1);\n const left = Math.max(plot.x, Math.min(xa, xb));\n const right = Math.min(plot.x + plot.width, Math.max(xa, xb));\n const top = Math.max(plot.y, Math.min(ya, yb));\n const bottom = Math.min(plot.y + plot.height, Math.max(ya, yb));\n return { x: left, y: top, width: right - left, height: bottom - top };\n};\n\nexport interface BackgroundInput {\n width: number;\n height: number;\n scales: Scales;\n x: AxisModel;\n y: AxisModel;\n xTicks: AxisTicks;\n yTicks: AxisTicks;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n}\n\nexport const drawBackground = (\n ctx: CanvasRenderingContext2D,\n input: BackgroundInput,\n) => {\n const { scales, theme, x, y, xTicks, yTicks } = input;\n const { plot } = scales;\n ctx.clearRect(0, 0, input.width, input.height);\n\n // areas\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n for (const a of input.annotations) {\n if (a.type !== \"rect\") continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n ctx.fillStyle = toCss(a.color, a.opacity);\n ctx.fillRect(r.x, r.y, r.width, r.height);\n }\n ctx.restore();\n\n // grid\n ctx.lineWidth = 1;\n ctx.strokeStyle = toCss(theme.grid);\n ctx.beginPath();\n if (y.grid) {\n for (const v of yTicks.values) {\n const py = crisp(scales.yToPx(v));\n if (py < plot.y - 1 || py > plot.y + plot.height + 1) continue;\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n }\n }\n if (x.grid) {\n for (const v of xTicks.values) {\n const px = crisp(scales.xToPx(v));\n if (px < plot.x - 1 || px > plot.x + plot.width + 1) continue;\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n }\n }\n ctx.stroke();\n\n const line = Math.ceil(theme.fontSize * 1.4);\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n\n // x axis\n if (x.visible) {\n ctx.strokeStyle = toCss(theme.axis);\n ctx.beginPath();\n const base = crisp(plot.y + plot.height);\n ctx.moveTo(plot.x, base);\n ctx.lineTo(plot.x + plot.width, base);\n ctx.stroke();\n ctx.textBaseline = \"top\";\n ctx.textAlign = \"center\";\n let lastRight = -Infinity;\n // left to right (reversed axes list their ticks right to left)\n const order = xTicks.values\n .map((v, i) => ({ px: scales.xToPx(v), text: xTicks.labels[i] }))\n .sort((a, b) => a.px - b.px);\n for (const { px, text } of order) {\n if (px < plot.x - 0.5 || px > plot.x + plot.width + 0.5) continue;\n const w = ctx.measureText(text).width;\n const left = Math.max(0, Math.min(input.width - w, px - w / 2));\n if (left < lastRight + 6) continue;\n lastRight = left + w;\n ctx.fillText(text, left + w / 2, plot.y + plot.height + 7);\n }\n if (x.title) {\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.fillText(\n x.title,\n plot.x + plot.width / 2,\n plot.y + plot.height + line + 10,\n );\n }\n }\n\n // y axis\n if (y.visible) {\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n yTicks.values.forEach((v, i) => {\n const py = scales.yToPx(v);\n if (py < plot.y - 0.5 || py > plot.y + plot.height + 0.5) return;\n ctx.fillText(yTicks.labels[i], plot.x - 8, py);\n });\n if (y.title) {\n ctx.save();\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.translate(line / 2 + 4, plot.y + plot.height / 2);\n ctx.rotate(-Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.fillText(y.title, 0, 0);\n ctx.restore();\n }\n }\n};\n\nconst overlaps = (a: Rect, b: Rect) =>\n a.x < b.x + b.width &&\n b.x < a.x + a.width &&\n a.y < b.y + b.height &&\n b.y < a.y + a.height;\n\nconst inside = (r: Rect, plot: Rect) =>\n r.x >= plot.x &&\n r.y >= plot.y &&\n r.x + r.width <= plot.x + plot.width &&\n r.y + r.height <= plot.y + plot.height;\n\n/** Text with a halo in the background color (readable over data) */\nconst haloText = (\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n color: string,\n halo: string,\n) => {\n ctx.lineWidth = 3;\n ctx.lineJoin = \"round\";\n ctx.strokeStyle = halo;\n ctx.strokeText(text, x, y);\n ctx.fillStyle = color;\n ctx.fillText(text, x, y);\n};\n\n/** Greedy placement: right, left, above, below the dot; skipped when no slot is free */\nexport const placeLabels = (\n labels: readonly PointLabel[],\n plot: Rect,\n measure: (text: string) => number,\n height: number,\n occupied: Rect[] = [],\n): { label: PointLabel; box: Rect }[] => {\n const placed: { label: PointLabel; box: Rect }[] = [];\n for (const label of labels) {\n const w = measure(label.text);\n const gap = label.r + 4;\n const candidates: Rect[] = [\n { x: label.x + gap, y: label.y - height / 2, width: w, height },\n { x: label.x - gap - w, y: label.y - height / 2, width: w, height },\n { x: label.x - w / 2, y: label.y - gap - height, width: w, height },\n { x: label.x - w / 2, y: label.y + gap, width: w, height },\n ];\n const box = candidates.find(\n (c) => inside(c, plot) && !occupied.some((o) => overlaps(o, c)),\n );\n if (!box) continue;\n occupied.push(box);\n placed.push({ label, box });\n }\n return placed;\n};\n\nexport interface ForegroundInput {\n width: number;\n height: number;\n scales: Scales;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n pointLabels: readonly PointLabel[];\n /**\n * Clears the canvas first (off when the layers share one canvas)\n * @default true\n */\n clear?: boolean;\n}\n\nexport const drawForeground = (\n ctx: CanvasRenderingContext2D,\n input: ForegroundInput,\n) => {\n const { scales, theme } = input;\n const { plot } = scales;\n if (input.clear !== false) ctx.clearRect(0, 0, input.width, input.height);\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n\n const halo = toCss(theme.background, 0.9);\n const occupied: Rect[] = [];\n const labelHeight = theme.fontSize + 4;\n\n for (const a of input.annotations) {\n if (a.type !== \"line\") continue;\n const color = toCss(a.color);\n ctx.strokeStyle = color;\n ctx.lineWidth = a.width;\n ctx.setLineDash(a.dash);\n ctx.beginPath();\n if (a.axis === \"y\") {\n const py = crisp(scales.yToPx(a.value));\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"bottom\";\n haloText(ctx, a.label, plot.x + plot.width - 6, py - 3, color, halo);\n }\n } else {\n const px = crisp(scales.xToPx(a.value));\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n haloText(ctx, a.label, px + 5, plot.y + 5, color, halo);\n }\n }\n }\n ctx.setLineDash([]);\n\n // labels of areas\n ctx.font = font(theme, theme.fontSize + 1, 600);\n for (const a of input.annotations) {\n if (a.type !== \"rect\" || !a.label) continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n const pad = 10;\n const w = ctx.measureText(a.label).width;\n const pos = a.labelPosition;\n const tx = pos.endsWith(\"left\")\n ? r.x + pad\n : pos.endsWith(\"right\")\n ? r.x + r.width - pad - w\n : r.x + (r.width - w) / 2;\n const ty = pos.startsWith(\"top\")\n ? r.y + pad\n : pos.startsWith(\"bottom\")\n ? r.y + r.height - pad - labelHeight\n : r.y + (r.height - labelHeight) / 2;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n ctx.fillStyle = toCss(a.labelColor);\n ctx.fillText(a.label, tx, ty);\n occupied.push({ x: tx, y: ty, width: w, height: labelHeight });\n }\n\n // free texts\n for (const a of input.annotations) {\n if (a.type !== \"text\" || !a.text) continue;\n ctx.font = font(theme, theme.fontSize, a.weight);\n const box = textBox(a, scales, ctx.measureText(a.text).width, labelHeight);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n haloText(ctx, a.text, box.x, box.y + box.height / 2, toCss(a.color), halo);\n occupied.push(box);\n }\n\n // point labels\n if (input.pointLabels.length) {\n ctx.font = font(theme);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n const textColor = toCss(theme.text, 0.85);\n const placed = placeLabels(\n input.pointLabels,\n plot,\n (t) => ctx.measureText(t).width,\n labelHeight - 2,\n occupied,\n );\n for (const { label, box } of placed) {\n haloText(ctx, label.text, box.x, box.y + box.height / 2, textColor, halo);\n }\n }\n ctx.restore();\n};\n"],"mappings":";AAqDA,IAAaA,KAAQ,GAAmB,IAAOC,EAAM,UAAU,IAAS,QACtE,GAAGC,EAAO,GAAGC,EAAK,KAAKF,EAAM,cAKlBG,KACX,GACA,GACA,GACA,MACS;CACT,IAAM,EAAE,YAASC,GACXC,IAAKC,EAAE,MAAM,KAAA,IAAYC,EAAK,IAAIA,EAAK,QAAQ,IAAIH,EAAE,MAAME,EAAE,CAAC,GAC9DE,IAAKF,EAAE,MAAM,KAAA,IAAYC,EAAK,IAAIA,EAAK,SAAS,IAAIH,EAAE,MAAME,EAAE,CAAC,GAEjEG,IAAIJ,IAAKK,IAAQ,GACjBC,IAAIH,IAAKI,IAAS;CAOtB,OANIN,EAAE,WAAW,QAAO,IAAIE,IAAK,IACxBF,EAAE,WAAW,WAAU,IAAIE,IAAK,IAAMI,IACtCN,EAAE,WAAW,SAAQ,IAAID,IAAK,IAC9BC,EAAE,WAAW,YAAS,IAAID,IAAK,IAAMK,IAC9C,IAAI,KAAK,IAAIH,EAAK,IAAI,GAAK,KAAK,IAAIE,GAAGF,EAAK,IAAIA,EAAK,QAAQ,IAAMG,CAAK,CAAC,GACzE,IAAI,KAAK,IAAIH,EAAK,IAAI,GAAG,KAAK,IAAII,GAAGJ,EAAK,IAAIA,EAAK,SAAS,IAAIK,CAAM,CAAC,GAChE;EAAE;EAAG;EAAG;EAAO;CAAO;AAC/B,GAqIMC,KAAY,GAAS,MACzBP,EAAE,IAAIQ,EAAE,IAAIA,EAAE,SACdA,EAAE,IAAIR,EAAE,IAAIA,EAAE,SACdA,EAAE,IAAIQ,EAAE,IAAIA,EAAE,UACdA,EAAE,IAAIR,EAAE,IAAIA,EAAE,QAEVS,KAAU,GAAS,MACvBC,EAAE,KAAKT,EAAK,KACZS,EAAE,KAAKT,EAAK,KACZS,EAAE,IAAIA,EAAE,SAAST,EAAK,IAAIA,EAAK,SAC/BS,EAAE,IAAIA,EAAE,UAAUT,EAAK,IAAIA,EAAK,QAoBrBU,KACX,GACA,GACA,GACA,GACA,IAAmB,CAAC,MACmB;CACvC,IAAMC,IAA6C,CAAC;CACpD,KAAK,IAAMC,KAASC,GAAQ;EAC1B,IAAMC,IAAIC,EAAQH,EAAM,IAAI,GACtBI,IAAMJ,EAAM,IAAI,GAOhBK,IAAM;GALV;IAAE,GAAGL,EAAM,IAAII;IAAK,GAAGJ,EAAM,IAAIP,IAAS;IAAG,OAAOS;IAAG;GAAO;GAC9D;IAAE,GAAGF,EAAM,IAAII,IAAMF;IAAG,GAAGF,EAAM,IAAIP,IAAS;IAAG,OAAOS;IAAG;GAAO;GAClE;IAAE,GAAGF,EAAM,IAAIE,IAAI;IAAG,GAAGF,EAAM,IAAII,IAAMX;IAAQ,OAAOS;IAAG;GAAO;GAClE;IAAE,GAAGF,EAAM,IAAIE,IAAI;IAAG,GAAGF,EAAM,IAAII;IAAK,OAAOF;IAAG;GAAO;EAE/C,CAAA,CAAW,MACpB,MAAMN,EAAOU,GAAGlB,CAAI,KAAK,CAACmB,EAAS,MAAM,MAAMb,EAASc,GAAGF,CAAC,CAAC,CAChE;EACA,AAAKD,MACLE,EAAS,KAAKF,CAAG,GACjBN,EAAO,KAAK;GAAE;GAAO;EAAI,CAAC;CAC5B;CACA,OAAOA;AACT"}
1
+ {"version":3,"file":"overlay.js","names":["font","theme","weight","size","textBox","s","px","a","plot","py","x","width","y","height","overlaps","b","inside","r","placeLabels","placed","label","labels","w","measure","gap","above","below","box","c","occupied","o"],"sources":["../../../../../../charts/src/engine/overlay.ts"],"sourcesContent":["// Canvas2D layers around the data: background (areas, grid, axes, tick\n// labels) and foreground (reference lines, annotation and point labels).\n\nimport { toCss, type Rgba } from \"./color\";\nimport type { AxisTicks } from \"./axis\";\nimport type { Rect, Scales } from \"./layout\";\nimport type { AxisModel } from \"./model\";\nimport type { ChartTheme } from \"./theme\";\nimport type { ChartLabelPosition } from \"./types\";\n\nexport interface ResolvedRect {\n type: \"rect\";\n x0?: number;\n x1?: number;\n y0?: number;\n y1?: number;\n color: Rgba;\n opacity: number;\n label?: string;\n labelPosition: ChartLabelPosition;\n labelColor: Rgba;\n}\n\nexport interface ResolvedLine {\n type: \"line\";\n axis: \"x\" | \"y\";\n value: number;\n color: Rgba;\n width: number;\n dash: number[];\n label?: string;\n}\n\nexport interface ResolvedText {\n type: \"text\";\n x?: number;\n y?: number;\n text: string;\n anchor: \"center\" | \"top\" | \"bottom\" | \"left\" | \"right\";\n color: Rgba;\n weight: number;\n}\n\nexport type ResolvedAnnotation = ResolvedRect | ResolvedLine | ResolvedText;\n\nexport interface PointLabel {\n x: number;\n y: number;\n /** Radius of the dot */\n r: number;\n text: string;\n /** Fixed side (bar values); any free side around the dot otherwise */\n placement?: \"above\" | \"below\";\n}\n\nexport const font = (theme: ChartTheme, size = theme.fontSize, weight = 400) =>\n `${weight} ${size}px ${theme.fontFamily}`;\n\nconst crisp = (v: number) => Math.round(v) + 0.5;\n\n/** Box of a text annotation, kept inside the plot */\nexport const textBox = (\n a: ResolvedText,\n s: Scales,\n width: number,\n height: number,\n): Rect => {\n const { plot } = s;\n const px = a.x === undefined ? plot.x + plot.width / 2 : s.xToPx(a.x);\n const py = a.y === undefined ? plot.y + plot.height / 2 : s.yToPx(a.y);\n const gap = 6;\n let x = px - width / 2;\n let y = py - height / 2;\n if (a.anchor === \"top\") y = py + gap;\n else if (a.anchor === \"bottom\") y = py - gap - height;\n else if (a.anchor === \"left\") x = px + gap;\n else if (a.anchor === \"right\") x = px - gap - width;\n x = Math.max(plot.x + gap, Math.min(x, plot.x + plot.width - gap - width));\n y = Math.max(plot.y + 2, Math.min(y, plot.y + plot.height - 2 - height));\n return { x, y, width, height };\n};\n\nconst rectOf = (a: ResolvedRect, s: Scales): Rect => {\n const { plot } = s;\n const xa = a.x0 === undefined ? -Infinity : s.xToPx(a.x0);\n const xb = a.x1 === undefined ? Infinity : s.xToPx(a.x1);\n const ya = a.y0 === undefined ? Infinity : s.yToPx(a.y0);\n const yb = a.y1 === undefined ? -Infinity : s.yToPx(a.y1);\n const left = Math.max(plot.x, Math.min(xa, xb));\n const right = Math.min(plot.x + plot.width, Math.max(xa, xb));\n const top = Math.max(plot.y, Math.min(ya, yb));\n const bottom = Math.min(plot.y + plot.height, Math.max(ya, yb));\n return { x: left, y: top, width: right - left, height: bottom - top };\n};\n\nexport interface BackgroundInput {\n width: number;\n height: number;\n scales: Scales;\n x: AxisModel;\n y: AxisModel;\n xTicks: AxisTicks;\n yTicks: AxisTicks;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n}\n\nexport const drawBackground = (\n ctx: CanvasRenderingContext2D,\n input: BackgroundInput,\n) => {\n const { scales, theme, x, y, xTicks, yTicks } = input;\n const { plot } = scales;\n ctx.clearRect(0, 0, input.width, input.height);\n\n // areas\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n for (const a of input.annotations) {\n if (a.type !== \"rect\") continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n ctx.fillStyle = toCss(a.color, a.opacity);\n ctx.fillRect(r.x, r.y, r.width, r.height);\n }\n ctx.restore();\n\n // grid\n ctx.lineWidth = 1;\n ctx.strokeStyle = toCss(theme.grid);\n ctx.beginPath();\n if (y.grid) {\n for (const v of yTicks.values) {\n const py = crisp(scales.yToPx(v));\n if (py < plot.y - 1 || py > plot.y + plot.height + 1) continue;\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n }\n }\n if (x.grid) {\n for (const v of xTicks.values) {\n const px = crisp(scales.xToPx(v));\n if (px < plot.x - 1 || px > plot.x + plot.width + 1) continue;\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n }\n }\n ctx.stroke();\n\n const line = Math.ceil(theme.fontSize * 1.4);\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n\n // x axis\n if (x.visible) {\n ctx.strokeStyle = toCss(theme.axis);\n ctx.beginPath();\n const base = crisp(plot.y + plot.height);\n ctx.moveTo(plot.x, base);\n ctx.lineTo(plot.x + plot.width, base);\n ctx.stroke();\n ctx.textBaseline = \"top\";\n ctx.textAlign = \"center\";\n let lastRight = -Infinity;\n // left to right (reversed axes list their ticks right to left)\n const order = xTicks.values\n .map((v, i) => ({ px: scales.xToPx(v), text: xTicks.labels[i] }))\n .sort((a, b) => a.px - b.px);\n for (const { px, text } of order) {\n if (px < plot.x - 0.5 || px > plot.x + plot.width + 0.5) continue;\n const w = ctx.measureText(text).width;\n const left = Math.max(0, Math.min(input.width - w, px - w / 2));\n if (left < lastRight + 6) continue;\n lastRight = left + w;\n ctx.fillText(text, left + w / 2, plot.y + plot.height + 7);\n }\n if (x.title) {\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.fillText(\n x.title,\n plot.x + plot.width / 2,\n plot.y + plot.height + line + 10,\n );\n }\n }\n\n // y axis\n if (y.visible) {\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n yTicks.values.forEach((v, i) => {\n const py = scales.yToPx(v);\n if (py < plot.y - 0.5 || py > plot.y + plot.height + 0.5) return;\n ctx.fillText(yTicks.labels[i], plot.x - 8, py);\n });\n if (y.title) {\n ctx.save();\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.translate(line / 2 + 4, plot.y + plot.height / 2);\n ctx.rotate(-Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.fillText(y.title, 0, 0);\n ctx.restore();\n }\n }\n};\n\nconst overlaps = (a: Rect, b: Rect) =>\n a.x < b.x + b.width &&\n b.x < a.x + a.width &&\n a.y < b.y + b.height &&\n b.y < a.y + a.height;\n\nconst inside = (r: Rect, plot: Rect) =>\n r.x >= plot.x &&\n r.y >= plot.y &&\n r.x + r.width <= plot.x + plot.width &&\n r.y + r.height <= plot.y + plot.height;\n\n/** Text with a halo in the background color (readable over data) */\nconst haloText = (\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n color: string,\n halo: string,\n) => {\n ctx.lineWidth = 3;\n ctx.lineJoin = \"round\";\n ctx.strokeStyle = halo;\n ctx.strokeText(text, x, y);\n ctx.fillStyle = color;\n ctx.fillText(text, x, y);\n};\n\n/** Greedy placement: right, left, above, below the dot; skipped when no slot is free */\nexport const placeLabels = (\n labels: readonly PointLabel[],\n plot: Rect,\n measure: (text: string) => number,\n height: number,\n occupied: Rect[] = [],\n): { label: PointLabel; box: Rect }[] => {\n const placed: { label: PointLabel; box: Rect }[] = [];\n for (const label of labels) {\n const w = measure(label.text);\n const gap = label.r + 4;\n const above = {\n x: label.x - w / 2,\n y: label.y - gap - height,\n width: w,\n height,\n };\n const below = { x: label.x - w / 2, y: label.y + gap, width: w, height };\n const candidates: Rect[] =\n label.placement === \"above\"\n ? [above]\n : label.placement === \"below\"\n ? [below]\n : [\n { x: label.x + gap, y: label.y - height / 2, width: w, height },\n {\n x: label.x - gap - w,\n y: label.y - height / 2,\n width: w,\n height,\n },\n above,\n below,\n ];\n const box = candidates.find(\n (c) => inside(c, plot) && !occupied.some((o) => overlaps(o, c)),\n );\n if (!box) continue;\n occupied.push(box);\n placed.push({ label, box });\n }\n return placed;\n};\n\nexport interface ForegroundInput {\n width: number;\n height: number;\n scales: Scales;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n pointLabels: readonly PointLabel[];\n /**\n * Clears the canvas first (off when the layers share one canvas)\n * @default true\n */\n clear?: boolean;\n}\n\nexport const drawForeground = (\n ctx: CanvasRenderingContext2D,\n input: ForegroundInput,\n) => {\n const { scales, theme } = input;\n const { plot } = scales;\n if (input.clear !== false) ctx.clearRect(0, 0, input.width, input.height);\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n\n const halo = toCss(theme.background, 0.9);\n const occupied: Rect[] = [];\n const labelHeight = theme.fontSize + 4;\n\n for (const a of input.annotations) {\n if (a.type !== \"line\") continue;\n const color = toCss(a.color);\n ctx.strokeStyle = color;\n ctx.lineWidth = a.width;\n ctx.setLineDash(a.dash);\n ctx.beginPath();\n if (a.axis === \"y\") {\n const py = crisp(scales.yToPx(a.value));\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"bottom\";\n haloText(ctx, a.label, plot.x + plot.width - 6, py - 3, color, halo);\n }\n } else {\n const px = crisp(scales.xToPx(a.value));\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n haloText(ctx, a.label, px + 5, plot.y + 5, color, halo);\n }\n }\n }\n ctx.setLineDash([]);\n\n // labels of areas\n ctx.font = font(theme, theme.fontSize + 1, 600);\n for (const a of input.annotations) {\n if (a.type !== \"rect\" || !a.label) continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n const pad = 10;\n const w = ctx.measureText(a.label).width;\n const pos = a.labelPosition;\n const tx = pos.endsWith(\"left\")\n ? r.x + pad\n : pos.endsWith(\"right\")\n ? r.x + r.width - pad - w\n : r.x + (r.width - w) / 2;\n const ty = pos.startsWith(\"top\")\n ? r.y + pad\n : pos.startsWith(\"bottom\")\n ? r.y + r.height - pad - labelHeight\n : r.y + (r.height - labelHeight) / 2;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n ctx.fillStyle = toCss(a.labelColor);\n ctx.fillText(a.label, tx, ty);\n occupied.push({ x: tx, y: ty, width: w, height: labelHeight });\n }\n\n // free texts\n for (const a of input.annotations) {\n if (a.type !== \"text\" || !a.text) continue;\n ctx.font = font(theme, theme.fontSize, a.weight);\n const box = textBox(a, scales, ctx.measureText(a.text).width, labelHeight);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n haloText(ctx, a.text, box.x, box.y + box.height / 2, toCss(a.color), halo);\n occupied.push(box);\n }\n\n // point labels\n if (input.pointLabels.length) {\n ctx.font = font(theme);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n const textColor = toCss(theme.text, 0.85);\n const placed = placeLabels(\n input.pointLabels,\n plot,\n (t) => ctx.measureText(t).width,\n labelHeight - 2,\n occupied,\n );\n for (const { label, box } of placed) {\n haloText(ctx, label.text, box.x, box.y + box.height / 2, textColor, halo);\n }\n }\n ctx.restore();\n};\n"],"mappings":";AAuDA,IAAaA,KAAQ,GAAmB,IAAOC,EAAM,UAAU,IAAS,QACtE,GAAGC,EAAO,GAAGC,EAAK,KAAKF,EAAM,cAKlBG,KACX,GACA,GACA,GACA,MACS;CACT,IAAM,EAAE,YAASC,GACXC,IAAKC,EAAE,MAAM,KAAA,IAAYC,EAAK,IAAIA,EAAK,QAAQ,IAAIH,EAAE,MAAME,EAAE,CAAC,GAC9DE,IAAKF,EAAE,MAAM,KAAA,IAAYC,EAAK,IAAIA,EAAK,SAAS,IAAIH,EAAE,MAAME,EAAE,CAAC,GAEjEG,IAAIJ,IAAKK,IAAQ,GACjBC,IAAIH,IAAKI,IAAS;CAOtB,OANIN,EAAE,WAAW,QAAO,IAAIE,IAAK,IACxBF,EAAE,WAAW,WAAU,IAAIE,IAAK,IAAMI,IACtCN,EAAE,WAAW,SAAQ,IAAID,IAAK,IAC9BC,EAAE,WAAW,YAAS,IAAID,IAAK,IAAMK,IAC9C,IAAI,KAAK,IAAIH,EAAK,IAAI,GAAK,KAAK,IAAIE,GAAGF,EAAK,IAAIA,EAAK,QAAQ,IAAMG,CAAK,CAAC,GACzE,IAAI,KAAK,IAAIH,EAAK,IAAI,GAAG,KAAK,IAAII,GAAGJ,EAAK,IAAIA,EAAK,SAAS,IAAIK,CAAM,CAAC,GAChE;EAAE;EAAG;EAAG;EAAO;CAAO;AAC/B,GAqIMC,KAAY,GAAS,MACzBP,EAAE,IAAIQ,EAAE,IAAIA,EAAE,SACdA,EAAE,IAAIR,EAAE,IAAIA,EAAE,SACdA,EAAE,IAAIQ,EAAE,IAAIA,EAAE,UACdA,EAAE,IAAIR,EAAE,IAAIA,EAAE,QAEVS,KAAU,GAAS,MACvBC,EAAE,KAAKT,EAAK,KACZS,EAAE,KAAKT,EAAK,KACZS,EAAE,IAAIA,EAAE,SAAST,EAAK,IAAIA,EAAK,SAC/BS,EAAE,IAAIA,EAAE,UAAUT,EAAK,IAAIA,EAAK,QAoBrBU,KACX,GACA,GACA,GACA,GACA,IAAmB,CAAC,MACmB;CACvC,IAAMC,IAA6C,CAAC;CACpD,KAAK,IAAMC,KAASC,GAAQ;EAC1B,IAAMC,IAAIC,EAAQH,EAAM,IAAI,GACtBI,IAAMJ,EAAM,IAAI,GAChBK,IAAQ;GACZ,GAAGL,EAAM,IAAIE,IAAI;GACjB,GAAGF,EAAM,IAAII,IAAMX;GACnB,OAAOS;GACP;EACF,GACMI,IAAQ;GAAE,GAAGN,EAAM,IAAIE,IAAI;GAAG,GAAGF,EAAM,IAAII;GAAK,OAAOF;GAAG;EAAO,GAiBjEK,KAfJP,EAAM,cAAc,UAChB,CAACK,CAAK,IACNL,EAAM,cAAc,UAClB,CAACM,CAAK,IACN;GACE;IAAE,GAAGN,EAAM,IAAII;IAAK,GAAGJ,EAAM,IAAIP,IAAS;IAAG,OAAOS;IAAG;GAAO;GAC9D;IACE,GAAGF,EAAM,IAAII,IAAMF;IACnB,GAAGF,EAAM,IAAIP,IAAS;IACtB,OAAOS;IACP;GACF;GACAG;GACAC;EACF,EAAA,CACe,MACpB,MAAMV,EAAOY,GAAGpB,CAAI,KAAK,CAACqB,EAAS,MAAM,MAAMf,EAASgB,GAAGF,CAAC,CAAC,CAChE;EACA,AAAKD,MACLE,EAAS,KAAKF,CAAG,GACjBR,EAAO,KAAK;GAAE;GAAO;EAAI,CAAC;CAC5B;CACA,OAAOA;AACT"}
@@ -1,3 +1,3 @@
1
- var e=(e,t,n)=>e.map(e=>({...e,type:e.type??t,...n!==void 0&&(e.type??t)===`bar`?{stack:e.stack??n}:{}})),t=(t,n=!1)=>e(t,n?`area`:`line`),n=(t,n=!1)=>e(t,`bar`,n?`stack`:void 0),r=t=>e(t,`scatter`),i={topLeft:`var(--danger-color, #ef4444)`,topRight:`var(--primary-color, #4f46e5)`,bottomLeft:`var(--warning-color, #f59e0b)`,bottomRight:`var(--text-secondary-color, #64748b)`},a=`var(--border-strong-color, var(--border-color, #cbd5e1))`,o=e=>{let[t,n]=e.xDomain??[0,10],[r,i]=e.yDomain??[0,10];return{x0:t,x1:n,y0:r,y1:i,xs:e.xSplit??(t+n)/2,ys:e.ySplit??(r+i)/2}},s=(e,t,n)=>{let{xs:r,ys:i}=o(e),a=e.reverseX?t<r:t>=r;return n>=i?a?`topRight`:`topLeft`:a?`bottomRight`:`bottomLeft`},c=(e,t={})=>{let{x0:n,x1:r,y0:c,y1:l,xs:u,ys:d}=o(e),f=!!e.reverseX,p=t=>e.quadrants?.[t]?.color??i[t],m=[{type:`scatter`,name:e.name??``,pointSize:e.pointSize??12,showLabels:e.showLabels??!0,opacity:.9,data:e.points.map(t=>({x:t.x,y:t.y,label:t.label,size:t.size,color:t.color??p(s(e,t.x,t.y))}))}],h=f?[u,r]:[n,u],g=f?[n,u]:[u,r],_=(t,[n,r],[i,a],o)=>({type:`rect`,x0:n,x1:r,y0:i,y1:a,color:p(t),opacity:.07,label:e.quadrants?.[t]?.label,labelPosition:o}),v=e.axisLabels??{},y=f?r:n,b=f?n:r,x=[...v.top?[{type:`text`,x:u,y:l,text:v.top,anchor:`top`}]:[],...v.bottom?[{type:`text`,x:u,y:c,text:v.bottom,anchor:`bottom`}]:[],...v.left?[{type:`text`,x:y,y:d,text:v.left,anchor:`left`}]:[],...v.right?[{type:`text`,x:b,y:d,text:v.right,anchor:`right`}]:[]],S=[_(`topLeft`,h,[d,l],`top-left`),_(`topRight`,g,[d,l],`top-right`),_(`bottomLeft`,h,[c,d],`bottom-left`),_(`bottomRight`,g,[c,d],`bottom-right`),{type:`line`,axis:`x`,value:u,dash:[],color:a},{type:`line`,axis:`y`,value:d,dash:[],color:a},...x,...t.annotations??[]],C=e.showTicks??!0,w=t.interaction!==!1&&{zoom:!1,...typeof t.interaction==`object`?t.interaction:{},...e.draggable?{dragPoints:!0}:{}};return{...t,series:m,annotations:S,tooltip:t.tooltip??(C?void 0:{render:t=>{let n=t.items[0];if(!n)return null;let r=e.quadrants?.[s(e,n.x,n.y)]?.label;return[n.label??e.name??``,r??``].filter(Boolean).join(`
1
+ var e=(e,t,n,r)=>e.map(e=>{let i=e.type??t;return{...e,type:i,...n!==void 0&&i===t?{stack:e.stack??n}:{},...r!==void 0&&(i===`line`||i===`area`)?{curve:e.curve??r}:{}}}),t=(t,n=!1,r={})=>e(t,n?`area`:`line`,r.stacked?`stack`:void 0,r.curve),n=(t,n=!1,r=!1)=>e(t,`bar`,n?`stack`:void 0).map(e=>r&&e.type===`bar`?{...e,showLabels:e.showLabels??!0}:e),r=t=>e(t,`scatter`),i={topLeft:`var(--danger-color, #ef4444)`,topRight:`var(--primary-color, #4f46e5)`,bottomLeft:`var(--warning-color, #f59e0b)`,bottomRight:`var(--text-secondary-color, #64748b)`},a=`var(--border-strong-color, var(--border-color, #cbd5e1))`,o=e=>{let[t,n]=e.xDomain??[0,10],[r,i]=e.yDomain??[0,10];return{x0:t,x1:n,y0:r,y1:i,xs:e.xSplit??(t+n)/2,ys:e.ySplit??(r+i)/2}},s=(e,t,n)=>{let{xs:r,ys:i}=o(e),a=e.reverseX?t<r:t>=r;return n>=i?a?`topRight`:`topLeft`:a?`bottomRight`:`bottomLeft`},c=(e,t={})=>{let{x0:n,x1:r,y0:c,y1:l,xs:u,ys:d}=o(e),f=!!e.reverseX,p=t=>e.quadrants?.[t]?.color??i[t],m=[{type:`scatter`,name:e.name??``,pointSize:e.pointSize??12,showLabels:e.showLabels??!0,opacity:.9,data:e.points.map(t=>({x:t.x,y:t.y,label:t.label,size:t.size,color:t.color??p(s(e,t.x,t.y))}))}],h=f?[u,r]:[n,u],g=f?[n,u]:[u,r],_=(t,[n,r],[i,a],o)=>({type:`rect`,x0:n,x1:r,y0:i,y1:a,color:p(t),opacity:.07,label:e.quadrants?.[t]?.label,labelPosition:o}),v=e.axisLabels??{},y=f?r:n,b=f?n:r,x=[...v.top?[{type:`text`,x:u,y:l,text:v.top,anchor:`top`}]:[],...v.bottom?[{type:`text`,x:u,y:c,text:v.bottom,anchor:`bottom`}]:[],...v.left?[{type:`text`,x:y,y:d,text:v.left,anchor:`left`}]:[],...v.right?[{type:`text`,x:b,y:d,text:v.right,anchor:`right`}]:[]],S=[_(`topLeft`,h,[d,l],`top-left`),_(`topRight`,g,[d,l],`top-right`),_(`bottomLeft`,h,[c,d],`bottom-left`),_(`bottomRight`,g,[c,d],`bottom-right`),{type:`line`,axis:`x`,value:u,dash:[],color:a},{type:`line`,axis:`y`,value:d,dash:[],color:a},...x,...t.annotations??[]],C=e.showTicks??!0,w=t.interaction!==!1&&{zoom:!1,...typeof t.interaction==`object`?t.interaction:{},...e.draggable?{dragPoints:!0}:{}};return{...t,series:m,annotations:S,tooltip:t.tooltip??(C?void 0:{render:t=>{let n=t.items[0];if(!n)return null;let r=e.quadrants?.[s(e,n.x,n.y)]?.label;return[n.label??e.name??``,r??``].filter(Boolean).join(`
2
2
  `)}}),xAxis:{min:n,max:r,title:e.xLabel,reverse:f,nice:!1,grid:!1,tickCount:4,visible:C||!!e.xLabel,...C?{}:{format:()=>``}},yAxis:{min:c,max:l,title:e.yLabel,nice:!1,grid:!1,tickCount:4,visible:C||!!e.yLabel,...C?{}:{format:()=>``}},legend:t.legend??!1,padding:t.padding??(C?void 0:{top:4,right:4,bottom:4,left:4}),interaction:w}};exports.DEFAULT_QUADRANT_COLORS=i,exports.barSeries=n,exports.lineSeries=t,exports.quadrantChartOptions=c,exports.quadrantOf=s,exports.scatterSeries=r,exports.withSeriesType=e;
3
3
  //# sourceMappingURL=presets.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"presets.cjs","names":["withSeriesType","series","s","type","stack","lineSeries","area","barSeries","stacked","scatterSeries","DEFAULT_QUADRANT_COLORS","DIVIDER","splits","x0","x1","config","y0","y1","quadrantOf","right","x","xs","y","ys","quadrantChartOptions","reverseX","color","corner","p","left","rect","xa","xb","ya","yb","position","ends","visualLeft","visualRight","texts","annotations","base","showTicks","interaction","item","event","region"],"sources":["../../../../../../charts/src/engine/presets.ts"],"sourcesContent":["// Option presets of the chart components, shared by every platform (React,\n// mini-programs, React Native): they turn component props into engine\n// options.\n\nimport type {\n ChartAnnotation,\n ChartInteractionOptions,\n ChartOptions,\n ChartSeries,\n ChartSeriesType,\n} from \"./types\";\n\n/** Gives the series without a `type` the type of the component */\nexport const withSeriesType = (\n series: readonly ChartSeries[],\n type: ChartSeriesType,\n stack?: string,\n): ChartSeries[] =>\n series.map((s) => ({\n ...s,\n type: s.type ?? type,\n ...(stack !== undefined && (s.type ?? type) === \"bar\"\n ? { stack: s.stack ?? stack }\n : {}),\n }));\n\n/** Series of a LineChart (`area` fills them) */\nexport const lineSeries = (series: readonly ChartSeries[], area = false) =>\n withSeriesType(series, area ? \"area\" : \"line\");\n\n/** Series of a BarChart (`stacked` stacks them) */\nexport const barSeries = (series: readonly ChartSeries[], stacked = false) =>\n withSeriesType(series, \"bar\", stacked ? \"stack\" : undefined);\n\n/** Series of a ScatterChart */\nexport const scatterSeries = (series: readonly ChartSeries[]) =>\n withSeriesType(series, \"scatter\");\n\n/** A point of a QuadrantChart */\nexport interface QuadrantPoint {\n /** Position on the horizontal axis */\n x: number;\n /** Position on the vertical axis */\n y: number;\n /** Text drawn next to the dot and shown in the tooltip */\n label?: string;\n /** Dot color (any CSS color); the color of its quadrant by default */\n color?: string;\n /** Dot diameter in pixels */\n size?: number;\n}\n\n/** Title and color of a quadrant */\nexport interface QuadrantRegion {\n /** Title drawn in the outer corner of the quadrant */\n label?: string;\n /** Background tint and default dot color (any CSS color) */\n color?: string;\n}\n\n/** The four quadrants of a QuadrantChart */\nexport interface QuadrantRegions {\n topLeft?: QuadrantRegion;\n topRight?: QuadrantRegion;\n bottomLeft?: QuadrantRegion;\n bottomRight?: QuadrantRegion;\n}\n\n/** A quadrant, as seen on screen */\nexport type QuadrantCorner = keyof QuadrantRegions;\n\n/** Texts at the four ends of the dividers, inside the plot */\nexport interface QuadrantAxisLabels {\n top?: string;\n bottom?: string;\n left?: string;\n right?: string;\n}\n\n/** Settings of a quadrant matrix (the props of QuadrantChart) */\nexport interface QuadrantConfig {\n /** Points to place */\n points: readonly QuadrantPoint[];\n /**\n * Range of the horizontal axis\n * @default [0, 10]\n */\n xDomain?: [number, number];\n /**\n * Range of the vertical axis\n * @default [0, 10]\n */\n yDomain?: [number, number];\n /** X value of the vertical divider (the middle of `xDomain` by default) */\n xSplit?: number;\n /** Y value of the horizontal divider (the middle of `yDomain` by default) */\n ySplit?: number;\n /** Titles and colors of the quadrants */\n quadrants?: QuadrantRegions;\n /** Title of the horizontal axis */\n xLabel?: string;\n /** Title of the vertical axis */\n yLabel?: string;\n /** Texts at the ends of the dividers, drawn inside the plot (e.g. \"Important\" at the top) */\n axisLabels?: QuadrantAxisLabels;\n /**\n * Shows the numeric ticks of the axes; `false` keeps only the matrix\n * @default true\n */\n showTicks?: boolean;\n /** Reverses the horizontal axis (e.g. \"urgent\" on the left) */\n reverseX?: boolean;\n /**\n * Draws the labels next to the dots (overlapping labels are skipped)\n * @default true\n */\n showLabels?: boolean;\n /**\n * Dot diameter in pixels\n * @default 12\n */\n pointSize?: number;\n /** Name of the points in the tooltip */\n name?: string;\n /** Lets the user drag the dots (`drag` / `drop` events) */\n draggable?: boolean;\n}\n\nexport const DEFAULT_QUADRANT_COLORS: Required<Record<QuadrantCorner, string>> =\n {\n topLeft: \"var(--danger-color, #ef4444)\",\n topRight: \"var(--primary-color, #4f46e5)\",\n bottomLeft: \"var(--warning-color, #f59e0b)\",\n bottomRight: \"var(--text-secondary-color, #64748b)\",\n };\n\nconst DIVIDER = \"var(--border-strong-color, var(--border-color, #cbd5e1))\";\n\nconst splits = (config: QuadrantConfig) => {\n const [x0, x1] = config.xDomain ?? [0, 10];\n const [y0, y1] = config.yDomain ?? [0, 10];\n return {\n x0,\n x1,\n y0,\n y1,\n xs: config.xSplit ?? (x0 + x1) / 2,\n ys: config.ySplit ?? (y0 + y1) / 2,\n };\n};\n\n/** Quadrant of a data position, as seen on screen */\nexport const quadrantOf = (\n config: Pick<\n QuadrantConfig,\n \"xDomain\" | \"yDomain\" | \"xSplit\" | \"ySplit\" | \"reverseX\"\n >,\n x: number,\n y: number,\n): QuadrantCorner => {\n const { xs, ys } = splits(config as QuadrantConfig);\n const right = config.reverseX ? x < xs : x >= xs;\n const top = y >= ys;\n return top\n ? right\n ? \"topRight\"\n : \"topLeft\"\n : right\n ? \"bottomRight\"\n : \"bottomLeft\";\n};\n\n/** Center of a quadrant in data coordinates */\nexport const quadrantCenter = (\n config: Pick<\n QuadrantConfig,\n \"xDomain\" | \"yDomain\" | \"xSplit\" | \"ySplit\" | \"reverseX\"\n >,\n corner: QuadrantCorner,\n): { x: number; y: number } => {\n const { x0, x1, y0, y1, xs, ys } = splits(config as QuadrantConfig);\n const visualRight = corner.endsWith(\"Right\");\n const dataHigh = config.reverseX ? !visualRight : visualRight;\n return {\n x: dataHigh ? (xs + x1) / 2 : (x0 + xs) / 2,\n y: corner.startsWith(\"top\") ? (ys + y1) / 2 : (y0 + ys) / 2,\n };\n};\n\n/** Engine options of a quadrant matrix */\nexport const quadrantChartOptions = (\n config: QuadrantConfig,\n base: Omit<ChartOptions, \"series\"> = {},\n): ChartOptions => {\n const { x0, x1, y0, y1, xs, ys } = splits(config);\n const reverseX = !!config.reverseX;\n const color = (corner: QuadrantCorner) =>\n config.quadrants?.[corner]?.color ?? DEFAULT_QUADRANT_COLORS[corner];\n\n const series: ChartSeries[] = [\n {\n type: \"scatter\",\n name: config.name ?? \"\",\n pointSize: config.pointSize ?? 12,\n showLabels: config.showLabels ?? true,\n opacity: 0.9,\n data: config.points.map((p) => ({\n x: p.x,\n y: p.y,\n label: p.label,\n size: p.size,\n color: p.color ?? color(quadrantOf(config, p.x, p.y)),\n })),\n },\n ];\n\n // visual left / right -> data ranges\n const left: [number, number] = reverseX ? [xs, x1] : [x0, xs];\n const right: [number, number] = reverseX ? [x0, xs] : [xs, x1];\n const rect = (\n corner: QuadrantCorner,\n [xa, xb]: [number, number],\n [ya, yb]: [number, number],\n position: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\",\n ): ChartAnnotation => ({\n type: \"rect\",\n x0: xa,\n x1: xb,\n y0: ya,\n y1: yb,\n color: color(corner),\n opacity: 0.07,\n label: config.quadrants?.[corner]?.label,\n labelPosition: position,\n });\n const ends = config.axisLabels ?? {};\n const visualLeft = reverseX ? x1 : x0;\n const visualRight = reverseX ? x0 : x1;\n const texts: ChartAnnotation[] = [\n ...(ends.top\n ? [{ type: \"text\", x: xs, y: y1, text: ends.top, anchor: \"top\" } as const]\n : []),\n ...(ends.bottom\n ? [\n {\n type: \"text\",\n x: xs,\n y: y0,\n text: ends.bottom,\n anchor: \"bottom\",\n } as const,\n ]\n : []),\n ...(ends.left\n ? [\n {\n type: \"text\",\n x: visualLeft,\n y: ys,\n text: ends.left,\n anchor: \"left\",\n } as const,\n ]\n : []),\n ...(ends.right\n ? [\n {\n type: \"text\",\n x: visualRight,\n y: ys,\n text: ends.right,\n anchor: \"right\",\n } as const,\n ]\n : []),\n ];\n\n const annotations: ChartAnnotation[] = [\n rect(\"topLeft\", left, [ys, y1], \"top-left\"),\n rect(\"topRight\", right, [ys, y1], \"top-right\"),\n rect(\"bottomLeft\", left, [y0, ys], \"bottom-left\"),\n rect(\"bottomRight\", right, [y0, ys], \"bottom-right\"),\n { type: \"line\", axis: \"x\", value: xs, dash: [], color: DIVIDER },\n { type: \"line\", axis: \"y\", value: ys, dash: [], color: DIVIDER },\n ...texts,\n ...(base.annotations ?? []),\n ];\n\n const showTicks = config.showTicks ?? true;\n const interaction: boolean | ChartInteractionOptions =\n base.interaction === false\n ? false\n : {\n zoom: false,\n ...(typeof base.interaction === \"object\" ? base.interaction : {}),\n ...(config.draggable ? { dragPoints: true } : {}),\n };\n\n return {\n ...base,\n series,\n annotations,\n tooltip:\n base.tooltip ??\n (showTicks\n ? undefined\n : {\n render: (event) => {\n const item = event.items[0];\n if (!item) return null;\n const region =\n config.quadrants?.[quadrantOf(config, item.x, item.y)]?.label;\n return [item.label ?? config.name ?? \"\", region ?? \"\"]\n .filter(Boolean)\n .join(\"\\n\");\n },\n }),\n xAxis: {\n min: x0,\n max: x1,\n title: config.xLabel,\n reverse: reverseX,\n nice: false,\n grid: false,\n tickCount: 4,\n visible: showTicks || !!config.xLabel,\n ...(showTicks ? {} : { format: () => \"\" }),\n },\n yAxis: {\n min: y0,\n max: y1,\n title: config.yLabel,\n nice: false,\n grid: false,\n tickCount: 4,\n visible: showTicks || !!config.yLabel,\n ...(showTicks ? {} : { format: () => \"\" }),\n },\n legend: base.legend ?? false,\n padding:\n base.padding ??\n (showTicks ? undefined : { top: 4, right: 4, bottom: 4, left: 4 }),\n interaction,\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"presets.cjs","names":["withSeriesType","series","t","s","type","stack","curve","lineSeries","area","extra","barSeries","stacked","labels","scatterSeries","DEFAULT_QUADRANT_COLORS","DIVIDER","splits","x0","x1","config","y0","y1","quadrantOf","right","x","xs","y","ys","quadrantChartOptions","reverseX","color","corner","p","left","rect","xa","xb","ya","yb","position","ends","visualLeft","visualRight","texts","annotations","base","showTicks","interaction","item","event","region"],"sources":["../../../../../../charts/src/engine/presets.ts"],"sourcesContent":["// Option presets of the chart components, shared by every platform (React,\n// mini-programs, React Native): they turn component props into engine\n// options.\n\nimport type {\n ChartAnnotation,\n ChartCurve,\n ChartInteractionOptions,\n ChartOptions,\n ChartSeries,\n ChartSeriesType,\n} from \"./types\";\n\n/** Gives the series without a `type` the type of the component */\nexport const withSeriesType = (\n series: readonly ChartSeries[],\n type: ChartSeriesType,\n stack?: string,\n curve?: ChartCurve,\n): ChartSeries[] =>\n series.map((s) => {\n const t = s.type ?? type;\n return {\n ...s,\n type: t,\n ...(stack !== undefined && t === type ? { stack: s.stack ?? stack } : {}),\n ...(curve !== undefined && (t === \"line\" || t === \"area\")\n ? { curve: s.curve ?? curve }\n : {}),\n };\n });\n\n/** Options of the line-like components */\nexport interface LineSeriesOptions {\n /** Stacks the series on top of each other */\n stacked?: boolean;\n /** Shape of the lines */\n curve?: ChartCurve;\n}\n\n/** Series of a LineChart (`area` fills them) */\nexport const lineSeries = (\n series: readonly ChartSeries[],\n area = false,\n extra: LineSeriesOptions = {},\n) =>\n withSeriesType(\n series,\n area ? \"area\" : \"line\",\n extra.stacked ? \"stack\" : undefined,\n extra.curve,\n );\n\n/** Series of an AreaChart */\nexport const areaSeries = (\n series: readonly ChartSeries[],\n extra: LineSeriesOptions = {},\n) => lineSeries(series, true, extra);\n\n/** Series of a BarChart (`stacked` stacks them, `labels` shows the values) */\nexport const barSeries = (\n series: readonly ChartSeries[],\n stacked = false,\n labels = false,\n) =>\n withSeriesType(series, \"bar\", stacked ? \"stack\" : undefined).map((s) =>\n labels && s.type === \"bar\" ? { ...s, showLabels: s.showLabels ?? true } : s,\n );\n\n/** Series of a ScatterChart */\nexport const scatterSeries = (series: readonly ChartSeries[]) =>\n withSeriesType(series, \"scatter\");\n\n/** Series of a CandlestickChart */\nexport const candlestickSeries = (series: readonly ChartSeries[]) =>\n withSeriesType(series, \"candlestick\");\n\n/** A cell of a HeatmapChart */\nexport interface HeatmapCell {\n /** Column: a category name (or a number on a numeric axis) */\n x: string | number;\n /** Row: a category name (or a number on a numeric axis) */\n y: string | number;\n /** Value mapped to the color scale; `null` leaves the cell empty */\n value: number | null;\n}\n\n/** Settings of a heatmap (the props of HeatmapChart) */\nexport interface HeatmapConfig {\n /** Cells */\n data: readonly HeatmapCell[];\n /** Column names in order (collected from the data when omitted) */\n xCategories?: readonly string[];\n /** Row names from bottom to top (collected from the data when omitted) */\n yCategories?: readonly string[];\n /** Colors from the lowest to the highest value; a ramp of the first palette color by default */\n colorScale?: readonly string[];\n /** Values at the ends of the color scale; the data range by default */\n valueRange?: readonly [number, number];\n /** Name of the value in the tooltip */\n name?: string;\n /** Corner radius of the cells, in pixels */\n radius?: number;\n /** Formats the values in the tooltip */\n format?: (value: number) => string;\n}\n\n/** Engine options of a heatmap */\nexport const heatmapChartOptions = (\n config: HeatmapConfig,\n base: Partial<ChartOptions> = {},\n): ChartOptions => {\n const numericX = config.data.some((c) => typeof c.x === \"number\");\n const numericY = config.data.some((c) => typeof c.y === \"number\");\n return {\n ...base,\n series: [\n {\n id: \"heatmap\",\n name: config.name ?? \"Value\",\n type: \"heatmap\",\n data: config.data.map((c) => ({ x: c.x, y: c.y, value: c.value })),\n colorScale: config.colorScale,\n valueRange: config.valueRange,\n radius: config.radius,\n format: config.format,\n },\n ],\n xAxis: {\n ...(numericX\n ? {}\n : { type: \"category\" as const, categories: config.xCategories }),\n grid: false,\n ...base.xAxis,\n },\n yAxis: {\n ...(numericY\n ? {}\n : { type: \"category\" as const, categories: config.yCategories }),\n grid: false,\n ...base.yAxis,\n },\n legend: base.legend ?? false,\n interaction: base.interaction ?? { zoom: false },\n tooltip: base.tooltip ?? { mode: \"nearest\" },\n };\n};\n\n/** Settings of a sparkline (the props of Sparkline) */\nexport interface SparklineConfig {\n /** Values (or `[x, y]` pairs, typed arrays, ...) */\n data: ChartSeries[\"data\"];\n /**\n * How the values are drawn\n * @default \"line\"\n */\n type?: \"line\" | \"area\" | \"bar\";\n /** Color (any CSS color); the first palette color by default */\n color?: string;\n /**\n * Shape of the line\n * @default \"smooth\"\n */\n curve?: ChartCurve;\n /** Name shown in the tooltip */\n name?: string;\n /** Draws a reference line at this value (e.g. a target or the average) */\n reference?: number;\n /** Formats the value in the tooltip */\n format?: (value: number) => string;\n}\n\n/** Engine options of a sparkline: no axes, no legend, a tooltip only */\nexport const sparklineOptions = (\n config: SparklineConfig,\n base: Partial<ChartOptions> = {},\n): ChartOptions => {\n const type = config.type ?? \"line\";\n return {\n ...base,\n series: [\n {\n id: \"sparkline\",\n name: config.name ?? \"Value\",\n type,\n data: config.data,\n color: config.color,\n curve: type === \"bar\" ? undefined : (config.curve ?? \"smooth\"),\n lineWidth: 1.5,\n opacity: type === \"area\" ? 0.22 : undefined,\n radius: type === \"bar\" ? 1.5 : undefined,\n format: config.format,\n },\n ],\n xAxis: { visible: false, grid: false, ...base.xAxis },\n yAxis: { visible: false, grid: false, nice: false, ...base.yAxis },\n legend: false,\n padding: base.padding ?? { top: 4, right: 4, bottom: 4, left: 4 },\n interaction: base.interaction ?? { zoom: false },\n annotations:\n config.reference !== undefined\n ? [\n ...(base.annotations ?? []),\n {\n type: \"line\",\n axis: \"y\",\n value: config.reference,\n dash: [2, 3],\n },\n ]\n : base.annotations,\n };\n};\n\n/** A point of a QuadrantChart */\nexport interface QuadrantPoint {\n /** Position on the horizontal axis */\n x: number;\n /** Position on the vertical axis */\n y: number;\n /** Text drawn next to the dot and shown in the tooltip */\n label?: string;\n /** Dot color (any CSS color); the color of its quadrant by default */\n color?: string;\n /** Dot diameter in pixels */\n size?: number;\n}\n\n/** Title and color of a quadrant */\nexport interface QuadrantRegion {\n /** Title drawn in the outer corner of the quadrant */\n label?: string;\n /** Background tint and default dot color (any CSS color) */\n color?: string;\n}\n\n/** The four quadrants of a QuadrantChart */\nexport interface QuadrantRegions {\n topLeft?: QuadrantRegion;\n topRight?: QuadrantRegion;\n bottomLeft?: QuadrantRegion;\n bottomRight?: QuadrantRegion;\n}\n\n/** A quadrant, as seen on screen */\nexport type QuadrantCorner = keyof QuadrantRegions;\n\n/** Texts at the four ends of the dividers, inside the plot */\nexport interface QuadrantAxisLabels {\n top?: string;\n bottom?: string;\n left?: string;\n right?: string;\n}\n\n/** Settings of a quadrant matrix (the props of QuadrantChart) */\nexport interface QuadrantConfig {\n /** Points to place */\n points: readonly QuadrantPoint[];\n /**\n * Range of the horizontal axis\n * @default [0, 10]\n */\n xDomain?: [number, number];\n /**\n * Range of the vertical axis\n * @default [0, 10]\n */\n yDomain?: [number, number];\n /** X value of the vertical divider (the middle of `xDomain` by default) */\n xSplit?: number;\n /** Y value of the horizontal divider (the middle of `yDomain` by default) */\n ySplit?: number;\n /** Titles and colors of the quadrants */\n quadrants?: QuadrantRegions;\n /** Title of the horizontal axis */\n xLabel?: string;\n /** Title of the vertical axis */\n yLabel?: string;\n /** Texts at the ends of the dividers, drawn inside the plot (e.g. \"Important\" at the top) */\n axisLabels?: QuadrantAxisLabels;\n /**\n * Shows the numeric ticks of the axes; `false` keeps only the matrix\n * @default true\n */\n showTicks?: boolean;\n /** Reverses the horizontal axis (e.g. \"urgent\" on the left) */\n reverseX?: boolean;\n /**\n * Draws the labels next to the dots (overlapping labels are skipped)\n * @default true\n */\n showLabels?: boolean;\n /**\n * Dot diameter in pixels\n * @default 12\n */\n pointSize?: number;\n /** Name of the points in the tooltip */\n name?: string;\n /** Lets the user drag the dots (`drag` / `drop` events) */\n draggable?: boolean;\n}\n\nexport const DEFAULT_QUADRANT_COLORS: Required<Record<QuadrantCorner, string>> =\n {\n topLeft: \"var(--danger-color, #ef4444)\",\n topRight: \"var(--primary-color, #4f46e5)\",\n bottomLeft: \"var(--warning-color, #f59e0b)\",\n bottomRight: \"var(--text-secondary-color, #64748b)\",\n };\n\nconst DIVIDER = \"var(--border-strong-color, var(--border-color, #cbd5e1))\";\n\nconst splits = (config: QuadrantConfig) => {\n const [x0, x1] = config.xDomain ?? [0, 10];\n const [y0, y1] = config.yDomain ?? [0, 10];\n return {\n x0,\n x1,\n y0,\n y1,\n xs: config.xSplit ?? (x0 + x1) / 2,\n ys: config.ySplit ?? (y0 + y1) / 2,\n };\n};\n\n/** Quadrant of a data position, as seen on screen */\nexport const quadrantOf = (\n config: Pick<\n QuadrantConfig,\n \"xDomain\" | \"yDomain\" | \"xSplit\" | \"ySplit\" | \"reverseX\"\n >,\n x: number,\n y: number,\n): QuadrantCorner => {\n const { xs, ys } = splits(config as QuadrantConfig);\n const right = config.reverseX ? x < xs : x >= xs;\n const top = y >= ys;\n return top\n ? right\n ? \"topRight\"\n : \"topLeft\"\n : right\n ? \"bottomRight\"\n : \"bottomLeft\";\n};\n\n/** Center of a quadrant in data coordinates */\nexport const quadrantCenter = (\n config: Pick<\n QuadrantConfig,\n \"xDomain\" | \"yDomain\" | \"xSplit\" | \"ySplit\" | \"reverseX\"\n >,\n corner: QuadrantCorner,\n): { x: number; y: number } => {\n const { x0, x1, y0, y1, xs, ys } = splits(config as QuadrantConfig);\n const visualRight = corner.endsWith(\"Right\");\n const dataHigh = config.reverseX ? !visualRight : visualRight;\n return {\n x: dataHigh ? (xs + x1) / 2 : (x0 + xs) / 2,\n y: corner.startsWith(\"top\") ? (ys + y1) / 2 : (y0 + ys) / 2,\n };\n};\n\n/** Engine options of a quadrant matrix */\nexport const quadrantChartOptions = (\n config: QuadrantConfig,\n base: Omit<ChartOptions, \"series\"> = {},\n): ChartOptions => {\n const { x0, x1, y0, y1, xs, ys } = splits(config);\n const reverseX = !!config.reverseX;\n const color = (corner: QuadrantCorner) =>\n config.quadrants?.[corner]?.color ?? DEFAULT_QUADRANT_COLORS[corner];\n\n const series: ChartSeries[] = [\n {\n type: \"scatter\",\n name: config.name ?? \"\",\n pointSize: config.pointSize ?? 12,\n showLabels: config.showLabels ?? true,\n opacity: 0.9,\n data: config.points.map((p) => ({\n x: p.x,\n y: p.y,\n label: p.label,\n size: p.size,\n color: p.color ?? color(quadrantOf(config, p.x, p.y)),\n })),\n },\n ];\n\n // visual left / right -> data ranges\n const left: [number, number] = reverseX ? [xs, x1] : [x0, xs];\n const right: [number, number] = reverseX ? [x0, xs] : [xs, x1];\n const rect = (\n corner: QuadrantCorner,\n [xa, xb]: [number, number],\n [ya, yb]: [number, number],\n position: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\",\n ): ChartAnnotation => ({\n type: \"rect\",\n x0: xa,\n x1: xb,\n y0: ya,\n y1: yb,\n color: color(corner),\n opacity: 0.07,\n label: config.quadrants?.[corner]?.label,\n labelPosition: position,\n });\n const ends = config.axisLabels ?? {};\n const visualLeft = reverseX ? x1 : x0;\n const visualRight = reverseX ? x0 : x1;\n const texts: ChartAnnotation[] = [\n ...(ends.top\n ? [{ type: \"text\", x: xs, y: y1, text: ends.top, anchor: \"top\" } as const]\n : []),\n ...(ends.bottom\n ? [\n {\n type: \"text\",\n x: xs,\n y: y0,\n text: ends.bottom,\n anchor: \"bottom\",\n } as const,\n ]\n : []),\n ...(ends.left\n ? [\n {\n type: \"text\",\n x: visualLeft,\n y: ys,\n text: ends.left,\n anchor: \"left\",\n } as const,\n ]\n : []),\n ...(ends.right\n ? [\n {\n type: \"text\",\n x: visualRight,\n y: ys,\n text: ends.right,\n anchor: \"right\",\n } as const,\n ]\n : []),\n ];\n\n const annotations: ChartAnnotation[] = [\n rect(\"topLeft\", left, [ys, y1], \"top-left\"),\n rect(\"topRight\", right, [ys, y1], \"top-right\"),\n rect(\"bottomLeft\", left, [y0, ys], \"bottom-left\"),\n rect(\"bottomRight\", right, [y0, ys], \"bottom-right\"),\n { type: \"line\", axis: \"x\", value: xs, dash: [], color: DIVIDER },\n { type: \"line\", axis: \"y\", value: ys, dash: [], color: DIVIDER },\n ...texts,\n ...(base.annotations ?? []),\n ];\n\n const showTicks = config.showTicks ?? true;\n const interaction: boolean | ChartInteractionOptions =\n base.interaction === false\n ? false\n : {\n zoom: false,\n ...(typeof base.interaction === \"object\" ? base.interaction : {}),\n ...(config.draggable ? { dragPoints: true } : {}),\n };\n\n return {\n ...base,\n series,\n annotations,\n tooltip:\n base.tooltip ??\n (showTicks\n ? undefined\n : {\n render: (event) => {\n const item = event.items[0];\n if (!item) return null;\n const region =\n config.quadrants?.[quadrantOf(config, item.x, item.y)]?.label;\n return [item.label ?? config.name ?? \"\", region ?? \"\"]\n .filter(Boolean)\n .join(\"\\n\");\n },\n }),\n xAxis: {\n min: x0,\n max: x1,\n title: config.xLabel,\n reverse: reverseX,\n nice: false,\n grid: false,\n tickCount: 4,\n visible: showTicks || !!config.xLabel,\n ...(showTicks ? {} : { format: () => \"\" }),\n },\n yAxis: {\n min: y0,\n max: y1,\n title: config.yLabel,\n nice: false,\n grid: false,\n tickCount: 4,\n visible: showTicks || !!config.yLabel,\n ...(showTicks ? {} : { format: () => \"\" }),\n },\n legend: base.legend ?? false,\n padding:\n base.padding ??\n (showTicks ? undefined : { top: 4, right: 4, bottom: 4, left: 4 }),\n interaction,\n };\n};\n"],"mappings":"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"}
@@ -1,9 +1,16 @@
1
1
  //#region ../charts/src/engine/presets.ts
2
- var e = (e, t, n) => e.map((e) => ({
2
+ var e = (e, t, n, r) => e.map((e) => {
3
+ let i = e.type ?? t;
4
+ return {
5
+ ...e,
6
+ type: i,
7
+ ...n !== void 0 && i === t ? { stack: e.stack ?? n } : {},
8
+ ...r !== void 0 && (i === "line" || i === "area") ? { curve: e.curve ?? r } : {}
9
+ };
10
+ }), t = (t, n = !1, r = {}) => e(t, n ? "area" : "line", r.stacked ? "stack" : void 0, r.curve), n = (t, n = !1, r = !1) => e(t, "bar", n ? "stack" : void 0).map((e) => r && e.type === "bar" ? {
3
11
  ...e,
4
- type: e.type ?? t,
5
- ...n !== void 0 && (e.type ?? t) === "bar" ? { stack: e.stack ?? n } : {}
6
- })), t = (t, n = !1) => e(t, n ? "area" : "line"), n = (t, n = !1) => e(t, "bar", n ? "stack" : void 0), r = (t) => e(t, "scatter"), i = {
12
+ showLabels: e.showLabels ?? !0
13
+ } : e), r = (t) => e(t, "scatter"), i = {
7
14
  topLeft: "var(--danger-color, #ef4444)",
8
15
  topRight: "var(--primary-color, #4f46e5)",
9
16
  bottomLeft: "var(--warning-color, #f59e0b)",
@@ -1 +1 @@
1
- {"version":3,"file":"presets.js","names":["withSeriesType","series","s","type","stack","lineSeries","area","barSeries","stacked","scatterSeries","DEFAULT_QUADRANT_COLORS","DIVIDER","splits","x0","x1","config","y0","y1","quadrantOf","right","x","xs","y","ys","quadrantChartOptions","reverseX","color","corner","p","left","rect","xa","xb","ya","yb","position","ends","visualLeft","visualRight","texts","annotations","base","showTicks","interaction","item","event","region"],"sources":["../../../../../../charts/src/engine/presets.ts"],"sourcesContent":["// Option presets of the chart components, shared by every platform (React,\n// mini-programs, React Native): they turn component props into engine\n// options.\n\nimport type {\n ChartAnnotation,\n ChartInteractionOptions,\n ChartOptions,\n ChartSeries,\n ChartSeriesType,\n} from \"./types\";\n\n/** Gives the series without a `type` the type of the component */\nexport const withSeriesType = (\n series: readonly ChartSeries[],\n type: ChartSeriesType,\n stack?: string,\n): ChartSeries[] =>\n series.map((s) => ({\n ...s,\n type: s.type ?? type,\n ...(stack !== undefined && (s.type ?? type) === \"bar\"\n ? { stack: s.stack ?? stack }\n : {}),\n }));\n\n/** Series of a LineChart (`area` fills them) */\nexport const lineSeries = (series: readonly ChartSeries[], area = false) =>\n withSeriesType(series, area ? \"area\" : \"line\");\n\n/** Series of a BarChart (`stacked` stacks them) */\nexport const barSeries = (series: readonly ChartSeries[], stacked = false) =>\n withSeriesType(series, \"bar\", stacked ? \"stack\" : undefined);\n\n/** Series of a ScatterChart */\nexport const scatterSeries = (series: readonly ChartSeries[]) =>\n withSeriesType(series, \"scatter\");\n\n/** A point of a QuadrantChart */\nexport interface QuadrantPoint {\n /** Position on the horizontal axis */\n x: number;\n /** Position on the vertical axis */\n y: number;\n /** Text drawn next to the dot and shown in the tooltip */\n label?: string;\n /** Dot color (any CSS color); the color of its quadrant by default */\n color?: string;\n /** Dot diameter in pixels */\n size?: number;\n}\n\n/** Title and color of a quadrant */\nexport interface QuadrantRegion {\n /** Title drawn in the outer corner of the quadrant */\n label?: string;\n /** Background tint and default dot color (any CSS color) */\n color?: string;\n}\n\n/** The four quadrants of a QuadrantChart */\nexport interface QuadrantRegions {\n topLeft?: QuadrantRegion;\n topRight?: QuadrantRegion;\n bottomLeft?: QuadrantRegion;\n bottomRight?: QuadrantRegion;\n}\n\n/** A quadrant, as seen on screen */\nexport type QuadrantCorner = keyof QuadrantRegions;\n\n/** Texts at the four ends of the dividers, inside the plot */\nexport interface QuadrantAxisLabels {\n top?: string;\n bottom?: string;\n left?: string;\n right?: string;\n}\n\n/** Settings of a quadrant matrix (the props of QuadrantChart) */\nexport interface QuadrantConfig {\n /** Points to place */\n points: readonly QuadrantPoint[];\n /**\n * Range of the horizontal axis\n * @default [0, 10]\n */\n xDomain?: [number, number];\n /**\n * Range of the vertical axis\n * @default [0, 10]\n */\n yDomain?: [number, number];\n /** X value of the vertical divider (the middle of `xDomain` by default) */\n xSplit?: number;\n /** Y value of the horizontal divider (the middle of `yDomain` by default) */\n ySplit?: number;\n /** Titles and colors of the quadrants */\n quadrants?: QuadrantRegions;\n /** Title of the horizontal axis */\n xLabel?: string;\n /** Title of the vertical axis */\n yLabel?: string;\n /** Texts at the ends of the dividers, drawn inside the plot (e.g. \"Important\" at the top) */\n axisLabels?: QuadrantAxisLabels;\n /**\n * Shows the numeric ticks of the axes; `false` keeps only the matrix\n * @default true\n */\n showTicks?: boolean;\n /** Reverses the horizontal axis (e.g. \"urgent\" on the left) */\n reverseX?: boolean;\n /**\n * Draws the labels next to the dots (overlapping labels are skipped)\n * @default true\n */\n showLabels?: boolean;\n /**\n * Dot diameter in pixels\n * @default 12\n */\n pointSize?: number;\n /** Name of the points in the tooltip */\n name?: string;\n /** Lets the user drag the dots (`drag` / `drop` events) */\n draggable?: boolean;\n}\n\nexport const DEFAULT_QUADRANT_COLORS: Required<Record<QuadrantCorner, string>> =\n {\n topLeft: \"var(--danger-color, #ef4444)\",\n topRight: \"var(--primary-color, #4f46e5)\",\n bottomLeft: \"var(--warning-color, #f59e0b)\",\n bottomRight: \"var(--text-secondary-color, #64748b)\",\n };\n\nconst DIVIDER = \"var(--border-strong-color, var(--border-color, #cbd5e1))\";\n\nconst splits = (config: QuadrantConfig) => {\n const [x0, x1] = config.xDomain ?? [0, 10];\n const [y0, y1] = config.yDomain ?? [0, 10];\n return {\n x0,\n x1,\n y0,\n y1,\n xs: config.xSplit ?? (x0 + x1) / 2,\n ys: config.ySplit ?? (y0 + y1) / 2,\n };\n};\n\n/** Quadrant of a data position, as seen on screen */\nexport const quadrantOf = (\n config: Pick<\n QuadrantConfig,\n \"xDomain\" | \"yDomain\" | \"xSplit\" | \"ySplit\" | \"reverseX\"\n >,\n x: number,\n y: number,\n): QuadrantCorner => {\n const { xs, ys } = splits(config as QuadrantConfig);\n const right = config.reverseX ? x < xs : x >= xs;\n const top = y >= ys;\n return top\n ? right\n ? \"topRight\"\n : \"topLeft\"\n : right\n ? \"bottomRight\"\n : \"bottomLeft\";\n};\n\n/** Center of a quadrant in data coordinates */\nexport const quadrantCenter = (\n config: Pick<\n QuadrantConfig,\n \"xDomain\" | \"yDomain\" | \"xSplit\" | \"ySplit\" | \"reverseX\"\n >,\n corner: QuadrantCorner,\n): { x: number; y: number } => {\n const { x0, x1, y0, y1, xs, ys } = splits(config as QuadrantConfig);\n const visualRight = corner.endsWith(\"Right\");\n const dataHigh = config.reverseX ? !visualRight : visualRight;\n return {\n x: dataHigh ? (xs + x1) / 2 : (x0 + xs) / 2,\n y: corner.startsWith(\"top\") ? (ys + y1) / 2 : (y0 + ys) / 2,\n };\n};\n\n/** Engine options of a quadrant matrix */\nexport const quadrantChartOptions = (\n config: QuadrantConfig,\n base: Omit<ChartOptions, \"series\"> = {},\n): ChartOptions => {\n const { x0, x1, y0, y1, xs, ys } = splits(config);\n const reverseX = !!config.reverseX;\n const color = (corner: QuadrantCorner) =>\n config.quadrants?.[corner]?.color ?? DEFAULT_QUADRANT_COLORS[corner];\n\n const series: ChartSeries[] = [\n {\n type: \"scatter\",\n name: config.name ?? \"\",\n pointSize: config.pointSize ?? 12,\n showLabels: config.showLabels ?? true,\n opacity: 0.9,\n data: config.points.map((p) => ({\n x: p.x,\n y: p.y,\n label: p.label,\n size: p.size,\n color: p.color ?? color(quadrantOf(config, p.x, p.y)),\n })),\n },\n ];\n\n // visual left / right -> data ranges\n const left: [number, number] = reverseX ? [xs, x1] : [x0, xs];\n const right: [number, number] = reverseX ? [x0, xs] : [xs, x1];\n const rect = (\n corner: QuadrantCorner,\n [xa, xb]: [number, number],\n [ya, yb]: [number, number],\n position: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\",\n ): ChartAnnotation => ({\n type: \"rect\",\n x0: xa,\n x1: xb,\n y0: ya,\n y1: yb,\n color: color(corner),\n opacity: 0.07,\n label: config.quadrants?.[corner]?.label,\n labelPosition: position,\n });\n const ends = config.axisLabels ?? {};\n const visualLeft = reverseX ? x1 : x0;\n const visualRight = reverseX ? x0 : x1;\n const texts: ChartAnnotation[] = [\n ...(ends.top\n ? [{ type: \"text\", x: xs, y: y1, text: ends.top, anchor: \"top\" } as const]\n : []),\n ...(ends.bottom\n ? [\n {\n type: \"text\",\n x: xs,\n y: y0,\n text: ends.bottom,\n anchor: \"bottom\",\n } as const,\n ]\n : []),\n ...(ends.left\n ? [\n {\n type: \"text\",\n x: visualLeft,\n y: ys,\n text: ends.left,\n anchor: \"left\",\n } as const,\n ]\n : []),\n ...(ends.right\n ? [\n {\n type: \"text\",\n x: visualRight,\n y: ys,\n text: ends.right,\n anchor: \"right\",\n } as const,\n ]\n : []),\n ];\n\n const annotations: ChartAnnotation[] = [\n rect(\"topLeft\", left, [ys, y1], \"top-left\"),\n rect(\"topRight\", right, [ys, y1], \"top-right\"),\n rect(\"bottomLeft\", left, [y0, ys], \"bottom-left\"),\n rect(\"bottomRight\", right, [y0, ys], \"bottom-right\"),\n { type: \"line\", axis: \"x\", value: xs, dash: [], color: DIVIDER },\n { type: \"line\", axis: \"y\", value: ys, dash: [], color: DIVIDER },\n ...texts,\n ...(base.annotations ?? []),\n ];\n\n const showTicks = config.showTicks ?? true;\n const interaction: boolean | ChartInteractionOptions =\n base.interaction === false\n ? false\n : {\n zoom: false,\n ...(typeof base.interaction === \"object\" ? base.interaction : {}),\n ...(config.draggable ? { dragPoints: true } : {}),\n };\n\n return {\n ...base,\n series,\n annotations,\n tooltip:\n base.tooltip ??\n (showTicks\n ? undefined\n : {\n render: (event) => {\n const item = event.items[0];\n if (!item) return null;\n const region =\n config.quadrants?.[quadrantOf(config, item.x, item.y)]?.label;\n return [item.label ?? config.name ?? \"\", region ?? \"\"]\n .filter(Boolean)\n .join(\"\\n\");\n },\n }),\n xAxis: {\n min: x0,\n max: x1,\n title: config.xLabel,\n reverse: reverseX,\n nice: false,\n grid: false,\n tickCount: 4,\n visible: showTicks || !!config.xLabel,\n ...(showTicks ? {} : { format: () => \"\" }),\n },\n yAxis: {\n min: y0,\n max: y1,\n title: config.yLabel,\n nice: false,\n grid: false,\n tickCount: 4,\n visible: showTicks || !!config.yLabel,\n ...(showTicks ? {} : { format: () => \"\" }),\n },\n legend: base.legend ?? false,\n padding:\n base.padding ??\n (showTicks ? undefined : { top: 4, right: 4, bottom: 4, left: 4 }),\n interaction,\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"presets.js","names":["withSeriesType","series","t","s","type","stack","curve","lineSeries","area","extra","barSeries","stacked","labels","scatterSeries","DEFAULT_QUADRANT_COLORS","DIVIDER","splits","x0","x1","config","y0","y1","quadrantOf","right","x","xs","y","ys","quadrantChartOptions","reverseX","color","corner","p","left","rect","xa","xb","ya","yb","position","ends","visualLeft","visualRight","texts","annotations","base","showTicks","interaction","item","event","region"],"sources":["../../../../../../charts/src/engine/presets.ts"],"sourcesContent":["// Option presets of the chart components, shared by every platform (React,\n// mini-programs, React Native): they turn component props into engine\n// options.\n\nimport type {\n ChartAnnotation,\n ChartCurve,\n ChartInteractionOptions,\n ChartOptions,\n ChartSeries,\n ChartSeriesType,\n} from \"./types\";\n\n/** Gives the series without a `type` the type of the component */\nexport const withSeriesType = (\n series: readonly ChartSeries[],\n type: ChartSeriesType,\n stack?: string,\n curve?: ChartCurve,\n): ChartSeries[] =>\n series.map((s) => {\n const t = s.type ?? type;\n return {\n ...s,\n type: t,\n ...(stack !== undefined && t === type ? { stack: s.stack ?? stack } : {}),\n ...(curve !== undefined && (t === \"line\" || t === \"area\")\n ? { curve: s.curve ?? curve }\n : {}),\n };\n });\n\n/** Options of the line-like components */\nexport interface LineSeriesOptions {\n /** Stacks the series on top of each other */\n stacked?: boolean;\n /** Shape of the lines */\n curve?: ChartCurve;\n}\n\n/** Series of a LineChart (`area` fills them) */\nexport const lineSeries = (\n series: readonly ChartSeries[],\n area = false,\n extra: LineSeriesOptions = {},\n) =>\n withSeriesType(\n series,\n area ? \"area\" : \"line\",\n extra.stacked ? \"stack\" : undefined,\n extra.curve,\n );\n\n/** Series of an AreaChart */\nexport const areaSeries = (\n series: readonly ChartSeries[],\n extra: LineSeriesOptions = {},\n) => lineSeries(series, true, extra);\n\n/** Series of a BarChart (`stacked` stacks them, `labels` shows the values) */\nexport const barSeries = (\n series: readonly ChartSeries[],\n stacked = false,\n labels = false,\n) =>\n withSeriesType(series, \"bar\", stacked ? \"stack\" : undefined).map((s) =>\n labels && s.type === \"bar\" ? { ...s, showLabels: s.showLabels ?? true } : s,\n );\n\n/** Series of a ScatterChart */\nexport const scatterSeries = (series: readonly ChartSeries[]) =>\n withSeriesType(series, \"scatter\");\n\n/** Series of a CandlestickChart */\nexport const candlestickSeries = (series: readonly ChartSeries[]) =>\n withSeriesType(series, \"candlestick\");\n\n/** A cell of a HeatmapChart */\nexport interface HeatmapCell {\n /** Column: a category name (or a number on a numeric axis) */\n x: string | number;\n /** Row: a category name (or a number on a numeric axis) */\n y: string | number;\n /** Value mapped to the color scale; `null` leaves the cell empty */\n value: number | null;\n}\n\n/** Settings of a heatmap (the props of HeatmapChart) */\nexport interface HeatmapConfig {\n /** Cells */\n data: readonly HeatmapCell[];\n /** Column names in order (collected from the data when omitted) */\n xCategories?: readonly string[];\n /** Row names from bottom to top (collected from the data when omitted) */\n yCategories?: readonly string[];\n /** Colors from the lowest to the highest value; a ramp of the first palette color by default */\n colorScale?: readonly string[];\n /** Values at the ends of the color scale; the data range by default */\n valueRange?: readonly [number, number];\n /** Name of the value in the tooltip */\n name?: string;\n /** Corner radius of the cells, in pixels */\n radius?: number;\n /** Formats the values in the tooltip */\n format?: (value: number) => string;\n}\n\n/** Engine options of a heatmap */\nexport const heatmapChartOptions = (\n config: HeatmapConfig,\n base: Partial<ChartOptions> = {},\n): ChartOptions => {\n const numericX = config.data.some((c) => typeof c.x === \"number\");\n const numericY = config.data.some((c) => typeof c.y === \"number\");\n return {\n ...base,\n series: [\n {\n id: \"heatmap\",\n name: config.name ?? \"Value\",\n type: \"heatmap\",\n data: config.data.map((c) => ({ x: c.x, y: c.y, value: c.value })),\n colorScale: config.colorScale,\n valueRange: config.valueRange,\n radius: config.radius,\n format: config.format,\n },\n ],\n xAxis: {\n ...(numericX\n ? {}\n : { type: \"category\" as const, categories: config.xCategories }),\n grid: false,\n ...base.xAxis,\n },\n yAxis: {\n ...(numericY\n ? {}\n : { type: \"category\" as const, categories: config.yCategories }),\n grid: false,\n ...base.yAxis,\n },\n legend: base.legend ?? false,\n interaction: base.interaction ?? { zoom: false },\n tooltip: base.tooltip ?? { mode: \"nearest\" },\n };\n};\n\n/** Settings of a sparkline (the props of Sparkline) */\nexport interface SparklineConfig {\n /** Values (or `[x, y]` pairs, typed arrays, ...) */\n data: ChartSeries[\"data\"];\n /**\n * How the values are drawn\n * @default \"line\"\n */\n type?: \"line\" | \"area\" | \"bar\";\n /** Color (any CSS color); the first palette color by default */\n color?: string;\n /**\n * Shape of the line\n * @default \"smooth\"\n */\n curve?: ChartCurve;\n /** Name shown in the tooltip */\n name?: string;\n /** Draws a reference line at this value (e.g. a target or the average) */\n reference?: number;\n /** Formats the value in the tooltip */\n format?: (value: number) => string;\n}\n\n/** Engine options of a sparkline: no axes, no legend, a tooltip only */\nexport const sparklineOptions = (\n config: SparklineConfig,\n base: Partial<ChartOptions> = {},\n): ChartOptions => {\n const type = config.type ?? \"line\";\n return {\n ...base,\n series: [\n {\n id: \"sparkline\",\n name: config.name ?? \"Value\",\n type,\n data: config.data,\n color: config.color,\n curve: type === \"bar\" ? undefined : (config.curve ?? \"smooth\"),\n lineWidth: 1.5,\n opacity: type === \"area\" ? 0.22 : undefined,\n radius: type === \"bar\" ? 1.5 : undefined,\n format: config.format,\n },\n ],\n xAxis: { visible: false, grid: false, ...base.xAxis },\n yAxis: { visible: false, grid: false, nice: false, ...base.yAxis },\n legend: false,\n padding: base.padding ?? { top: 4, right: 4, bottom: 4, left: 4 },\n interaction: base.interaction ?? { zoom: false },\n annotations:\n config.reference !== undefined\n ? [\n ...(base.annotations ?? []),\n {\n type: \"line\",\n axis: \"y\",\n value: config.reference,\n dash: [2, 3],\n },\n ]\n : base.annotations,\n };\n};\n\n/** A point of a QuadrantChart */\nexport interface QuadrantPoint {\n /** Position on the horizontal axis */\n x: number;\n /** Position on the vertical axis */\n y: number;\n /** Text drawn next to the dot and shown in the tooltip */\n label?: string;\n /** Dot color (any CSS color); the color of its quadrant by default */\n color?: string;\n /** Dot diameter in pixels */\n size?: number;\n}\n\n/** Title and color of a quadrant */\nexport interface QuadrantRegion {\n /** Title drawn in the outer corner of the quadrant */\n label?: string;\n /** Background tint and default dot color (any CSS color) */\n color?: string;\n}\n\n/** The four quadrants of a QuadrantChart */\nexport interface QuadrantRegions {\n topLeft?: QuadrantRegion;\n topRight?: QuadrantRegion;\n bottomLeft?: QuadrantRegion;\n bottomRight?: QuadrantRegion;\n}\n\n/** A quadrant, as seen on screen */\nexport type QuadrantCorner = keyof QuadrantRegions;\n\n/** Texts at the four ends of the dividers, inside the plot */\nexport interface QuadrantAxisLabels {\n top?: string;\n bottom?: string;\n left?: string;\n right?: string;\n}\n\n/** Settings of a quadrant matrix (the props of QuadrantChart) */\nexport interface QuadrantConfig {\n /** Points to place */\n points: readonly QuadrantPoint[];\n /**\n * Range of the horizontal axis\n * @default [0, 10]\n */\n xDomain?: [number, number];\n /**\n * Range of the vertical axis\n * @default [0, 10]\n */\n yDomain?: [number, number];\n /** X value of the vertical divider (the middle of `xDomain` by default) */\n xSplit?: number;\n /** Y value of the horizontal divider (the middle of `yDomain` by default) */\n ySplit?: number;\n /** Titles and colors of the quadrants */\n quadrants?: QuadrantRegions;\n /** Title of the horizontal axis */\n xLabel?: string;\n /** Title of the vertical axis */\n yLabel?: string;\n /** Texts at the ends of the dividers, drawn inside the plot (e.g. \"Important\" at the top) */\n axisLabels?: QuadrantAxisLabels;\n /**\n * Shows the numeric ticks of the axes; `false` keeps only the matrix\n * @default true\n */\n showTicks?: boolean;\n /** Reverses the horizontal axis (e.g. \"urgent\" on the left) */\n reverseX?: boolean;\n /**\n * Draws the labels next to the dots (overlapping labels are skipped)\n * @default true\n */\n showLabels?: boolean;\n /**\n * Dot diameter in pixels\n * @default 12\n */\n pointSize?: number;\n /** Name of the points in the tooltip */\n name?: string;\n /** Lets the user drag the dots (`drag` / `drop` events) */\n draggable?: boolean;\n}\n\nexport const DEFAULT_QUADRANT_COLORS: Required<Record<QuadrantCorner, string>> =\n {\n topLeft: \"var(--danger-color, #ef4444)\",\n topRight: \"var(--primary-color, #4f46e5)\",\n bottomLeft: \"var(--warning-color, #f59e0b)\",\n bottomRight: \"var(--text-secondary-color, #64748b)\",\n };\n\nconst DIVIDER = \"var(--border-strong-color, var(--border-color, #cbd5e1))\";\n\nconst splits = (config: QuadrantConfig) => {\n const [x0, x1] = config.xDomain ?? [0, 10];\n const [y0, y1] = config.yDomain ?? [0, 10];\n return {\n x0,\n x1,\n y0,\n y1,\n xs: config.xSplit ?? (x0 + x1) / 2,\n ys: config.ySplit ?? (y0 + y1) / 2,\n };\n};\n\n/** Quadrant of a data position, as seen on screen */\nexport const quadrantOf = (\n config: Pick<\n QuadrantConfig,\n \"xDomain\" | \"yDomain\" | \"xSplit\" | \"ySplit\" | \"reverseX\"\n >,\n x: number,\n y: number,\n): QuadrantCorner => {\n const { xs, ys } = splits(config as QuadrantConfig);\n const right = config.reverseX ? x < xs : x >= xs;\n const top = y >= ys;\n return top\n ? right\n ? \"topRight\"\n : \"topLeft\"\n : right\n ? \"bottomRight\"\n : \"bottomLeft\";\n};\n\n/** Center of a quadrant in data coordinates */\nexport const quadrantCenter = (\n config: Pick<\n QuadrantConfig,\n \"xDomain\" | \"yDomain\" | \"xSplit\" | \"ySplit\" | \"reverseX\"\n >,\n corner: QuadrantCorner,\n): { x: number; y: number } => {\n const { x0, x1, y0, y1, xs, ys } = splits(config as QuadrantConfig);\n const visualRight = corner.endsWith(\"Right\");\n const dataHigh = config.reverseX ? !visualRight : visualRight;\n return {\n x: dataHigh ? (xs + x1) / 2 : (x0 + xs) / 2,\n y: corner.startsWith(\"top\") ? (ys + y1) / 2 : (y0 + ys) / 2,\n };\n};\n\n/** Engine options of a quadrant matrix */\nexport const quadrantChartOptions = (\n config: QuadrantConfig,\n base: Omit<ChartOptions, \"series\"> = {},\n): ChartOptions => {\n const { x0, x1, y0, y1, xs, ys } = splits(config);\n const reverseX = !!config.reverseX;\n const color = (corner: QuadrantCorner) =>\n config.quadrants?.[corner]?.color ?? DEFAULT_QUADRANT_COLORS[corner];\n\n const series: ChartSeries[] = [\n {\n type: \"scatter\",\n name: config.name ?? \"\",\n pointSize: config.pointSize ?? 12,\n showLabels: config.showLabels ?? true,\n opacity: 0.9,\n data: config.points.map((p) => ({\n x: p.x,\n y: p.y,\n label: p.label,\n size: p.size,\n color: p.color ?? color(quadrantOf(config, p.x, p.y)),\n })),\n },\n ];\n\n // visual left / right -> data ranges\n const left: [number, number] = reverseX ? [xs, x1] : [x0, xs];\n const right: [number, number] = reverseX ? [x0, xs] : [xs, x1];\n const rect = (\n corner: QuadrantCorner,\n [xa, xb]: [number, number],\n [ya, yb]: [number, number],\n position: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\",\n ): ChartAnnotation => ({\n type: \"rect\",\n x0: xa,\n x1: xb,\n y0: ya,\n y1: yb,\n color: color(corner),\n opacity: 0.07,\n label: config.quadrants?.[corner]?.label,\n labelPosition: position,\n });\n const ends = config.axisLabels ?? {};\n const visualLeft = reverseX ? x1 : x0;\n const visualRight = reverseX ? x0 : x1;\n const texts: ChartAnnotation[] = [\n ...(ends.top\n ? [{ type: \"text\", x: xs, y: y1, text: ends.top, anchor: \"top\" } as const]\n : []),\n ...(ends.bottom\n ? [\n {\n type: \"text\",\n x: xs,\n y: y0,\n text: ends.bottom,\n anchor: \"bottom\",\n } as const,\n ]\n : []),\n ...(ends.left\n ? [\n {\n type: \"text\",\n x: visualLeft,\n y: ys,\n text: ends.left,\n anchor: \"left\",\n } as const,\n ]\n : []),\n ...(ends.right\n ? [\n {\n type: \"text\",\n x: visualRight,\n y: ys,\n text: ends.right,\n anchor: \"right\",\n } as const,\n ]\n : []),\n ];\n\n const annotations: ChartAnnotation[] = [\n rect(\"topLeft\", left, [ys, y1], \"top-left\"),\n rect(\"topRight\", right, [ys, y1], \"top-right\"),\n rect(\"bottomLeft\", left, [y0, ys], \"bottom-left\"),\n rect(\"bottomRight\", right, [y0, ys], \"bottom-right\"),\n { type: \"line\", axis: \"x\", value: xs, dash: [], color: DIVIDER },\n { type: \"line\", axis: \"y\", value: ys, dash: [], color: DIVIDER },\n ...texts,\n ...(base.annotations ?? []),\n ];\n\n const showTicks = config.showTicks ?? true;\n const interaction: boolean | ChartInteractionOptions =\n base.interaction === false\n ? false\n : {\n zoom: false,\n ...(typeof base.interaction === \"object\" ? base.interaction : {}),\n ...(config.draggable ? { dragPoints: true } : {}),\n };\n\n return {\n ...base,\n series,\n annotations,\n tooltip:\n base.tooltip ??\n (showTicks\n ? undefined\n : {\n render: (event) => {\n const item = event.items[0];\n if (!item) return null;\n const region =\n config.quadrants?.[quadrantOf(config, item.x, item.y)]?.label;\n return [item.label ?? config.name ?? \"\", region ?? \"\"]\n .filter(Boolean)\n .join(\"\\n\");\n },\n }),\n xAxis: {\n min: x0,\n max: x1,\n title: config.xLabel,\n reverse: reverseX,\n nice: false,\n grid: false,\n tickCount: 4,\n visible: showTicks || !!config.xLabel,\n ...(showTicks ? {} : { format: () => \"\" }),\n },\n yAxis: {\n min: y0,\n max: y1,\n title: config.yLabel,\n nice: false,\n grid: false,\n tickCount: 4,\n visible: showTicks || !!config.yLabel,\n ...(showTicks ? {} : { format: () => \"\" }),\n },\n legend: base.legend ?? false,\n padding:\n base.padding ??\n (showTicks ? undefined : { top: 4, right: 4, bottom: 4, left: 4 }),\n interaction,\n };\n};\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e=require("./color.cjs"),t=require("./data.cjs"),n=require("./layout.cjs"),r=require("./model.cjs"),i=require("./axis.cjs");var a={top:12,right:16,bottom:4,left:4},o=(e,t)=>t,s=(t,n)=>{let r=n.resolve??o;return(t??[]).map(t=>{if(t.type===`rect`){let i=t.color?r(t.color,n.primary):n.primary;return{type:`rect`,x0:t.x0,x1:t.x1,y0:t.y0,y1:t.y1,color:i,opacity:t.opacity??.08,label:t.label,labelPosition:t.labelPosition??`top-left`,labelColor:t.labelColor?r(t.labelColor,i):e.mix(i,n.text,.2)}}return t.type===`text`?{type:`text`,x:t.x,y:t.y,text:t.text,anchor:t.anchor??`center`,color:t.color?r(t.color,n.textMuted):n.textMuted,weight:t.weight??500}:{type:`line`,axis:t.axis,value:t.value,color:t.color?r(t.color,n.textMuted):n.textMuted,width:t.width??1,dash:[...t.dash??[4,4]],label:t.label}})},c=e=>{let{model:t,view:r,theme:o,width:s,height:c,measure:l}=e,u=t.y.tickCount??(c>=220?5:Math.max(2,Math.round((c-48)/52))),d=i.axisTicks(t.y,r.y,u),f=0;if(t.y.visible)for(let e of d.labels)f=Math.max(f,l(e));let p=48;if(t.x.type===`category`){p=0;let e=Math.max(1,Math.floor(t.x.categories.length/200));for(let n=0;n<t.x.categories.length;n+=e)p=Math.max(p,l(t.x.categories[n]))}let m={...a,...e.padding},h=n.computePlot({width:s,height:c,padding:m,yLabelWidth:t.y.visible?Math.ceil(f):0,xAxisVisible:t.x.visible,xTitle:!!t.x.title&&t.x.visible,yTitle:!!t.y.title&&t.y.visible,fontSize:o.fontSize});e.top&&(h.y+=e.top);let g=t.x.type===`category`?Math.max(1,Math.floor(h.width/(p+14))):t.x.tickCount??Math.max(2,Math.floor(h.width/96)),_=i.axisTicks(t.x,r.x,g);return{plot:h,scales:n.createScales(h,r,t.x.reverse,t.y.reverse),xTicks:_,yTicks:d}},l=(e,t,n)=>{let r=[];for(let i of e.series){if(i.hidden||i.type!==`scatter`||!i.showLabels)continue;let{x:e,y:a,count:o,labels:s,size:c}=i.cols;if(s)for(let l=0;l<o&&r.length<300;l++){let o=s[l];if(!o)continue;let u=e[l],d=a[l];if(u<t.x[0]||u>t.x[1]||d<t.y[0]||d>t.y[1])continue;let f=c&&c[l]>0?c[l]:i.pointSize;r.push({x:n.xToPx(u),y:n.yToPx(d),r:f/2,text:o})}}return r},u=(e,t,n)=>{let r=e.cols.x[t]+(e.type===`bar`?e.barOffset:0),i=e.type===`bar`&&e.barTop?e.barTop[t]:e.cols.y[t];return{px:n.xToPx(r),py:n.yToPx(i)}},d=(e,t,n,r,i)=>{let a=u(e,t,i),o=!1;if(e.type===`bar`&&e.barBase){let s=e.barHalfWidth/i.xPerPx,c=i.yToPx(e.barBase[t]);o=Math.abs(n-a.px)<=s&&r>=Math.min(c,a.py)-2&&r<=Math.max(c,a.py)+2}return{series:e,index:t,px:a.px,py:a.py,dx:Math.abs(i.xToPx(e.cols.x[t])-n),dist:o?0:Math.hypot(a.px-n,a.py-r),inside:o}},f=(e,t)=>e.cols.size&&e.cols.size[t]>0?e.cols.size[t]:e.pointSize,p=(e,t,n,i,a)=>{let o=Math.max(e.pointSize/2+6,10)+a,s=i.pxToX(t),c=i.pxToY(n),l=o*i.xPerPx,u=o*i.yPerPx,d=-1,p=1/0,{x:m,y:h}=e.cols;return r.gridOf(e).query(s-l,s+l,c-u,c+u,r=>{let o=Math.hypot(i.xToPx(m[r])-t,i.yToPx(h[r])-n);o<=Math.max(f(e,r)/2+4,8)+a&&o<=p&&(p=o,d=r)}),d},m=(e,n)=>{let{x:r,y:i,count:a,sorted:o}=e.cols;if(o)return t.nearestIndex(r,i,a,n);let s=-1,c=1/0;for(let e=0;e<a;e++){if(!Number.isFinite(i[e]))continue;let t=Math.abs(r[e]-n);t<c&&(c=t,s=e)}return s},h=(t,n)=>{let r=t.pointColors?.[n],i=t.cols.labels?.[n];return{seriesIndex:t.index,seriesId:t.id,seriesName:t.name,index:n,x:t.cols.x[n],y:t.cols.y[n],color:r?e.toCss(r):t.colorCss,...i===void 0?{}:{label:i}}},g=(e,t)=>{if(!e.length)return null;e.sort((e,t)=>e.series.index-t.series.index);let n=e.map(e=>h(e.series,e.index)),r=n[0].x;return{items:n,x:r,xLabel:t?.formatValue(r)??String(r)}},_=(e,t,n,r,i,a=0)=>{let{plot:o}=t,s=6+a;if(r<o.x-s||r>o.x+o.width+s||i<o.y-s||i>o.y+o.height+s)return null;let c=t.pxToX(r),l=[],u=[];for(let n of e.series)if(!(n.hidden||n.cols.count===0)){if(n.type===`scatter`){let e=p(n,r,i,t,a);e>=0&&l.push(d(n,e,r,i,t))}else{let e=m(n,c);e>=0&&u.push(d(n,e,r,i,t))}}if(e.tooltipMode===`nearest`){let e=[...l,...u].filter(e=>e.inside||e.series.type===`scatter`||e.dist<=32+a);return e.length?g([e.reduce((e,t)=>t.dist<=e.dist?t:e)],n):null}if(!u.length)return l.length?g([l.reduce((e,t)=>t.dist<=e.dist?t:e)],n):null;let f=Math.min(...u.map(e=>e.dx)),_=e.x.type===`category`?.5/t.xPerPx:0,v=u.filter(e=>e.dx<=f+Math.max(1,_)),y=v.reduce((e,t)=>t.dx<e.dx?t:e),b=g([y,...v.filter(e=>e!==y),...l],n);return b&&(b.x=h(y.series,y.index).x,b.xLabel=n?.formatValue(b.x)??String(b.x)),b},v=(e,t)=>e===t||!!e&&!!t&&e.items.length===t.items.length&&e.items.every((e,n)=>e.index===t.items[n].index&&e.seriesIndex===t.items[n].seriesIndex),y=(e,t,n)=>{let r=n?.formatValue??String;if(t.items.every(t=>e.series[t.seriesIndex].type===`scatter`)&&t.items.length===1){let n=t.items[0],i=[{color:null,name:e.x.title??`x`,value:t.xLabel},{color:null,name:e.y.title??`y`,value:r(n.y)}];return n.label!==void 0&&e.series.length>1&&i.push({color:null,name:``,value:n.seriesName}),{title:n.label??n.seriesName,titleColor:n.color,rows:i}}return{title:t.xLabel,titleColor:null,rows:t.items.map(e=>({color:e.color,name:e.label?`${e.seriesName} · ${e.label}`:e.seriesName,value:r(e.y)}))}},b=(e,t,n)=>{let r=[],{plot:i}=t;for(let a of n.items){let n=e.series[a.seriesIndex];if(n.type===`bar`&&n.barBase&&n.barTop){let e=t.xToPx(a.x+n.barOffset),i=Math.max(n.barHalfWidth/t.xPerPx,1),o=t.yToPx(n.barBase[a.index]),s=t.yToPx(n.barTop[a.index]);r.push({kind:`bar`,x:e-i,y:Math.min(o,s),width:i*2,height:Math.max(1,Math.abs(o-s))});continue}let o=t.xToPx(a.x),s=t.yToPx(a.y);if(o<i.x-1||o>i.x+i.width+1||s<i.y-1||s>i.y+i.height+1)continue;let c=n.type===`scatter`?f(n,a.index)+6:Math.max(10,n.lineWidth*2+6);r.push({kind:`dot`,x:o,y:s,size:c,color:a.color})}return r},x=(e,t,n)=>n??(e.tooltipMode===`axis`&&t.items.some(t=>e.series[t.seriesIndex].type!==`scatter`));exports.DEFAULT_PADDING=a,exports.collectPointLabels=l,exports.dotSize=f,exports.fallbackResolve=o,exports.hitTest=_,exports.hoverItemOf=h,exports.hoverMarks=b,exports.layoutChart=c,exports.pointOf=u,exports.resolveAnnotations=s,exports.sameHover=v,exports.showsCrosshair=x,exports.tooltipContent=y;
1
+ const e=require("./color.cjs"),t=require("./data.cjs"),n=require("./layout.cjs"),r=require("./model.cjs"),i=require("./format.cjs"),a=require("./axis.cjs");var o={top:12,right:16,bottom:4,left:4},s=(e,t)=>t,c=(t,n)=>{let r=n.resolve??s;return(t??[]).map(t=>{if(t.type===`rect`){let i=t.color?r(t.color,n.primary):n.primary;return{type:`rect`,x0:t.x0,x1:t.x1,y0:t.y0,y1:t.y1,color:i,opacity:t.opacity??.08,label:t.label,labelPosition:t.labelPosition??`top-left`,labelColor:t.labelColor?r(t.labelColor,i):e.mix(i,n.text,.2)}}return t.type===`text`?{type:`text`,x:t.x,y:t.y,text:t.text,anchor:t.anchor??`center`,color:t.color?r(t.color,n.textMuted):n.textMuted,weight:t.weight??500}:{type:`line`,axis:t.axis,value:t.value,color:t.color?r(t.color,n.textMuted):n.textMuted,width:t.width??1,dash:[...t.dash??[4,4]],label:t.label}})},l=e=>{let{model:t,view:r,theme:i,width:s,height:c,measure:l}=e,u=t.y.tickCount??(t.y.type===`category`?Math.max(1,Math.floor((c-40)/(i.fontSize+5))):c>=220?5:Math.max(2,Math.round((c-48)/52))),d=a.axisTicks(t.y,r.y,u),f=0;if(t.y.visible)for(let e of d.labels)f=Math.max(f,l(e));let p=48;if(t.x.type===`category`){p=0;let e=Math.max(1,Math.floor(t.x.categories.length/200));for(let n=0;n<t.x.categories.length;n+=e)p=Math.max(p,l(t.x.categories[n]))}let m={...o,...e.padding},h=n.computePlot({width:s,height:c,padding:m,yLabelWidth:t.y.visible?Math.ceil(f):0,xAxisVisible:t.x.visible,xTitle:!!t.x.title&&t.x.visible,yTitle:!!t.y.title&&t.y.visible,fontSize:i.fontSize});e.top&&(h.y+=e.top);let g=t.x.type===`category`?Math.max(1,Math.floor(h.width/(p+14))):t.x.tickCount??Math.max(3,Math.floor(h.width/88)),_=a.axisTicks(t.x,r.x,g);return{plot:h,scales:n.createScales(h,r,t.x.reverse,t.y.reverse),xTicks:_,yTicks:d}},u=(e,t,n,r)=>{let a=[],o=e.percent?i.formatValue:r?.formatValue??i.formatValue;for(let r of e.series){if(r.hidden||!r.showLabels)continue;if(r.type===`bar`&&r.barTop){let e=r.format??o,{x:i,y:s,count:c}=r.cols,l=r.barTop,[u,d]=t.x[0]<=t.x[1]?t.x:[t.x[1],t.x[0]];for(let t=0;t<c&&a.length<300;t++){let o=i[t]+r.barOffset;if(!Number.isFinite(s[t])||o<u||o>d)continue;let c=l[t]<(r.barBase?.[t]??0);a.push({x:n.xToPx(o),y:n.yToPx(l[t]),r:0,text:e(s[t]),placement:c?`below`:`above`})}continue}if(r.type!==`scatter`)continue;let{x:e,y:i,count:s,labels:c,size:l}=r.cols;if(c)for(let o=0;o<s&&a.length<300;o++){let s=c[o];if(!s)continue;let u=e[o],d=i[o];if(u<t.x[0]||u>t.x[1]||d<t.y[0]||d>t.y[1])continue;let f=l&&l[o]>0?l[o]:r.pointSize;a.push({x:n.xToPx(u),y:n.yToPx(d),r:f/2,text:s})}}return a},d=(e,t,n)=>{let i=e.cols.x[t]+(e.type===`bar`?e.barOffset:0);return{px:n.xToPx(i),py:n.yToPx(r.plottedY(e,t))}},f=(e,t,n,r,i)=>{let a=d(e,t,i),o=!1;if(e.type===`bar`&&e.barBase){let s=e.barHalfWidth/i.xPerPx,c=i.yToPx(e.barBase[t]);o=Math.abs(n-a.px)<=s&&r>=Math.min(c,a.py)-2&&r<=Math.max(c,a.py)+2}else if(e.type===`candlestick`){let{high:s,low:c,y:l}=e.cols,u=Math.max(e.barHalfWidth/i.xPerPx,3),d=i.yToPx(s?s[t]:l[t]),f=i.yToPx(c?c[t]:l[t]);o=Math.abs(n-a.px)<=u&&r>=Math.min(d,f)-2&&r<=Math.max(d,f)+2}return{series:e,index:t,px:a.px,py:a.py,dx:Math.abs(i.xToPx(e.cols.x[t])-n),dist:o?0:Math.hypot(a.px-n,a.py-r),inside:o}},p=(e,t)=>e.cols.size&&e.cols.size[t]>0?e.cols.size[t]:e.pointSize,m=(e,t,n,i,a)=>{let o=Math.max(e.pointSize/2+6,10)+a,s=i.pxToX(t),c=i.pxToY(n),l=o*i.xPerPx,u=o*i.yPerPx,d=-1,f=1/0,{x:m,y:h}=e.cols;return r.gridOf(e).query(s-l,s+l,c-u,c+u,r=>{let o=Math.hypot(i.xToPx(m[r])-t,i.yToPx(h[r])-n);o<=Math.max(p(e,r)/2+4,8)+a&&o<=f&&(f=o,d=r)}),d},h=(e,t,n)=>{let{x:i,y:a}=e.cellHalf,{x:o,y:s}=e.cols,c=-1;return r.gridOf(e).query(t-i,t+i,n-a,n+a,r=>{e.cellColors?.[r]&&Math.abs(o[r]-t)<=i&&Math.abs(s[r]-n)<=a&&(c=r)}),c},g=(e,n)=>{let{x:r,y:i,count:a,sorted:o}=e.cols;if(o)return t.nearestIndex(r,i,a,n);let s=-1,c=1/0;for(let e=0;e<a;e++){if(!Number.isFinite(i[e]))continue;let t=Math.abs(r[e]-n);t<c&&(c=t,s=e)}return s},_=(t,n)=>{let r=t.pointColors?.[n],i=t.cols.labels?.[n],{open:a,high:o,low:s,value:c}=t.cols,l=r?e.toCss(r):t.colorCss,u={};if(t.type===`candlestick`){let r=a?a[n]:NaN;Number.isFinite(r)&&(u.open=r),o&&Number.isFinite(o[n])&&(u.high=o[n]),s&&Number.isFinite(s[n])&&(u.low=s[n]),l=e.toCss(t.cols.y[n]<r?t.downColor:t.upColor)}else if(t.type===`heatmap`){let r=c?c[n]:t.cols.y[n];Number.isFinite(r)&&(u.value=r);let i=t.cellColors?.[n];i&&(l=e.toCss(e.unpackColor(i)))}return{seriesIndex:t.index,seriesId:t.id,seriesName:t.name,index:n,x:t.cols.x[n],y:t.cols.y[n],color:l,...i===void 0?{}:{label:i},...u}},v=(e,t)=>{if(!e.length)return null;e.sort((e,t)=>e.series.index-t.series.index);let n=e.map(e=>_(e.series,e.index)),r=n[0].x;return{items:n,x:r,xLabel:t?.formatValue(r)??String(r)}},y=(e,t,n,r,i,a=0)=>{let{plot:o}=t,s=6+a;if(r<o.x-s||r>o.x+o.width+s||i<o.y-s||i>o.y+o.height+s)return null;let c=t.pxToX(r),l=[],u=[];for(let n of e.series)if(!(n.hidden||n.cols.count===0)){if(n.type===`scatter`){let e=m(n,r,i,t,a);e>=0&&l.push(f(n,e,r,i,t))}else if(n.type===`heatmap`){let e=h(n,t.pxToX(r),t.pxToY(i));if(e>=0){let a=f(n,e,r,i,t);a.inside=!0,a.dist=0,l.push(a)}}else{let e=g(n,c);e>=0&&u.push(f(n,e,r,i,t))}}if(e.tooltipMode===`nearest`){let e=[...l,...u].filter(e=>e.inside||e.series.type===`scatter`||e.dist<=32+a);return e.length?v([e.reduce((e,t)=>t.dist<=e.dist?t:e)],n):null}if(!u.length)return l.length?v([l.reduce((e,t)=>t.dist<=e.dist?t:e)],n):null;let d=Math.min(...u.map(e=>e.dx)),p=e.x.type===`category`?.5/t.xPerPx:0,y=u.filter(e=>e.dx<=d+Math.max(1,p)),b=y.reduce((e,t)=>t.dx<e.dx?t:e),x=v([b,...y.filter(e=>e!==b),...l],n);return x&&(x.x=_(b.series,b.index).x,x.xLabel=n?.formatValue(x.x)??String(x.x)),x},b=(e,t)=>e===t||!!e&&!!t&&e.items.length===t.items.length&&e.items.every((e,n)=>e.index===t.items[n].index&&e.seriesIndex===t.items[n].seriesIndex),x=(e,t,n)=>{let r=n?.formatValue??String,a=t.items[0],o=a?e.series[a.seriesIndex]:null;if(t.items.length===1&&o?.type===`heatmap`){let n=e.y.type===`category`?e.y.categories[Math.round(a.y)]??r(a.y):r(a.y);return{title:`${t.xLabel} · ${n}`,titleColor:null,rows:[{color:a.color,name:a.label??o.name,value:a.value===void 0?`–`:(o.format??i.formatValue)(a.value)}]}}if(t.items.every(t=>e.series[t.seriesIndex].type===`scatter`)&&t.items.length===1){let n=t.items[0],i=[{color:null,name:e.x.title??`x`,value:t.xLabel},{color:null,name:e.y.title??`y`,value:r(n.y)}];return n.label!==void 0&&e.series.length>1&&i.push({color:null,name:``,value:n.seriesName}),{title:n.label??n.seriesName,titleColor:n.color,rows:i}}let s=[],c=[];for(let n of t.items){let t=e.series[n.seriesIndex];if(c.push(s.length),t.type===`candlestick`){let e=n.open!==void 0&&n.open!==0?(n.y-n.open)/Math.abs(n.open)*100:NaN;s.push({color:n.color,name:t.name,value:Number.isFinite(e)?`${e>=0?`+`:``}${e.toFixed(2)}%`:``});let i=[[`Open`,n.open],[`High`,n.high],[`Low`,n.low],[`Close`,n.y]];for(let[e,n]of i)n!==void 0&&Number.isFinite(n)&&s.push({color:null,name:e,value:(t.format??r)(n)});continue}s.push({color:n.color,name:n.label?`${n.seriesName} · ${n.label}`:n.seriesName,value:(t.format??r)(n.y)})}if(e.percent){let n=new Map;for(let r of t.items){let t=S(e,r.seriesIndex);t!==null&&Number.isFinite(r.y)&&n.set(t,(n.get(t)??0)+Math.abs(r.y))}t.items.forEach((t,r)=>{let a=S(e,t.seriesIndex),o=a===null?void 0:n.get(a),l=s[c[r]];o&&l&&Number.isFinite(t.y)&&(l.value=`${(e.series[t.seriesIndex].format??i.formatValue)(t.y)} · ${(Math.abs(t.y)/o*100).toFixed(1)}%`)})}return{title:t.xLabel,titleColor:null,rows:s}},S=(e,t)=>e.series[t].hidden?null:e.stacks[t],C=(t,n,r)=>{let i=[],{plot:a}=n,o=1/0,s=-1/0;for(let c of r.items){let r=t.series[c.seriesIndex];if(r.type===`bar`||r.type===`candlestick`){let e=n.xToPx(c.x+r.barOffset),t=Math.max(r.barHalfWidth/n.xPerPx,1);o=Math.min(o,e-t),s=Math.max(s,e+t);continue}if(r.type===`heatmap`){let e=n.xToPx(c.x),t=n.yToPx(c.y),a=Math.abs(r.cellHalf.x/n.xPerPx),o=Math.abs(r.cellHalf.y/n.yPerPx);i.push({kind:`cell`,x:e-a,y:t-o,width:a*2,height:o*2});continue}let{px:l,py:u}=d(r,c.index,n);if(l<a.x-1||l>a.x+a.width+1||u<a.y-1||u>a.y+a.height+1)continue;let f=r.type===`scatter`?p(r,c.index)+4:Math.max(9,r.lineWidth*2+5),m=r.pointColors?.[c.index]??r.color;i.push({kind:`dot`,x:l,y:u,size:f,color:c.color,halo:e.toCss(m,.2)})}if(s>o){let e=Math.max(4,(s-o)*.14),t=Math.max(a.x,o-e),n=Math.min(a.x+a.width,s+e);n>t&&i.unshift({kind:`band`,x:t,y:a.y,width:n-t,height:a.height})}return i},w=e=>e===`scatter`?`dot`:e===`line`?`line`:`square`,T=(e,t,n)=>n??(e.tooltipMode===`axis`&&t.items.some(t=>{let n=e.series[t.seriesIndex].type;return n===`line`||n===`area`})&&!t.items.some(t=>{let n=e.series[t.seriesIndex].type;return n===`bar`||n===`candlestick`}));exports.DEFAULT_PADDING=o,exports.collectPointLabels=u,exports.dotSize=p,exports.fallbackResolve=s,exports.hitTest=y,exports.hoverItemOf=_,exports.hoverMarks=C,exports.layoutChart=l,exports.legendShape=w,exports.pointOf=d,exports.resolveAnnotations=c,exports.sameHover=b,exports.showsCrosshair=T,exports.tooltipContent=x;
2
2
  //# sourceMappingURL=scene.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"scene.cjs","names":["mix","axisTicks","computePlot","createScales","nearestIndex","toCss","require_color","require_data","require_layout","require_model","require_axis","DEFAULT_PADDING","fallbackResolve","fallback","resolveAnnotations","resolve","theme","annotations","a","color","layoutChart","input","yCount","model","height","yTicks","view","yLabelWidth","label","measure","categoryWidth","step","i","padding","plot","xCount","xTicks","collectPointLabels","labels","series","texts","count","text","xi","x","yi","y","d","size","s","pointOf","xv","yv","sc","candidateOf","p","inside","half","base","px","py","dotSize","nearestScatter","radius","slop","rx","ry","best","bestDist","nearestX","sorted","bestD","hoverItemOf","pc","index","eventOf","candidates","b","items","c","hitTest","margin","scatter","others","all","bestDx","bandPx","aligned","first","event","sameHover","it","tooltipContent","yFormat","rows","hoverMarks","marks","cx","showsCrosshair","crosshair"],"sources":["../../../../../../charts/src/engine/scene.ts"],"sourcesContent":["// The DOM-free half of a chart: annotations, layout, point labels, hit\n// testing and tooltip content. Shared by createChart (DOM + GPU),\n// createCanvasChart (any 2D context) and the React Native views.\n\nimport { axisTicks, type AxisTicks } from \"./axis\";\nimport { mix, toCss, type Rgba } from \"./color\";\nimport { nearestIndex } from \"./data\";\nimport { computePlot, createScales, type Rect, type Scales } from \"./layout\";\nimport { gridOf, type ChartModel, type SeriesModel } from \"./model\";\nimport type { PointLabel, ResolvedAnnotation } from \"./overlay\";\nimport type { ChartTheme } from \"./theme\";\nimport type {\n ChartAnnotation,\n ChartHoverEvent,\n ChartHoverItem,\n ChartPadding,\n ChartView,\n} from \"./types\";\n\nexport const MAX_POINT_LABELS = 300;\nexport const DEFAULT_PADDING = { top: 12, right: 16, bottom: 4, left: 4 };\n\nexport const fallbackResolve = (_value: string, fallback: Rgba) => fallback;\n\n/** Annotation colors resolved against the theme */\nexport const resolveAnnotations = (\n annotations: readonly ChartAnnotation[] | undefined,\n theme: ChartTheme,\n): ResolvedAnnotation[] => {\n const resolve = theme.resolve ?? fallbackResolve;\n return (annotations ?? []).map((a) => {\n if (a.type === \"rect\") {\n const color = a.color ? resolve(a.color, theme.primary) : theme.primary;\n return {\n type: \"rect\",\n x0: a.x0,\n x1: a.x1,\n y0: a.y0,\n y1: a.y1,\n color,\n opacity: a.opacity ?? 0.08,\n label: a.label,\n labelPosition: a.labelPosition ?? \"top-left\",\n labelColor: a.labelColor\n ? resolve(a.labelColor, color)\n : mix(color, theme.text, 0.2),\n };\n }\n if (a.type === \"text\") {\n return {\n type: \"text\",\n x: a.x,\n y: a.y,\n text: a.text,\n anchor: a.anchor ?? \"center\",\n color: a.color ? resolve(a.color, theme.textMuted) : theme.textMuted,\n weight: a.weight ?? 500,\n };\n }\n return {\n type: \"line\",\n axis: a.axis,\n value: a.value,\n color: a.color ? resolve(a.color, theme.textMuted) : theme.textMuted,\n width: a.width ?? 1,\n dash: [...(a.dash ?? [4, 4])],\n label: a.label,\n };\n });\n};\n\nexport interface ChartLayout {\n plot: Rect;\n scales: Scales;\n xTicks: AxisTicks;\n yTicks: AxisTicks;\n}\n\nexport interface LayoutInput {\n model: ChartModel;\n view: ChartView;\n theme: ChartTheme;\n /** Size of the drawing area (legend excluded), CSS pixels */\n width: number;\n height: number;\n padding?: ChartPadding;\n /** Offset of the drawing area (e.g. below a legend) */\n top?: number;\n /** Width of a tick label in the theme font */\n measure: (text: string) => number;\n}\n\n/** Ticks, room for the axes and the plot rectangle */\nexport const layoutChart = (input: LayoutInput): ChartLayout => {\n const { model, view, theme, width, height, measure } = input;\n // same count as the nice range of the model (its ends are then ticks),\n // fewer on short charts\n const yCount =\n model.y.tickCount ??\n (height >= 220 ? 5 : Math.max(2, Math.round((height - 48) / 52)));\n const yTicks = axisTicks(model.y, view.y, yCount);\n let yLabelWidth = 0;\n if (model.y.visible) {\n for (const label of yTicks.labels)\n yLabelWidth = Math.max(yLabelWidth, measure(label));\n }\n let categoryWidth = 48;\n if (model.x.type === \"category\") {\n categoryWidth = 0;\n const step = Math.max(1, Math.floor(model.x.categories.length / 200));\n for (let i = 0; i < model.x.categories.length; i += step) {\n categoryWidth = Math.max(categoryWidth, measure(model.x.categories[i]));\n }\n }\n const padding = { ...DEFAULT_PADDING, ...input.padding };\n const plot = computePlot({\n width,\n height,\n padding,\n yLabelWidth: model.y.visible ? Math.ceil(yLabelWidth) : 0,\n xAxisVisible: model.x.visible,\n xTitle: !!model.x.title && model.x.visible,\n yTitle: !!model.y.title && model.y.visible,\n fontSize: theme.fontSize,\n });\n if (input.top) plot.y += input.top;\n const xCount =\n model.x.type === \"category\"\n ? Math.max(1, Math.floor(plot.width / (categoryWidth + 14)))\n : (model.x.tickCount ?? Math.max(2, Math.floor(plot.width / 96)));\n const xTicks = axisTicks(model.x, view.x, xCount);\n const scales = createScales(plot, view, model.x.reverse, model.y.reverse);\n return { plot, scales, xTicks, yTicks };\n};\n\n/** Labels of the visible scatter points (`showLabels`) */\nexport const collectPointLabels = (\n model: ChartModel,\n view: ChartView,\n s: Scales,\n): PointLabel[] => {\n const labels: PointLabel[] = [];\n for (const series of model.series) {\n if (series.hidden || series.type !== \"scatter\" || !series.showLabels)\n continue;\n const { x, y, count, labels: texts, size } = series.cols;\n if (!texts) continue;\n for (let i = 0; i < count && labels.length < MAX_POINT_LABELS; i++) {\n const text = texts[i];\n if (!text) continue;\n const xi = x[i];\n const yi = y[i];\n if (xi < view.x[0] || xi > view.x[1] || yi < view.y[0] || yi > view.y[1])\n continue;\n const d = size && size[i] > 0 ? size[i] : series.pointSize;\n labels.push({ x: s.xToPx(xi), y: s.yToPx(yi), r: d / 2, text });\n }\n }\n return labels;\n};\n\n// ---------------------------------------------------------------- hit tests\n\ninterface Candidate {\n series: SeriesModel;\n index: number;\n /** Pixel position of the point */\n px: number;\n py: number;\n dx: number;\n dist: number;\n inside: boolean;\n}\n\n/** Pixel position of a point (the top of a bar) */\nexport const pointOf = (s: SeriesModel, i: number, sc: Scales) => {\n const xv = s.cols.x[i] + (s.type === \"bar\" ? s.barOffset : 0);\n const yv = s.type === \"bar\" && s.barTop ? s.barTop[i] : s.cols.y[i];\n return { px: sc.xToPx(xv), py: sc.yToPx(yv) };\n};\n\nconst candidateOf = (\n s: SeriesModel,\n i: number,\n px: number,\n py: number,\n sc: Scales,\n): Candidate => {\n const p = pointOf(s, i, sc);\n let inside = false;\n if (s.type === \"bar\" && s.barBase) {\n const half = s.barHalfWidth / sc.xPerPx;\n const base = sc.yToPx(s.barBase[i]);\n inside =\n Math.abs(px - p.px) <= half &&\n py >= Math.min(base, p.py) - 2 &&\n py <= Math.max(base, p.py) + 2;\n }\n return {\n series: s,\n index: i,\n px: p.px,\n py: p.py,\n dx: Math.abs(sc.xToPx(s.cols.x[i]) - px),\n dist: inside ? 0 : Math.hypot(p.px - px, p.py - py),\n inside,\n };\n};\n\n/** Diameter of a scatter dot */\nexport const dotSize = (s: SeriesModel, i: number) =>\n s.cols.size && s.cols.size[i] > 0 ? s.cols.size[i] : s.pointSize;\n\nconst nearestScatter = (\n s: SeriesModel,\n px: number,\n py: number,\n sc: Scales,\n slop: number,\n) => {\n const radius = Math.max(s.pointSize / 2 + 6, 10) + slop;\n const xv = sc.pxToX(px);\n const yv = sc.pxToY(py);\n const rx = radius * sc.xPerPx;\n const ry = radius * sc.yPerPx;\n let best = -1;\n let bestDist = Infinity;\n const { x, y } = s.cols;\n gridOf(s).query(xv - rx, xv + rx, yv - ry, yv + ry, (i) => {\n const d = Math.hypot(sc.xToPx(x[i]) - px, sc.yToPx(y[i]) - py);\n const reach = Math.max(dotSize(s, i) / 2 + 4, 8) + slop;\n if (d <= reach && d <= bestDist) {\n bestDist = d;\n best = i;\n }\n });\n return best;\n};\n\nconst nearestX = (s: SeriesModel, xv: number) => {\n const { x, y, count, sorted } = s.cols;\n if (sorted) return nearestIndex(x, y, count, xv);\n let best = -1;\n let bestD = Infinity;\n for (let i = 0; i < count; i++) {\n if (!Number.isFinite(y[i])) continue;\n const d = Math.abs(x[i] - xv);\n if (d < bestD) {\n bestD = d;\n best = i;\n }\n }\n return best;\n};\n\n/** Hover payload item of a point */\nexport const hoverItemOf = (s: SeriesModel, index: number): ChartHoverItem => {\n const pc = s.pointColors?.[index];\n const label = s.cols.labels?.[index];\n return {\n seriesIndex: s.index,\n seriesId: s.id,\n seriesName: s.name,\n index,\n x: s.cols.x[index],\n y: s.cols.y[index],\n color: pc ? toCss(pc) : s.colorCss,\n ...(label !== undefined ? { label } : {}),\n };\n};\n\nconst eventOf = (\n candidates: Candidate[],\n xTicks: AxisTicks | null,\n): ChartHoverEvent | null => {\n if (!candidates.length) return null;\n candidates.sort((a, b) => a.series.index - b.series.index);\n const items = candidates.map((c) => hoverItemOf(c.series, c.index));\n const x = items[0].x;\n return { items, x, xLabel: xTicks?.formatValue(x) ?? String(x) };\n};\n\n/**\n * Points under a pixel of the stage: the nearest point (scatter / `nearest`\n * tooltips) or every series at the nearest x (`axis` tooltips).\n * `slop` widens the reach of the dots (touch screens).\n */\nexport const hitTest = (\n model: ChartModel,\n sc: Scales,\n xTicks: AxisTicks | null,\n px: number,\n py: number,\n slop = 0,\n): ChartHoverEvent | null => {\n const { plot } = sc;\n const margin = 6 + slop;\n if (\n px < plot.x - margin ||\n px > plot.x + plot.width + margin ||\n py < plot.y - margin ||\n py > plot.y + plot.height + margin\n ) {\n return null;\n }\n const xv = sc.pxToX(px);\n const scatter: Candidate[] = [];\n const others: Candidate[] = [];\n for (const s of model.series) {\n if (s.hidden || s.cols.count === 0) continue;\n if (s.type === \"scatter\") {\n const i = nearestScatter(s, px, py, sc, slop);\n if (i >= 0) scatter.push(candidateOf(s, i, px, py, sc));\n } else {\n const i = nearestX(s, xv);\n if (i >= 0) others.push(candidateOf(s, i, px, py, sc));\n }\n }\n if (model.tooltipMode === \"nearest\") {\n const all = [...scatter, ...others].filter(\n (c) => c.inside || c.series.type === \"scatter\" || c.dist <= 32 + slop,\n );\n if (!all.length) return null;\n const best = all.reduce((a, b) => (b.dist <= a.dist ? b : a));\n return eventOf([best], xTicks);\n }\n if (!others.length) {\n if (!scatter.length) return null;\n return eventOf(\n [scatter.reduce((a, b) => (b.dist <= a.dist ? b : a))],\n xTicks,\n );\n }\n const bestDx = Math.min(...others.map((c) => c.dx));\n const bandPx = model.x.type === \"category\" ? 0.5 / sc.xPerPx : 0;\n const aligned = others.filter((c) => c.dx <= bestDx + Math.max(1, bandPx));\n const first = aligned.reduce((a, b) => (b.dx < a.dx ? b : a));\n const ordered = [first, ...aligned.filter((c) => c !== first), ...scatter];\n const event = eventOf(ordered, xTicks);\n if (event) {\n event.x = hoverItemOf(first.series, first.index).x;\n event.xLabel = xTicks?.formatValue(event.x) ?? String(event.x);\n }\n return event;\n};\n\n/** Whether two hover payloads point at the same points */\nexport const sameHover = (\n a: ChartHoverEvent | null,\n b: ChartHoverEvent | null,\n): boolean =>\n a === b ||\n (!!a &&\n !!b &&\n a.items.length === b.items.length &&\n a.items.every(\n (it, i) =>\n it.index === b.items[i].index &&\n it.seriesIndex === b.items[i].seriesIndex,\n ));\n\n// ------------------------------------------------------------------ tooltip\n\nexport interface TooltipRow {\n /** Swatch color (CSS) */\n color: string | null;\n name: string;\n value: string;\n}\n\nexport interface TooltipContent {\n title: string;\n /** Swatch of the title (single scatter point) */\n titleColor: string | null;\n rows: TooltipRow[];\n}\n\n/** Default tooltip content of a hover payload */\nexport const tooltipContent = (\n model: ChartModel,\n event: ChartHoverEvent,\n yTicks: AxisTicks | null,\n): TooltipContent => {\n const yFormat = yTicks?.formatValue ?? String;\n const scatterOnly = event.items.every(\n (it) => model.series[it.seriesIndex].type === \"scatter\",\n );\n if (scatterOnly && event.items.length === 1) {\n const it = event.items[0];\n const rows: TooltipRow[] = [\n { color: null, name: model.x.title ?? \"x\", value: event.xLabel },\n { color: null, name: model.y.title ?? \"y\", value: yFormat(it.y) },\n ];\n if (it.label !== undefined && model.series.length > 1)\n rows.push({ color: null, name: \"\", value: it.seriesName });\n return { title: it.label ?? it.seriesName, titleColor: it.color, rows };\n }\n return {\n title: event.xLabel,\n titleColor: null,\n rows: event.items.map((it) => ({\n color: it.color,\n name: it.label ? `${it.seriesName} · ${it.label}` : it.seriesName,\n value: yFormat(it.y),\n })),\n };\n};\n\n/** Shape of the hover marker of an item: a ring on a point, or a bar highlight */\nexport type HoverMark =\n | { kind: \"dot\"; x: number; y: number; size: number; color: string }\n | { kind: \"bar\"; x: number; y: number; width: number; height: number };\n\n/** Markers of the hovered points (pixels of the stage) */\nexport const hoverMarks = (\n model: ChartModel,\n sc: Scales,\n event: ChartHoverEvent,\n): HoverMark[] => {\n const marks: HoverMark[] = [];\n const { plot } = sc;\n for (const it of event.items) {\n const s = model.series[it.seriesIndex];\n if (s.type === \"bar\" && s.barBase && s.barTop) {\n const cx = sc.xToPx(it.x + s.barOffset);\n const half = Math.max(s.barHalfWidth / sc.xPerPx, 1);\n const a = sc.yToPx(s.barBase[it.index]);\n const b = sc.yToPx(s.barTop[it.index]);\n marks.push({\n kind: \"bar\",\n x: cx - half,\n y: Math.min(a, b),\n width: half * 2,\n height: Math.max(1, Math.abs(a - b)),\n });\n continue;\n }\n const px = sc.xToPx(it.x);\n const py = sc.yToPx(it.y);\n if (\n px < plot.x - 1 ||\n px > plot.x + plot.width + 1 ||\n py < plot.y - 1 ||\n py > plot.y + plot.height + 1\n ) {\n continue;\n }\n const size =\n s.type === \"scatter\"\n ? dotSize(s, it.index) + 6\n : Math.max(10, s.lineWidth * 2 + 6);\n marks.push({ kind: \"dot\", x: px, y: py, size, color: it.color });\n }\n return marks;\n};\n\n/** Whether the guide line follows the pointer */\nexport const showsCrosshair = (\n model: ChartModel,\n event: ChartHoverEvent,\n crosshair: boolean | undefined,\n) =>\n crosshair ??\n (model.tooltipMode === \"axis\" &&\n event.items.some((it) => model.series[it.seriesIndex].type !== \"scatter\"));\n"],"mappings":"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"}
1
+ {"version":3,"file":"scene.cjs","names":["mix","axisTicks","computePlot","createScales","formatValue","plottedY","nearestIndex","toCss","unpackColor","require_color","require_data","require_layout","require_model","require_format","require_axis","DEFAULT_PADDING","fallbackResolve","fallback","resolveAnnotations","resolve","theme","annotations","a","color","layoutChart","input","yCount","model","height","yTicks","view","yLabelWidth","label","measure","categoryWidth","step","i","padding","plot","xCount","xTicks","collectPointLabels","labels","axisFormat","series","format","top","x0","x1","count","xv","x","y","negative","s","texts","text","xi","yi","d","size","pointOf","sc","candidateOf","p","inside","half","base","px","py","high","b","low","dotSize","nearestScatter","radius","slop","yv","rx","ry","best","bestDist","cellAt","hx","hy","found","nearestX","sorted","bestD","hoverItemOf","pc","index","extra","o","open","v","value","packed","eventOf","candidates","items","c","hitTest","margin","scatter","others","all","bestDx","bandPx","aligned","first","event","sameHover","it","tooltipContent","yFormat","firstSeries","yName","rows","rowOf","change","ohlc","name","totals","stack","stackIdOf","total","row","k","seriesIndex","hoverMarks","marks","bandLo","bandHi","cx","cy","hw","hh","rgba","pad","legendShape","type","showsCrosshair","crosshair"],"sources":["../../../../../../charts/src/engine/scene.ts"],"sourcesContent":["// The DOM-free half of a chart: annotations, layout, point labels, hit\n// testing and tooltip content. Shared by createChart (DOM + GPU),\n// createCanvasChart (any 2D context) and the React Native views.\n\nimport { axisTicks, type AxisTicks } from \"./axis\";\nimport { mix, toCss, unpackColor, type Rgba } from \"./color\";\nimport { nearestIndex } from \"./data\";\nimport { formatValue } from \"./format\";\nimport { computePlot, createScales, type Rect, type Scales } from \"./layout\";\nimport { gridOf, plottedY, type ChartModel, type SeriesModel } from \"./model\";\nimport type { PointLabel, ResolvedAnnotation } from \"./overlay\";\nimport type { ChartTheme } from \"./theme\";\nimport type {\n ChartAnnotation,\n ChartHoverEvent,\n ChartHoverItem,\n ChartPadding,\n ChartView,\n} from \"./types\";\n\nexport const MAX_POINT_LABELS = 300;\nexport const DEFAULT_PADDING = { top: 12, right: 16, bottom: 4, left: 4 };\n\nexport const fallbackResolve = (_value: string, fallback: Rgba) => fallback;\n\n/** Annotation colors resolved against the theme */\nexport const resolveAnnotations = (\n annotations: readonly ChartAnnotation[] | undefined,\n theme: ChartTheme,\n): ResolvedAnnotation[] => {\n const resolve = theme.resolve ?? fallbackResolve;\n return (annotations ?? []).map((a) => {\n if (a.type === \"rect\") {\n const color = a.color ? resolve(a.color, theme.primary) : theme.primary;\n return {\n type: \"rect\",\n x0: a.x0,\n x1: a.x1,\n y0: a.y0,\n y1: a.y1,\n color,\n opacity: a.opacity ?? 0.08,\n label: a.label,\n labelPosition: a.labelPosition ?? \"top-left\",\n labelColor: a.labelColor\n ? resolve(a.labelColor, color)\n : mix(color, theme.text, 0.2),\n };\n }\n if (a.type === \"text\") {\n return {\n type: \"text\",\n x: a.x,\n y: a.y,\n text: a.text,\n anchor: a.anchor ?? \"center\",\n color: a.color ? resolve(a.color, theme.textMuted) : theme.textMuted,\n weight: a.weight ?? 500,\n };\n }\n return {\n type: \"line\",\n axis: a.axis,\n value: a.value,\n color: a.color ? resolve(a.color, theme.textMuted) : theme.textMuted,\n width: a.width ?? 1,\n dash: [...(a.dash ?? [4, 4])],\n label: a.label,\n };\n });\n};\n\nexport interface ChartLayout {\n plot: Rect;\n scales: Scales;\n xTicks: AxisTicks;\n yTicks: AxisTicks;\n}\n\nexport interface LayoutInput {\n model: ChartModel;\n view: ChartView;\n theme: ChartTheme;\n /** Size of the drawing area (legend excluded), CSS pixels */\n width: number;\n height: number;\n padding?: ChartPadding;\n /** Offset of the drawing area (e.g. below a legend) */\n top?: number;\n /** Width of a tick label in the theme font */\n measure: (text: string) => number;\n}\n\n/** Ticks, room for the axes and the plot rectangle */\nexport const layoutChart = (input: LayoutInput): ChartLayout => {\n const { model, view, theme, width, height, measure } = input;\n // same count as the nice range of the model (its ends are then ticks),\n // fewer on short charts; category rows get a label each when they fit\n const yCount =\n model.y.tickCount ??\n (model.y.type === \"category\"\n ? Math.max(1, Math.floor((height - 40) / (theme.fontSize + 5)))\n : height >= 220\n ? 5\n : Math.max(2, Math.round((height - 48) / 52)));\n const yTicks = axisTicks(model.y, view.y, yCount);\n let yLabelWidth = 0;\n if (model.y.visible) {\n for (const label of yTicks.labels)\n yLabelWidth = Math.max(yLabelWidth, measure(label));\n }\n let categoryWidth = 48;\n if (model.x.type === \"category\") {\n categoryWidth = 0;\n const step = Math.max(1, Math.floor(model.x.categories.length / 200));\n for (let i = 0; i < model.x.categories.length; i += step) {\n categoryWidth = Math.max(categoryWidth, measure(model.x.categories[i]));\n }\n }\n const padding = { ...DEFAULT_PADDING, ...input.padding };\n const plot = computePlot({\n width,\n height,\n padding,\n yLabelWidth: model.y.visible ? Math.ceil(yLabelWidth) : 0,\n xAxisVisible: model.x.visible,\n xTitle: !!model.x.title && model.x.visible,\n yTitle: !!model.y.title && model.y.visible,\n fontSize: theme.fontSize,\n });\n if (input.top) plot.y += input.top;\n const xCount =\n model.x.type === \"category\"\n ? Math.max(1, Math.floor(plot.width / (categoryWidth + 14)))\n : (model.x.tickCount ?? Math.max(3, Math.floor(plot.width / 88)));\n const xTicks = axisTicks(model.x, view.x, xCount);\n const scales = createScales(plot, view, model.x.reverse, model.y.reverse);\n return { plot, scales, xTicks, yTicks };\n};\n\n/** Labels of the visible scatter points and bar values (`showLabels`) */\nexport const collectPointLabels = (\n model: ChartModel,\n view: ChartView,\n s: Scales,\n yTicks?: AxisTicks | null,\n): PointLabel[] => {\n const labels: PointLabel[] = [];\n // 100% stacks: the axis shows percents, the labels the actual values\n const axisFormat = model.percent\n ? formatValue\n : (yTicks?.formatValue ?? formatValue);\n for (const series of model.series) {\n if (series.hidden || !series.showLabels) continue;\n if (series.type === \"bar\" && series.barTop) {\n const format = series.format ?? axisFormat;\n const { x, y, count } = series.cols;\n const top = series.barTop;\n const [x0, x1] = view.x[0] <= view.x[1] ? view.x : [view.x[1], view.x[0]];\n for (let i = 0; i < count && labels.length < MAX_POINT_LABELS; i++) {\n const xv = x[i] + series.barOffset;\n if (!Number.isFinite(y[i]) || xv < x0 || xv > x1) continue;\n const negative = top[i] < (series.barBase?.[i] ?? 0);\n labels.push({\n x: s.xToPx(xv),\n y: s.yToPx(top[i]),\n r: 0,\n text: format(y[i]),\n placement: negative ? \"below\" : \"above\",\n });\n }\n continue;\n }\n if (series.type !== \"scatter\") continue;\n const { x, y, count, labels: texts, size } = series.cols;\n if (!texts) continue;\n for (let i = 0; i < count && labels.length < MAX_POINT_LABELS; i++) {\n const text = texts[i];\n if (!text) continue;\n const xi = x[i];\n const yi = y[i];\n if (xi < view.x[0] || xi > view.x[1] || yi < view.y[0] || yi > view.y[1])\n continue;\n const d = size && size[i] > 0 ? size[i] : series.pointSize;\n labels.push({ x: s.xToPx(xi), y: s.yToPx(yi), r: d / 2, text });\n }\n }\n return labels;\n};\n\n// ---------------------------------------------------------------- hit tests\n\ninterface Candidate {\n series: SeriesModel;\n index: number;\n /** Pixel position of the point */\n px: number;\n py: number;\n dx: number;\n dist: number;\n inside: boolean;\n}\n\n/** Pixel position of a point (the top of a bar or stack, the close of a candle) */\nexport const pointOf = (s: SeriesModel, i: number, sc: Scales) => {\n const xv = s.cols.x[i] + (s.type === \"bar\" ? s.barOffset : 0);\n return { px: sc.xToPx(xv), py: sc.yToPx(plottedY(s, i)) };\n};\n\nconst candidateOf = (\n s: SeriesModel,\n i: number,\n px: number,\n py: number,\n sc: Scales,\n): Candidate => {\n const p = pointOf(s, i, sc);\n let inside = false;\n if (s.type === \"bar\" && s.barBase) {\n const half = s.barHalfWidth / sc.xPerPx;\n const base = sc.yToPx(s.barBase[i]);\n inside =\n Math.abs(px - p.px) <= half &&\n py >= Math.min(base, p.py) - 2 &&\n py <= Math.max(base, p.py) + 2;\n } else if (s.type === \"candlestick\") {\n const { high, low, y } = s.cols;\n const half = Math.max(s.barHalfWidth / sc.xPerPx, 3);\n const a = sc.yToPx(high ? high[i] : y[i]);\n const b = sc.yToPx(low ? low[i] : y[i]);\n inside =\n Math.abs(px - p.px) <= half &&\n py >= Math.min(a, b) - 2 &&\n py <= Math.max(a, b) + 2;\n }\n return {\n series: s,\n index: i,\n px: p.px,\n py: p.py,\n dx: Math.abs(sc.xToPx(s.cols.x[i]) - px),\n dist: inside ? 0 : Math.hypot(p.px - px, p.py - py),\n inside,\n };\n};\n\n/** Diameter of a scatter dot */\nexport const dotSize = (s: SeriesModel, i: number) =>\n s.cols.size && s.cols.size[i] > 0 ? s.cols.size[i] : s.pointSize;\n\nconst nearestScatter = (\n s: SeriesModel,\n px: number,\n py: number,\n sc: Scales,\n slop: number,\n) => {\n const radius = Math.max(s.pointSize / 2 + 6, 10) + slop;\n const xv = sc.pxToX(px);\n const yv = sc.pxToY(py);\n const rx = radius * sc.xPerPx;\n const ry = radius * sc.yPerPx;\n let best = -1;\n let bestDist = Infinity;\n const { x, y } = s.cols;\n gridOf(s).query(xv - rx, xv + rx, yv - ry, yv + ry, (i) => {\n const d = Math.hypot(sc.xToPx(x[i]) - px, sc.yToPx(y[i]) - py);\n const reach = Math.max(dotSize(s, i) / 2 + 4, 8) + slop;\n if (d <= reach && d <= bestDist) {\n bestDist = d;\n best = i;\n }\n });\n return best;\n};\n\n/** Heatmap cell containing a data position, -1 if none */\nconst cellAt = (s: SeriesModel, xv: number, yv: number) => {\n const { x: hx, y: hy } = s.cellHalf;\n const { x, y } = s.cols;\n let found = -1;\n gridOf(s).query(xv - hx, xv + hx, yv - hy, yv + hy, (i) => {\n if (\n s.cellColors?.[i] &&\n Math.abs(x[i] - xv) <= hx &&\n Math.abs(y[i] - yv) <= hy\n ) {\n found = i;\n }\n });\n return found;\n};\n\nconst nearestX = (s: SeriesModel, xv: number) => {\n const { x, y, count, sorted } = s.cols;\n if (sorted) return nearestIndex(x, y, count, xv);\n let best = -1;\n let bestD = Infinity;\n for (let i = 0; i < count; i++) {\n if (!Number.isFinite(y[i])) continue;\n const d = Math.abs(x[i] - xv);\n if (d < bestD) {\n bestD = d;\n best = i;\n }\n }\n return best;\n};\n\n/** Hover payload item of a point */\nexport const hoverItemOf = (s: SeriesModel, index: number): ChartHoverItem => {\n const pc = s.pointColors?.[index];\n const label = s.cols.labels?.[index];\n const { open, high, low, value } = s.cols;\n let color = pc ? toCss(pc) : s.colorCss;\n const extra: Partial<ChartHoverItem> = {};\n if (s.type === \"candlestick\") {\n const o = open ? open[index] : NaN;\n if (Number.isFinite(o)) extra.open = o;\n if (high && Number.isFinite(high[index])) extra.high = high[index];\n if (low && Number.isFinite(low[index])) extra.low = low[index];\n color = toCss(s.cols.y[index] < o ? s.downColor : s.upColor);\n } else if (s.type === \"heatmap\") {\n const v = value ? value[index] : s.cols.y[index];\n if (Number.isFinite(v)) extra.value = v;\n const packed = s.cellColors?.[index];\n if (packed) color = toCss(unpackColor(packed));\n }\n return {\n seriesIndex: s.index,\n seriesId: s.id,\n seriesName: s.name,\n index,\n x: s.cols.x[index],\n y: s.cols.y[index],\n color,\n ...(label !== undefined ? { label } : {}),\n ...extra,\n };\n};\n\nconst eventOf = (\n candidates: Candidate[],\n xTicks: AxisTicks | null,\n): ChartHoverEvent | null => {\n if (!candidates.length) return null;\n candidates.sort((a, b) => a.series.index - b.series.index);\n const items = candidates.map((c) => hoverItemOf(c.series, c.index));\n const x = items[0].x;\n return { items, x, xLabel: xTicks?.formatValue(x) ?? String(x) };\n};\n\n/**\n * Points under a pixel of the stage: the nearest point (scatter / `nearest`\n * tooltips) or every series at the nearest x (`axis` tooltips).\n * `slop` widens the reach of the dots (touch screens).\n */\nexport const hitTest = (\n model: ChartModel,\n sc: Scales,\n xTicks: AxisTicks | null,\n px: number,\n py: number,\n slop = 0,\n): ChartHoverEvent | null => {\n const { plot } = sc;\n const margin = 6 + slop;\n if (\n px < plot.x - margin ||\n px > plot.x + plot.width + margin ||\n py < plot.y - margin ||\n py > plot.y + plot.height + margin\n ) {\n return null;\n }\n const xv = sc.pxToX(px);\n const scatter: Candidate[] = [];\n const others: Candidate[] = [];\n for (const s of model.series) {\n if (s.hidden || s.cols.count === 0) continue;\n if (s.type === \"scatter\") {\n const i = nearestScatter(s, px, py, sc, slop);\n if (i >= 0) scatter.push(candidateOf(s, i, px, py, sc));\n } else if (s.type === \"heatmap\") {\n const i = cellAt(s, sc.pxToX(px), sc.pxToY(py));\n if (i >= 0) {\n const c = candidateOf(s, i, px, py, sc);\n c.inside = true;\n c.dist = 0;\n scatter.push(c);\n }\n } else {\n const i = nearestX(s, xv);\n if (i >= 0) others.push(candidateOf(s, i, px, py, sc));\n }\n }\n if (model.tooltipMode === \"nearest\") {\n const all = [...scatter, ...others].filter(\n (c) => c.inside || c.series.type === \"scatter\" || c.dist <= 32 + slop,\n );\n if (!all.length) return null;\n const best = all.reduce((a, b) => (b.dist <= a.dist ? b : a));\n return eventOf([best], xTicks);\n }\n if (!others.length) {\n if (!scatter.length) return null;\n return eventOf(\n [scatter.reduce((a, b) => (b.dist <= a.dist ? b : a))],\n xTicks,\n );\n }\n const bestDx = Math.min(...others.map((c) => c.dx));\n const bandPx = model.x.type === \"category\" ? 0.5 / sc.xPerPx : 0;\n const aligned = others.filter((c) => c.dx <= bestDx + Math.max(1, bandPx));\n const first = aligned.reduce((a, b) => (b.dx < a.dx ? b : a));\n const ordered = [first, ...aligned.filter((c) => c !== first), ...scatter];\n const event = eventOf(ordered, xTicks);\n if (event) {\n event.x = hoverItemOf(first.series, first.index).x;\n event.xLabel = xTicks?.formatValue(event.x) ?? String(event.x);\n }\n return event;\n};\n\n/** Whether two hover payloads point at the same points */\nexport const sameHover = (\n a: ChartHoverEvent | null,\n b: ChartHoverEvent | null,\n): boolean =>\n a === b ||\n (!!a &&\n !!b &&\n a.items.length === b.items.length &&\n a.items.every(\n (it, i) =>\n it.index === b.items[i].index &&\n it.seriesIndex === b.items[i].seriesIndex,\n ));\n\n// ------------------------------------------------------------------ tooltip\n\nexport interface TooltipRow {\n /** Swatch color (CSS) */\n color: string | null;\n name: string;\n value: string;\n}\n\nexport interface TooltipContent {\n title: string;\n /** Swatch of the title (single scatter point) */\n titleColor: string | null;\n rows: TooltipRow[];\n}\n\n/** Default tooltip content of a hover payload */\nexport const tooltipContent = (\n model: ChartModel,\n event: ChartHoverEvent,\n yTicks: AxisTicks | null,\n): TooltipContent => {\n const yFormat = yTicks?.formatValue ?? String;\n const first = event.items[0];\n const firstSeries = first ? model.series[first.seriesIndex] : null;\n if (event.items.length === 1 && firstSeries?.type === \"heatmap\") {\n const yName =\n model.y.type === \"category\"\n ? (model.y.categories[Math.round(first.y)] ?? yFormat(first.y))\n : yFormat(first.y);\n return {\n title: `${event.xLabel} · ${yName}`,\n titleColor: null,\n rows: [\n {\n color: first.color,\n name: first.label ?? firstSeries.name,\n value:\n first.value === undefined\n ? \"–\"\n : (firstSeries.format ?? formatValue)(first.value),\n },\n ],\n };\n }\n const scatterOnly = event.items.every(\n (it) => model.series[it.seriesIndex].type === \"scatter\",\n );\n if (scatterOnly && event.items.length === 1) {\n const it = event.items[0];\n const rows: TooltipRow[] = [\n { color: null, name: model.x.title ?? \"x\", value: event.xLabel },\n { color: null, name: model.y.title ?? \"y\", value: yFormat(it.y) },\n ];\n if (it.label !== undefined && model.series.length > 1)\n rows.push({ color: null, name: \"\", value: it.seriesName });\n return { title: it.label ?? it.seriesName, titleColor: it.color, rows };\n }\n const rows: TooltipRow[] = [];\n /** Row of every item */\n const rowOf: number[] = [];\n for (const it of event.items) {\n const s = model.series[it.seriesIndex];\n rowOf.push(rows.length);\n if (s.type === \"candlestick\") {\n const change =\n it.open !== undefined && it.open !== 0\n ? ((it.y - it.open) / Math.abs(it.open)) * 100\n : NaN;\n rows.push({\n color: it.color,\n name: s.name,\n value: Number.isFinite(change)\n ? `${change >= 0 ? \"+\" : \"\"}${change.toFixed(2)}%`\n : \"\",\n });\n const ohlc: [string, number | undefined][] = [\n [\"Open\", it.open],\n [\"High\", it.high],\n [\"Low\", it.low],\n [\"Close\", it.y],\n ];\n for (const [name, v] of ohlc) {\n if (v !== undefined && Number.isFinite(v))\n rows.push({ color: null, name, value: (s.format ?? yFormat)(v) });\n }\n continue;\n }\n rows.push({\n color: it.color,\n name: it.label ? `${it.seriesName} · ${it.label}` : it.seriesName,\n value: (s.format ?? yFormat)(it.y),\n });\n }\n if (model.percent) {\n // 100% stacks: the share of every value next to it\n const totals = new Map<string, number>();\n for (const it of event.items) {\n const stack = stackIdOf(model, it.seriesIndex);\n if (stack !== null && Number.isFinite(it.y))\n totals.set(stack, (totals.get(stack) ?? 0) + Math.abs(it.y));\n }\n event.items.forEach((it, k) => {\n const stack = stackIdOf(model, it.seriesIndex);\n const total = stack !== null ? totals.get(stack) : undefined;\n const row = rows[rowOf[k]];\n if (total && row && Number.isFinite(it.y)) {\n const format = model.series[it.seriesIndex].format ?? formatValue;\n row.value = `${format(it.y)} · ${((Math.abs(it.y) / total) * 100).toFixed(1)}%`;\n }\n });\n }\n return { title: event.xLabel, titleColor: null, rows };\n};\n\n/** Stack of a series in a 100% chart (`null` when it is not stacked) */\nconst stackIdOf = (model: ChartModel, seriesIndex: number): string | null =>\n model.series[seriesIndex].hidden ? null : model.stacks[seriesIndex];\n\n/**\n * Shape of the hover marker of an item: a dot with a soft halo on a point,\n * a band behind the hovered bar group / candle, or the outline of a cell\n */\nexport type HoverMark =\n | {\n kind: \"dot\";\n x: number;\n y: number;\n size: number;\n color: string;\n /** Translucent series color of the halo around the dot */\n halo: string;\n }\n | { kind: \"band\"; x: number; y: number; width: number; height: number }\n | { kind: \"cell\"; x: number; y: number; width: number; height: number };\n\n/** Markers of the hovered points (pixels of the stage); bands come first */\nexport const hoverMarks = (\n model: ChartModel,\n sc: Scales,\n event: ChartHoverEvent,\n): HoverMark[] => {\n const marks: HoverMark[] = [];\n const { plot } = sc;\n let bandLo = Infinity;\n let bandHi = -Infinity;\n for (const it of event.items) {\n const s = model.series[it.seriesIndex];\n if (s.type === \"bar\" || s.type === \"candlestick\") {\n const cx = sc.xToPx(it.x + s.barOffset);\n const half = Math.max(s.barHalfWidth / sc.xPerPx, 1);\n bandLo = Math.min(bandLo, cx - half);\n bandHi = Math.max(bandHi, cx + half);\n continue;\n }\n if (s.type === \"heatmap\") {\n const cx = sc.xToPx(it.x);\n const cy = sc.yToPx(it.y);\n const hw = Math.abs(s.cellHalf.x / sc.xPerPx);\n const hh = Math.abs(s.cellHalf.y / sc.yPerPx);\n marks.push({\n kind: \"cell\",\n x: cx - hw,\n y: cy - hh,\n width: hw * 2,\n height: hh * 2,\n });\n continue;\n }\n const { px, py } = pointOf(s, it.index, sc);\n if (\n px < plot.x - 1 ||\n px > plot.x + plot.width + 1 ||\n py < plot.y - 1 ||\n py > plot.y + plot.height + 1\n ) {\n continue;\n }\n const size =\n s.type === \"scatter\"\n ? dotSize(s, it.index) + 4\n : Math.max(9, s.lineWidth * 2 + 5);\n const rgba = s.pointColors?.[it.index] ?? s.color;\n marks.push({\n kind: \"dot\",\n x: px,\n y: py,\n size,\n color: it.color,\n halo: toCss(rgba, 0.2),\n });\n }\n if (bandHi > bandLo) {\n // the group of bars plus a margin, clipped to the plot\n const pad = Math.max(4, (bandHi - bandLo) * 0.14);\n const x0 = Math.max(plot.x, bandLo - pad);\n const x1 = Math.min(plot.x + plot.width, bandHi + pad);\n if (x1 > x0) {\n marks.unshift({\n kind: \"band\",\n x: x0,\n y: plot.y,\n width: x1 - x0,\n height: plot.height,\n });\n }\n }\n return marks;\n};\n\n/** Swatch of a series in the legend */\nexport const legendShape = (\n type: SeriesModel[\"type\"],\n): \"dot\" | \"line\" | \"square\" =>\n type === \"scatter\" ? \"dot\" : type === \"line\" ? \"line\" : \"square\";\n\n/** Whether the guide line follows the pointer */\nexport const showsCrosshair = (\n model: ChartModel,\n event: ChartHoverEvent,\n crosshair: boolean | undefined,\n) =>\n crosshair ??\n (model.tooltipMode === \"axis\" &&\n event.items.some((it) => {\n const type = model.series[it.seriesIndex].type;\n return type === \"line\" || type === \"area\";\n }) &&\n // bars get a band instead\n !event.items.some((it) => {\n const type = model.series[it.seriesIndex].type;\n return type === \"bar\" || type === \"candlestick\";\n }));\n"],"mappings":"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"}