一、概述
数据可视化提供了自定义图表模板的功能,以满足现有图表模板无法满足业务需求的情况。
二、如何使用
- 点击数据可视化页面头部的“图表模板”

- 点击
创建按钮后弹出图表模板表单,填写后提交保存
- 找到刚刚创建的图表模板,点击操作栏中的“低无一体”按钮

- 点击弹窗底部的“生成sdk”按钮

- 上一步操作完成后会重新刷新页面,再次找到该条数据,点击“低无一体”按钮,再次进来可以看到“下载模板工程”的按钮已经可以点击了,点击该按钮就可以下载到该自定义图表模板的示例代码包文件
kunlun-chart-sdk.zip
- 解压
kunlun-chart-sdk.zip后我们可以看到工程结构,在根目录下执行npm i安装依赖
- 可以看到
packages/kunlun-plugin/src/chart/CUSTOM_BAR.vue是我们自定义的图表vue组件,可以修改里面的自定义展示和逻辑处理 - 完成自定义代码后去根目录运行
npm run build打包代码,打包后可以在packages/kunlun-plugin/dist下看到打包后的js和css文件(如模板中无css则不会生成css文件,无需理会)
- 回到自定义图表模板的管理页面,找到对应的数据行,再次点击“低无一体”按钮,在弹窗内上传上一步生成的
kunlun-plugin.umd.js和kunlun-plugin.css文件,上传完成后点击弹窗底部的“确定”按钮保存
10. 进入图表的编辑页面,在图表分类选择处,可以看到柱状图的分类下有我们新增的“自定义柱状图”的子类,点击切换
11. 切换后可以看到图表已经从开始柱状图变成了我们在前面自定义的蓝色边框样式,内部是hello chart文字的图表。
二、示例自定义图表组件
本例子以echarts的图表库实现柱状图,框架自带的是以G2的库实现的柱状图 demo-echarts-bar.vue
vue
<template>
<div class="data-designer-chart-instance demo-echarts-bar" ref="designerChartViewRef">
<div class="data-designer-chart-container" ref="designerChartViewInnerRef"></div>
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted, ref, watch } from 'vue';
import DataSet from '@antv/data-set';
import * as echarts from 'echarts/core';
import { ECharts, EChartsCoreOption } from 'echarts/core';
import { GridComponent } from 'echarts/components';
import { BarChart, BarSeriesOption } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';
import { deepClone } from '@oinone/kunlun-dependencies';
import {
filterDimensionScaleColumns,
isSameObj,
ChartTypeEnum,
IChartData,
IChartDataResult,
chartViewMixin,
isNeedRerenderChart,
isShowChatView,
watchEchartsSize,
ChartRenderEngine
} from '@oinone/kunlun-data-designer-core';
echarts.use([GridComponent, BarChart, CanvasRenderer]);
export default defineComponent({
props: {
...chartViewMixin.props
},
data() {
return {
engine: ChartRenderEngine.ECHARTS,
chartType: [ChartTypeEnum.MAP_CHINA]
};
},
mixins: [chartViewMixin],
setup(props, { emit }) {
const chart = ref<ECharts>();
const designerChartViewRef = ref<HTMLElement>(null as any);
const designerChartViewInnerRef = ref<HTMLElement>(null as any);
onMounted(() => {
initChart();
});
let option = {} as EChartsCoreOption;
function initChart() {
chart.value = echarts.init(designerChartViewInnerRef.value);
option = {
yAxis: {
type: 'value'
}
};
}
let oldChartData = {} as IChartData;
watch(
() => props.chartData,
(newVal) => {
if (!newVal || !chart.value) {
return;
}
if (!isNeedRerenderChart(newVal, oldChartData)) {
oldChartData = deepClone(newVal);
return;
}
render(chart.value!, newVal, props.chartDataResult);
oldChartData = deepClone(newVal);
},
{
immediate: true,
deep: true
}
);
let oldChartDataResult = {} as IChartDataResult;
function watchDataList(chartData: IChartData, chartDataResult: IChartDataResult) {
oldChartDataResult = deepClone(props.chartDataResult);
if (!chart.value) {
initChart();
}
render(chart.value!, chartData, chartDataResult);
}
// 监听数据的变动自动重新渲染
watch(
() => props.chartDataResult.data,
() => {
if (isSameObj(oldChartDataResult, props.chartDataResult)) {
return;
}
if (!designerChartViewRef.value) {
onMounted(() => {
watchDataList(props.chartData, props.chartDataResult);
});
} else {
watchDataList(props.chartData, props.chartDataResult);
}
},
{ immediate: true, deep: true }
);
/**
* 自定义渲染逻辑
* @param chart echarts图表对象
* @param chartData 图表模板的定义
* @param chartDataResult chartDataResult.data存放的是后端返回的图表数据
*/
function render(chart: ECharts, chartData: IChartData, chartDataResult: IChartDataResult) {
if (!isShowChatView(chartData)) {
return;
}
if (!isSameObj(chartData, chartDataResult.chartData)) {
return;
}
const {
scales = [],
dimensions = [],
} = filterDimensionScaleColumns(chartData);
const dataList = !scales.length || !dimensions.length ? [] : ((chartDataResult.data! || []) as any[]);
dataList.forEach((a) => {
if (dimensions.length && !a.name) {
a.name = a[dimensions[0].chartField.displayName];
}
if (scales.length && !a.value) {
a.value = a[scales[0].chartField.displayName] || null;
}
});
const dv = new DataSet.DataView().source(dataList);
option.xAxis = {
type: 'category',
data: dv.rows?.map((a) => a?.name)
};
option.series = [
{
type: 'bar',
data: dv.rows?.map((a) => a?.value)
} as BarSeriesOption
];
chart.setOption(option);
}
// 监听图表容器大小
watchEchartsSize(props, chart!);
return { designerChartViewRef, designerChartViewInnerRef, chart };
}
});
</script>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
(一)注册该模板
typescript
import { ChartRenderEngine, ChartRenderType, registerChartComponent } from '@oinone/kunlun-data-designer-core';
import component from './demo-echarts-bar.vue';
registerChartComponent({
engine: ChartRenderEngine.ECHARTS,
render: ChartRenderType.CANVAS,
chartTemplateCode: 'test002'
},
{
component
} as any
);1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
(三)效果展示
