@macroui/echarts-vue 1.0.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 +21 -0
- package/README.md +550 -0
- package/README.zh-Hans.md +518 -0
- package/dist/graphic.d.ts +2786 -0
- package/dist/graphic.js +673 -0
- package/dist/graphic.js.map +1 -0
- package/dist/index-CJnrqQei.d.ts +219 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +741 -0
- package/dist/index.js.map +1 -0
- package/dist/index.min.js +5 -0
- package/dist/index.min.js.map +1 -0
- package/dist/runtime-CcSlBnVC.js +55 -0
- package/dist/runtime-CcSlBnVC.js.map +1 -0
- package/dist/style.css +3 -0
- package/package.json +92 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,741 @@
|
|
|
1
|
+
import { a as isPlainObject, c as parseOnEvent, i as isOn, l as warn$1, n as useRuntime, o as isSameSet, r as isBrowser, s as isValidArrayIndex } from "./runtime-CcSlBnVC.js";
|
|
2
|
+
import { Teleport, computed, defineComponent, h, inject, nextTick, onBeforeUnmount, onMounted, onScopeDispose, onUnmounted, onUpdated, shallowReactive, shallowRef, toRefs, toValue, watch, watchEffect } from "vue";
|
|
3
|
+
import { init, throttle } from "echarts/core";
|
|
4
|
+
//#region src/composables/api.ts
|
|
5
|
+
const METHOD_NAMES = [
|
|
6
|
+
"getWidth",
|
|
7
|
+
"getHeight",
|
|
8
|
+
"getDom",
|
|
9
|
+
"getOption",
|
|
10
|
+
"resize",
|
|
11
|
+
"dispatchAction",
|
|
12
|
+
"convertToPixel",
|
|
13
|
+
"convertFromPixel",
|
|
14
|
+
"containPixel",
|
|
15
|
+
"getDataURL",
|
|
16
|
+
"getConnectedDataURL",
|
|
17
|
+
"appendData",
|
|
18
|
+
"clear",
|
|
19
|
+
"isDisposed",
|
|
20
|
+
"dispose"
|
|
21
|
+
];
|
|
22
|
+
function usePublicAPI(chart) {
|
|
23
|
+
function makePublicMethod(name) {
|
|
24
|
+
const fn = function(...args) {
|
|
25
|
+
if (!chart.value) throw new Error("ECharts is not initialized yet.");
|
|
26
|
+
return Reflect.apply(chart.value[name], chart.value, args);
|
|
27
|
+
};
|
|
28
|
+
return fn;
|
|
29
|
+
}
|
|
30
|
+
return METHOD_NAMES.reduce((acc, name) => {
|
|
31
|
+
acc[name] = makePublicMethod(name);
|
|
32
|
+
return acc;
|
|
33
|
+
}, {});
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/composables/autoresize.ts
|
|
37
|
+
function useAutoresize(chart, autoresize, root) {
|
|
38
|
+
watch([
|
|
39
|
+
root,
|
|
40
|
+
chart,
|
|
41
|
+
autoresize
|
|
42
|
+
], ([root, chart, autoresize], _, onCleanup) => {
|
|
43
|
+
let ro = null;
|
|
44
|
+
if (root && chart && autoresize) {
|
|
45
|
+
const { offsetWidth, offsetHeight } = root;
|
|
46
|
+
const { throttle: wait = 100, onResize } = autoresize === true ? {} : autoresize;
|
|
47
|
+
let initialResizeTriggered = false;
|
|
48
|
+
const callback = () => {
|
|
49
|
+
chart.resize();
|
|
50
|
+
onResize?.();
|
|
51
|
+
};
|
|
52
|
+
const resizeCallback = wait ? throttle(callback, wait) : callback;
|
|
53
|
+
ro = new ResizeObserver(() => {
|
|
54
|
+
if (!initialResizeTriggered) {
|
|
55
|
+
initialResizeTriggered = true;
|
|
56
|
+
if (root.offsetWidth === offsetWidth && root.offsetHeight === offsetHeight) return;
|
|
57
|
+
}
|
|
58
|
+
if (root.offsetWidth === 0 || root.offsetHeight === 0) return;
|
|
59
|
+
resizeCallback();
|
|
60
|
+
});
|
|
61
|
+
ro.observe(root);
|
|
62
|
+
}
|
|
63
|
+
onCleanup(() => {
|
|
64
|
+
if (ro) {
|
|
65
|
+
ro.disconnect();
|
|
66
|
+
ro = null;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const autoresizeProps = { autoresize: [Boolean, Object] };
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/composables/loading.ts
|
|
74
|
+
const LOADING_OPTIONS_KEY = Symbol();
|
|
75
|
+
function useLoading(chart, loading, loadingOptions) {
|
|
76
|
+
const defaultLoadingOptions = inject(LOADING_OPTIONS_KEY, {});
|
|
77
|
+
const realLoadingOptions = computed(() => ({
|
|
78
|
+
...toValue(defaultLoadingOptions),
|
|
79
|
+
...loadingOptions.value ?? {}
|
|
80
|
+
}));
|
|
81
|
+
watchEffect(() => {
|
|
82
|
+
const instance = chart.value;
|
|
83
|
+
if (!instance) return;
|
|
84
|
+
if (loading.value) instance.showLoading(realLoadingOptions.value);
|
|
85
|
+
else instance.hideLoading();
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const loadingProps = {
|
|
89
|
+
loading: Boolean,
|
|
90
|
+
loadingOptions: Object
|
|
91
|
+
};
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region src/composables/slot.ts
|
|
94
|
+
const SLOT_OPTION_PATHS = {
|
|
95
|
+
tooltip: ["tooltip", "formatter"],
|
|
96
|
+
dataView: [
|
|
97
|
+
"toolbox",
|
|
98
|
+
"feature",
|
|
99
|
+
"dataView",
|
|
100
|
+
"optionToContent"
|
|
101
|
+
]
|
|
102
|
+
};
|
|
103
|
+
const SLOT_PREFIXES = ["tooltip", "dataView"];
|
|
104
|
+
function isValidSlotName(key) {
|
|
105
|
+
return SLOT_PREFIXES.some((slotPrefix) => key === slotPrefix || key.startsWith(slotPrefix + "-"));
|
|
106
|
+
}
|
|
107
|
+
function ensureChild(parent, seg, nextSeg) {
|
|
108
|
+
const next = readSegment(parent, seg);
|
|
109
|
+
if (Array.isArray(next)) {
|
|
110
|
+
const cloned = [...next];
|
|
111
|
+
writeSegment(parent, seg, cloned);
|
|
112
|
+
return cloned;
|
|
113
|
+
}
|
|
114
|
+
if (isPlainObject(next)) {
|
|
115
|
+
const cloned = { ...next };
|
|
116
|
+
writeSegment(parent, seg, cloned);
|
|
117
|
+
return cloned;
|
|
118
|
+
}
|
|
119
|
+
if (next === void 0) {
|
|
120
|
+
const created = nextSeg && isValidArrayIndex(nextSeg) ? [] : {};
|
|
121
|
+
writeSegment(parent, seg, created);
|
|
122
|
+
return created;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function readSegment(parent, seg) {
|
|
126
|
+
if (Array.isArray(parent)) return parent[Number(seg)];
|
|
127
|
+
return parent[seg];
|
|
128
|
+
}
|
|
129
|
+
function writeSegment(parent, seg, value) {
|
|
130
|
+
if (Array.isArray(parent)) {
|
|
131
|
+
parent[Number(seg)] = value;
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
parent[seg] = value;
|
|
135
|
+
}
|
|
136
|
+
function useSlotOption(slots, onSlotsChange) {
|
|
137
|
+
const detachedRoot = isBrowser() ? document.createElement("div") : void 0;
|
|
138
|
+
const containers = shallowReactive({});
|
|
139
|
+
const initialized = shallowReactive({});
|
|
140
|
+
const params = shallowReactive({});
|
|
141
|
+
const isMounted = shallowRef(false);
|
|
142
|
+
const warnedInvalidSlots = /* @__PURE__ */ new Set();
|
|
143
|
+
const collectSlotNames = (warnInvalid) => {
|
|
144
|
+
const result = [];
|
|
145
|
+
for (const key of Object.keys(slots)) {
|
|
146
|
+
if (key === "graphic") continue;
|
|
147
|
+
if (isValidSlotName(key)) result.push(key);
|
|
148
|
+
else if (warnInvalid && !warnedInvalidSlots.has(key)) {
|
|
149
|
+
warn$1(`Invalid slot name: ${key}`);
|
|
150
|
+
warnedInvalidSlots.add(key);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return result;
|
|
154
|
+
};
|
|
155
|
+
let slotNames = collectSlotNames(false);
|
|
156
|
+
const render = () => {
|
|
157
|
+
const names = collectSlotNames(false);
|
|
158
|
+
if (names.length === 0 || !isMounted.value || !detachedRoot) return;
|
|
159
|
+
return h(Teleport, { to: detachedRoot }, names.map((slotName) => {
|
|
160
|
+
const slot = slots[slotName];
|
|
161
|
+
const slotContent = initialized[slotName] ? slot?.(params[slotName]) : void 0;
|
|
162
|
+
return h("div", {
|
|
163
|
+
key: slotName,
|
|
164
|
+
ref: (el) => {
|
|
165
|
+
if (el instanceof HTMLElement) containers[slotName] = el;
|
|
166
|
+
},
|
|
167
|
+
style: { display: "contents" }
|
|
168
|
+
}, slotContent);
|
|
169
|
+
}));
|
|
170
|
+
};
|
|
171
|
+
function patchOption(src) {
|
|
172
|
+
const root = { ...src };
|
|
173
|
+
const names = collectSlotNames(true);
|
|
174
|
+
for (const key of names) {
|
|
175
|
+
const prefix = key.startsWith("tooltip") ? "tooltip" : "dataView";
|
|
176
|
+
const rest = key.slice(prefix.length);
|
|
177
|
+
const parts = rest ? rest.slice(1).split("-") : [];
|
|
178
|
+
const tail = SLOT_OPTION_PATHS[prefix];
|
|
179
|
+
const path = [...parts, ...tail];
|
|
180
|
+
let current = root;
|
|
181
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
182
|
+
current = ensureChild(current, path[i], path[i + 1]);
|
|
183
|
+
if (!current) break;
|
|
184
|
+
}
|
|
185
|
+
if (!current) continue;
|
|
186
|
+
const leaf = path[path.length - 1];
|
|
187
|
+
const formatter = (payload) => {
|
|
188
|
+
initialized[key] = true;
|
|
189
|
+
params[key] = payload;
|
|
190
|
+
return containers[key];
|
|
191
|
+
};
|
|
192
|
+
writeSegment(current, leaf, formatter);
|
|
193
|
+
}
|
|
194
|
+
return root;
|
|
195
|
+
}
|
|
196
|
+
onUpdated(() => {
|
|
197
|
+
const nextSlotNames = collectSlotNames(false);
|
|
198
|
+
if (!isSameSet(nextSlotNames, slotNames)) {
|
|
199
|
+
const nextSlotNameSet = new Set(nextSlotNames);
|
|
200
|
+
for (const key of slotNames) if (!nextSlotNameSet.has(key)) {
|
|
201
|
+
delete params[key];
|
|
202
|
+
delete initialized[key];
|
|
203
|
+
delete containers[key];
|
|
204
|
+
}
|
|
205
|
+
slotNames = nextSlotNames;
|
|
206
|
+
onSlotsChange();
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
onMounted(() => {
|
|
210
|
+
isMounted.value = true;
|
|
211
|
+
});
|
|
212
|
+
onUnmounted(() => {
|
|
213
|
+
detachedRoot?.remove();
|
|
214
|
+
});
|
|
215
|
+
return {
|
|
216
|
+
render,
|
|
217
|
+
patchOption
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
//#endregion
|
|
221
|
+
//#region src/wc.ts
|
|
222
|
+
let registered = null;
|
|
223
|
+
const TAG_NAME = "x-macroui-echarts";
|
|
224
|
+
function register() {
|
|
225
|
+
if (registered != null) return registered;
|
|
226
|
+
const registry = globalThis.customElements;
|
|
227
|
+
if (!isBrowser() || !registry?.get) {
|
|
228
|
+
registered = false;
|
|
229
|
+
return registered;
|
|
230
|
+
}
|
|
231
|
+
if (!registry.get("x-macroui-echarts")) try {
|
|
232
|
+
class ECElement extends HTMLElement {
|
|
233
|
+
__dispose = null;
|
|
234
|
+
disconnectedCallback() {
|
|
235
|
+
if (this.__dispose) {
|
|
236
|
+
this.__dispose();
|
|
237
|
+
this.__dispose = null;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
registry.define(TAG_NAME, ECElement);
|
|
242
|
+
} catch {
|
|
243
|
+
registered = false;
|
|
244
|
+
return registered;
|
|
245
|
+
}
|
|
246
|
+
registered = true;
|
|
247
|
+
return registered;
|
|
248
|
+
}
|
|
249
|
+
//#endregion
|
|
250
|
+
//#region src/core/events.ts
|
|
251
|
+
function getEmitter(instance, zr) {
|
|
252
|
+
return zr ? instance.getZr() : instance;
|
|
253
|
+
}
|
|
254
|
+
function resolveHandlers(value) {
|
|
255
|
+
if (typeof value === "function") return [value];
|
|
256
|
+
if (!Array.isArray(value)) return [];
|
|
257
|
+
const handlers = [];
|
|
258
|
+
for (const item of value) if (typeof item === "function") handlers.push(item);
|
|
259
|
+
return handlers;
|
|
260
|
+
}
|
|
261
|
+
function createBoundHandler(emitter, event, value, once) {
|
|
262
|
+
const handlers = resolveHandlers(value);
|
|
263
|
+
if (handlers.length === 0) return;
|
|
264
|
+
const invoke = (...args) => {
|
|
265
|
+
for (const handler of handlers) handler(...args);
|
|
266
|
+
};
|
|
267
|
+
if (!once) return invoke;
|
|
268
|
+
let called = false;
|
|
269
|
+
const onceHandler = (...args) => {
|
|
270
|
+
if (called) return;
|
|
271
|
+
called = true;
|
|
272
|
+
invoke(...args);
|
|
273
|
+
emitter.off(event, onceHandler);
|
|
274
|
+
};
|
|
275
|
+
return onceHandler;
|
|
276
|
+
}
|
|
277
|
+
function toNativeEventKey(event, once) {
|
|
278
|
+
if (!event.startsWith("native:")) return null;
|
|
279
|
+
const nativeEvent = event.slice(7);
|
|
280
|
+
if (!nativeEvent) return null;
|
|
281
|
+
return `on${nativeEvent.charAt(0).toUpperCase()}${nativeEvent.slice(1)}${once ? "Once" : ""}`;
|
|
282
|
+
}
|
|
283
|
+
function useReactiveChartListeners(chart, attrs) {
|
|
284
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
285
|
+
let activeInstance;
|
|
286
|
+
function clearBindings() {
|
|
287
|
+
for (const binding of bindings.values()) binding.emitter.off(binding.event, binding.handler);
|
|
288
|
+
bindings.clear();
|
|
289
|
+
}
|
|
290
|
+
watchEffect(() => {
|
|
291
|
+
const instance = chart.value;
|
|
292
|
+
if (!instance) {
|
|
293
|
+
clearBindings();
|
|
294
|
+
activeInstance = void 0;
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
if (activeInstance && activeInstance !== instance) clearBindings();
|
|
298
|
+
activeInstance = instance;
|
|
299
|
+
const seen = /* @__PURE__ */ new Set();
|
|
300
|
+
for (const key in attrs) {
|
|
301
|
+
const parsed = parseOnEvent(key);
|
|
302
|
+
if (!parsed || parsed.event.startsWith("native:")) continue;
|
|
303
|
+
const zr = parsed.event.startsWith("zr:");
|
|
304
|
+
const event = zr ? parsed.event.slice(3) : parsed.event;
|
|
305
|
+
const source = attrs[key];
|
|
306
|
+
const emitter = getEmitter(instance, zr);
|
|
307
|
+
const existing = bindings.get(key);
|
|
308
|
+
if (existing && existing.source === source && existing.event === event && existing.once === parsed.once) {
|
|
309
|
+
seen.add(key);
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
if (existing) {
|
|
313
|
+
existing.emitter.off(existing.event, existing.handler);
|
|
314
|
+
bindings.delete(key);
|
|
315
|
+
}
|
|
316
|
+
const handler = createBoundHandler(emitter, event, source, parsed.once);
|
|
317
|
+
if (!handler) continue;
|
|
318
|
+
emitter.on(event, handler);
|
|
319
|
+
bindings.set(key, {
|
|
320
|
+
emitter,
|
|
321
|
+
event,
|
|
322
|
+
source,
|
|
323
|
+
once: parsed.once,
|
|
324
|
+
handler
|
|
325
|
+
});
|
|
326
|
+
seen.add(key);
|
|
327
|
+
}
|
|
328
|
+
for (const [key, binding] of bindings) {
|
|
329
|
+
if (seen.has(key)) continue;
|
|
330
|
+
binding.emitter.off(binding.event, binding.handler);
|
|
331
|
+
bindings.delete(key);
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
onScopeDispose(clearBindings);
|
|
335
|
+
}
|
|
336
|
+
function useReactiveEventAttrs(attrs) {
|
|
337
|
+
return {
|
|
338
|
+
nonEventAttrs: computed(() => {
|
|
339
|
+
const result = {};
|
|
340
|
+
for (const key in attrs) {
|
|
341
|
+
if (isOn(key)) continue;
|
|
342
|
+
result[key] = attrs[key];
|
|
343
|
+
}
|
|
344
|
+
return result;
|
|
345
|
+
}),
|
|
346
|
+
nativeListeners: computed(() => {
|
|
347
|
+
const result = {};
|
|
348
|
+
for (const key in attrs) {
|
|
349
|
+
const parsed = parseOnEvent(key);
|
|
350
|
+
if (!parsed) continue;
|
|
351
|
+
const nativeKey = toNativeEventKey(parsed.event, parsed.once);
|
|
352
|
+
if (!nativeKey) continue;
|
|
353
|
+
result[nativeKey] = attrs[key];
|
|
354
|
+
}
|
|
355
|
+
return result;
|
|
356
|
+
})
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
//#endregion
|
|
360
|
+
//#region src/update.ts
|
|
361
|
+
/**
|
|
362
|
+
* Read an item's `id` as a string.
|
|
363
|
+
* Only accept string or number. Other types are ignored to surface inconsistent data early.
|
|
364
|
+
*/
|
|
365
|
+
function readId(item) {
|
|
366
|
+
if (!isPlainObject(item)) return;
|
|
367
|
+
const raw = item.id;
|
|
368
|
+
if (typeof raw === "string") return raw;
|
|
369
|
+
if (typeof raw === "number" && Number.isFinite(raw)) return String(raw);
|
|
370
|
+
}
|
|
371
|
+
function summarizeArray(items) {
|
|
372
|
+
const ids = /* @__PURE__ */ new Set();
|
|
373
|
+
let noIdCount = 0;
|
|
374
|
+
for (let i = 0; i < items.length; i++) {
|
|
375
|
+
const id = readId(items[i]);
|
|
376
|
+
if (id === void 0) {
|
|
377
|
+
noIdCount++;
|
|
378
|
+
continue;
|
|
379
|
+
}
|
|
380
|
+
ids.add(id);
|
|
381
|
+
}
|
|
382
|
+
return {
|
|
383
|
+
idsSorted: ids.size > 0 ? Array.from(ids).sort() : [],
|
|
384
|
+
noIdCount
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Build a minimal signature from a full ECharts option.
|
|
389
|
+
* Only top-level keys are inspected.
|
|
390
|
+
*/
|
|
391
|
+
function buildSignature(option) {
|
|
392
|
+
const opt = option;
|
|
393
|
+
const optionsLength = Array.isArray(opt.options) ? opt.options.length : 0;
|
|
394
|
+
const mediaLength = Array.isArray(opt.media) ? opt.media.length : 0;
|
|
395
|
+
const arrays = Object.create(null);
|
|
396
|
+
const objects = [];
|
|
397
|
+
const scalars = [];
|
|
398
|
+
for (const key of Object.keys(opt)) {
|
|
399
|
+
if (key === "options" || key === "media") continue;
|
|
400
|
+
const value = opt[key];
|
|
401
|
+
if (Array.isArray(value)) {
|
|
402
|
+
arrays[key] = summarizeArray(value);
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
if (isPlainObject(value)) {
|
|
406
|
+
objects.push(key);
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
if (value !== void 0) scalars.push(key);
|
|
410
|
+
}
|
|
411
|
+
if (objects.length > 1) objects.sort();
|
|
412
|
+
if (scalars.length > 1) scalars.sort();
|
|
413
|
+
return {
|
|
414
|
+
optionsLength,
|
|
415
|
+
mediaLength,
|
|
416
|
+
arrays,
|
|
417
|
+
objects,
|
|
418
|
+
scalars
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
function diffKeys(prevKeys, nextKeys) {
|
|
422
|
+
if (prevKeys.length === 0) return [];
|
|
423
|
+
if (nextKeys.length === 0) return prevKeys.slice();
|
|
424
|
+
const nextSet = new Set(nextKeys);
|
|
425
|
+
const missing = [];
|
|
426
|
+
for (let i = 0; i < prevKeys.length; i++) {
|
|
427
|
+
const key = prevKeys[i];
|
|
428
|
+
if (!nextSet.has(key)) missing.push(key);
|
|
429
|
+
}
|
|
430
|
+
return missing;
|
|
431
|
+
}
|
|
432
|
+
function hasMissingIds(prevIds, nextIds) {
|
|
433
|
+
if (prevIds.length === 0) return false;
|
|
434
|
+
if (nextIds.length === 0) return true;
|
|
435
|
+
const nextSet = new Set(nextIds);
|
|
436
|
+
for (let i = 0; i < prevIds.length; i++) if (!nextSet.has(prevIds[i])) return true;
|
|
437
|
+
return false;
|
|
438
|
+
}
|
|
439
|
+
function shouldForceNotMerge(prev, next) {
|
|
440
|
+
if (next.optionsLength < prev.optionsLength) return true;
|
|
441
|
+
if (next.mediaLength < prev.mediaLength) return true;
|
|
442
|
+
return diffKeys(prev.scalars, next.scalars).length > 0;
|
|
443
|
+
}
|
|
444
|
+
function collectObjectOverrides(prev, next) {
|
|
445
|
+
const overrides = /* @__PURE__ */ new Map();
|
|
446
|
+
const missingObjects = diffKeys(prev.objects, next.objects);
|
|
447
|
+
for (let i = 0; i < missingObjects.length; i++) {
|
|
448
|
+
const key = missingObjects[i];
|
|
449
|
+
const movedToArray = next.arrays[key] !== void 0;
|
|
450
|
+
const movedToScalar = next.scalars.includes(key);
|
|
451
|
+
if (!movedToArray && !movedToScalar) overrides.set(key, null);
|
|
452
|
+
}
|
|
453
|
+
return overrides;
|
|
454
|
+
}
|
|
455
|
+
function collectArrayChanges(prev, next, overrides) {
|
|
456
|
+
const replaceMerge = /* @__PURE__ */ new Set();
|
|
457
|
+
for (const key of Object.keys(prev.arrays)) {
|
|
458
|
+
const prevArray = prev.arrays[key];
|
|
459
|
+
if (!prevArray) continue;
|
|
460
|
+
const nextArray = next.arrays[key];
|
|
461
|
+
if (!nextArray) {
|
|
462
|
+
if (prevArray.idsSorted.length > 0 || prevArray.noIdCount > 0) {
|
|
463
|
+
overrides.set(key, []);
|
|
464
|
+
replaceMerge.add(key);
|
|
465
|
+
}
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
if (hasMissingIds(prevArray.idsSorted, nextArray.idsSorted)) {
|
|
469
|
+
replaceMerge.add(key);
|
|
470
|
+
continue;
|
|
471
|
+
}
|
|
472
|
+
if (nextArray.noIdCount < prevArray.noIdCount) replaceMerge.add(key);
|
|
473
|
+
}
|
|
474
|
+
return replaceMerge;
|
|
475
|
+
}
|
|
476
|
+
function applyOverrides(option, next, overrides) {
|
|
477
|
+
if (overrides.size === 0) return {
|
|
478
|
+
option,
|
|
479
|
+
signature: next
|
|
480
|
+
};
|
|
481
|
+
const normalizedOption = { ...option };
|
|
482
|
+
overrides.forEach((value, key) => {
|
|
483
|
+
normalizedOption[key] = value;
|
|
484
|
+
});
|
|
485
|
+
return {
|
|
486
|
+
option: normalizedOption,
|
|
487
|
+
signature: buildSignature(normalizedOption)
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Produce an update plan plus a normalized option that encodes common deletions.
|
|
492
|
+
* Falls back to `notMerge: true` when the change looks complex.
|
|
493
|
+
*/
|
|
494
|
+
function planUpdate(prev, option) {
|
|
495
|
+
const next = buildSignature(option);
|
|
496
|
+
if (!prev) return {
|
|
497
|
+
option,
|
|
498
|
+
signature: next,
|
|
499
|
+
plan: { notMerge: false }
|
|
500
|
+
};
|
|
501
|
+
if (shouldForceNotMerge(prev, next)) return {
|
|
502
|
+
option,
|
|
503
|
+
signature: next,
|
|
504
|
+
plan: { notMerge: true }
|
|
505
|
+
};
|
|
506
|
+
const overrides = collectObjectOverrides(prev, next);
|
|
507
|
+
const replaceMergeSet = collectArrayChanges(prev, next, overrides);
|
|
508
|
+
const normalized = applyOverrides(option, next, overrides);
|
|
509
|
+
const replaceMerge = replaceMergeSet.size > 0 ? Array.from(replaceMergeSet).sort() : void 0;
|
|
510
|
+
return {
|
|
511
|
+
option: normalized.option,
|
|
512
|
+
signature: normalized.signature,
|
|
513
|
+
plan: replaceMerge ? {
|
|
514
|
+
notMerge: false,
|
|
515
|
+
replaceMerge
|
|
516
|
+
} : { notMerge: false }
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
//#endregion
|
|
520
|
+
//#region src/style.css?raw
|
|
521
|
+
var style_default = "x-macroui-echarts{display:block;width:100%;height:100%;min-width:0;}\nx-macroui-echarts>.echarts-host{display:block;width:100%;height:100%;min-width:0;}\nx-macroui-echarts>.echarts-host>:first-child,x-macroui-echarts>.echarts-host>:first-child>canvas{border-radius:inherit;}\n";
|
|
522
|
+
//#endregion
|
|
523
|
+
//#region src/style.ts
|
|
524
|
+
if (isBrowser()) if (Array.isArray(document.adoptedStyleSheets) && "replaceSync" in CSSStyleSheet.prototype) {
|
|
525
|
+
const sheet = new CSSStyleSheet();
|
|
526
|
+
sheet.replaceSync(style_default);
|
|
527
|
+
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
|
|
528
|
+
} else {
|
|
529
|
+
const styleEl = document.createElement("style");
|
|
530
|
+
styleEl.textContent = style_default;
|
|
531
|
+
document.head.appendChild(styleEl);
|
|
532
|
+
}
|
|
533
|
+
//#endregion
|
|
534
|
+
//#region src/ECharts.ts
|
|
535
|
+
const wcRegistered = register();
|
|
536
|
+
const THEME_KEY = Symbol();
|
|
537
|
+
const INIT_OPTIONS_KEY = Symbol();
|
|
538
|
+
const UPDATE_OPTIONS_KEY = Symbol();
|
|
539
|
+
//#endregion
|
|
540
|
+
//#region src/index.ts
|
|
541
|
+
var src_default = defineComponent({
|
|
542
|
+
name: "Echarts",
|
|
543
|
+
inheritAttrs: false,
|
|
544
|
+
props: {
|
|
545
|
+
option: Object,
|
|
546
|
+
theme: { type: [Object, String] },
|
|
547
|
+
initOptions: Object,
|
|
548
|
+
updateOptions: Object,
|
|
549
|
+
group: String,
|
|
550
|
+
manualUpdate: Boolean,
|
|
551
|
+
...autoresizeProps,
|
|
552
|
+
...loadingProps
|
|
553
|
+
},
|
|
554
|
+
emits: {},
|
|
555
|
+
slots: Object,
|
|
556
|
+
setup(props, { attrs, expose, slots }) {
|
|
557
|
+
const attrsMap = attrs;
|
|
558
|
+
const root = shallowRef();
|
|
559
|
+
const chartHost = shallowRef();
|
|
560
|
+
const chart = shallowRef();
|
|
561
|
+
const isReady = shallowRef(false);
|
|
562
|
+
const defaultTheme = inject(THEME_KEY, null);
|
|
563
|
+
const defaultInitOptions = inject(INIT_OPTIONS_KEY, null);
|
|
564
|
+
const defaultUpdateOptions = inject(UPDATE_OPTIONS_KEY, null);
|
|
565
|
+
const { autoresize, manualUpdate, loading, loadingOptions } = toRefs(props);
|
|
566
|
+
const realTheme = computed(() => props.theme || toValue(defaultTheme));
|
|
567
|
+
const realInitOptions = computed(() => props.initOptions || toValue(defaultInitOptions) || void 0);
|
|
568
|
+
const realUpdateOptions = computed(() => props.updateOptions || toValue(defaultUpdateOptions));
|
|
569
|
+
const { nonEventAttrs, nativeListeners } = useReactiveEventAttrs(attrsMap);
|
|
570
|
+
const { render: renderSlot, patchOption } = useSlotOption(slots, requestUpdate);
|
|
571
|
+
const { patchOption: patchGraphicOption, render: renderGraphic } = useRuntime({
|
|
572
|
+
chart,
|
|
573
|
+
slots,
|
|
574
|
+
manualUpdate,
|
|
575
|
+
requestUpdate
|
|
576
|
+
}) ?? {};
|
|
577
|
+
let lastSignature;
|
|
578
|
+
function withGraphicReplaceMerge(updateOptions) {
|
|
579
|
+
if (!slots.graphic || !patchGraphicOption) return updateOptions;
|
|
580
|
+
const replaceMerge = [...updateOptions?.replaceMerge ?? [], "graphic"];
|
|
581
|
+
return {
|
|
582
|
+
...updateOptions,
|
|
583
|
+
replaceMerge: [...new Set(replaceMerge)]
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
function applyOption(instance, option, override, manual = false) {
|
|
587
|
+
const slotted = patchOption(option);
|
|
588
|
+
const patched = patchGraphicOption ? patchGraphicOption(slotted) : slotted;
|
|
589
|
+
if (manual) {
|
|
590
|
+
instance.setOption(patched, withGraphicReplaceMerge(override) ?? {});
|
|
591
|
+
lastSignature = void 0;
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
if (override) {
|
|
595
|
+
const planned = planUpdate(lastSignature, patched);
|
|
596
|
+
instance.setOption(patched, withGraphicReplaceMerge(override));
|
|
597
|
+
lastSignature = planned.signature;
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
if (realUpdateOptions.value) {
|
|
601
|
+
instance.setOption(patched, withGraphicReplaceMerge(realUpdateOptions.value));
|
|
602
|
+
lastSignature = void 0;
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
const planned = planUpdate(lastSignature, patched);
|
|
606
|
+
const updateOptions = { notMerge: planned.plan.notMerge };
|
|
607
|
+
const replacements = (planned.plan.replaceMerge ?? []).filter((key) => key != null);
|
|
608
|
+
if (replacements.length > 0) updateOptions.replaceMerge = [...new Set(replacements)];
|
|
609
|
+
instance.setOption(planned.option, withGraphicReplaceMerge(updateOptions));
|
|
610
|
+
lastSignature = planned.signature;
|
|
611
|
+
}
|
|
612
|
+
function requestUpdate(updateOptions) {
|
|
613
|
+
const instance = chart.value;
|
|
614
|
+
const option = props.option;
|
|
615
|
+
if (!instance || !option || manualUpdate.value) return false;
|
|
616
|
+
applyOption(instance, option, updateOptions);
|
|
617
|
+
return true;
|
|
618
|
+
}
|
|
619
|
+
if (slots.graphic && !patchGraphicOption) warn$1("Detected `#graphic` slot but no extension is registered. Import from `@macroui/echarts-vue/graphic` to enable it.");
|
|
620
|
+
useReactiveChartListeners(chart, attrsMap);
|
|
621
|
+
function cleanup() {
|
|
622
|
+
const instance = chart.value;
|
|
623
|
+
if (instance) {
|
|
624
|
+
instance.dispose();
|
|
625
|
+
chart.value = void 0;
|
|
626
|
+
}
|
|
627
|
+
isReady.value = false;
|
|
628
|
+
lastSignature = void 0;
|
|
629
|
+
}
|
|
630
|
+
function init$1() {
|
|
631
|
+
isReady.value = false;
|
|
632
|
+
const host = chartHost.value;
|
|
633
|
+
const instance = chart.value = init(host, realTheme.value, realInitOptions.value);
|
|
634
|
+
if (props.group) instance.group = props.group;
|
|
635
|
+
function resize() {
|
|
636
|
+
if (!instance.isDisposed()) instance.resize();
|
|
637
|
+
}
|
|
638
|
+
function commit() {
|
|
639
|
+
const option = props.option;
|
|
640
|
+
if (!option) return;
|
|
641
|
+
if (manualUpdate.value) {
|
|
642
|
+
applyOption(instance, option, void 0, true);
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
applyOption(instance, option);
|
|
646
|
+
}
|
|
647
|
+
if (autoresize.value) {
|
|
648
|
+
nextTick(() => {
|
|
649
|
+
resize();
|
|
650
|
+
commit();
|
|
651
|
+
isReady.value = true;
|
|
652
|
+
});
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
commit();
|
|
656
|
+
isReady.value = true;
|
|
657
|
+
}
|
|
658
|
+
const setOption = (option, notMerge, lazyUpdate) => {
|
|
659
|
+
if (!props.manualUpdate) {
|
|
660
|
+
warn$1("`setOption` is only available when `manual-update` is `true`.");
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
const updateOptions = typeof notMerge === "boolean" ? {
|
|
664
|
+
notMerge,
|
|
665
|
+
lazyUpdate
|
|
666
|
+
} : notMerge;
|
|
667
|
+
const instance = chart.value;
|
|
668
|
+
if (!instance) return;
|
|
669
|
+
applyOption(instance, option, updateOptions ?? void 0, true);
|
|
670
|
+
};
|
|
671
|
+
watch(() => props.option, (option) => {
|
|
672
|
+
if (!option) {
|
|
673
|
+
lastSignature = void 0;
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
if (manualUpdate.value) {
|
|
677
|
+
warn$1("`option` prop changes are ignored when `manual-update` is `true`.");
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
const instance = chart.value;
|
|
681
|
+
if (!instance) return;
|
|
682
|
+
applyOption(instance, option);
|
|
683
|
+
}, { deep: true });
|
|
684
|
+
watch([manualUpdate, realInitOptions], () => {
|
|
685
|
+
cleanup();
|
|
686
|
+
init$1();
|
|
687
|
+
}, { deep: true });
|
|
688
|
+
watch(realTheme, (theme) => {
|
|
689
|
+
const instance = chart.value;
|
|
690
|
+
if (instance) {
|
|
691
|
+
instance.setTheme(theme || {});
|
|
692
|
+
if (props.option && !manualUpdate.value) applyOption(instance, props.option);
|
|
693
|
+
}
|
|
694
|
+
}, { deep: true });
|
|
695
|
+
watchEffect(() => {
|
|
696
|
+
const instance = chart.value;
|
|
697
|
+
if (props.group && instance) instance.group = props.group;
|
|
698
|
+
});
|
|
699
|
+
const publicApi = usePublicAPI(chart);
|
|
700
|
+
useLoading(chart, loading, loadingOptions);
|
|
701
|
+
useAutoresize(chart, autoresize, root);
|
|
702
|
+
onMounted(init$1);
|
|
703
|
+
onBeforeUnmount(() => {
|
|
704
|
+
if (wcRegistered && root.value) {
|
|
705
|
+
root.value.__dispose = cleanup;
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
cleanup();
|
|
709
|
+
});
|
|
710
|
+
expose({
|
|
711
|
+
setOption,
|
|
712
|
+
root,
|
|
713
|
+
chart,
|
|
714
|
+
...publicApi
|
|
715
|
+
});
|
|
716
|
+
return (() => {
|
|
717
|
+
const children = [h("div", {
|
|
718
|
+
ref: chartHost,
|
|
719
|
+
class: "echarts-host"
|
|
720
|
+
})];
|
|
721
|
+
if (isReady.value) {
|
|
722
|
+
const teleported = renderSlot();
|
|
723
|
+
if (teleported) children.push(teleported);
|
|
724
|
+
}
|
|
725
|
+
if (renderGraphic) {
|
|
726
|
+
const graphic = renderGraphic();
|
|
727
|
+
if (graphic) children.push(graphic);
|
|
728
|
+
}
|
|
729
|
+
return h(TAG_NAME, {
|
|
730
|
+
...nonEventAttrs.value,
|
|
731
|
+
...nativeListeners.value,
|
|
732
|
+
ref: root,
|
|
733
|
+
class: ["echarts", nonEventAttrs.value.class]
|
|
734
|
+
}, children);
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
});
|
|
738
|
+
//#endregion
|
|
739
|
+
export { INIT_OPTIONS_KEY, LOADING_OPTIONS_KEY, THEME_KEY, UPDATE_OPTIONS_KEY, src_default as default };
|
|
740
|
+
|
|
741
|
+
//# sourceMappingURL=index.js.map
|