01 [ArcGIS JS API + eCharts series] realized on a map drawn 2D charts

Outline

Chart ArcGIS API for JavaScript is currently drawing interface provided is very limited, but the style is not beautiful when we add the corresponding chart on the map, when combined with the current market need or other chart visualization plug-ins do. This article describes how to use the next ArcGIS API for JavaScript 4.14 eCharts 4.7.0 version and to achieve this demand. Article reference implementation [ GIS House ] blog content. First, look at the final results:

 

Realization of ideas

Implementation of this demand is completely pure front-end solution, followed by a brief introduction at the realization of ideas:

  • To achieve a basic two-dimensional map;
  • Add eCharts chart on the map;
  • Listening map view change events, redraw the chart size chart to follow the map to achieve pseudo-scaling.

 

Specific implementation process

1, first with the ArcGIS API for JavaScript to initialize a two-dimensional map, as follows:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>echarts和ArcGIS JS API结合</title>

    <link rel="stylesheet" href="https://js.arcgis.com/4.14/esri/themes/light/main.css" />
    <style>
        body {
            margin: 0 !important;
        }
        #mapview {
            position: absolute;
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <div id="mapview"></div>

    <script src="https://js.arcgis.com/4.14/"></script>
    <script>
        require(["esri/Map", "esri/views/MapView","esri/Basemap", "esri/layers/TileLayer"], function(Map, MapView, Basemap, TileLayer) {

            var basemap = new Basemap({      //此处自定义一张暗夜色的底图,并没有用JS API自带的底图
                baseLayers: [
                    new TileLayer({
                        url: "http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer",
                        title: "Basemap"
                    })
                ],
                title: "basemap",
                id: "basemap"
            });

            var map = new Map({
                basemap: basemap
            });
            var view = new MapView({
                container: "mapview", 
                map: map, 
                zoom: 8, 
                center: [104.072043,30.663724]     //地图中心点为成都
            });
      });
    </script>
</body>
</html>

2, then draw eCharts chart on the map. It means adding storage div elements of the chart in this mapview DOM element, and set the initial size, which means that the page requires the introduction of eCharts and the corresponding jQuery development kits, we only need to go to the official website to download the code is as follows:

Introduced development kits:

    <script src="./libs/jquery-3.4.1.min.js"></script>
    <script src="./libs/echarts.js"></script>

