热力图介绍
echarts的热力图有两种,一种时按照点元素的权重,还有一种是按照点元素的密度(官网api害死人,一直搞不清为什么要用.concat([1])
)
点元素密度案例
看一下热力图实现的案例:
效果图:
示例代码&注释:
$.get(ROOT_PATH + '/data/asset/data/hangzhou-tracks.json', function (data) {
var points = [].concat.apply([], data.map(function (track) {
return track.map(function (seg) {
return seg.coord.concat([1]);
});
}));
myChart.setOption(option = {
//是否使用动画
animation: false,
//背景地图中心点等基础值
bmap: {
center: [120.13066322374, 30.240018034923],
zoom: 14,
roam: true
},
//视觉映射组件
visualMap: {
show: false,
top: 'top',
min: 0,
max: 5,
seriesIndex: 0,
calculable: true,
//定义在选中范围中的视觉元素
inRange: {
color: ['blue', 'blue', 'green', 'yellow', 'red']
}
},
series: [{
type: 'heatmap',
//该系列使用的坐标系,可选'cartesian2d'和'geo'
coordinateSystem: 'bmap',
data: points,
//每个点的大小
pointSize: 5,
//每个点模糊的大小
blurSize: 6
}]
});
// 添加百度地图插件
var bmap = myChart.getModel().getComponent('bmap').getBMap();
bmap.addControl(new BMap.MapTypeControl());
});
我们打印一下接口的数据:
visualMap 线性映射:
线性映射 表示 series.data 中的每一个值(dataValue)会经过线性映射计算,从 [visualMap.min, visualMap.max] 映射到设定的 [visual value 1, visual value 2] 区间中的某一个视觉的值(下称 visual value)。
我们设置了 [visualMap.min, visualMap.max] 为 [0, 100],并且我们有 series.data: [50, 10, 100]。我们想将其映射到范围为 [0.4, 1] 的 opacity 上,从而达到用透明度表达数值大小的目的。那么 visualMap 组件会对 series.data 中的每一个 dataValue 做线性映射计算,得到一个 opacityValue。最终得到的 opacityValues 为 [0.7, 0.46, 1]
0.7 = 0.4 + 50 * 0.6 /100
0.46 = 0.4 + 10 * 0.6 / 100
对于 颜色(color),使用数组表示例如:[’#333’, ‘#78ab23’, ‘blue’]。意思就是以这三个点作为基准,形成一种『渐变』的色带,数据映射到这个色带上。也就是说,与 visualMap.min 相等的值会映射到 ‘#333’,与 visualMap.max 相等的值会映射到 ‘blue’。对于 visualMap.min 和 visualMap.max 中间的其他点,以所给定的 ‘#333’, ‘#78ab23’, ‘blue’ 这三个颜色作为基准点进行分段线性插值,得到映射结果。
所以在调用上述接口时,我们会在inRange里面配置不同程度下的颜色去做映射,point的格式为:经度、纬度、1
Vue上实现
框架:vue-cli和webpack
ak申请地址:http://lbsyun.baidu.com/index.php?title=jspopular
安装包:
npm install echarts -S
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<!--引入百度地图-->
<script type="text/javascript"
src="http://api.map.baidu.com/api?v=2.0&ak=" ></script>
<!--引入百度热力图-->
<script type="text/javascript" src="http://api.map.baidu.com/library/Heatmap/2.0/src/Heatmap_min.js"></script>
<script type="text/javascript" src=""></script>
<title>official</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
webpack.config.js
module.exports = {
entry: './src/main.js',
externals: {
"BMap": "BMap",
},
}
新建map.js
export function MP(ak) {
return new Promise(function (resolve, reject) {
window.onload = function () {
resolve(BMap)
}
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://api.map.baidu.com/api?v=2.0&ak="+ak+"&callback=init";
script.onerror = reject;
document.head.appendChild(script);
})
}
ChartTest.vue
<template>
<!--一定要给宽高,不然会报错,container没有高度-->
<div id="chart">echarts百度地图</div>
</template>
<script>
//引入json数据
import baiduJSON from "./datas/baiduData.json";
import "echarts/extension/bmap/bmap";
import { MP } from "../api/map.js";
export default {
data() {
return {
ak: '7G4utppO09SpqFPHlhzGRUideunFgY0W'
};
},
mounted() {
this.$nextTick(function () {
var _this = this;
MP(_this.ak).then((BMap) => {
let myChart = _this.$echarts.init(document.getElementById("chart"));
let pointsData = baiduJSON; //其实这一步是多余的
//把数据处理成需要的格式,只是把数值都改成了1,具体项目可以根据自己实际来处理
var points = [].concat.apply(
[],
pointsData.map(function (track) {
return track.map(function (seg) {
return seg.coord.concat([1]);
});
})
);
let option; // eslint-disable-line no-unused-vars
myChart.setOption(
(option = {
animation: false,
bmap: {
center: [120.13066322374, 30.240018034923],
zoom: 14,
roam: true,
},
visualMap: {
show: true,
top: "top",
min: 0,
max: 5,
seriesIndex: 0,
calculable: true,
inRange: {
color: ["blue", "blue", "green", "yellow", "red"],
},
},
series: [
{
type: "heatmap",
coordinateSystem: "bmap",
data: points,
pointSize: 5,
blurSize: 6,
},
],
})
);
var bmap = myChart.getModel().getComponent("bmap").getBMap();
bmap.addControl(new BMap.MapTypeControl());
});
});
},
};
</script>
<style>
#chart {
width: 1300px;
height: 1300px;
}
</style>
其中baiduData.json 下载地址:https://cdn.jsdelivr.net/gh/apache/incubator-echarts-website@asf-site/examples/data/asset/data/hangzhou-tracks.json
点元素权重案例
效果图:
示例代码&注释:
var convertData = function (data) {
var res = [];
for (var i = 0; i < data.length; i++) {
var geoCoord = geoCoordMap[data[i].name];
if (geoCoord) {
res.push(geoCoord.concat(data[i].value));
}
}
return res;
};
option = {
title: {
text: '全国主要城市空气质量',
subtext: 'data from PM25.in',
sublink: 'http://www.pm25.in',
left: 'center',
textStyle: {
color: '#fff'
}
},
//backgroundColor: '#404a59', //一定要去除,否则地图不现实
visualMap: {
min: 0,
max: 250,
splitNumber: 5,
inRange: {
color: ['#d94e5d','#eac736','#50a3ba'].reverse()
},
textStyle: {
color: '#000'
}
},
series: [{
name: 'AQI',
type: 'heatmap',
coordinateSystem: 'leaflet',
data: convertData([
{name: "海门", value: 9},
{name: "鄂尔多斯", value: 12},
{name: "招远", value: 12},
{name: "舟山", value: 12},
{name: "齐齐哈尔", value: 14},
{name: "盐城", value: 15},
{name: "赤峰", value: 16},
{name: "青岛", value: 18},
{name: "乳山", value: 18},
{name: "金昌", value: 19},
{name: "泉州", value: 21},
{name: "莱西", value: 21},
{name: "日照", value: 21},
{name: "胶南", value: 22},
{name: "南通", value: 23},
{name: "拉萨", value: 24},
{name: "云浮", value: 24},
{name: "梅州", value: 25},
{name: "文登", value: 25},
{name: "上海", value: 25},
{name: "攀枝花", value: 25},
{name: "威海", value: 25},
{name: "承德", value: 25},
{name: "厦门", value: 26},
{name: "汕尾", value: 26},
{name: "潮州", value: 26},
{name: "丹东", value: 27},
{name: "太仓", value: 27},
{name: "曲靖", value: 27},
{name: "烟台", value: 28},
{name: "福州", value: 29},
{name: "瓦房店", value: 30},
{name: "即墨", value: 30},
{name: "抚顺", value: 31},
{name: "玉溪", value: 31},
{name: "张家口", value: 31},
{name: "阳泉", value: 31},
{name: "莱州", value: 32},
{name: "湖州", value: 32},
{name: "汕头", value: 32},
{name: "昆山", value: 33},
{name: "宁波", value: 33},
{name: "湛江", value: 33},
{name: "揭阳", value: 34},
{name: "荣成", value: 34},
{name: "连云港", value: 35},
{name: "葫芦岛", value: 35},
{name: "常熟", value: 36},
{name: "东莞", value: 36},
{name: "河源", value: 36},
{name: "淮安", value: 36},
{name: "泰州", value: 36},
{name: "南宁", value: 37},
{name: "营口", value: 37},
{name: "惠州", value: 37},
{name: "江阴", value: 37},
{name: "蓬莱", value: 37},
{name: "韶关", value: 38},
{name: "嘉峪关", value: 38},
{name: "广州", value: 38},
{name: "延安", value: 38},
{name: "太原", value: 39},
{name: "清远", value: 39},
{name: "中山", value: 39},
{name: "昆明", value: 39},
{name: "寿光", value: 40},
{name: "盘锦", value: 40},
{name: "长治", value: 41},
{name: "深圳", value: 41},
{name: "珠海", value: 42},
{name: "宿迁", value: 43},
{name: "咸阳", value: 43},
{name: "铜川", value: 44},
{name: "平度", value: 44},
{name: "佛山", value: 44},
{name: "海口", value: 44},
{name: "江门", value: 45},
{name: "章丘", value: 45},
{name: "肇庆", value: 46},
{name: "大连", value: 47},
{name: "临汾", value: 47},
{name: "吴江", value: 47},
{name: "石嘴山", value: 49},
{name: "沈阳", value: 50},
{name: "苏州", value: 50},
{name: "茂名", value: 50},
{name: "嘉兴", value: 51},
{name: "长春", value: 51},
{name: "胶州", value: 52},
{name: "银川", value: 52},
{name: "张家港", value: 52},
{name: "三门峡", value: 53},
{name: "锦州", value: 54},
{name: "南昌", value: 54},
{name: "柳州", value: 54},
{name: "三亚", value: 54},
{name: "自贡", value: 56},
{name: "吉林", value: 56},
{name: "阳江", value: 57},
{name: "泸州", value: 57},
{name: "西宁", value: 57},
{name: "宜宾", value: 58},
{name: "呼和浩特", value: 58},
{name: "成都", value: 58},
{name: "大同", value: 58},
{name: "镇江", value: 59},
{name: "桂林", value: 59},
{name: "张家界", value: 59},
{name: "宜兴", value: 59},
{name: "北海", value: 60},
{name: "西安", value: 61},
{name: "金坛", value: 62},
{name: "东营", value: 62},
{name: "牡丹江", value: 63},
{name: "遵义", value: 63},
{name: "绍兴", value: 63},
{name: "扬州", value: 64},
{name: "常州", value: 64},
{name: "潍坊", value: 65},
{name: "重庆", value: 66},
{name: "台州", value: 67},
{name: "南京", value: 67},
{name: "滨州", value: 70},
{name: "贵阳", value: 71},
{name: "无锡", value: 71},
{name: "本溪", value: 71},
{name: "克拉玛依", value: 72},
{name: "渭南", value: 72},
{name: "马鞍山", value: 72},
{name: "宝鸡", value: 72},
{name: "焦作", value: 75},
{name: "句容", value: 75},
{name: "北京", value: 79},
{name: "徐州", value: 79},
{name: "衡水", value: 80},
{name: "包头", value: 80},
{name: "绵阳", value: 80},
{name: "乌鲁木齐", value: 84},
{name: "枣庄", value: 84},
{name: "杭州", value: 84},
{name: "淄博", value: 85},
{name: "鞍山", value: 86},
{name: "溧阳", value: 86},
{name: "库尔勒", value: 86},
{name: "安阳", value: 90},
{name: "开封", value: 90},
{name: "济南", value: 92},
{name: "德阳", value: 93},
{name: "温州", value: 95},
{name: "九江", value: 96},
{name: "邯郸", value: 98},
{name: "临安", value: 99},
{name: "兰州", value: 99},
{name: "沧州", value: 100},
{name: "临沂", value: 103},
{name: "南充", value: 104},
{name: "天津", value: 105},
{name: "富阳", value: 106},
{name: "泰安", value: 112},
{name: "诸暨", value: 112},
{name: "郑州", value: 113},
{name: "哈尔滨", value: 114},
{name: "聊城", value: 116},
{name: "芜湖", value: 117},
{name: "唐山", value: 119},
{name: "平顶山", value: 119},
{name: "邢台", value: 119},
{name: "德州", value: 120},
{name: "济宁", value: 120},
{name: "荆州", value: 127},
{name: "宜昌", value: 130},
{name: "义乌", value: 132},
{name: "丽水", value: 133},
{name: "洛阳", value: 134},
{name: "秦皇岛", value: 136},
{name: "株洲", value: 143},
{name: "石家庄", value: 147},
{name: "莱芜", value: 148},
{name: "常德", value: 152},
{name: "保定", value: 153},
{name: "湘潭", value: 154},
{name: "金华", value: 157},
{name: "岳阳", value: 169},
{name: "长沙", value: 175},
{name: "衢州", value: 177},
{name: "廊坊", value: 193},
{name: "菏泽", value: 194},
{name: "合肥", value: 229},
{name: "武汉", value: 273},
{name: "大庆", value: 279}
])
}]
};
L.capinfo.echartsLayer(option).addTo(map);