需求的效果:
需求:
在地图上根据地区的位置显示相关信息的数量高低(或参数的大小),展示不同颜色,用来表示数据,话不多说,开始撸代码:
1、html中的代码:
这里的id='heatmap'是一个父级的盒子,其中的图片宽度和高度都是父级元素的100%,用来展示热力图的位置
<div class="maps">
<div class="hotPic" id="heatmap">
<img src="../../../assets/stationchange/zhutubeijing.png" alt="">
</div>
</div>
2、data中存放的变量
data() {
return {
points: [], // 热力图数据存放数组
cavWidth: null, //获取宽度
cavHeight: null, //获取高度
}
},
3、method中的方法
methods:{
// 初始化获取宽高(考虑到后期的适配,获取父级元素的宽高)
getRectValue(){
this.cavWidth = document.getElementById("heatmap").clientWidth;
this.cavHeight = document.getElementById("heatmap").clientHeight;
console.log(this.cavWidth,this.cavHeight)
},
// 初始化获取数据(模拟的展示数据)
initValue(){
var len = 30
while (len--) {
var val = Math.floor(Math.random() * 100)
// max = Math.max(max, val)
var point = {
x: Math.floor(Math.random() * 500),
y: Math.floor(Math.random() * 400),
value: val
}
this.points.push(point)
}
},
}
在这里说明一下,热力图的数据是根据数据中的坐标点进行叠加(下面的两段代码是数据结构的介绍)
point = {
x: 5, // x coordinate of the datapoint, a number(x坐标)
y: 5, // y coordinate of the datapoint, a number(y坐标)
value: 100 // the value at datapoint(x, y)
};
最终热力图上的显示是需要多个point进行叠加的,也就是相当于多个point的集合
data = {
max: 100,
min: 0,
data: [
point, point ,point, point
]
};
接上面的模拟数据方法:
// 初始化热力图
initHotPic(){
this.deleteHotMap()
let self = this
var heatmapInstance = Heatmap.create({
container: document.getElementById('heatmap'),
gradient: {//渐变颜色
"0": "rgba(255,255,255,1)",//value为0的颜色
"0.3": "#82ff6d",//value为500的颜色
"0.8": "#f3ff6d",//value为1000的颜色
"1": "#ff6d6d",//value为2000的颜色
},
// radius: 10,
maxOpacity: 1,
minOpacity: 0,
blur: .75,
// radius:30, //半径
// opacity:0.5, //透明
// maxOpacity, //热图中最大值具有的最大不透明度
// minOpacity, //热图中最小值的最小不透明度
// onExtremaChange, //传递回调以接收极值更改更新
// blur, //将应用于所有数据点的模糊因子。模糊因子越高,渐变将越平滑
// xField, //数据点中x坐标的属性名称
// yField, //数据点中y坐标的属性名称
// valueField //数据点中y坐标的属性名称
})
var max = 0
// var width = 600
// var height = 400
var data = {
max: 100, //数据对比(max和min进行数据对比,从而展示热力颜色)
min:0,
data: self.points
}
heatmapInstance.setData(data)
},
Tips:热力图的每一次加载都会在dom里创建一个自己的canvas,所以,在每次初始化之前都需要提前清楚上一次的创建,防止热力图展示的叠加(本人亲自踩过的坑)
// 删除之前的热力图
deleteHotMap(){
var heatmapBox = document.getElementById("heatmap");
if(heatmapBox.children.length>1){
var oldCanvas = heatmapBox.children[1];
heatmapBox.removeChild(oldCanvas);
}
},
4、在周期函数里进行初始化
但是这里需要注意的是,为了自适应窗口的大小,保证x、y的位置不会存在误差,这里要进行相关的函数处理,需要对窗口的大小进行监听,窗口大小改变时,进行对数据中的x、y进行重新计算:
created(){
this.initValue()
},
mounted(){
this.getRectValue()
this.initHotPic()
this.progressDom = document.getElementsByClassName('progress_list')
var _this = this
window.onresize = () => {
return (() => {
_this.cavWidth = document.getElementById("heatmap").clientWidth;
_this.cavHeight = document.getElementById("heatmap").clientHeight;
})()
}
},
当然,为了保证热力图的数据能够自动根据窗口的大小进行改变,当然少不了监听函数,对视口的宽高进行设置,
watch:{
cavWidth:{
handler(curVal, oldVal) {
var _this = this;
_this.cavWidth = curVal;
if (oldVal != 0 && oldVal!=null) {
for (var i = 0; i < this.points.length; i++) {
this.points[i].x = Number((this.points[i].x * curVal / oldVal).toFixed(0));
}
_this.initHotPic();
}
// console.log("宽=" + curVal, oldVal);
},
},
cavHeight:{
handler(curVal, oldVal) {
var _this = this;
_this.cavHeight = curVal;
if (oldVal != 0 && oldVal!=null) {
for (var i = 0; i < this.points.length; i++) {
this.points[i].y = Number((this.points[i].y * curVal / oldVal).toFixed(0));
console.log(this.points[i].y)
}
_this.initHotPic();
}
// console.log("高=" + curVal, oldVal);
},
}
},
总结:
由于是项目中涉及到的,会有的坑已经被本人踩过了,代码及拿即用,欢迎各位猿友电站或在下方评论,有问题评论我会及时回复的,谢谢。
heatmap的官网指导:https://www.patrick-wied.at/static/heatmapjs/docs.html