minerva-design 1.1.0 → 1.2.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 (249) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/charts/canvas.d.cts +7 -0
  3. package/dist/charts/canvas.d.ts +7 -0
  4. package/dist/charts/core.cjs +1 -1
  5. package/dist/charts/core.d.cts +5 -1
  6. package/dist/charts/core.d.ts +5 -1
  7. package/dist/charts/core.js +4 -1
  8. package/dist/charts/engine/canvas.cjs +2 -0
  9. package/dist/charts/engine/canvas.cjs.map +1 -0
  10. package/dist/charts/engine/canvas.d.cts +85 -0
  11. package/dist/charts/engine/canvas.d.ts +85 -0
  12. package/dist/charts/engine/canvas.js +165 -0
  13. package/dist/charts/engine/canvas.js.map +1 -0
  14. package/dist/charts/engine/chart.cjs +2 -2
  15. package/dist/charts/engine/chart.cjs.map +1 -1
  16. package/dist/charts/engine/chart.js +382 -440
  17. package/dist/charts/engine/chart.js.map +1 -1
  18. package/dist/charts/engine/color.cjs +1 -1
  19. package/dist/charts/engine/color.cjs.map +1 -1
  20. package/dist/charts/engine/color.d.cts +10 -0
  21. package/dist/charts/engine/color.d.ts +10 -0
  22. package/dist/charts/engine/color.js +75 -3
  23. package/dist/charts/engine/color.js.map +1 -1
  24. package/dist/charts/engine/controller.cjs +3 -0
  25. package/dist/charts/engine/controller.cjs.map +1 -0
  26. package/dist/charts/engine/controller.d.cts +182 -0
  27. package/dist/charts/engine/controller.d.ts +182 -0
  28. package/dist/charts/engine/controller.js +528 -0
  29. package/dist/charts/engine/controller.js.map +1 -0
  30. package/dist/charts/engine/model.cjs +1 -1
  31. package/dist/charts/engine/model.cjs.map +1 -1
  32. package/dist/charts/engine/model.d.cts +2 -2
  33. package/dist/charts/engine/model.d.ts +2 -2
  34. package/dist/charts/engine/model.js +72 -72
  35. package/dist/charts/engine/model.js.map +1 -1
  36. package/dist/charts/engine/overlay.cjs +1 -1
  37. package/dist/charts/engine/overlay.cjs.map +1 -1
  38. package/dist/charts/engine/overlay.d.cts +17 -1
  39. package/dist/charts/engine/overlay.d.ts +17 -1
  40. package/dist/charts/engine/overlay.js +63 -49
  41. package/dist/charts/engine/overlay.js.map +1 -1
  42. package/dist/charts/engine/presets.cjs +3 -0
  43. package/dist/charts/engine/presets.cjs.map +1 -0
  44. package/dist/charts/engine/presets.d.cts +103 -0
  45. package/dist/charts/engine/presets.d.ts +103 -0
  46. package/dist/charts/engine/presets.js +153 -0
  47. package/dist/charts/engine/presets.js.map +1 -0
  48. package/dist/charts/engine/renderers/canvas2d.cjs +1 -1
  49. package/dist/charts/engine/renderers/canvas2d.cjs.map +1 -1
  50. package/dist/charts/engine/renderers/canvas2d.d.cts +17 -1
  51. package/dist/charts/engine/renderers/canvas2d.d.ts +17 -1
  52. package/dist/charts/engine/renderers/canvas2d.js +88 -51
  53. package/dist/charts/engine/renderers/canvas2d.js.map +1 -1
  54. package/dist/charts/engine/scene.cjs +2 -0
  55. package/dist/charts/engine/scene.cjs.map +1 -0
  56. package/dist/charts/engine/scene.d.cts +89 -0
  57. package/dist/charts/engine/scene.d.ts +89 -0
  58. package/dist/charts/engine/scene.js +241 -0
  59. package/dist/charts/engine/scene.js.map +1 -0
  60. package/dist/charts/engine/theme.cjs +1 -1
  61. package/dist/charts/engine/theme.cjs.map +1 -1
  62. package/dist/charts/engine/theme.d.cts +25 -1
  63. package/dist/charts/engine/theme.d.ts +25 -1
  64. package/dist/charts/engine/theme.js +42 -26
  65. package/dist/charts/engine/theme.js.map +1 -1
  66. package/dist/charts/engine/types.d.cts +69 -2
  67. package/dist/charts/engine/types.d.ts +69 -2
  68. package/dist/charts/index.cjs +1 -1
  69. package/dist/charts/index.d.cts +1 -1
  70. package/dist/charts/index.d.ts +1 -1
  71. package/dist/charts/index.js +5 -2
  72. package/dist/charts/react/Chart.cjs +1 -1
  73. package/dist/charts/react/Chart.cjs.map +1 -1
  74. package/dist/charts/react/Chart.d.cts +11 -4
  75. package/dist/charts/react/Chart.d.ts +11 -4
  76. package/dist/charts/react/Chart.js +81 -39
  77. package/dist/charts/react/Chart.js.map +1 -1
  78. package/dist/charts/react/charts.cjs +1 -1
  79. package/dist/charts/react/charts.cjs.map +1 -1
  80. package/dist/charts/react/charts.d.cts +1 -1
  81. package/dist/charts/react/charts.d.ts +1 -1
  82. package/dist/charts/react/charts.js +99 -145
  83. package/dist/charts/react/charts.js.map +1 -1
  84. package/dist/charts/react/types.d.cts +29 -61
  85. package/dist/charts/react/types.d.ts +29 -61
  86. package/dist/native/charts/src/canvas.cjs +1 -0
  87. package/dist/native/charts/src/canvas.js +6 -0
  88. package/dist/native/charts/src/engine/axis.cjs +2 -0
  89. package/dist/native/charts/src/engine/axis.cjs.map +1 -0
  90. package/dist/native/charts/src/engine/axis.js +38 -0
  91. package/dist/native/charts/src/engine/axis.js.map +1 -0
  92. package/dist/native/charts/src/engine/canvas.cjs +1 -0
  93. package/dist/native/charts/src/engine/canvas.js +1 -0
  94. package/dist/native/charts/src/engine/color.cjs +2 -0
  95. package/dist/native/charts/src/engine/color.cjs.map +1 -0
  96. package/dist/native/charts/src/engine/color.js +130 -0
  97. package/dist/native/charts/src/engine/color.js.map +1 -0
  98. package/dist/native/charts/src/engine/controller.cjs +3 -0
  99. package/dist/native/charts/src/engine/controller.cjs.map +1 -0
  100. package/dist/native/charts/src/engine/controller.js +528 -0
  101. package/dist/native/charts/src/engine/controller.js.map +1 -0
  102. package/dist/native/charts/src/engine/data.cjs +2 -0
  103. package/dist/native/charts/src/engine/data.cjs.map +1 -0
  104. package/dist/native/charts/src/engine/data.js +104 -0
  105. package/dist/native/charts/src/engine/data.js.map +1 -0
  106. package/dist/native/charts/src/engine/decimate.cjs +2 -0
  107. package/dist/native/charts/src/engine/decimate.cjs.map +1 -0
  108. package/dist/native/charts/src/engine/decimate.js +28 -0
  109. package/dist/native/charts/src/engine/decimate.js.map +1 -0
  110. package/dist/native/charts/src/engine/format.cjs +2 -0
  111. package/dist/native/charts/src/engine/format.cjs.map +1 -0
  112. package/dist/native/charts/src/engine/format.js +34 -0
  113. package/dist/native/charts/src/engine/format.js.map +1 -0
  114. package/dist/native/charts/src/engine/layout.cjs +2 -0
  115. package/dist/native/charts/src/engine/layout.cjs.map +1 -0
  116. package/dist/native/charts/src/engine/layout.js +26 -0
  117. package/dist/native/charts/src/engine/layout.js.map +1 -0
  118. package/dist/native/charts/src/engine/model.cjs +2 -0
  119. package/dist/native/charts/src/engine/model.cjs.map +1 -0
  120. package/dist/native/charts/src/engine/model.js +175 -0
  121. package/dist/native/charts/src/engine/model.js.map +1 -0
  122. package/dist/native/charts/src/engine/overlay.cjs +2 -0
  123. package/dist/native/charts/src/engine/overlay.cjs.map +1 -0
  124. package/dist/native/charts/src/engine/overlay.js +49 -0
  125. package/dist/native/charts/src/engine/overlay.js.map +1 -0
  126. package/dist/native/charts/src/engine/presets.cjs +3 -0
  127. package/dist/native/charts/src/engine/presets.cjs.map +1 -0
  128. package/dist/native/charts/src/engine/presets.js +147 -0
  129. package/dist/native/charts/src/engine/presets.js.map +1 -0
  130. package/dist/native/charts/src/engine/scale.cjs +2 -0
  131. package/dist/native/charts/src/engine/scale.cjs.map +1 -0
  132. package/dist/native/charts/src/engine/scale.js +37 -0
  133. package/dist/native/charts/src/engine/scale.js.map +1 -0
  134. package/dist/native/charts/src/engine/scene.cjs +2 -0
  135. package/dist/native/charts/src/engine/scene.cjs.map +1 -0
  136. package/dist/native/charts/src/engine/scene.js +241 -0
  137. package/dist/native/charts/src/engine/scene.js.map +1 -0
  138. package/dist/native/charts/src/engine/spatial.cjs +2 -0
  139. package/dist/native/charts/src/engine/spatial.cjs.map +1 -0
  140. package/dist/native/charts/src/engine/spatial.js +53 -0
  141. package/dist/native/charts/src/engine/spatial.js.map +1 -0
  142. package/dist/native/charts/src/engine/theme.cjs +2 -0
  143. package/dist/native/charts/src/engine/theme.cjs.map +1 -0
  144. package/dist/native/charts/src/engine/theme.js +62 -0
  145. package/dist/native/charts/src/engine/theme.js.map +1 -0
  146. package/dist/native/charts/src/engine/time.cjs +2 -0
  147. package/dist/native/charts/src/engine/time.cjs.map +1 -0
  148. package/dist/native/charts/src/engine/time.js +189 -0
  149. package/dist/native/charts/src/engine/time.js.map +1 -0
  150. package/dist/native/charts/src/engine/viewport.cjs +2 -0
  151. package/dist/native/charts/src/engine/viewport.cjs.map +1 -0
  152. package/dist/native/charts/src/engine/viewport.js +12 -0
  153. package/dist/native/charts/src/engine/viewport.js.map +1 -0
  154. package/dist/native/components/Chart/ChartBase.cjs +2 -0
  155. package/dist/native/components/Chart/ChartBase.cjs.map +1 -0
  156. package/dist/native/components/Chart/ChartBase.d.cts +29 -0
  157. package/dist/native/components/Chart/ChartBase.d.ts +29 -0
  158. package/dist/native/components/Chart/ChartBase.js +287 -0
  159. package/dist/native/components/Chart/ChartBase.js.map +1 -0
  160. package/dist/native/components/Chart/charts.cjs +2 -0
  161. package/dist/native/components/Chart/charts.cjs.map +1 -0
  162. package/dist/native/components/Chart/charts.d.cts +19 -0
  163. package/dist/native/components/Chart/charts.d.ts +19 -0
  164. package/dist/native/components/Chart/charts.js +173 -0
  165. package/dist/native/components/Chart/charts.js.map +1 -0
  166. package/dist/native/components/Chart/index.cjs +1 -0
  167. package/dist/native/components/Chart/index.d.cts +2 -0
  168. package/dist/native/components/Chart/index.d.ts +2 -0
  169. package/dist/native/components/Chart/index.js +2 -0
  170. package/dist/native/components/Chart/measure.cjs +2 -0
  171. package/dist/native/components/Chart/measure.cjs.map +1 -0
  172. package/dist/native/components/Chart/measure.d.cts +5 -0
  173. package/dist/native/components/Chart/measure.d.ts +5 -0
  174. package/dist/native/components/Chart/measure.js +11 -0
  175. package/dist/native/components/Chart/measure.js.map +1 -0
  176. package/dist/native/components/Chart/scene.cjs +2 -0
  177. package/dist/native/components/Chart/scene.cjs.map +1 -0
  178. package/dist/native/components/Chart/scene.d.cts +41 -0
  179. package/dist/native/components/Chart/scene.d.ts +41 -0
  180. package/dist/native/components/Chart/scene.js +419 -0
  181. package/dist/native/components/Chart/scene.js.map +1 -0
  182. package/dist/native/components/Chart/theme.cjs +2 -0
  183. package/dist/native/components/Chart/theme.cjs.map +1 -0
  184. package/dist/native/components/Chart/theme.d.cts +10 -0
  185. package/dist/native/components/Chart/theme.d.ts +10 -0
  186. package/dist/native/components/Chart/theme.js +10 -0
  187. package/dist/native/components/Chart/theme.js.map +1 -0
  188. package/dist/native/components/Chart/types.d.cts +129 -0
  189. package/dist/native/components/Chart/types.d.ts +129 -0
  190. package/dist/native/index.cjs +1 -1
  191. package/dist/native/index.d.cts +1 -0
  192. package/dist/native/index.d.ts +1 -0
  193. package/dist/native/index.js +6 -4
  194. package/dist/native/manifest.d.cts +7 -0
  195. package/dist/native/manifest.d.ts +7 -0
  196. package/dist/native/source/components/Chart/ChartBase.tsx +545 -0
  197. package/dist/native/source/components/Chart/charts.tsx +291 -0
  198. package/dist/native/source/components/Chart/index.ts +8 -0
  199. package/dist/native/source/components/Chart/measure.ts +50 -0
  200. package/dist/native/source/components/Chart/scene.tsx +987 -0
  201. package/dist/native/source/components/Chart/theme.ts +16 -0
  202. package/dist/native/source/components/Chart/types.ts +194 -0
  203. package/dist/native/source/index.ts +1 -0
  204. package/dist/native/source/manifest.ts +14 -0
  205. package/dist/taro/charts.d.ts +144 -0
  206. package/dist/taro/index.d.ts +1 -0
  207. package/dist/taro/index.js +3064 -618
  208. package/dist/uni/BarChart.vue +75 -0
  209. package/dist/uni/BarChart.vue.d.ts +111 -0
  210. package/dist/uni/Chart.vue +68 -0
  211. package/dist/uni/Chart.vue.d.ts +100 -0
  212. package/dist/uni/LineChart.vue +75 -0
  213. package/dist/uni/LineChart.vue.d.ts +111 -0
  214. package/dist/uni/ProgressIndicator.vue.d.ts +1 -1
  215. package/dist/uni/QuadrantChart.vue +184 -0
  216. package/dist/uni/QuadrantChart.vue.d.ts +173 -0
  217. package/dist/uni/ScatterChart.vue +69 -0
  218. package/dist/uni/ScatterChart.vue.d.ts +100 -0
  219. package/dist/uni/chart-canvas.d.ts +68 -0
  220. package/dist/uni/chart-canvas.js +363 -0
  221. package/dist/uni/chart-types.d.ts +135 -0
  222. package/dist/uni/chart-types.js +84 -0
  223. package/dist/uni/charts-canvas.d.ts +1 -0
  224. package/dist/uni/charts-canvas.js +8 -0
  225. package/dist/uni/index.d.ts +6 -0
  226. package/dist/uni/index.js +6 -0
  227. package/dist/weapp/bar-chart/index.js +1 -0
  228. package/dist/weapp/bar-chart/index.json +1 -0
  229. package/dist/weapp/bar-chart/index.wxml +1 -0
  230. package/dist/weapp/bar-chart/index.wxss +1 -0
  231. package/dist/weapp/chart/index.js +1 -0
  232. package/dist/weapp/chart/index.json +1 -0
  233. package/dist/weapp/chart/index.wxml +1 -0
  234. package/dist/weapp/chart/index.wxss +1 -0
  235. package/dist/weapp/controls.js +4019 -266
  236. package/dist/weapp/line-chart/index.js +1 -0
  237. package/dist/weapp/line-chart/index.json +1 -0
  238. package/dist/weapp/line-chart/index.wxml +1 -0
  239. package/dist/weapp/line-chart/index.wxss +1 -0
  240. package/dist/weapp/quadrant-chart/index.js +1 -0
  241. package/dist/weapp/quadrant-chart/index.json +1 -0
  242. package/dist/weapp/quadrant-chart/index.wxml +1 -0
  243. package/dist/weapp/quadrant-chart/index.wxss +1 -0
  244. package/dist/weapp/scatter-chart/index.js +1 -0
  245. package/dist/weapp/scatter-chart/index.json +1 -0
  246. package/dist/weapp/scatter-chart/index.wxml +1 -0
  247. package/dist/weapp/scatter-chart/index.wxss +1 -0
  248. package/dist/weapp/types.d.ts +295 -0
  249. package/package.json +21 -1
