☰
ECharts中国地图铁路线路可视化:悬浮提示与layui弹框交互实战
2026/10/15 1:03:36 网站建设 项目流程

1. 项目背景与核心需求拆解

1.1 这个项目到底要解决什么问题

先把标题拆开看:ECharts中国地图 + 悬浮提示 + 点击铁路弹出layui弹框。三个关键词串起来,其实就是一个典型的“数据可视化大屏交互”需求——用ECharts渲染一张中国地图作为底图,地图上叠加铁路线路图层,鼠标悬浮到铁路线上时显示提示信息(比如线路名称、起止城市、里程等),点击某条铁路时弹出一个layui的弹框,展示这条线路的详细信息。

这种需求在实际工作中出现的频率非常高。比如某物流公司的全国干线监控大屏、某铁路数据展示平台、某交通规划部门的线路可视化系统,都会用到类似的技术组合。ECharts负责地图渲染和交互,layui负责弹框UI,两者配合能快速搭出一个看起来专业、用起来顺手的可视化页面。

适合阅读这篇文章的人:前端开发工程师、数据可视化开发者、需要做大屏项目的技术人员,以及正在学习ECharts地图交互的进阶学习者。哪怕你之前只做过简单的柱状图、折线图,只要对ECharts有基本了解,跟着思路走就能复现出来。

1.2 为什么选ECharts + layui这个组合

ECharts在国内地图可视化领域的地位不用多说,它内置了geo坐标系和map系列,支持自定义地图数据,悬浮提示(tooltip)和点击事件(click)都有成熟的API。更重要的是,ECharts的社区生态好,中国地图的GeoJSON数据容易获取,铁路线路可以用lines系列或者自定义series来画。

layui则是一个经典的前端UI框架,它的layer模块弹框功能非常成熟,调用简单,样式统一,适合快速开发。虽然现在很多新项目转向了Vue/React组件库,但在一些传统企业项目、后台管理系统、大屏展示项目中,layui依然是主力。

两者结合的核心逻辑是:ECharts负责“图”和“交互触发”,layui负责“弹框展示”。ECharts的click事件拿到铁路线路的数据后,调用layer.open()把数据传进去渲染成弹框内容。这个分工非常清晰,不会出现职责混乱。

1.3 整体技术方案的设计思路

整个方案可以分成四层来理解:

  • 地图底图层:用ECharts的geo组件加载中国地图GeoJSON,设置地图样式(底色、边框、区域高亮等)。
  • 铁路线路层:用ECharts的lines系列或者自定义series,把铁路线路的经纬度坐标点渲染成线条,叠加在地图上。
  • 交互层:配置tooltip实现悬浮提示,绑定click事件实现点击响应。
  • 弹框层:用layui的layer模块,接收点击事件传来的数据,动态渲染弹框内容。

这个分层设计的好处是每一层职责单一,后续要改地图样式只动第一层,要加新的线路只动第二层,要改弹框内容只动第四层。维护起来不会牵一发动全身。

注意:ECharts版本选择很关键。建议用ECharts 5.x版本,它对地图的支持更完善,tooltip的formatter函数也更灵活。如果用4.x版本,部分API有差异,比如geo的配置项名称可能不同。

2. 核心细节解析与实操要点

2.1 中国地图数据的获取与注册

ECharts本身不包含地图数据,需要单独引入中国地图的GeoJSON。获取途径有几种:从ECharts官方示例仓库下载、从阿里云DataV的地图数据接口获取、或者用第三方工具从shapefile转换。不管哪种方式,最终拿到的是一个JSON文件,里面包含了中国各省份的边界坐标。

拿到GeoJSON后,需要调用echarts.registerMap('china', geoJsonData)把地图注册到ECharts实例中。这一步很关键,注册之后才能在geo组件或map系列中通过map: 'china'来引用。

// 假设geoJsonData是通过fetch或import拿到的中国地图GeoJSON echarts.registerMap('china', geoJsonData); // 然后在option中配置geo组件 option = { geo: { map: 'china', roam: true, // 允许缩放和拖拽 label: { show: false // 地图上的省份名称先隐藏,避免和铁路线重叠 }, itemStyle: { areaColor: '#0b1c3a', // 地图底色,深色系适合大屏 borderColor: '#1e90ff', borderWidth: 1 }, emphasis: { itemStyle: { areaColor: '#1a3a6b' // 鼠标悬浮到省份时的高亮色 } } } };

