@dou-ui/chart 0.0.0-stage → 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -2
  3. package/dist/chart.js +6 -0
  4. package/dist/chart.js.map +1 -0
  5. package/dist/chart.vue_vue_type_script_setup_true_lang.js +4245 -0
  6. package/dist/chart.vue_vue_type_script_setup_true_lang.js.map +1 -0
  7. package/dist/components/area.js +6 -0
  8. package/dist/components/area.js.map +1 -0
  9. package/dist/components/area.vue_vue_type_script_setup_true_lang.js +55 -0
  10. package/dist/components/area.vue_vue_type_script_setup_true_lang.js.map +1 -0
  11. package/dist/components/axis.js +6 -0
  12. package/dist/components/axis.js.map +1 -0
  13. package/dist/components/axis.vue_vue_type_script_setup_true_lang.js +46 -0
  14. package/dist/components/axis.vue_vue_type_script_setup_true_lang.js.map +1 -0
  15. package/dist/components/bar.js +6 -0
  16. package/dist/components/bar.js.map +1 -0
  17. package/dist/components/bar.vue_vue_type_script_setup_true_lang.js +46 -0
  18. package/dist/components/bar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  19. package/dist/components/boxplot.js +6 -0
  20. package/dist/components/boxplot.js.map +1 -0
  21. package/dist/components/boxplot.vue_vue_type_script_setup_true_lang.js +42 -0
  22. package/dist/components/boxplot.vue_vue_type_script_setup_true_lang.js.map +1 -0
  23. package/dist/components/brush.js +6 -0
  24. package/dist/components/brush.js.map +1 -0
  25. package/dist/components/brush.vue_vue_type_script_setup_true_lang.js +42 -0
  26. package/dist/components/brush.vue_vue_type_script_setup_true_lang.js.map +1 -0
  27. package/dist/components/funnel.js +6 -0
  28. package/dist/components/funnel.js.map +1 -0
  29. package/dist/components/funnel.vue_vue_type_script_setup_true_lang.js +41 -0
  30. package/dist/components/funnel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  31. package/dist/components/gauge.js +6 -0
  32. package/dist/components/gauge.js.map +1 -0
  33. package/dist/components/gauge.vue_vue_type_script_setup_true_lang.js +91 -0
  34. package/dist/components/gauge.vue_vue_type_script_setup_true_lang.js.map +1 -0
  35. package/dist/components/heatmap.js +6 -0
  36. package/dist/components/heatmap.js.map +1 -0
  37. package/dist/components/heatmap.vue_vue_type_script_setup_true_lang.js +45 -0
  38. package/dist/components/heatmap.vue_vue_type_script_setup_true_lang.js.map +1 -0
  39. package/dist/components/histogram.js +6 -0
  40. package/dist/components/histogram.js.map +1 -0
  41. package/dist/components/histogram.vue_vue_type_script_setup_true_lang.js +61 -0
  42. package/dist/components/histogram.vue_vue_type_script_setup_true_lang.js.map +1 -0
  43. package/dist/components/line.js +6 -0
  44. package/dist/components/line.js.map +1 -0
  45. package/dist/components/line.vue_vue_type_script_setup_true_lang.js +52 -0
  46. package/dist/components/line.vue_vue_type_script_setup_true_lang.js.map +1 -0
  47. package/dist/components/marker.js +6 -0
  48. package/dist/components/marker.js.map +1 -0
  49. package/dist/components/marker.vue_vue_type_script_setup_true_lang.js +31 -0
  50. package/dist/components/marker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  51. package/dist/components/pie.js +6 -0
  52. package/dist/components/pie.js.map +1 -0
  53. package/dist/components/pie.vue_vue_type_script_setup_true_lang.js +42 -0
  54. package/dist/components/pie.vue_vue_type_script_setup_true_lang.js.map +1 -0
  55. package/dist/components/radar.js +6 -0
  56. package/dist/components/radar.js.map +1 -0
  57. package/dist/components/radar.vue_vue_type_script_setup_true_lang.js +45 -0
  58. package/dist/components/radar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  59. package/dist/components/range.js +6 -0
  60. package/dist/components/range.js.map +1 -0
  61. package/dist/components/range.vue_vue_type_script_setup_true_lang.js +27 -0
  62. package/dist/components/range.vue_vue_type_script_setup_true_lang.js.map +1 -0
  63. package/dist/components/scatter.js +6 -0
  64. package/dist/components/scatter.js.map +1 -0
  65. package/dist/components/scatter.vue_vue_type_script_setup_true_lang.js +45 -0
  66. package/dist/components/scatter.vue_vue_type_script_setup_true_lang.js.map +1 -0
  67. package/dist/components/sunburst.js +6 -0
  68. package/dist/components/sunburst.js.map +1 -0
  69. package/dist/components/sunburst.vue_vue_type_script_setup_true_lang.js +36 -0
  70. package/dist/components/sunburst.vue_vue_type_script_setup_true_lang.js.map +1 -0
  71. package/dist/components/tooltip.js +6 -0
  72. package/dist/components/tooltip.js.map +1 -0
  73. package/dist/components/tooltip.vue_vue_type_script_setup_true_lang.js +31 -0
  74. package/dist/components/tooltip.vue_vue_type_script_setup_true_lang.js.map +1 -0
  75. package/dist/components/treemap.js +6 -0
  76. package/dist/components/treemap.js.map +1 -0
  77. package/dist/components/treemap.vue_vue_type_script_setup_true_lang.js +33 -0
  78. package/dist/components/treemap.vue_vue_type_script_setup_true_lang.js.map +1 -0
  79. package/dist/components/waterfall.js +6 -0
  80. package/dist/components/waterfall.js.map +1 -0
  81. package/dist/components/waterfall.vue_vue_type_script_setup_true_lang.js +49 -0
  82. package/dist/components/waterfall.vue_vue_type_script_setup_true_lang.js.map +1 -0
  83. package/dist/components/zoom.js +6 -0
  84. package/dist/components/zoom.js.map +1 -0
  85. package/dist/components/zoom.vue_vue_type_script_setup_true_lang.js +37 -0
  86. package/dist/components/zoom.vue_vue_type_script_setup_true_lang.js.map +1 -0
  87. package/dist/context.js +30 -0
  88. package/dist/context.js.map +1 -0
  89. package/dist/core/bar.js +223 -0
  90. package/dist/core/bar.js.map +1 -0
  91. package/dist/core/box.js +150 -0
  92. package/dist/core/box.js.map +1 -0
  93. package/dist/core/colors.js +58 -0
  94. package/dist/core/colors.js.map +1 -0
  95. package/dist/core/data.js +257 -0
  96. package/dist/core/data.js.map +1 -0
  97. package/dist/core/decimate.js +211 -0
  98. package/dist/core/decimate.js.map +1 -0
  99. package/dist/core/format.js +151 -0
  100. package/dist/core/format.js.map +1 -0
  101. package/dist/core/funnel.js +68 -0
  102. package/dist/core/funnel.js.map +1 -0
  103. package/dist/core/grid.js +87 -0
  104. package/dist/core/grid.js.map +1 -0
  105. package/dist/core/heatmap.js +187 -0
  106. package/dist/core/heatmap.js.map +1 -0
  107. package/dist/core/histogram.js +81 -0
  108. package/dist/core/histogram.js.map +1 -0
  109. package/dist/core/hit.js +115 -0
  110. package/dist/core/hit.js.map +1 -0
  111. package/dist/core/labels.js +141 -0
  112. package/dist/core/labels.js.map +1 -0
  113. package/dist/core/layout.js +1002 -0
  114. package/dist/core/layout.js.map +1 -0
  115. package/dist/core/line.js +230 -0
  116. package/dist/core/line.js.map +1 -0
  117. package/dist/core/marker.js +205 -0
  118. package/dist/core/marker.js.map +1 -0
  119. package/dist/core/model.js +391 -0
  120. package/dist/core/model.js.map +1 -0
  121. package/dist/core/painter.js +79 -0
  122. package/dist/core/painter.js.map +1 -0
  123. package/dist/core/pattern.js +102 -0
  124. package/dist/core/pattern.js.map +1 -0
  125. package/dist/core/pie.js +119 -0
  126. package/dist/core/pie.js.map +1 -0
  127. package/dist/core/radar.js +83 -0
  128. package/dist/core/radar.js.map +1 -0
  129. package/dist/core/scale.js +149 -0
  130. package/dist/core/scale.js.map +1 -0
  131. package/dist/core/scatter.js +263 -0
  132. package/dist/core/scatter.js.map +1 -0
  133. package/dist/core/svg.js +209 -0
  134. package/dist/core/svg.js.map +1 -0
  135. package/dist/core/sync.js +21 -0
  136. package/dist/core/sync.js.map +1 -0
  137. package/dist/core/time.js +217 -0
  138. package/dist/core/time.js.map +1 -0
  139. package/dist/core/tree.js +348 -0
  140. package/dist/core/tree.js.map +1 -0
  141. package/dist/core/warn.js +11 -0
  142. package/dist/core/warn.js.map +1 -0
  143. package/dist/core/waterfall.js +134 -0
  144. package/dist/core/waterfall.js.map +1 -0
  145. package/dist/core/window.js +94 -0
  146. package/dist/core/window.js.map +1 -0
  147. package/dist/define.js +62 -0
  148. package/dist/define.js.map +1 -0
  149. package/dist/index.js +49 -0
  150. package/dist/index.js.map +1 -0
  151. package/dist/locale.js +170 -0
  152. package/dist/locale.js.map +1 -0
  153. package/dist/overlay.js +6 -0
  154. package/dist/overlay.js.map +1 -0
  155. package/dist/overlay.vue_vue_type_script_setup_true_lang.js +207 -0
  156. package/dist/overlay.vue_vue_type_script_setup_true_lang.js.map +1 -0
  157. package/dist/pointer.js +6 -0
  158. package/dist/pointer.js.map +1 -0
  159. package/dist/pointer.vue_vue_type_script_setup_true_lang.js +136 -0
  160. package/dist/pointer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  161. package/dist/static.js +6 -0
  162. package/dist/static.js.map +1 -0
  163. package/dist/static.vue_vue_type_script_setup_true_lang.js +34 -0
  164. package/dist/static.vue_vue_type_script_setup_true_lang.js.map +1 -0
  165. package/dist/style.css +1 -0
  166. package/dist/style.d.ts +1 -0
  167. package/dist/style.js +3 -0
  168. package/dist/table.js +6 -0
  169. package/dist/table.js.map +1 -0
  170. package/dist/table.vue_vue_type_script_setup_true_lang.js +52 -0
  171. package/dist/table.vue_vue_type_script_setup_true_lang.js.map +1 -0
  172. package/dist/types/chart.vue.d.ts +24 -0
  173. package/dist/types/components/area.vue.d.ts +16 -0
  174. package/dist/types/components/axis.vue.d.ts +8 -0
  175. package/dist/types/components/bar.vue.d.ts +14 -0
  176. package/dist/types/components/boxplot.vue.d.ts +14 -0
  177. package/dist/types/components/brush.vue.d.ts +22 -0
  178. package/dist/types/components/funnel.vue.d.ts +14 -0
  179. package/dist/types/components/gauge.vue.d.ts +17 -0
  180. package/dist/types/components/heatmap.vue.d.ts +14 -0
  181. package/dist/types/components/histogram.vue.d.ts +14 -0
  182. package/dist/types/components/line.vue.d.ts +16 -0
  183. package/dist/types/components/marker.vue.d.ts +6 -0
  184. package/dist/types/components/pie.vue.d.ts +23 -0
  185. package/dist/types/components/radar.vue.d.ts +16 -0
  186. package/dist/types/components/range.vue.d.ts +12 -0
  187. package/dist/types/components/scatter.vue.d.ts +14 -0
  188. package/dist/types/components/sunburst.vue.d.ts +17 -0
  189. package/dist/types/components/tooltip.vue.d.ts +13 -0
  190. package/dist/types/components/treemap.vue.d.ts +8 -0
  191. package/dist/types/components/waterfall.vue.d.ts +16 -0
  192. package/dist/types/components/zoom.vue.d.ts +18 -0
  193. package/dist/types/context.d.ts +87 -0
  194. package/dist/types/core/bar.d.ts +38 -0
  195. package/dist/types/core/box.d.ts +25 -0
  196. package/dist/types/core/colors.d.ts +16 -0
  197. package/dist/types/core/data.d.ts +72 -0
  198. package/dist/types/core/decimate.d.ts +39 -0
  199. package/dist/types/core/format.d.ts +33 -0
  200. package/dist/types/core/funnel.d.ts +15 -0
  201. package/dist/types/core/grid.d.ts +18 -0
  202. package/dist/types/core/heatmap.d.ts +17 -0
  203. package/dist/types/core/histogram.d.ts +23 -0
  204. package/dist/types/core/hit.d.ts +31 -0
  205. package/dist/types/core/labels.d.ts +45 -0
  206. package/dist/types/core/layout.d.ts +259 -0
  207. package/dist/types/core/line.d.ts +36 -0
  208. package/dist/types/core/marker.d.ts +67 -0
  209. package/dist/types/core/model.d.ts +86 -0
  210. package/dist/types/core/painter.d.ts +34 -0
  211. package/dist/types/core/pattern.d.ts +14 -0
  212. package/dist/types/core/pie.d.ts +66 -0
  213. package/dist/types/core/radar.d.ts +12 -0
  214. package/dist/types/core/scale.d.ts +60 -0
  215. package/dist/types/core/scatter.d.ts +16 -0
  216. package/dist/types/core/series.d.ts +228 -0
  217. package/dist/types/core/svg.d.ts +63 -0
  218. package/dist/types/core/sync.d.ts +8 -0
  219. package/dist/types/core/time.d.ts +20 -0
  220. package/dist/types/core/tree.d.ts +84 -0
  221. package/dist/types/core/warn.d.ts +4 -0
  222. package/dist/types/core/waterfall.d.ts +24 -0
  223. package/dist/types/core/window.d.ts +36 -0
  224. package/dist/types/define.d.ts +115 -0
  225. package/dist/types/index.d.ts +363 -0
  226. package/dist/types/locale.d.ts +100 -0
  227. package/dist/types/overlay.vue.d.ts +95 -0
  228. package/dist/types/pointer.vue.d.ts +53 -0
  229. package/dist/types/static.vue.d.ts +24 -0
  230. package/dist/types/table.vue.d.ts +19 -0
  231. package/dist/types/types.d.ts +555 -0
  232. package/dist/types/zoom-layer.vue.d.ts +41 -0
  233. package/dist/zoom-layer.js +6 -0
  234. package/dist/zoom-layer.js.map +1 -0
  235. package/dist/zoom-layer.vue_vue_type_script_setup_true_lang.js +210 -0
  236. package/dist/zoom-layer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  237. package/package.json +53 -4
