1. 热力图到底能解决什么问题:从一次信号覆盖大屏的改造说起
去年我给一个通信项目做网络覆盖监控大屏,需求很直接:把城市各片区的信号强度展示在地图上。最初我用的是散点图加颜色映射,点位密集之后整个页面糊成一片,根本看不出哪里信号差、哪里覆盖盲区多。后来换成了热力图,问题几分钟就解决了——颜色深浅一铺开,弱覆盖区域一目了然。
ECharts的热力图(heatmap)说白了就是用颜色表达数值大小:把二维平面划分成一个个小格子,每个格子按数值映射到不同颜色,高值偏红偏深,低值偏蓝偏浅。它和散点图最大的区别在于:散点靠点的疏密和大小表达分布,热力图靠色块的连续颜色过渡表达强度,信息密度高得多。
ECharts里做热力图的核心就是series类型设为heatmap,再配合一个visualMap视觉映射组件,官方文档内容分散,东一句西一句,新手很容易看懵。这篇我把热力图从数据结构、核心配置到实战场景、常见坑一次性讲透,不整虚的,直接给能跑的配置和代码。
这篇文章适合谁看?一是要用ECharts做数据可视化大屏的开发者,二是做数据分析、想用热力图展示相关性矩阵或分布密度的同学,三是刚上手ECharts、在官方文档里绕晕了想找一份热力图专题攻略的新手。文章里的所有配置我都按实际项目经验来写,部分通用技巧如果你有更好用的方案,欢迎评论区交流。
2. 热力图的地基:series-heatmap的数据结构与渲染逻辑
要玩转热力图,首先得理解它的底层数据组织方式。ECharts热力图的数据结构并不复杂,总共就三层:坐标轴、数据点、映射关系。
2.1 数据结构:每一条数据都是 [x, y, value]
看一个最简单的高频写法:
option = { xAxis: { type: 'category', data: ['周一', '周二', '周三', '周四', '周五'] }, yAxis: { type: 'category', data: ['早班', '中班', '晚班'] }, visualMap: { min: 0, max: 100 }, series: [{ type: 'heatmap', data: [ [0, 0, 20], [1, 0, 45], [2, 0, 70], [3, 0, 90], [4, 0, 55], [0, 1, 30], [1, 1, 60], [2, 1, 85], [3, 1, 100], [4, 1, 40], // ... ] }] };这里每一项[x, y, value]中的x和y不是像素坐标,而是类目数据的索引,对应xAxis.data和yAxis.data里的第几个类目,value才是决定颜色深浅的数值。这一点容易踩坑,很多人在数据里写坐标轴的实际值,结果图和坐标轴完全对不上。
值得一提的是,data里的每个元素也支持对象写法,灵活性更高:
data: [ { value: [0, 0, 20], itemStyle: { color: '#dd0000' } }, { value: [1, 0, 45] } ]这种写法适合需要对某个格子单独设置颜色、单独控制样式的场景,比如把某一格标记成异常。
2.2 渲染原理:为什么两个坐标轴都必须是category类型
热力图本质上是在笛卡尔坐标系中绘制矩形块,它的位置不靠坐标值计算,而是靠类目序号对应的坐标轴区域来定位。所以xAxis和yAxis的type必须设置为category,否则图形块不会按预期铺开。
同时,data里的索引值必须保证在类目数组长度范围内,超出范围或者缺数据,对应的区域就是空白或null。如果你遇到热力图"缺了一块",第一反应应该是检查数据里有没有遗漏某个格子,或者某个索引值是否越界。
2.3 visualMap为什么是热力图的灵魂
visualMap的作用是把数据值域映射到颜色。你可以理解成在画图之前给所有格子算好"该用什么颜色"的查色表。它和热力图属于绑定关系,没有visualMap的热力图是一堆灰块,有了它才是一张有信息量的热力图。
visualMap: { min: 0, max: 100, calculable: true, inRange: { color: ['#50a3ba', '#eac736', '#d94e5d'] }, orient: 'horizontal', left: 'center', bottom: 10 }我用实际项目经验说:min和max这两个值决定了颜色映射的上下限,一定要根据业务场景显式设置,不能指望ECharts自动算。否则当数据极端值出现时,整张图颜色可能全偏到一端,失去对比度。如果你做的是相关性热力图,数值范围天然是-1到1,min/max直接写-1和1即可。如果你做的是信号强度热力图,min/max一般设置为业务上可接受的最低值和最高值,低于min的格子统一显示最冷色,高于max的统一显示最热色。
2.4 最小可运行示例:矩阵热力图Demo
下面给一个完整的最小demo,你可以直接复制到ECharts实例里验证:
var hours = ['12a', '1a', '2a', '3a', '4a', '5a', '6a']; var days = ['Saturday', 'Friday', 'Thursday']; var data = []; for (var i = 0; i < days.length; i++) { for (var j = 0; j < hours.length; j++) { data.push([j, i, Math.random() * 100]); } } option = { grid: { top: 40, right: 60, left: 60, bottom: 40 }, xAxis: { type: 'category', data: hours, splitArea: { show: true } }, yAxis: { type: 'category', data: days, splitArea: { show: true } }, visualMap: { min: 0, max: 100, calculable: true, inRange: { color: ['#313695', '#74add1', '#fee090', '#f46d43', '#a50026'] } }, series: [{ type: 'heatmap', data: data, label: { show: true }, emphasis: { itemStyle: { shadowBlur: 10, shadowColor: 'rgba(0, 0, 0, 0.5)' } } }] };跑通这一个demo,你就已经掌握了热力图80%的骨架逻辑:坐标轴类目 + 三元组数据 + visualMap + series。下面再逐项拆配置,深入每一个高频场景。
3. 逐项拆解高频配置项:从visualMap到坐标轴与label
热力图能配置的项很多,但常用的其实集中在四五类:visualMap、坐标轴与布局、label、tooltip、itemStyle。逐类拆开讲,每一处都告诉你为什么要这么配。
3.1 visualMap的进阶用法:连续与分段、阈值控制
visualMap有两种形态:continuous(连续型)和piecewise(分段型),默认是连续型。
连续型适合数值平滑变化的数据,比如信号强度、温度分布,视觉过渡自然:
visualMap: { type: 'continuous', min: -100, max: 0, calculable: true, // 拖动手柄动态筛选 realtime: true, // 拖动过程中实时更新 precision: 1, // 显示小数位数 itemWidth: 15, itemHeight: 120, text: ['高', '低'], // 两端文字 textStyle: { color: '#333' } }分段型适合把数据离散成几个等级,比如把相关性系数分成"强正相关、弱正相关、不相关、弱负相关、强负相关"五档,或者把信号质量分成"优、良、差、无"四档:
visualMap: { type: 'piecewise', pieces: [ { min: 0.8, label: '强正相关', color: '#d73027' }, { min: 0.3, max: 0.8, label: '中正相关', color: '#fc8d59' }, { min: -0.3, max: 0.3, label: '弱相关', color: '#ffffbf' }, { min: -0.8, max: -0.3, label: '中负相关', color: '#91bfdb' }, { max: -0.8, label: '强负相关', color: '#4575b4' } ] }这里有一个核心技巧:做"相关热力图阈值"时,直接用pieces就能实现。有时候我们只关心绝对值大于0.6的强相关关系,那就把阈值以下的格子设成同一个灰色,视觉上自动弱化无关区域。这个技巧我最早是在一份基因表达数据分析报告里发现的,后来在自己做特征相关性分析时一直沿用。
3.2 坐标轴和布局:网格线、留白、标签旋转
热力图的坐标轴虽然都是category类型,但有几个细节配置很重要:
splitArea用来显示类目之间的分界线。如果不开启,格子与格子之间容易粘在一起,尤其在颜色接近的数据上很难区分单元格边界。推荐在xAxis和yAxis都开启splitArea: { show: true },它会在背景区域绘制条纹,利于视觉分割。
标签旋转:当x轴类目特别多时(比如24小时或365天),全部横排会重叠,可以让轴标签旋转:
xAxis: { type: 'category', data: hourList, axisLabel: { rotate: 45, interval: 0, // 强制显示所有标签 fontSize: 12 } }interval: 0表示所有标签都显示,类目很多时不建议这么做,可以用interval: 2让每三个显示一个,保持图面干净。
grid留白:热力图左侧通常需要放置visualMap或色条,如果grid的right太小,色条会压到图上。我的经验是把right控制在50到80之间,bottom根据是否放图例决定。网格边距的大小直接影响热力图是否被挤压变形。
3.3 label配置:每个格子里要不要显示数值
热力图的label用于在格子里显示具体数值,关键配置:
label: { show: true, fontSize: 10, color: '#333', formatter: function(params) { return params.value[2].toFixed(2); } }怎么决定开不开label?我的经验是看格子大小和数据量:5x5的矩阵(比如5个特征的相关系数矩阵)格子大,开label很有用,读者一眼能看到具体数值;100x100的矩阵格子太小,开label只会挤成一团,建议关掉。如果必须在大矩阵上显示数值,配合fontSize: 8和color: '#fff'勉强能看,但性能上也要考虑,建议关闭。
3.4 itemStyle和emphasis:边框、阴影、高亮反馈
itemStyle控制格子本身的样式,尤其注意borderColor和borderWidth,它们决定了格子边缘是否清晰。默认情况下ECharts会给格子留1px的白色边框,如果你希望格子无缝拼接(类似大屏上的连续色块效果),可以设置:
itemStyle: { borderWidth: 0 }而emphasis控制鼠标悬停时的反馈。很多人省略这个配置,导致鼠标悬停只有默认的tooltip,视觉反馈不够明显。合理的高亮样式会让图"活"起来:
emphasis: { itemStyle: { shadowBlur: 10, shadowColor: 'rgba(0, 0, 0, 0.5)', borderWidth: 2, borderColor: '#fff' } }3.5 tooltip:默认值、自定义formatter、自动换行
heatmap的tooltip默认会显示"x轴类目,y轴类目,数值",但格式往往不够友好。我按项目经验给你两个配置方向:
第一,自定义格式化内容。比如这种:
tooltip: { formatter: function(params) { return '时间:' + params.value[0] + '点<br/>日期:' + params.value[1] + '<br/>访问量:' + params.value[2]; } }第二,处理自动换行问题。ECharts的tooltip在数据内容很长时不一定会自动换行。最简单可靠的做法是在formatter里手动加<br/>,也就是上面例子的写法。如果你遇到边界情况,比如移动端tooltip被截断,可以配合confine: true让tooltip不超出容器边界。这两个配置组合下来,大部分换行问题都能解决。
4. 三类高频实战场景走一遍:矩阵热力、地图热力、类色斑图
讲完配置项,下面结合最常见的三类场景给出完整可用的配置。这些配置都是实际项目中验证过的,你拿过去改改数据就能用。
4.1 场景一:相关性矩阵热力图(可用于特征分析)
数据分析中最常见的场景就是特征相关性分析。假设我们有10个特征,算完相关系数矩阵后,想用热力图直观展示哪些特征强相关、哪些弱相关。我的做法是先生成矩阵数据,再配合piecewise形式的分段颜色:
// 假设 features 是长度为10的数组,corrMatrix 是 10x10 的相关系数矩阵 var data = []; for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { data.push([j, i, corrMatrix[i][j]]); } } option = { grid: { top: 40, right: 70, left: 80, bottom: 40 }, xAxis: { type: 'category', data: features, axisLabel: { rotate: 30 } }, yAxis: { type: 'category', data: features }, visualMap: { type: 'piecewise', pieces: [ { min: 0.6, label: '强正相关', color: '#b2182b' }, { min: 0.2, max: 0.6, label: '中正相关', color: '#ef8a62' }, { min: -0.2, max: 0.2, label: '弱相关', color: '#f7f7f7' }, { min: -0.6, max: -0.2, label: '中负相关', color: '#67a9cf' }, { max: -0.6, label: '强负相关', color: '#2166ac' } ] }, series: [{ type: 'heatmap', data: data, label: { show: true, fontSize: 10, formatter: function(p) { return p.value[2].toFixed(2); } } }] };做相关热力图时,我强烈建议主对角线的格子也要渲染,它们是完美的参考基准,颜色最深,一眼就能对比出其他格子的相对强度。如果矩阵很大(比如50个特征),label建议关掉,只保留颜色分区,聚焦宏观模式。
4.2 场景二:地理区域热力图(中国地图或省市地图)
区域型热力图用于展示不同地区的指标值(如各省访问量、各区投诉量)。它不是用heatmap series,而是通过map系列 +visualMap实现的,但视觉上同样是热力效果,很多人把它也叫热力图。
// 需要先注册地图数据 $.get('china.json', function(chinaJson) { echarts.registerMap('china', chinaJson); var chart = echarts.init(document.getElementById('main')); chart.setOption({ visualMap: { min: 0, max: 1000, left: 20, bottom: 20, inRange: { color: ['#f0f9e8', '#bae4bc', '#7bccc4', '#2b8cbe'] } }, series: [{ type: 'map', map: 'china', roam: true, label: { show: false }, emphasis: { label: { show: true }, itemStyle: { areaColor: '#ffcc00' } }, data: [ { name: '北京', value: 800 }, { name: '上海', value: 600 }, { name: '广东', value: 950 } // ... ] }] }); });用map系列时注意两点:
- 地图数据需要单独准备,社区里能找到各种GeoJSON文件,我这里不做推荐,你按自己项目所在地区选择合法合规的地图数据源即可。
- visualMap和series之间通过
visualMap的seriesIndex字段建立关联。一个页面多个图时,务必指定关联关系,否则可能出现series数据没有正确映射到颜色。
如果你要叠加散点、线数据到地图上,可以在同一个option里追加带coordinateSystem: 'geo'的series,两者互不干扰。常见的用法是地图热力 + 点位散点叠加,一张图上既有区域整体水平,又有具体点位信息。
4.3 场景三:类色斑图/信号覆盖网格热力图
通信、气象、环境监测领域经常要渲染色斑图,也就是把地理区域划分成细密网格,每个网格显示一个值(信号强度、PM2.5浓度、温湿度等)。这类图本质上是heatmap series +geo坐标系的组合。
先说如何让heatmap在地理坐标系上展示。ECharts的heatmap原生支持coordinateSystem: 'geo',配合GeoJSON地图即可。数据项是[经度, 纬度, 值]:
option = { geo: { map: 'china', roam: true, itemStyle: { borderColor: '#ccc' } }, visualMap: { type: 'continuous', min: -110, max: -30, calculable: true, inRange: { color: ['#313695', '#74add1', '#fee090', '#f46d43', '#a50026'] } }, series: [{ type: 'heatmap', coordinateSystem: 'geo', data: signalData, // [[lng, lat, value], ...] pointSize: 10, blurSize: 20 }] };在ECharts 4及以下版本,coordinateSystem: 'geo'的heatmap走的是模拟热力(scatter变形),控制的是pointSize和blurSize;在ECharts 5中,你也可以用type: 'heatmap'+coordinateSystem: 'geo'继续实现,但要注意不同版本之间数据格式和渲染效果有差异。实际做信号热力图时,如果点位数据密集,直接grid网格化后渲染成矩阵热力图,视觉上更贴近传统色斑图,性能也更好。
我自己做信号覆盖图时采用过一种半手工方案:把目标区域按经纬度切成等尺寸格子(比如500m x 500m),每个格子计算平均信号强度,然后塞进grid热力图里渲染。好处是数据结构简单、渲染性能好、颜色过渡可控;缺点是需要自己对原始采样点做网格聚合,多写一段聚合逻辑。
4.4 场景四:密度型热力图(散点密度暗喻)
还有一种用法:用heatmap模拟散点密度分布。比如你有几万个用户点击位置,坐标是经纬度,直接把散点画出来会一片黑。正确的处理是先把坐标点聚合到网格上,统计每个网格的点击数,再丢给heatmap。
这个聚合逻辑很简单,就是给坐标点做整数除法分桶:
var gridSize = 0.01; // 网格尺寸,单位是坐标值 var bucket = {}; coords.forEach(function(c) { var key = Math.floor(c.lng / gridSize) + '_' + Math.floor(c.lat / gridSize); bucket[key] = (bucket[key] || 0) + 1; }); var data = Object.keys(bucket).map(function(key) { var parts = key.split('_'); return [parseInt(parts[0]) * gridSize + gridSize / 2, parseInt(parts[1]) * gridSize + gridSize / 2, bucket[key]]; });聚合后再交给heatmap渲染,点密度一目了然。这个方案在大屏项目里消耗低、效果好,比直接用scatter + large模式更可控。
5. 踩坑实录:tooltip换行、数据错位、Vue3适配等高频问题排查
这一节我给实战中遇到的高频坑做个排错梳理。每个坑都是真实踩过、定位过、修复过的,希望能帮你少走弯路。
5.1 tooltip内容过长不自动换行
现象:tooltip内容拼接后很长,组件里没有自动换行,超出屏幕被截断。
原因:ECharts默认情况下tooltip是跟随鼠标的,当内容过长时会超出容器可视范围,而它本身没有智能换行策略。
排查链路:先确认你的formatter返回的字符串里有没有<br/>。ECharts的tooltip是HTML渲染模式(默认renderMode: 'html'),返回的<br/>会被正确识别为换行。如果你没有手动换行,它不会自动断行。
修复方案有两个:
- 在formatter里手动拼接
<br/>,并把每个字段单独一行。 - 设置
tooltip: { renderMode: 'richText' },强制使用富文本渲染,但richText模式下部分HTML标签不支持,需要额外测试。
我个人推荐方案1,稳定、可控、全版本兼容。
5.2 热力图格子"整体偏移"一格
现象:某些数据点渲染出来错位移到旁边一个格子里,或者图块和坐标轴标签对不上。
原因:这是我见过最典型的bug,往往不是配置写错,而是数据里x/y索引坐标系搞反了,或者数据顺序与坐标轴类目顺序不一致。
排查链路:优先打印出option里series.data的前三条,手工对照xAxis.data和yAxis.data的顺序,确认到底是[xIndex, yIndex, value]还是[yIndex, xIndex, value]。在大多数业务代码里,我们习惯用双重循环遍历,容易写成data.push([i, j, value]),但i应该是x轴索引,j是y轴索引,写反了整张图就转置了。
修复方案:统一数据组装逻辑,推荐先循环y,再循环x:
for (var i = 0; i < xList.length; i++) { for (var j = 0; j < yList.length; j++) { data.push([i, j, getValue(xList[i], yList[j])]); } }5.3 visualMap颜色全部一样
现象:所有格子颜色一致,或者颜色分布和数值严重不匹配。
原因:很多情况下是visualMap的min/max范围设置不对。比如数据全是60到80的浮动,但min设成了0、max设成了1000,那所有格子都会落在同一条色带上,视觉上毫无区分度。
排查链路:先在控制台打印visuaMap绑定的series数据范围,看min/max是否覆盖了实际数据区间。如果你的数据集存在极值(比如少量异常值达到1000),其余数据在10左右,min/max设置不合适会导致正常数据挤成同色。
修复方案:根据实际业务数据设置合理的min/max,不要偷懒不设。极端值对颜色映射的影响可以采用分位数截断:比如把min设为数据的5%分位数,max设为95%分位数,把异常值排除在色带之外。
5.4 Vue3项目里pxtorem对ECharts没起到效果
现象:在Vue3项目中用postcss-pxtorem做移动端适配,结果ECharts图表里的文字、图例大小都没跟随rem缩放。
原因:ECharts实例一旦初始化,内部样式都是通过内联样式和canvas渲染的,它们不会走CSS的rem转换。pxtorem只处理CSS文件里的px单位,而ECharts的textStyle.fontSize、itemWidth等配置在JS代码里写的是数字px,不在CSS编译链路上。
排查链路:检查ECharts配置里是否有写死的fontSize数字。如果你用rem作为单位去配置,ECharts内部不识别rem,必须手动换算成px。
修复方案有两种思路:
- 动态rem换算:在初始化ECharts之前,根据当前rem基准值把配置里的fontSize等转换成px数字。比如
fontSize: 0.24 * document.documentElement.clientWidth / 10这种方式动态计算。 - 单独监听resize:在不同屏宽下重新
chart.setOption更新字体大小。配合window.addEventListener('resize', throttledFn),注意节流。
项目实践总结:如果你做大屏(PC端)适配,优先用rem方案;如果你做移动端H5,直接用vw/vh做ECharts容器尺寸,内部字体用chart.resize()加手动缩放会更稳。pxtorem配合ECharts始终十分别扭,不建议死磕。
5.5 大数据量渲染卡顿
现象:热力图网格数达到几千甚至上万时,渲染明显卡顿,悬停tooltip也不流畅。
原因:热力图每个格子都是一个独立图形元素,几万个格子会拖垮canvas绘制性能。
排查链路:先算一下数据规模。假设x轴类目100个,y轴100个,那就有10000个格子。此时如果每个格子都开了label,性能直接雪崩。
修复方案:
- 关掉label,至少在大图上关掉。
- 减少emphasis阴影效果,阴影计算成本高。
- 尽量使用单一series,不要多个heatmap series叠加。
- 如果必须展示大量数据,考虑预先降采样或者网格聚合,把可视范围缩小。
实测经验:3000个格子内几乎无感,6000个格子轻微掉帧,10000个格子开阴影会有明显卡顿,关掉阴影和label后还能接受。
5.6 热力图和地图结合时地图不显示
现象:coordinateSystem: 'geo'配置了,但图完全空白,或者只有散点没有地图底图。
原因:常见原因是没有正确注册地图数据,或者geo配置的map名和注册名不一致。
排查链路:确认是否调用了echarts.registerMap('xxx', jsonData),并且geo.map和series引用的map名完全相同。另外确认地图JSON数据是否符合GeoJSON格式,个别来源的数据类型不对会导致注册失败但不报错。
修复方案:保证注册和引用名称一致,比如统一用china;同时把geo的show: true显式设置,避免地图被隐藏。
5.7 饼图labelLine小圆点偏移、折线图x轴刻度密度问题(扩展排查)
这两个问题和热力图无关,但它们高频出现在同一份项目代码里。做数据大屏时,经常遇到饼图labelLine末尾的小圆点偏移,一般是ECharts版本bug或富文本配置冲突,解决思路是升级或换用label.layout策略。折线图x轴刻度过密则使用axisLabel.interval和axisTick.alignWithLabel控制。这些排查思路可以反过来加深你对ECharts整体配置体系的理解,遇到热力图类似问题时,定位思路是一样的:先还原最小案例,再逐项核对配置。
6. 交互拓展与集成:点击下钻、外部联动、大屏适配
热力图做出来只是第一步,放到项目里怎么交互、怎么联动才是真实需求。这节分享几个我常用的集成方法。
6.1 鼠标点击事件与下钻
在ECharts中,热力图的每个格子可以绑定click事件,拿到格子的x/y索引,进而实现点击下钻或联动。
chart.on('click', function(params) { if (params.componentType === 'series' && params.seriesType === 'heatmap') { var xLabel = params.name; // x轴类目 var yLabel = params.data[1]; // y轴索引,注意这里不是y轴类目值 var value = params.data[2]; console.log('选中格子:' + xLabel + ', ' + yLabel + ', 数值=' + value); // 触发外部联动,比如更新另一张图表 } });这里有个细节:在订制热力图时,params.data的结构是原始[xIndex, yIndex, value],params.name则是x轴类目的名称。如果你需要获取y轴类目名称,需要通过option.yAxis.data[params.data[1]]去反向查表。
6.2 与外部组件联动:点击热力图格子筛选明细表格
实际项目中,热力图经常做"总览图",点击某格子后,下方明细表格要展示该格子对应的原始数据。我的做法是维护一个Map,key是"xIndex-yIndex",value是明细数组,在click事件里查表更新表格。
这么做的好处是总览图表保持高性能,明细数据按需加载。热力图只负责"指出哪里有问题",具体问题内容交给表格或详情面板,职责划分清晰。
6.3 大屏适配思路:热力图尺寸随容器自适应
做数据可视化大屏时,热力图容器宽度是固定的百分比,但浏览器窗口变化时图表需要自适应。标准做法是:
const chart = echarts.init(document.getElementById('heatmapContainer')); const resizeObserver = new ResizeObserver(() => chart.resize()); resizeObserver.observe(document.getElementById('heatmapContainer'));ResizeObserver比window.resize事件更精准,它会监听容器尺寸变化而不是整个窗口变化,在大屏嵌套布局里更实用。同时,在大屏项目中热力图的visualMap色条常常被要求固定放在左下角或右下角,不要让它跟随resize出现偏移。
6.4 与高清屏的适配细节
ECharts在devicePixelRatio大于1的屏幕上默认会开启高清渲染,本身效果不错。但如果你热力图格子太密集,渲染出来可能反而发虚。可以通过初始化参数强制设置分辨率:
const chart = echarts.init(dom, null, { renderer: 'canvas', devicePixelRatio: 2 });devicePixelRatio设为2通常够用,设太高会让canvas绘制负担成倍增加,热力图格子多时容易卡顿。
写在最后的一个小习惯
我这里补一个自己养成很久的习惯:不管是热力图还是别的ECharts图表,我拿到项目需求后不会急着写option,而是先把数据样例打印出来,手工数一数维度,再确定x轴类目、y轴类目和映射关系。热力图的问题里,有相当一部分是数据组织错了而不是配置错了。这个习惯帮我省掉了大量的debug时间。
如果你在集成过程中遇到官方文档描述不够清楚的情况,可以去ECharts官方示例里找相近效果,把示例的option下载下来,再逐步替换成自己的数据和样式,基本都能跑通。热力图这个图表面向的业务场景多,但从配置骨架看就那几板斧——数据结构、visualMap、坐标轴、label、tooltip。把这几样吃透,再复杂的变体也就是在此基础上做增删。希望这篇文章能让你少翻几次文档,一次就把热力图配顺。