@liujitcn/kratos-admin-bi 0.0.0-stage → 0.1.6
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 +43 -2
- package/dist/package/declarations/index.d.ts +1 -0
- package/dist/package/declarations/src/api/bi/admin/v1/bi_card.d.ts +18 -0
- package/dist/package/declarations/src/api/bi/admin/v1/bi_card.js +46 -0
- package/dist/package/declarations/src/api/bi/admin/v1/bi_dashboard.d.ts +17 -0
- package/dist/package/declarations/src/api/bi/admin/v1/bi_dashboard.js +30 -0
- package/dist/package/declarations/src/api/bi/admin/v1/bi_query.d.ts +11 -0
- package/dist/package/declarations/src/api/bi/admin/v1/bi_query.js +41 -0
- package/dist/package/declarations/src/api/bi/admin/v1/bi_query_record.d.ts +10 -0
- package/dist/package/declarations/src/api/bi/admin/v1/bi_query_record.js +14 -0
- package/dist/package/declarations/src/api/bi/admin/v1/bi_source.d.ts +26 -0
- package/dist/package/declarations/src/api/bi/admin/v1/bi_source.js +46 -0
- package/dist/package/declarations/src/bi-core.d.ts +17 -0
- package/dist/package/declarations/src/bi-core.js +22 -0
- package/dist/package/declarations/src/bi-dashboard-schema.d.ts +31 -0
- package/dist/package/declarations/src/bi-dashboard-schema.js +39 -0
- package/dist/package/declarations/src/bi-messages.d.ts +247 -0
- package/dist/package/declarations/src/bi-messages.js +247 -0
- package/dist/package/declarations/src/bi-response.d.ts +10 -0
- package/dist/package/declarations/src/bi-response.js +33 -0
- package/dist/package/declarations/src/bi-vue.d.ts +10 -0
- package/dist/package/declarations/src/bi-vue.js +10 -0
- package/dist/package/declarations/src/card-schema.d.ts +30 -0
- package/dist/package/declarations/src/card-schema.js +87 -0
- package/dist/package/declarations/src/components/BiCardChartEditor.vue.d.ts +17 -0
- package/dist/package/declarations/src/components/BiCardChartEditor.vue.js +527 -0
- package/dist/package/declarations/src/components/BiCardFormDialog.vue.d.ts +20 -0
- package/dist/package/declarations/src/components/BiCardFormDialog.vue.js +495 -0
- package/dist/package/declarations/src/components/BiCardLibrary.vue.d.ts +3 -0
- package/dist/package/declarations/src/components/BiCardLibrary.vue.js +807 -0
- package/dist/package/declarations/src/components/BiCardVisualization.vue.d.ts +10 -0
- package/dist/package/declarations/src/components/BiCardVisualization.vue.js +97 -0
- package/dist/package/declarations/src/components/BiChart.vue.d.ts +20 -0
- package/dist/package/declarations/src/components/BiChart.vue.js +112 -0
- package/dist/package/declarations/src/components/BiDashboard.vue.d.ts +9 -0
- package/dist/package/declarations/src/components/BiDashboard.vue.js +81 -0
- package/dist/package/declarations/src/components/BiDashboardMenuDialog.vue.d.ts +12 -0
- package/dist/package/declarations/src/components/BiDashboardMenuDialog.vue.js +252 -0
- package/dist/package/declarations/src/components/BiDataCard.vue.d.ts +36 -0
- package/dist/package/declarations/src/components/BiDataCard.vue.js +372 -0
- package/dist/package/declarations/src/components/BiDesigner.vue.d.ts +17 -0
- package/dist/package/declarations/src/components/BiDesigner.vue.js +666 -0
- package/dist/package/declarations/src/components/BiSourceModelDialog.vue.d.ts +17 -0
- package/dist/package/declarations/src/components/BiSourceModelDialog.vue.js +2118 -0
- package/dist/package/declarations/src/components/BiWorkbenchPreview.vue.d.ts +7 -0
- package/dist/package/declarations/src/components/BiWorkbenchPreview.vue.js +176 -0
- package/dist/package/declarations/src/components/source-model-layout.d.ts +3 -0
- package/dist/package/declarations/src/components/source-model-layout.js +66 -0
- package/dist/package/declarations/src/dataset/index.d.ts +7 -0
- package/dist/package/declarations/src/dataset/index.js +25 -0
- package/dist/package/declarations/src/dataset/labels.d.ts +2 -0
- package/dist/package/declarations/src/dataset/labels.js +21 -0
- package/dist/package/declarations/src/dataset/transform.d.ts +20 -0
- package/dist/package/declarations/src/dataset/transform.js +173 -0
- package/dist/package/declarations/src/engine/chart-types.d.ts +14 -0
- package/dist/package/declarations/src/engine/chart-types.js +37 -0
- package/dist/package/declarations/src/engine/echarts.d.ts +16 -0
- package/dist/package/declarations/src/engine/echarts.js +491 -0
- package/dist/package/declarations/src/engine/types.d.ts +36 -0
- package/dist/package/declarations/src/engine/types.js +20 -0
- package/dist/package/declarations/src/env.d.ts +17 -0
- package/dist/package/declarations/src/env.js +67 -0
- package/dist/package/declarations/src/index.d.ts +1 -0
- package/dist/package/declarations/src/index.js +1 -0
- package/dist/package/declarations/src/locales/en-US.json +254 -0
- package/dist/package/declarations/src/locales/generated.d.ts +1021 -0
- package/dist/package/declarations/src/locales/generated.js +13 -0
- package/dist/package/declarations/src/locales/ja-JP.json +254 -0
- package/dist/package/declarations/src/locales/zh-CN.json +254 -0
- package/dist/package/declarations/src/locales/zh-TW.json +254 -0
- package/dist/package/declarations/src/module.d.ts +2 -0
- package/dist/package/declarations/src/module.js +9 -0
- package/dist/package/declarations/src/rpc/bi/admin/v1/bi_card.d.ts +145 -0
- package/dist/package/declarations/src/rpc/bi/admin/v1/bi_card.js +6 -0
- package/dist/package/declarations/src/rpc/bi/admin/v1/bi_dashboard.d.ts +107 -0
- package/dist/package/declarations/src/rpc/bi/admin/v1/bi_dashboard.js +6 -0
- package/dist/package/declarations/src/rpc/bi/admin/v1/bi_query.d.ts +157 -0
- package/dist/package/declarations/src/rpc/bi/admin/v1/bi_query.js +6 -0
- package/dist/package/declarations/src/rpc/bi/admin/v1/bi_query_record.d.ts +83 -0
- package/dist/package/declarations/src/rpc/bi/admin/v1/bi_query_record.js +15 -0
- package/dist/package/declarations/src/rpc/bi/admin/v1/bi_source.d.ts +301 -0
- package/dist/package/declarations/src/rpc/bi/admin/v1/bi_source.js +6 -0
- package/dist/package/declarations/src/rpc/common/v1/types.d.ts +60 -0
- package/dist/package/declarations/src/rpc/common/v1/types.js +6 -0
- package/dist/package/declarations/src/schema/layout.d.ts +7 -0
- package/dist/package/declarations/src/schema/layout.js +52 -0
- package/dist/package/declarations/src/schema/types.d.ts +83 -0
- package/dist/package/declarations/src/schema/types.js +1 -0
- package/dist/package/declarations/src/theme/index.d.ts +29 -0
- package/dist/package/declarations/src/theme/index.js +83 -0
- package/dist/package/declarations/src/theme/palettes.d.ts +7 -0
- package/dist/package/declarations/src/theme/palettes.js +28 -0
- package/dist/package/declarations/src/theme/presets.d.ts +73 -0
- package/dist/package/declarations/src/theme/presets.js +235 -0
- package/dist/package/declarations/src/views/card/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/card/index.vue.js +18 -0
- package/dist/package/declarations/src/views/dashboard/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/dashboard/index.vue.js +107 -0
- package/dist/package/declarations/src/views/designer/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/designer/index.vue.js +332 -0
- package/dist/package/declarations/src/views/manage/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/manage/index.vue.js +325 -0
- package/dist/package/declarations/src/views/query/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/query/index.vue.js +876 -0
- package/dist/package/declarations/src/views/source/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/source/index.vue.js +343 -0
- package/dist/package/declarations/src/views/workbench/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/workbench/index.vue.js +362 -0
- package/dist/package/src/api/bi/admin/v1/bi_card.ts +67 -0
- package/dist/package/src/api/bi/admin/v1/bi_dashboard.ts +51 -0
- package/dist/package/src/api/bi/admin/v1/bi_query.ts +55 -0
- package/dist/package/src/api/bi/admin/v1/bi_query_record.ts +25 -0
- package/dist/package/src/api/bi/admin/v1/bi_source.ts +80 -0
- package/dist/package/src/bi-core.ts +43 -0
- package/dist/package/src/bi-dashboard-schema.ts +69 -0
- package/dist/package/src/bi-messages.ts +249 -0
- package/dist/package/src/bi-response.ts +39 -0
- package/dist/package/src/bi-vue.ts +13 -0
- package/dist/package/src/card-schema.ts +111 -0
- package/dist/package/src/components/BiCardChartEditor.vue +139 -0
- package/dist/package/src/components/BiCardFormDialog.vue +289 -0
- package/dist/package/src/components/BiCardLibrary.vue +310 -0
- package/dist/package/src/components/BiCardVisualization.vue +95 -0
- package/dist/package/src/components/BiChart.vue +134 -0
- package/dist/package/src/components/BiDashboard.vue +53 -0
- package/dist/package/src/components/BiDashboardMenuDialog.vue +177 -0
- package/dist/package/src/components/BiDataCard.vue +231 -0
- package/dist/package/src/components/BiDesigner.vue +287 -0
- package/dist/package/src/components/BiSourceModelDialog.vue +846 -0
- package/dist/package/src/components/BiWorkbenchPreview.vue +131 -0
- package/dist/package/src/components/source-model-layout.ts +62 -0
- package/dist/package/src/dataset/index.ts +28 -0
- package/dist/package/src/dataset/labels.ts +19 -0
- package/dist/package/src/dataset/transform.ts +189 -0
- package/dist/package/src/engine/chart-types.ts +44 -0
- package/dist/package/src/engine/echarts.ts +568 -0
- package/dist/package/src/engine/types.ts +60 -0
- package/dist/package/src/env.ts +82 -0
- package/dist/package/src/index.ts +1 -0
- package/dist/package/src/locales/en-US.json +254 -0
- package/dist/package/src/locales/generated.ts +16 -0
- package/dist/package/src/locales/ja-JP.json +254 -0
- package/dist/package/src/locales/zh-CN.json +254 -0
- package/dist/package/src/locales/zh-TW.json +254 -0
- package/dist/package/src/module.ts +12 -0
- package/dist/package/src/rpc/bi/admin/v1/bi_card.ts +169 -0
- package/dist/package/src/rpc/bi/admin/v1/bi_dashboard.ts +126 -0
- package/dist/package/src/rpc/bi/admin/v1/bi_query.ts +187 -0
- package/dist/package/src/rpc/bi/admin/v1/bi_query_record.ts +98 -0
- package/dist/package/src/rpc/bi/admin/v1/bi_source.ts +338 -0
- package/dist/package/src/rpc/common/v1/types.ts +77 -0
- package/dist/package/src/schema/layout.ts +54 -0
- package/dist/package/src/schema/types.ts +103 -0
- package/dist/package/src/styles.scss +1 -0
- package/dist/package/src/theme/index.ts +108 -0
- package/dist/package/src/theme/palettes.ts +34 -0
- package/dist/package/src/theme/presets.ts +278 -0
- package/dist/package/src/views/card/index.vue +5 -0
- package/dist/package/src/views/dashboard/index.vue +58 -0
- package/dist/package/src/views/designer/index.vue +164 -0
- package/dist/package/src/views/manage/index.vue +276 -0
- package/dist/package/src/views/query/index.vue +593 -0
- package/dist/package/src/views/source/index.vue +214 -0
- package/dist/package/src/views/workbench/index.vue +208 -0
- package/package.json +67 -3
- package/tsconfig.json +12 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { BiDashboard } from "../rpc/bi/admin/v1/bi_dashboard";
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
dashboard: BiDashboard;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/// <reference types="../../../../../node_modules/.pnpm/@vue+language-core@3.3.13/node_modules/@vue/language-core/types/template-helpers.d.ts" />
|
|
2
|
+
/// <reference types="../../../../../node_modules/.pnpm/@vue+language-core@3.3.13/node_modules/@vue/language-core/types/props-fallback.d.ts" />
|
|
3
|
+
import { onBeforeUnmount, ref } from "vue";
|
|
4
|
+
import { useIntersectionObserver } from "@vueuse/core";
|
|
5
|
+
import { t } from "@liujitcn/kratos-admin-core";
|
|
6
|
+
import { dashboardResults, dashboardSnapshotCard, parseDashboardLayout } from "../bi-dashboard-schema";
|
|
7
|
+
import { defBiDashboardService } from "../api/bi/admin/v1/bi_dashboard";
|
|
8
|
+
import BiCardVisualization from "./BiCardVisualization.vue";
|
|
9
|
+
const { defineProps, } = {};
|
|
10
|
+
const props = defineProps();
|
|
11
|
+
const host = ref();
|
|
12
|
+
const layout = ref({ schemaVersion: 3, name: "", cards: [] });
|
|
13
|
+
const results = ref(new Map());
|
|
14
|
+
const loading = ref(true);
|
|
15
|
+
const error = ref("");
|
|
16
|
+
let active = true;
|
|
17
|
+
const { stop } = useIntersectionObserver(host, ([entry]) => {
|
|
18
|
+
if (entry?.isIntersecting) {
|
|
19
|
+
stop();
|
|
20
|
+
void load();
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
/** 入口可见时按发布版本取真实数据,缩略图复用卡片渲染器。 */
|
|
24
|
+
async function load() {
|
|
25
|
+
loading.value = true;
|
|
26
|
+
error.value = "";
|
|
27
|
+
try {
|
|
28
|
+
const data = await defBiDashboardService.GetBiDashboardData({
|
|
29
|
+
id: props.dashboard.id,
|
|
30
|
+
version: props.dashboard.published_version
|
|
31
|
+
});
|
|
32
|
+
if (!active)
|
|
33
|
+
return;
|
|
34
|
+
layout.value = parseDashboardLayout(data.schema_json);
|
|
35
|
+
results.value = dashboardResults(data);
|
|
36
|
+
}
|
|
37
|
+
catch (cause) {
|
|
38
|
+
if (active)
|
|
39
|
+
error.value = cause instanceof Error ? cause.message : t("bi.query.error");
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
if (active)
|
|
43
|
+
loading.value = false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
onBeforeUnmount(() => {
|
|
47
|
+
active = false;
|
|
48
|
+
});
|
|
49
|
+
const __VLS_ctx = {
|
|
50
|
+
...{},
|
|
51
|
+
...{},
|
|
52
|
+
...{},
|
|
53
|
+
};
|
|
54
|
+
let __VLS_components;
|
|
55
|
+
let __VLS_intrinsics;
|
|
56
|
+
let __VLS_directives;
|
|
57
|
+
void __VLS_ctx, __VLS_components, __VLS_intrinsics, __VLS_directives;
|
|
58
|
+
// @ts-ignore
|
|
59
|
+
__VLS_withDotValue(loading, {});
|
|
60
|
+
// @ts-ignore
|
|
61
|
+
__VLS_withDotValue(error, {});
|
|
62
|
+
// @ts-ignore
|
|
63
|
+
__VLS_withDotValue(layout, {});
|
|
64
|
+
// @ts-ignore
|
|
65
|
+
__VLS_withDotValue(results, {});
|
|
66
|
+
void {};
|
|
67
|
+
/** @type {__VLS_StyleScopedClasses['bi-workbench-preview']} */ ;
|
|
68
|
+
/** @type {__VLS_StyleScopedClasses['bi-workbench-preview']} */ ;
|
|
69
|
+
/** @type {__VLS_StyleScopedClasses['bi-workbench-preview__empty']} */ ;
|
|
70
|
+
__VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
|
|
71
|
+
ref: "host",
|
|
72
|
+
...{ class: "bi-workbench-preview" },
|
|
73
|
+
'aria-busy': (loading.value),
|
|
74
|
+
});
|
|
75
|
+
/** @type {__VLS_StyleScopedClasses['bi-workbench-preview']} */ ;
|
|
76
|
+
if (loading.value) {
|
|
77
|
+
let __VLS_0;
|
|
78
|
+
/** @ts-ignore @type { | typeof __VLS_components.elSkeleton | typeof __VLS_components.ElSkeleton | typeof __VLS_components['el-skeleton']} */
|
|
79
|
+
elSkeleton;
|
|
80
|
+
// @ts-ignore
|
|
81
|
+
const __VLS_1 = __VLS_asFunctionalComponent1(__VLS_0, new __VLS_0({
|
|
82
|
+
// @ts-ignore
|
|
83
|
+
rows: (2), animated: true,
|
|
84
|
+
}));
|
|
85
|
+
const __VLS_2 = __VLS_1({
|
|
86
|
+
rows: (2),
|
|
87
|
+
animated: true,
|
|
88
|
+
}, ...__VLS_functionalComponentArgsRest(__VLS_1));
|
|
89
|
+
}
|
|
90
|
+
else if (error.value) {
|
|
91
|
+
__VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
|
|
92
|
+
...{ class: "bi-workbench-preview__empty" },
|
|
93
|
+
role: "alert",
|
|
94
|
+
});
|
|
95
|
+
/** @type {__VLS_StyleScopedClasses['bi-workbench-preview__empty']} */ ;
|
|
96
|
+
__VLS_asFunctionalElement1(__VLS_intrinsics.span, __VLS_intrinsics.span)({});
|
|
97
|
+
(error.value);
|
|
98
|
+
let __VLS_5;
|
|
99
|
+
/** @ts-ignore @type { | typeof __VLS_components.elButton | typeof __VLS_components.ElButton | typeof __VLS_components['el-button'] | typeof __VLS_components.elButton | typeof __VLS_components.ElButton | typeof __VLS_components['el-button']} */
|
|
100
|
+
elButton;
|
|
101
|
+
// @ts-ignore
|
|
102
|
+
const __VLS_6 = __VLS_asFunctionalComponent1(__VLS_5, new __VLS_5({
|
|
103
|
+
// @ts-ignore
|
|
104
|
+
...{ 'onClick': {} }, link: true, type: "primary",
|
|
105
|
+
}));
|
|
106
|
+
const __VLS_7 = __VLS_6({
|
|
107
|
+
...{ 'onClick': {} },
|
|
108
|
+
link: true,
|
|
109
|
+
type: "primary",
|
|
110
|
+
}, ...__VLS_functionalComponentArgsRest(__VLS_6));
|
|
111
|
+
let __VLS_10;
|
|
112
|
+
const __VLS_11 = {
|
|
113
|
+
/** @type {typeof __VLS_10.click} */
|
|
114
|
+
onClick: (load),
|
|
115
|
+
};
|
|
116
|
+
void __VLS_11;
|
|
117
|
+
const { default: __VLS_12 } = __VLS_nonNull(__VLS_8.slots);
|
|
118
|
+
(__VLS_unwrap(t, {})("bi.card.retry"));
|
|
119
|
+
// @ts-ignore
|
|
120
|
+
[loading, loading, error, error, t,];
|
|
121
|
+
var __VLS_8;
|
|
122
|
+
var __VLS_9;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
const __VLS_13 = __VLS_tryAsConstant((layout.value.cards.slice(0, 2)));
|
|
126
|
+
for (const [item] of __VLS_vFor(__VLS_nonNull(__VLS_13))) {
|
|
127
|
+
__VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
|
|
128
|
+
key: (item.id),
|
|
129
|
+
...{ class: "bi-workbench-preview__card" },
|
|
130
|
+
});
|
|
131
|
+
/** @type {__VLS_StyleScopedClasses['bi-workbench-preview__card']} */ ;
|
|
132
|
+
__VLS_asFunctionalElement1(__VLS_intrinsics.h4, __VLS_intrinsics.h4)({
|
|
133
|
+
title: (item.name),
|
|
134
|
+
});
|
|
135
|
+
(item.name);
|
|
136
|
+
__VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
|
|
137
|
+
...{ class: "bi-workbench-preview__chart" },
|
|
138
|
+
});
|
|
139
|
+
/** @type {__VLS_StyleScopedClasses['bi-workbench-preview__chart']} */ ;
|
|
140
|
+
if (results.value.get(item.id)) {
|
|
141
|
+
const __VLS_14 = BiCardVisualization;
|
|
142
|
+
// @ts-ignore
|
|
143
|
+
const __VLS_15 = __VLS_asFunctionalComponent1(__VLS_14, new __VLS_14({
|
|
144
|
+
// @ts-ignore
|
|
145
|
+
card: (__VLS_unwrap(dashboardSnapshotCard, {})(item)), result: (results.value.get(item.id)), compact: true,
|
|
146
|
+
}));
|
|
147
|
+
const __VLS_16 = __VLS_15({
|
|
148
|
+
card: (__VLS_unwrap(dashboardSnapshotCard, {})(item)),
|
|
149
|
+
result: (results.value.get(item.id)),
|
|
150
|
+
compact: true,
|
|
151
|
+
}, ...__VLS_functionalComponentArgsRest(__VLS_15));
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
__VLS_asFunctionalElement1(__VLS_intrinsics.span, __VLS_intrinsics.span)({
|
|
155
|
+
...{ class: "bi-workbench-preview__empty" },
|
|
156
|
+
});
|
|
157
|
+
/** @type {__VLS_StyleScopedClasses['bi-workbench-preview__empty']} */ ;
|
|
158
|
+
(__VLS_unwrap(t, {})("common.message.no_data"));
|
|
159
|
+
}
|
|
160
|
+
// @ts-ignore
|
|
161
|
+
[t, layout, results, results, dashboardSnapshotCard,];
|
|
162
|
+
}
|
|
163
|
+
if (!layout.value.cards.length) {
|
|
164
|
+
__VLS_asFunctionalElement1(__VLS_intrinsics.span, __VLS_intrinsics.span)({
|
|
165
|
+
...{ class: "bi-workbench-preview__empty" },
|
|
166
|
+
});
|
|
167
|
+
/** @type {__VLS_StyleScopedClasses['bi-workbench-preview__empty']} */ ;
|
|
168
|
+
(__VLS_unwrap(t, {})("bi.dashboard.empty"));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// @ts-ignore
|
|
172
|
+
[t, layout,];
|
|
173
|
+
const __VLS_export = (await import('vue')).defineComponent({
|
|
174
|
+
__typeProps: {},
|
|
175
|
+
});
|
|
176
|
+
export default {};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/** 将事实表置于中央,关联子树分布两侧并为连线保留间距。 */
|
|
2
|
+
export function formatSourceModelLayout(model) {
|
|
3
|
+
const tables = new Map(model.tables.map(table => [table.key, table]));
|
|
4
|
+
const children = new Map();
|
|
5
|
+
const targets = new Set();
|
|
6
|
+
for (const relation of model.relations) {
|
|
7
|
+
if (!tables.has(relation.left_table) || !tables.has(relation.right_table))
|
|
8
|
+
continue;
|
|
9
|
+
const branch = children.get(relation.left_table) ?? [];
|
|
10
|
+
branch.push(relation.right_table);
|
|
11
|
+
children.set(relation.left_table, branch);
|
|
12
|
+
targets.add(relation.right_table);
|
|
13
|
+
}
|
|
14
|
+
if (tables.has(model.base_table)) {
|
|
15
|
+
const branches = children.get(model.base_table) ?? [];
|
|
16
|
+
for (const table of model.tables) {
|
|
17
|
+
if (table.key !== model.base_table && !targets.has(table.key))
|
|
18
|
+
branches.push(table.key);
|
|
19
|
+
}
|
|
20
|
+
children.set(model.base_table, branches);
|
|
21
|
+
}
|
|
22
|
+
const visited = new Set();
|
|
23
|
+
let row = 0;
|
|
24
|
+
/** 为子树分配独立行,避免同层节点和不同分支相互遮挡。 */
|
|
25
|
+
function placeTable(key, depth, direction) {
|
|
26
|
+
const table = tables.get(key);
|
|
27
|
+
if (!table || visited.has(key))
|
|
28
|
+
return;
|
|
29
|
+
visited.add(key);
|
|
30
|
+
const childRows = (children.get(key) ?? [])
|
|
31
|
+
.map(child => placeTable(child, depth + 1, direction))
|
|
32
|
+
.filter((value) => value !== undefined);
|
|
33
|
+
const center = childRows.length ? (childRows[0] + childRows[childRows.length - 1]) / 2 : row++;
|
|
34
|
+
table.x = direction * depth * 520;
|
|
35
|
+
table.y = 40 + center * 280;
|
|
36
|
+
return center;
|
|
37
|
+
}
|
|
38
|
+
const base = tables.get(model.base_table);
|
|
39
|
+
if (base) {
|
|
40
|
+
visited.add(base.key);
|
|
41
|
+
const branches = children.get(base.key) ?? [];
|
|
42
|
+
const middle = Math.ceil(branches.length / 2);
|
|
43
|
+
for (const key of branches.slice(0, middle))
|
|
44
|
+
placeTable(key, 1, 1);
|
|
45
|
+
const rightRows = row;
|
|
46
|
+
const rightTables = model.tables.filter(table => visited.has(table.key) && table !== base);
|
|
47
|
+
row = 0;
|
|
48
|
+
for (const key of branches.slice(middle))
|
|
49
|
+
placeTable(key, 1, -1);
|
|
50
|
+
const leftRows = row;
|
|
51
|
+
row = Math.max(1, leftRows, rightRows);
|
|
52
|
+
for (const table of rightTables)
|
|
53
|
+
table.y += (row - rightRows) * 140;
|
|
54
|
+
for (const table of model.tables.filter(table => visited.has(table.key) && table.x < 0))
|
|
55
|
+
table.y += (row - leftRows) * 140;
|
|
56
|
+
base.x = 0;
|
|
57
|
+
base.y = 40 + (row - 1) * 140;
|
|
58
|
+
}
|
|
59
|
+
for (const table of model.tables.filter(table => !targets.has(table.key)))
|
|
60
|
+
placeTable(table.key, 0, 1);
|
|
61
|
+
for (const table of model.tables)
|
|
62
|
+
placeTable(table.key, 0, 1);
|
|
63
|
+
const minX = Math.min(0, ...model.tables.map(table => table.x));
|
|
64
|
+
for (const table of model.tables)
|
|
65
|
+
table.x += 40 - minX;
|
|
66
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { BiRow } from "../schema/types";
|
|
2
|
+
/** 从行集合推导列名(所有行键的并集,保持首次出现顺序) */
|
|
3
|
+
export declare function getColumns(rows: BiRow[] | undefined): string[];
|
|
4
|
+
/** 数值化:非有限数归 0(图表轴不允许 NaN/undefined) */
|
|
5
|
+
export declare function toNumber(value: unknown): number;
|
|
6
|
+
/** 去重保序 */
|
|
7
|
+
export declare function unique<T>(list: T[]): T[];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** 从行集合推导列名(所有行键的并集,保持首次出现顺序) */
|
|
2
|
+
export function getColumns(rows) {
|
|
3
|
+
if (!rows?.length)
|
|
4
|
+
return [];
|
|
5
|
+
const cols = [];
|
|
6
|
+
const seen = new Set();
|
|
7
|
+
for (const row of rows) {
|
|
8
|
+
for (const key of Object.keys(row ?? {})) {
|
|
9
|
+
if (!seen.has(key)) {
|
|
10
|
+
seen.add(key);
|
|
11
|
+
cols.push(key);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return cols;
|
|
16
|
+
}
|
|
17
|
+
/** 数值化:非有限数归 0(图表轴不允许 NaN/undefined) */
|
|
18
|
+
export function toNumber(value) {
|
|
19
|
+
const n = Number(value);
|
|
20
|
+
return Number.isFinite(n) ? n : 0;
|
|
21
|
+
}
|
|
22
|
+
/** 去重保序 */
|
|
23
|
+
export function unique(list) {
|
|
24
|
+
return [...new Set(list)];
|
|
25
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** 按日期分组值生成短标签,只改变显示文本,保留原始分类和提示数据。 */
|
|
2
|
+
export function createDimensionLabelFormatter(values, field = "") {
|
|
3
|
+
const pattern = /^(\d{4})-(\d{2})(?:-(\d{2})(?:[ T](\d{2})(?::(\d{2}))?(?::(\d{2})(?:\.\d+)?)?(?:Z|[+-]\d{2}:?\d{2})?)?)?$/;
|
|
4
|
+
const dates = values.map(value => pattern.exec(String(value ?? ""))).filter(value => value !== null);
|
|
5
|
+
const month = /(?:^|_)(?:month|monthly|ym)(?:_|$)|月/i.test(field);
|
|
6
|
+
const hour = /(?:^|_)(?:hour|hourly)(?:_|$)|小时/i.test(field) ||
|
|
7
|
+
(dates.length > 0 &&
|
|
8
|
+
dates.every(date => date[3] && date[0].slice(0, 10) === dates[0][0].slice(0, 10)) &&
|
|
9
|
+
dates.some(date => Number(date[4]) || Number(date[5]) || Number(date[6])));
|
|
10
|
+
return value => {
|
|
11
|
+
const text = String(value ?? "");
|
|
12
|
+
const date = pattern.exec(text);
|
|
13
|
+
if (!date)
|
|
14
|
+
return text;
|
|
15
|
+
if (month || !date[3])
|
|
16
|
+
return `${date[2]}月`;
|
|
17
|
+
if (hour && date[4])
|
|
18
|
+
return `${date[4]}时`;
|
|
19
|
+
return `${date[2]}/${date[3]}`;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 图表级数据变换管线:过滤 → 聚合 → 排序 → TopN。
|
|
3
|
+
* 渲染器在 compile 前调用 transformRows,设计器画布与渲染器共用同一管线。
|
|
4
|
+
* 聚合语义 = 主流 BI:按 dimension 分组,对 measure(或宽表 measures 全部列)施加 agg。
|
|
5
|
+
*/
|
|
6
|
+
import type { BiChartFilter, BiChartSchema, BiRow } from "../schema/types";
|
|
7
|
+
export declare function applyFilters(rows: BiRow[], filters: BiChartFilter[] | undefined): BiRow[];
|
|
8
|
+
/** 分组聚合:输出每(维度组)一行的宽表(保留维度列 + 各度量列) */
|
|
9
|
+
export declare function aggregateRows(rows: BiRow[], chart: BiChartSchema): BiRow[];
|
|
10
|
+
export declare function sortRows(rows: BiRow[], chart: BiChartSchema): BiRow[];
|
|
11
|
+
/** 渲染管线:过滤 → 聚合 → 排序/TopN,返回供 compile 消费的行 */
|
|
12
|
+
export declare function transformRows(chart: BiChartSchema, inputRows: BiRow[]): BiRow[];
|
|
13
|
+
export type BiFieldType = "number" | "date" | "string";
|
|
14
|
+
export declare function inferFieldType(rows: BiRow[] | undefined, field: string): BiFieldType;
|
|
15
|
+
export declare function formatNumber(value: number, format?: {
|
|
16
|
+
decimals?: number;
|
|
17
|
+
thousand?: boolean;
|
|
18
|
+
prefix?: string;
|
|
19
|
+
suffix?: string;
|
|
20
|
+
}): string;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 图表级数据变换管线:过滤 → 聚合 → 排序 → TopN。
|
|
3
|
+
* 渲染器在 compile 前调用 transformRows,设计器画布与渲染器共用同一管线。
|
|
4
|
+
* 聚合语义 = 主流 BI:按 dimension 分组,对 measure(或宽表 measures 全部列)施加 agg。
|
|
5
|
+
*/
|
|
6
|
+
import { NON_AGG_TYPES } from "../engine/chart-types";
|
|
7
|
+
import { toNumber } from "./index";
|
|
8
|
+
/** 单过滤器行判定;值解析:数字串转数,in 接数组 */
|
|
9
|
+
function matchFilter(row, f) {
|
|
10
|
+
const cell = row[f.field];
|
|
11
|
+
switch (f.op) {
|
|
12
|
+
case "eq":
|
|
13
|
+
return String(cell) === String(f.value);
|
|
14
|
+
case "ne":
|
|
15
|
+
return String(cell) !== String(f.value);
|
|
16
|
+
case "gt":
|
|
17
|
+
return toNumber(cell) > toNumber(f.value);
|
|
18
|
+
case "gte":
|
|
19
|
+
return toNumber(cell) >= toNumber(f.value);
|
|
20
|
+
case "lt":
|
|
21
|
+
return toNumber(cell) < toNumber(f.value);
|
|
22
|
+
case "lte":
|
|
23
|
+
return toNumber(cell) <= toNumber(f.value);
|
|
24
|
+
case "contains":
|
|
25
|
+
return String(cell ?? "").includes(String(f.value ?? ""));
|
|
26
|
+
case "in": {
|
|
27
|
+
const list = Array.isArray(f.value) ? f.value : [f.value];
|
|
28
|
+
return list.map(String).includes(String(cell));
|
|
29
|
+
}
|
|
30
|
+
default:
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function applyFilters(rows, filters) {
|
|
35
|
+
if (!filters?.length)
|
|
36
|
+
return rows;
|
|
37
|
+
return rows.filter((row) => filters.every((f) => matchFilter(row, f)));
|
|
38
|
+
}
|
|
39
|
+
const AGG_FNS = {
|
|
40
|
+
sum: (nums) => nums.reduce((a, b) => a + b, 0),
|
|
41
|
+
avg: (nums) => (nums.length ? nums.reduce((a, b) => a + b, 0) / nums.length : 0),
|
|
42
|
+
max: (nums) => (nums.length ? Math.max(...nums) : 0),
|
|
43
|
+
min: (nums) => (nums.length ? Math.min(...nums) : 0),
|
|
44
|
+
// count 不依赖数值:调用方传入占位 1 数组
|
|
45
|
+
count: (nums) => nums.length,
|
|
46
|
+
};
|
|
47
|
+
/** 是否应执行聚合:给了 dimension + 显式 agg(非 none);
|
|
48
|
+
* 边列表/矩阵型(sankey/graph/heatmap)天然按行消费,不做维度聚合 */
|
|
49
|
+
function shouldAggregate(chart) {
|
|
50
|
+
if (NON_AGG_TYPES.has(chart.type))
|
|
51
|
+
return false;
|
|
52
|
+
const agg = chart.aggregation ?? "sum";
|
|
53
|
+
const dim = chart.encoding?.dimension;
|
|
54
|
+
if (!dim || agg === "none")
|
|
55
|
+
return false;
|
|
56
|
+
// 至少要有一个度量对象(count 允许无 measure)
|
|
57
|
+
return !!(chart.encoding?.measure || chart.encoding?.measures?.length || agg === "count");
|
|
58
|
+
}
|
|
59
|
+
/** 分组键字段:维度 + (pivot 图的列维度也要保留,供 S2 交叉表用) */
|
|
60
|
+
function groupFieldsOf(chart) {
|
|
61
|
+
const fields = [chart.encoding?.dimension ?? ""];
|
|
62
|
+
if (chart.type === "pivot" && chart.encoding?.series)
|
|
63
|
+
fields.push(chart.encoding.series);
|
|
64
|
+
return fields.filter(Boolean);
|
|
65
|
+
}
|
|
66
|
+
/** 分组聚合:输出每(维度组)一行的宽表(保留维度列 + 各度量列) */
|
|
67
|
+
export function aggregateRows(rows, chart) {
|
|
68
|
+
const groupFields = groupFieldsOf(chart);
|
|
69
|
+
const agg = chart.aggregation ?? "sum";
|
|
70
|
+
const measure = chart.encoding?.measure;
|
|
71
|
+
const measures = chart.encoding?.measures ?? (measure ? [measure] : []);
|
|
72
|
+
const keyOf = (row) => groupFields.map((f) => String(row[f] ?? "")).join("\u0001");
|
|
73
|
+
const groups = new Map();
|
|
74
|
+
for (const row of rows) {
|
|
75
|
+
const key = keyOf(row);
|
|
76
|
+
const bucket = groups.get(key);
|
|
77
|
+
if (bucket)
|
|
78
|
+
bucket.push(row);
|
|
79
|
+
else
|
|
80
|
+
groups.set(key, [row]);
|
|
81
|
+
}
|
|
82
|
+
const apply = (nums) => {
|
|
83
|
+
switch (agg) {
|
|
84
|
+
case "count":
|
|
85
|
+
return nums.length;
|
|
86
|
+
case "none":
|
|
87
|
+
return 0;
|
|
88
|
+
case "avg":
|
|
89
|
+
return AGG_FNS.avg(nums);
|
|
90
|
+
case "max":
|
|
91
|
+
return AGG_FNS.max(nums);
|
|
92
|
+
case "min":
|
|
93
|
+
return AGG_FNS.min(nums);
|
|
94
|
+
default:
|
|
95
|
+
return AGG_FNS.sum(nums);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const out = [];
|
|
99
|
+
for (const bucket of groups.values()) {
|
|
100
|
+
const row = {};
|
|
101
|
+
for (const f of groupFields)
|
|
102
|
+
row[f] = bucket[0]?.[f];
|
|
103
|
+
if (agg === "count" && measures.length === 0) {
|
|
104
|
+
// 纯计数:值列名用 measure 占位或固定 count
|
|
105
|
+
row[measure ?? "count"] = bucket.length;
|
|
106
|
+
}
|
|
107
|
+
for (const m of measures) {
|
|
108
|
+
row[m] = apply(bucket.map((r) => (agg === "count" ? 1 : toNumber(r[m]))));
|
|
109
|
+
}
|
|
110
|
+
// 非分组字段的长表 series 值在聚合后无意义(pivot 的列维度已保留),丢弃
|
|
111
|
+
out.push(row);
|
|
112
|
+
}
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
export function sortRows(rows, chart) {
|
|
116
|
+
const sort = chart.sort;
|
|
117
|
+
if (!sort)
|
|
118
|
+
return rows;
|
|
119
|
+
const dim = chart.encoding?.dimension ?? "";
|
|
120
|
+
const measure = chart.encoding?.measures?.[0] ?? chart.encoding?.measure ?? "";
|
|
121
|
+
const dir = sort.order === "desc" ? -1 : 1;
|
|
122
|
+
const sorted = [...rows].sort((a, b) => {
|
|
123
|
+
if (sort.by === "measure" && measure) {
|
|
124
|
+
return (toNumber(a[measure]) - toNumber(b[measure])) * dir;
|
|
125
|
+
}
|
|
126
|
+
return String(a[dim] ?? "").localeCompare(String(b[dim] ?? ""), "zh-CN") * dir;
|
|
127
|
+
});
|
|
128
|
+
return sort.topN && sort.topN > 0 ? sorted.slice(0, sort.topN) : sorted;
|
|
129
|
+
}
|
|
130
|
+
/** 渲染管线:过滤 → 聚合 → 排序/TopN,返回供 compile 消费的行 */
|
|
131
|
+
export function transformRows(chart, inputRows) {
|
|
132
|
+
let rows = applyFilters(inputRows, chart.filters);
|
|
133
|
+
if (shouldAggregate(chart)) {
|
|
134
|
+
rows = aggregateRows(rows, chart);
|
|
135
|
+
}
|
|
136
|
+
rows = sortRows(rows, chart);
|
|
137
|
+
return rows;
|
|
138
|
+
}
|
|
139
|
+
export function inferFieldType(rows, field) {
|
|
140
|
+
if (!rows?.length)
|
|
141
|
+
return "string";
|
|
142
|
+
let sawValue = false;
|
|
143
|
+
let allNumber = true;
|
|
144
|
+
let allDate = true;
|
|
145
|
+
for (const row of rows.slice(0, 100)) {
|
|
146
|
+
const v = row?.[field];
|
|
147
|
+
if (v === null || v === undefined || v === "")
|
|
148
|
+
continue;
|
|
149
|
+
sawValue = true;
|
|
150
|
+
if (allNumber && !Number.isFinite(Number(v)))
|
|
151
|
+
allNumber = false;
|
|
152
|
+
if (allDate && !(typeof v === "string" && /^[\d-]{8,}$/.test(v) && !Number.isNaN(Date.parse(v)))) {
|
|
153
|
+
allDate = false;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (!sawValue)
|
|
157
|
+
return "string";
|
|
158
|
+
if (allNumber)
|
|
159
|
+
return "number";
|
|
160
|
+
if (allDate)
|
|
161
|
+
return "date";
|
|
162
|
+
return "string";
|
|
163
|
+
}
|
|
164
|
+
// ============ 数值格式化(轴标签/标签/提示共用) ============
|
|
165
|
+
export function formatNumber(value, format) {
|
|
166
|
+
let n = Number.isFinite(value) ? value : 0;
|
|
167
|
+
if (format?.decimals !== undefined)
|
|
168
|
+
n = Number(n.toFixed(format.decimals));
|
|
169
|
+
let str = String(n);
|
|
170
|
+
if (format?.thousand)
|
|
171
|
+
str = str.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
172
|
+
return (format?.prefix ?? "") + str + (format?.suffix ?? "");
|
|
173
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 图型注册表:type → engine 映射。
|
|
3
|
+
* 内置 8 种 echarts 图型;引擎适配器包(bi-engine-s2 等)经
|
|
4
|
+
* registerChartType("pivot", "s2") 扩展设计器的图型选择与引擎解析。
|
|
5
|
+
*/
|
|
6
|
+
import type { BiChartType } from "../schema/types";
|
|
7
|
+
/** 边列表 / 矩阵型图:数据是边或三元组,默认不做维度聚合 */
|
|
8
|
+
export declare const NON_AGG_TYPES: Set<string>;
|
|
9
|
+
/** 注册新图型(设计器图型网格与 addChart 的引擎解析随之扩展);重复注册覆盖 */
|
|
10
|
+
export declare function registerChartType(type: string, engine: string): void;
|
|
11
|
+
/** 已注册的全部图型(内置 + 扩展,按注册顺序) */
|
|
12
|
+
export declare function getChartTypes(): BiChartType[];
|
|
13
|
+
/** 图型对应的引擎名(未注册图型回落 echarts) */
|
|
14
|
+
export declare function getEngineForType(type: string | undefined): string;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 图型注册表:type → engine 映射。
|
|
3
|
+
* 内置 8 种 echarts 图型;引擎适配器包(bi-engine-s2 等)经
|
|
4
|
+
* registerChartType("pivot", "s2") 扩展设计器的图型选择与引擎解析。
|
|
5
|
+
*/
|
|
6
|
+
const BUILTIN_CHART_TYPES = [
|
|
7
|
+
"bar",
|
|
8
|
+
"line",
|
|
9
|
+
"area",
|
|
10
|
+
"pie",
|
|
11
|
+
"donut",
|
|
12
|
+
"scatter",
|
|
13
|
+
"radar",
|
|
14
|
+
"gauge",
|
|
15
|
+
"funnel",
|
|
16
|
+
"treemap",
|
|
17
|
+
"sunburst",
|
|
18
|
+
"sankey",
|
|
19
|
+
"heatmap",
|
|
20
|
+
];
|
|
21
|
+
/** 边列表 / 矩阵型图:数据是边或三元组,默认不做维度聚合 */
|
|
22
|
+
export const NON_AGG_TYPES = new Set(["sankey", "graph", "heatmap"]);
|
|
23
|
+
const typeToEngine = new Map();
|
|
24
|
+
for (const t of BUILTIN_CHART_TYPES)
|
|
25
|
+
typeToEngine.set(t, "echarts");
|
|
26
|
+
/** 注册新图型(设计器图型网格与 addChart 的引擎解析随之扩展);重复注册覆盖 */
|
|
27
|
+
export function registerChartType(type, engine) {
|
|
28
|
+
typeToEngine.set(type, engine);
|
|
29
|
+
}
|
|
30
|
+
/** 已注册的全部图型(内置 + 扩展,按注册顺序) */
|
|
31
|
+
export function getChartTypes() {
|
|
32
|
+
return [...typeToEngine.keys()];
|
|
33
|
+
}
|
|
34
|
+
/** 图型对应的引擎名(未注册图型回落 echarts) */
|
|
35
|
+
export function getEngineForType(type) {
|
|
36
|
+
return typeToEngine.get(type ?? "") ?? "echarts";
|
|
37
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { BarSeriesOption, GaugeSeriesOption, LineSeriesOption, PieSeriesOption, RadarSeriesOption, ScatterSeriesOption } from "echarts/charts";
|
|
2
|
+
import type { ComposeOption } from "echarts/core";
|
|
3
|
+
import type { GridComponentOption, LegendComponentOption, TitleComponentOption, TooltipComponentOption } from "echarts/components";
|
|
4
|
+
import type { BiResolvedTheme } from "../theme";
|
|
5
|
+
import type { BiChartSchema, BiRow } from "../schema/types";
|
|
6
|
+
import type { ChartEngine } from "./types";
|
|
7
|
+
export type BiEChartsOption = ComposeOption<BarSeriesOption | LineSeriesOption | PieSeriesOption | ScatterSeriesOption | RadarSeriesOption | GaugeSeriesOption | TitleComponentOption | LegendComponentOption | TooltipComponentOption | GridComponentOption>;
|
|
8
|
+
/** schema + 行数据 + 主题模式 → ECharts option */
|
|
9
|
+
export declare function compileEcharts(chart: BiChartSchema, rows: BiRow[], theme: BiResolvedTheme): BiEChartsOption;
|
|
10
|
+
/**
|
|
11
|
+
* 创建 ECharts 引擎实例(幂等注册 echarts 模块)。
|
|
12
|
+
* handle 上带内部约定字段 __echartsInstance 供 bindEvents 取实例。
|
|
13
|
+
*/
|
|
14
|
+
export declare function createEchartsEngine(): ChartEngine;
|
|
15
|
+
/** 默认注册(调用方引入本模块后执行一次;重复注册无害) */
|
|
16
|
+
export declare function installEchartsEngine(): void;
|