Draw diagrams on the map:

            //初始化图表信息函数
			function echartsMapInit() {
                echartsInfos = [];      //绘制函数里定义一个存放图表配置的全局数组
                echartsInfos.push({
                    x: 104.072043,      //图表在地图上绘制的位置
                    y: 30.663724,
                    content: '<div id="info1" style="height:150px;width:300px;position:absolute;"></div>',      //存放图表的DOM元素
                    id:"info1",
                    echartsObj:null,
                    option:{                   //图表的配置信息,具体参数可到eCharts官网查看
                        color: ['#3398DB'],
                        tooltip : {
                            trigger: 'axis',
                            axisPointer : {            
                                type : 'shadow'        
                            }
                        },
                        grid: {
                            left: '3%',
                            right: '4%',
                            bottom: '3%',
                            top: '3%',
                            containLabel: true,
                        },
                        xAxis : [
                            {
                                type : 'category',
                                data : ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
                                axisTick: {
                                    alignWithLabel: true
                                },              
                                axisLabel:{  
                                    interval:0,
                                    rotate:-30,
                                },  
                                axisLine:{  
                                    lineStyle:{  
                                        color:'#FFFFFF',  
                                        width:1,
                                    }  
                                }
                            }
                        ],
                        yAxis : [
                            {
                                type : 'value',
                                splitLine: {  
                                    lineStyle: {  
                                        color: ['#0087ED']  
                                    }  
                                },  
                                nameTextStyle: {  
                                    color: ['#FFFFFF']  
                                    },  
                                axisLine:{  
                                    lineStyle:{  
                                        color:'#FFFFFF',  
                                        width:1,
                                    }  
                                }
                            }
                        ],
                        series : [
                            {
                                name:'直接访问',
                                type:'bar',
                                barWidth: '60%',
                                data:[10, 52, 200, 334, 390, 330, 220]
                            }
                        ]
                    }
                });

                echartsInfos.push({       //需要绘制的第二个图表的相关信息
                    x: 106.492447,
                    y: 29.608168,
                    content: '<div id="info2" style="height:150px;width:300px;position:absolute;"></div>',
                    id:"info2",
                    echartsObj:null,
                    option:{
                        title: {
                            text: ''
                        },
                        tooltip : {
                            trigger: 'axis',
                            axisPointer: {
                                type: 'cross',
                                label: {
                                    backgroundColor: '#6a7985'
                                }
                            }
                        },
                        legend: {
                            data:['视频广告','直接访问','搜索引擎'],
                            textStyle:{  
                                color: ['#FFFFFF']  
                            },  
                        },
                        toolbox: {
                            feature: {
                                saveAsImage: {}
                            }
                        },
                        grid: {
                            left: '3%',
                            right: '4%',
                            bottom: '3%',
                            top: '10%',
                            containLabel: true
                        },
                        xAxis : [
                            {
                                type : 'category',
                                boundaryGap : false,
                                data : ['周一','周二','周三','周四','周五','周六','周日'],
                                nameTextStyle: {  
                                    color: ['#FFFFFF']  
                                },  
                                axisLine:{  
                                    lineStyle:{  
                                        color:'#FFFFFF',  
                                        width:1,
                                    }  
                                }
                            }
                        ],
                        yAxis : [
                            {
                                type : 'value',
                                nameTextStyle: {  
                                    color: ['#FFFFFF']  
                                },  
                                axisLine:{  
                                    lineStyle:{  
                                        color:'#FFFFFF',  
                                        width:1,
                                    }  
                                }
                            }
                        ],
                        series : [
                            {
                                name:'视频广告',
                                type:'line',
                                stack: '总量',
                                areaStyle: {},
                                data:[150, 232, 201, 154, 190, 330, 410]
                            },
                            {
                                name:'直接访问',
                                type:'line',
                                stack: '总量',
                                areaStyle: {normal: {}},
                                data:[320, 332, 301, 334, 390, 330, 320]
                            },
                            {
                                name:'搜索引擎',
                                type:'line',
                                stack: '总量',
                                label: {
                                    normal: {
                                        show: true,
                                        position: 'top'
                                    }
                                },
                                areaStyle: {normal: {}},
                                data:[820, 932, 901, 934, 1290, 1330, 1320]
                            }
                        ]
                    }
                });

                for (var i = 0; i < echartsInfos.length; i++) {
                        var echartsInfo = echartsInfos[i];
                        
                        var mapPoint = {             //坐标转换,将地理坐标转为屏幕坐标
                            x: echartsInfo.x,
                            y: echartsInfo.y,
                            // spatialReference: {
                            //     wkid: view.spatialReference.wkid
                            // }
                            spatialReference: {
                                wkid: 4326
                            }
                        };
                        var screenPoint = view.toScreen(mapPoint);
                        var obj = {};            //重新定义一个图表配置信息的对象
                        obj.x =screenPoint.x;
                        obj.y =screenPoint.y;
                        obj.content = echartsInfo.content;
                        obj.id = echartsInfo.id;
                        obj.option = echartsInfo.option;
                        obj.echartsObj  = echartsInfo.echartsObj;
                        echartsInfos[i].echartsObj = loadEchartsMap(obj);
                }
            };

			//绘制图表函数
            function loadEchartsMap(obj) {
                $("#mapview").append(obj.content);           //往mapview追加存放图表的DOM元素
                
                var dom = document.getElementById(obj.id);     //绘制图表
                var myChart = echarts.init(dom);
                myChart.setOption(obj.option);

                positionEchartsMap(obj);        //调整图表位置及大小
                return myChart;
            }

3, after the initialization is complete chart information, to re-adjust the position and size of the chart, where the size of the chart to follow the map to achieve scale, so to get level map view to resize the chart according to hierarchy, as follows:

            //统计图窗口位置
            function relocatePopup() {
                for (var i = 0; i < echartsInfos.length; i++) {
                    var echartsInfo = echartsInfos[i];
                    //坐标转换
                    var mapPoint = {
                    	x: echartsInfo.x,
                    	y: echartsInfo.y,
                    	//spatialReference: view.spatialReference
                    	spatialReference: {
                        	wkid: 4326
                    	}
                    };
                    var screenPoint = view.toScreen(mapPoint);
                    var obj = {};
                    obj.x =screenPoint.x;
                    obj.y =screenPoint.y;
                    obj.option = echartsInfo.option;
                    obj.id = echartsInfo.id;
                    obj.echartsObj  = echartsInfo.echartsObj;
                    
                    positionEchartsMap(obj);
            }
            };

			//调整图表位置及大小函数
            function positionEchartsMap(obj) {
                $('#' + obj.id).css('transform', 'translate3d(' + obj.x + 'px, ' + obj.y + 'px, 0)');

                switch(view.zoom) {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                        $('#'+obj.id).css('height', '50px');
                        $('#'+obj.id).css('width', '100px');
                        break;
                    case 6:
                    case 7:
                    case 8:
                        $('#'+obj.id).css('height', '120px');
                        $('#'+obj.id).css('width', '200px');
                        break;
                    case 9:
                    case 10:
                        $('#'+obj.id).css('height', '150px');
                        $('#'+obj.id).css('width', '300px');
                        break;
                    case 11:
                    case 12:
                        $('#'+obj.id).css('height', '200px');
                        $('#'+obj.id).css('width', '350px');
                        break;
                    default:
                        $('#'+obj.id).css('height', '250px');
                        $('#'+obj.id).css('width', '400px');

                }
                if(obj.echartsObj) {
                    obj.echartsObj.resize(); 
                } 
            };

