在低代码平台的核心能力中,报表引擎承担着数据可视化、业务数据汇总分析的关键角色,是企业用户快速获取数据价值的核心载体。Apache ECharts作为国内最流行的数据可视化库,凭借丰富的图表类型、灵活的配置能力和优秀的兼容性,成为低代码报表引擎的首选可视化方案。
宏天低代码平台的报表引擎,基于ECharts进行深度封装与定制,解决了原生ECharts在低代码场景下的复用性差、配置繁琐、与平台生态适配不足等问题,同时严格遵循ECharts开源协议,确保引用合规。本文将从图表组件封装、数据转换层、主题切换系统、导出功能实现四个核心维度,拆解宏天低代码报表引擎的封装实践,希望能为低代码平台开发者提供可参考的实操思路。
一、图表组件封装:从“重复开发”到“组件化复用”
原生ECharts的使用需要开发者手动初始化图表、配置option、处理容器适配和实例销毁,在低代码平台中,若每个报表都重复编写上述逻辑,会大幅降低开发效率,且难以保证代码一致性。基于此,我们对ECharts进行组件化封装,核心目标是实现“配置化调用、多场景复用、低成本适配”。
封装思路围绕“提取通用逻辑、暴露可配置接口”展开,具体实现分为三个层面:
1.1 基础封装:统一实例管理
将图表的初始化、销毁、resize适配等通用逻辑封装在基础组件中,避免重复编码。通过props接收容器宽高、图表类型、配置项等核心参数,内部自动处理实例创建与销毁,解决原生ECharts频繁初始化导致的性能问题和内存泄漏风险。
核心代码示例:
<template>
<div ref="chartRef" :style="{ width, height }" class="echarts-container" />
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch } from 'vue';
import * as echarts from 'echarts';
import type { EChartsOption, ECharts } from 'echarts';
const props = defineProps({
width: { type: [String, Number], default: '100%' },
height: { type: [String, Number], default: '400px' },
option: { type: Object as () => EChartsOption, required: true },
theme: { type: String, default: 'light' }
});
const chartRef = ref<HTMLDivElement>(null);
let chartInstance: ECharts | null = null;
// 初始化图表
const initChart = () => {
if (!chartRef.value) return;
// 销毁已有实例,避免重复渲染
if (chartInstance) {
chartInstance.dispose();
}
// 初始化实例,传入主题配置
chartInstance = echarts.init(chartRef.value, props.theme);
chartInstance.setOption(props.option, { notMerge: true });
};
// 监听窗口resize,适配图表尺寸
const handleResize = () => {
chartInstance?.resize();
};
onMounted(() => {
initChart();
window.addEventListener('resize', handleResize);
});
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
chartInstance?.dispose();
chartInstance = null;
});
// 监听配置项变化,重新渲染图表
watch(
() => props.option,
() => {
initChart();
},
{ deep: true }
);
</script>
<style scoped>
.echarts-container {
position: relative;
box-sizing: border-box;
min-width: 300px;
min-height: 300px;
transition: width 0.3s ease, height 0.3s ease;
}
</style>
1.2 业务封装:贴合低代码场景定制
在基础组件之上,结合宏天低代码平台的业务场景,封装折线图、柱状图、饼图、雷达图等常用业务图表组件,预设行业通用配置(如坐标轴样式、图例位置、tooltip格式),用户只需传入数据,即可快速生成符合业务需求的报表图表。
例如,针对企业管理报表场景,封装“数据对比柱状图”组件,预设双Y轴配置、数据标签显示、hover高亮效果,用户无需手动配置复杂的option,仅需传入“对比数据”“坐标轴名称”等简单参数,即可完成图表渲染,大幅降低非技术用户的使用门槛。
1.3 扩展性设计:支持自定义配置覆盖
为满足高级用户的个性化需求,组件预留自定义option接口,允许用户通过传入额外配置,覆盖预设样式和逻辑,实现“基础配置零代码、高级配置可定制”的灵活模式。同时,支持组件嵌套,可将多个图表组件组合成复杂报表看板,适配多维度数据展示场景。
二、数据转换层:打通“多源数据”到“可视化图表”的壁垒
低代码平台的报表数据来源具有多样性,可能来自数据库、接口、Excel导入、自定义数据集等,而ECharts对数据格式有固定要求(如数组、对象数组),若直接将原始数据传入图表组件,会导致图表渲染失败。因此,我们设计了数据转换层,作为报表引擎与ECharts之间的“桥梁”,核心作用是实现多源数据的标准化处理。
数据转换层的核心设计思路的是“分层处理、可扩展、可复用”,具体分为三个步骤:
2.1 数据接入:统一多源数据入口
封装统一的数据接入接口,支持对接不同类型的数据源,将数据库查询结果、接口返回数据、Excel解析数据等,统一转换为标准的JSON格式,消除数据来源差异带来的格式混乱问题。例如,将数据库返回的二维表数据,转换为ECharts所需的“xData数组 + series数据数组”格式。
2.2 数据清洗与转换:标准化处理
针对接入的原始数据,进行清洗、过滤、格式化处理,解决数据缺失、格式错误、冗余等问题,同时根据图表类型,将数据转换为对应的格式。例如:
- 折线图/柱状图:将原始数据转换为「x轴数据数组 + 系列数据数组」,处理数据为空时的默认显示(如显示0或空值提示);
- 饼图:将原始数据转换为「{name: string, value: number}」格式,过滤value为0的无效数据;
- 雷达图:将多维度数据转换为「indicator数组 + 系列数据数组」,统一指标名称和数据范围。
核心代码示例(数据转换工具函数):
/**
* 柱状图数据转换:将原始表格数据转换为ECharts所需格式
* @param rawData 原始数据(数组对象)
* @param xKey x轴对应的数据字段
* @param seriesKeys 系列数据对应的数据字段(支持多系列)
* @returns 转换后的ECharts数据格式
*/
export const transformBarData = (rawData: Record<string, any>[], xKey: string, seriesKeys: string[]) => {
if (!rawData.length || !xKey || !seriesKeys.length) return { xData: [], series: [] };
// 提取x轴数据,去重并保持顺序
const xData = Array.from(new Set(rawData.map(item => item[xKey])));
// 处理系列数据
const series = seriesKeys.map(key => {
return {
name: key,
type: 'bar',
data: xData.map(x => {
const item = rawData.find(item => item[xKey] === x);
// 处理空值,避免图表渲染异常
return item?.[key] ?? 0;
})
};
});
return { xData, series };
};
2.3 数据缓存与更新:提升性能
针对高频访问的报表数据,设计数据缓存机制,避免重复请求数据源和重复转换数据,提升报表渲染速度。同时,监听数据源变化,当原始数据更新时,自动触发数据转换和图表重渲染,确保报表数据的实时性。
三、主题切换系统:实现“平台风格统一+个性化适配”
宏天低代码平台支持系统级主题切换(浅色/深色),报表引擎作为平台的核心模块,需与系统主题保持一致,同时允许用户根据需求自定义图表主题。基于ECharts的主题机制,我们设计了分层主题切换系统,实现“系统主题联动+自定义主题覆盖”的双重能力。
3.1 主题注册:预设系统主题
根据宏天低代码平台的UI设计规范,自定义浅色、深色两套基础主题,通过ECharts的registerTheme方法注册到全局,主题内容包括图表配色、字体样式、坐标轴样式、图例样式等,确保报表图表与平台整体风格统一。
核心代码示例(主题注册):
import * as echarts from 'echarts';
// 浅色主题配置(贴合平台浅色风格)
const lightTheme = {
color: ['#188df0', '#2378f7', '#4096ff', '#69b1ff', '#91cfff'],
backgroundColor: '#ffffff',
textStyle: { color: '#333333' },
axisLine: { lineStyle: { color: '#e5e6eb' } },
legend: { textStyle: { color: '#666666' } }
};
// 深色主题配置(贴合平台深色风格)
const darkTheme = {
color: ['#4096ff', '#7cb305', '#ffc53d', '#ff8a00', '#f5222d'],
backgroundColor: '#1f2937',
textStyle: { color: '#e5e7eb' },
axisLine: { lineStyle: { color: '#374151' } },
legend: { textStyle: { color: '#d1d5db' } }
};
// 注册主题到ECharts全局
echarts.registerTheme('hongtian-light', lightTheme);
echarts.registerTheme('hongtian-dark', darkTheme);
3.2 主题联动:与系统主题同步
通过监听平台系统主题的切换事件,自动切换报表图表的主题,无需用户手动操作。核心逻辑是:当系统主题切换时,获取当前主题名称,重新初始化图表实例并传入对应主题,同时通过配置净化避免主题样式残留,实现无缝切换,解决原生ECharts主题切换时的闪烁问题。
核心代码示例(主题联动):
// 监听系统主题变化(假设平台提供themeChange事件)
import { onMounted, watch } from 'vue';
import { useThemeStore } from '@/store/theme'; // 平台主题状态管理
const themeStore = useThemeStore();
// 监听主题变化,切换图表主题
watch(
() => themeStore.currentTheme,
(newTheme) => {
// 映射平台主题到ECharts注册的主题
const echartsTheme = newTheme === 'light' ? 'hongtian-light' : 'hongtian-dark';
// 重新初始化图表,传入新主题
initChart(echartsTheme);
},
{ immediate: true }
);
3.3 自定义主题:支持个性化配置
为满足用户个性化需求,提供主题自定义功能,允许用户通过颜色选择器、样式配置面板,修改图表的配色、字体、边框等样式,实时预览效果,修改完成后自动生成自定义主题配置,并覆盖系统主题,同时支持主题保存和复用,适配不同业务场景的视觉需求。
四、导出功能实现:满足“数据留存+多场景复用”需求
企业用户在使用报表时,常常需要将报表图表或数据导出,用于汇报、存档、二次分析等场景。基于ECharts的导出能力,我们扩展实现了多格式、多场景的导出功能,同时优化导出性能和用户体验,支持图表导出、数据导出两种核心模式。
4.1 图表导出:多格式适配
基于ECharts的exportToCanvas和exportToSVG方法,封装图表导出功能,支持PNG、JPEG、SVG三种图片格式,满足不同场景需求:PNG/JPEG适用于汇报、演示;SVG适用于矢量图编辑、高清打印。
核心优化点:
- 设置导出分辨率倍率(pixelRatio: 2),提升导出图片清晰度;
- 导出时忽略工具栏组件,避免导出内容冗余;
- 添加导出加载状态,避免用户重复点击;
- 处理大数据量图表导出卡顿问题,通过节流控制导出频率。
核心代码示例(图表导出为PNG):
/**
* 图表导出为PNG
* @param chartInstance ECharts实例
* @param fileName 导出文件名
*/
export const exportChartAsPNG = async (chartInstance: ECharts, fileName: string = '报表图表') => {
try {
// 显示加载状态
showLoading('正在导出,请稍候...');
// 导出Canvas,设置高清分辨率
const canvas = await chartInstance.exportToCanvas({ pixelRatio: 2 });
// 转换为图片链接并下载
const a = document.createElement('a');
a.download = `${fileName}.png`;
a.href = canvas.toDataURL('image/png');
a.click();
// 隐藏加载状态
hideLoading();
} catch (error) {
hideLoading();
showMessage('导出失败,请重试', 'error');
console.error('图表导出失败:', error);
}
};
4.2 数据导出:支持Excel格式
除了图表导出,用户还需要导出报表的原始数据,用于二次分析。我们基于xlsx库,封装数据导出功能,将报表的原始数据或转换后的数据,导出为Excel格式,支持多sheet页导出(如图表数据、原始数据分开导出),同时保留数据格式和表头信息。
4.3 批量导出:提升效率
针对多图表报表看板场景,支持批量导出功能,用户可选择需要导出的图表或数据,一键导出为压缩包,包含所有选中的图表图片和Excel数据文件,大幅提升多报表导出的效率。
五、ECharts引用合规说明
宏天低代码平台的报表引擎,基于Apache ECharts(Apache License, Version 2.0)进行封装开发,严格遵循开源协议要求,确保引用合规:
- 保留ECharts的版权声明和开源协议信息,未修改ECharts核心源码;
- 基于ECharts进行的二次开发(组件封装、功能扩展),遵循Apache License 2.0协议要求,开源相关封装代码;
- 在平台文档和报表引擎说明中,明确标注所使用的ECharts版本和开源协议,尊重开源作者权益。
六、实践总结与优化方向
基于ECharts的宏天低代码报表引擎封装实践,核心是围绕“低代码场景需求”,解决原生ECharts的复用性、适配性、易用性问题,通过组件化封装、标准化数据转换、灵活的主题切换和完善的导出功能,满足企业用户的报表可视化需求,同时确保开源引用合规。
目前,该报表引擎已在宏天低代码平台中广泛应用,覆盖企业管理、数据分析、业务监控等多个场景,有效降低了报表开发成本,提升了用户使用体验。