在 UniApp 中实现热力图色阶,可以通过以下步骤完成,主要依赖 Canvas 绘制和颜色插值计算:
实现思路
- 数据准备:准备热力点的坐标和权重数据。
- 颜色映射:定义色阶数组,将权重映射到对应颜色。
- Canvas 绘制:在 Canvas 上绘制热力图,使用径向渐变模拟热力点。
示例代码
<template>
<view>
<canvas canvas-id="heatmapCanvas" style="width: 300px; height: 300px;"></canvas>
</view>
</template>
<script>
export default {
data() {
return {
points: [ // 热力点数据:[x, y, weight]
[50, 50, 1],
[100, 100, 0.5],
[200, 150, 0.8]
],
colorStops: [ // 色阶定义,从冷到热
{ offset: 0, color: 'blue' },
{ offset: 0.5, color: 'yellow' },
{ offset: 1, color: 'red' }
]
};
},
onReady() {
this.drawHeatmap();
},
methods: {
drawHeatmap() {
const ctx = uni.createCanvasContext('heatmapCanvas', this);
// 绘制每个热力点
this.points.forEach(point => {
const [x, y, weight] = point;
const gradient = ctx.createCircularGradient(x, y, 30);
// 根据权重插值颜色
const color = this.getColor(weight);
gradient.addColorStop(0, color);
gradient.addColorStop(1, 'rgba(0,0,0,0)'); // 边缘透明
ctx.fillStyle = gradient;
ctx.fillRect(x - 30, y - 30, 60, 60);
});
ctx.draw();
},
getColor(weight) {
// 线性插值计算颜色
const index = weight * (this.colorStops.length - 1);
const startIndex = Math.floor(index);
const endIndex = Math.ceil(index);
const ratio = index - startIndex;
const startColor = this.hexToRgb(this.colorStops[startIndex].color);
const endColor = this.hexToRgb(this.colorStops[endIndex].color);
const r = startColor.r + (endColor.r - startColor.r) * ratio;
const g = startColor.g + (endColor.g - startColor.g) * ratio;
const b = startColor.b + (endColor.b - startColor.b) * ratio;
return `rgb(${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)})`;
},
hexToRgb(hex) {
// 简化的 hex 转 rgb,支持 'red' 等颜色名(实际需处理颜色名)
const ctx = uni.createCanvasContext('', this);
ctx.fillStyle = hex;
return ctx.fillStyle; // 实际需解析计算
}
}
};
</script>
注意事项
- 性能优化:数据量大时需分帧渲染或使用 WebGL。
- 颜色插值:示例简化了颜色处理,实际需完善 hexToRgb 函数。
- 权重归一化:确保权重在 0-1 范围内。
更复杂场景可考虑使用第三方库(如 heatmap.js)通过 RenderJS 集成。