ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Echarts动态K线图实战:从数据处理到性能优化的完整方案

Echarts动态K线图实战:从数据处理到性能优化的完整方案 我有段时间做行情数据可视化大屏K线图这块需求一出来团队里第一反应就是拿Echarts做。其实从纯技术角度看手写Canvas也不是不行但真正把动态K线做到能看、能用、不卡、不崩Echarts的candlestick系列确实是最省力的路径。这篇就当作一次项目复盘把从选型到数据预处理、核心配置、动态更新、交互优化再到我实际踩过的一堆坑完整捋一遍。不管你是刚接触Echarts的新手还是已经被K线图的数据刷新、性能优化折磨过的老手这篇应该都能给你一些可以直接用的东西。1. 为什么用Echarts做K线图选型逻辑和方案对比我最早接到这个需求的时候第一反应不是用哪个库而是先想清楚一个事K线图和普通折线图、柱状图有什么本质区别普通图表展示的是趋势K线图展示的是一段周期内的价格博弈。它每一根柱子都包含开盘、收盘、最高、最低四个价格这四个价格之间的关系决定了K线的实体和影线形态。再加上我们通常还要叠加成交量、均线、涨跌幅标记数据处理和绘制的复杂度就上来了。如果用原生Canvas去实现你需要自己处理坐标换算、柱子绘制、十字光标、缩放交互、动态刷新时的重绘逻辑。不是说做不到而是这套东西做完并稳定下来至少得两到三周。而Echarts在这块是成熟的它内置了专门的candlestick系列类型各种交互和渲染细节都已经处理得很完善开发时间可以压缩到一两天。除了K线图本身我选择Echarts还有几个现实原因生态成熟不管是折线图、饼图还是中国地图Echarts都有现成的配置方案。我这次大屏项目里除了K线图还有折线图、柱状图、饼图甚至柱状图还想用自定义图片做柱子展示。全部用Echarts统一处理维护成本最低。数据量大时的渲染性能Echarts底层基于Canvas几千根K线渲染起来没什么压力配合dataZoom还能做到分段渲染。社区资源丰富遇到问题搜一下基本都有答案。比如tooltip自动换行、饼图labelLine偏移、3D柱状图这些话题社区里都有大量现成的讨论。有一说一Echarts也有一些让人头疼的地方。比如版本差异导致的配置项不兼容Vue3下pxtorem对Echarts的字体不生效大屏适配要额外处理。但这些属于使用成本不是选型成本整体还是利大于弊。版本选择上我建议直接用5.x版本。4.x虽然稳定但5.x在性能、tree-shaking、主题定制方面都有明显改进。用npm安装npm install echarts或者直接用CDNscript srchttps://cdn.jsdelivr.net/npm/echarts5/dist/echarts.min.js/script如果项目只需要K线、折线、柱状这几个核心图表可以考虑按需引入import * as echarts from echarts/core; import { CandlestickChart, LineChart, BarChart } from echarts/charts; import { GridComponent, TooltipComponent, DataZoomComponent, LegendComponent } from echarts/components; import { CanvasRenderer } from echarts/renderers; echarts.use([ CandlestickChart, LineChart, BarChart, GridComponent, TooltipComponent, DataZoomComponent, LegendComponent, CanvasRenderer ]);按需引入的好处是打包体积能小不少尤其项目本身对首屏体积有要求的话这个优化很值得做。2. 动态K线的数据地基OHLC结构与坐标轴校准很多人一上来就写option结果图表渲染出来乱七八糟。问题基本都出在数据格式和坐标轴设置上。这部分我说透一点避免你走弯路。2.1 K线的数据格式Echarts的candlestick系列数据格式是嵌套数组每根K线对应一个子数组[open, close, lowest, highest]注意这个顺序不是开盘、最高、最低、收盘而是开盘、收盘、最低、最高。我第一次写的时候按OHLC顺序传数据结果整个图表的影线和实体全乱了找了半天才发现是顺序问题。最终传入series的data是一个二维数组或者每个元素还包含一个时间字段。比如const data [ [2024-01-02, 3200, 3300, 3180, 3350], [2024-01-03, 3310, 3400, 3290, 3420], // ...更多数据 ];这里第一个字段是时间后面跟open、close、lowest、highest。2.2 x轴类型选择为什么K线图通常用categoryK线图的x轴有两种常见设置type: category和type: time。我实际用下来的经验是做K线图优先用category不用time。原因很简单K线数据天然是按交易周期逐根排列的用category每一根K线对应一个固定的索引位置配合dataZoom缩放时行为非常符合直觉。用time轴的话两个交易日之间如果间隔了一个周末显示上会出现空隙视觉上不连续。做日K、周K时尤其明显。time轴在数据量大的时候性能开销也更大因为没有必要在时间轴上做等距映射。x轴对应的数据可以这样设置xAxis: { type: category, data: data.map(item item[0]), // 时间数组 boundaryGap: true, // K线在category轴上通常设为true让柱子不贴边 }2.3 数据预处理的几个细节盘中动态刷新时数据容易出现重复、缺失、乱序。这里分享几个我常用的预处理技巧按时间升序排列K线图对数据顺序极其敏感一旦顺序乱了K线的连接和均线计算全都会出错。每次拿到新数据先按时间排序。去重相同时间戳的数据只保留最新一条避免出现一根时间点上叠了两根K线的问题。缺失日期处理如果是日K有些日期因为停牌、节假日没有数据。用category轴时日期数组里如果没有那一天这一格就会空着如果希望它连续显示可以在日期数组里补充空数据比如[time, null, null, null, null]Echarts会跳过绘制。这些看起来不起眼的细节反而是动态K线图能稳定跑起来的关键。2.4 y轴与grid布局K线图通常会把主图和成交量分成上下两个区域这种布局是靠两个grid实现的。主图放K线和均线副图放成交量两个grid之间留一点间距。grid: [ { left: 60, right: 20, top: 30, height: 60% }, { left: 60, right: 20, top: 75%, height: 18% } ],主K线图区域和成交量区域各自独立缩放的时候配合dataZoom的xAxisIndex: [0, 1]就能实现两个区域联动缩放。y轴也分两个yAxis: [ { scale: true, gridIndex: 0 }, // 主图y轴不用设min/maxscale:true让图表自动适配数据区间 { gridIndex: 1, splitLine: { show: false } } // 成交量y轴 ]这里特别提一下scale: true。K线图的y轴不要强制从0开始。如果某只股票的股价在3200到3400之间波动y轴从0开始的话K线的波动幅度会被压缩成一条几乎看不出变化的直线。scale: true会让y轴根据当前可见数据自动调整区间这也是炒股软件里K线图的标准做法。3. 核心Option逐项拆解做出一个能看的K线图数据格式理清了接下来就是把option搭起来。我直接从实际项目里抽一段简化的配置来逐项讲。const option { animation: false, // 动态数据下建议关闭动画 legend: { data: [日K, MA5, MA10, MA20], top: 10 }, tooltip: { trigger: axis, axisPointer: { type: cross } }, grid: [ { left: 70, right: 20, top: 40, height: 55% }, { left: 70, right: 20, top: 75%, height: 15% } ], xAxis: [ { type: category, data: dateList, gridIndex: 0, boundaryGap: true, axisLine: { lineStyle: { color: #ccc } }, axisLabel: { show: true } }, { type: category, data: dateList, gridIndex: 1, axisLabel: { show: false }, axisTick: { show: false }, splitLine: { show: false }, boundaryGap: true } ], yAxis: [ { scale: true, gridIndex: 0, splitLine: { lineStyle: { color: #f0f0f0 } } }, { gridIndex: 1, splitLine: { show: false }, axisLabel: { show: true } } ], dataZoom: [ { type: inside, xAxisIndex: [0, 1], start: 60, end: 100 }, { type: slider, xAxisIndex: [0, 1], top: 92%, height: 20, start: 60, end: 100 } ], series: [ { name: 日K, type: candlestick, data: klineData, itemStyle: { color: #ef232a, color0: #14b143, borderColor: #ef232a, borderColor0: #14b143 } }, { name: MA5, type: line, data: maData[5], smooth: true, showSymbol: false, lineStyle: { width: 1 } }, { name: MA10, type: line, data: maData[10], smooth: true, showSymbol: false, lineStyle: { width: 1 } }, { name: MA20, type: line, data: maData[20], smooth: true, showSymbol: false, lineStyle: { width: 1 } }, { name: 成交量, type: bar, xAxisIndex: 1, yAxisIndex: 1, data: volumeData } ] };这段option里面有几个重点**第一阴阳线的颜色设置。**中国股市习惯是红涨绿跌和欧美的绿涨红跌正好相反。所以你必须在itemStyle里明确指定color是阳线填充色color0是阴线填充色borderColor和borderColor0对应的是两条边框的颜色。如果不设置Echarts默认用的是红涨绿跌还是绿涨红跌我记得不同版本还有差别所以最好还是自己写死别依赖默认值。**第二dataZoom的start和end。**默认显示最近40%的K线比如start: 60, end: 100。这样打开页面就能直接看到最新一段行情也避免初始渲染上万根K线带来的卡顿。**第三成交量为什么用bar。**很多人会以为成交量就是柱状图这不冲突直接在series数组里加一个type: bar类型的系列同时指定xAxisIndex: 1, yAxisIndex: 1映射到下面的grid区域。成交量的颜色可以参考涨跌比如涨的时候红色跌的时候绿色itemStyle: { color: function(params) { const index params.dataIndex; const klineItem klineData[index]; return klineItem[0] klineItem[1] ? #ef232a : #14b143; } }**第四均线MA的计算。**均线不是Echarts帮你算的得自己在数据预处理阶段算好。MA5就是连续5根K线收盘价的平均值function calcMA(dayCount, klineData) { const result []; for (let i 0; i klineData.length; i) { if (i dayCount - 1) { result.push(-); } else { let sum 0; for (let j 0; j dayCount; j) { sum klineData[i - j][1]; // 收盘价是第二位 } result.push((sum / dayCount).toFixed(2)); } } return result; }注意如果某根的位置不足dayCount根需要补一个-占位Echarts中这个值相当于null不会绘制点。4. 让K线动起来动态更新的完整方案很多K线图表项目静态展示其实不难难的是让K线像真实行情软件一样每隔几秒自动追加最新一根K线或者本地成交量持续变化。下面我把动态更新的几种方案都梳理一遍。4.1 setOption的合并机制动态更新的核心Echarts动态更新的核心是setOption的合并机制。你不需要每次把整个图表重新渲染只需要传入要更新的数据片段chart.setOption({ series: [ { data: newKlineData }, ] });这里有个关键点**Echarts默认是merge模式不是replace模式。**如果你新传入的data比原来的短图表不会自动截断而是保留多余部分。这就导致一个经典bug数据源更新后图表上总是残留旧数据。解决方法是在更新时明确处理数据要么在外部维护一份完整的最新数据数组每次都整体替换chart.setOption({ xAxis: { data: newDateList }, series: [ { data: newKlineData }, { data: newMa5 }, // ... ] });要么当你确实想清空旧数据再更新时用notMerge: truechart.setOption(option, true);但notMerge: true是把整个图表配置重置动态刷新时通常不需要这样。实际项目里我建议统一采用外部维护完整数据每次全量setOption的策略。看起来每次传了一堆数据但这个做法的好处是代码逻辑简单、不容易出状态错乱的问题。在几千根K线的规模下性能完全能接受。4.2 定时轮询简单的实时行情方案如果你的数据源是REST接口而不是WebSocket最常见的方案就是setInterval轮询function fetchData() { fetch(/api/kline?symbolBTCUSDT) .then(res res.json()) .then(data { // data是后端返回的最新K线数组 updateChart(data); }); } setInterval(fetchData, 3000);注意一点不要在setInterval回调里做重活。比如每次轮询都在前端重新算一遍所有均线、重新格式化几千个日期字符串这些操作都很耗性能。正确做法是后端把均线也一并算好返回或者前端只在数据有变化时才重新计算。4.3 WebSocket实时推送增量更新的最佳实践如果是做真正的实时行情就得靠WebSocket。这时候增量更新的优势就体现出来了。const ws new WebSocket(wss://your-api/ws/kline); ws.onmessage function(event) { const tick JSON.parse(event.data); // tick: { time: 2024-01-03 10:30:00, open: 3200, close: 3300, low: 3180, high: 3350, volume: 12345 } // 判断是更新当前K线还是追加新K线 const lastIndex klineData.length - 1; const lastK klineData[lastIndex]; if (tick.time lastK[0]) { // 同一根K线内更新比如1分钟K线还没走完 klineData[lastIndex] [tick.time, tick.open, tick.close, tick.low, tick.high]; } else { // 新的一根K线 klineData.push([tick.time, tick.open, tick.close, tick.low, tick.high]); } updateChart(klineData); };这里要注意区分两种实时场景盘中刷新当前这根K线还没结束价格在不断变化。那么你需要做的是修改最后一根K线的close、high、low而不是追加新K线。新周期开启新的一根K线出现了这时候才需要push新数据。把这两种情况分清楚动态图才不会出现最后一根K线一直重复或者最新K线缺失的问题。4.4 性能优化几千根K线也能保持流畅动态更新状态下最容易出现的问题是越往后越卡。原因通常是这么几个数据量太大。一次性渲染上万根K线Canvas绘制压力大。解决思路是配合dataZoom只渲染可视区域。Echarts内部对大数据量有优化机制但前提是x轴用dataZoom把范围限制住不要默认显示全部。具体我用的方式是把dataZoom的start和end做成动态的。比如用户当前看的是最后100根但最新数据一到如果还让start保持在99%用户视角就会自动跟随const zoom chart.getOption().dataZoom[0]; if (zoom.end 100) { // 用户在最右侧跟随最新数据 chart.setOption({ dataZoom: [ { start: zoom.start, end: 100 }, { start: zoom.start, end: 100 } ] }); }但如果用户已经把缩放位置拖到了历史区域就不要强行改变用户的视野否则体验会很差。频繁setOption导致的开销。WebSocket消息可能一秒推送多次如果每次都全量更新chart性能会急剧下降。解决方案是加一个节流或批量更新机制let pendingData null; let lastUpdateTime 0; ws.onmessage function(event) { // 只记录最新数据 pendingData JSON.parse(event.data); throttleUpdate(); }; function throttleUpdate() { const now Date.now(); if (now - lastUpdateTime 1000) { // 每秒最多更新一次 applyUpdate(pendingData); lastUpdateTime now; } else { // 还没到更新时间用requestAnimationFrame延后更新 requestAnimationFrame(throttleUpdate); } }这个方案的思路是行情推送频率再高图表每秒最多重新渲染两次左右人眼看起来已经足够流畅但CPU和GPU的开销会大幅下降。关闭动画。动态图表里动画反而是累赘。K线更新本来就频繁你给每个新K线加一个生长动画不仅没有意义还会在快速刷新时导致渲染卡顿。所以我在前面的option里特意加了animation: false。如果是首次加载想让用户看到数据从无到有的过程可以只对静态首屏开动画首屏之后动态更新阶段就关闭。4.5 大屏场景下的适配问题这次项目的落地场景是数据可视化大屏里面除了K线图还有中国地图、饼图、柱状图。大屏适配有几个坑我在这里一起说了rem适配不生效网上很多方案是用pxtorem把px转rem方便大屏等比缩放。但pxtorem不会处理Echarts内部通过canvas绘制的文字因为Echarts的字体大小是在它自己的配置项里设置的根本不会经过CSS编译。所以对Echarts来说正确的做法是监听resize事件动态调整fontSize相关的配置或者直接按设计稿比例计算像素值。容器宽高为0大屏页面经常用flex布局如果图表容器初始时宽度为0比如还没加载完图表会渲染成空白。解决方式是确保容器有明确高度然后在数据加载完成后调用chart.resize()。一屏多图表大屏里常常同时存在K线图、饼图、柱状图所有图表共用同一个resize处理逻辑。用window.addEventListener(resize, ...)统一处理不要在单个图表里重复监听。window.addEventListener(resize, () { klineChart.resize(); mapChart.resize(); pieChart.resize(); });5. 交互体验优化Tooltip、缩放力度与视觉细节一个K线图能不能让人愿意用交互细节很关键。这里分享几个我反复调整过的点。5.1 Tooltip格式化从默认展示到可读性强默认的K线图tooltip会一次性把所有series的数据都列出来包括K线的OHLC、多条均线、成交量。如果都不格式化显示会非常乱而且数字没有单位、没有颜色提示。我最终用的formatter是这样的tooltip: { trigger: axis, axisPointer: { type: cross }, formatter: function(params) { let res ; const date params[0].axisValue; res date br/; params.forEach(item { const seriesName item.seriesName; const value item.value; if (seriesName 日K) { const open Number(value[1]).toFixed(2); const close Number(value[2]).toFixed(2); const low Number(value[3]).toFixed(2); const high Number(value[4]).toFixed(2); const color open close ? #ef232a : #14b143; res span stylecolor: color 开盘:/span open br/; res span stylecolor: color 收盘:/span close br/; res span stylecolor: color 最低:/span low br/; res span stylecolor: color 最高:/span high br/; } else { // 均线、成交量等其他series if (item.value !isNaN(item.value)) { res seriesName : Number(item.value).toFixed(2) br/; } } }); return res; } }这里用到了br/来实现换行。之前总有人在网上问Echarts的tooltip怎么自动换行其实用HTML字符串拼接就行tooltip的formatter支持返回HTML片段br/就是最直接的换行方式。如果你看到一个很长的tooltip没有换行多半是用了\n而不是br/。5.2 十字准星让K线图的定位更精确K线图的axisPointer建议用cross就是十字准星。配合tooltip鼠标移到哪根K线附近就能精确定位到那一根K线的OHLCaxisPointer: { type: cross, crossStyle: { color: #999 }, label: { backgroundColor: #6a7985 } }实际用下来十字准星非常符合行情软件的使用习惯。用户鼠标一放到图上马上就能看到当前是哪一天价格在什么区间。5.3 markLine标记最高价和最低价有时候用户希望一眼看到历史最高价和最低价。有两种实现方式一种是在数据预处理时算好然后用markLine的yAxis类型series: [ { name: 日K, type: candlestick, data: klineData, markLine: { symbol: none, label: { show: true, formatter: {b}: {c} }, data: [ { name: 最高价, yAxis: maxPrice, lineStyle: { color: #ef232a, type: dashed } }, { name: 最低价, yAxis: minPrice, lineStyle: { color: #14b143, type: dashed } } ] } } ]一种是直接用markPoint标记最高和最低的点。两者视觉和使用场景不同看具体需求。动态更新时如果价格突破新高要记得重新计算maxPrice和minPrice再用chart.setOption更新markLine。5.4 视觉风格让K线图不廉价K线图给人的第一印象很大程度来自配色和网格。我总结一套比较耐看的方案背景色深色背景下用#1e1e28或接近的颜色浅色背景下保持白色用浅灰色分割线。网格线splitLine用#f0f0f0太深会抢K线的注意力太浅又起不到参考作用。均线颜色MA5用橙黄色、MA10用蓝色、MA20用紫色和主流行情软件保持一致用户上手成本低。成交量透明度设成70%左右既能看清又不会压过主图。legend: { data: [日K, MA5, MA10, MA20], textStyle: { color: #999 }, top: 10 }5.5 结合热搜需求柱状图自定义图片的扩展思路这次的标题是K线图但实际项目中往往还要配套其他类型的图表。比如有开发者在搜Echarts柱状图柱子可以用自定义图片显示不——这其实是可以的。Echarts的series-bar支持itemStyle里的color设置为image或者pattern。如果你做了K线的成交量图想用类似于能量柱的纹理来替代纯色思路也是一样的itemStyle: { color: { image: data:image/png;base64,..., // 或者图片URL repeat: repeat } }这种玩法在装饰性要求高的大屏里经常用到但注意图片资源体积别太大否则初始化时会卡顿。6. 动态K线图最容易翻车的几个场景排查与解决最后这部分我把自己实际踩过、以及网上高频出现的一些坑列出来每条都给出排查思路和解决方案。6.1 数据更新后图表错乱坐标轴和Data一致性问题现象图表上K线越来越多但x轴标签和K线数据对不上或者更新后旧数据残留。排查思路先确认你给xAxis.data和给series.data传的是不是同一个数组。如果一个是过滤后的数据、一个是全量数据那必然错位。检查setOption是否每次都传了完整的xAxis数据。如果只传series不传xAxisEcharts会沿用旧xAxis但数据长度已经变了位置就会错乱。检查是否有异步顺序问题。比如发起两次请求第一次请求后到的最新数据反而把第二次请求的新数据覆盖了。这种情况要加请求序号或时间戳判断只处理最新一次的响应。6.2 DataZoom联动失败上面拖拽下面不动现象主图dataZoom拖动了但成交量区域没有跟着缩放。排查思路dataZoom的xAxisIndex必须同时包含主图和副图的x轴索引。比如主图是xAxis[0]成交量是xAxis[1]那就要写xAxisIndex: [0, 1]。dataZoom: [ { type: inside, xAxisIndex: [0, 1], start: 60, end: 100 }, { type: slider, xAxisIndex: [0, 1], start: 60, end: 100 } ]6.3 Tooltip内容错乱鼠标移动到某个位置显示的是另一根K线的数据现象tooltip显示日期和K线对不上偏移了一根。原因多半是x轴用category时boundaryGap设置不对。K线图要用boundaryGap: true这样K线是坐在刻度上的而不是横跨在刻度之间。如果设成falsetooltip的定位会偏移。6.4 容器隐藏导致图表空白现象tab切换时第一次切换到K线的tab图表是空白的要等resize后才显示。原因图表的容器在初始化时是隐藏的宽度为0。解决方式是在tab切换完成后再初始化图表或者在显示后调用chart.resize()。tabPane.addEventListener(click, () { setTimeout(() { klineChart.resize(); }, 0); });6.5 当前K线更新时均线末尾没更新现象最新价变化了但MA5、MA10、MA20的最后一点没有跟着变。原因更新了K线数据但没有重新计算均线。均线是基于收盘价算的K线收盘价变了均线肯定也要变。每次更新最后一根K线时要同步重新计算最后几个均线点位。6.6 自适应分辨率resize后图表变形现象浏览器窗口改变后K线被拉伸变形。原因resize只调用了chart.resize()重置了宽高但图表是自适应布局的如果容器大小变了而内部比例没变就会变形。大屏项目中通常采用按设计稿固定尺寸、整体缩放的方式来应对而不是简单地reflow。// 大屏整体缩放而不是窗口reflow const scaleX window.innerWidth / 1920; const scaleY window.innerHeight / 1080; document.querySelector(#app).style.transform scale(${scaleX}, ${scaleY});这种方式的好处是所有Echarts图表的坐标和文字大小都按1920设计稿来不会出现字体大小不变但图表拉伸的尴尬。6.7 大数据量初始化卡顿现象一次性加载近一年的分钟级K线有几万根数据页面卡住很久。解决方法用dataZoom控制初始可视范围不要显示全部。关闭动画。如果数据量真的非常大比如十万级别考虑后端做聚合把分钟线聚合成小时线、日线或者在前端做抽稀处理。打开Echarts的采样配置比如对line系列设置sampling: lttb该配置主要对折线有效但可以减少绘制点。6.8 颜色习惯与团队期望不一致现象产品经理说怎么绿涨红跌我们不是红涨绿跌吗结果发现是itemStyle的color和color0设置反了。这个算是最常见的不是bug的bug。Echarts不同版本默认颜色不一样且candlestick的color对应阳线color0对应阴线但不同行业对阳线用什么颜色定义不一样。所以一开始就明确写itemStyle: { color: #ef232a, // 阳线收盘 开盘 color0: #14b143, // 阴线收盘 开盘 borderColor: #ef232a, borderColor0: #14b143 }不要偷懒不写否则后来换了一套主题数据或者换个版本颜色可能就悄悄变了。6.9 Echarts在Vue3中的响应式陷阱现象Vue3项目里把option定义成reactive对象然后直接改option.series[0].data发现图表不更新。或者反过来数据变了但图表没变。Echarts的实例和Vue的响应式系统之间没有直接关系。你必须在数据变化后手动调用chart.setOption。另外不要把整个Echarts实例放进reactive里会造成不必要的性能损耗一般用shallowRef或普通变量保存图表实例即可。import * as echarts from echarts/core; let chart null; onMounted(() { chart echarts.init(document.getElementById(kline)); chart.setOption(initialOption); }); function updateChart(newData) { chart.setOption({ series: [{ data: newData }] }); }写在项目最后的一点心得动态K线图做完以后我自己最大的体会是Echarts只是画笔真正的功夫在数据处理和状态管理上。K线的OHLC顺序、均线计算、增量更新逻辑、setOption合并的边界情况这些才是让图表稳定好用的关键。如果你打算在自己的项目里做类似功能我建议先拿一段静态K线数据把图表样式调好再接入真实数据源做动态刷新。两步分开做排查问题时思路会清楚得多。最后的最后再分享一个小技巧开发阶段打开Echarts的debugMode很多配置项问题会直接输出警告信息。遇到图表不渲染、数据不显示的诡异问题先把控制台报错看完再决定要不要重写数据逻辑。很多玄学Bug到最后都只是一个小小的属性名写错了而已。
返回列表