假设需求背景:每到冬天都会有很多候鸟老人到海南来过冬,结合当前国内新冠疫情形势,统计来自全国各风险区域(高中低风险)的人数,对海南各市县地图进行渲染,地图弹窗结合echarts柱状图可视化。
统计测试数据如下:
数据说明:high字段表示高风险地区来海南人数 高风险>1500, 1500>=中风险>500, 低风险=<500
dataTest = [
{“city”:“海口”, “level”:“高风险”, “high”:2150, “mid”:2600, “low”:3400},
{“city”:“三亚”, “level”:“高风险”, “high”:3445, “mid”:5330, “low”:6754},
{“city”:“文昌”, “level”:“高风险”, “high”:1100, “mid”:2000, “low”:3450},
{“city”:“儋州”, “level”:“高风险”, “high”:1550, “mid”:2600, “low”:3400},
{“city”:“琼海”, “level”:“高风险”, “high”:1656, “mid”:2700, “low”:3210},
{“city”:“保亭”, “level”:“中风险”, “high”:800, “mid”:2100, “low”:2221},
{“city”:“陵水”, “level”:“中风险”, “high”:900, “mid”:2500, “low”:2354},
{“city”:“东方”, “level”:“低风险”, “high”:460, “mid”:620, “low”:810},
{“city”:“白沙”, “level”:“低风险”, “high”:324, “mid”:612, “low”:465},
{“city”:“临高”, “level”:“低风险”, “high”:432, “mid”:532, “low”:410},
{“city”:“定安”, “level”:“低风险”, “high”:335, “mid”:605, “low”:405},
{“city”:“澄迈”, “level”:“低风险”, “high”:356, “mid”:557, “low”:396},
{“city”:“琼中”, “level”:“低风险”, “high”:469, “mid”:630, “low”:454},
{“city”:“屯昌”, “level”:“低风险”, “high”:357, “mid”:658, “low”:440},
{“city”:“乐东”, “level”:“低风险”, “high”:287, “mid”:265, “low”:415},
{“city”:“昌江”, “level”:“低风险”, “high”:223, “mid”:254, “low”:349},
{“city”:“万宁”, “level”:“中风险”, “high”:550, “mid”:605, “low”:701},
{“city”:“五指山”, “level”:“中风险”, “high”:581, “mid”:653, “low”:818}
]
实现效果:根据风险等级渲染地图颜色,可选择有底图和无底图效果。
地图弹窗结合echarts柱状图可视化:
实现步骤:
1、本地加载json数据创建featurelayer要素图层,不依赖地图服务,可选择有底图和无底图效果。
2、将测试数据属性赋予featurelayer,并根据属性指标渲染地图(本例根据"level"字段风险等级渲染,高风险:红色;中风险:黄色;低风险:绿色)。实际项目中,测试数据来自接口,实现对地图的实时渲染。
3、监听鼠标点击图层事件:点击时创建echarts容器div,配置echarts(本例采用最简单的柱状图),并将此div作为地图弹窗的内容。
4、监听鼠标移入图层事件:移入时当前要素高亮显示。
5、监听鼠标移出图层事件:移出时移除高亮显示。
相关资源下载,包含海南地市json数据、echarts相关js,源代码:传送门:资源下载
实现代码,下载相关资源后可直接打开运行:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>arcgis api 弹窗结合echart可视化</title>
<link rel="stylesheet" href="https://js.arcgis.com/3.20/esri/css/esri.css">
<style>
body,
html {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
font-family: Arial;
}
#map {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
border: 0px dashed black;
background-color: rgb(192, 192, 192);
}
/* 弹窗窗口 */
.esriPopup .contentPane {
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
font-size: 16px;
height: 260px;
width: 400px;
}
/* 弹窗标题 */
.esriPopup .titlePane {
width: 410px;
}
/* 弹窗缩放至按钮 */
.esriPopup .actionsPane {
padding: 0px;
}
</style>
</head>
<body>
<div id="map">
</div>
</body>
<!-- 引入ARCGIS API -->
<script src="echarts.js"></script>
<script src="https://js.arcgis.com/3.20"></script>
<script type="text/javascript">
var map, getJson;
require([
"esri/map",
'esri/Color',
"esri/tasks/FeatureSet",
"esri/layers/FeatureLayer",
"Echarts3Layer.js",
'esri/renderers/UniqueValueRenderer',
"esri/layers/ArcGISTiledMapServiceLayer",
'esri/symbols/SimpleFillSymbol',
'esri/symbols/SimpleLineSymbol',
"esri/layers/GraphicsLayer",
'esri/graphic',
"esri/geometry/Extent",
"dojo/domReady!"
], function(
Map,
Color,
FeatureSet,
FeatureLayer,
Echarts3Layer,
UniqueValueRenderer,
ArcGISTiledMapServiceLayer,
SimpleFillSymbol,
SimpleLineSymbol,
GraphicsLayer,
Graphic,
Extent,
) {
//地图范围
var mapExtent = new Extent({
xmax: 113.799760210539,
xmin: 106.57095767482662,
ymax: 20.459116202966324,
ymin: 18.27952992162579,
spatialReference: {
wkid: 4326
}
})
map = new Map("map", {
extent: mapExtent,
sliderStyle: "small",
logo: false,
});
//arcgis 在线底图(可选择有底图和无底图背景)
var myTileLayer = new ArcGISTiledMapServiceLayer("http://cache1.arcgisonline.cn/arcgis/rest/services/ChinaOnlineCommunity/MapServer", {
visible: true
});
map.addLayer(myTileLayer)
var glayer = new GraphicsLayer() //高亮绘制图层
map.addLayer(glayer);
map.on('load', function () {
map.hideZoomSlider()
map.hidePanArrows()
})
window.onload = function() {
getJson()
}
//测试数据,高风险地区来海南人数,高风险>1500, 1500>=中风险>500, 低风险=<500
var dataTest = [
{"city":"海口", "level":"高风险", "high":2150, "mid":2600, "low":3400},
{"city":"三亚", "level":"高风险", "high":3445, "mid":5330, "low":6754},
{"city":"文昌", "level":"高风险", "high":1100, "mid":2000, "low":3450},
{"city":"儋州", "level":"高风险", "high":1550, "mid":2600, "low":3400},
{"city":"琼海", "level":"高风险", "high":1656, "mid":2700, "low":3210},
{"city":"保亭", "level":"中风险", "high":800, "mid":2100, "low":2221},
{"city":"陵水", "level":"中风险", "high":900, "mid":2500, "low":2354},
{"city":"东方", "level":"低风险", "high":460, "mid":620, "low":810},
{"city":"白沙", "level":"低风险", "high":324, "mid":612, "low":465},
{"city":"临高", "level":"低风险", "high":432, "mid":532, "low":410},
{"city":"定安", "level":"低风险", "high":335, "mid":605, "low":405},
{"city":"澄迈", "level":"低风险", "high":356, "mid":557, "low":396},
{"city":"琼中", "level":"低风险", "high":469, "mid":630, "low":454},
{"city":"屯昌", "level":"低风险", "high":357, "mid":658, "low":440},
{"city":"乐东", "level":"低风险", "high":287, "mid":265, "low":415},
{"city":"昌江", "level":"低风险", "high":223, "mid":254, "low":349},
{"city":"万宁", "level":"中风险", "high":550, "mid":605, "low":701},
{"city":"五指山", "level":"中风险", "high":581, "mid":653, "low":818}
]
//获取本地json数据,根据json数据创建要素图层,根据属性指标渲染图层
getJson = function () {
let json = null
let url = "city.json"/*json文件url*/
let request = new XMLHttpRequest();
request.open("get", url);/*设置请求方法与路径*/
request.send(null);/*不发送数据到服务器*/
request.onload = function () {/*XHR对象获取到返回信息后执行*/
if (request.status == 0) {/*返回状态为0,即为数据获取成功*/
json = JSON.parse(request.responseText);
let featureSet = new FeatureSet(json)
let layerDefinition = { //要素描述
"geometryType": "esriGeometryPolygon",
"fields":[
{
"name" : "FID", //字段名称
"type" : "esriFieldTypeOID", //字段类型
"alias" : "FID"
},
{
"name" : "city_name",
"type" : "esriFieldTypeString",
"alias" : "city_name",
"length" : 254
},
{
"name" : "value",
"type" : "esriFieldTypeInteger",
"alias" : "value"
}
]
}
//要素合集
let featureCollection = {
layerDefinition: layerDefinition,
featureSet: featureSet
}
let featureLayer = new FeatureLayer(featureCollection) //使用要素合集创建要素图层
//根据测试数据渲染图层
addData(featureLayer,dataTest) //将测试数据属性赋予要素图层
let symbol = new SimpleFillSymbol() //默认渲染符号
let renderer = new UniqueValueRenderer(symbol, "level") //唯一值渲染,根据level字段渲染
renderer.addValue('高风险', new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, //高风险渲染符号
new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
new Color([105,105,105]), 1),new Color([255,0,0,0.7]))
)
renderer.addValue('中风险', new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, //中风险渲染符号
new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
new Color([105,105,105]), 1),new Color([255,255,0,0.7])))
renderer.addValue('低风险', new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, //低风险渲染符号
new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
new Color([105,105,105]), 1),new Color([0,128,0,0.7])))
featureLayer.setRenderer(renderer) //渲染要素图层
featureLayer.setOpacity(0.8) //图层透明度
map.addLayer(featureLayer)
//监听鼠标点击图层事件
featureLayer.on('click',function(evt) {
//获取图层属性信息
let data_num = [] //用于存放各风险人数的集合
let high = evt.graphic.attributes.high //高风险人数
let mid = evt.graphic.attributes.mid //中风险人数
let low = evt.graphic.attributes.low //低风险人数
data_num.push(high)
data_num.push(mid)
data_num.push(low)
let cityName = evt.graphic.attributes.city //城市名称
let level = evt.graphic.attributes.level //风险等级
let cityLevel = cityName + ":" + level //城市风险等级
//创建echart的容器div
if(document.getElementById("echart")){ //每次点击都判断是否存在echart容器div,如果存在,则删除
let div = document.getElementById("echart");
div.parentNode.removeChild(div);
}
let divChart = document.createElement("div") //创建容器div
divChart.id= "echart"; //赋予id
divChart.style = "width:380px;height:260px;" //容器size大小
document.body.appendChild(divChart) //添加到节点
//根据div创建echart实例和配置
let myChart = echarts.init(document.getElementById("echart")); //根据id创建echart实例
let option = { //配置,本例采用最简单的柱状图
title: {
text: cityLevel
},
tooltip: {},
legend: {
data:['人数']
},
xAxis: {
data: ["高风险","中风险","低风险"]
},
yAxis: {},
series: [{
name: '人数',
type: 'bar',
data: data_num
}]
}
myChart.setOption(option); //echart实例加载配置
//图层弹窗配置
map.infoWindow.setTitle("高风险人数分布"); //弹窗标题
map.infoWindow.setContent(divChart); //将echart柱状图当做弹窗内容
map.infoWindow.show(evt.screenPoint,map.getInfoWindowAnchor(evt.screenPoint)); //弹窗显示位置
})
//监听鼠标移入图层事件
featureLayer.on("mouse-over",function(evt) {
//鼠标移入图层高亮显示
let sfs = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID,
new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
new Color([0,191,255]), 3),new Color([192,192,192,0.01])
)
let highlight = new Graphic(evt.graphic.geometry,sfs);
glayer.add(highlight)
})
//监听鼠标移出图层事件
featureLayer.on("mouse-out",function(){
//鼠标移出图层后移除高亮显示
glayer.clear()
})
}
}
}
//将测试数据属性赋予要素图层
addData = function(layer,data) {
let length = layer.graphics.length
for (let i=0; i<length; i++){
cityname = layer.graphics[i].attributes.city_name
for (let j=0; j<data.length; j++) {
city = data[j].city
if (cityname == city) {
layer.graphics[i].attributes = Object.assign(data[j], {'cityname': data[j].city})
}
}
}
}
});
</script>
</html>