@@ -0,0 +1,257 @@
1
+ import { inOrder } from "./hit.js";
2
+ import { toRaw } from "vue";
3
+ // src/core/data.ts
4
+ /** Whether `data` is given by column. */
5
+ var byColumn = (data) => !Array.isArray(data);
6
+ /** How many rows `data` has: the length of its first column, when by column. */
7
+ function rowCount(data) {
8
+ if (!byColumn(data)) return data.length;
9
+ for (const key in data) return data[key].length;
10
+ return 0;
11
+ }
12
+ var columnRows = /* @__PURE__ */ new WeakMap();
13
+ /**
14
+ * Row `i` of `data`. A row of columns is put together when first asked
15
+ * for, and is then the same object each time.
16
+ */
17
+ function rowOf(data, i) {
18
+ if (!byColumn(data)) return data[i];
19
+ let made = columnRows.get(data);
20
+ if (!made) columnRows.set(data, made = /* @__PURE__ */ new Map());
21
+ let row = made.get(i);
22
+ if (!row) {
23
+ row = {};
24
+ for (const key in data) row[key] = data[key][i];
25
+ made.set(i, row);
26
+ }
27
+ return row;
28
+ }
29
+ var DATE = /^(\d{4})-(\d{1,2})(?:-(\d{1,2}))?(?:[ T](\d{1,2}):(\d{2})(?::(\d{2})(?:\.(\d+))?)?)?$/;
30
+ /**
31
+ * A point in time in ms, or `NaN`. Dates without a zone (`'2026-10-31'`,
32
+ * `'2026-10-31 09:30'`) are read in local time, the way people write them.
33
+ */
34
+ function toTime(value) {
35
+ if (value instanceof Date) return value.getTime();
36
+ if (typeof value === "number") return value;
37
+ if (typeof value !== "string") return NaN;
38
+ const match = DATE.exec(value.trim());
39
+ if (match) {
40
+ const [, y, mo, d, h, mi, s, ms] = match;
41
+ return new Date(Number(y), Number(mo) - 1, d ? Number(d) : 1, h ? Number(h) : 0, mi ? Number(mi) : 0, s ? Number(s) : 0, ms ? Number(ms.slice(0, 3).padEnd(3, "0")) : 0).getTime();
42
+ }
43
+ return Date.parse(value);
44
+ }
45
+ /** Reads `accessor` from `row`. */
46
+ function read(row, accessor, index) {
47
+ if (typeof accessor === "function") return accessor(row, index);
48
+ return row == null ? void 0 : row[accessor];
49
+ }
50
+ /** Places rows by their index when there is no x. */
51
+ var byIndex = (_row, index) => index;
52
+ /** Guesses how x values are meant from the first one that is there. */
53
+ function inferXKind(rows, accessor) {
54
+ const column = byColumn(rows) && typeof accessor === "string" ? rows[accessor] : null;
55
+ for (let i = 0, n = rowCount(rows); i < n; i++) {
56
+ const value = column ? column[i] : read(rowOf(rows, i), accessor, i);
57
+ if (value == null || value === "") continue;
58
+ if (typeof value === "number") return "linear";
59
+ if (value instanceof Date) return "time";
60
+ if (typeof value === "string" && DATE.test(value.trim())) return "time";
61
+ return "category";
62
+ }
63
+ return "linear";
64
+ }
65
+ var cache = /* @__PURE__ */ new WeakMap();
66
+ /** The last array a column was built from, for each scope and key. */
67
+ var latest = /* @__PURE__ */ new Map();
68
+ /** At most this many rows gone from the start, for the rest to be kept. */
69
+ var MOST_DROPPED = 4096;
70
+ /**
71
+ * How `rows` carries on from `before`: how many rows of `before` are gone
72
+ * from its start (`dropped`) and how many are kept (`kept`, the start of
73
+ * `rows`). `null` when it doesn't carry on from it.
74
+ */
75
+ function carriesOn(rows, before) {
76
+ if (!rows.length || !before.length) return null;
77
+ const first = rows[0];
78
+ let dropped = -1;
79
+ for (let i = 0, most = Math.min(before.length, MOST_DROPPED); i < most; i++) if (before[i] === first) {
80
+ dropped = i;
81
+ break;
82
+ }
83
+ if (dropped < 0) return null;
84
+ const kept = before.length - dropped;
85
+ if (kept >= rows.length) return null;
86
+ if (rows[kept - 1] !== before[before.length - 1]) return null;
87
+ if (rows[kept >> 1] !== before[dropped + (kept >> 1)]) return null;
88
+ return {
89
+ dropped,
90
+ kept
91
+ };
92
+ }
93
+ function cached(rows, scope, key, build, extend) {
94
+ let scopes = cache.get(rows);
95
+ if (!scopes) cache.set(rows, scopes = /* @__PURE__ */ new Map());
96
+ let entries = scopes.get(scope);
97
+ if (!entries) scopes.set(scope, entries = /* @__PURE__ */ new Map());
98
+ if (entries.has(key)) return entries.get(key);
99
+ const name = typeof key === "string" ? `${scope}\u0000${key}` : null;
100
+ let value = null;
101
+ const live = name && extend && !byColumn(rows);
102
+ if (live) {
103
+ const last = latest.get(name);
104
+ const before = last?.rows.deref();
105
+ const link = before && carriesOn(rows, before);
106
+ if (link) value = extend(last.value, link.dropped, link.kept);
107
+ }
108
+ value ??= build();
109
+ entries.set(key, value);
110
+ if (live && typeof WeakRef === "function") latest.set(name, {
111
+ rows: new WeakRef(rows),
112
+ value
113
+ });
114
+ return value;
115
+ }
116
+ /** Whether a column is a typed array of numbers, which can be copied at once. */
117
+ var isNumbers = (column) => ArrayBuffer.isView(column) && !(column instanceof DataView) && !(column instanceof BigInt64Array) && !(column instanceof BigUint64Array);
118
+ /** A value that isn't a number, read as one: `NaN` for none. */
119
+ function slowNumber(value) {
120
+ return value == null || value === "" ? NaN : Number(value);
121
+ }
122
+ /** Reads the x of each row from `from` on into `values`, as numbers or times (not categories). */
123
+ function readX(rows, accessor, time, from, values) {
124
+ if (accessor === byIndex) {
125
+ for (let i = from; i < values.length; i++) values[i] = i;
126
+ return;
127
+ }
128
+ if (byColumn(rows)) {
129
+ const column = typeof accessor === "string" ? toRaw(rows[accessor]) ?? [] : null;
130
+ if (from === 0 && isNumbers(column)) return values.set(column.subarray(0, values.length));
131
+ for (let i = from, n = values.length; i < n; i++) {
132
+ const value = column ? column[i] : read(rowOf(rows, i), accessor, i);
133
+ values[i] = typeof value === "number" ? value : time ? toTime(value) : slowNumber(value);
134
+ }
135
+ return;
136
+ }
137
+ const key = typeof accessor === "string" ? accessor : null;
138
+ for (let i = from; i < rows.length; i++) {
139
+ const row = rows[i];
140
+ const value = key === null ? read(row, accessor, i) : row == null ? void 0 : row[key];
141
+ values[i] = typeof value === "number" ? value : time ? toTime(value) : slowNumber(value);
142
+ }
143
+ }
144
+ /** Reads the y of each row from `from` on into `values`; anything not finite is `NaN`. */
145
+ function readY(rows, accessor, from, values) {
146
+ if (byColumn(rows)) {
147
+ const column = typeof accessor === "string" ? toRaw(rows[accessor]) ?? [] : null;
148
+ if (from === 0 && isNumbers(column)) {
149
+ values.set(column.subarray(0, values.length));
150
+ for (let i = 0; i < values.length; i++) {
151
+ const v = values[i];
152
+ if (v - v !== 0) values[i] = NaN;
153
+ }
154
+ return;
155
+ }
156
+ for (let i = from, n = values.length; i < n; i++) {
157
+ const value = column ? column[i] : read(rowOf(rows, i), accessor, i);
158
+ const v = typeof value === "number" ? value : slowNumber(value);
159
+ values[i] = v - v === 0 ? v : NaN;
160
+ }
161
+ return;
162
+ }
163
+ const key = typeof accessor === "string" ? accessor : null;
164
+ for (let i = from; i < rows.length; i++) {
165
+ const row = rows[i];
166
+ const value = key === null ? read(row, accessor, i) : row == null ? void 0 : row[key];
167
+ const n = typeof value === "number" ? value : slowNumber(value);
168
+ values[i] = n - n === 0 ? n : NaN;
169
+ }
170
+ }
171
+ /** X columns with a gap somewhere. */
172
+ var gapped = /* @__PURE__ */ new WeakSet();
173
+ /**
174
+ * The x values of `rows` as one typed array. Built once per data array,
175
+ * accessor and kind: replace the array (don't change it in place) for the
176
+ * chart to see new data.
177
+ */
178
+ function xColumn(rows, accessor, kind) {
179
+ const raw = toRaw(rows);
180
+ return cached(raw, `x:${kind}`, accessor, () => buildX(raw, accessor, kind), (before, dropped, kept) => {
181
+ if (kind === "category" || !before.sorted || gapped.has(before.values)) return null;
182
+ const values = new Float64Array(rowCount(raw));
183
+ values.set(before.values.subarray(dropped));
184
+ readX(raw, accessor, kind === "time", kept, values);
185
+ for (let i = kept; i < values.length; i++) if (!(values[i] >= values[i - 1])) return null;
186
+ inOrder(values);
187
+ return {
188
+ kind,
189
+ values,
190
+ categories: before.categories,
191
+ sorted: true
192
+ };
193
+ });
194
+ }
195
+ function buildX(rows, accessor, kind) {
196
+ const values = new Float64Array(rowCount(rows));
197
+ const categories = [];
198
+ if (kind === "category") {
199
+ const seen = /* @__PURE__ */ new Map();
200
+ const column = byColumn(rows) && typeof accessor === "string" ? rows[accessor] : null;
201
+ for (let i = 0; i < values.length; i++) {
202
+ const value = column ? column[i] : read(rowOf(rows, i), accessor, i);
203
+ const label = value == null ? "" : String(value);
204
+ let at = seen.get(label);
205
+ if (at === void 0) seen.set(label, at = categories.push(label) - 1);
206
+ values[i] = at;
207
+ }
208
+ } else readX(rows, accessor, kind === "time", 0, values);
209
+ let sorted = true;
210
+ let gaps = false;
211
+ let last = -Infinity;
212
+ for (let i = 0; i < values.length; i++) {
213
+ const n = values[i];
214
+ if (n < last) sorted = false;
215
+ if (n === n) last = n;
216
+ else gaps = true;
217
+ }
218
+ if (sorted && !gaps) inOrder(values);
219
+ if (gaps) gapped.add(values);
220
+ return {
221
+ kind,
222
+ values,
223
+ categories,
224
+ sorted
225
+ };
226
+ }
227
+ /**
228
+ * The y values of `rows` as one typed array; anything that isn't a finite
229
+ * number (`null`, a gap) is `NaN`.
230
+ */
231
+ function yColumn(rows, accessor) {
232
+ const raw = toRaw(rows);
233
+ return cached(raw, "y", accessor, () => {
234
+ const values = new Float64Array(rowCount(raw));
235
+ readY(raw, accessor, 0, values);
236
+ return values;
237
+ }, (before, dropped, kept) => {
238
+ const values = new Float64Array(rowCount(raw));
239
+ values.set(before.subarray(dropped));
240
+ readY(raw, accessor, kept, values);
241
+ return values;
242
+ });
243
+ }
244
+ /** The smallest and largest number in `values` (skipping `NaN`), or `null`. */
245
+ function extent(values, from = 0, to = values.length) {
246
+ let min = Infinity;
247
+ let max = -Infinity;
248
+ for (let i = from; i < to; i++) {
249
+ const v = values[i];
250
+ if (v < min) min = v;
251
+ if (v > max) max = v;
252
+ }
253
+ return min <= max ? [min, max] : null;
254
+ }
255
+ export { byColumn, byIndex, carriesOn, extent, inferXKind, read, rowCount, rowOf, toTime, xColumn, yColumn };
256
+
257
+ //# sourceMappingURL=data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.js","names":[],"sources":["../../src/core/data.ts"],"sourcesContent":["import { toRaw } from 'vue'\nimport { inOrder } from './hit'\n\n/** A row of chart data: usually an object, read through accessors. */\nexport type ChartRow = any\n\n/**\n * Data given by column instead of by row: a list of values for each key,\n * all as long as each other. Typed arrays (`Float64Array`) are read\n * fastest; a key reads its column, a function gets a row put together\n * from all the columns.\n */\nexport type ChartColumns = Readonly<Record<string, ArrayLike<unknown>>>\n\n/** Data as rows (objects), or as columns. */\nexport type ChartData = readonly ChartRow[] | ChartColumns\n\n/** Whether `data` is given by column. */\nexport const byColumn = (data: ChartData): data is ChartColumns => !Array.isArray(data)\n\n/** How many rows `data` has: the length of its first column, when by column. */\nexport function rowCount(data: ChartData): number {\n if (!byColumn(data)) return data.length\n for (const key in data) return data[key]!.length\n return 0\n}\n\nconst columnRows = new WeakMap<ChartColumns, Map<number, Record<string, unknown>>>()\n\n/**\n * Row `i` of `data`. A row of columns is put together when first asked\n * for, and is then the same object each time.\n */\nexport function rowOf(data: ChartData, i: number): ChartRow {\n if (!byColumn(data)) return data[i]\n let made = columnRows.get(data)\n if (!made) columnRows.set(data, (made = new Map()))\n let row = made.get(i)\n if (!row) {\n row = {}\n for (const key in data) row[key] = data[key]![i]\n made.set(i, row)\n }\n return row\n}\n\n/**\n * Picks a value from a row: a key of the row, or a function of the row and\n * its index. Prefer keys for large data: a function written inline in the\n * template is new on every render, so its column can't be cached.\n */\nexport type ChartAccessor<V = unknown> = string | ((row: ChartRow, index: number) => V)\n\n/** How x values are read: numbers, points in time (ms), or categories. */\nexport type XKind = 'linear' | 'time' | 'category'\n\nexport interface XColumn {\n kind: XKind\n /** Numbers, times in ms, or the index of each row's category in `categories`. */\n values: Float64Array\n /** For `category`: the categories in the order they first appear. */\n categories: string[]\n /** Whether `values` never go down, so the visible part can be found by bisection. */\n sorted: boolean\n}\n\nconst DATE = /^(\\d{4})-(\\d{1,2})(?:-(\\d{1,2}))?(?:[ T](\\d{1,2}):(\\d{2})(?::(\\d{2})(?:\\.(\\d+))?)?)?$/\n\n/**\n * A point in time in ms, or `NaN`. Dates without a zone (`'2026-10-31'`,\n * `'2026-10-31 09:30'`) are read in local time, the way people write them.\n */\nexport function toTime(value: unknown): number {\n if (value instanceof Date) return value.getTime()\n if (typeof value === 'number') return value\n if (typeof value !== 'string') return Number.NaN\n const match = DATE.exec(value.trim())\n if (match) {\n const [, y, mo, d, h, mi, s, ms] = match\n return new Date(\n Number(y),\n Number(mo) - 1,\n d ? Number(d) : 1,\n h ? Number(h) : 0,\n mi ? Number(mi) : 0,\n s ? Number(s) : 0,\n ms ? Number(ms.slice(0, 3).padEnd(3, '0')) : 0,\n ).getTime()\n }\n return Date.parse(value)\n}\n\n/** Reads `accessor` from `row`. */\nexport function read(row: ChartRow, accessor: ChartAccessor, index: number): unknown {\n if (typeof accessor === 'function') return accessor(row, index)\n return row == null ? undefined : (row as Record<string, unknown>)[accessor]\n}\n\n/** Places rows by their index when there is no x. */\nexport const byIndex: ChartAccessor = (_row, index) => index\n\n/** Guesses how x values are meant from the first one that is there. */\nexport function inferXKind(rows: ChartData, accessor: ChartAccessor): XKind {\n const column = byColumn(rows) && typeof accessor === 'string' ? rows[accessor] : null\n for (let i = 0, n = rowCount(rows); i < n; i++) {\n const value = column ? column[i] : read(rowOf(rows, i), accessor, i)\n if (value == null || value === '') continue\n if (typeof value === 'number') return 'linear'\n if (value instanceof Date) return 'time'\n if (typeof value === 'string' && DATE.test(value.trim())) return 'time'\n return 'category'\n }\n return 'linear'\n}\n\n/* columns, cached per data array and accessor */\n\nconst cache = new WeakMap<object, Map<string, Map<unknown, unknown>>>()\n\n/*\n * Live data comes as a new array each time: the last one with a few rows\n * added at the end, and perhaps a few gone from the start. The column of\n * the last array is then moved along and only the new rows are read.\n */\n\n/** The last array a column was built from, for each scope and key. */\nconst latest = new Map<string, { rows: WeakRef<readonly ChartRow[]>; value: unknown }>()\n/** At most this many rows gone from the start, for the rest to be kept. */\nconst MOST_DROPPED = 4096\n\n/**\n * How `rows` carries on from `before`: how many rows of `before` are gone\n * from its start (`dropped`) and how many are kept (`kept`, the start of\n * `rows`). `null` when it doesn't carry on from it.\n */\nexport function carriesOn(\n rows: readonly ChartRow[],\n before: readonly ChartRow[],\n): { dropped: number; kept: number } | null {\n if (!rows.length || !before.length) return null\n const first = rows[0]\n let dropped = -1\n for (let i = 0, most = Math.min(before.length, MOST_DROPPED); i < most; i++) {\n if (before[i] === first) {\n dropped = i\n break\n }\n }\n if (dropped < 0) return null\n const kept = before.length - dropped\n // nothing new: the rows may have been changed in place, so read them all\n if (kept >= rows.length) return null\n // the same rows at the end and in the middle: taken as the same throughout\n if (rows[kept - 1] !== before[before.length - 1]) return null\n if (rows[kept >> 1] !== before[dropped + (kept >> 1)]) return null\n return { dropped, kept }\n}\n\nfunction cached<T>(\n rows: ChartData,\n scope: string,\n key: unknown,\n build: () => T,\n /** Builds it from the column of the array `rows` carries on from. */\n extend?: (before: T, dropped: number, kept: number) => T | null,\n): T {\n let scopes = cache.get(rows)\n if (!scopes) cache.set(rows, (scopes = new Map()))\n let entries = scopes.get(scope)\n if (!entries) scopes.set(scope, (entries = new Map()))\n if (entries.has(key)) return entries.get(key) as T\n // only keys read the same row the same wherever it is: a function also gets the index\n const name = typeof key === 'string' ? `${scope}\\u0000${key}` : null\n let value: T | null = null\n // live data comes as rows\n const live = name && extend && !byColumn(rows)\n if (live) {\n const last = latest.get(name)\n const before = last?.rows.deref()\n const link = before && carriesOn(rows, before)\n if (link) value = extend(last!.value as T, link.dropped, link.kept)\n }\n value ??= build()\n entries.set(key, value)\n if (live && typeof WeakRef === 'function') latest.set(name, { rows: new WeakRef(rows), value })\n return value\n}\n\n/*\n * Reading columns: the loops below run once per row of data that may have\n * a million rows, so they read a key straight off the row and take a\n * number as it is without a call. Rows of a raw array are raw themselves,\n * so they aren't unwrapped one by one.\n */\n\ntype Numbers =\n | Float64Array\n | Float32Array\n | Int32Array\n | Uint32Array\n | Int16Array\n | Uint16Array\n | Int8Array\n | Uint8Array\n\n/** Whether a column is a typed array of numbers, which can be copied at once. */\nconst isNumbers = (column: unknown): column is Numbers =>\n ArrayBuffer.isView(column) &&\n !(column instanceof DataView) &&\n !(column instanceof BigInt64Array) &&\n !(column instanceof BigUint64Array)\n\n/** A value that isn't a number, read as one: `NaN` for none. */\nfunction slowNumber(value: unknown): number {\n return value == null || value === '' ? Number.NaN : Number(value)\n}\n\n/** Reads the x of each row from `from` on into `values`, as numbers or times (not categories). */\nfunction readX(\n rows: ChartData,\n accessor: ChartAccessor,\n time: boolean,\n from: number,\n values: Float64Array,\n) {\n if (accessor === byIndex) {\n for (let i = from; i < values.length; i++) values[i] = i\n return\n }\n if (byColumn(rows)) {\n const column = typeof accessor === 'string' ? (toRaw(rows[accessor]) ?? []) : null\n // numbers already: copied at once\n if (from === 0 && isNumbers(column)) return values.set(column.subarray(0, values.length))\n for (let i = from, n = values.length; i < n; i++) {\n const value = column ? column[i] : read(rowOf(rows, i), accessor, i)\n values[i] = typeof value === 'number' ? value : time ? toTime(value) : slowNumber(value)\n }\n return\n }\n const key = typeof accessor === 'string' ? accessor : null\n for (let i = from; i < rows.length; i++) {\n const row = rows[i]\n const value = key === null ? read(row, accessor, i) : row == null ? undefined : row[key]\n values[i] = typeof value === 'number' ? value : time ? toTime(value) : slowNumber(value)\n }\n}\n\n/** Reads the y of each row from `from` on into `values`; anything not finite is `NaN`. */\nfunction readY(rows: ChartData, accessor: ChartAccessor, from: number, values: Float64Array) {\n if (byColumn(rows)) {\n const column = typeof accessor === 'string' ? (toRaw(rows[accessor]) ?? []) : null\n if (from === 0 && isNumbers(column)) {\n values.set(column.subarray(0, values.length))\n for (let i = 0; i < values.length; i++) {\n const v = values[i]!\n if (v - v !== 0) values[i] = Number.NaN\n }\n return\n }\n for (let i = from, n = values.length; i < n; i++) {\n const value = column ? column[i] : read(rowOf(rows, i), accessor, i)\n const v = typeof value === 'number' ? value : slowNumber(value)\n values[i] = v - v === 0 ? v : Number.NaN\n }\n return\n }\n const key = typeof accessor === 'string' ? accessor : null\n for (let i = from; i < rows.length; i++) {\n const row = rows[i]\n const value = key === null ? read(row, accessor, i) : row == null ? undefined : row[key]\n const n = typeof value === 'number' ? value : slowNumber(value)\n // `n - n` is 0 only for finite numbers\n values[i] = n - n === 0 ? n : Number.NaN\n }\n}\n\n/** X columns with a gap somewhere. */\nconst gapped = new WeakSet<Float64Array>()\n\n/**\n * The x values of `rows` as one typed array. Built once per data array,\n * accessor and kind: replace the array (don't change it in place) for the\n * chart to see new data.\n */\nexport function xColumn(rows: ChartData, accessor: ChartAccessor, kind: XKind): XColumn {\n const raw = toRaw(rows)\n return cached(\n raw,\n `x:${kind}`,\n accessor,\n () => buildX(raw, accessor, kind),\n (before, dropped, kept) => {\n // categories and gaps of the dropped rows would linger: built afresh\n if (kind === 'category' || !before.sorted || gapped.has(before.values)) return null\n const values = new Float64Array(rowCount(raw))\n values.set(before.values.subarray(dropped))\n readX(raw, accessor, kind === 'time', kept, values)\n // out of order or missing: built afresh, which works out the rest\n for (let i = kept; i < values.length; i++) if (!(values[i]! >= values[i - 1]!)) return null\n inOrder(values)\n return { kind, values, categories: before.categories, sorted: true }\n },\n )\n}\n\nfunction buildX(rows: ChartData, accessor: ChartAccessor, kind: XKind): XColumn {\n const values = new Float64Array(rowCount(rows))\n const categories: string[] = []\n if (kind === 'category') {\n const seen = new Map<string, number>()\n const column = byColumn(rows) && typeof accessor === 'string' ? rows[accessor] : null\n for (let i = 0; i < values.length; i++) {\n const value = column ? column[i] : read(rowOf(rows, i), accessor, i)\n const label = value == null ? '' : String(value)\n let at = seen.get(label)\n if (at === undefined) seen.set(label, (at = categories.push(label) - 1))\n values[i] = at\n }\n } else readX(rows, accessor, kind === 'time', 0, values)\n let sorted = true\n let gaps = false\n let last = -Infinity\n for (let i = 0; i < values.length; i++) {\n const n = values[i]!\n if (n < last) sorted = false\n if (n === n) last = n\n else gaps = true\n }\n // the order hovering needs is then just as the rows come\n if (sorted && !gaps) inOrder(values)\n if (gaps) gapped.add(values)\n return { kind, values, categories, sorted }\n}\n\n/**\n * The y values of `rows` as one typed array; anything that isn't a finite\n * number (`null`, a gap) is `NaN`.\n */\nexport function yColumn(rows: ChartData, accessor: ChartAccessor): Float64Array {\n const raw = toRaw(rows)\n return cached(\n raw,\n 'y',\n accessor,\n () => {\n const values = new Float64Array(rowCount(raw))\n readY(raw, accessor, 0, values)\n return values\n },\n (before, dropped, kept) => {\n const values = new Float64Array(rowCount(raw))\n values.set(before.subarray(dropped))\n readY(raw, accessor, kept, values)\n return values\n },\n )\n}\n\n/** The smallest and largest number in `values` (skipping `NaN`), or `null`. */\nexport function extent(\n values: ArrayLike<number>,\n from = 0,\n to = values.length,\n): [number, number] | null {\n let min = Infinity\n let max = -Infinity\n for (let i = from; i < to; i++) {\n const v = values[i]!\n if (v < min) min = v\n if (v > max) max = v\n }\n return min <= max ? [min, max] : null\n}\n\n/** The first index whose value is `>= target`, in a sorted array (`NaN`s aside). */\nexport function bisect(\n values: ArrayLike<number>,\n target: number,\n lo = 0,\n hi = values.length,\n): number {\n while (lo < hi) {\n const mid = (lo + hi) >>> 1\n if (values[mid]! < target) lo = mid + 1\n else hi = mid\n }\n return lo\n}\n"],"mappings":"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"}
@@ -0,0 +1,211 @@
1
+ var pool = /* @__PURE__ */ new Int32Array(1024);
2
+ /** Points per block at the first level; each level up takes this many blocks. */
3
+ var SHIFT = 5;
4
+ var BLOCK = 32;
5
+ /** Below this many points a line is quick enough without summaries. */
6
+ var SUMMARIZED = 16384;
7
+ var summaries = /* @__PURE__ */ new WeakMap();
8
+ /** The summaries of `ys` along `xs` if they have been made. */
9
+ function summaryOf(xs, ys) {
10
+ const known = summaries.get(ys);
11
+ return known && known.xs === xs ? known.levels : null;
12
+ }
13
+ /** Makes the summaries of a sorted line long enough to need them, finest first. */
14
+ function summarize(xs, ys) {
15
+ if (Math.min(xs.length, ys.length) < SUMMARIZED) return null;
16
+ const known = summaryOf(xs, ys);
17
+ if (known) return known;
18
+ const n = Math.min(xs.length, ys.length);
19
+ const levels = [];
20
+ let count = n >> SHIFT;
21
+ let low = new Int32Array(count);
22
+ let high = new Int32Array(count);
23
+ let gap = new Uint8Array(count);
24
+ for (let b = 0; b < count; b++) {
25
+ let lo = -1;
26
+ let hi = -1;
27
+ let broken = 0;
28
+ for (let i = b << SHIFT, end = i + BLOCK; i < end; i++) {
29
+ const y = ys[i];
30
+ if (y !== y || xs[i] !== xs[i]) {
31
+ broken = 1;
32
+ continue;
33
+ }
34
+ if (lo < 0 || y < ys[lo]) lo = i;
35
+ if (hi < 0 || y > ys[hi]) hi = i;
36
+ }
37
+ low[b] = lo;
38
+ high[b] = hi;
39
+ gap[b] = broken;
40
+ }
41
+ levels.push({
42
+ size: BLOCK,
43
+ low,
44
+ high,
45
+ gap
46
+ });
47
+ while (count >= BLOCK) {
48
+ const under = levels[levels.length - 1];
49
+ count >>= SHIFT;
50
+ low = new Int32Array(count);
51
+ high = new Int32Array(count);
52
+ gap = new Uint8Array(count);
53
+ for (let b = 0; b < count; b++) {
54
+ let lo = -1;
55
+ let hi = -1;
56
+ let broken = 0;
57
+ for (let k = b << SHIFT, end = k + BLOCK; k < end; k++) {
58
+ broken |= under.gap[k];
59
+ const l = under.low[k];
60
+ const h = under.high[k];
61
+ if (l >= 0 && (lo < 0 || ys[l] < ys[lo])) lo = l;
62
+ if (h >= 0 && (hi < 0 || ys[h] > ys[hi])) hi = h;
63
+ }
64
+ low[b] = lo;
65
+ high[b] = hi;
66
+ gap[b] = broken;
67
+ }
68
+ levels.push({
69
+ size: under.size << SHIFT,
70
+ low,
71
+ high,
72
+ gap
73
+ });
74
+ }
75
+ summaries.set(ys, {
76
+ xs,
77
+ levels
78
+ });
79
+ return levels;
80
+ }
81
+ /**
82
+ * The indices from `from` to `to` (exclusive) to draw, in order, with
83
+ * `BREAK` between runs that a gap (a `NaN` y) splits. With `connect`, gaps
84
+ * are skipped instead. Columns are whole pixels of the x scale `x * k + b`.
85
+ *
86
+ * The returned array is reused by the next call: use it before calling again.
87
+ */
88
+ function decimate(xs, ys, from, to, k, b, connect = false, sorted = false) {
89
+ const levels = sorted && to - from >= SUMMARIZED ? summaryOf(xs, ys) : null;
90
+ let out = pool;
91
+ let length = 0;
92
+ const push = (index) => {
93
+ if (length === out.length) {
94
+ const bigger = new Int32Array(out.length * 2);
95
+ bigger.set(out);
96
+ out = pool = bigger;
97
+ }
98
+ out[length++] = index;
99
+ };
100
+ let column = NaN;
101
+ let first = -1;
102
+ let last = -1;
103
+ let min = -1;
104
+ let max = -1;
105
+ let low = 0;
106
+ let high = 0;
107
+ const flush = () => {
108
+ if (first < 0) return;
109
+ push(first);
110
+ const early = min < max ? min : max;
111
+ const late = min < max ? max : min;
112
+ if (early !== first && early !== last) push(early);
113
+ if (late !== first && late !== last && late !== early) push(late);
114
+ if (last !== first) push(last);
115
+ first = last = min = max = -1;
116
+ };
117
+ for (let i = from; i < to; i++) {
118
+ if (levels && (i & 31) === 0) {
119
+ let taken = false;
120
+ for (let l = levels.length - 1; l >= 0 && !taken; l--) {
121
+ const level = levels[l];
122
+ const size = level.size;
123
+ if (i % size !== 0 || i + size > to) continue;
124
+ const block = i / size;
125
+ if (level.gap[block]) continue;
126
+ const c = Math.floor(xs[i] * k + b);
127
+ if (Math.floor(xs[i + size - 1] * k + b) !== c) continue;
128
+ const lo = level.low[block];
129
+ const hi = level.high[block];
130
+ if (c !== column) {
131
+ flush();
132
+ column = c;
133
+ first = i;
134
+ min = lo;
135
+ max = hi;
136
+ low = ys[lo];
137
+ high = ys[hi];
138
+ } else {
139
+ if (ys[lo] < low) {
140
+ low = ys[lo];
141
+ min = lo;
142
+ }
143
+ if (ys[hi] > high) {
144
+ high = ys[hi];
145
+ max = hi;
146
+ }
147
+ }
148
+ last = i + size - 1;
149
+ i += size - 1;
150
+ taken = true;
151
+ }
152
+ if (taken) continue;
153
+ }
154
+ const y = ys[i];
155
+ const x = xs[i];
156
+ if (y !== y || x !== x) {
157
+ if (connect) continue;
158
+ flush();
159
+ if (length > 0 && out[length - 1] !== -1) push(-1);
160
+ column = NaN;
161
+ continue;
162
+ }
163
+ const c = Math.floor(x * k + b);
164
+ if (c !== column) {
165
+ flush();
166
+ column = c;
167
+ first = last = min = max = i;
168
+ low = high = y;
169
+ continue;
170
+ }
171
+ last = i;
172
+ if (y < low) {
173
+ low = y;
174
+ min = i;
175
+ } else if (y > high) {
176
+ high = y;
177
+ max = i;
178
+ }
179
+ }
180
+ flush();
181
+ return {
182
+ indices: out,
183
+ length
184
+ };
185
+ }
186
+ /**
187
+ * The part of a sorted x column that is on screen, widened by one point on
188
+ * each side so lines run to the edge.
189
+ */
190
+ function visibleRange(xs, sorted, lo, hi) {
191
+ if (!sorted) return [0, xs.length];
192
+ let a = 0;
193
+ let b = xs.length;
194
+ while (a < b) {
195
+ const mid = a + b >>> 1;
196
+ if (xs[mid] < lo) a = mid + 1;
197
+ else b = mid;
198
+ }
199
+ const from = Math.max(0, a - 1);
200
+ a = from;
201
+ b = xs.length;
202
+ while (a < b) {
203
+ const mid = a + b >>> 1;
204
+ if (xs[mid] <= hi) a = mid + 1;
205
+ else b = mid;
206
+ }
207
+ return [from, Math.min(xs.length, a + 1)];
208
+ }
209
+ export { decimate, summarize, visibleRange };
210
+
211
+ //# sourceMappingURL=decimate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decimate.js","names":[],"sources":["../../src/core/decimate.ts"],"sourcesContent":["/**\n * Picks the points worth drawing. A pixel column can't show more than its\n * first, lowest, highest and last point, so a line of a million points is\n * drawn from at most four per column and looks exactly the same.\n */\n\n/** Marks a break in the line: a gap in the data. */\nexport const BREAK = -1\n\nlet pool = new Int32Array(1024)\n\n/*\n * Summaries of a long sorted line, for skipping over it: for each block of\n * 32 points (then of 32 blocks, and so on) the lowest and highest point in\n * it and whether it has a gap. A block that falls in one pixel column is\n * taken whole, so a column of thousands of points costs a few dozen steps.\n * Made when the page is idle (see `prepare`), not for data that is drawn\n * once and replaced, as live data is.\n */\n\n/** Points per block at the first level; each level up takes this many blocks. */\nconst SHIFT = 5\nconst BLOCK = 1 << SHIFT\n/** Below this many points a line is quick enough without summaries. */\nconst SUMMARIZED = 1 << 14\n\ninterface Level {\n /** Points per block. */\n size: number\n /** The row of the lowest and the highest y in each block. */\n low: Int32Array\n high: Int32Array\n /** Whether a block has a gap (a `NaN` x or y). */\n gap: Uint8Array\n}\n\nconst summaries = new WeakMap<Float64Array, { xs: Float64Array; levels: Level[] }>()\n\n/** The summaries of `ys` along `xs` if they have been made. */\nfunction summaryOf(xs: Float64Array, ys: Float64Array): Level[] | null {\n const known = summaries.get(ys)\n return known && known.xs === xs ? known.levels : null\n}\n\n/** Makes the summaries of a sorted line long enough to need them, finest first. */\nexport function summarize(xs: Float64Array, ys: Float64Array): Level[] | null {\n if (Math.min(xs.length, ys.length) < SUMMARIZED) return null\n const known = summaryOf(xs, ys)\n if (known) return known\n const n = Math.min(xs.length, ys.length)\n const levels: Level[] = []\n // the first level from the points\n let count = n >> SHIFT\n let low = new Int32Array(count)\n let high = new Int32Array(count)\n let gap = new Uint8Array(count)\n for (let b = 0; b < count; b++) {\n let lo = -1\n let hi = -1\n let broken = 0\n for (let i = b << SHIFT, end = i + BLOCK; i < end; i++) {\n const y = ys[i]!\n if (y !== y || xs[i]! !== xs[i]!) {\n broken = 1\n continue\n }\n if (lo < 0 || y < ys[lo]!) lo = i\n if (hi < 0 || y > ys[hi]!) hi = i\n }\n low[b] = lo\n high[b] = hi\n gap[b] = broken\n }\n levels.push({ size: BLOCK, low, high, gap })\n // each next level from the one under it\n while (count >= BLOCK) {\n const under = levels[levels.length - 1]!\n count >>= SHIFT\n low = new Int32Array(count)\n high = new Int32Array(count)\n gap = new Uint8Array(count)\n for (let b = 0; b < count; b++) {\n let lo = -1\n let hi = -1\n let broken = 0\n for (let k = b << SHIFT, end = k + BLOCK; k < end; k++) {\n broken |= under.gap[k]!\n const l = under.low[k]!\n const h = under.high[k]!\n if (l >= 0 && (lo < 0 || ys[l]! < ys[lo]!)) lo = l\n if (h >= 0 && (hi < 0 || ys[h]! > ys[hi]!)) hi = h\n }\n low[b] = lo\n high[b] = hi\n gap[b] = broken\n }\n levels.push({ size: under.size << SHIFT, low, high, gap })\n }\n summaries.set(ys, { xs, levels })\n return levels\n}\n\n/**\n * The indices from `from` to `to` (exclusive) to draw, in order, with\n * `BREAK` between runs that a gap (a `NaN` y) splits. With `connect`, gaps\n * are skipped instead. Columns are whole pixels of the x scale `x * k + b`.\n *\n * The returned array is reused by the next call: use it before calling again.\n */\nexport function decimate(\n xs: Float64Array,\n ys: Float64Array,\n from: number,\n to: number,\n /** Pixel of x is `x * k + b`. */\n k: number,\n b: number,\n connect = false,\n /** Whether `xs` goes up from start to end: long lines can then skip whole blocks. */\n sorted = false,\n): { indices: Int32Array; length: number } {\n const levels = sorted && to - from >= SUMMARIZED ? summaryOf(xs, ys) : null\n // at most 4 per column plus a break per gap; grow when needed\n let out = pool\n let length = 0\n const push = (index: number) => {\n if (length === out.length) {\n const bigger = new Int32Array(out.length * 2)\n bigger.set(out)\n out = pool = bigger\n }\n out[length++] = index\n }\n\n let column = Number.NaN\n let first = -1\n let last = -1\n let min = -1\n let max = -1\n let low = 0\n let high = 0\n const flush = () => {\n if (first < 0) return\n push(first)\n // the lowest and highest, in the order they come\n const early = min < max ? min : max\n const late = min < max ? max : min\n if (early !== first && early !== last) push(early)\n if (late !== first && late !== last && late !== early) push(late)\n if (last !== first) push(last)\n first = last = min = max = -1\n }\n\n for (let i = from; i < to; i++) {\n // a block of points all in one column: its first, lowest, highest and last at once\n if (levels && (i & (BLOCK - 1)) === 0) {\n let taken = false\n for (let l = levels.length - 1; l >= 0 && !taken; l--) {\n const level = levels[l]!\n const size = level.size\n if (i % size !== 0 || i + size > to) continue\n const block = i / size\n if (level.gap[block]) continue\n const c = Math.floor(xs[i]! * k + b)\n if (Math.floor(xs[i + size - 1]! * k + b) !== c) continue\n const lo = level.low[block]!\n const hi = level.high[block]!\n if (c !== column) {\n flush()\n column = c\n first = i\n min = lo\n max = hi\n low = ys[lo]!\n high = ys[hi]!\n } else {\n if (ys[lo]! < low) {\n low = ys[lo]!\n min = lo\n }\n if (ys[hi]! > high) {\n high = ys[hi]!\n max = hi\n }\n }\n last = i + size - 1\n i += size - 1\n taken = true\n }\n if (taken) continue\n }\n const y = ys[i]!\n const x = xs[i]!\n if (y !== y || x !== x) {\n if (connect) continue\n flush()\n if (length > 0 && out[length - 1] !== BREAK) push(BREAK)\n column = Number.NaN\n continue\n }\n const c = Math.floor(x * k + b)\n if (c !== column) {\n flush()\n column = c\n first = last = min = max = i\n low = high = y\n continue\n }\n last = i\n if (y < low) {\n low = y\n min = i\n } else if (y > high) {\n high = y\n max = i\n }\n }\n flush()\n return { indices: out, length }\n}\n\n/**\n * The part of a sorted x column that is on screen, widened by one point on\n * each side so lines run to the edge.\n */\nexport function visibleRange(\n xs: ArrayLike<number>,\n sorted: boolean,\n lo: number,\n hi: number,\n): [number, number] {\n if (!sorted) return [0, xs.length]\n let a = 0\n let b = xs.length\n while (a < b) {\n const mid = (a + b) >>> 1\n if (xs[mid]! < lo) a = mid + 1\n else b = mid\n }\n const from = Math.max(0, a - 1)\n a = from\n b = xs.length\n while (a < b) {\n const mid = (a + b) >>> 1\n if (xs[mid]! <= hi) a = mid + 1\n else b = mid\n }\n return [from, Math.min(xs.length, a + 1)]\n}\n"],"mappings":"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"}