热力图(Heatmap)实现
热力图(Heatmap)实现
热力图是一种通过颜色变化展示数据密度的可视化方式,特别适合展示大量数据的分布规律。ECharts提供了强大的热力图组件,支持直角坐标系和地理坐标系两种形式,能够灵活应对不同场景的需求。
基本热力图配置
最简单的热力图只需要三个关键配置项:x轴、y轴和数据点。数据点需要包含x坐标、y坐标和值三个维度。以下是一个基础示例:
option = {
tooltip: {},
grid: {
left: '3%',
right: '7%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
},
yAxis: {
type: 'category',
data: ['早餐', '午餐', '晚餐', '夜宵']
},
visualMap: {
min: 0,
max: 10,
calculable: true,
orient: 'horizontal',
left: 'center',
bottom: '15%'
},
series: [{
name: '用餐热度',
type: 'heatmap',
data: [
[0, 0, 5], // 周一早餐
[0, 1, 7], // 周一午餐
[0, 2, 3], // 周一晚餐
[0, 3, 1], // 周一夜宵
// 其他数据...
[6, 2, 8] // 周日晚餐
],
label: {
show: true
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}]
};
数据格式处理
实际项目中,原始数据往往需要经过处理才能用于热力图展示。常见的数据转换方式包括:
- 从二维数组转换:
function convertToHeatmapData(matrix) {
const result = [];
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
result.push([i, j, matrix[i][j]]);
}
}
return result;
}
- 从对象数组转换:
const rawData = [
{ day: '周一', meal: '早餐', value: 5 },
{ day: '周一', meal: '午餐', value: 7 },
// ...
];
const xCategories = [...new Set(rawData.map(item => item.day))];
const yCategories = [...new Set(rawData.map(item => item.meal))];
const heatmapData = rawData.map(item => [
xCategories.indexOf(item.day),
yCategories.indexOf(item.meal),
item.value
]);
视觉映射配置
visualMap组件控制如何将数据值映射到视觉元素(主要是颜色)。ECharts提供了多种视觉映射方式:
visualMap: {
type: 'piecewise', // 分段型
pieces: [
{ min: 0, max: 3, label: '低', color: '#d94e5d' },
{ min: 3, max: 6, label: '中', color: '#eac736' },
{ min: 6, max: 10, label: '高', color: '#50a3ba' }
],
orient: 'vertical',
left: 'right',
top: 'center'
}
或者使用连续型映射:
visualMap: {
type: 'continuous',
min: 0,
max: 10,
inRange: {
color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
}
}
地理热力图
ECharts支持在地图上展示热力图,特别适合展示地理分布数据:
$.get('geoJSON/China.json', function(geoJson) {
echarts.registerMap('china', geoJson);
const option = {
tooltip: {
trigger: 'item',
formatter: '{b}: {c}'
},
visualMap: {
min: 0,
max: 1000,
text: ['高', '低'],
realtime: false,
calculable: true,
inRange: {
color: ['#50a3ba', '#eac736', '#d94e5d']
}
},
series: [{
name: '销量',
type: 'heatmap',
coordinateSystem: 'geo',
data: [
{name: '北京', value: 923},
{name: '上海', value: 865},
// ...
],
pointSize: 10,
blurSize: 15
}]
};
myChart.setOption(option);
});
性能优化技巧
当数据量较大时,热力图可能会出现性能问题。以下是一些优化建议:
- 使用渐进渲染:
series: [{
progressive: 1000,
progressiveThreshold: 10000
}]
- 降低数据精度:
function downsampleData(data, factor) {
const result = [];
for (let i = 0; i < data.length; i += factor) {
result.push(data[i]);
}
return result;
}
- 调整热力点大小和模糊半径:
series: [{
pointSize: 5, // 较小的点
blurSize: 8 // 适当的模糊半径
}]
交互功能增强
ECharts热力图支持丰富的交互功能:
- 数据筛选:
visualMap: {
type: 'continuous',
range: [3, 7], // 只显示值在3-7之间的数据
hoverLink: true // 鼠标悬停时显示对应数据
}
- 区域缩放:
dataZoom: [
{
type: 'slider',
xAxisIndex: 0,
filterMode: 'filter'
},
{
type: 'inside',
xAxisIndex: 0,
filterMode: 'filter'
}
]
- 自定义提示框:
tooltip: {
formatter: function(params) {
return `${params.seriesName}<br/>
${params.data[0]}: ${params.data[1]}<br/>
值: ${params.data[2]}`;
}
}
高级应用示例
结合散点图的热力图,可以同时展示数据分布和具体数值:
series: [
{
name: '热力图',
type: 'heatmap',
data: heatmapData,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
},
{
name: '散点',
type: 'scatter',
symbolSize: function(data) {
return Math.sqrt(data[2]) * 5;
},
data: heatmapData.filter(item => item[2] > threshold),
label: {
show: true,
formatter: function(params) {
return params.data[2];
}
}
}
]
动态数据更新
热力图支持动态数据更新,适合实时数据展示:
function updateHeatmap() {
const newData = generateNewData();
myChart.setOption({
series: [{
data: newData
}]
});
// 更新visualMap范围
const values = newData.map(item => item[2]);
myChart.setOption({
visualMap: {
min: Math.min(...values),
max: Math.max(...values)
}
});
}
setInterval(updateHeatmap, 2000);
自定义渲染效果
通过修改itemStyle可以实现各种自定义效果:
series: [{
itemStyle: {
borderColor: 'rgba(255, 255, 255, 0.8)',
borderWidth: 1,
shadowColor: 'rgba(0, 0, 0, 0.5)',
shadowBlur: 10
},
blurSize: 5,
pointSize: 15
}]
多热力图联动
多个热力图可以通过axisIndex实现联动:
grid: [
{left: '5%', width: '40%', top: '10%', height: '80%'},
{right: '5%', width: '40%', top: '10%', height: '80%'}
],
xAxis: [
{gridIndex: 0, type: 'category', data: ['Q1', 'Q2', 'Q3', 'Q4']},
{gridIndex: 1, type: 'category', data: ['A组', 'B组', 'C组', 'D组']}
],
yAxis: [
{gridIndex: 0, type: 'category', data: ['北京', '上海', '广州', '深圳']},
{gridIndex: 1, type: 'category', data: ['产品1', '产品2', '产品3']}
],
series: [
{
type: 'heatmap',
data: data1,
xAxisIndex: 0,
yAxisIndex: 0
},
{
type: 'heatmap',
data: data2,
xAxisIndex: 1,
yAxisIndex: 1
}
]
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:地图(Map)实现
下一篇:原始类型与字面量类型