ECharts进阶:自定义Loading动画提升数据可视化体验

张开发
2026/4/16 2:49:13 15 分钟阅读

分享文章

ECharts进阶:自定义Loading动画提升数据可视化体验
1. 为什么需要自定义Loading动画在大屏数据可视化项目中我们经常会遇到多个图表同时加载的情况。由于数据来源不同、接口响应速度差异某些图表可能需要较长时间才能完成数据获取和渲染。这时候如果没有任何提示用户可能会误以为页面卡顿或者功能失效体验非常糟糕。我去年参与过一个智慧城市大屏项目里面包含12个实时更新的ECharts图表。测试阶段就有用户反馈说有些图表偶尔会空白几秒钟。后来我们加入了自定义Loading动画用户等待时的焦虑感明显降低项目验收时获得了客户的高度评价。ECharts自带的showLoading/hideLoading API就是为解决这类问题而生的。但很多人只是简单调用默认效果其实这个功能远比想象中强大。通过合理配置你可以实现品牌视觉统一的加载动画不同数据类型的差异化提示多图表加载的进度反馈网络异常时的友好提示2. 基础配置与核心参数解析2.1 快速上手基础用法先来看最基本的实现方式这也是大多数开发者最先接触的写法const chart echarts.init(document.getElementById(chart)); chart.showLoading(); // 模拟数据加载 fetch(/api/data).then(data { chart.setOption(data); chart.hideLoading(); });这种最简单的调用会显示ECharts默认的旋转动画和loading文字。但实际项目中我们通常需要更精细的控制。showLoading方法接受两个参数type目前仅支持default类型opts配置对象这才是真正的重点2.2 核心配置参数详解opts对象支持以下关键属性以v5.4.0版本为例参数类型默认值说明textstringloading显示的文字内容colorstring#c23531旋转动画颜色textColorstring#000文字颜色maskColorstringrgba(255,255,255,0.8)遮罩层颜色zlevelnumber0图形层级fontSizenumber12文字大小showSpinnerbooleantrue是否显示旋转动画spinnerRadiusnumber10旋转动画半径lineWidthnumber5旋转动画线宽fontWeightstringnormal文字粗细fontStylestringnormal文字样式fontFamilystringsans-serif字体实际项目中我常用的一个配置示例chart.showLoading({ text: 数据加载中..., color: #1890ff, textColor: #666, maskColor: rgba(0, 0, 0, 0.1), fontSize: 14, spinnerRadius: 12, lineWidth: 4 });3. 高级定制技巧3.1 多图表协同加载方案在大屏项目中经常需要处理多个图表的加载状态。这里分享一个实用的封装方法class ChartLoader { constructor(charts) { this.charts Array.isArray(charts) ? charts : [charts]; this.loadingCount 0; } show(text) { this.loadingCount; this.charts.forEach(chart { chart.showLoading({ text: text || 加载中 (${this.loadingCount}/${this.charts.length}), maskColor: rgba(0, 0, 0, 0.05) }); }); } hide() { if (--this.loadingCount 0) { this.charts.forEach(chart chart.hideLoading()); this.loadingCount 0; } } } // 使用示例 const chart1 echarts.init(document.getElementById(chart1)); const chart2 echarts.init(document.getElementById(chart2)); const loader new ChartLoader([chart1, chart2]); // 开始加载 loader.show(数据加载中...); // 某个图表加载完成 fetch(/api/data1).then(data { chart1.setOption(data); loader.hide(); }); // 另一个图表加载完成 fetch(/api/data2).then(data { chart2.setOption(data); loader.hide(); });这个方案实现了统一的加载状态管理进度提示功能自动化的状态同步防止过早隐藏loading3.2 自定义SVG动画虽然ECharts官方只提供了默认的旋转动画但我们可以通过一些技巧实现自定义SVG动画。这里分享一个实战中验证过的方案function showCustomLoading(chart, options {}) { // 先隐藏默认loading chart.hideLoading(); // 创建自定义容器 const container chart.getDom(); const loader document.createElement(div); loader.className custom-loader; loader.innerHTML svg viewBox0 0 50 50 circle cx25 cy25 r20 fillnone stroke${options.color || #1890ff} stroke-width4/circle /svg div classloader-text${options.text || 加载中...}/div ; // 添加样式 const style document.createElement(style); style.textContent .custom-loader { position: absolute; top: 0; left: 0; right: 0; bottom: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; background: ${options.maskColor || rgba(255,255,255,0.7)}; z-index: 1000; } .custom-loader svg { width: 50px; height: 50px; animation: rotate 2s linear infinite; } .custom-loader circle { stroke-dasharray: 90, 150; stroke-dashoffset: 0; animation: dash 1.5s ease-in-out infinite; } .custom-loader .loader-text { margin-top: 10px; color: ${options.textColor || #666}; font-size: ${options.fontSize || 14}px; } keyframes rotate { 100% { transform: rotate(360deg); } } keyframes dash { 0% { stroke-dasharray: 1, 150; stroke-dashoffset: 0; } 50% { stroke-dasharray: 90, 150; stroke-dashoffset: -35; } 100% { stroke-dasharray: 90, 150; stroke-dashoffset: -124; } } ; container.appendChild(style); container.appendChild(loader); // 返回隐藏方法 return () { container.removeChild(loader); container.removeChild(style); }; } // 使用示例 const chart echarts.init(document.getElementById(chart)); const hideLoading showCustomLoading(chart, { text: 正在获取最新数据, color: #ff4d4f }); // 数据加载完成后 fetch(/api/data).then(data { chart.setOption(data); hideLoading(); });4. 性能优化与常见问题4.1 性能优化建议遮罩层优化maskColor使用rgba时alpha值不宜过大。实测发现当设置为0.8以上时在某些低端设备上会出现渲染性能问题。推荐使用0.1-0.3之间的透明度。动画性能如果自定义CSS动画建议使用transform和opacity属性硬件加速避免使用box-shadow等耗性能的属性简化动画复杂度内存管理SPA项目中一定要在组件销毁时移除loading// Vue示例 beforeDestroy() { this.chart this.chart.hideLoading(); this.chart.dispose(); }4.2 常见问题解决方案问题1调用hideLoading后动画仍然可见原因通常是因为在setOption之前调用了hideLoading解决// 正确顺序 chart.setOption(data); chart.hideLoading(); // 错误顺序 chart.hideLoading(); chart.setOption(data);问题2移动端显示模糊原因旋转动画使用了非整数像素的lineWidth解决chart.showLoading({ lineWidth: Math.floor(devicePixelRatio) // 根据设备像素比调整 });问题3多图表加载不同步解决使用第3.1节的ChartLoader方案或者考虑Promise.allPromise.all([ fetch(/api/data1), fetch(/api/data2) ]).then(([data1, data2]) { chart1.setOption(data1); chart2.setOption(data2); chart1.hideLoading(); chart2.hideLoading(); });

更多文章