vvplot 0.1.3 → 0.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.
- package/README.md +2 -2
- package/dist/style.css +0 -13
- package/dist/vvplot.d.ts +307 -0
- package/dist/{Selection.js → vvplot.esm.js} +4264 -287
- package/dist/vvplot.esm.min.js +2 -0
- package/dist/vvplot.global.js +12138 -0
- package/dist/vvplot.global.min.js +2 -0
- package/package.json +7 -9
- package/dist/break.d.ts +0 -1
- package/dist/break.js +0 -118
- package/dist/components.d.ts +0 -74
- package/dist/components.js +0 -27
- package/dist/index.d.ts +0 -74
- package/dist/index.js +0 -27
- package/dist/label.d.ts +0 -1
- package/dist/label.js +0 -151
- package/dist/scale.d.ts +0 -1
- package/dist/scale.js +0 -2973
- package/dist/theme.d.ts +0 -1
- package/dist/theme.js +0 -254
- package/dist/utils.js +0 -372
package/dist/theme.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { }
|
package/dist/theme.js
DELETED
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
import { obj_merge } from "./utils.js";
|
|
2
|
-
const theme_base = {
|
|
3
|
-
axis: {
|
|
4
|
-
line_width: 1,
|
|
5
|
-
tick_width: 1,
|
|
6
|
-
tick_length: 5,
|
|
7
|
-
label_size: 12,
|
|
8
|
-
title_size: 18
|
|
9
|
-
},
|
|
10
|
-
axis_h: {
|
|
11
|
-
title_offset: 20
|
|
12
|
-
},
|
|
13
|
-
axis_v: {
|
|
14
|
-
title_offset: 30,
|
|
15
|
-
title_angle: 90
|
|
16
|
-
},
|
|
17
|
-
axis_left: {
|
|
18
|
-
tick_position: "left",
|
|
19
|
-
title_position: "left"
|
|
20
|
-
},
|
|
21
|
-
axis_right: {
|
|
22
|
-
tick_position: "right",
|
|
23
|
-
title_position: "right"
|
|
24
|
-
},
|
|
25
|
-
axis_top: {
|
|
26
|
-
tick_position: "top",
|
|
27
|
-
title_position: "top"
|
|
28
|
-
},
|
|
29
|
-
axis_bottom: {
|
|
30
|
-
tick_position: "bottom",
|
|
31
|
-
title_position: "bottom"
|
|
32
|
-
},
|
|
33
|
-
grid: {
|
|
34
|
-
line_width: 1,
|
|
35
|
-
line_width_major: 2
|
|
36
|
-
},
|
|
37
|
-
plot: {
|
|
38
|
-
margin: 20,
|
|
39
|
-
padding_h: 50,
|
|
40
|
-
padding_v: 20
|
|
41
|
-
},
|
|
42
|
-
legend: {
|
|
43
|
-
spacing: 4
|
|
44
|
-
},
|
|
45
|
-
selection: {
|
|
46
|
-
background: "#00000020"
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
const theme_default = {
|
|
50
|
-
axis: {
|
|
51
|
-
line_color: "black",
|
|
52
|
-
tick_color: "black",
|
|
53
|
-
label_color: "black",
|
|
54
|
-
title_color: "black"
|
|
55
|
-
},
|
|
56
|
-
grid: {
|
|
57
|
-
line_color: "#eeeeee"
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
const theme_light = {
|
|
61
|
-
axis: {
|
|
62
|
-
line_color: "gray",
|
|
63
|
-
tick_color: "gray",
|
|
64
|
-
label_color: "gray",
|
|
65
|
-
title_color: "gray"
|
|
66
|
-
},
|
|
67
|
-
grid: {
|
|
68
|
-
line_color: "#eeeeee"
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
const theme_gray = {
|
|
72
|
-
axis: {
|
|
73
|
-
tick_color: "black",
|
|
74
|
-
label_color: "black",
|
|
75
|
-
title_color: "black"
|
|
76
|
-
},
|
|
77
|
-
grid: {
|
|
78
|
-
line_color: "white"
|
|
79
|
-
},
|
|
80
|
-
plot: {
|
|
81
|
-
background: "#eeeeee"
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
const theme_dark = {
|
|
85
|
-
axis: {
|
|
86
|
-
tick_color: "#333333",
|
|
87
|
-
label_color: "#555555",
|
|
88
|
-
title_color: "black"
|
|
89
|
-
},
|
|
90
|
-
grid: {
|
|
91
|
-
line_color: "#666666"
|
|
92
|
-
},
|
|
93
|
-
plot: {
|
|
94
|
-
background: "#888888"
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
const theme_linedraw = {
|
|
98
|
-
axis: {
|
|
99
|
-
line_color: "black",
|
|
100
|
-
tick_color: "black",
|
|
101
|
-
label_color: "black",
|
|
102
|
-
title_color: "black"
|
|
103
|
-
},
|
|
104
|
-
grid: {
|
|
105
|
-
line_color: "black",
|
|
106
|
-
line_width_major: 1,
|
|
107
|
-
line_width_minor: 0.5
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
const theme_classic = {
|
|
111
|
-
axis: {
|
|
112
|
-
line_color: "black",
|
|
113
|
-
tick_color: "black",
|
|
114
|
-
label_color: "black",
|
|
115
|
-
title_color: "black"
|
|
116
|
-
},
|
|
117
|
-
grid: null
|
|
118
|
-
};
|
|
119
|
-
const theme_void = {
|
|
120
|
-
axis: null,
|
|
121
|
-
grid: null
|
|
122
|
-
};
|
|
123
|
-
function themeMerge(...themes) {
|
|
124
|
-
return themes.reduce((acc, t) => {
|
|
125
|
-
for (let k in t) {
|
|
126
|
-
if (t[k] === null) {
|
|
127
|
-
acc[k] = null;
|
|
128
|
-
} else {
|
|
129
|
-
acc[k] = obj_merge(acc[k], t[k]);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return acc ?? void 0;
|
|
133
|
-
}, {});
|
|
134
|
-
}
|
|
135
|
-
function themePreprocess(theme2, flip = false) {
|
|
136
|
-
let {
|
|
137
|
-
axis_h,
|
|
138
|
-
axis_v,
|
|
139
|
-
axis_x,
|
|
140
|
-
axis_y,
|
|
141
|
-
grid_h,
|
|
142
|
-
grid_v,
|
|
143
|
-
grid_x,
|
|
144
|
-
grid_y,
|
|
145
|
-
plot: {
|
|
146
|
-
margin_x,
|
|
147
|
-
margin_y,
|
|
148
|
-
margin_h,
|
|
149
|
-
margin_v,
|
|
150
|
-
padding_x,
|
|
151
|
-
padding_y,
|
|
152
|
-
padding_h,
|
|
153
|
-
padding_v,
|
|
154
|
-
...plot
|
|
155
|
-
} = {},
|
|
156
|
-
...rest
|
|
157
|
-
} = theme2;
|
|
158
|
-
if (flip) {
|
|
159
|
-
axis_h = obj_merge(axis_h, axis_y);
|
|
160
|
-
axis_v = obj_merge(axis_v, axis_x);
|
|
161
|
-
grid_h = obj_merge(grid_h, grid_x);
|
|
162
|
-
grid_v = obj_merge(grid_v, grid_y);
|
|
163
|
-
plot.margin_h = margin_y === void 0 ? margin_h : margin_y;
|
|
164
|
-
plot.margin_v = margin_x === void 0 ? margin_v : margin_x;
|
|
165
|
-
plot.padding_h = padding_y === void 0 ? padding_h : padding_y;
|
|
166
|
-
plot.padding_v = padding_x === void 0 ? padding_v : padding_x;
|
|
167
|
-
} else {
|
|
168
|
-
axis_h = obj_merge(axis_h, axis_x);
|
|
169
|
-
axis_v = obj_merge(axis_v, axis_y);
|
|
170
|
-
grid_h = obj_merge(grid_h, grid_y);
|
|
171
|
-
grid_v = obj_merge(grid_v, grid_x);
|
|
172
|
-
plot.margin_h = margin_x === void 0 ? margin_h : margin_x;
|
|
173
|
-
plot.margin_v = margin_y === void 0 ? margin_v : margin_y;
|
|
174
|
-
plot.padding_h = padding_x === void 0 ? padding_h : padding_x;
|
|
175
|
-
plot.padding_v = padding_y === void 0 ? padding_v : padding_y;
|
|
176
|
-
}
|
|
177
|
-
return {
|
|
178
|
-
axis_h,
|
|
179
|
-
axis_v,
|
|
180
|
-
grid_h,
|
|
181
|
-
grid_v,
|
|
182
|
-
plot,
|
|
183
|
-
...rest
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
function themeBuild(theme2) {
|
|
187
|
-
function _grid_build(grid_theme) {
|
|
188
|
-
return {
|
|
189
|
-
line_color_major: ["line_color", "line_color_major"].map((k) => grid_theme?.[k]).findLast((x) => x !== void 0),
|
|
190
|
-
line_color_minor: ["line_color", "line_color_minor"].map((k) => grid_theme?.[k]).findLast((x) => x !== void 0),
|
|
191
|
-
line_width_major: ["line_width", "line_width_major"].map((k) => grid_theme?.[k]).findLast((x) => x !== void 0),
|
|
192
|
-
line_width_minor: ["line_width", "line_width_minor"].map((k) => grid_theme?.[k]).findLast((x) => x !== void 0)
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
return {
|
|
196
|
-
axis: {
|
|
197
|
-
h: obj_merge(...["axis", "axis_h"].map((k) => theme2?.[k])),
|
|
198
|
-
v: obj_merge(...["axis", "axis_v"].map((k) => theme2?.[k])),
|
|
199
|
-
left: obj_merge(
|
|
200
|
-
...["axis", "axis_v", "axis_left"].map((k) => theme2?.[k])
|
|
201
|
-
),
|
|
202
|
-
right: obj_merge(
|
|
203
|
-
...["axis", "axis_v", "axis_right"].map((k) => theme2?.[k])
|
|
204
|
-
),
|
|
205
|
-
top: obj_merge(
|
|
206
|
-
...["axis", "axis_h", "axis_top"].map((k) => theme2?.[k])
|
|
207
|
-
),
|
|
208
|
-
bottom: obj_merge(
|
|
209
|
-
...["axis", "axis_h", "axis_bottom"].map((k) => theme2?.[k])
|
|
210
|
-
)
|
|
211
|
-
},
|
|
212
|
-
grid: {
|
|
213
|
-
h: _grid_build(obj_merge(...["grid", "grid_h"].map((k) => theme2?.[k]))),
|
|
214
|
-
v: _grid_build(obj_merge(...["grid", "grid_v"].map((k) => theme2?.[k])))
|
|
215
|
-
},
|
|
216
|
-
plot: {
|
|
217
|
-
margin: {
|
|
218
|
-
left: ["margin", "margin_h", "margin_left"].map((k) => theme2?.plot?.[k]).findLast((x) => x !== void 0) ?? 0,
|
|
219
|
-
right: ["margin", "margin_h", "margin_right"].map((k) => theme2?.plot?.[k]).findLast((x) => x !== void 0) ?? 0,
|
|
220
|
-
top: ["margin", "margin_v", "margin_top"].map((k) => theme2?.plot?.[k]).findLast((x) => x !== void 0) ?? 0,
|
|
221
|
-
bottom: ["margin", "margin_v", "margin_bottom"].map((k) => theme2?.plot?.[k]).findLast((x) => x !== void 0) ?? 0
|
|
222
|
-
},
|
|
223
|
-
padding: {
|
|
224
|
-
left: ["padding", "padding_h", "padding_left"].map((k) => theme2?.plot?.[k]).findLast((x) => x !== void 0) ?? 0,
|
|
225
|
-
right: ["padding", "padding_h", "padding_right"].map((k) => theme2?.plot?.[k]).findLast((x) => x !== void 0) ?? 0,
|
|
226
|
-
top: ["padding", "padding_v", "padding_top"].map((k) => theme2?.plot?.[k]).findLast((x) => x !== void 0) ?? 0,
|
|
227
|
-
bottom: ["padding", "padding_v", "padding_bottom"].map((k) => theme2?.plot?.[k]).findLast((x) => x !== void 0) ?? 0
|
|
228
|
-
},
|
|
229
|
-
background: theme2?.plot?.background
|
|
230
|
-
},
|
|
231
|
-
selection: theme2?.selection ?? {},
|
|
232
|
-
legend: {
|
|
233
|
-
spacing: theme2?.legend?.spacing ?? 0
|
|
234
|
-
}
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
const theme = {
|
|
238
|
-
base: theme_base,
|
|
239
|
-
default: theme_default,
|
|
240
|
-
light: theme_light,
|
|
241
|
-
classic: theme_classic,
|
|
242
|
-
gray: theme_gray,
|
|
243
|
-
dark: theme_dark,
|
|
244
|
-
linedraw: theme_linedraw,
|
|
245
|
-
void: theme_void
|
|
246
|
-
};
|
|
247
|
-
export {
|
|
248
|
-
theme as default,
|
|
249
|
-
themeBuild,
|
|
250
|
-
themeMerge,
|
|
251
|
-
themePreprocess,
|
|
252
|
-
theme_base,
|
|
253
|
-
theme_default
|
|
254
|
-
};
|
package/dist/utils.js
DELETED
|
@@ -1,372 +0,0 @@
|
|
|
1
|
-
class GEnumElement {
|
|
2
|
-
constructor(label, value, level) {
|
|
3
|
-
this.label = label;
|
|
4
|
-
this.value = value;
|
|
5
|
-
this.level = level;
|
|
6
|
-
}
|
|
7
|
-
toString() {
|
|
8
|
-
return this.label;
|
|
9
|
-
}
|
|
10
|
-
valueOf() {
|
|
11
|
-
return this.value;
|
|
12
|
-
}
|
|
13
|
-
toJSON() {
|
|
14
|
-
return this.label;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
class GEnumLevel extends Array {
|
|
18
|
-
/**
|
|
19
|
-
* return:
|
|
20
|
-
* x if x is a GEnumLevel
|
|
21
|
-
* new GEnumLevel from distinct values of x, ordered by natural order, if x is iterable
|
|
22
|
-
* new GEnumLevel from keys of x, orderd by coresponing values, if x is an object
|
|
23
|
-
* @param {*} x
|
|
24
|
-
* @param {function} [sortkey]
|
|
25
|
-
* @returns {GEnumLevel}
|
|
26
|
-
*/
|
|
27
|
-
static from(x) {
|
|
28
|
-
if (x instanceof this) return x;
|
|
29
|
-
if (x[Symbol.iterator]) {
|
|
30
|
-
let lvl = unique(Array.from(x).map((x2) => String(x2))).sort((a, b) => compare(a, b, { numeric: true }));
|
|
31
|
-
return new this(...lvl);
|
|
32
|
-
} else if (typeof x === "object") {
|
|
33
|
-
let lvl = Object.keys(x).map((x2) => String(x2)).sort((a, b) => compare(x[a], x[b]));
|
|
34
|
-
return new this(...lvl);
|
|
35
|
-
}
|
|
36
|
-
throw new Error(`Invalid level values: ${x}`);
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* build a GEnumLevel
|
|
40
|
-
* @param {string[]} level
|
|
41
|
-
*/
|
|
42
|
-
constructor(...level) {
|
|
43
|
-
level = level.map((x, i) => new GEnumElement(String(x), i));
|
|
44
|
-
level.forEach((l) => l.level = level);
|
|
45
|
-
level.mapping = Object.fromEntries(level.map((fct) => [fct, fct]));
|
|
46
|
-
Object.setPrototypeOf(level, GEnumLevel.prototype);
|
|
47
|
-
return level;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* get the level instance by index or key
|
|
51
|
-
* @param {(number|string)} idx
|
|
52
|
-
* @returns {GEnumElement}
|
|
53
|
-
*/
|
|
54
|
-
getItem(idx) {
|
|
55
|
-
if (typeof idx === "number" || idx instanceof Number) {
|
|
56
|
-
return this[idx];
|
|
57
|
-
} else {
|
|
58
|
-
return this.mapping[idx];
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* convert an array to a GEnum array
|
|
63
|
-
* @param {string[]} arr array to be converted, preferably a string array (items of other types will be converted to string)
|
|
64
|
-
* @returns {GEnumElement[]}
|
|
65
|
-
*/
|
|
66
|
-
apply(arr) {
|
|
67
|
-
let result = arr.map((x) => this.mapping[x]);
|
|
68
|
-
result.level = this;
|
|
69
|
-
return result;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
function isContinuous(x) {
|
|
73
|
-
return typeof x === "number" || x instanceof Number || x instanceof Date;
|
|
74
|
-
}
|
|
75
|
-
function plus(a, b = 0) {
|
|
76
|
-
if (b == 0 || a == null) return a;
|
|
77
|
-
if (a instanceof Date) return new a.constructor(+a + b);
|
|
78
|
-
return +a + b;
|
|
79
|
-
}
|
|
80
|
-
const numutils = {
|
|
81
|
-
min(arr, { na_rm = true, infinity_rm = true } = {}) {
|
|
82
|
-
if (na_rm) arr = arr.filter(isContinuous);
|
|
83
|
-
if (infinity_rm) arr = arr.filter((x) => isFinite(x));
|
|
84
|
-
return Array.from(arr).reduce((a, b) => a < b ? a : b, Infinity);
|
|
85
|
-
},
|
|
86
|
-
max(arr, { na_rm = true, infinity_rm = true } = {}) {
|
|
87
|
-
if (na_rm) arr = arr.filter(isContinuous);
|
|
88
|
-
if (infinity_rm) arr = arr.filter((x) => isFinite(x));
|
|
89
|
-
return Array.from(arr).reduce((a, b) => a > b ? a : b, -Infinity);
|
|
90
|
-
},
|
|
91
|
-
mean(arr, { na_rm = true, infinity_rm = true } = {}) {
|
|
92
|
-
if (na_rm) arr = arr.filter(isContinuous);
|
|
93
|
-
if (infinity_rm) arr = arr.filter((x) => isFinite(x));
|
|
94
|
-
if (arr.length == 0) return NaN;
|
|
95
|
-
return Array.from(arr).reduce((a, v) => a + v, 0) / arr.length;
|
|
96
|
-
},
|
|
97
|
-
sd(arr, { na_rm = true, infinity_rm = true } = {}) {
|
|
98
|
-
if (na_rm) arr = arr.filter(isContinuous);
|
|
99
|
-
if (infinity_rm) arr = arr.filter((x) => isFinite(x));
|
|
100
|
-
if (arr.length <= 1) return NaN;
|
|
101
|
-
let mean = Array.from(arr).reduce((a, v) => a + v, 0) / arr.length;
|
|
102
|
-
return Math.sqrt(Array.from(arr).reduce((a, v) => a + (v - mean) ** 2, 0) / (arr.length - 1));
|
|
103
|
-
},
|
|
104
|
-
quantile(arr, p, { na_rm = true, infinity_rm = true } = {}) {
|
|
105
|
-
if (na_rm) arr = arr.filter(isContinuous);
|
|
106
|
-
if (infinity_rm) arr = arr.filter((x) => isFinite(x));
|
|
107
|
-
if (arr.length == 0) return NaN;
|
|
108
|
-
arr = Array.from(arr).sort((a, b) => a - b);
|
|
109
|
-
let idx = (arr.length - 1) * p, lo = Math.floor(idx), hi = Math.ceil(idx);
|
|
110
|
-
if (lo == hi) return arr[lo];
|
|
111
|
-
return arr[lo] * (hi - idx) + arr[hi] * (idx - lo);
|
|
112
|
-
},
|
|
113
|
-
extent(arr, { na_rm = true, infinity_rm = true } = {}) {
|
|
114
|
-
if (na_rm) arr = arr.filter(isContinuous);
|
|
115
|
-
if (infinity_rm) arr = arr.filter((x) => isFinite(x));
|
|
116
|
-
if (arr.length == 0) return new Array(2);
|
|
117
|
-
let min = Array.from(arr).reduce((a, b) => a < b ? a : b, Infinity), max = Array.from(arr).reduce((a, b) => a > b ? a : b, -Infinity);
|
|
118
|
-
return Object.assign([min, max], { min, max });
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
const vecutils = {
|
|
122
|
-
/* vectorized summation of numbers */
|
|
123
|
-
sum(...values) {
|
|
124
|
-
if (values.some((x) => x == null)) return null;
|
|
125
|
-
if (values.some((x) => !Array.isArray(x) && typeof x != "number"))
|
|
126
|
-
throw new Error("Arguments must be numbers or arrays");
|
|
127
|
-
let nums = values.filter((x) => !Array.isArray(x)).reduce((s, a) => +a + s, 0);
|
|
128
|
-
values = values.filter((x) => Array.isArray(x));
|
|
129
|
-
if (values.length == 0)
|
|
130
|
-
return [nums];
|
|
131
|
-
if (values.some((v) => v.length == 0))
|
|
132
|
-
return [];
|
|
133
|
-
let length = values[0].length;
|
|
134
|
-
if (values.some((v) => v.length != length))
|
|
135
|
-
throw new Error("Arrays must have the same length");
|
|
136
|
-
return Array.from({ length }, (_, i) => values.reduce((s, a) => +a[i] + s, nums));
|
|
137
|
-
},
|
|
138
|
-
/* vectorized opposite of numbers */
|
|
139
|
-
opposite(value) {
|
|
140
|
-
if (value == null) return null;
|
|
141
|
-
if (!Array.isArray(value) && typeof value != "number")
|
|
142
|
-
throw new Error("Arguments must be numbers or arrays");
|
|
143
|
-
if (Array.isArray(value))
|
|
144
|
-
return value.map((v) => v == null ? v : -v);
|
|
145
|
-
return -value;
|
|
146
|
-
},
|
|
147
|
-
/* vectorized concat of strings */
|
|
148
|
-
concat(...values) {
|
|
149
|
-
if (values.some((x) => x == null)) return null;
|
|
150
|
-
let arrs = values.filter((x) => Array.isArray(x));
|
|
151
|
-
if (arrs.length == 0) return [values.join("")];
|
|
152
|
-
if (values.some((v) => v.length == 0))
|
|
153
|
-
return [];
|
|
154
|
-
let length = arrs[0].length;
|
|
155
|
-
if (arrs.some((v) => v.length != length))
|
|
156
|
-
throw new Error("Arrays must have the same length");
|
|
157
|
-
return Array.from({ length }, (_, i) => values.map((a) => Array.isArray(a) ? a[i] : a).join(""));
|
|
158
|
-
},
|
|
159
|
-
/* vectorized function application */
|
|
160
|
-
apply(func, ...values) {
|
|
161
|
-
if (values.some((x) => x == null)) return null;
|
|
162
|
-
let arrs = values.filter((x) => Array.isArray(x));
|
|
163
|
-
if (arrs.length == 0) return [func(...values)];
|
|
164
|
-
if (values.some((v) => v.length == 0))
|
|
165
|
-
return [];
|
|
166
|
-
let length = arrs[0].length;
|
|
167
|
-
if (arrs.some((v) => v.length != length))
|
|
168
|
-
throw new Error("Arrays must have the same length");
|
|
169
|
-
return Array.from({ length }, (_, i) => func(...values.map((a) => Array.isArray(a) ? a[i] : a)));
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
function obj_merge(...arr) {
|
|
173
|
-
arr = arr.filter((x) => x !== void 0);
|
|
174
|
-
if (arr.length == 0) return void 0;
|
|
175
|
-
arr = arr.slice(arr.findIndex((x) => x == null) + 1);
|
|
176
|
-
if (arr.length == 0) return null;
|
|
177
|
-
return arr.reduce((a, c) => {
|
|
178
|
-
for (let k in c) {
|
|
179
|
-
if (c[k] === null) delete a[k];
|
|
180
|
-
if (c[k] != void 0) a[k] = c[k];
|
|
181
|
-
}
|
|
182
|
-
return a;
|
|
183
|
-
}, {});
|
|
184
|
-
}
|
|
185
|
-
function str_c(...args) {
|
|
186
|
-
if (args.some((x) => x === void 0)) return void 0;
|
|
187
|
-
if (args.some((x) => x === null)) return null;
|
|
188
|
-
return args.join("");
|
|
189
|
-
}
|
|
190
|
-
function unique(arr, mapper = null) {
|
|
191
|
-
let map = /* @__PURE__ */ new Map();
|
|
192
|
-
for (let i in arr) {
|
|
193
|
-
let key = mapper ? mapper(arr[i]) : arr[i];
|
|
194
|
-
if (!map.has(key)) map.set(key, arr[i]);
|
|
195
|
-
}
|
|
196
|
-
return Array.from(map.values());
|
|
197
|
-
}
|
|
198
|
-
function compare(a, b, { numeric = false } = {}) {
|
|
199
|
-
if (typeof a != "number" || typeof b != "number")
|
|
200
|
-
return String(a).localeCompare(String(b), void 0, { numeric });
|
|
201
|
-
return a - b;
|
|
202
|
-
}
|
|
203
|
-
function emitEvent(handlers, ...args) {
|
|
204
|
-
if (Array.isArray(handlers)) {
|
|
205
|
-
handlers = handlers.filter((h) => typeof h === "function");
|
|
206
|
-
if (handlers.length === 0) return false;
|
|
207
|
-
handlers.forEach((h) => h(...args));
|
|
208
|
-
return true;
|
|
209
|
-
}
|
|
210
|
-
if (typeof handlers !== "function") return false;
|
|
211
|
-
handlers(...args);
|
|
212
|
-
return true;
|
|
213
|
-
}
|
|
214
|
-
function oob_censor(value, { min, max }) {
|
|
215
|
-
if (value < min || value > max) return NaN;
|
|
216
|
-
return value;
|
|
217
|
-
}
|
|
218
|
-
function oob_squish_any(value, { min, max }) {
|
|
219
|
-
if (value < min) return min;
|
|
220
|
-
if (value > max) return max;
|
|
221
|
-
return value;
|
|
222
|
-
}
|
|
223
|
-
function oob_squish_infinite(value, { min, max }) {
|
|
224
|
-
if (value == -Infinity) return min;
|
|
225
|
-
if (value == Infinity) return max;
|
|
226
|
-
return value;
|
|
227
|
-
}
|
|
228
|
-
function dropNull(obj) {
|
|
229
|
-
if (typeof obj !== "object" || obj == null) return obj;
|
|
230
|
-
return Object.fromEntries(Object.entries(obj).filter(([k, v]) => v != null));
|
|
231
|
-
}
|
|
232
|
-
function deepEqual(a, b) {
|
|
233
|
-
if (a === b) return true;
|
|
234
|
-
if (typeof a !== "object" || typeof b !== "object" || a == null || b == null) return false;
|
|
235
|
-
let aKeys = Object.keys(a), bKeys = Object.keys(b);
|
|
236
|
-
if (aKeys.length !== bKeys.length) return false;
|
|
237
|
-
for (let key of aKeys) {
|
|
238
|
-
if (!deepEqual(a[key], b[key])) return false;
|
|
239
|
-
}
|
|
240
|
-
return true;
|
|
241
|
-
}
|
|
242
|
-
function categorize(array) {
|
|
243
|
-
if (!Array.isArray(array)) throw new Error("Argument must be an array");
|
|
244
|
-
let categories = [], result = [];
|
|
245
|
-
for (let i = 0; i < array.length; i++) {
|
|
246
|
-
let obj = array[i];
|
|
247
|
-
let idx = categories.findIndex((cat) => deepEqual(cat, obj));
|
|
248
|
-
if (idx === -1) {
|
|
249
|
-
categories.push(obj);
|
|
250
|
-
idx = categories.length - 1;
|
|
251
|
-
}
|
|
252
|
-
result.push(idx);
|
|
253
|
-
}
|
|
254
|
-
result.categories = categories;
|
|
255
|
-
return result;
|
|
256
|
-
}
|
|
257
|
-
function interaction(...arrays) {
|
|
258
|
-
if (arrays.length == 0) return null;
|
|
259
|
-
let length = arrays.filter((x) => Array.isArray(x)).reduce((l, arr) => {
|
|
260
|
-
if (Array.isArray(arr)) {
|
|
261
|
-
if (l == null) return arr.length;
|
|
262
|
-
if (l != arr.length) throw new Error("Arrays must have the same length");
|
|
263
|
-
}
|
|
264
|
-
return l;
|
|
265
|
-
}, null) ?? 0;
|
|
266
|
-
let categories = [], result = [];
|
|
267
|
-
for (let i = 0; i < length; i++) {
|
|
268
|
-
let arr = arrays.map((x) => Array.isArray(x) ? x[i] : x);
|
|
269
|
-
let idx = categories.findIndex((x) => x.every((v, j) => v === arr[j]));
|
|
270
|
-
if (idx === -1) {
|
|
271
|
-
categories.push(arr);
|
|
272
|
-
idx = categories.length - 1;
|
|
273
|
-
}
|
|
274
|
-
result.push(idx);
|
|
275
|
-
}
|
|
276
|
-
result.categories = categories;
|
|
277
|
-
return result;
|
|
278
|
-
}
|
|
279
|
-
function intraaction(arrays) {
|
|
280
|
-
if (Object.keys(arrays).length == 0) return null;
|
|
281
|
-
let length = Object.values(arrays).filter((x) => Array.isArray(x)).reduce((l, arr) => {
|
|
282
|
-
if (Array.isArray(arr)) {
|
|
283
|
-
if (l == null) return arr.length;
|
|
284
|
-
if (l != arr.length) throw new Error("Arrays must have the same length");
|
|
285
|
-
}
|
|
286
|
-
return l;
|
|
287
|
-
}, null) ?? 0;
|
|
288
|
-
let keys = Object.keys(arrays);
|
|
289
|
-
let categories = [], result = [];
|
|
290
|
-
for (let i = 0; i < length; i++) {
|
|
291
|
-
let arr = Object.fromEntries(keys.map((k) => [k, Array.isArray(arrays[k]) ? arrays[k][i] : arrays[k]]));
|
|
292
|
-
let idx = categories.findIndex((x) => keys.every((k) => x[k] === arr[k]));
|
|
293
|
-
if (idx === -1) {
|
|
294
|
-
categories.push(arr);
|
|
295
|
-
idx = categories.length - 1;
|
|
296
|
-
}
|
|
297
|
-
result.push(idx);
|
|
298
|
-
}
|
|
299
|
-
result.categories = categories;
|
|
300
|
-
return result;
|
|
301
|
-
}
|
|
302
|
-
function intrazip(arrays) {
|
|
303
|
-
if (Object.keys(arrays).length == 0) return [];
|
|
304
|
-
let length = Object.values(arrays).filter((x) => Array.isArray(x)).reduce((l, arr) => {
|
|
305
|
-
if (Array.isArray(arr)) {
|
|
306
|
-
if (l == null) return arr.length;
|
|
307
|
-
if (l != arr.length) throw new Error("Arrays must have the same length");
|
|
308
|
-
}
|
|
309
|
-
return l;
|
|
310
|
-
}, null) ?? 0;
|
|
311
|
-
return Array.from({ length }, (_, i) => Object.fromEntries(Object.keys(arrays).map((k) => [k, Array.isArray(arrays[k]) ? arrays[k][i] : arrays[k]])));
|
|
312
|
-
}
|
|
313
|
-
function serializeSVG(svgElement) {
|
|
314
|
-
if (!(svgElement instanceof SVGElement)) return null;
|
|
315
|
-
function removeComments(node) {
|
|
316
|
-
let i = node.childNodes.length;
|
|
317
|
-
while (i--) {
|
|
318
|
-
const child = node.childNodes[i];
|
|
319
|
-
if (child.nodeType === Node.COMMENT_NODE) {
|
|
320
|
-
node.removeChild(child);
|
|
321
|
-
} else if (child.nodeType === Node.ELEMENT_NODE) {
|
|
322
|
-
removeComments(child);
|
|
323
|
-
if (child.getAttribute("style") == "") child.removeAttribute("style");
|
|
324
|
-
if (child.getAttribute("class") == "") child.removeAttribute("class");
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
let svgClone = svgElement.cloneNode(true);
|
|
329
|
-
let foreignElements = Array.from(svgElement.querySelectorAll("foreignObject")), foreignClones = Array.from(svgClone.querySelectorAll("foreignObject"));
|
|
330
|
-
for (let i = 0; i < foreignElements.length; i++) {
|
|
331
|
-
let foreignElement = foreignElements[i], foreignClone = foreignClones[i];
|
|
332
|
-
let canvas = foreignElements[i].querySelector("canvas");
|
|
333
|
-
if (!canvas) continue;
|
|
334
|
-
let img = svgClone.ownerDocument.createElementNS("http://www.w3.org/2000/svg", "image");
|
|
335
|
-
img.setAttribute("href", canvas.toDataURL());
|
|
336
|
-
img.setAttribute("x", foreignElement.getAttribute("x"));
|
|
337
|
-
img.setAttribute("y", foreignElement.getAttribute("y"));
|
|
338
|
-
img.setAttribute("width", foreignElement.getAttribute("width"));
|
|
339
|
-
img.setAttribute("height", foreignElement.getAttribute("height"));
|
|
340
|
-
foreignClone.parentNode.replaceChild(img, foreignClone);
|
|
341
|
-
}
|
|
342
|
-
for (let node of svgClone.querySelectorAll(".vvplot-interactive")) node.remove();
|
|
343
|
-
removeComments(svgClone);
|
|
344
|
-
svgClone.setAttribute("xmlns", "http://www.w3.org/2000/svg");
|
|
345
|
-
svgClone.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
|
|
346
|
-
svgClone.setAttribute("version", "1.1");
|
|
347
|
-
svgClone.setAttribute("width", svgElement.scrollWidth);
|
|
348
|
-
svgClone.setAttribute("height", svgElement.scrollHeight);
|
|
349
|
-
svgClone.setAttribute("viewBox", `0 0 ${svgElement.scrollWidth} ${svgElement.scrollHeight}`);
|
|
350
|
-
const serializer = new XMLSerializer();
|
|
351
|
-
return serializer.serializeToString(svgClone);
|
|
352
|
-
}
|
|
353
|
-
export {
|
|
354
|
-
GEnumElement,
|
|
355
|
-
GEnumLevel,
|
|
356
|
-
categorize,
|
|
357
|
-
dropNull,
|
|
358
|
-
emitEvent,
|
|
359
|
-
interaction,
|
|
360
|
-
intraaction,
|
|
361
|
-
intrazip,
|
|
362
|
-
numutils,
|
|
363
|
-
obj_merge,
|
|
364
|
-
oob_censor,
|
|
365
|
-
oob_squish_any,
|
|
366
|
-
oob_squish_infinite,
|
|
367
|
-
plus,
|
|
368
|
-
serializeSVG,
|
|
369
|
-
str_c,
|
|
370
|
-
unique,
|
|
371
|
-
vecutils
|
|
372
|
-
};
|