@dlh.io/bideux 0.1.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/LICENSE +202 -0
- package/README.md +90 -0
- package/dist/all.d.ts +14 -0
- package/dist/all.js +15 -0
- package/dist/all.js.map +1 -0
- package/dist/chunk-62IQGXLW.js +11470 -0
- package/dist/chunk-62IQGXLW.js.map +1 -0
- package/dist/chunk-75CRTQK7.js +315 -0
- package/dist/chunk-75CRTQK7.js.map +1 -0
- package/dist/chunk-FVO6E22Z.js +225 -0
- package/dist/chunk-FVO6E22Z.js.map +1 -0
- package/dist/chunk-GRITOB4M.js +337 -0
- package/dist/chunk-GRITOB4M.js.map +1 -0
- package/dist/chunk-HPFHIZWO.js +40 -0
- package/dist/chunk-HPFHIZWO.js.map +1 -0
- package/dist/chunk-IMNUQGHE.js +2864 -0
- package/dist/chunk-IMNUQGHE.js.map +1 -0
- package/dist/chunk-LHD445PJ.js +571 -0
- package/dist/chunk-LHD445PJ.js.map +1 -0
- package/dist/chunk-LPLBBHOW.js +386 -0
- package/dist/chunk-LPLBBHOW.js.map +1 -0
- package/dist/chunk-NGM5R3LW.js +881 -0
- package/dist/chunk-NGM5R3LW.js.map +1 -0
- package/dist/chunk-OMPR32AR.js +1320 -0
- package/dist/chunk-OMPR32AR.js.map +1 -0
- package/dist/chunk-QDQ5VVTC.js +255 -0
- package/dist/chunk-QDQ5VVTC.js.map +1 -0
- package/dist/chunk-RRWZKNDZ.js +1004 -0
- package/dist/chunk-RRWZKNDZ.js.map +1 -0
- package/dist/chunk-SRWIBMEB.js +178 -0
- package/dist/chunk-SRWIBMEB.js.map +1 -0
- package/dist/element/chunk-AOKCBPMV.js +1646 -0
- package/dist/element/chunk-AOKCBPMV.js.map +1 -0
- package/dist/element/chunk-B67SYRQP.js +281 -0
- package/dist/element/chunk-B67SYRQP.js.map +1 -0
- package/dist/element/chunk-FNRVFA2C.js +55 -0
- package/dist/element/chunk-FNRVFA2C.js.map +1 -0
- package/dist/element/chunk-G3C722QP.js +4707 -0
- package/dist/element/chunk-G3C722QP.js.map +1 -0
- package/dist/element/chunk-H5IFOSQP.js +346 -0
- package/dist/element/chunk-H5IFOSQP.js.map +1 -0
- package/dist/element/chunk-LXR3CLCN.js +30 -0
- package/dist/element/chunk-LXR3CLCN.js.map +1 -0
- package/dist/element/chunk-TFV4CJR4.js +183 -0
- package/dist/element/chunk-TFV4CJR4.js.map +1 -0
- package/dist/element/chunk-TXSK3CIN.js +859 -0
- package/dist/element/chunk-TXSK3CIN.js.map +1 -0
- package/dist/element/chunk-WDTTBY3S.js +45 -0
- package/dist/element/chunk-WDTTBY3S.js.map +1 -0
- package/dist/element/chunk-ZI3RYCAR.js +233 -0
- package/dist/element/chunk-ZI3RYCAR.js.map +1 -0
- package/dist/element/element.d.ts +3044 -0
- package/dist/element/element.js +146554 -0
- package/dist/element/element.js.map +1 -0
- package/dist/element/revo-grid.entry-7FHEBN3O.js +4817 -0
- package/dist/element/revo-grid.entry-7FHEBN3O.js.map +1 -0
- package/dist/element/revogr-attribution_7.entry-LSOFVZRA.js +1328 -0
- package/dist/element/revogr-attribution_7.entry-LSOFVZRA.js.map +1 -0
- package/dist/element/revogr-clipboard_3.entry-V74UIBPJ.js +494 -0
- package/dist/element/revogr-clipboard_3.entry-V74UIBPJ.js.map +1 -0
- package/dist/element/revogr-data_4.entry-2UBOKTFN.js +1041 -0
- package/dist/element/revogr-data_4.entry-2UBOKTFN.js.map +1 -0
- package/dist/element/revogr-filter-panel.entry-B24PLQU4.js +552 -0
- package/dist/element/revogr-filter-panel.entry-B24PLQU4.js.map +1 -0
- package/dist/index.d.ts +1041 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/react.d.ts +1915 -0
- package/dist/react.js +14 -0
- package/dist/react.js.map +1 -0
- package/dist/renderers/echarts.d.ts +44 -0
- package/dist/renderers/echarts.js +6 -0
- package/dist/renderers/echarts.js.map +1 -0
- package/dist/renderers/index.d.ts +48 -0
- package/dist/renderers/index.js +12 -0
- package/dist/renderers/index.js.map +1 -0
- package/dist/renderers/revogrid.d.ts +76 -0
- package/dist/renderers/revogrid.js +6 -0
- package/dist/renderers/revogrid.js.map +1 -0
- package/dist/renderers/tabulator.d.ts +37 -0
- package/dist/renderers/tabulator.js +6 -0
- package/dist/renderers/tabulator.js.map +1 -0
- package/dist/result-table-CPls-277.d.ts +1885 -0
- package/dist/schema/dashboard.schema.json +4374 -0
- package/dist/schema/semantic-model.schema.json +1200 -0
- package/dist/schema/widget.schema.json +1793 -0
- package/dist/styles.css +156 -0
- package/dist/theme.css +1789 -0
- package/dist/types-CHFSsU_X.d.ts +1007 -0
- package/package.json +119 -0
|
@@ -0,0 +1,1320 @@
|
|
|
1
|
+
import { isRecord, record, displayBlock, stringValue, rendererFrame } from './chunk-75CRTQK7.js';
|
|
2
|
+
import { format, addDays, subDays } from 'date-fns';
|
|
3
|
+
|
|
4
|
+
var AGGREGATE_FUNCTIONS = /* @__PURE__ */ new Set([
|
|
5
|
+
"min",
|
|
6
|
+
"max",
|
|
7
|
+
"median",
|
|
8
|
+
"avg",
|
|
9
|
+
"sum",
|
|
10
|
+
"count",
|
|
11
|
+
"first",
|
|
12
|
+
"last"
|
|
13
|
+
]);
|
|
14
|
+
var MATH_FUNCTIONS = {
|
|
15
|
+
abs: (v) => Math.abs(toNumber(v)),
|
|
16
|
+
round: (v) => Math.round(toNumber(v)),
|
|
17
|
+
floor: (v) => Math.floor(toNumber(v)),
|
|
18
|
+
ceil: (v) => Math.ceil(toNumber(v)),
|
|
19
|
+
float: (v) => Number(v),
|
|
20
|
+
int: (v) => Math.trunc(toNumber(v)),
|
|
21
|
+
len: (v) => Array.isArray(v) ? v.length : String(v).length,
|
|
22
|
+
today: (fmt) => format(/* @__PURE__ */ new Date(), typeof fmt === "string" && fmt ? fmt : "yyyy-MM-dd"),
|
|
23
|
+
yesterday: (fmt) => format(
|
|
24
|
+
subDays(/* @__PURE__ */ new Date(), 1),
|
|
25
|
+
typeof fmt === "string" && fmt ? fmt : "yyyy-MM-dd"
|
|
26
|
+
),
|
|
27
|
+
tomorrow: (fmt) => format(
|
|
28
|
+
addDays(/* @__PURE__ */ new Date(), 1),
|
|
29
|
+
typeof fmt === "string" && fmt ? fmt : "yyyy-MM-dd"
|
|
30
|
+
),
|
|
31
|
+
now: () => (/* @__PURE__ */ new Date()).toISOString()
|
|
32
|
+
};
|
|
33
|
+
function tokenize(input) {
|
|
34
|
+
const tokens = [];
|
|
35
|
+
const regex = /\s*(\d+(?:\.\d+)?(?:[eE][+-]?\d+)?|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|\$\{[A-Za-z_][A-Za-z0-9_]*\}|&&|\|\||==|!=|<=|>=|\*\*|[+\-*/%<>,!():.[\]{}]|[A-Za-z_][A-Za-z0-9_]*)\s*/y;
|
|
36
|
+
while (regex.lastIndex < input.length) {
|
|
37
|
+
const match = regex.exec(input);
|
|
38
|
+
if (!match) {
|
|
39
|
+
throw new Error(`Unexpected character at position ${regex.lastIndex}`);
|
|
40
|
+
}
|
|
41
|
+
const captured = match[1];
|
|
42
|
+
if (captured === void 0) {
|
|
43
|
+
throw new Error(`Unexpected character at position ${regex.lastIndex}`);
|
|
44
|
+
}
|
|
45
|
+
let value = captured;
|
|
46
|
+
let type;
|
|
47
|
+
let raw = value;
|
|
48
|
+
if (/^\$\{/.test(value)) {
|
|
49
|
+
type = "variable";
|
|
50
|
+
value = value.slice(2, -1);
|
|
51
|
+
raw = value;
|
|
52
|
+
} else if (/^\d/.test(value)) {
|
|
53
|
+
type = "number";
|
|
54
|
+
raw = Number(value);
|
|
55
|
+
} else if (value === "true" || value === "false") {
|
|
56
|
+
type = "boolean";
|
|
57
|
+
raw = value === "true";
|
|
58
|
+
} else if (value === "null") {
|
|
59
|
+
type = "null";
|
|
60
|
+
raw = null;
|
|
61
|
+
} else if (/^"|'/.test(value)) {
|
|
62
|
+
type = "string";
|
|
63
|
+
raw = value.slice(1, -1).replace(/\\(.)/g, (_, ch) => {
|
|
64
|
+
switch (ch) {
|
|
65
|
+
case "n":
|
|
66
|
+
return "\n";
|
|
67
|
+
case "t":
|
|
68
|
+
return " ";
|
|
69
|
+
case "r":
|
|
70
|
+
return "\r";
|
|
71
|
+
default:
|
|
72
|
+
return ch;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
} else if (/^[A-Za-z_]/.test(value)) {
|
|
76
|
+
type = "identifier";
|
|
77
|
+
} else if (/^[+\-*/%<>=!&|*]+$/.test(value)) {
|
|
78
|
+
type = "operator";
|
|
79
|
+
} else {
|
|
80
|
+
type = "punct";
|
|
81
|
+
}
|
|
82
|
+
tokens.push({ type, value, raw });
|
|
83
|
+
}
|
|
84
|
+
return tokens;
|
|
85
|
+
}
|
|
86
|
+
var Parser = class {
|
|
87
|
+
constructor(tokens) {
|
|
88
|
+
this.tokens = tokens;
|
|
89
|
+
}
|
|
90
|
+
pos = 0;
|
|
91
|
+
parse() {
|
|
92
|
+
const node = this.logicalOr();
|
|
93
|
+
if (this.pos < this.tokens.length) {
|
|
94
|
+
const token = this.current();
|
|
95
|
+
if (token === void 0) {
|
|
96
|
+
throw new Error("Unexpected end of expression");
|
|
97
|
+
}
|
|
98
|
+
throw new Error(
|
|
99
|
+
`Unexpected token '${token.value}' at position ${this.pos}`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
return node;
|
|
103
|
+
}
|
|
104
|
+
current() {
|
|
105
|
+
return this.tokens[this.pos];
|
|
106
|
+
}
|
|
107
|
+
peek(offset = 0) {
|
|
108
|
+
return this.tokens[this.pos + offset];
|
|
109
|
+
}
|
|
110
|
+
eat(value) {
|
|
111
|
+
if (this.current()?.value !== value) {
|
|
112
|
+
throw new Error(
|
|
113
|
+
`Expected '${value}' but got '${this.current()?.value ?? "EOF"}'`
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
this.pos++;
|
|
117
|
+
}
|
|
118
|
+
matchOperator(...ops) {
|
|
119
|
+
const token = this.current();
|
|
120
|
+
if (token?.type === "operator" && ops.includes(token.value)) {
|
|
121
|
+
this.pos++;
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
previousOperator(fallback) {
|
|
127
|
+
return this.tokens[this.pos - 1]?.value ?? fallback;
|
|
128
|
+
}
|
|
129
|
+
logicalOr() {
|
|
130
|
+
let left = this.logicalAnd();
|
|
131
|
+
while (this.matchOperator("||")) {
|
|
132
|
+
const right = this.logicalAnd();
|
|
133
|
+
left = { kind: "binary", op: "||", left, right };
|
|
134
|
+
}
|
|
135
|
+
return left;
|
|
136
|
+
}
|
|
137
|
+
logicalAnd() {
|
|
138
|
+
let left = this.equality();
|
|
139
|
+
while (this.matchOperator("&&")) {
|
|
140
|
+
const right = this.equality();
|
|
141
|
+
left = { kind: "binary", op: "&&", left, right };
|
|
142
|
+
}
|
|
143
|
+
return left;
|
|
144
|
+
}
|
|
145
|
+
equality() {
|
|
146
|
+
let left = this.comparison();
|
|
147
|
+
while (this.matchOperator("==", "!=")) {
|
|
148
|
+
const op = this.previousOperator("==");
|
|
149
|
+
const right = this.comparison();
|
|
150
|
+
left = { kind: "binary", op, left, right };
|
|
151
|
+
}
|
|
152
|
+
return left;
|
|
153
|
+
}
|
|
154
|
+
comparison() {
|
|
155
|
+
let left = this.additive();
|
|
156
|
+
while (this.matchOperator("<", "<=", ">", ">=")) {
|
|
157
|
+
const op = this.previousOperator("<");
|
|
158
|
+
const right = this.additive();
|
|
159
|
+
left = { kind: "binary", op, left, right };
|
|
160
|
+
}
|
|
161
|
+
return left;
|
|
162
|
+
}
|
|
163
|
+
additive() {
|
|
164
|
+
let left = this.multiplicative();
|
|
165
|
+
while (this.matchOperator("+", "-")) {
|
|
166
|
+
const op = this.previousOperator("+");
|
|
167
|
+
const right = this.multiplicative();
|
|
168
|
+
left = { kind: "binary", op, left, right };
|
|
169
|
+
}
|
|
170
|
+
return left;
|
|
171
|
+
}
|
|
172
|
+
multiplicative() {
|
|
173
|
+
let left = this.power();
|
|
174
|
+
while (this.matchOperator("*", "/", "%")) {
|
|
175
|
+
const op = this.previousOperator("*");
|
|
176
|
+
const right = this.power();
|
|
177
|
+
left = { kind: "binary", op, left, right };
|
|
178
|
+
}
|
|
179
|
+
return left;
|
|
180
|
+
}
|
|
181
|
+
power() {
|
|
182
|
+
let left = this.unary();
|
|
183
|
+
while (this.matchOperator("**")) {
|
|
184
|
+
const right = this.unary();
|
|
185
|
+
left = { kind: "binary", op: "**", left, right };
|
|
186
|
+
}
|
|
187
|
+
return left;
|
|
188
|
+
}
|
|
189
|
+
unary() {
|
|
190
|
+
if (this.matchOperator("+", "-", "!")) {
|
|
191
|
+
const token = this.tokens[this.pos - 1];
|
|
192
|
+
if (token === void 0) {
|
|
193
|
+
throw new Error("Unexpected end of expression");
|
|
194
|
+
}
|
|
195
|
+
const op = token.value;
|
|
196
|
+
const right = this.unary();
|
|
197
|
+
return { kind: "unary", op, right };
|
|
198
|
+
}
|
|
199
|
+
return this.primary();
|
|
200
|
+
}
|
|
201
|
+
primary() {
|
|
202
|
+
const token = this.current();
|
|
203
|
+
if (!token) throw new Error("Unexpected end of expression");
|
|
204
|
+
if (token.type === "number") {
|
|
205
|
+
this.pos++;
|
|
206
|
+
return { kind: "number", value: Number(token.raw) };
|
|
207
|
+
}
|
|
208
|
+
if (token.type === "variable") {
|
|
209
|
+
this.pos++;
|
|
210
|
+
return { kind: "variable", name: token.value };
|
|
211
|
+
}
|
|
212
|
+
if (token.type === "string") {
|
|
213
|
+
this.pos++;
|
|
214
|
+
return { kind: "string", value: String(token.raw) };
|
|
215
|
+
}
|
|
216
|
+
if (token.type === "boolean") {
|
|
217
|
+
this.pos++;
|
|
218
|
+
return { kind: "boolean", value: Boolean(token.raw) };
|
|
219
|
+
}
|
|
220
|
+
if (token.type === "null") {
|
|
221
|
+
this.pos++;
|
|
222
|
+
return { kind: "null" };
|
|
223
|
+
}
|
|
224
|
+
if (token.type === "identifier") {
|
|
225
|
+
this.pos++;
|
|
226
|
+
const name = token.value;
|
|
227
|
+
if (this.current()?.value === "(") {
|
|
228
|
+
this.eat("(");
|
|
229
|
+
const args = [];
|
|
230
|
+
if (this.current()?.value !== ")") {
|
|
231
|
+
args.push(this.logicalOr());
|
|
232
|
+
while (this.current()?.value === ",") {
|
|
233
|
+
this.eat(",");
|
|
234
|
+
args.push(this.logicalOr());
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
this.eat(")");
|
|
238
|
+
return { kind: "call", name, args };
|
|
239
|
+
}
|
|
240
|
+
if (this.current()?.value === "." && (name === "rows" || name === "row")) {
|
|
241
|
+
this.eat(".");
|
|
242
|
+
const fieldToken = this.current();
|
|
243
|
+
if (fieldToken?.type !== "identifier") {
|
|
244
|
+
throw new Error(`Expected field name after '${name}.'`);
|
|
245
|
+
}
|
|
246
|
+
this.pos++;
|
|
247
|
+
if (name === "row") {
|
|
248
|
+
return { kind: "rowField", name: fieldToken.value };
|
|
249
|
+
}
|
|
250
|
+
return { kind: "rowsField", name: fieldToken.value };
|
|
251
|
+
}
|
|
252
|
+
return { kind: "identifier", name };
|
|
253
|
+
}
|
|
254
|
+
if (token.value === "(") {
|
|
255
|
+
this.eat("(");
|
|
256
|
+
const node = this.logicalOr();
|
|
257
|
+
this.eat(")");
|
|
258
|
+
return node;
|
|
259
|
+
}
|
|
260
|
+
throw new Error(`Unexpected token '${token.value}'`);
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
function toNumber(value) {
|
|
264
|
+
if (typeof value === "number") return value;
|
|
265
|
+
if (typeof value === "boolean") return value ? 1 : 0;
|
|
266
|
+
if (value === null || value === void 0) return 0;
|
|
267
|
+
const parsed = Number(value);
|
|
268
|
+
return Number.isNaN(parsed) ? 0 : parsed;
|
|
269
|
+
}
|
|
270
|
+
function toString(value) {
|
|
271
|
+
if (value === null || value === void 0) return "";
|
|
272
|
+
if (typeof value === "string") return value;
|
|
273
|
+
return String(value);
|
|
274
|
+
}
|
|
275
|
+
function isTruthy(value) {
|
|
276
|
+
if (typeof value === "boolean") return value;
|
|
277
|
+
if (typeof value === "number") return value !== 0;
|
|
278
|
+
if (typeof value === "string") return value.length > 0;
|
|
279
|
+
if (Array.isArray(value)) return value.length > 0;
|
|
280
|
+
return value !== null && value !== void 0;
|
|
281
|
+
}
|
|
282
|
+
function compareEqual(left, right) {
|
|
283
|
+
if (left === null || left === void 0)
|
|
284
|
+
return right === null || right === void 0;
|
|
285
|
+
if (right === null || right === void 0) return false;
|
|
286
|
+
if (typeof left === "number" && typeof right === "number")
|
|
287
|
+
return left === right;
|
|
288
|
+
return String(left) === String(right);
|
|
289
|
+
}
|
|
290
|
+
function evaluateNode(node, context) {
|
|
291
|
+
switch (node.kind) {
|
|
292
|
+
case "number":
|
|
293
|
+
return node.value;
|
|
294
|
+
case "string":
|
|
295
|
+
return node.value;
|
|
296
|
+
case "boolean":
|
|
297
|
+
return node.value;
|
|
298
|
+
case "null":
|
|
299
|
+
return null;
|
|
300
|
+
case "variable": {
|
|
301
|
+
const variables = context.variables ?? {};
|
|
302
|
+
if (node.name in variables) return variables[node.name];
|
|
303
|
+
throw new Error(`Unknown variable '${node.name}'`);
|
|
304
|
+
}
|
|
305
|
+
case "identifier": {
|
|
306
|
+
const variables = context.variables ?? {};
|
|
307
|
+
if (node.name in variables) return variables[node.name];
|
|
308
|
+
if (context.row && node.name in context.row)
|
|
309
|
+
return context.row[node.name];
|
|
310
|
+
if (context.rows && context.rows.length > 0) {
|
|
311
|
+
const sample = context.rows[0];
|
|
312
|
+
if (sample !== void 0 && node.name in sample) {
|
|
313
|
+
return context.row?.[node.name];
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
throw new Error(`Unknown identifier '${node.name}'`);
|
|
317
|
+
}
|
|
318
|
+
case "rowField":
|
|
319
|
+
if (!context.row)
|
|
320
|
+
throw new Error("'row.field' is only valid inside a filter context");
|
|
321
|
+
return context.row[node.name];
|
|
322
|
+
case "rowsField": {
|
|
323
|
+
const rows = context.rows ?? [];
|
|
324
|
+
return rows.map((row) => row[node.name]);
|
|
325
|
+
}
|
|
326
|
+
case "call": {
|
|
327
|
+
const argValues = node.args.map((arg) => evaluateNode(arg, context));
|
|
328
|
+
if (AGGREGATE_FUNCTIONS.has(node.name)) {
|
|
329
|
+
return evaluateAggregate(node.name, argValues);
|
|
330
|
+
}
|
|
331
|
+
const fn = MATH_FUNCTIONS[node.name];
|
|
332
|
+
if (fn) return fn(argValues[0]);
|
|
333
|
+
throw new Error(`Unknown function '${node.name}'`);
|
|
334
|
+
}
|
|
335
|
+
case "unary": {
|
|
336
|
+
const right = evaluateNode(node.right, context);
|
|
337
|
+
if (node.op === "!") return !isTruthy(right);
|
|
338
|
+
const num = toNumber(right);
|
|
339
|
+
return node.op === "-" ? -num : num;
|
|
340
|
+
}
|
|
341
|
+
case "binary": {
|
|
342
|
+
const left = evaluateNode(node.left, context);
|
|
343
|
+
const right = evaluateNode(node.right, context);
|
|
344
|
+
switch (node.op) {
|
|
345
|
+
case "||":
|
|
346
|
+
return isTruthy(left) || isTruthy(right);
|
|
347
|
+
case "&&":
|
|
348
|
+
return isTruthy(left) && isTruthy(right);
|
|
349
|
+
case "==":
|
|
350
|
+
return compareEqual(left, right);
|
|
351
|
+
case "!=":
|
|
352
|
+
return !compareEqual(left, right);
|
|
353
|
+
case "<":
|
|
354
|
+
return toNumber(left) < toNumber(right);
|
|
355
|
+
case "<=":
|
|
356
|
+
return toNumber(left) <= toNumber(right);
|
|
357
|
+
case ">":
|
|
358
|
+
return toNumber(left) > toNumber(right);
|
|
359
|
+
case ">=":
|
|
360
|
+
return toNumber(left) >= toNumber(right);
|
|
361
|
+
case "+":
|
|
362
|
+
if (typeof left === "string" || typeof right === "string") {
|
|
363
|
+
return toString(left) + toString(right);
|
|
364
|
+
}
|
|
365
|
+
return toNumber(left) + toNumber(right);
|
|
366
|
+
case "-":
|
|
367
|
+
return toNumber(left) - toNumber(right);
|
|
368
|
+
case "*":
|
|
369
|
+
return toNumber(left) * toNumber(right);
|
|
370
|
+
case "/": {
|
|
371
|
+
const divisor = toNumber(right);
|
|
372
|
+
return divisor === 0 ? 0 : toNumber(left) / divisor;
|
|
373
|
+
}
|
|
374
|
+
case "%": {
|
|
375
|
+
const mod = toNumber(right);
|
|
376
|
+
return mod === 0 ? 0 : toNumber(left) % mod;
|
|
377
|
+
}
|
|
378
|
+
case "**":
|
|
379
|
+
return toNumber(left) ** toNumber(right);
|
|
380
|
+
default:
|
|
381
|
+
throw new Error(`Unknown operator '${node.op}'`);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
default:
|
|
385
|
+
throw new Error("Unknown expression node");
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
function evaluateAggregate(name, args) {
|
|
389
|
+
if (args.length === 0) return null;
|
|
390
|
+
const values = args[0];
|
|
391
|
+
if (!Array.isArray(values)) {
|
|
392
|
+
throw new Error(`Aggregate '${name}' requires a row vector argument`);
|
|
393
|
+
}
|
|
394
|
+
const numeric = values.map(
|
|
395
|
+
(v) => v === null || v === void 0 ? NaN : Number(v)
|
|
396
|
+
);
|
|
397
|
+
const finite = numeric.filter((n) => Number.isFinite(n));
|
|
398
|
+
switch (name) {
|
|
399
|
+
case "min":
|
|
400
|
+
return finite.length ? Math.min(...finite) : null;
|
|
401
|
+
case "max":
|
|
402
|
+
return finite.length ? Math.max(...finite) : null;
|
|
403
|
+
case "sum":
|
|
404
|
+
return finite.reduce((a, b) => a + b, 0);
|
|
405
|
+
case "avg":
|
|
406
|
+
return finite.length ? finite.reduce((a, b) => a + b, 0) / finite.length : null;
|
|
407
|
+
case "count":
|
|
408
|
+
return values.filter((v) => v !== null && v !== void 0 && v !== "").length;
|
|
409
|
+
case "first":
|
|
410
|
+
return values[0] ?? null;
|
|
411
|
+
case "last":
|
|
412
|
+
return values[values.length - 1] ?? null;
|
|
413
|
+
case "median": {
|
|
414
|
+
if (!finite.length) return null;
|
|
415
|
+
const sorted = [...finite].sort((a, b) => a - b);
|
|
416
|
+
const mid = Math.floor(sorted.length / 2);
|
|
417
|
+
if (sorted.length % 2) return sorted[mid];
|
|
418
|
+
const lower = sorted[mid - 1];
|
|
419
|
+
const upper = sorted[mid];
|
|
420
|
+
if (lower === void 0 || upper === void 0) return null;
|
|
421
|
+
return (lower + upper) / 2;
|
|
422
|
+
}
|
|
423
|
+
default:
|
|
424
|
+
throw new Error(`Unknown aggregate '${name}'`);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
function interpolateTemplate(template, variables) {
|
|
428
|
+
return template.replace(/\$\{([^}]+)\}/g, (_, name) => {
|
|
429
|
+
if (!(name in variables)) throw new Error(`Unknown variable '${name}'`);
|
|
430
|
+
const value = variables[name];
|
|
431
|
+
return value === null || value === void 0 ? "" : String(value);
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
function interpolateVariables(value, variables) {
|
|
435
|
+
if (typeof value === "string") {
|
|
436
|
+
if (!value.includes("${")) return value;
|
|
437
|
+
const interpolated = interpolateTemplate(value, variables);
|
|
438
|
+
if (/^\$\{[^}]+\}$/.test(value)) {
|
|
439
|
+
const name = value.slice(2, -1);
|
|
440
|
+
const raw = variables[name];
|
|
441
|
+
if (typeof raw === "number" || typeof raw === "boolean" || raw === null) {
|
|
442
|
+
return raw;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
if (/^-?\d+(\.\d+)?$/.test(interpolated) && !Number.isNaN(Number(interpolated))) {
|
|
446
|
+
return Number(interpolated);
|
|
447
|
+
}
|
|
448
|
+
return interpolated;
|
|
449
|
+
}
|
|
450
|
+
if (Array.isArray(value)) {
|
|
451
|
+
return value.map((item) => interpolateVariables(item, variables));
|
|
452
|
+
}
|
|
453
|
+
if (value !== null && typeof value === "object") {
|
|
454
|
+
const record2 = value;
|
|
455
|
+
return Object.fromEntries(
|
|
456
|
+
Object.entries(record2).map(([k, v]) => [
|
|
457
|
+
k,
|
|
458
|
+
interpolateVariables(v, variables)
|
|
459
|
+
])
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
return value;
|
|
463
|
+
}
|
|
464
|
+
function evaluateExpression(expression, context) {
|
|
465
|
+
const tokens = tokenize(expression);
|
|
466
|
+
const parser = new Parser(tokens);
|
|
467
|
+
const node = parser.parse();
|
|
468
|
+
return evaluateNode(node, context);
|
|
469
|
+
}
|
|
470
|
+
function evaluateVariables(variables, rows, existingVariables) {
|
|
471
|
+
if (!variables) return {};
|
|
472
|
+
const result = { ...existingVariables ?? {} };
|
|
473
|
+
for (const [name, expression] of Object.entries(variables)) {
|
|
474
|
+
result[name] = evaluateExpression(expression, { rows, variables: result });
|
|
475
|
+
}
|
|
476
|
+
return result;
|
|
477
|
+
}
|
|
478
|
+
function applyFilter(filter, rows, variables) {
|
|
479
|
+
if (!filter) return rows;
|
|
480
|
+
return rows.filter(
|
|
481
|
+
(row) => isTruthy(evaluateExpression(filter, { rows, row, variables }))
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
function dateBuiltinVariables() {
|
|
485
|
+
const today = /* @__PURE__ */ new Date();
|
|
486
|
+
return {
|
|
487
|
+
today: format(today, "yyyy-MM-dd"),
|
|
488
|
+
yesterday: format(subDays(today, 1), "yyyy-MM-dd"),
|
|
489
|
+
tomorrow: format(addDays(today, 1), "yyyy-MM-dd"),
|
|
490
|
+
now: today.toISOString()
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
function resolveFilterDefault(defaultValue, extraVariables) {
|
|
494
|
+
if (defaultValue === void 0 || defaultValue === null) return "";
|
|
495
|
+
if (typeof defaultValue !== "string") return defaultValue;
|
|
496
|
+
const variables = { ...dateBuiltinVariables(), ...extraVariables ?? {} };
|
|
497
|
+
const trimmed = defaultValue.trim();
|
|
498
|
+
if (trimmed.startsWith("=")) {
|
|
499
|
+
try {
|
|
500
|
+
return evaluateExpression(trimmed.slice(1).trim(), { variables });
|
|
501
|
+
} catch {
|
|
502
|
+
return defaultValue;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
if (defaultValue.includes("${")) {
|
|
506
|
+
try {
|
|
507
|
+
return interpolateVariables(defaultValue, variables);
|
|
508
|
+
} catch {
|
|
509
|
+
return defaultValue;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
return defaultValue;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// ../dashboard-renderers/src/value-format.ts
|
|
516
|
+
var compactFormatter = new Intl.NumberFormat("en-US", {
|
|
517
|
+
notation: "compact",
|
|
518
|
+
maximumFractionDigits: 1
|
|
519
|
+
});
|
|
520
|
+
var exactFormatter = new Intl.NumberFormat("en-US", {
|
|
521
|
+
maximumFractionDigits: 2
|
|
522
|
+
});
|
|
523
|
+
var NAMED_FORMATS = /* @__PURE__ */ new Set(["percent", "currency", "number"]);
|
|
524
|
+
function formatCompactNumber(value) {
|
|
525
|
+
if (!Number.isFinite(value)) return "";
|
|
526
|
+
if (Math.abs(value) < 1e3) return exactFormatter.format(value);
|
|
527
|
+
return compactFormatter.format(value);
|
|
528
|
+
}
|
|
529
|
+
function formatValue(value, options = {}) {
|
|
530
|
+
if (value === void 0 || value === null) return "-";
|
|
531
|
+
const format2 = options.format ?? "number";
|
|
532
|
+
const notation = options.compact === true ? "compact" : "standard";
|
|
533
|
+
const places = typeof options.decimals === "number" && options.decimals >= 0 && options.decimals <= 20 ? Math.floor(options.decimals) : void 0;
|
|
534
|
+
const wrap = (text) => (options.prefix ?? "") + text + (options.suffix ?? "");
|
|
535
|
+
if (format2 === "currency") {
|
|
536
|
+
const currencyOptions = {
|
|
537
|
+
minimumFractionDigits: places ?? 2,
|
|
538
|
+
maximumFractionDigits: places ?? 2,
|
|
539
|
+
notation
|
|
540
|
+
};
|
|
541
|
+
if (options.compact === true) currencyOptions.compactDisplay = "short";
|
|
542
|
+
return wrap(new Intl.NumberFormat("en-US", currencyOptions).format(value));
|
|
543
|
+
}
|
|
544
|
+
if (format2 === "percent") {
|
|
545
|
+
return wrap(
|
|
546
|
+
new Intl.NumberFormat("en-US", {
|
|
547
|
+
style: "percent",
|
|
548
|
+
minimumFractionDigits: places,
|
|
549
|
+
maximumFractionDigits: places ?? 1
|
|
550
|
+
}).format(value)
|
|
551
|
+
);
|
|
552
|
+
}
|
|
553
|
+
const numberOptions = { notation };
|
|
554
|
+
if (options.compact === true) numberOptions.compactDisplay = "short";
|
|
555
|
+
if (places !== void 0) {
|
|
556
|
+
numberOptions.minimumFractionDigits = places;
|
|
557
|
+
numberOptions.maximumFractionDigits = places;
|
|
558
|
+
}
|
|
559
|
+
return wrap(new Intl.NumberFormat("en-US", numberOptions).format(value));
|
|
560
|
+
}
|
|
561
|
+
function namedFormatter(name) {
|
|
562
|
+
return (value) => formatValue(Number(value), { format: name, decimals: 1 });
|
|
563
|
+
}
|
|
564
|
+
function withNamedAxisFormatter(axis) {
|
|
565
|
+
if (!isRecord(axis)) return axis;
|
|
566
|
+
const label = isRecord(axis.axisLabel) ? { ...axis.axisLabel } : void 0;
|
|
567
|
+
if (label === void 0 || typeof label.formatter !== "string" || !NAMED_FORMATS.has(label.formatter)) {
|
|
568
|
+
return axis;
|
|
569
|
+
}
|
|
570
|
+
return {
|
|
571
|
+
...axis,
|
|
572
|
+
axisLabel: { ...label, formatter: namedFormatter(label.formatter) }
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
function applyNamedFormatters(option) {
|
|
576
|
+
const next = { ...option };
|
|
577
|
+
for (const key of ["xAxis", "yAxis"]) {
|
|
578
|
+
const axes = option[key];
|
|
579
|
+
if (axes === void 0) continue;
|
|
580
|
+
next[key] = Array.isArray(axes) ? axes.map(withNamedAxisFormatter) : withNamedAxisFormatter(axes);
|
|
581
|
+
}
|
|
582
|
+
if (isRecord(option.tooltip)) {
|
|
583
|
+
const formatter = option.tooltip.valueFormatter;
|
|
584
|
+
if (typeof formatter === "string" && NAMED_FORMATS.has(formatter)) {
|
|
585
|
+
next.tooltip = {
|
|
586
|
+
...option.tooltip,
|
|
587
|
+
valueFormatter: namedFormatter(formatter)
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
return next;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// ../dashboard-renderers/src/chart-defaults.ts
|
|
595
|
+
var ZOOM_THRESHOLD = 60;
|
|
596
|
+
var ROTATE_LABEL_COUNT = 6;
|
|
597
|
+
var LONG_LABEL_CHARS = 10;
|
|
598
|
+
var exactFormatter2 = new Intl.NumberFormat("en-US", {
|
|
599
|
+
maximumFractionDigits: 2
|
|
600
|
+
});
|
|
601
|
+
var MONTHS = [
|
|
602
|
+
"Jan",
|
|
603
|
+
"Feb",
|
|
604
|
+
"Mar",
|
|
605
|
+
"Apr",
|
|
606
|
+
"May",
|
|
607
|
+
"Jun",
|
|
608
|
+
"Jul",
|
|
609
|
+
"Aug",
|
|
610
|
+
"Sep",
|
|
611
|
+
"Oct",
|
|
612
|
+
"Nov",
|
|
613
|
+
"Dec"
|
|
614
|
+
];
|
|
615
|
+
var DATE_LABEL = /^(\d{4})-(\d{2})-(\d{2})/u;
|
|
616
|
+
function niceCeil(value) {
|
|
617
|
+
if (value === 0) return 0;
|
|
618
|
+
const magnitude = 10 ** Math.floor(Math.log10(Math.abs(value)));
|
|
619
|
+
const step = magnitude / 2;
|
|
620
|
+
return Math.ceil(value / step) * step;
|
|
621
|
+
}
|
|
622
|
+
function niceFloor(value) {
|
|
623
|
+
if (value === 0) return 0;
|
|
624
|
+
const magnitude = 10 ** Math.floor(Math.log10(Math.abs(value)));
|
|
625
|
+
const step = magnitude / 2;
|
|
626
|
+
return Math.floor(value / step) * step;
|
|
627
|
+
}
|
|
628
|
+
function valueScaleBounds(values) {
|
|
629
|
+
let lowest = Number.POSITIVE_INFINITY;
|
|
630
|
+
let highest = Number.NEGATIVE_INFINITY;
|
|
631
|
+
for (const value of values) {
|
|
632
|
+
if (!Number.isFinite(value)) continue;
|
|
633
|
+
if (value < lowest) lowest = value;
|
|
634
|
+
if (value > highest) highest = value;
|
|
635
|
+
}
|
|
636
|
+
if (lowest > highest) return { min: 0, max: 1 };
|
|
637
|
+
const min = lowest < 0 ? niceFloor(lowest) : 0;
|
|
638
|
+
const max = niceCeil(highest);
|
|
639
|
+
return max <= min ? { min, max: min + 1 } : { min, max };
|
|
640
|
+
}
|
|
641
|
+
function formatDateLabel(value, withYear) {
|
|
642
|
+
const match = DATE_LABEL.exec(value);
|
|
643
|
+
if (match === null) return value;
|
|
644
|
+
const monthNumber = Number(match[2]);
|
|
645
|
+
const month = MONTHS[monthNumber - 1] ?? match[2] ?? "";
|
|
646
|
+
const day = String(Number(match[3]));
|
|
647
|
+
const year = match[1] ?? "";
|
|
648
|
+
return withYear ? `${month} ${day}, ${year.slice(2)}` : `${month} ${day}`;
|
|
649
|
+
}
|
|
650
|
+
function categoryData(axis) {
|
|
651
|
+
if (!Array.isArray(axis.data)) return [];
|
|
652
|
+
return axis.data.map(
|
|
653
|
+
(entry) => typeof entry === "string" || typeof entry === "number" ? String(entry) : isRecord(entry) ? String(entry.value ?? "") : ""
|
|
654
|
+
);
|
|
655
|
+
}
|
|
656
|
+
function looksLikeDates(values) {
|
|
657
|
+
if (values.length === 0) return false;
|
|
658
|
+
return values.filter((value) => DATE_LABEL.test(value)).length / values.length >= 0.8;
|
|
659
|
+
}
|
|
660
|
+
function withAxisLabelDefaults(axis) {
|
|
661
|
+
if (!isRecord(axis)) return axis;
|
|
662
|
+
const label = isRecord(axis.axisLabel) ? { ...axis.axisLabel } : {};
|
|
663
|
+
const hasFormatter = label.formatter !== void 0;
|
|
664
|
+
const type = typeof axis.type === "string" ? axis.type : "value";
|
|
665
|
+
if ((type === "value" || type === "log") && !hasFormatter) {
|
|
666
|
+
label.formatter = (value) => formatCompactNumber(value);
|
|
667
|
+
} else if (type === "category") {
|
|
668
|
+
const values = categoryData(axis);
|
|
669
|
+
if (!hasFormatter && looksLikeDates(values)) {
|
|
670
|
+
const years = new Set(values.map((value) => value.slice(0, 4)));
|
|
671
|
+
const withYear = years.size > 1;
|
|
672
|
+
label.formatter = (value) => formatDateLabel(value, withYear);
|
|
673
|
+
}
|
|
674
|
+
const longest = values.reduce(
|
|
675
|
+
(maximum, value) => Math.max(maximum, value.length),
|
|
676
|
+
0
|
|
677
|
+
);
|
|
678
|
+
if (label.rotate === void 0 && values.length > ROTATE_LABEL_COUNT && longest > LONG_LABEL_CHARS) {
|
|
679
|
+
label.rotate = 30;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
if (label.hideOverlap === void 0) label.hideOverlap = true;
|
|
683
|
+
return { ...axis, axisLabel: label };
|
|
684
|
+
}
|
|
685
|
+
function mapAxis(axes) {
|
|
686
|
+
return Array.isArray(axes) ? axes.map(withAxisLabelDefaults) : withAxisLabelDefaults(axes);
|
|
687
|
+
}
|
|
688
|
+
function withTooltipDefaults(tooltip, seriesCount) {
|
|
689
|
+
const next = isRecord(tooltip) ? { ...tooltip } : {};
|
|
690
|
+
const trigger = typeof next.trigger === "string" ? next.trigger : "item";
|
|
691
|
+
if (next.valueFormatter === void 0) {
|
|
692
|
+
next.valueFormatter = (value) => typeof value === "number" && Number.isFinite(value) ? exactFormatter2.format(value) : Array.isArray(value) ? value.map((entry) => String(entry)).join(" to ") : String(value ?? "");
|
|
693
|
+
}
|
|
694
|
+
if (trigger === "axis") {
|
|
695
|
+
if (next.axisPointer === void 0) {
|
|
696
|
+
next.axisPointer = { type: seriesCount > 1 ? "cross" : "line" };
|
|
697
|
+
}
|
|
698
|
+
if (next.order === void 0 && seriesCount > 2) {
|
|
699
|
+
next.order = "valueDesc";
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
if (next.extraCssText === void 0) {
|
|
703
|
+
next.extraCssText = "max-height:280px;overflow:auto;box-shadow:0 4px 16px rgba(0,0,0,0.12);";
|
|
704
|
+
}
|
|
705
|
+
return next;
|
|
706
|
+
}
|
|
707
|
+
function longestSeriesLength(series) {
|
|
708
|
+
return series.reduce((maximum, entry) => {
|
|
709
|
+
if (!isRecord(entry) || !Array.isArray(entry.data)) return maximum;
|
|
710
|
+
return Math.max(maximum, entry.data.length);
|
|
711
|
+
}, 0);
|
|
712
|
+
}
|
|
713
|
+
function hasCategoryAxis(option) {
|
|
714
|
+
const axes = Array.isArray(option.xAxis) ? option.xAxis : [option.xAxis];
|
|
715
|
+
return axes.some((axis) => isRecord(axis) && axis.type === "category");
|
|
716
|
+
}
|
|
717
|
+
function applyChartDefaults(option) {
|
|
718
|
+
const next = { ...option };
|
|
719
|
+
const rawSeries = option.series;
|
|
720
|
+
const series = Array.isArray(rawSeries) ? rawSeries : rawSeries === void 0 || rawSeries === null ? [] : [rawSeries];
|
|
721
|
+
next.tooltip = withTooltipDefaults(option.tooltip, series.length);
|
|
722
|
+
if (option.xAxis !== void 0) next.xAxis = mapAxis(option.xAxis);
|
|
723
|
+
if (option.yAxis !== void 0) next.yAxis = mapAxis(option.yAxis);
|
|
724
|
+
if (isRecord(option.legend) && option.legend.type === void 0) {
|
|
725
|
+
next.legend = { ...option.legend, type: "scroll" };
|
|
726
|
+
}
|
|
727
|
+
const zoomable = longestSeriesLength(series) >= ZOOM_THRESHOLD && option.dataZoom === void 0 && hasCategoryAxis(option);
|
|
728
|
+
if (zoomable) {
|
|
729
|
+
next.dataZoom = [
|
|
730
|
+
{
|
|
731
|
+
type: "inside",
|
|
732
|
+
zoomOnMouseWheel: "shift",
|
|
733
|
+
moveOnMouseWheel: false,
|
|
734
|
+
moveOnMouseMove: false
|
|
735
|
+
},
|
|
736
|
+
{ type: "slider", height: 14, bottom: 6, brushSelect: false }
|
|
737
|
+
];
|
|
738
|
+
if (isRecord(next.legend) && (next.legend.bottom === 0 || next.legend.bottom === "0")) {
|
|
739
|
+
next.legend = { ...next.legend, bottom: 26 };
|
|
740
|
+
}
|
|
741
|
+
if (isRecord(option.grid) && option.grid.bottom === "10%") {
|
|
742
|
+
next.grid = { ...option.grid, bottom: 56 };
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
return next;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
// ../dashboard-renderers/src/chart-options.ts
|
|
749
|
+
var GAUGE_POINTER_ICONS = {
|
|
750
|
+
pointer: "path://M12.8,0.7l12,40.1H0.7L12.8,0.7z",
|
|
751
|
+
arrow: "path://M12,2 L22,22 H18 V40 H6 V22 H2 L12,2 z",
|
|
752
|
+
hand: "path://M12,0 C18,0 22,6 22,12 L22,30 C22,36 18,40 12,40 C6,40 2,36 2,30 L2,12 C2,6 6,0 12,0 z"
|
|
753
|
+
};
|
|
754
|
+
function rowsFrom(result) {
|
|
755
|
+
if (!Array.isArray(result.rows)) return [];
|
|
756
|
+
return result.rows.filter(isRecord);
|
|
757
|
+
}
|
|
758
|
+
function stringRecord(value) {
|
|
759
|
+
if (!isRecord(value)) return void 0;
|
|
760
|
+
const entries = Object.entries(value).filter(
|
|
761
|
+
(entry) => typeof entry[1] === "string"
|
|
762
|
+
);
|
|
763
|
+
return Object.fromEntries(entries);
|
|
764
|
+
}
|
|
765
|
+
function resolveGaugePointer(pointer) {
|
|
766
|
+
if (pointer === void 0 || pointer === null) return void 0;
|
|
767
|
+
const name = typeof pointer === "string" ? pointer : void 0;
|
|
768
|
+
const pointerObject = isRecord(pointer) ? pointer : void 0;
|
|
769
|
+
const iconName = name ?? (typeof pointerObject?.icon === "string" ? pointerObject.icon : void 0);
|
|
770
|
+
if (iconName === void 0 || GAUGE_POINTER_ICONS[iconName] === void 0) {
|
|
771
|
+
if (typeof pointerObject?.icon === "string" && pointerObject.icon.startsWith("path://")) {
|
|
772
|
+
return pointerObject;
|
|
773
|
+
}
|
|
774
|
+
return pointerObject;
|
|
775
|
+
}
|
|
776
|
+
const icon = GAUGE_POINTER_ICONS[iconName];
|
|
777
|
+
const resolved = {
|
|
778
|
+
length: "90%",
|
|
779
|
+
width: 20,
|
|
780
|
+
offsetCenter: ["0%", "-50%"],
|
|
781
|
+
itemStyle: { color: "inherit" },
|
|
782
|
+
...pointerObject,
|
|
783
|
+
icon
|
|
784
|
+
};
|
|
785
|
+
if (isRecord(resolved.itemStyle) && resolved.itemStyle.color === "auto") {
|
|
786
|
+
resolved.itemStyle = { ...resolved.itemStyle, color: "inherit" };
|
|
787
|
+
}
|
|
788
|
+
return resolved;
|
|
789
|
+
}
|
|
790
|
+
function inferChartFields(rows) {
|
|
791
|
+
const first = rows[0];
|
|
792
|
+
if (first === void 0) {
|
|
793
|
+
return { x: "x", category: "category", value: "value" };
|
|
794
|
+
}
|
|
795
|
+
const keys = Object.keys(first);
|
|
796
|
+
const isNumeric = (key) => {
|
|
797
|
+
const cell = first[key];
|
|
798
|
+
return typeof cell === "number" || typeof cell === "string" && cell.trim() !== "" && !Number.isNaN(Number(cell));
|
|
799
|
+
};
|
|
800
|
+
const label = keys.find((key) => !isNumeric(key)) ?? keys[0] ?? "x";
|
|
801
|
+
const numeric = keys.find(isNumeric);
|
|
802
|
+
return {
|
|
803
|
+
x: keys.includes("x") ? "x" : label,
|
|
804
|
+
category: keys.includes("category") ? "category" : label,
|
|
805
|
+
value: keys.includes("value") ? "value" : numeric ?? keys[1] ?? keys[0] ?? "value"
|
|
806
|
+
};
|
|
807
|
+
}
|
|
808
|
+
function paddingFor(value) {
|
|
809
|
+
if (typeof value === "number" || typeof value === "string") {
|
|
810
|
+
return { top: value, right: value, bottom: value, left: value };
|
|
811
|
+
}
|
|
812
|
+
if (!isRecord(value)) return {};
|
|
813
|
+
const padding = {};
|
|
814
|
+
for (const key of ["top", "right", "bottom", "left"]) {
|
|
815
|
+
const entry = value[key];
|
|
816
|
+
if (typeof entry === "number" || typeof entry === "string") {
|
|
817
|
+
padding[key] = entry;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
return padding;
|
|
821
|
+
}
|
|
822
|
+
function unique(rows, field) {
|
|
823
|
+
const values = rows.map(
|
|
824
|
+
(row) => row[field] === void 0 || row[field] === null ? "" : String(row[field])
|
|
825
|
+
);
|
|
826
|
+
return [...new Set(values)];
|
|
827
|
+
}
|
|
828
|
+
function groupBy(rows, field) {
|
|
829
|
+
return rows.reduce((groups, row) => {
|
|
830
|
+
const key = row[field] === void 0 ? "" : String(row[field]);
|
|
831
|
+
const group = groups[key] ?? [];
|
|
832
|
+
group.push(row);
|
|
833
|
+
groups[key] = group;
|
|
834
|
+
return groups;
|
|
835
|
+
}, {});
|
|
836
|
+
}
|
|
837
|
+
function sumBy(rows, groupField, valueField, groupValue) {
|
|
838
|
+
return rows.filter((row) => String(row[groupField]) === String(groupValue)).reduce((sum, row) => sum + Number(row[valueField] ?? 0), 0);
|
|
839
|
+
}
|
|
840
|
+
function maxBy(rows, field) {
|
|
841
|
+
return rows.reduce(
|
|
842
|
+
(maximum, row) => Math.max(maximum, Number(row[field] ?? 0)),
|
|
843
|
+
0
|
|
844
|
+
);
|
|
845
|
+
}
|
|
846
|
+
function resolveBaseline(baseline, rows, groupField, groupValue) {
|
|
847
|
+
if (typeof baseline === "number") return baseline;
|
|
848
|
+
if (typeof baseline !== "string") return void 0;
|
|
849
|
+
const parsed = Number(baseline);
|
|
850
|
+
return Number.isNaN(parsed) ? sumBy(rows, groupField, baseline, groupValue) : parsed;
|
|
851
|
+
}
|
|
852
|
+
function sortRowsBy(rows, field, order) {
|
|
853
|
+
return [...rows].sort((left, right) => {
|
|
854
|
+
const leftValue = left[field];
|
|
855
|
+
const rightValue = right[field];
|
|
856
|
+
if (leftValue === null || leftValue === void 0) {
|
|
857
|
+
if (rightValue === null || rightValue === void 0) return 0;
|
|
858
|
+
return order === "asc" ? 1 : -1;
|
|
859
|
+
}
|
|
860
|
+
if (rightValue === null || rightValue === void 0) {
|
|
861
|
+
return order === "asc" ? -1 : 1;
|
|
862
|
+
}
|
|
863
|
+
const leftNumber = Number(leftValue);
|
|
864
|
+
const rightNumber = Number(rightValue);
|
|
865
|
+
if (!Number.isNaN(leftNumber) && !Number.isNaN(rightNumber)) {
|
|
866
|
+
return order === "asc" ? leftNumber - rightNumber : rightNumber - leftNumber;
|
|
867
|
+
}
|
|
868
|
+
const comparison = String(leftValue).localeCompare(String(rightValue));
|
|
869
|
+
return order === "asc" ? comparison : -comparison;
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
function customSeriesOption(widget, rows, seriesConfigs, seriesTemplate, categoryField, valueField, chartType, baseOption, common) {
|
|
873
|
+
const categories = unique(rows, categoryField);
|
|
874
|
+
const series = seriesConfigs.map((configuration) => {
|
|
875
|
+
const field = stringValue(configuration.field);
|
|
876
|
+
const seriesRest = { ...configuration };
|
|
877
|
+
delete seriesRest.field;
|
|
878
|
+
delete seriesRest.baseline;
|
|
879
|
+
const currentValueField = field ?? valueField;
|
|
880
|
+
const data = categories.map((category) => {
|
|
881
|
+
const value = sumBy(rows, categoryField, currentValueField, category);
|
|
882
|
+
const baseline = resolveBaseline(
|
|
883
|
+
configuration.baseline,
|
|
884
|
+
rows,
|
|
885
|
+
categoryField,
|
|
886
|
+
category
|
|
887
|
+
);
|
|
888
|
+
return baseline === void 0 ? value : [baseline, value];
|
|
889
|
+
});
|
|
890
|
+
return {
|
|
891
|
+
...seriesTemplate,
|
|
892
|
+
...seriesRest,
|
|
893
|
+
name: stringValue(configuration.name) ?? field ?? widget.metadata.name,
|
|
894
|
+
data,
|
|
895
|
+
type: stringValue(configuration.type) ?? chartType
|
|
896
|
+
};
|
|
897
|
+
});
|
|
898
|
+
return {
|
|
899
|
+
...common,
|
|
900
|
+
xAxis: {
|
|
901
|
+
...record(baseOption.xAxis),
|
|
902
|
+
type: "category",
|
|
903
|
+
data: categories,
|
|
904
|
+
axisLabel: { interval: "auto", hideOverlap: true }
|
|
905
|
+
},
|
|
906
|
+
yAxis: baseOption.yAxis === void 0 ? { type: "value" } : record(baseOption.yAxis),
|
|
907
|
+
legend: baseOption.legend === void 0 ? { bottom: 0 } : record(baseOption.legend),
|
|
908
|
+
series
|
|
909
|
+
};
|
|
910
|
+
}
|
|
911
|
+
function buildChartOption(widget, result) {
|
|
912
|
+
const mappings = record(widget.spec.mappings);
|
|
913
|
+
const display = displayBlock(widget, "echarts");
|
|
914
|
+
const xSort = record(display.xSort);
|
|
915
|
+
const xSortField = stringValue(xSort.by) ?? stringValue(mappings.x_order);
|
|
916
|
+
const xSortOrder = xSort.order === "desc" ? "desc" : "asc";
|
|
917
|
+
let rows = rowsFrom(result);
|
|
918
|
+
const resultVariables = record(result.variables);
|
|
919
|
+
const variables = evaluateVariables(
|
|
920
|
+
stringRecord(display.variables),
|
|
921
|
+
rows,
|
|
922
|
+
resultVariables
|
|
923
|
+
);
|
|
924
|
+
rows = applyFilter(stringValue(display.filter), rows, variables);
|
|
925
|
+
if (xSortField !== void 0) {
|
|
926
|
+
rows = sortRowsBy(rows, xSortField, xSortOrder);
|
|
927
|
+
}
|
|
928
|
+
const displayForInterpolation = { ...display };
|
|
929
|
+
delete displayForInterpolation.variables;
|
|
930
|
+
delete displayForInterpolation.filter;
|
|
931
|
+
const interpolated = record(
|
|
932
|
+
interpolateVariables(displayForInterpolation, variables)
|
|
933
|
+
);
|
|
934
|
+
const baseOption = record(interpolated.option);
|
|
935
|
+
const rawSeries = baseOption.series;
|
|
936
|
+
const seriesArray = Array.isArray(rawSeries) ? rawSeries : [rawSeries];
|
|
937
|
+
const seriesTemplate = record(seriesArray[0]);
|
|
938
|
+
const chartType = stringValue(seriesTemplate.type) ?? "line";
|
|
939
|
+
const inferred = inferChartFields(rows);
|
|
940
|
+
const xField = stringValue(mappings.x) ?? inferred.x;
|
|
941
|
+
const yField = stringValue(mappings.y) ?? inferred.value;
|
|
942
|
+
const categoryField = stringValue(mappings.category) ?? inferred.category;
|
|
943
|
+
const valueField = stringValue(mappings.value) ?? inferred.value;
|
|
944
|
+
const seriesField = stringValue(mappings.series);
|
|
945
|
+
const chartPadding = paddingFor(interpolated.chartPadding);
|
|
946
|
+
const baseOptionRest = { ...baseOption };
|
|
947
|
+
delete baseOptionRest.grid;
|
|
948
|
+
const grid = {
|
|
949
|
+
left: chartPadding.left ?? (chartType === "gauge" ? "0%" : "5%"),
|
|
950
|
+
right: chartPadding.right ?? (chartType === "gauge" ? "0%" : "5%"),
|
|
951
|
+
top: chartPadding.top ?? (chartType === "gauge" ? "0%" : "5%"),
|
|
952
|
+
bottom: chartPadding.bottom ?? (chartType === "gauge" ? "0%" : "10%"),
|
|
953
|
+
containLabel: true,
|
|
954
|
+
...record(baseOption.grid)
|
|
955
|
+
};
|
|
956
|
+
const common = {
|
|
957
|
+
tooltip: {
|
|
958
|
+
trigger: chartType === "pie" || chartType === "gauge" ? "item" : "axis",
|
|
959
|
+
appendToBody: true,
|
|
960
|
+
confine: false
|
|
961
|
+
},
|
|
962
|
+
grid,
|
|
963
|
+
...baseOptionRest
|
|
964
|
+
};
|
|
965
|
+
const customSeries = Array.isArray(interpolated.series) ? interpolated.series.filter(isRecord) : [];
|
|
966
|
+
if (customSeries.length > 0) {
|
|
967
|
+
return customSeriesOption(
|
|
968
|
+
widget,
|
|
969
|
+
rows,
|
|
970
|
+
customSeries,
|
|
971
|
+
seriesTemplate,
|
|
972
|
+
categoryField,
|
|
973
|
+
valueField,
|
|
974
|
+
chartType,
|
|
975
|
+
baseOptionRest,
|
|
976
|
+
common
|
|
977
|
+
);
|
|
978
|
+
}
|
|
979
|
+
if (chartType === "gauge") {
|
|
980
|
+
const first = rows[0] ?? {};
|
|
981
|
+
const startAngle = Number(seriesTemplate.startAngle);
|
|
982
|
+
const endAngle = Number(seriesTemplate.endAngle);
|
|
983
|
+
const semicircle = Number.isFinite(startAngle) && Number.isFinite(endAngle) && Math.abs(endAngle - startAngle) <= 180;
|
|
984
|
+
return {
|
|
985
|
+
...common,
|
|
986
|
+
series: [
|
|
987
|
+
{
|
|
988
|
+
...seriesTemplate,
|
|
989
|
+
radius: seriesTemplate.radius ?? (semicircle ? "90%" : "95%"),
|
|
990
|
+
center: seriesTemplate.center ?? (semicircle ? ["50%", "85%"] : ["50%", "55%"]),
|
|
991
|
+
...semicircle ? {
|
|
992
|
+
title: {
|
|
993
|
+
offsetCenter: ["0%", "20%"],
|
|
994
|
+
...record(seriesTemplate.title)
|
|
995
|
+
},
|
|
996
|
+
detail: {
|
|
997
|
+
offsetCenter: ["0%", "-5%"],
|
|
998
|
+
...record(seriesTemplate.detail)
|
|
999
|
+
}
|
|
1000
|
+
} : {},
|
|
1001
|
+
pointer: resolveGaugePointer(seriesTemplate.pointer),
|
|
1002
|
+
data: [
|
|
1003
|
+
{
|
|
1004
|
+
value: Number(first[valueField] ?? 0),
|
|
1005
|
+
name: widget.metadata.name
|
|
1006
|
+
}
|
|
1007
|
+
]
|
|
1008
|
+
}
|
|
1009
|
+
]
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
if (chartType === "pie") {
|
|
1013
|
+
const data2 = unique(rows, categoryField).map((category) => ({
|
|
1014
|
+
name: category,
|
|
1015
|
+
value: sumBy(rows, categoryField, valueField, category)
|
|
1016
|
+
}));
|
|
1017
|
+
return {
|
|
1018
|
+
...common,
|
|
1019
|
+
series: [
|
|
1020
|
+
{
|
|
1021
|
+
...seriesTemplate,
|
|
1022
|
+
data: data2,
|
|
1023
|
+
radius: seriesTemplate.radius ?? ["0%", "80%"]
|
|
1024
|
+
}
|
|
1025
|
+
]
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
1028
|
+
if (chartType === "heatmap") {
|
|
1029
|
+
const yCategoryField = stringValue(mappings.y) ?? "y";
|
|
1030
|
+
const data2 = rows.map((row) => [
|
|
1031
|
+
row[xField],
|
|
1032
|
+
row[yCategoryField],
|
|
1033
|
+
Number(row[valueField] ?? 0)
|
|
1034
|
+
]);
|
|
1035
|
+
return {
|
|
1036
|
+
...common,
|
|
1037
|
+
xAxis: {
|
|
1038
|
+
...record(baseOptionRest.xAxis),
|
|
1039
|
+
type: "category",
|
|
1040
|
+
data: unique(rows, xField),
|
|
1041
|
+
axisLabel: { interval: "auto", hideOverlap: true }
|
|
1042
|
+
},
|
|
1043
|
+
yAxis: {
|
|
1044
|
+
...record(baseOptionRest.yAxis),
|
|
1045
|
+
type: "category",
|
|
1046
|
+
data: unique(rows, yCategoryField),
|
|
1047
|
+
axisLabel: { interval: "auto", hideOverlap: true }
|
|
1048
|
+
},
|
|
1049
|
+
visualMap: {
|
|
1050
|
+
...valueScaleBounds(data2.map((cell) => Number(cell[2]))),
|
|
1051
|
+
calculable: true,
|
|
1052
|
+
orient: "horizontal",
|
|
1053
|
+
left: "center",
|
|
1054
|
+
bottom: 0,
|
|
1055
|
+
...record(baseOptionRest.visualMap)
|
|
1056
|
+
},
|
|
1057
|
+
series: [
|
|
1058
|
+
{
|
|
1059
|
+
...seriesTemplate,
|
|
1060
|
+
data: data2,
|
|
1061
|
+
encode: { x: xField, y: yCategoryField, value: valueField }
|
|
1062
|
+
}
|
|
1063
|
+
]
|
|
1064
|
+
};
|
|
1065
|
+
}
|
|
1066
|
+
if (chartType === "scatter") {
|
|
1067
|
+
const groups = seriesField === void 0 ? { [widget.metadata.name]: rows } : groupBy(rows, seriesField);
|
|
1068
|
+
return {
|
|
1069
|
+
...common,
|
|
1070
|
+
xAxis: { ...record(baseOptionRest.xAxis), type: "value" },
|
|
1071
|
+
yAxis: { ...record(baseOptionRest.yAxis), type: "value" },
|
|
1072
|
+
legend: { bottom: 0 },
|
|
1073
|
+
series: Object.entries(groups).map(([name, group]) => ({
|
|
1074
|
+
...seriesTemplate,
|
|
1075
|
+
name,
|
|
1076
|
+
data: group.map((row) => [
|
|
1077
|
+
Number(row[xField] ?? 0),
|
|
1078
|
+
Number(row[yField] ?? 0)
|
|
1079
|
+
]),
|
|
1080
|
+
type: "scatter"
|
|
1081
|
+
}))
|
|
1082
|
+
};
|
|
1083
|
+
}
|
|
1084
|
+
if (chartType === "radar") {
|
|
1085
|
+
const categories2 = unique(rows, categoryField);
|
|
1086
|
+
return {
|
|
1087
|
+
...common,
|
|
1088
|
+
radar: {
|
|
1089
|
+
indicator: categories2.map((category) => ({
|
|
1090
|
+
name: category,
|
|
1091
|
+
max: maxBy(rows, valueField)
|
|
1092
|
+
}))
|
|
1093
|
+
},
|
|
1094
|
+
series: [
|
|
1095
|
+
{
|
|
1096
|
+
...seriesTemplate,
|
|
1097
|
+
data: [
|
|
1098
|
+
{
|
|
1099
|
+
value: categories2.map(
|
|
1100
|
+
(category) => sumBy(rows, categoryField, valueField, category)
|
|
1101
|
+
),
|
|
1102
|
+
name: widget.metadata.name
|
|
1103
|
+
}
|
|
1104
|
+
]
|
|
1105
|
+
}
|
|
1106
|
+
]
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
1109
|
+
if (seriesField !== void 0) {
|
|
1110
|
+
const xValues = unique(rows, xField);
|
|
1111
|
+
const groups = groupBy(rows, seriesField);
|
|
1112
|
+
const seriesWithoutBaseline = { ...seriesTemplate };
|
|
1113
|
+
const baseline = seriesWithoutBaseline.baseline;
|
|
1114
|
+
delete seriesWithoutBaseline.baseline;
|
|
1115
|
+
return {
|
|
1116
|
+
...common,
|
|
1117
|
+
xAxis: {
|
|
1118
|
+
...record(baseOptionRest.xAxis),
|
|
1119
|
+
type: "category",
|
|
1120
|
+
data: xValues,
|
|
1121
|
+
axisLabel: { interval: "auto", hideOverlap: true }
|
|
1122
|
+
},
|
|
1123
|
+
yAxis: baseOptionRest.yAxis === void 0 ? { type: "value" } : record(baseOptionRest.yAxis),
|
|
1124
|
+
legend: baseOptionRest.legend === void 0 ? { bottom: 0 } : record(baseOptionRest.legend),
|
|
1125
|
+
series: Object.entries(groups).map(([name, group]) => ({
|
|
1126
|
+
...seriesWithoutBaseline,
|
|
1127
|
+
name,
|
|
1128
|
+
data: xValues.map((x) => {
|
|
1129
|
+
const row = group.find(
|
|
1130
|
+
(candidate) => String(candidate[xField]) === String(x)
|
|
1131
|
+
);
|
|
1132
|
+
const value = Number(row?.[yField] ?? 0);
|
|
1133
|
+
const base = resolveBaseline(baseline, group, xField, x);
|
|
1134
|
+
return base === void 0 ? value : [base, value];
|
|
1135
|
+
}),
|
|
1136
|
+
type: chartType
|
|
1137
|
+
}))
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1140
|
+
const categories = unique(rows, categoryField);
|
|
1141
|
+
const data = categories.map((category) => {
|
|
1142
|
+
const value = sumBy(rows, categoryField, valueField, category);
|
|
1143
|
+
const baseline = resolveBaseline(
|
|
1144
|
+
seriesTemplate.baseline,
|
|
1145
|
+
rows,
|
|
1146
|
+
categoryField,
|
|
1147
|
+
category
|
|
1148
|
+
);
|
|
1149
|
+
return baseline === void 0 ? value : [baseline, value];
|
|
1150
|
+
});
|
|
1151
|
+
if (chartType === "bar" && interpolated.orientation === "horizontal") {
|
|
1152
|
+
return {
|
|
1153
|
+
...common,
|
|
1154
|
+
xAxis: { ...record(baseOptionRest.xAxis), type: "value" },
|
|
1155
|
+
yAxis: {
|
|
1156
|
+
...record(baseOptionRest.yAxis),
|
|
1157
|
+
type: "category",
|
|
1158
|
+
data: categories,
|
|
1159
|
+
axisLabel: { interval: "auto", hideOverlap: true }
|
|
1160
|
+
},
|
|
1161
|
+
series: [{ ...seriesTemplate, data, type: "bar" }]
|
|
1162
|
+
};
|
|
1163
|
+
}
|
|
1164
|
+
return {
|
|
1165
|
+
...common,
|
|
1166
|
+
xAxis: {
|
|
1167
|
+
...record(baseOptionRest.xAxis),
|
|
1168
|
+
type: "category",
|
|
1169
|
+
data: categories,
|
|
1170
|
+
axisLabel: { interval: "auto", hideOverlap: true }
|
|
1171
|
+
},
|
|
1172
|
+
yAxis: baseOptionRest.yAxis === void 0 ? { type: "value" } : record(baseOptionRest.yAxis),
|
|
1173
|
+
series: [{ ...seriesTemplate, data }]
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1176
|
+
function chartAxisKey(option) {
|
|
1177
|
+
if (!isRecord(option)) return "";
|
|
1178
|
+
const axes = Array.isArray(option.xAxis) ? option.xAxis : [option.xAxis];
|
|
1179
|
+
const axis = axes.find(
|
|
1180
|
+
(entry) => isRecord(entry) && entry.type === "category"
|
|
1181
|
+
);
|
|
1182
|
+
if (!isRecord(axis) || !Array.isArray(axis.data)) return "";
|
|
1183
|
+
const values = axis.data.map(
|
|
1184
|
+
(entry) => isRecord(entry) ? String(entry.value ?? "") : String(entry)
|
|
1185
|
+
);
|
|
1186
|
+
if (values.length === 0) return "";
|
|
1187
|
+
return `${values.length}|${values[0]}|${values[values.length - 1]}`;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
// ../dashboard-renderers/src/chart-theme.ts
|
|
1191
|
+
function buildChartTheme(tokens) {
|
|
1192
|
+
const axis = {
|
|
1193
|
+
axisLine: { show: true, lineStyle: { color: tokens.border } },
|
|
1194
|
+
axisTick: { show: false },
|
|
1195
|
+
axisLabel: { color: tokens.mutedForeground, fontSize: 11 },
|
|
1196
|
+
splitLine: {
|
|
1197
|
+
show: true,
|
|
1198
|
+
lineStyle: { color: tokens.border, type: "dashed", opacity: 0.7 }
|
|
1199
|
+
},
|
|
1200
|
+
splitArea: { show: false }
|
|
1201
|
+
};
|
|
1202
|
+
return {
|
|
1203
|
+
color: [...tokens.seriesColors],
|
|
1204
|
+
backgroundColor: "transparent",
|
|
1205
|
+
textStyle: { fontFamily: tokens.fontFamily, color: tokens.foreground },
|
|
1206
|
+
title: {
|
|
1207
|
+
textStyle: { color: tokens.foreground, fontWeight: 600 },
|
|
1208
|
+
subtextStyle: { color: tokens.mutedForeground }
|
|
1209
|
+
},
|
|
1210
|
+
legend: {
|
|
1211
|
+
textStyle: { color: tokens.mutedForeground },
|
|
1212
|
+
itemWidth: 10,
|
|
1213
|
+
itemHeight: 10,
|
|
1214
|
+
icon: "roundRect"
|
|
1215
|
+
},
|
|
1216
|
+
tooltip: {
|
|
1217
|
+
backgroundColor: tokens.surface,
|
|
1218
|
+
borderColor: tokens.border,
|
|
1219
|
+
borderWidth: 1,
|
|
1220
|
+
textStyle: { color: tokens.surfaceForeground, fontSize: 12 },
|
|
1221
|
+
axisPointer: {
|
|
1222
|
+
lineStyle: { color: tokens.border },
|
|
1223
|
+
crossStyle: { color: tokens.border },
|
|
1224
|
+
label: { backgroundColor: tokens.mutedForeground }
|
|
1225
|
+
}
|
|
1226
|
+
},
|
|
1227
|
+
categoryAxis: { ...axis, splitLine: { show: false } },
|
|
1228
|
+
valueAxis: axis,
|
|
1229
|
+
logAxis: axis,
|
|
1230
|
+
timeAxis: axis,
|
|
1231
|
+
line: { symbol: "circle", symbolSize: 6, lineStyle: { width: 2 } },
|
|
1232
|
+
bar: { itemStyle: { borderRadius: [3, 3, 0, 0] } },
|
|
1233
|
+
pie: { itemStyle: { borderColor: tokens.surface, borderWidth: 1 } },
|
|
1234
|
+
visualMap: {
|
|
1235
|
+
textStyle: { color: tokens.mutedForeground },
|
|
1236
|
+
inRange: {
|
|
1237
|
+
color: [...tokens.heatmapColors ?? tokens.seriesColors.slice(0, 3)]
|
|
1238
|
+
}
|
|
1239
|
+
},
|
|
1240
|
+
dataZoom: {
|
|
1241
|
+
borderColor: tokens.border,
|
|
1242
|
+
textStyle: { color: tokens.mutedForeground }
|
|
1243
|
+
},
|
|
1244
|
+
toolbox: { iconStyle: { borderColor: tokens.mutedForeground } }
|
|
1245
|
+
};
|
|
1246
|
+
}
|
|
1247
|
+
var CHART_MOTION = {
|
|
1248
|
+
animation: true,
|
|
1249
|
+
animationDuration: 520,
|
|
1250
|
+
animationEasing: "cubicOut",
|
|
1251
|
+
animationDelay: (index) => Math.min(index, 40) * 12,
|
|
1252
|
+
animationDurationUpdate: 420,
|
|
1253
|
+
animationEasingUpdate: "cubicInOut",
|
|
1254
|
+
animationDelayUpdate: (index) => Math.min(index, 40) * 6
|
|
1255
|
+
};
|
|
1256
|
+
var CHART_MOTION_OFF = {
|
|
1257
|
+
animation: false,
|
|
1258
|
+
animationDuration: 0,
|
|
1259
|
+
animationDurationUpdate: 0,
|
|
1260
|
+
animationDelay: 0,
|
|
1261
|
+
animationDelayUpdate: 0
|
|
1262
|
+
};
|
|
1263
|
+
function withChartMotion(option, reduced) {
|
|
1264
|
+
const next = {
|
|
1265
|
+
...reduced ? CHART_MOTION_OFF : CHART_MOTION
|
|
1266
|
+
};
|
|
1267
|
+
for (const [key, value] of Object.entries(option)) {
|
|
1268
|
+
if (value !== void 0) next[key] = value;
|
|
1269
|
+
}
|
|
1270
|
+
return next;
|
|
1271
|
+
}
|
|
1272
|
+
function chartStructureKey(option) {
|
|
1273
|
+
const rawSeries = option.series;
|
|
1274
|
+
const series = Array.isArray(rawSeries) ? rawSeries : rawSeries === void 0 || rawSeries === null ? [] : [rawSeries];
|
|
1275
|
+
const seriesKey = series.map(
|
|
1276
|
+
(entry) => isRecord(entry) ? `${String(entry.type ?? "")}|${String(entry.name ?? "")}` : "?"
|
|
1277
|
+
).join(",");
|
|
1278
|
+
const axisKey = ["xAxis", "yAxis"].map((key) => {
|
|
1279
|
+
const axes = Array.isArray(option[key]) ? option[key] : [option[key]];
|
|
1280
|
+
return axes.map((axis) => isRecord(axis) ? String(axis.type ?? "") : "").join("/");
|
|
1281
|
+
}).join(";");
|
|
1282
|
+
const extras = ["radar", "visualMap", "dataZoom"].map((key) => option[key] === void 0 ? "0" : "1").join("");
|
|
1283
|
+
return `${seriesKey}#${axisKey}#${extras}`;
|
|
1284
|
+
}
|
|
1285
|
+
function chartLoadingOptions(tokens, mode) {
|
|
1286
|
+
return {
|
|
1287
|
+
text: "Refreshing",
|
|
1288
|
+
color: tokens.seriesColors[0] ?? tokens.foreground,
|
|
1289
|
+
textColor: tokens.mutedForeground,
|
|
1290
|
+
maskColor: mode === "dark" ? "rgba(15, 17, 21, 0.55)" : "rgba(250, 251, 252, 0.6)",
|
|
1291
|
+
zlevel: 0,
|
|
1292
|
+
fontFamily: tokens.fontFamily,
|
|
1293
|
+
fontSize: 12
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
// ../dashboard-renderers/src/chart-model.ts
|
|
1298
|
+
function buildChartRendererModel(widget, result, context = {}) {
|
|
1299
|
+
const option = withChartMotion(
|
|
1300
|
+
applyChartDefaults(applyNamedFormatters(buildChartOption(widget, result))),
|
|
1301
|
+
context.reducedMotion === true
|
|
1302
|
+
);
|
|
1303
|
+
return {
|
|
1304
|
+
kind: "chart",
|
|
1305
|
+
frame: rendererFrame(
|
|
1306
|
+
widget,
|
|
1307
|
+
"echarts",
|
|
1308
|
+
context.widgetDefaults,
|
|
1309
|
+
context.framed
|
|
1310
|
+
),
|
|
1311
|
+
option,
|
|
1312
|
+
axisKey: chartAxisKey(option),
|
|
1313
|
+
structureKey: chartStructureKey(option),
|
|
1314
|
+
loading: context.loading === true
|
|
1315
|
+
};
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
export { applyChartDefaults, applyFilter, applyNamedFormatters, buildChartOption, buildChartRendererModel, buildChartTheme, chartAxisKey, chartLoadingOptions, chartStructureKey, evaluateExpression, evaluateVariables, formatCompactNumber, formatValue, inferChartFields, interpolateVariables, resolveFilterDefault, valueScaleBounds, withChartMotion };
|
|
1319
|
+
//# sourceMappingURL=chunk-OMPR32AR.js.map
|
|
1320
|
+
//# sourceMappingURL=chunk-OMPR32AR.js.map
|