@@ -0,0 +1,153 @@
1
+ //#region src/engine/presets.ts
2
+ var e = (e, t, n) => e.map((e) => ({
3
+ ...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 = {
7
+ topLeft: "var(--danger-color, #ef4444)",
8
+ topRight: "var(--primary-color, #4f46e5)",
9
+ bottomLeft: "var(--warning-color, #f59e0b)",
10
+ bottomRight: "var(--text-secondary-color, #64748b)"
11
+ }, a = "var(--border-strong-color, var(--border-color, #cbd5e1))", o = (e) => {
12
+ let [t, n] = e.xDomain ?? [0, 10], [r, i] = e.yDomain ?? [0, 10];
13
+ return {
14
+ x0: t,
15
+ x1: n,
16
+ y0: r,
17
+ y1: i,
18
+ xs: e.xSplit ?? (t + n) / 2,
19
+ ys: e.ySplit ?? (r + i) / 2
20
+ };
21
+ }, s = (e, t, n) => {
22
+ let { xs: r, ys: i } = o(e), a = e.reverseX ? t < r : t >= r;
23
+ return n >= i ? a ? "topRight" : "topLeft" : a ? "bottomRight" : "bottomLeft";
24
+ }, c = (e, t) => {
25
+ let { x0: n, x1: r, y0: i, y1: a, xs: s, ys: c } = o(e), l = t.endsWith("Right");
26
+ return {
27
+ x: (e.reverseX ? !l : l) ? (s + r) / 2 : (n + s) / 2,
28
+ y: t.startsWith("top") ? (c + a) / 2 : (i + c) / 2
29
+ };
30
+ }, l = (e, t = {}) => {
31
+ 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 = [{
32
+ type: "scatter",
33
+ name: e.name ?? "",
34
+ pointSize: e.pointSize ?? 12,
35
+ showLabels: e.showLabels ?? !0,
36
+ opacity: .9,
37
+ data: e.points.map((t) => ({
38
+ x: t.x,
39
+ y: t.y,
40
+ label: t.label,
41
+ size: t.size,
42
+ color: t.color ?? p(s(e, t.x, t.y))
43
+ }))
44
+ }], h = f ? [u, r] : [n, u], g = f ? [n, u] : [u, r], _ = (t, [n, r], [i, a], o) => ({
45
+ type: "rect",
46
+ x0: n,
47
+ x1: r,
48
+ y0: i,
49
+ y1: a,
50
+ color: p(t),
51
+ opacity: .07,
52
+ label: e.quadrants?.[t]?.label,
53
+ labelPosition: o
54
+ }), v = e.axisLabels ?? {}, y = f ? r : n, b = f ? n : r, x = [
55
+ ...v.top ? [{
56
+ type: "text",
57
+ x: u,
58
+ y: l,
59
+ text: v.top,
60
+ anchor: "top"
61
+ }] : [],
62
+ ...v.bottom ? [{
63
+ type: "text",
64
+ x: u,
65
+ y: c,
66
+ text: v.bottom,
67
+ anchor: "bottom"
68
+ }] : [],
69
+ ...v.left ? [{
70
+ type: "text",
71
+ x: y,
72
+ y: d,
73
+ text: v.left,
74
+ anchor: "left"
75
+ }] : [],
76
+ ...v.right ? [{
77
+ type: "text",
78
+ x: b,
79
+ y: d,
80
+ text: v.right,
81
+ anchor: "right"
82
+ }] : []
83
+ ], S = [
84
+ _("topLeft", h, [d, l], "top-left"),
85
+ _("topRight", g, [d, l], "top-right"),
86
+ _("bottomLeft", h, [c, d], "bottom-left"),
87
+ _("bottomRight", g, [c, d], "bottom-right"),
88
+ {
89
+ type: "line",
90
+ axis: "x",
91
+ value: u,
92
+ dash: [],
93
+ color: a
94
+ },
95
+ {
96
+ type: "line",
97
+ axis: "y",
98
+ value: d,
99
+ dash: [],
100
+ color: a
101
+ },
102
+ ...x,
103
+ ...t.annotations ?? []
104
+ ], C = e.showTicks ?? !0, w = t.interaction !== !1 && {
105
+ zoom: !1,
106
+ ...typeof t.interaction == "object" ? t.interaction : {},
107
+ ...e.draggable ? { dragPoints: !0 } : {}
108
+ };
109
+ return {
110
+ ...t,
111
+ series: m,
112
+ annotations: S,
113
+ tooltip: t.tooltip ?? (C ? void 0 : { render: (t) => {
114
+ let n = t.items[0];
115
+ if (!n) return null;
116
+ let r = e.quadrants?.[s(e, n.x, n.y)]?.label;
117
+ return [n.label ?? e.name ?? "", r ?? ""].filter(Boolean).join("\n");
118
+ } }),
119
+ xAxis: {
120
+ min: n,
121
+ max: r,
122
+ title: e.xLabel,
123
+ reverse: f,
124
+ nice: !1,
125
+ grid: !1,
126
+ tickCount: 4,
127
+ visible: C || !!e.xLabel,
128
+ ...C ? {} : { format: () => "" }
129
+ },
130
+ yAxis: {
131
+ min: c,
132
+ max: l,
133
+ title: e.yLabel,
134
+ nice: !1,
135
+ grid: !1,
136
+ tickCount: 4,
137
+ visible: C || !!e.yLabel,
138
+ ...C ? {} : { format: () => "" }
139
+ },
140
+ legend: t.legend ?? !1,
141
+ padding: t.padding ?? (C ? void 0 : {
142
+ top: 4,
143
+ right: 4,
144
+ bottom: 4,
145
+ left: 4
146
+ }),
147
+ interaction: w
148
+ };
149
+ };
150
+ //#endregion
151
+ export { i as DEFAULT_QUADRANT_COLORS, n as barSeries, t as lineSeries, c as quadrantCenter, l as quadrantChartOptions, s as quadrantOf, r as scatterSeries, e as withSeriesType };
152
+
153
+ //# sourceMappingURL=presets.js.map
@@ -0,0 +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","quadrantCenter","visualRight","corner","quadrantChartOptions","reverseX","color","p","left","rect","xa","xb","ya","yb","position","ends","visualLeft","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,2 +1,2 @@
1
- const e=require("./types.cjs"),t=require("../decimate.cjs");var n=2e4,r=(e,t)=>`rgba(${Math.round(e[0]*255)},${Math.round(e[1]*255)},${Math.round(e[2]*255)},${e[3]*t})`,i=e=>[(e&255)/255,(e>>>8&255)/255,(e>>>16&255)/255,(e>>>24&255)/255],a=e=>!Number.isFinite(e)||Math.abs(e)>=15e37,o=(e,t,n)=>{let r=0,i=t;for(;r<i;){let t=r+i>>>1;e[t*2]<n?r=t+1:i=t}return r},s=n=>{let s=n.getContext(`2d`);if(!s)return null;let c=null,l=e=>{let{xScale:t,xOffset:n,yScale:r,yOffset:i}=e.transform,a=e.width,o=e.height;return{px:e=>((e*t+n)*.5+.5)*a,py:e=>(1-((e*r+i)*.5+.5))*o,xRange:()=>{let e=(-1-n)/t,r=(1-n)/t;return e<r?[e,r]:[r,e]}}},u=(n,r)=>{if(!n.sorted||n.count<=r.width*2)return{points:n.points,length:n.count};let i=l(r),[a,s]=i.xRange(),c=Math.max(0,o(n.points,n.count,a)-1),u=Math.min(n.count,o(n.points,n.count,s)+1),d=t.decimateMinMax(n.points,c,u,i.px,e.GAP*.5);return{points:d.points,length:d.length}},d=(e,t)=>{let n=l(t),{points:i,length:o}=u(e,t);s.beginPath();let c=!1;for(let e=0;e<o;e++){let t=i[e*2],r=i[e*2+1];if(a(t)||a(r)){c=!1;continue}c?s.lineTo(n.px(t),n.py(r)):s.moveTo(n.px(t),n.py(r)),c=!0}s.lineWidth=e.width*t.dpr,s.lineJoin=`round`,s.lineCap=`round`,s.strokeStyle=r(e.color,1),s.stroke()},f=(e,t)=>{let n=l(t),{points:i,length:o}=u(e,t),c=n.py(e.baseline),d=s.createLinearGradient(0,0,0,c);d.addColorStop(0,r(e.color,e.opacity)),d.addColorStop(1,r(e.color,e.opacity*.3)),s.fillStyle=d,s.beginPath();let f=-1,p=0,m=()=>{f<0||(s.lineTo(p,c),s.closePath(),f=-1)};for(let e=0;e<o;e++){let t=i[e*2],r=i[e*2+1];if(a(t)||a(r)){m();continue}let o=n.px(t);f<0&&(f=e,s.moveTo(o,c)),s.lineTo(o,n.py(r)),p=o}m(),s.fill()},p=(e,t)=>{let n=l(t),i=Math.max(Math.abs(e.halfWidth*t.transform.xScale)*.5*t.width,.5),o=e.radius*t.dpr;s.fillStyle=r(e.color,1),s.beginPath();let c=e.instances;for(let t=0;t<e.count;t++){let e=c[t*3],r=c[t*3+1],l=c[t*3+2];if(a(e)||a(r)||a(l))continue;let u=n.px(e),d=n.py(r),f=n.py(l),p=Math.min(d,f),m=Math.abs(d-f),h=Math.min(o,i,m/2);h>.5&&typeof s.roundRect==`function`?s.roundRect(u-i,p,i*2,m,h):s.rect(u-i,p,i*2,m)}s.fill()},m=(e,t)=>{let r=l(t),i=n.width,o=n.height;c??(c=document.createElement(`canvas`)),c.width=i,c.height=o;let u=c.getContext(`2d`);if(!u)return;let d=u.createImageData(i,o),f=d.data,p=new Float32Array(e.instances,0,e.count*4),m=new Uint32Array(e.instances,0,e.count*4);for(let n=0;n<e.count;n++){let s=p[n*4],c=p[n*4+1],l=p[n*4+2];if(a(s)||a(c)||!(l>0))continue;let u=r.px(s),d=r.py(c),h=Math.max(1,Math.round(l*t.dpr*.8)),g=Math.round(u-h/2),_=Math.round(d-h/2),v=m[n*4+3],y=(v>>>24&255)/255*Math.max(e.opacity,.6),b=v&255,x=v>>>8&255,S=v>>>16&255;for(let e=Math.max(0,_);e<Math.min(o,_+h);e++)for(let t=Math.max(0,g);t<Math.min(i,g+h);t++){let n=(e*i+t)*4,r=f[n+3]/255,a=y+r*(1-y);f[n]=(b*y+f[n]*r*(1-y))/a,f[n+1]=(x*y+f[n+1]*r*(1-y))/a,f[n+2]=(S*y+f[n+2]*r*(1-y))/a,f[n+3]=a*255}}u.putImageData(d,0,0),s.drawImage(c,0,0)},h=(e,t)=>{if(e.count>2e4){m(e,t);return}let n=l(t),o=new Float32Array(e.instances,0,e.count*4),c=new Uint32Array(e.instances,0,e.count*4),u=new Map;for(let t=0;t<e.count;t++){let e=c[t*4+3],n=u.get(e);n||u.set(e,n=[]),n.push(t)}let d=e.stroke*t.dpr;for(let[c,l]of u){let u=i(c);s.beginPath();for(let e of l){let r=o[e*4],i=o[e*4+1],c=o[e*4+2];if(a(r)||a(i)||!(c>0))continue;let l=n.px(r),u=n.py(i),d=c*t.dpr/2;s.moveTo(l+d,u),s.arc(l,u,d,0,Math.PI*2)}if(s.fillStyle=r(u,e.opacity),s.fill(),d>0){s.beginPath();for(let e of l){let r=o[e*4],i=o[e*4+1],c=o[e*4+2];if(a(r)||a(i)||!(c>0))continue;let l=Math.max(0,c*t.dpr/2-d/2),u=n.px(r),f=n.py(i);s.moveTo(u+l,f),s.arc(u,f,l,0,Math.PI*2)}s.lineWidth=d,s.strokeStyle=r(u,1),s.stroke()}}};return{kind:`canvas2d`,canvas:n,resize(e,t){n.width=Math.max(1,e),n.height=Math.max(1,t)},render(e,t){s.setTransform(1,0,0,1,0,0),s.clearRect(0,0,n.width,n.height);for(let n of e)switch(n.kind){case`line`:n.count>1&&d(n,t);break;case`area`:n.count>1&&f(n,t);break;case`bar`:p(n,t);break;default:h(n,t)}},destroy(){c=null,n.width=0,n.height=0}}};exports.SCATTER_PIXEL_THRESHOLD=n,exports.createCanvas2dRenderer=s;
1
+ const e=require("./types.cjs"),t=require("../decimate.cjs");var n=2e4,r=(e,t)=>`rgba(${Math.round(e[0]*255)},${Math.round(e[1]*255)},${Math.round(e[2]*255)},${e[3]*t})`,i=e=>[(e&255)/255,(e>>>8&255)/255,(e>>>16&255)/255,(e>>>24&255)/255],a=e=>!Number.isFinite(e)||Math.abs(e)>=15e37,o=(e,t,n)=>{let r=0,i=t;for(;r<i;){let t=r+i>>>1;e[t*2]<n?r=t+1:i=t}return r},s=(n,s)=>{let c=null,l=e=>{let{xScale:t,xOffset:n,yScale:r,yOffset:i}=e.transform,a=e.width,o=e.height;return{px:e=>((e*t+n)*.5+.5)*a,py:e=>(1-((e*r+i)*.5+.5))*o,xRange:()=>{let e=(-1-n)/t,r=(1-n)/t;return e<r?[e,r]:[r,e]}}},u=(n,r)=>{if(!n.sorted||n.count<=r.width*2)return{points:n.points,length:n.count};let i=l(r),[a,s]=i.xRange(),c=Math.max(0,o(n.points,n.count,a)-1),u=Math.min(n.count,o(n.points,n.count,s)+1),d=t.decimateMinMax(n.points,c,u,i.px,e.GAP*.5);return{points:d.points,length:d.length}},d=(e,t)=>{let i=l(t),{points:o,length:s}=u(e,t);n.beginPath();let c=!1;for(let e=0;e<s;e++){let t=o[e*2],r=o[e*2+1];if(a(t)||a(r)){c=!1;continue}c?n.lineTo(i.px(t),i.py(r)):n.moveTo(i.px(t),i.py(r)),c=!0}n.lineWidth=e.width*t.dpr,n.lineJoin=`round`,n.lineCap=`round`,n.strokeStyle=r(e.color,1),n.stroke()},f=(e,t)=>{let i=l(t),{points:o,length:s}=u(e,t),c=i.py(e.baseline),d=n.createLinearGradient(0,0,0,c);d.addColorStop(0,r(e.color,e.opacity)),d.addColorStop(1,r(e.color,e.opacity*.3)),n.fillStyle=d,n.beginPath();let f=-1,p=0,m=()=>{f<0||(n.lineTo(p,c),n.closePath(),f=-1)};for(let e=0;e<s;e++){let t=o[e*2],r=o[e*2+1];if(a(t)||a(r)){m();continue}let s=i.px(t);f<0&&(f=e,n.moveTo(s,c)),n.lineTo(s,i.py(r)),p=s}m(),n.fill()},p=(e,t)=>{let i=l(t),o=Math.max(Math.abs(e.halfWidth*t.transform.xScale)*.5*t.width,.5),s=e.radius*t.dpr;n.fillStyle=r(e.color,1),n.beginPath();let c=e.instances;for(let t=0;t<e.count;t++){let e=c[t*3],r=c[t*3+1],l=c[t*3+2];if(a(e)||a(r)||a(l))continue;let u=i.px(e),d=i.py(r),f=i.py(l),p=Math.min(d,f),m=Math.abs(d-f),h=Math.min(s,o,m/2);h>.5&&typeof n.roundRect==`function`?n.roundRect(u-o,p,o*2,m,h):n.rect(u-o,p,o*2,m)}n.fill()},m=(e,t)=>{let o=l(t),s=t.width,c=t.height,u=new Float32Array(e.instances,0,e.count*4),d=new Uint32Array(e.instances,0,e.count*4),f=0;for(let t=0;t<Math.min(e.count,64);t++)f=Math.max(f,u[t*4+2]);f=Math.max(1,Math.round((f||2)*t.dpr*.8));let p=Math.ceil(s/f),m=Math.ceil(c/f),h=new Int32Array(p*m).fill(-1);for(let t=0;t<e.count;t++){let e=u[t*4],n=u[t*4+1];if(a(e)||a(n)||!(u[t*4+2]>0))continue;let r=Math.floor(o.px(e)/f),i=Math.floor(o.py(n)/f);r<0||i<0||r>=p||i>=m||(h[i*p+r]=t)}let g=new Map;for(let e=0;e<h.length;e++){let t=h[e];if(t<0)continue;let n=d[t*4+3],r=g.get(n);r||g.set(n,r=[]),r.push(e)}for(let[t,a]of g){n.fillStyle=r(i(t),Math.max(e.opacity,.6));for(let e of a)n.fillRect(e%p*f,Math.floor(e/p)*f,f,f)}},h=(e,t)=>{let r=l(t),i=t.width,o=t.height;if(c??(c=s?.()??null),!c){m(e,t);return}c.width=i,c.height=o;let u=c.getContext(`2d`);if(!u)return;let d=u.createImageData(i,o),f=d.data,p=new Float32Array(e.instances,0,e.count*4),h=new Uint32Array(e.instances,0,e.count*4);for(let n=0;n<e.count;n++){let s=p[n*4],c=p[n*4+1],l=p[n*4+2];if(a(s)||a(c)||!(l>0))continue;let u=r.px(s),d=r.py(c),m=Math.max(1,Math.round(l*t.dpr*.8)),g=Math.round(u-m/2),_=Math.round(d-m/2),v=h[n*4+3],y=(v>>>24&255)/255*Math.max(e.opacity,.6),b=v&255,x=v>>>8&255,S=v>>>16&255;for(let e=Math.max(0,_);e<Math.min(o,_+m);e++)for(let t=Math.max(0,g);t<Math.min(i,g+m);t++){let n=(e*i+t)*4,r=f[n+3]/255,a=y+r*(1-y);f[n]=(b*y+f[n]*r*(1-y))/a,f[n+1]=(x*y+f[n+1]*r*(1-y))/a,f[n+2]=(S*y+f[n+2]*r*(1-y))/a,f[n+3]=a*255}}u.putImageData(d,0,0),n.drawImage(c,0,0)},g=(e,t)=>{if(e.count>2e4){h(e,t);return}let o=l(t),s=new Float32Array(e.instances,0,e.count*4),c=new Uint32Array(e.instances,0,e.count*4),u=new Map;for(let t=0;t<e.count;t++){let e=c[t*4+3],n=u.get(e);n||u.set(e,n=[]),n.push(t)}let d=e.stroke*t.dpr;for(let[c,l]of u){let u=i(c);n.beginPath();for(let e of l){let r=s[e*4],i=s[e*4+1],c=s[e*4+2];if(a(r)||a(i)||!(c>0))continue;let l=o.px(r),u=o.py(i),d=c*t.dpr/2;n.moveTo(l+d,u),n.arc(l,u,d,0,Math.PI*2)}if(n.fillStyle=r(u,e.opacity),n.fill(),d>0){n.beginPath();for(let e of l){let r=s[e*4],i=s[e*4+1],c=s[e*4+2];if(a(r)||a(i)||!(c>0))continue;let l=Math.max(0,c*t.dpr/2-d/2),u=o.px(r),f=o.py(i);n.moveTo(u+l,f),n.arc(u,f,l,0,Math.PI*2)}n.lineWidth=d,n.strokeStyle=r(u,1),n.stroke()}}};return{paint(e,t,r=0,i=0){n.save(),n.setTransform(1,0,0,1,r,i),n.beginPath(),n.rect(0,0,t.width,t.height),n.clip();for(let n of e)switch(n.kind){case`line`:n.count>1&&d(n,t);break;case`area`:n.count>1&&f(n,t);break;case`bar`:p(n,t);break;default:g(n,t)}n.restore()},destroy(){c=null}}},c=e=>{let t=e.getContext(`2d`);if(!t)return null;let n=s(t,()=>typeof document>`u`?null:document.createElement(`canvas`));return{kind:`canvas2d`,canvas:e,resize(t,n){e.width=Math.max(1,t),e.height=Math.max(1,n)},render(r,i){t.setTransform(1,0,0,1,0,0),t.clearRect(0,0,e.width,e.height),n.paint(r,i)},destroy(){n.destroy(),e.width=0,e.height=0}}};exports.SCATTER_PIXEL_THRESHOLD=n,exports.createCanvas2dPainter=s,exports.createCanvas2dRenderer=c;
2
2
  //# sourceMappingURL=canvas2d.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"canvas2d.cjs","names":["decimateMinMax","GAP","require_types","require_decimate","SCATTER_PIXEL_THRESHOLD","rgba","c","alpha","unpack","packed","isGap","v","lowerBoundX","lo","hi","count","mid","points","value","createCanvas2dRenderer","ctx","canvas","scratch","mapper","frame","w","h","x","xScale","xOffset","y","yScale","yOffset","a","b","visiblePoints","item","m","x0","x1","start","end","result","drawLine","pen","i","length","drawArea","base","gradient","runStart","lastX","close","px","drawBars","half","r","y0","y1","cx","top","height","radius","drawScatterPixels","sctx","image","data","f","u","size","cy","s","g","py","o","da","outA","drawScatter","groups","list","stroke","color","width","items"],"sources":["../../../../../charts/src/engine/renderers/canvas2d.ts"],"sourcesContent":["// Canvas2D backend: the fallback without GPU. Lines are decimated to a few\n// points per pixel column and very large scatter sets are written pixel by\n// pixel, so it stays usable with large data sets.\n\nimport { decimateMinMax } from \"../decimate\";\nimport type { Rgba } from \"../color\";\nimport {\n GAP,\n type ChartRenderer,\n type RenderFrame,\n type RenderItem,\n type ScatterItem,\n} from \"./types\";\n\n/** Scatter sets above this size are rasterized through ImageData */\nexport const SCATTER_PIXEL_THRESHOLD = 20000;\n\nconst rgba = (c: Rgba, alpha: number) =>\n `rgba(${Math.round(c[0] * 255)},${Math.round(c[1] * 255)},${Math.round(c[2] * 255)},${c[3] * alpha})`;\n\nconst unpack = (packed: number): Rgba => [\n (packed & 0xff) / 255,\n ((packed >>> 8) & 0xff) / 255,\n ((packed >>> 16) & 0xff) / 255,\n ((packed >>> 24) & 0xff) / 255,\n];\n\nconst isGap = (v: number) => !Number.isFinite(v) || Math.abs(v) >= GAP * 0.5;\n\n/** First point index whose relative x is >= value (sorted, interleaved) */\nconst lowerBoundX = (points: Float32Array, count: number, value: number) => {\n let lo = 0;\n let hi = count;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (points[mid * 2] < value) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n};\n\nexport const createCanvas2dRenderer = (\n canvas: HTMLCanvasElement,\n): ChartRenderer | null => {\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return null;\n let scratch: HTMLCanvasElement | null = null;\n\n const mapper = (frame: RenderFrame) => {\n const { xScale, xOffset, yScale, yOffset } = frame.transform;\n const w = frame.width;\n const h = frame.height;\n return {\n px: (x: number) => ((x * xScale + xOffset) * 0.5 + 0.5) * w,\n py: (y: number) => (1 - ((y * yScale + yOffset) * 0.5 + 0.5)) * h,\n /** Visible relative x range */\n xRange: (): [number, number] => {\n const a = (-1 - xOffset) / xScale;\n const b = (1 - xOffset) / xScale;\n return a < b ? [a, b] : [b, a];\n },\n };\n };\n\n /** Points actually drawn: decimated when there are many per pixel */\n const visiblePoints = (\n item: Extract<RenderItem, { kind: \"line\" | \"area\" }>,\n frame: RenderFrame,\n ): { points: ArrayLike<number>; length: number } => {\n if (!item.sorted || item.count <= frame.width * 2) {\n return { points: item.points, length: item.count };\n }\n const m = mapper(frame);\n const [x0, x1] = m.xRange();\n const start = Math.max(0, lowerBoundX(item.points, item.count, x0) - 1);\n const end = Math.min(\n item.count,\n lowerBoundX(item.points, item.count, x1) + 1,\n );\n const result = decimateMinMax(item.points, start, end, m.px, GAP * 0.5);\n return { points: result.points, length: result.length };\n };\n\n const drawLine = (\n item: Extract<RenderItem, { kind: \"line\" }>,\n frame: RenderFrame,\n ) => {\n const m = mapper(frame);\n const { points, length } = visiblePoints(item, frame);\n ctx.beginPath();\n let pen = false;\n for (let i = 0; i < length; i++) {\n const x = points[i * 2];\n const y = points[i * 2 + 1];\n if (isGap(x) || isGap(y)) {\n pen = false;\n continue;\n }\n if (pen) ctx.lineTo(m.px(x), m.py(y));\n else ctx.moveTo(m.px(x), m.py(y));\n pen = true;\n }\n ctx.lineWidth = item.width * frame.dpr;\n ctx.lineJoin = \"round\";\n ctx.lineCap = \"round\";\n ctx.strokeStyle = rgba(item.color, 1);\n ctx.stroke();\n };\n\n const drawArea = (\n item: Extract<RenderItem, { kind: \"area\" }>,\n frame: RenderFrame,\n ) => {\n const m = mapper(frame);\n const { points, length } = visiblePoints(item, frame);\n const base = m.py(item.baseline);\n const gradient = ctx.createLinearGradient(0, 0, 0, base);\n gradient.addColorStop(0, rgba(item.color, item.opacity));\n gradient.addColorStop(1, rgba(item.color, item.opacity * 0.3));\n ctx.fillStyle = gradient;\n ctx.beginPath();\n let runStart = -1;\n let lastX = 0;\n const close = () => {\n if (runStart < 0) return;\n ctx.lineTo(lastX, base);\n ctx.closePath();\n runStart = -1;\n };\n for (let i = 0; i < length; i++) {\n const x = points[i * 2];\n const y = points[i * 2 + 1];\n if (isGap(x) || isGap(y)) {\n close();\n continue;\n }\n const px = m.px(x);\n if (runStart < 0) {\n runStart = i;\n ctx.moveTo(px, base);\n }\n ctx.lineTo(px, m.py(y));\n lastX = px;\n }\n close();\n ctx.fill();\n };\n\n const drawBars = (\n item: Extract<RenderItem, { kind: \"bar\" }>,\n frame: RenderFrame,\n ) => {\n const m = mapper(frame);\n const half = Math.max(\n Math.abs(item.halfWidth * frame.transform.xScale) * 0.5 * frame.width,\n 0.5,\n );\n const r = item.radius * frame.dpr;\n ctx.fillStyle = rgba(item.color, 1);\n ctx.beginPath();\n const v = item.instances;\n for (let i = 0; i < item.count; i++) {\n const x = v[i * 3];\n const y0 = v[i * 3 + 1];\n const y1 = v[i * 3 + 2];\n if (isGap(x) || isGap(y0) || isGap(y1)) continue;\n const cx = m.px(x);\n const a = m.py(y0);\n const b = m.py(y1);\n const top = Math.min(a, b);\n const height = Math.abs(a - b);\n const radius = Math.min(r, half, height / 2);\n if (radius > 0.5 && typeof ctx.roundRect === \"function\") {\n ctx.roundRect(cx - half, top, half * 2, height, radius);\n } else {\n ctx.rect(cx - half, top, half * 2, height);\n }\n }\n ctx.fill();\n };\n\n const drawScatterPixels = (item: ScatterItem, frame: RenderFrame) => {\n const m = mapper(frame);\n const w = canvas.width;\n const h = canvas.height;\n scratch ??= document.createElement(\"canvas\");\n scratch.width = w;\n scratch.height = h;\n const sctx = scratch.getContext(\"2d\");\n if (!sctx) return;\n const image = sctx.createImageData(w, h);\n const data = image.data;\n const f = new Float32Array(item.instances, 0, item.count * 4);\n const u = new Uint32Array(item.instances, 0, item.count * 4);\n for (let i = 0; i < item.count; i++) {\n const x = f[i * 4];\n const y = f[i * 4 + 1];\n const size = f[i * 4 + 2];\n if (isGap(x) || isGap(y) || !(size > 0)) continue;\n const cx = m.px(x);\n const cy = m.py(y);\n const s = Math.max(1, Math.round(size * frame.dpr * 0.8));\n const x0 = Math.round(cx - s / 2);\n const y0 = Math.round(cy - s / 2);\n const packed = u[i * 4 + 3];\n const alpha =\n (((packed >>> 24) & 0xff) / 255) * Math.max(item.opacity, 0.6);\n const r = packed & 0xff;\n const g = (packed >>> 8) & 0xff;\n const b = (packed >>> 16) & 0xff;\n for (let py = Math.max(0, y0); py < Math.min(h, y0 + s); py++) {\n for (let px = Math.max(0, x0); px < Math.min(w, x0 + s); px++) {\n const o = (py * w + px) * 4;\n const da = data[o + 3] / 255;\n const outA = alpha + da * (1 - alpha);\n // straight-alpha \"over\"\n data[o] = (r * alpha + data[o] * da * (1 - alpha)) / outA;\n data[o + 1] = (g * alpha + data[o + 1] * da * (1 - alpha)) / outA;\n data[o + 2] = (b * alpha + data[o + 2] * da * (1 - alpha)) / outA;\n data[o + 3] = outA * 255;\n }\n }\n }\n sctx.putImageData(image, 0, 0);\n ctx.drawImage(scratch, 0, 0);\n };\n\n const drawScatter = (item: ScatterItem, frame: RenderFrame) => {\n if (item.count > SCATTER_PIXEL_THRESHOLD) {\n drawScatterPixels(item, frame);\n return;\n }\n const m = mapper(frame);\n const f = new Float32Array(item.instances, 0, item.count * 4);\n const u = new Uint32Array(item.instances, 0, item.count * 4);\n const groups = new Map<number, number[]>();\n for (let i = 0; i < item.count; i++) {\n const packed = u[i * 4 + 3];\n let list = groups.get(packed);\n if (!list) groups.set(packed, (list = []));\n list.push(i);\n }\n const stroke = item.stroke * frame.dpr;\n for (const [packed, list] of groups) {\n const color = unpack(packed);\n ctx.beginPath();\n for (const i of list) {\n const x = f[i * 4];\n const y = f[i * 4 + 1];\n const size = f[i * 4 + 2];\n if (isGap(x) || isGap(y) || !(size > 0)) continue;\n const cx = m.px(x);\n const cy = m.py(y);\n const r = (size * frame.dpr) / 2;\n ctx.moveTo(cx + r, cy);\n ctx.arc(cx, cy, r, 0, Math.PI * 2);\n }\n ctx.fillStyle = rgba(color, item.opacity);\n ctx.fill();\n if (stroke > 0) {\n ctx.beginPath();\n for (const i of list) {\n const x = f[i * 4];\n const y = f[i * 4 + 1];\n const size = f[i * 4 + 2];\n if (isGap(x) || isGap(y) || !(size > 0)) continue;\n const r = Math.max(0, (size * frame.dpr) / 2 - stroke / 2);\n const cx = m.px(x);\n const cy = m.py(y);\n ctx.moveTo(cx + r, cy);\n ctx.arc(cx, cy, r, 0, Math.PI * 2);\n }\n ctx.lineWidth = stroke;\n ctx.strokeStyle = rgba(color, 1);\n ctx.stroke();\n }\n }\n };\n\n return {\n kind: \"canvas2d\",\n canvas,\n resize(width, height) {\n canvas.width = Math.max(1, width);\n canvas.height = Math.max(1, height);\n },\n render(items, frame) {\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n for (const item of items) {\n switch (item.kind) {\n case \"line\":\n if (item.count > 1) drawLine(item, frame);\n break;\n case \"area\":\n if (item.count > 1) drawArea(item, frame);\n break;\n case \"bar\":\n drawBars(item, frame);\n break;\n default:\n drawScatter(item, frame);\n break;\n }\n }\n },\n destroy() {\n scratch = null;\n canvas.width = 0;\n canvas.height = 0;\n },\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"canvas2d.cjs","names":["decimateMinMax","GAP","require_types","require_decimate","SCATTER_PIXEL_THRESHOLD","rgba","c","alpha","unpack","packed","isGap","v","lowerBoundX","lo","hi","count","mid","points","value","createCanvas2dPainter","scratch","mapper","frame","w","h","x","xScale","xOffset","y","yScale","yOffset","a","b","visiblePoints","item","m","x0","x1","start","end","result","drawLine","ctx","pen","i","length","drawArea","base","gradient","runStart","lastX","close","px","drawBars","half","r","y0","y1","cx","top","height","radius","drawScatterCells","f","u","cell","cols","rows","owner","cy","groups","list","cells","drawScatterPixels","scratchCanvas","sctx","image","data","size","s","g","py","o","da","outA","drawScatter","stroke","color","left","items","createCanvas2dRenderer","canvas","painter","width"],"sources":["../../../../../charts/src/engine/renderers/canvas2d.ts"],"sourcesContent":["// Canvas2D backend: the fallback without GPU. Lines are decimated to a few\n// points per pixel column and very large scatter sets are written pixel by\n// pixel, so it stays usable with large data sets.\n\nimport { decimateMinMax } from \"../decimate\";\nimport type { Rgba } from \"../color\";\nimport {\n GAP,\n type ChartRenderer,\n type RenderFrame,\n type RenderItem,\n type ScatterItem,\n} from \"./types\";\n\n/** Scatter sets above this size are rasterized through ImageData */\nexport const SCATTER_PIXEL_THRESHOLD = 20000;\n\nconst rgba = (c: Rgba, alpha: number) =>\n `rgba(${Math.round(c[0] * 255)},${Math.round(c[1] * 255)},${Math.round(c[2] * 255)},${c[3] * alpha})`;\n\nconst unpack = (packed: number): Rgba => [\n (packed & 0xff) / 255,\n ((packed >>> 8) & 0xff) / 255,\n ((packed >>> 16) & 0xff) / 255,\n ((packed >>> 24) & 0xff) / 255,\n];\n\nconst isGap = (v: number) => !Number.isFinite(v) || Math.abs(v) >= GAP * 0.5;\n\n/** First point index whose relative x is >= value (sorted, interleaved) */\nconst lowerBoundX = (points: Float32Array, count: number, value: number) => {\n let lo = 0;\n let hi = count;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (points[mid * 2] < value) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n};\n\nexport interface Canvas2dPainter {\n /**\n * Draws the items in a `frame.width` x `frame.height` device-pixel area\n * whose top-left corner is at (`left`, `top`) device pixels; nothing is\n * cleared\n */\n paint(\n items: readonly RenderItem[],\n frame: RenderFrame,\n left?: number,\n top?: number,\n ): void;\n destroy(): void;\n}\n\n/**\n * Data layer drawn with any 2D context (browser canvases, mini-program\n * canvases, OffscreenCanvas). `scratchCanvas` creates the canvas used to\n * rasterize very large scatter sets; without it they are drawn as one\n * square per occupied pixel cell.\n */\nexport const createCanvas2dPainter = (\n ctx: CanvasRenderingContext2D,\n scratchCanvas?: () => HTMLCanvasElement | null,\n): Canvas2dPainter => {\n let scratch: HTMLCanvasElement | null = null;\n\n const mapper = (frame: RenderFrame) => {\n const { xScale, xOffset, yScale, yOffset } = frame.transform;\n const w = frame.width;\n const h = frame.height;\n return {\n px: (x: number) => ((x * xScale + xOffset) * 0.5 + 0.5) * w,\n py: (y: number) => (1 - ((y * yScale + yOffset) * 0.5 + 0.5)) * h,\n /** Visible relative x range */\n xRange: (): [number, number] => {\n const a = (-1 - xOffset) / xScale;\n const b = (1 - xOffset) / xScale;\n return a < b ? [a, b] : [b, a];\n },\n };\n };\n\n /** Points actually drawn: decimated when there are many per pixel */\n const visiblePoints = (\n item: Extract<RenderItem, { kind: \"line\" | \"area\" }>,\n frame: RenderFrame,\n ): { points: ArrayLike<number>; length: number } => {\n if (!item.sorted || item.count <= frame.width * 2) {\n return { points: item.points, length: item.count };\n }\n const m = mapper(frame);\n const [x0, x1] = m.xRange();\n const start = Math.max(0, lowerBoundX(item.points, item.count, x0) - 1);\n const end = Math.min(\n item.count,\n lowerBoundX(item.points, item.count, x1) + 1,\n );\n const result = decimateMinMax(item.points, start, end, m.px, GAP * 0.5);\n return { points: result.points, length: result.length };\n };\n\n const drawLine = (\n item: Extract<RenderItem, { kind: \"line\" }>,\n frame: RenderFrame,\n ) => {\n const m = mapper(frame);\n const { points, length } = visiblePoints(item, frame);\n ctx.beginPath();\n let pen = false;\n for (let i = 0; i < length; i++) {\n const x = points[i * 2];\n const y = points[i * 2 + 1];\n if (isGap(x) || isGap(y)) {\n pen = false;\n continue;\n }\n if (pen) ctx.lineTo(m.px(x), m.py(y));\n else ctx.moveTo(m.px(x), m.py(y));\n pen = true;\n }\n ctx.lineWidth = item.width * frame.dpr;\n ctx.lineJoin = \"round\";\n ctx.lineCap = \"round\";\n ctx.strokeStyle = rgba(item.color, 1);\n ctx.stroke();\n };\n\n const drawArea = (\n item: Extract<RenderItem, { kind: \"area\" }>,\n frame: RenderFrame,\n ) => {\n const m = mapper(frame);\n const { points, length } = visiblePoints(item, frame);\n const base = m.py(item.baseline);\n const gradient = ctx.createLinearGradient(0, 0, 0, base);\n gradient.addColorStop(0, rgba(item.color, item.opacity));\n gradient.addColorStop(1, rgba(item.color, item.opacity * 0.3));\n ctx.fillStyle = gradient;\n ctx.beginPath();\n let runStart = -1;\n let lastX = 0;\n const close = () => {\n if (runStart < 0) return;\n ctx.lineTo(lastX, base);\n ctx.closePath();\n runStart = -1;\n };\n for (let i = 0; i < length; i++) {\n const x = points[i * 2];\n const y = points[i * 2 + 1];\n if (isGap(x) || isGap(y)) {\n close();\n continue;\n }\n const px = m.px(x);\n if (runStart < 0) {\n runStart = i;\n ctx.moveTo(px, base);\n }\n ctx.lineTo(px, m.py(y));\n lastX = px;\n }\n close();\n ctx.fill();\n };\n\n const drawBars = (\n item: Extract<RenderItem, { kind: \"bar\" }>,\n frame: RenderFrame,\n ) => {\n const m = mapper(frame);\n const half = Math.max(\n Math.abs(item.halfWidth * frame.transform.xScale) * 0.5 * frame.width,\n 0.5,\n );\n const r = item.radius * frame.dpr;\n ctx.fillStyle = rgba(item.color, 1);\n ctx.beginPath();\n const v = item.instances;\n for (let i = 0; i < item.count; i++) {\n const x = v[i * 3];\n const y0 = v[i * 3 + 1];\n const y1 = v[i * 3 + 2];\n if (isGap(x) || isGap(y0) || isGap(y1)) continue;\n const cx = m.px(x);\n const a = m.py(y0);\n const b = m.py(y1);\n const top = Math.min(a, b);\n const height = Math.abs(a - b);\n const radius = Math.min(r, half, height / 2);\n if (radius > 0.5 && typeof ctx.roundRect === \"function\") {\n ctx.roundRect(cx - half, top, half * 2, height, radius);\n } else {\n ctx.rect(cx - half, top, half * 2, height);\n }\n }\n ctx.fill();\n };\n\n /** One square per occupied cell (the last point of a cell wins, like the GPU) */\n const drawScatterCells = (item: ScatterItem, frame: RenderFrame) => {\n const m = mapper(frame);\n const w = frame.width;\n const h = frame.height;\n const f = new Float32Array(item.instances, 0, item.count * 4);\n const u = new Uint32Array(item.instances, 0, item.count * 4);\n let cell = 0;\n for (let i = 0; i < Math.min(item.count, 64); i++)\n cell = Math.max(cell, f[i * 4 + 2]);\n cell = Math.max(1, Math.round((cell || 2) * frame.dpr * 0.8));\n const cols = Math.ceil(w / cell);\n const rows = Math.ceil(h / cell);\n const owner = new Int32Array(cols * rows).fill(-1);\n for (let i = 0; i < item.count; i++) {\n const x = f[i * 4];\n const y = f[i * 4 + 1];\n if (isGap(x) || isGap(y) || !(f[i * 4 + 2] > 0)) continue;\n const cx = Math.floor(m.px(x) / cell);\n const cy = Math.floor(m.py(y) / cell);\n if (cx < 0 || cy < 0 || cx >= cols || cy >= rows) continue;\n owner[cy * cols + cx] = i;\n }\n const groups = new Map<number, number[]>();\n for (let c = 0; c < owner.length; c++) {\n const i = owner[c];\n if (i < 0) continue;\n const packed = u[i * 4 + 3];\n let list = groups.get(packed);\n if (!list) groups.set(packed, (list = []));\n list.push(c);\n }\n for (const [packed, cells] of groups) {\n ctx.fillStyle = rgba(unpack(packed), Math.max(item.opacity, 0.6));\n for (const c of cells) {\n ctx.fillRect(\n (c % cols) * cell,\n Math.floor(c / cols) * cell,\n cell,\n cell,\n );\n }\n }\n };\n\n const drawScatterPixels = (item: ScatterItem, frame: RenderFrame) => {\n const m = mapper(frame);\n const w = frame.width;\n const h = frame.height;\n scratch ??= scratchCanvas?.() ?? null;\n if (!scratch) {\n drawScatterCells(item, frame);\n return;\n }\n scratch.width = w;\n scratch.height = h;\n const sctx = scratch.getContext(\"2d\");\n if (!sctx) return;\n const image = sctx.createImageData(w, h);\n const data = image.data;\n const f = new Float32Array(item.instances, 0, item.count * 4);\n const u = new Uint32Array(item.instances, 0, item.count * 4);\n for (let i = 0; i < item.count; i++) {\n const x = f[i * 4];\n const y = f[i * 4 + 1];\n const size = f[i * 4 + 2];\n if (isGap(x) || isGap(y) || !(size > 0)) continue;\n const cx = m.px(x);\n const cy = m.py(y);\n const s = Math.max(1, Math.round(size * frame.dpr * 0.8));\n const x0 = Math.round(cx - s / 2);\n const y0 = Math.round(cy - s / 2);\n const packed = u[i * 4 + 3];\n const alpha =\n (((packed >>> 24) & 0xff) / 255) * Math.max(item.opacity, 0.6);\n const r = packed & 0xff;\n const g = (packed >>> 8) & 0xff;\n const b = (packed >>> 16) & 0xff;\n for (let py = Math.max(0, y0); py < Math.min(h, y0 + s); py++) {\n for (let px = Math.max(0, x0); px < Math.min(w, x0 + s); px++) {\n const o = (py * w + px) * 4;\n const da = data[o + 3] / 255;\n const outA = alpha + da * (1 - alpha);\n // straight-alpha \"over\"\n data[o] = (r * alpha + data[o] * da * (1 - alpha)) / outA;\n data[o + 1] = (g * alpha + data[o + 1] * da * (1 - alpha)) / outA;\n data[o + 2] = (b * alpha + data[o + 2] * da * (1 - alpha)) / outA;\n data[o + 3] = outA * 255;\n }\n }\n }\n sctx.putImageData(image, 0, 0);\n ctx.drawImage(scratch, 0, 0);\n };\n\n const drawScatter = (item: ScatterItem, frame: RenderFrame) => {\n if (item.count > SCATTER_PIXEL_THRESHOLD) {\n drawScatterPixels(item, frame);\n return;\n }\n const m = mapper(frame);\n const f = new Float32Array(item.instances, 0, item.count * 4);\n const u = new Uint32Array(item.instances, 0, item.count * 4);\n const groups = new Map<number, number[]>();\n for (let i = 0; i < item.count; i++) {\n const packed = u[i * 4 + 3];\n let list = groups.get(packed);\n if (!list) groups.set(packed, (list = []));\n list.push(i);\n }\n const stroke = item.stroke * frame.dpr;\n for (const [packed, list] of groups) {\n const color = unpack(packed);\n ctx.beginPath();\n for (const i of list) {\n const x = f[i * 4];\n const y = f[i * 4 + 1];\n const size = f[i * 4 + 2];\n if (isGap(x) || isGap(y) || !(size > 0)) continue;\n const cx = m.px(x);\n const cy = m.py(y);\n const r = (size * frame.dpr) / 2;\n ctx.moveTo(cx + r, cy);\n ctx.arc(cx, cy, r, 0, Math.PI * 2);\n }\n ctx.fillStyle = rgba(color, item.opacity);\n ctx.fill();\n if (stroke > 0) {\n ctx.beginPath();\n for (const i of list) {\n const x = f[i * 4];\n const y = f[i * 4 + 1];\n const size = f[i * 4 + 2];\n if (isGap(x) || isGap(y) || !(size > 0)) continue;\n const r = Math.max(0, (size * frame.dpr) / 2 - stroke / 2);\n const cx = m.px(x);\n const cy = m.py(y);\n ctx.moveTo(cx + r, cy);\n ctx.arc(cx, cy, r, 0, Math.PI * 2);\n }\n ctx.lineWidth = stroke;\n ctx.strokeStyle = rgba(color, 1);\n ctx.stroke();\n }\n }\n };\n\n return {\n paint(items, frame, left = 0, top = 0) {\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, left, top);\n ctx.beginPath();\n ctx.rect(0, 0, frame.width, frame.height);\n ctx.clip();\n for (const item of items) {\n switch (item.kind) {\n case \"line\":\n if (item.count > 1) drawLine(item, frame);\n break;\n case \"area\":\n if (item.count > 1) drawArea(item, frame);\n break;\n case \"bar\":\n drawBars(item, frame);\n break;\n default:\n drawScatter(item, frame);\n break;\n }\n }\n ctx.restore();\n },\n destroy() {\n scratch = null;\n },\n };\n};\n\nexport const createCanvas2dRenderer = (\n canvas: HTMLCanvasElement,\n): ChartRenderer | null => {\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return null;\n const painter = createCanvas2dPainter(ctx, () =>\n typeof document === \"undefined\" ? null : document.createElement(\"canvas\"),\n );\n return {\n kind: \"canvas2d\",\n canvas,\n resize(width, height) {\n canvas.width = Math.max(1, width);\n canvas.height = Math.max(1, height);\n },\n render(items, frame) {\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n painter.paint(items, frame);\n },\n destroy() {\n painter.destroy();\n canvas.width = 0;\n canvas.height = 0;\n },\n };\n};\n"],"mappings":"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"}
@@ -1,4 +1,20 @@
1
- import { ChartRenderer } from './types.cjs';
1
+ import { ChartRenderer, RenderFrame, RenderItem } from './types.cjs';
2
2
  /** Scatter sets above this size are rasterized through ImageData */
3
3
  export declare const SCATTER_PIXEL_THRESHOLD = 20000;
4
+ export interface Canvas2dPainter {
5
+ /**
6
+ * Draws the items in a `frame.width` x `frame.height` device-pixel area
7
+ * whose top-left corner is at (`left`, `top`) device pixels; nothing is
8
+ * cleared
9
+ */
10
+ paint(items: readonly RenderItem[], frame: RenderFrame, left?: number, top?: number): void;
11
+ destroy(): void;
12
+ }
13
+ /**
14
+ * Data layer drawn with any 2D context (browser canvases, mini-program
15
+ * canvases, OffscreenCanvas). `scratchCanvas` creates the canvas used to
16
+ * rasterize very large scatter sets; without it they are drawn as one
17
+ * square per occupied pixel cell.
18
+ */
19
+ export declare const createCanvas2dPainter: (ctx: CanvasRenderingContext2D, scratchCanvas?: () => HTMLCanvasElement | null) => Canvas2dPainter;
4
20
  export declare const createCanvas2dRenderer: (canvas: HTMLCanvasElement) => ChartRenderer | null;
@@ -1,4 +1,20 @@
1
- import { ChartRenderer } from './types.js';
1
+ import { ChartRenderer, RenderFrame, RenderItem } from './types.js';
2
2
  /** Scatter sets above this size are rasterized through ImageData */
3
3
  export declare const SCATTER_PIXEL_THRESHOLD = 20000;
4
+ export interface Canvas2dPainter {
5
+ /**
6
+ * Draws the items in a `frame.width` x `frame.height` device-pixel area
7
+ * whose top-left corner is at (`left`, `top`) device pixels; nothing is
8
+ * cleared
9
+ */
10
+ paint(items: readonly RenderItem[], frame: RenderFrame, left?: number, top?: number): void;
11
+ destroy(): void;
12
+ }
13
+ /**
14
+ * Data layer drawn with any 2D context (browser canvases, mini-program
15
+ * canvases, OffscreenCanvas). `scratchCanvas` creates the canvas used to
16
+ * rasterize very large scatter sets; without it they are drawn as one
17
+ * square per occupied pixel cell.
18
+ */
19
+ export declare const createCanvas2dPainter: (ctx: CanvasRenderingContext2D, scratchCanvas?: () => HTMLCanvasElement | null) => Canvas2dPainter;
4
20
  export declare const createCanvas2dRenderer: (canvas: HTMLCanvasElement) => ChartRenderer | null;
@@ -13,9 +13,7 @@ var n = 2e4, r = (e, t) => `rgba(${Math.round(e[0] * 255)},${Math.round(e[1] * 2
13
13
  e[t * 2] < n ? r = t + 1 : i = t;
14
14
  }
15
15
  return r;
16
- }, s = (n) => {
17
- let s = n.getContext("2d");
18
- if (!s) return null;
16
+ }, s = (n, s) => {
19
17
  let c = null, l = (e) => {
20
18
  let { xScale: t, xOffset: n, yScale: r, yOffset: i } = e.transform, a = e.width, o = e.height;
21
19
  return {
@@ -37,67 +35,93 @@ var n = 2e4, r = (e, t) => `rgba(${Math.round(e[0] * 255)},${Math.round(e[1] * 2
37
35
  length: d.length
38
36
  };
39
37
  }, d = (e, t) => {
40
- let n = l(t), { points: i, length: o } = u(e, t);
41
- s.beginPath();
38
+ let i = l(t), { points: o, length: s } = u(e, t);
39
+ n.beginPath();
42
40
  let c = !1;
43
- for (let e = 0; e < o; e++) {
44
- let t = i[e * 2], r = i[e * 2 + 1];
41
+ for (let e = 0; e < s; e++) {
42
+ let t = o[e * 2], r = o[e * 2 + 1];
45
43
  if (a(t) || a(r)) {
46
44
  c = !1;
47
45
  continue;
48
46
  }
49
- c ? s.lineTo(n.px(t), n.py(r)) : s.moveTo(n.px(t), n.py(r)), c = !0;
47
+ c ? n.lineTo(i.px(t), i.py(r)) : n.moveTo(i.px(t), i.py(r)), c = !0;
50
48
  }
51
- s.lineWidth = e.width * t.dpr, s.lineJoin = "round", s.lineCap = "round", s.strokeStyle = r(e.color, 1), s.stroke();
49
+ n.lineWidth = e.width * t.dpr, n.lineJoin = "round", n.lineCap = "round", n.strokeStyle = r(e.color, 1), n.stroke();
52
50
  }, f = (e, t) => {
53
- let n = l(t), { points: i, length: o } = u(e, t), c = n.py(e.baseline), d = s.createLinearGradient(0, 0, 0, c);
54
- d.addColorStop(0, r(e.color, e.opacity)), d.addColorStop(1, r(e.color, e.opacity * .3)), s.fillStyle = d, s.beginPath();
51
+ let i = l(t), { points: o, length: s } = u(e, t), c = i.py(e.baseline), d = n.createLinearGradient(0, 0, 0, c);
52
+ d.addColorStop(0, r(e.color, e.opacity)), d.addColorStop(1, r(e.color, e.opacity * .3)), n.fillStyle = d, n.beginPath();
55
53
  let f = -1, p = 0, m = () => {
56
- f < 0 || (s.lineTo(p, c), s.closePath(), f = -1);
54
+ f < 0 || (n.lineTo(p, c), n.closePath(), f = -1);
57
55
  };
58
- for (let e = 0; e < o; e++) {
59
- let t = i[e * 2], r = i[e * 2 + 1];
56
+ for (let e = 0; e < s; e++) {
57
+ let t = o[e * 2], r = o[e * 2 + 1];
60
58
  if (a(t) || a(r)) {
61
59
  m();
62
60
  continue;
63
61
  }
64
- let o = n.px(t);
65
- f < 0 && (f = e, s.moveTo(o, c)), s.lineTo(o, n.py(r)), p = o;
62
+ let s = i.px(t);
63
+ f < 0 && (f = e, n.moveTo(s, c)), n.lineTo(s, i.py(r)), p = s;
66
64
  }
67
- m(), s.fill();
65
+ m(), n.fill();
68
66
  }, p = (e, t) => {
69
- let n = l(t), i = Math.max(Math.abs(e.halfWidth * t.transform.xScale) * .5 * t.width, .5), o = e.radius * t.dpr;
70
- s.fillStyle = r(e.color, 1), s.beginPath();
67
+ let i = l(t), o = Math.max(Math.abs(e.halfWidth * t.transform.xScale) * .5 * t.width, .5), s = e.radius * t.dpr;
68
+ n.fillStyle = r(e.color, 1), n.beginPath();
71
69
  let c = e.instances;
72
70
  for (let t = 0; t < e.count; t++) {
73
71
  let e = c[t * 3], r = c[t * 3 + 1], l = c[t * 3 + 2];
74
72
  if (a(e) || a(r) || a(l)) continue;
75
- let u = n.px(e), d = n.py(r), f = n.py(l), p = Math.min(d, f), m = Math.abs(d - f), h = Math.min(o, i, m / 2);
76
- h > .5 && typeof s.roundRect == "function" ? s.roundRect(u - i, p, i * 2, m, h) : s.rect(u - i, p, i * 2, m);
73
+ let u = i.px(e), d = i.py(r), f = i.py(l), p = Math.min(d, f), m = Math.abs(d - f), h = Math.min(s, o, m / 2);
74
+ h > .5 && typeof n.roundRect == "function" ? n.roundRect(u - o, p, o * 2, m, h) : n.rect(u - o, p, o * 2, m);
77
75
  }
78
- s.fill();
76
+ n.fill();
79
77
  }, m = (e, t) => {
80
- let r = l(t), i = n.width, o = n.height;
81
- c ?? (c = document.createElement("canvas")), c.width = i, c.height = o;
78
+ let o = l(t), s = t.width, c = t.height, u = new Float32Array(e.instances, 0, e.count * 4), d = new Uint32Array(e.instances, 0, e.count * 4), f = 0;
79
+ for (let t = 0; t < Math.min(e.count, 64); t++) f = Math.max(f, u[t * 4 + 2]);
80
+ f = Math.max(1, Math.round((f || 2) * t.dpr * .8));
81
+ let p = Math.ceil(s / f), m = Math.ceil(c / f), h = new Int32Array(p * m).fill(-1);
82
+ for (let t = 0; t < e.count; t++) {
83
+ let e = u[t * 4], n = u[t * 4 + 1];
84
+ if (a(e) || a(n) || !(u[t * 4 + 2] > 0)) continue;
85
+ let r = Math.floor(o.px(e) / f), i = Math.floor(o.py(n) / f);
86
+ r < 0 || i < 0 || r >= p || i >= m || (h[i * p + r] = t);
87
+ }
88
+ let g = /* @__PURE__ */ new Map();
89
+ for (let e = 0; e < h.length; e++) {
90
+ let t = h[e];
91
+ if (t < 0) continue;
92
+ let n = d[t * 4 + 3], r = g.get(n);
93
+ r || g.set(n, r = []), r.push(e);
94
+ }
95
+ for (let [t, a] of g) {
96
+ n.fillStyle = r(i(t), Math.max(e.opacity, .6));
97
+ for (let e of a) n.fillRect(e % p * f, Math.floor(e / p) * f, f, f);
98
+ }
99
+ }, h = (e, t) => {
100
+ let r = l(t), i = t.width, o = t.height;
101
+ if (c ?? (c = s?.() ?? null), !c) {
102
+ m(e, t);
103
+ return;
104
+ }
105
+ c.width = i, c.height = o;
82
106
  let u = c.getContext("2d");
83
107
  if (!u) return;
84
- let d = u.createImageData(i, o), f = d.data, p = new Float32Array(e.instances, 0, e.count * 4), m = new Uint32Array(e.instances, 0, e.count * 4);
108
+ let d = u.createImageData(i, o), f = d.data, p = new Float32Array(e.instances, 0, e.count * 4), h = new Uint32Array(e.instances, 0, e.count * 4);
85
109
  for (let n = 0; n < e.count; n++) {
86
110
  let s = p[n * 4], c = p[n * 4 + 1], l = p[n * 4 + 2];
87
111
  if (a(s) || a(c) || !(l > 0)) continue;
88
- let u = r.px(s), d = r.py(c), h = Math.max(1, Math.round(l * t.dpr * .8)), g = Math.round(u - h / 2), _ = Math.round(d - h / 2), v = m[n * 4 + 3], y = (v >>> 24 & 255) / 255 * Math.max(e.opacity, .6), b = v & 255, x = v >>> 8 & 255, S = v >>> 16 & 255;
89
- for (let e = Math.max(0, _); e < Math.min(o, _ + h); e++) for (let t = Math.max(0, g); t < Math.min(i, g + h); t++) {
112
+ let u = r.px(s), d = r.py(c), m = Math.max(1, Math.round(l * t.dpr * .8)), g = Math.round(u - m / 2), _ = Math.round(d - m / 2), v = h[n * 4 + 3], y = (v >>> 24 & 255) / 255 * Math.max(e.opacity, .6), b = v & 255, x = v >>> 8 & 255, S = v >>> 16 & 255;
113
+ for (let e = Math.max(0, _); e < Math.min(o, _ + m); e++) for (let t = Math.max(0, g); t < Math.min(i, g + m); t++) {
90
114
  let n = (e * i + t) * 4, r = f[n + 3] / 255, a = y + r * (1 - y);
91
115
  f[n] = (b * y + f[n] * r * (1 - y)) / a, f[n + 1] = (x * y + f[n + 1] * r * (1 - y)) / a, f[n + 2] = (S * y + f[n + 2] * r * (1 - y)) / a, f[n + 3] = a * 255;
92
116
  }
93
117
  }
94
- u.putImageData(d, 0, 0), s.drawImage(c, 0, 0);
95
- }, h = (e, t) => {
118
+ u.putImageData(d, 0, 0), n.drawImage(c, 0, 0);
119
+ }, g = (e, t) => {
96
120
  if (e.count > 2e4) {
97
- m(e, t);
121
+ h(e, t);
98
122
  return;
99
123
  }
100
- let n = l(t), o = new Float32Array(e.instances, 0, e.count * 4), c = new Uint32Array(e.instances, 0, e.count * 4), u = /* @__PURE__ */ new Map();
124
+ let o = l(t), s = new Float32Array(e.instances, 0, e.count * 4), c = new Uint32Array(e.instances, 0, e.count * 4), u = /* @__PURE__ */ new Map();
101
125
  for (let t = 0; t < e.count; t++) {
102
126
  let e = c[t * 4 + 3], n = u.get(e);
103
127
  n || u.set(e, n = []), n.push(t);
@@ -105,33 +129,28 @@ var n = 2e4, r = (e, t) => `rgba(${Math.round(e[0] * 255)},${Math.round(e[1] * 2
105
129
  let d = e.stroke * t.dpr;
106
130
  for (let [c, l] of u) {
107
131
  let u = i(c);
108
- s.beginPath();
132
+ n.beginPath();
109
133
  for (let e of l) {
110
- let r = o[e * 4], i = o[e * 4 + 1], c = o[e * 4 + 2];
134
+ let r = s[e * 4], i = s[e * 4 + 1], c = s[e * 4 + 2];
111
135
  if (a(r) || a(i) || !(c > 0)) continue;
112
- let l = n.px(r), u = n.py(i), d = c * t.dpr / 2;
113
- s.moveTo(l + d, u), s.arc(l, u, d, 0, Math.PI * 2);
136
+ let l = o.px(r), u = o.py(i), d = c * t.dpr / 2;
137
+ n.moveTo(l + d, u), n.arc(l, u, d, 0, Math.PI * 2);
114
138
  }
115
- if (s.fillStyle = r(u, e.opacity), s.fill(), d > 0) {
116
- s.beginPath();
139
+ if (n.fillStyle = r(u, e.opacity), n.fill(), d > 0) {
140
+ n.beginPath();
117
141
  for (let e of l) {
118
- let r = o[e * 4], i = o[e * 4 + 1], c = o[e * 4 + 2];
142
+ let r = s[e * 4], i = s[e * 4 + 1], c = s[e * 4 + 2];
119
143
  if (a(r) || a(i) || !(c > 0)) continue;
120
- let l = Math.max(0, c * t.dpr / 2 - d / 2), u = n.px(r), f = n.py(i);
121
- s.moveTo(u + l, f), s.arc(u, f, l, 0, Math.PI * 2);
144
+ let l = Math.max(0, c * t.dpr / 2 - d / 2), u = o.px(r), f = o.py(i);
145
+ n.moveTo(u + l, f), n.arc(u, f, l, 0, Math.PI * 2);
122
146
  }
123
- s.lineWidth = d, s.strokeStyle = r(u, 1), s.stroke();
147
+ n.lineWidth = d, n.strokeStyle = r(u, 1), n.stroke();
124
148
  }
125
149
  }
126
150
  };
127
151
  return {
128
- kind: "canvas2d",
129
- canvas: n,
130
- resize(e, t) {
131
- n.width = Math.max(1, e), n.height = Math.max(1, t);
132
- },
133
- render(e, t) {
134
- s.setTransform(1, 0, 0, 1, 0, 0), s.clearRect(0, 0, n.width, n.height);
152
+ paint(e, t, r = 0, i = 0) {
153
+ n.save(), n.setTransform(1, 0, 0, 1, r, i), n.beginPath(), n.rect(0, 0, t.width, t.height), n.clip();
135
154
  for (let n of e) switch (n.kind) {
136
155
  case "line":
137
156
  n.count > 1 && d(n, t);
@@ -142,15 +161,33 @@ var n = 2e4, r = (e, t) => `rgba(${Math.round(e[0] * 255)},${Math.round(e[1] * 2
142
161
  case "bar":
143
162
  p(n, t);
144
163
  break;
145
- default: h(n, t);
164
+ default: g(n, t);
146
165
  }
166
+ n.restore();
167
+ },
168
+ destroy() {
169
+ c = null;
170
+ }
171
+ };
172
+ }, c = (e) => {
173
+ let t = e.getContext("2d");
174
+ if (!t) return null;
175
+ let n = s(t, () => typeof document > "u" ? null : document.createElement("canvas"));
176
+ return {
177
+ kind: "canvas2d",
178
+ canvas: e,
179
+ resize(t, n) {
180
+ e.width = Math.max(1, t), e.height = Math.max(1, n);
181
+ },
182
+ render(r, i) {
183
+ t.setTransform(1, 0, 0, 1, 0, 0), t.clearRect(0, 0, e.width, e.height), n.paint(r, i);
147
184
  },
148
185
  destroy() {
149
- c = null, n.width = 0, n.height = 0;
186
+ n.destroy(), e.width = 0, e.height = 0;
150
187
  }
151
188
  };
152
189
  };
153
190
  //#endregion
154
- export { n as SCATTER_PIXEL_THRESHOLD, s as createCanvas2dRenderer };
191
+ export { n as SCATTER_PIXEL_THRESHOLD, s as createCanvas2dPainter, c as createCanvas2dRenderer };
155
192
 
156
193
  //# sourceMappingURL=canvas2d.js.map