4, the final size of the map view change event listener to call relocatePopup method redraw the chart, as follows:

            view.when(function() {
                //监听地图变化事件,刷新统计图位置
                view.watch("extent", function() {
                    relocatePopup();
                });
                view.watch("rotation", function() {
                    relocatePopup();
                });

                //地图加载完,初始化统计图
                echartsMapInit();
            });

5, after completion of the above steps, to achieve a pure front-end technology and eCharts binding ArcGIS JS API function to draw a two-dimensional graph.

 

All code attached:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>echarts和ArcGIS JS API结合</title>

    <link rel="stylesheet" href="https://js.arcgis.com/4.14/esri/themes/light/main.css" />
    <style>
        body {
            margin: 0 !important;
        }
        #mapview {
            position: absolute;
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <div id="mapview"></div>

    <script src="./libs/jquery-3.4.1.min.js"></script>
    <script src="./libs/echarts.js"></script>
    <script src="https://js.arcgis.com/4.14/"></script>
    <script>
        require(["esri/Map", "esri/views/MapView","esri/Basemap", "esri/layers/TileLayer"], function(Map, MapView, Basemap, TileLayer) {

            var basemap = new Basemap({
                baseLayers: [
                    new TileLayer({
                        url: "http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer",
                        title: "Basemap"
                    })
                ],
                title: "basemap",
                id: "basemap"
            });

            var map = new Map({
                basemap: basemap
            });
            var view = new MapView({
                container: "mapview", 
                map: map, 
                zoom: 8, 
                center: [104.072043,30.663724] 
            });

            view.when(function() {
                view.watch("extent", function() {
                    relocatePopup();
                });
                view.watch("rotation", function() {
                    relocatePopup();
                });

                echartsMapInit();
            });

            function relocatePopup(e) {
                for (var i = 0; i < echartsInfos.length; i++) {
                    var echartsInfo = echartsInfos[i];

                    var mapPoint = {
                    x: echartsInfo.x,
                    y: echartsInfo.y,
                    //spatialReference: view.spatialReference
                    spatialReference: {
                        wkid: 4326
                    }
                    };
                    var screenPoint = view.toScreen(mapPoint);
                    var obj = {};
                    obj.x =screenPoint.x;
                    obj.y =screenPoint.y;
                    obj.option = echartsInfo.option;
                    obj.id = echartsInfo.id;
                    obj.echartsObj  = echartsInfo.echartsObj;

                    positionEchartsMap(obj);
            }
            };

            function positionEchartsMap(obj) {
                $('#' + obj.id).css('transform', 'translate3d(' + obj.x + 'px, ' + obj.y + 'px, 0)');

                switch(view.zoom) {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                        $('#'+obj.id).css('height', '50px');
                        $('#'+obj.id).css('width', '100px');
                        break;
                    case 6:
                    case 7:
                    case 8:
                        $('#'+obj.id).css('height', '120px');
                        $('#'+obj.id).css('width', '200px');
                        break;
                    case 9:
                    case 10:
                        $('#'+obj.id).css('height', '150px');
                        $('#'+obj.id).css('width', '300px');
                        break;
                    case 11:
                    case 12:
                        $('#'+obj.id).css('height', '200px');
                        $('#'+obj.id).css('width', '350px');
                        break;
                    default:
                        $('#'+obj.id).css('height', '250px');
                        $('#'+obj.id).css('width', '400px');

                }
                if(obj.echartsObj) {
                    obj.echartsObj.resize(); 
                } 
            };

            function echartsMapInit() {
                echartsInfos = [];
                echartsInfos.push({
                    x: 104.072043,
                    y: 30.663724,
                    content: '<div id="info1" style="height:150px;width:300px;position:absolute;"></div>',
                    id:"info1",
                    echartsObj:null,
                    option:{
                        color: ['#3398DB'],
                        tooltip : {
                            trigger: 'axis',
                            axisPointer : {            
                                type : 'shadow'        
                            }
                        },
                        grid: {
                            left: '3%',
                            right: '4%',
                            bottom: '3%',
                            top: '3%',
                            containLabel: true,
                            //y2: 140
                        },
                        xAxis : [
                            {
                                type : 'category',
                                data : ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
                                axisTick: {
                                    alignWithLabel: true
                                },              
                                axisLabel:{  
                                    interval:0,
                                    rotate:-30,
                                },  
                                axisLine:{  
                                    lineStyle:{  
                                        color:'#FFFFFF',  
                                        width:1,
                                    }  
                                }
                            }
                        ],
                        yAxis : [
                            {
                                type : 'value',
                                splitLine: {  
                                    lineStyle: {  
                                        color: ['#0087ED']  
                                    }  
                                },  
                                nameTextStyle: {  
                                    color: ['#FFFFFF']  
                                    },  
                                axisLine:{  
                                    lineStyle:{  
                                        color:'#FFFFFF',  
                                        width:1,
                                    }  
                                }
                            }
                        ],
                        series : [
                            {
                                name:'直接访问',
                                type:'bar',
                                barWidth: '60%',
                                data:[10, 52, 200, 334, 390, 330, 220]
                            }
                        ]
                    }
                });

                echartsInfos.push({
                    x: 106.492447,
                    y: 29.608168,
                    content: '<div id="info2" style="height:150px;width:300px;position:absolute;"></div>',
                    id:"info2",
                    echartsObj:null,
                    option:{
                        title: {
                            text: ''
                        },
                        tooltip : {
                            trigger: 'axis',
                            axisPointer: {
                                type: 'cross',
                                label: {
                                    backgroundColor: '#6a7985'
                                }
                            }
                        },
                        legend: {
                            data:['视频广告','直接访问','搜索引擎'],
                            textStyle:{  
                                color: ['#FFFFFF']  
                            },  
                        },
                        toolbox: {
                            feature: {
                                saveAsImage: {}
                            }
                        },
                        grid: {
                            left: '3%',
                            right: '4%',
                            bottom: '3%',
                            top: '10%',
                            containLabel: true
                        },
                        xAxis : [
                            {
                                type : 'category',
                                boundaryGap : false,
                                data : ['周一','周二','周三','周四','周五','周六','周日'],
                                nameTextStyle: {  
                                    color: ['#FFFFFF']  
                                },  
                                axisLine:{  
                                    lineStyle:{  
                                        color:'#FFFFFF',  
                                        width:1,
                                    }  
                                }
                            }
                        ],
                        yAxis : [
                            {
                                type : 'value',
                                nameTextStyle: {  
                                    color: ['#FFFFFF']  
                                },  
                                axisLine:{  
                                    lineStyle:{  
                                        color:'#FFFFFF',  
                                        width:1,
                                    }  
                                }
                            }
                        ],
                        series : [
                            {
                                name:'视频广告',
                                type:'line',
                                stack: '总量',
                                areaStyle: {},
                                data:[150, 232, 201, 154, 190, 330, 410]
                            },
                            {
                                name:'直接访问',
                                type:'line',
                                stack: '总量',
                                areaStyle: {normal: {}},
                                data:[320, 332, 301, 334, 390, 330, 320]
                            },
                            {
                                name:'搜索引擎',
                                type:'line',
                                stack: '总量',
                                label: {
                                    normal: {
                                        show: true,
                                        position: 'top'
                                    }
                                },
                                areaStyle: {normal: {}},
                                data:[820, 932, 901, 934, 1290, 1330, 1320]
                            }
                        ]
                    }
                });

                for (var i = 0; i < echartsInfos.length; i++) {
                        var echartsInfo = echartsInfos[i];

                        var mapPoint = {
                            x: echartsInfo.x,
                            y: echartsInfo.y,
                            // spatialReference: {
                            //     wkid: view.spatialReference.wkid
                            // }
                            spatialReference: {
                                wkid: 4326
                            }
                        };
                        var screenPoint = view.toScreen(mapPoint);
                        var obj = {};
                        obj.x =screenPoint.x;
                        obj.y =screenPoint.y;
                        obj.content = echartsInfo.content;
                        obj.id = echartsInfo.id;
                        obj.option = echartsInfo.option;
                        obj.echartsObj  = echartsInfo.echartsObj;
                        echartsInfos[i].echartsObj = loadEchartsMap(obj);
                }
            };

            function loadEchartsMap(obj) {

                $("#mapview").append(obj.content);

                var dom = document.getElementById(obj.id);
                var myChart = echarts.init(dom);
                myChart.setOption(obj.option);

                positionEchartsMap(obj);
                return myChart;
            }
      });
    </script>
</body>
</html>

 

发布了138 篇原创文章 · 获赞 201 · 访问量 28万+

Guess you like

Origin blog.csdn.net/qq_35117024/article/details/105058536