1.1.2 • Published 3 years ago

echarts-extension-bingmap v1.1.2

Weekly downloads
-
License
MIT
Repository
-
Last release
3 years ago

一个ECharts扩展,使得可以在echarts中使用必应地图

This is a Bing Map extension for ECharts which is used to display visualizations such as Scatter

例子

Refer to examples/index.html

Preview

如何运行例子

  • 首先全局安装一个webserver
npm install -g webserver
  • 将项目代码下载到本地
git clone https://gitee.com/sailimuhu/echarts-extension-bingmap.git
  • 进入到项目目录,找到examples/index.html,将文件内的bing地图的key替换为自己的key,可以在这里注册账号,申请key;
  • 然后在项目目录下运行
webserver 3000 .

在npm项目中使用该扩展

安装

npm install echarts-extension-bingmap --save

Import

Import packaged distribution file echarts-extension-bingmap.min.js and add Bing Map API script and ECharts script.

<!-- import JavaScript API of Bing Map, please replace the key with your own key -->
<script type='text/javascript'
    src='https://www.bing.com/api/maps/mapcontrol?key={key}&callback=loadMapScenario&mkt=en&setlang=zh-cn'
    sync defer></script>
<!-- import echarts -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>

<!-- import echarts-extension-bingmap -->
<!-- <script src="../dist/echarts-extension-bingmap.js"></script> -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts-extension-bingmap@1.0.0/dist/echarts-extension-bingmap.min.js"></script>

You can also import this extension by require or import if you are using webpack.

require('echarts');
require('echarts-extension-bingmap');

Usage

This extension can be configured simply like geo.

var midnightMapStyle = {
    "version": "1.0",
    "settings": {
      "landColor": "#0B334D"
    },
    "elements": {
      "mapElement": {
        "labelColor": "#FFFFFF",
        "labelOutlineColor": "#000000"
      },
      "political": {
        "borderStrokeColor": "#144B53",
        "borderOutlineColor": "#00000000"
      },
      "point": {
        "iconColor": "#0C4152",
        "fillColor": "#000000",
        "strokeColor": "#0C4152"
      },
      "transportation": {
        "strokeColor": "#000000",
        "fillColor": "#000000"
      },
      "highway": {
        "strokeColor": "#158399",
        "fillColor": "#000000"
      },
      "controlledAccessHighway": {
        "strokeColor": "#158399",
        "fillColor": "#000000"
      },
      "arterialRoad": {
        "strokeColor": "#157399",
        "fillColor": "#000000"
      },
      "majorRoad": {
        "strokeColor": "#157399",
        "fillColor": "#000000"
      },
      "railway": {
        "strokeColor": "#146474",
        "fillColor": "#000000"
      },
      "structure": {
        "fillColor": "#115166"
      },
      "water": {
        "fillColor": "#021019"
      },
      "area": {
        "fillColor": "#115166"
      }
    }
  };
option = {
  // load bingmap component
  bingmap: {
    viewOption:{
      // initial options of Bing Map
      // See http://www.bingmap.cn/guide/e0411686-dafe-11e8-aa18-d46d6d978bfa?module=doc for details
      // initial map center, accepts an array like [lng, lat] or an object like { lng, lat }
      center: {lng: 108.39, lat: 39.9},
      // center: [108.39, 39.9],
      // initial map zoom
      zoom: 4,
    },
    mapOption:{
      // 地图的自定义样式,demo参考这里:  http://www.bingmap.cn/demos/02b0b57e-a3c0-40e0-b8a4-6421d57df9d8?module=demo
      // 关于customMapStyle的说明参考这里:https://docs.microsoft.com/en-us/bingmaps/articles/custom-map-styles-in-bing-maps?redirectedfrom=MSDN
      customMapStyle: midnightMapStyle
      // More initial options...
    }
  },
  series: [
    {
      type: 'scatter',
      // use `bingmap` as the coordinate system
      coordinateSystem: 'bingmap',
      // data items [[lng, lat, value], [lng, lat, value], ...]
      data: [[120, 30, 8], [120.1, 30.2, 20]],
      encode: {
        // encode the third element of data item as the `value` dimension
        value: 2,
        lng: 0,
        lat: 1
      }
    }
  ]
};

