【实现自己的可视化引擎14】地图

1,613 阅读2分钟

前言

大数据可视化不可绕开的图表便是地图。本章节,我们将简单实现一个完整的中国地图以及简单的交互,并封装成React组件。效果图如下:

组件使用代码如下:

render() {
    const { clientX, clientY, province } = this.state;
    return (
      <React.Fragment>
        <div style={{top: clientY, left: clientX}} className="tip">
          { province }
        </div>
        <Map
          className="chart"
          onClick={this.onMapClick}
        />
      </React.Fragment>
  )
}

地图图层

地图图层的实现其实很简单,由效果图可以看出,地图由多个多变形拼接组成,所以我们只需计算出各个省市边界的相应坐标,几个绘制地图。
这里我们只需将各个省市的经纬度转换成画布上的坐标即可,各省市geojson数据可以戳这里。 地图图层绘制代码如下:

make() {
    this.clearEventListener();
    this.childs.splice(0, this.childs.length);
    const xStep = this.width / (maxX - minX);
    const yStep = this.height / (maxY - minY);
    for (let m = 0; m < bound.features.length; m++) {
      const coordinates =  bound.features[m].geometry.coordinates;
      for (let i = 0; i < coordinates.length; i++) {
        let item = coordinates[i];
        for (let j = 0; j < item.length; j++) {
          let dots = item[j];
          let polygonPoint = [];
          for (let k = 0; k < dots.length; k++) {
            polygonPoint.push(
              new Point(
                (dots[k][0] - minX) * xStep,
                (dots[k][1] - minY) * yStep
              ));
          }
          let polygon = new Polygon(this.canvas, {
            type: Polygon.TYPE.STROKE,
            color: this.color,
          }, polygonPoint);
          this.addChild(polygon);
        }
      }
    }
    // 绘制省界线
    for (let m = 0; m < full.features.length; m++) {
      const coordinates =  full.features[m].geometry.coordinates;
      for (let i = 0; i < coordinates.length; i++) {
        let item = coordinates[i];
        for (let j = 0; j < item.length; j++) {
          let dots = item[j];
          let polygonPoint = [];
          for (let k = 0; k < dots.length; k++) {
            polygonPoint.push(
              new Point(
                (dots[k][0] - minX) * xStep,
                (dots[k][1] - minY) * yStep
              ));
          }
          let polygon = new Polygon(this.canvas, {
            type: Polygon.TYPE.STROKE,
            color: this.color,
            lineDash: [5, 10],
            lineWidth: 1,
          }, polygonPoint);
          polygon.ext = full.features[m].properties;
          (this.onClick && (
            polygon.addEventListener(Event.EVENT_CLICK, (e) => {
              console.log(e);
              this.onClick && this.onClick(e);
            })
          ))
    
          this.addChild(polygon);
        }
      }
    }
}

为了减少绘制过程中的计算,我们已经实现计算完成了中国地图的最大最小经纬度maxX, maxY, minX, minY。上述代码中bound为中国地图轮廓的经纬度geo数据,full为各省市自治区的geo数据,geo数据格式不在这里赘述,可自行查看网站数据

React 封装

React封装需要DOM的挂载完成,所以我们在生命周期componentDidMount函数中构建我们的图层。
代码如下:

componentDidMount () {
    const { style = {} } = this.props;
    this.canvas = new Canvas({
      ele: this.ref.current,
      canAction: false,
    });
    this.map = new MapLayer(this.canvas, {
      color: style.color,
      onClick: this.props.onClick
    });
    this.map.make();
    this.canvas.addChild(this.map);
    this.canvas.paint();
}

目录

【实现自己的可视化引擎01】认识Canvas
【实现自己的可视化框架引擎02】抽象图像元素
【实现自己的可视化引擎03】构建基础图元库
【实现自己的可视化引擎04】图像元素动画
【实现自己的可视化引擎05】交互与事件
【实现自己的可视化引擎06】折线图
【实现自己的可视化引擎07】柱状图
【实现自己的可视化引擎08】条形图
【实现自己的可视化引擎09】饼图
【实现自己的可视化引擎10】散点图
【实现自己的可视化引擎11】雷达图
【实现自己的可视化引擎12】K线图
【实现自己的可视化引擎13】仪表盘
【实现自己的可视化引擎14】地图
【实现自己的可视化引擎15】关系图