echarts矢量地图自定义图标数据展示—echarts地图图表三种方案
Author:zhoulujun@live.cn Date:
地图数据展示,最先开始是想用百度地图,自定义覆盖物的形式展现,但是无法要做到区域选择高亮,还是比较麻烦。echarts可以实现矢量地图,地图图表并配上大数据。但是,需要把数据自定义形式覆盖到 地图上去。地图的formatter需要手工定义。
echarts地图图表三种方案
第一种方案,直接用地图图表形式展现
import echarts from 'echarts'
import shenZhenArea from 'shenZhen-area' //区域gis数据,区域 properties 属性里面没有cp 属性(lable),自动计算,可有手动补上。
import shenZhenBorder from 'shenZhen-border.json'边界gis数据,方便实现自定义外边框
//地图展示数据
let mapData2ShowValue = [
{"name": "光明区", "value": [2121, 1800]},
{"name": "南山区", "value": [2121, 1800]},
{"name": "盐田区", "value": [2121, 1800]},
{"name": "罗湖区", "value": [2121, 1800]},
{"name": "福田区", "value": [2121, 1800]},
{"name": "大鹏新区", "value": [2121, 1800]},
{"name": "龙岗区", "value": [2121, 1800]},
{"name": "坪山区", "value": [2121, 1800]},
{"name": "宝安区", "value": [2121, 1800]},
{"name": "龙华区", "value": [2121, 1800]}]
echarts.registerMap('shenZhenBorder', shenZhenBorder)
echarts.registerMap('shenZhenArea', shenZhenArea)
let chart1 = echarts.init(document.getElementById('map1'))
chart1.setOption({
geo: {
type: 'map',
map: 'shenZhenBorder',
itemStyle: {
areaColor: '#f0f',
borderColor: '0ff', //省市边界线
borderWidth: 4,
},
label: {
show: false,
},
emphasis: {
itemStyle: {
areaColor: "rgba(0,193,255,0)",
},
}
},
series: [
{
name: 'name4',
type: 'map',
mapType: 'shenZhenArea',
data: mapData2ShowValue,
// nameMap: nameMap,//label 用了 formatter ,所以需要注释
selectedMode: 'false', //是否允许选中多个区域
itemStyle: {
areaColor: "rgba(0,51,100,.4)",
borderColor: "rgba(0,150,236,1)",
},
label: {
show: true,
width: 110,
height: 110,
align: 'left',
position: [0, 0],
backgroundColor: {
image: require('../../../public/maps/map-icon2.png'),
width: 110,
height: 110
},
formatter: function (val) {
// console.log('_______-formatter')
// console.log(val)
let str= '{a|' + (nameMap&&nameMap[val.name]||val.name) + '}' + '\n'
+ '{hr|}\n'
// + '{num|' + val.data.value[0] + '}\n'
// + '{num|' + val.data.value[1] + '}'
//可能有多个数值
let numArr=val.data.value.map(num=>{
return '{num|' + num + '}'
})
str+=numArr.join('\n')
return str;
},
rich: {
a: {
color: '#000',
fontSize: 14,
padding: [0, 0, 15, 10],
align: 'left',
},
hr: {
width: 110,
height: 30,
},
num: {
padding: [8, 0, 0, 35],
color: '#fff',
fontSize: 14,
}
},
},
emphasis: {
itemStyle: {
areaColor: "rgba(0,193,255,.6)",
},
},
},
]
})
如果需要改动标注点的位置,需要改变cp坐标
//设置区域 标注地点,默认echarts自动计算
shenZhenArea.features.forEach((area, index) => {
area.properties['cp'] = scatterData[index].value.slice(0,2)
})
//地图名字区域实际名字 和 自定义地区的名称映射
let nameMap = {}
mapData2ShowValue.forEach((item, index) => {
nameMap[item.name]=scatterData[index].name
})
第二方案,通过散点,添加上去
import echarts from 'echarts'
import shenZhenArea from 'shenZhen-area'
import shenZhenBorder from 'shenZhen-border.json'边界gis数据,方便实现自定义外边框
echarts.registerMap('shenZhenBorder', shenZhenBorder)
echarts.registerMap('shenZhenArea', shenZhenArea)
let chart2 = echarts.init(document.getElementById('map2'))
//散点 添加标注到地图 series data 数据
let scatterData = [
{
"name": "光明",
"value": [113.92635602317334, 22.77565238823337, 2121, 1800]
},
{
"name": "南山",
"value": [113.90793997084684, 22.49941161039266, 2121, 1800]
},
{
"name": "盐田",
"value": [114.26956427107639, 22.59860716243546, 2121, 1800]
},
{
"name": "罗湖",
"value": [114.14902283766655, 22.56721616495356, 2121, 1800]
},
{
"name": "福田",
"value": [114.04857164315834, 22.547125926565144, 2121, 1800]
},
{
"name": "大鹏",
"value": [114.48218596611878, 22.607396641730393, 2121, 1800]
},
{
"name": "龙岗",
"value": [114.25617077847531, 22.73296063165799, 2121, 1800]
},
{
"name": "坪山",
"value": [114.35829615955865, 22.677712476089848, 2121, 1800]
},
{
"name": "宝安",
"value": [113.85938856016787, 22.64632147860795, 2121, 1800]
},
{
"name": "龙华",
"value": [114.04187489685779, 22.7116147533703, 2121, 1800]
}];
chart2.setOption({
geo: {
map: 'shenZhenBorder',
itemStyle: {
areaColor: "rgba(0,139,255,0)",
borderColor: "rgba(0,150,236,1)", //省市边界线
borderWidth: 4,
},
emphasis: {
itemStyle: {
areaColor: "rgba(0,193,255,0)",
},
}
},
series: [
{
tooltip: {
show: false,
},
type: 'map',
map: 'shenZhenArea',
itemStyle: {
areaColor: "rgba(0,51,100,.4)",
borderColor: "rgba(0,150,236,1)",
},
label: {
show: false,
},
emphasis: {
itemStyle: {
areaColor: "rgba(0,193,255,.6)",
},
label: {
show: false,
},
}
},
{
name: 'ShowData',
type: 'scatter',
coordinateSystem: 'geo',
// symbol:'none',
symbol: `image://${require('../../../public/maps/map-icon2.png')}`,
symbolSize: [110, 110],
encode: {
value: 2
},
label: {
show: true,
width: 110,
height: 110,
align: 'left',
position: [0, 0],
formatter: function (val) {
// console.log('_______-formatter')
// console.log(val)
let str= '{a|' + (nameMap&&nameMap[val.name]||val.name) + '}' + '\n'
+ '{hr|}\n'
// + '{num|' + val.data.value[0] + '}\n'
// + '{num|' + val.data.value[1] + '}'
//可能有多个数值
let temArr=val.data.value.slice(2)
let numArr=temArr.map(num=>{
return '{num|' + num + '}'
})
str+=numArr.join('\n')
return str;
},
rich: {
a: {
color: '#000',
fontSize: 14,
padding: [0, 0, 15, 10],
align: 'left',
},
hr: {
width: 110,
height: 30,
},
num: {
padding: [8, 0, 0, 60],
color: '#fff',
fontSize: 14,
},
num2: {
fontSize: 14,
}
}, //富文本样式,就是上面的formatter中'{a|'和'{b|'
},
/*label: {
show: true,
position: ['0', '15%'],
formatter: function(val) {
// console.log('val')
/!* let dom=
''+
''+
''+val.name+''+
''+
''+
''+val.data.value[2]+''+
''+val.data.value[3]+''+
''+
''
return dom;*!/
// console.log(val)
return '{name|' + val.name + '}' + '\n'
+'{hr|}\n'
+ '{yellow|}{b|' + val.data.value[2] +'}\n'
+ '{blue|}{b|' + val.data.value[3]+ '}';
}, //让series 中的文字进行换行
rich: {
name: {
color: '#000',
fontSize: 14,
},
hr:{
width:80,
height:30
},
yellow:{
verticalAlign:'middle',
offset:[-30,0],
width:8,
height:8,
backgroundColor:'#fff22a',
borderRadius:8,
},
blue:{
verticalAlign:'middle',
// offset:[30,0],
width:8,
height:8,
backgroundColor:'#2813ff',
borderRadius:8,
},
abg: {
backgroundColor: '#033',
width: '100%',
align: 'right',
height: 25,
padding:[0,10],
borderRadius: [4, 4, 0, 0]
},
b: {
color: '#fff',
fontFamily: 'Microsoft YaHei',
fontSize: 14,
width: '100%',
height: 24,
padding:[0,10],
backgroundColor: 'rgba(4,4,4,0.5)',
borderRadius: 4,
// borderWidth: 1,
// borderColor: '#f00',
textAlign: 'center',
}
}, //富文本样式,就是上面的formatter中'{a|'和'{b|'
},*/
itemStyle: {
normal: {
color: '#f4e925',
shadowBlur: 10,
shadowColor: '#333'
}
},
data: scatterData,
}
]
})
第三种方案,通过获取标注点的经纬度转像素坐标,绝对定位dom到地图上,通过css 鼠标事件穿透,pointer-events: none。等等手段达到目的
import echarts from 'echarts'
import shenZhenArea from 'shenZhen-area'
import shenZhenBorder from 'shenZhen-border.json'
echarts.registerMap('shenZhenBorder', shenZhenBorder)
echarts.registerMap('shenZhenArea', shenZhenArea)
let chart3 = echarts.init(document.getElementById('map3'))
let scatterData = [
{
"name": "光明",
"value": [113.92635602317334, 22.77565238823337, 2121, 1800]
},
{
"name": "南山",
"value": [113.90793997084684, 22.49941161039266, 2121, 1800]
},
{
"name": "盐田",
"value": [114.26956427107639, 22.59860716243546, 2121, 1800]
},
{
"name": "罗湖",
"value": [114.14902283766655, 22.56721616495356, 2121, 1800]
},
{
"name": "福田",
"value": [114.04857164315834, 22.547125926565144, 2121, 1800]
},
{
"name": "大鹏",
"value": [114.48218596611878, 22.607396641730393, 2121, 1800]
},
{
"name": "龙岗",
"value": [114.25617077847531, 22.73296063165799, 2121, 1800]
},
{
"name": "坪山",
"value": [114.35829615955865, 22.677712476089848, 2121, 1800]
},
{
"name": "宝安",
"value": [113.85938856016787, 22.64632147860795, 2121, 1800]
},
{
"name": "龙华",
"value": [114.04187489685779, 22.7116147533703, 2121, 1800]
}];
chart3.setOption({
geo: {
map: 'shenZhenBorder',
itemStyle: {
areaColor: "rgba(0,139,255,0)",
borderColor: "rgba(0,150,236,1)", //省市边界线
borderWidth: 4,
},
emphasis: {
itemStyle: {
areaColor: "rgba(0,193,255,0)",
},
}
},
series: [
{
tooltip: {
show: false,
},
type: 'map',
map: 'shenZhenArea',
itemStyle: {
areaColor: "rgba(0,51,100,.4)",
borderColor: "rgba(0,150,236,1)",
},
label: {
show: false,
},
// data:shenZhenArea.features.map((area)=>{
// return area.properties.name
// }),
emphasis: {
itemStyle: {
areaColor: "rgba(0,193,255,.6)",
},
label: {
show: false,
},
}
},
]
})
let chartBox3 = this.$refs.chartBox3
setMapMark(chartBox3)
function setMapMark(box) {
let domList = scatterData.map((item) => {
let arrPx = chart3.convertToPixel('geo', item.value.slice(0, 2))
let temArr=item.value.slice(2)
// console.log(arrPx)
let dom = `
${item.name} ${temArr.map((num)=>{
//可能有多个数值
return `
${num} `
}).join('')}
`
return dom
})
box.innerHTML = domList.join('')
}
dom样式
.map-item-show {
z-index: 99999;
position: absolute;
width: 109px;
height: 110px;
font-size: 14px;
background: url('../../../public/maps/map-icon.png') no-repeat;
background-size: 44px 100px;
line-height: 1;
pointer-events: none;
}
.map-name-box {
color: #000;
padding: 14px 8px;
}
.map-data-box {
width: 56px;
background: rgba(0, 0, 0, .4);
border-radius: 4px;
color: #fff;
padding :2px 8px;
margin :10px 0 0 30px;
>div{
line-height :18px;
display :flex;
justify-content :start;
align-items :center;
}
.map-data-icon{
width :8px;
height :8px;
background :#2813ff;
border-radius :100%;
margin-right :6px;
}
.icon-yellow{
background #fff22a;
}
}
三面三种方案都可以实现各有优劣,第一实现最简单,第二种实现map 于散点复合图表,可以做出效果更佳
第三种dom实现,免得写坑爹的formatter(rich没有css3来的顺手)
搞完也累了,给个美女,看看
转载本站文章《echarts矢量地图自定义图标数据展示—echarts地图图表三种方案》,
请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/js/2016_0219_7633.html