这里有个细节:roam: true允许用户缩放和拖拽地图,但如果你的铁路线路数据是固定坐标,缩放后线路位置会自动跟随,不需要额外处理。但如果用了自定义的series坐标系,就要注意坐标系的同步问题。

实操心得:地图GeoJSON文件不要直接放在项目里打包,建议用异步加载的方式。因为中国地图的GeoJSON文件通常有几百KB,直接打包进bundle会让首屏加载变慢。可以用fetch在组件挂载后再加载,加载完成后再初始化ECharts实例。

2.2 铁路线路数据的组织与渲染

铁路线路的数据本质上是一系列经纬度坐标点。每条铁路线路可以表示为一个数组,数组里每个元素是[经度, 纬度]。比如京广铁路可以简化为北京、石家庄、郑州、武汉、长沙、广州这几个关键节点的坐标连线。

数据组织方式建议用对象数组,每条线路一个对象:

const railwayData = [ { name: '京广铁路', coords: [ [116.407, 39.904], // 北京 [114.514, 38.042], // 石家庄 [113.625, 34.746], // 郑州 [114.305, 30.593], // 武汉 [112.938, 28.228], // 长沙 [113.264, 23.129] // 广州 ], startCity: '北京', endCity: '广州', mileage: 2298, description: '京广铁路是中国南北铁路大动脉,连接华北和华南地区。' }, // ... 更多线路 ];

渲染时用ECharts的lines系列:

const linesSeries = railwayData.map(item => ({ name: item.name, type: 'lines', coordinateSystem: 'geo', data: [{ coords: item.coords, // 把原始数据挂到data上,方便click事件取用 rawData: item }], lineStyle: { color: '#00d4ff', width: 2, curveness: 0.1, // 轻微弯曲,避免多条线路完全重叠 opacity: 0.8 }, emphasis: { lineStyle: { width: 4, color: '#ffcc00' // 悬浮时加粗变亮 } }, zlevel: 2 // 确保线路在地图上方 }));

这里有个关键点:coordinateSystem: 'geo'表示线路使用geo组件的坐标系,这样线路会跟随地图的缩放和拖拽自动调整位置。如果用了其他坐标系(比如cartesian2d),缩放地图时线路不会跟着动,那就乱套了。

注意:curveness参数控制线条弯曲程度,默认是0(直线)。铁路线路本身是弯曲的,但如果你只有关键节点坐标,用直线连接也能接受。加一点curveness可以让多条线路在视觉上更容易区分,但不要设太大,否则线路会偏离实际地理位置。

2.3 tooltip悬浮提示的配置技巧

ECharts的tooltip默认是显示series的name和data值,但对于铁路线路这种自定义数据,需要用到formatter函数来自定义提示内容。

tooltip: { trigger: 'item', // 注意:lines系列要用'item',不能用'axis' backgroundColor: 'rgba(10, 30, 60, 0.9)', borderColor: '#1e90ff', borderWidth: 1, textStyle: { color: '#ffffff', fontSize: 13 }, formatter: function(params) { // params.data.rawData 是我们之前挂上去的原始数据 if (params.data && params.data.rawData) { const d = params.data.rawData; return ` <div style="padding: 5px;"> <div style="font-weight: bold; color: #00d4ff; margin-bottom: 5px;">${d.name}</div> <div>起点:${d.startCity}</div> <div>终点:${d.endCity}</div> <div>里程:${d.mileage} 公里</div> </div> `; } return params.name; } }

这里有个坑:lines系列的tooltip触发方式必须是trigger: 'item',不能用'axis'。因为lines不是坐标轴系列,没有axis的概念。如果设成'axis',tooltip根本不会触发。

另一个坑是params.data.rawData的取值。ECharts在tooltip的formatter里传过来的params对象,params.data是当前数据项。如果你在data里直接写了rawData属性,就能通过params.data.rawData拿到。但如果你用的是dataset方式,取值路径会不一样。

实操心得:tooltip的formatter返回的HTML字符串里,不要用太复杂的样式。ECharts的tooltip是一个浮层div,样式支持有限。如果需要更复杂的展示,建议还是用点击弹框的方式,tooltip只做简单提示。

2.4 layui弹框的集成与数据传递

layui的layer模块弹框调用非常简单:

layui.use(['layer'], function() { var layer = layui.layer; // 在ECharts的click事件中调用 myChart.on('click', function(params) { if (params.data && params.data.rawData) { const d = params.data.rawData; const content = ` <div style="padding: 20px; line-height: 2;"> <h3 style="color: #1e90ff; margin-bottom: 15px;">${d.name}</h3> <table class="layui-table"> <tr><td style="width: 100px;">起点</td><td>${d.startCity}</td></tr> <tr><td>终点</td><td>${d.endCity}</td></tr> <tr><td>里程</td><td>${d.mileage} 公里</td></tr> <tr><td>描述</td><td>${d.description}</td></tr> </table> </div> `; layer.open({ type: 1, // 1表示页面层 title: '铁路线路详情', area: ['500px', 'auto'], content: content, shade: 0.3, // 遮罩透明度 shadeClose: true, // 点击遮罩关闭 maxmin: true, // 允许最大化最小化 skin: 'layui-layer-molv' // 墨绿风格,适合大屏 }); } }); });

这里的关键是数据传递:ECharts的click事件通过params.data.rawData拿到原始数据对象,然后拼成HTML字符串传给layer.open的content参数。整个过程是同步的,不需要异步请求。

注意:layer.open的content如果是HTML字符串,layui会把它插入到弹框的body里。如果字符串里有特殊字符(比如引号),要注意转义。另外,如果弹框内容需要绑定事件(比如按钮点击),要在layer.open的success回调里绑定,因为content插入DOM的时机是在success回调之前。

3. 完整实操流程与核心环节实现

3.1 环境准备与依赖引入

先列一下需要的东西:

  • ECharts 5.x:可以用CDN引入,也可以用npm安装。
  • layui 2.x:同样可以用CDN或npm。
  • 中国地图GeoJSON:从ECharts官方示例仓库或DataV获取。
  • 一个HTML文件或前端项目骨架。

用CDN的方式最简单,适合快速验证:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>铁路线路可视化</title> <link rel="stylesheet" href="https://cdn.staticfile.org/layui/2.8.18/css/layui.css"> <style> html, body { margin: 0; padding: 0; height: 100%; background: #0a1628; } #mapContainer { width: 100%; height: 100vh; } </style> </head> <body> <div id="mapContainer"></div> <script src="https://cdn.staticfile.org/echarts/5.4.3/echarts.min.js"></script> <script src="https://cdn.staticfile.org/layui/2.8.18/layui.js"></script> <script> // 后续代码写在这里 </script> </body> </html>

如果用npm项目,就npm install echarts layui,然后按模块化方式引入。layui的npm包用法和CDN略有不同,需要import layui from 'layui-src'或者用layui.use的方式。

实操心得:layui的CDN版本和npm版本在layer模块的调用方式上基本一致,但npm版本需要额外配置CSS的引入。如果项目用了webpack,可以用import 'layui-src/dist/css/layui.css'来引入样式。

3.2 地图初始化与铁路线路叠加

完整的初始化流程分三步:注册地图、配置option、初始化实例。

// 第一步:异步加载中国地图GeoJSON fetch('https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json') .then(res => res.json()) .then(geoJson => { // 注册地图 echarts.registerMap('china', geoJson); // 第二步:准备铁路线路数据 const railwayData = [ { name: '京广铁路', coords: [[116.407, 39.904], [114.514, 38.042], [113.625, 34.746], [114.305, 30.593], [112.938, 28.228], [113.264, 23.129]], startCity: '北京', endCity: '广州', mileage: 2298, description: '京广铁路是中国南北铁路大动脉。' }, { name: '京沪铁路', coords: [[116.407, 39.904], [117.200, 39.084], [117.000, 36.675], [118.796, 32.060], [121.473, 31.230]], startCity: '北京', endCity: '上海', mileage: 1318, description: '京沪铁路连接中国两大直辖市。' }, { name: '陇海铁路', coords: [[108.948, 34.263], [113.625, 34.746], [117.184, 34.261], [119.167, 34.600]], startCity: '西安', endCity: '连云港', mileage: 1759, description: '陇海铁路是中国东西向铁路干线。' } ]; // 第三步:配置option const option = { backgroundColor: '#0a1628', tooltip: { trigger: 'item', backgroundColor: 'rgba(10, 30, 60, 0.9)', borderColor: '#1e90ff', borderWidth: 1, textStyle: { color: '#fff', fontSize: 13 }, formatter: function(params) { if (params.data && params.data.rawData) { const d = params.data.rawData; return `<div style="padding:5px;"> <div style="font-weight:bold;color:#00d4ff;margin-bottom:5px;">${d.name}</div> <div>起点:${d.startCity}</div> <div>终点:${d.endCity}</div> <div>里程:${d.mileage} 公里</div> </div>`; } return params.name; } }, geo: { map: 'china', roam: true, zoom: 1.2, center: [104.0, 35.0], label: { show: false }, itemStyle: { areaColor: '#0b1c3a', borderColor: '#1e90ff', borderWidth: 1 }, emphasis: { itemStyle: { areaColor: '#1a3a6b' }, label: { show: true, color: '#fff' } } }, series: railwayData.map(item => ({ name: item.name, type: 'lines', coordinateSystem: 'geo', data: [{ coords: item.coords, rawData: item }], lineStyle: { color: '#00d4ff', width: 2, curveness: 0.1, opacity: 0.8 }, emphasis: { lineStyle: { width: 4, color: '#ffcc00' } }, zlevel: 2 })) }; // 初始化ECharts实例 const myChart = echarts.init(document.getElementById('mapContainer')); myChart.setOption(option); // 第四步:绑定click事件,弹出layui弹框 layui.use(['layer'], function() { const layer = layui.layer; myChart.on('click', function(params) { if (params.data && params.data.rawData) { const d = params.data.rawData; const content = ` <div style="padding:20px;line-height:2;"> <h3 style="color:#1e90ff;margin-bottom:15px;">${d.name}</h3> <table class="layui-table"> <tr><td style="width:100px;">起点</td><td>${d.startCity}</td></tr> <tr><td>终点</td><td>${d.endCity}</td></tr> <tr><td>里程</td><td>${d.mileage} 公里</td></tr> <tr><td>描述</td><td>${d.description}</td></tr> </table> </div> `; layer.open({ type: 1, title: '铁路线路详情', area: ['500px', 'auto'], content: content, shade: 0.3, shadeClose: true, maxmin: true, skin: 'layui-layer-molv' }); } }); }); });

这段代码可以直接复制到一个HTML文件里运行,前提是网络能访问CDN和GeoJSON接口。如果内网环境,需要把GeoJSON文件下载到本地,用相对路径引入。

3.3 参数计算与坐标优化

铁路线路的坐标点如果只取关键城市,线路会显得很“折”,不够平滑。有两种优化方式:

第一种是增加中间节点。比如京广铁路在北京和石家庄之间,可以加上保定(115.464, 38.874)的坐标。节点越多,线路越接近真实走向。

第二种是用贝塞尔曲线或样条插值。ECharts的lines系列本身不支持曲线插值,但可以在数据准备阶段用算法生成平滑曲线。比如用Catmull-Rom样条算法,把关键节点转换成密集的曲线点。

// 简单的Catmull-Rom样条插值示例 function catmullRom(points, numSegments) { const result = []; for (let i = 0; i < points.length - 1; i++) { const p0 = points[Math.max(0, i - 1)]; const p1 = points[i]; const p2 = points[i + 1]; const p3 = points[Math.min(points.length - 1, i + 2)]; for (let t = 0; t < numSegments; t++) { const s = t / numSegments; const s2 = s * s; const s3 = s2 * s; const lon = 0.5 * ((2 * p1[0]) + (-p0[0] + p2[0]) * s + (2 * p0[0] - 5 * p1[0] + 4 * p2[0] - p3[0]) * s2 + (-p0[0] + 3 * p1[0] - 3 * p2[0] + p3[0]) * s3); const lat = 0.5 * ((2 * p1[1]) + (-p0[1] + p2[1]) * s + (2 * p0[1] - 5 * p1[1] + 4 * p2[1] - p3[1]) * s2 + (-p0[1] + 3 * p1[1] - 3 * p2[1] + p3[1]) * s3); result.push([lon, lat]); } } result.push(points[points.length - 1]); return result; } // 使用 const smoothCoords = catmullRom(item.coords, 10);

这样每条线路的坐标点从原来的几个变成几十个,线条看起来就平滑多了。但要注意,插值后的坐标点数量增加,渲染性能会略有下降。如果线路很多(比如上百条),建议控制插值密度,或者只在缩放级别较高时才启用平滑。

注意:经纬度坐标的插值是在平面坐标系下做的,地球是曲面,大范围插值会有偏差。但对于中国地图这种尺度,偏差可以忽略不计。如果做全球地图,就需要用大圆航线算法了。

3.4 弹框内容的动态渲染与样式优化

layui的弹框内容支持HTML字符串,也支持DOM元素。如果弹框内容比较复杂,建议用DOM元素的方式,避免字符串拼接带来的转义问题。

// 用DOM元素的方式构建弹框内容 function createPopupContent(data) { const div = document.createElement('div'); div.style.padding = '20px'; div.style.lineHeight = '2'; const title = document.createElement('h3'); title.style.color = '#1e90ff'; title.style.marginBottom = '15px'; title.textContent = data.name; div.appendChild(title); const table = document.createElement('table'); table.className = 'layui-table'; const fields = [ ['起点', data.startCity], ['终点', data.endCity], ['里程', data.mileage + ' 公里'], ['描述', data.description] ]; fields.forEach(([label, value]) => { const tr = document.createElement('tr'); const td1 = document.createElement('td'); td1.style.width = '100px'; td1.textContent = label; const td2 = document.createElement('td'); td2.textContent = value; tr.appendChild(td1); tr.appendChild(td2); table.appendChild(tr); }); div.appendChild(table); return div; } // 在click事件中使用 myChart.on('click', function(params) { if (params.data && params.data.rawData) { const content = createPopupContent(params.data.rawData); layer.open({ type: 1, title: '铁路线路详情', area: ['500px', 'auto'], content: content, // 直接传DOM元素 shade: 0.3, shadeClose: true, maxmin: true, skin: 'layui-layer-molv' }); } });

用DOM元素的好处是数据绑定更安全,不会因为数据里有HTML特殊字符导致页面错乱。而且后续如果要给弹框里的元素绑定事件,直接操作DOM就行。

实操心得:layui的弹框在移动端表现一般,如果项目需要适配手机,建议用layer的mobile模式,或者换用其他移动端友好的弹框组件。另外,弹框的area参数如果设成'auto',高度会根据内容自动调整,但宽度最好固定,否则在不同屏幕上可能显示异常。

4. 常见问题与排查技巧实录

4.1 地图不显示或显示空白

这是最常见的问题,通常有以下几个原因:

GeoJSON没加载成功。打开浏览器控制台看Network面板,确认GeoJSON请求是否返回200。如果用的是本地文件,检查路径是否正确。如果用的是在线接口,检查是否有跨域问题。

registerMap没调用或调用时机不对。registerMap必须在setOption之前调用。如果GeoJSON是异步加载的,要确保在fetch的then回调里调用registerMap和setOption。

地图容器没有高度。ECharts初始化时需要容器有明确的宽高。如果容器是height: 100%但父元素没有高度,地图就渲染不出来。解决办法是给容器设一个固定高度,比如height: 100vh。

地图的center和zoom设置不当。如果center坐标偏了,地图可能显示在可视区域外。中国地图的默认center大概是[104.0, 35.0],zoom设为1.2左右比较合适。

4.2 铁路线路不显示或位置偏移

线路不显示的原因可能是:

  • coordinateSystem没设成'geo',导致线路用了错误的坐标系。
  • zlevel设置不当,线路被地图盖住了。把zlevel设成2或更高。
  • lineStyle的color和背景色太接近,看起来像没显示。换个亮色试试。

线路位置偏移的原因通常是坐标顺序搞反了。ECharts的geo坐标系是[经度, 纬度],如果写成了[纬度, 经度],线路就会跑到非洲去。检查一下数据里的坐标顺序。

4.3 tooltip不触发或内容不对

tooltip不触发的原因:

  • trigger设成了'axis',lines系列必须用'item'。
  • tooltip的formatter函数返回了空字符串或undefined。
  • params.data.rawData不存在,导致formatter走了默认分支。

tooltip内容不对的原因:

  • formatter里取的字段名和数据结构不一致。
  • HTML字符串里有未闭合的标签,导致渲染异常。

排查方法:在formatter函数里加console.log(params),看看params的结构到底是什么样的。这是最直接的排查方式。

4.4 layui弹框不弹出或样式错乱

弹框不弹出的原因:

  • layui的layer模块没加载成功。检查layui.use的回调是否执行。
  • click事件没绑定成功。检查myChart.on('click')是否在setOption之后调用。
  • params.data.rawData为空,导致if条件不成立。

弹框样式错乱的原因:

  • layui的CSS文件没引入。检查link标签的路径。
  • 弹框内容里的class名和layui的样式冲突。比如用了layui-table但没引入表格样式。
  • 弹框的area参数设置不合理,导致内容溢出或压缩。

4.5 常见问题速查表

问题现象可能原因排查方法解决方案
地图空白GeoJSON未加载Network面板检查请求确认路径和跨域配置
地图空白容器无高度检查CSS给容器设固定高度
线路不显示坐标系错误检查coordinateSystem设为'geo'
线路位置偏移坐标顺序反了检查数据改为[经度, 纬度]
tooltip不触发trigger类型错误检查trigger值改为'item'
tooltip内容为空rawData未挂载console.log(params)在data里加rawData
弹框不弹出layer未加载检查layui.use回调确认layui引入正确
弹框样式错乱CSS未引入检查link标签引入layui.css
地图缩放后线路偏移坐标系不同步检查coordinateSystem统一用'geo'
多条线路重叠curveness为0检查lineStyle设curveness为0.1-0.3

实操心得:排查ECharts问题时,善用myChart.getOption()查看当前配置,用myChart.getZr()查看渲染层。很多时候问题出在配置项没生效,而不是代码逻辑错误。另外,ECharts的官方文档和示例是最可靠的参考,遇到不确定的配置项,直接去官网搜。

4.6 性能优化与扩展建议

如果铁路线路很多(比如上百条),渲染性能会成为瓶颈。优化方向有几个:

减少坐标点数量。如果线路数据是从GPS轨迹来的,点可能非常密集。可以用Douglas-Peucker算法做抽稀,在保持线路形状的前提下减少点数。

用canvas渲染。ECharts默认用canvas渲染,但如果用了SVG渲染器,大量线条会导致DOM节点过多。确认renderer是canvas。

按需渲染。如果地图缩放级别较低,可以只显示主要干线,隐藏支线。监听georoam事件,根据zoom值动态调整series的显示。

用webgl渲染。ECharts 5.x支持webgl渲染,对于大量线条场景,webgl比canvas快很多。可以通过echarts.init(dom, null, { renderer: 'webgl' })启用。

扩展方面,可以给铁路线路加上动画效果,比如用effectScatter模拟列车运行,或者用lines的trailEffect实现流光效果。这些都能让大屏看起来更生动。

// 流光效果示例 lineStyle: { color: '#00d4ff', width: 2, curveness: 0.1, opacity: 0.8 }, effect: { show: true, period: 6, trailLength: 0.7, color: '#fff', symbolSize: 3 }

这个effect配置会让线路上有一个光点沿着线路移动,视觉效果很好,适合大屏展示。但要注意,effect会增加渲染开销,线路多的时候要谨慎使用。

5. 写在最后的一些个人体会

这个项目看起来简单,但实际做的时候细节很多。我踩过的坑包括:GeoJSON跨域、坐标顺序写反、tooltip的trigger类型搞错、layui弹框的content传了DOM元素但没等DOM渲染完就调用。每一个坑都花了不少时间排查。

最想分享的一条经验是:先把最小可运行版本跑通,再逐步加功能。不要一上来就写完整的代码,先确保地图能显示,再加一条线路,再加tooltip,再加弹框。每加一个功能就验证一次,这样出问题时能快速定位是哪一步引入的。

另外,ECharts的配置项非常多,不要试图记住所有参数。遇到不确定的,直接查官方文档的配置项手册,或者去ECharts的示例库找类似的例子改。官方示例库是最好的学习资源,没有之一。

最后,layui虽然是个老框架,但在一些特定场景下依然好用。它的layer弹框调用简单,样式统一,适合快速开发。如果你的项目已经在用layui,继续用它做弹框是完全合理的选择。如果项目是新起的,可以考虑用更现代的UI库,但核心的ECharts交互逻辑是一样的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询