function loadMapScenario() {
  console.log('loadMapScenario called')
  // initialize chart
  var chart = echarts.init(document.getElementById("echarts-bing-map"));
  chart.setOption(option);
  
  // Get the instance of Bing Map
  var bingmap = chart
                .getModel()
                .getComponent('bingmap')
                .getBingMap();       
                
  // Add some markers to map
  var pushpin = new Microsoft.Maps.Pushpin(bingmap.getCenter(), null);
  bingmap.entities.push(pushpin);
}

开发说明

该扩展是基于echarts的百度地图扩展修改而来的

参考资料

基本思路

通过阅读echarts-extension-bmap扩展,发现他的基本思路是这样的,主体还是echarts,通过这个扩展让地图成为整个echarts的底图,让echarts的chart作为地图的一个自定义覆盖层而存在,这个覆盖层中的chart元素可以根据地图的经纬度、缩放层级而产生联动。

源码解读

百度地图扩展的思路是,在创建坐标系的时候,通过echarts的api可以获取到整个echarts的根元素,然后创建一个dom元素作为该echarts根元素的子节点,并使用该dom元素来创建地图,然后获取echart视图层的dom元素,基于该元素创建一个Overlay层,添加到地图的图层列表内,这样就实现了echarts与地图的关联。 至于echarts元素要跟随地图的缩放和拖拽而联动,则要依赖于坐标系内的dataToPointpointToData两个函数来实现经纬度与像素的互相转换。

移植的步骤

  • 首先把百度地图扩展的源码复制过来
  • 确定名字叫做BingMap,在echarts中的坐标系名称为bingmap
    • 修改文件名为 BingMapCoordSys, BingMapModel, BingMapView
    • 将文件内所有BMap改为BingMap,所有 bmap改为bingmap
  • 使用Bing地图的api替换百度地图的api,主要有几点:
    • 创建地图 Microsoft.Maps.Map
    • 经纬度 Microsoft.Maps.Location
    • 像素点 Microsoft.Maps.Point
    • 经纬度转换为像素,使用 Microsoft.Maps.Map类的 tryLocationToPixel方法,这里注意第二个参数要使用Microsoft.Maps.PixelReference.control
    • 像素转换为经纬度,使用 Microsoft.Maps.Map类的tryPixelToLocation方法;
  • 创建Overlay层,这里使用了BingMap的 CustomOverlay类,这里的思路是拿到echarts的viewPortRoot的dom元素,将他和CustomOverlay对象关联,创建了一个echarts的自定义层,然后添加到地图的layers列表内;
    • 这里有个插曲,就是添加的CustomOverlay,通过bingmap.layers.insert()添加到地图的图层之后,无法响应mousemove, mousedown之类的事件,而如果创建CustomOverlay时将beneathLabels参数设置为false,则又会导致地图无法响应鼠标事件,所以最终的解决方法是,还是把beneathLabels参数设置为true,让他在地图的label层的下方,然后捕捉地图的鼠标事件,在通过dom的dispatchEvent方法将他发送给echarts,这样echarts组件就可以响应相关的鼠标事件了,具体实现请查看BingMapCoordSys.js文件。
  • 让该扩展支持设置地图参数,由于地图有支持mapOption和viewOption两种参数,所以我在扩展的参数中也提供了mapOption和viewOption两个参数;
  • 实现地图的自定义样式,Bing地图的mapOption支持了一个叫做 CustomMapStyle的参数,可以自定义样式,我只要在创建好地图之后,把用户传进来的mapOption通过setMapOption方法设置给地图即可。

开发过程中的几个关键点

  • 通过看zrender源码发现了painter.getViewportRoot()其实是一个dom元素;
  • 想通了Overlay的作用是吧echarts变成一个自定义层;
  • 学会了用dispatchEvent来转发事件;
  • 在用tryLocationToPixel是发现散点图位置不对,然后看文档发现有个Microsoft.Maps.PixelReference.control参数。

如何调试

开两个cmd

  • 开一个webserver来实时查看
npm install -g webserver
webserver run 3000 .

然后在浏览器中打开 http://localhost:3000/examples/index.html

  • 开始调试
npm run watch
  • 这样每次修改之后刷新浏览器即可看到最新的修改