arcgis api for 4.x 开发笔记-在Vue 2.X项目中开发arcgis api for javascript 4.x(五)—— 地图中添加Echarts的图表...

前言

 

地图上添加Echarts图表,其实就是将一个Echarts图表的容器放到地图上,然后监听地图的事件更新Echarts容器的大小及屏幕坐标。

为了可以复用方便,我决定将地图上添加Echarts图表封装成一个service。

结构

参数说明

  • mapView:由于需要将地图坐标转化为屏幕坐标,所以需要toScreen去完成,因此需要将地图的view传进Class里面,这里需要将传入的地图view保存到一个全局参数mapView。
  • mapDom:由于添加Echats的原理就是添加容器到地图,所以就是将容器添加到地图的DOM对象里面,所以这个需要传入地图的DOM对象。
  • events:需要监听地图的事件。
  • mapZoom:地图的缩放zoom。
  • chartConfigList:绘制Echarts图表需要的配置信息。

生成图表配置说明

属性说明类型默认值
x地图坐标里面的经度(longitude)number-
y地图坐标里面的纬度(latitude)number-
widthEcharts图表容器的宽number0
heightEcharts图表容器的高number0
idEcharts容器的DOM的idstring-
echartsObj存放生成的Echarts的图表对象Objectnull
option用于生成Echarts图表的配置参数Objectnull
    // 配置模板
    const chartConfig_template = {
      x: 102, // 图表在地图上绘制的位置
      y: 24,
      width: 15,
      height: 15,
      id: 'chartDiv',
      echartsObj: null,
      option: {
        tooltip: {
          trigger: 'item',
        },
        legend: {
          show: false,
        },
        series: [
          {
            name: title,
            type: 'pie',
            radius: ['40%', '70%'],
            avoidLabelOverlap: false,
            label: {
              show: false,
            },
            emphasis: {
              label: {
                show: false,
              },
            },
            labelLine: {
              show: false,
            },
            data: [
              {
                value: percent,
                name: '完成百分比(%)',
                itemStyle: { color: 'green' },
              },
              {
                value: unfinishedPercent,
                name: '未完成百分比(%)',
                itemStyle: { color: this.colors.white },
              },
            ],
          },
        ],
      },
    };

函数说明

  • 构造函数
constructor(mapView, mapDom) {
        super();
        this.mapView = mapView;
        this.mapDom = mapDom;

        if (this.mapView) {
            this.mapView.when(() => {
                this.setListenEvents();
            });
        }
    }
  • 监听添加
setListenEvents() {
        // 监听地图变化事件,刷新统计图位置
        this.mapView.watch('extent', () => {
            this.toScreenAllCharts();
        });
    }
  • 生成Echarts对象
 // 生成chart对象
    generateChartObject(chartConfig) {
        $(this.mapDom)
            .append(`<div id="${chartConfig.id}" class="chartDiv" style="height:${chartConfig.height || 0}px;width:${chartConfig.width || 0}px;position:absolute;"></div>`); // 往mapview追加存放图表的DOM元素

        const dom = document.getElementById(chartConfig.id); // 绘制图表
        const myChart = echarts.init(dom);
        myChart.setOption(chartConfig.option);

        return myChart;
    }
  • 实现Echarts图表根据地图缩放/移动而缩放/移动
// 调整图表位置及大小函数
    resizeChart(chartConfig) {
        const chartJqueryObject = $(`#${chartConfig.id}`);
        chartJqueryObject.css('transform', `translate3d(${chartConfig.x}px, ${chartConfig.y}px, 0)`);

        const { zoom } = this.mapView;
        if (this.mapZoom !== zoom) {
            this.mapZoom = zoom;
            if (chartConfig?.chartObj) {
                chartConfig.chartObj.resize({
                    height: zoom * chartConfig.height,
                    width: zoom * chartConfig.width,
                });
            }
        }
    }
  • 根据传入的配置文件生成相应的EchartsObject并且转换地图坐标为屏幕坐标
    // 刷新所有的chart到地图上
    toScreenAllCharts(chartConfigList = this.chartConfigList) {
        chartConfigList.forEach((chartConfig) => {
            const {
                x,
                y,
                chartObj,
            } = chartConfig;
            // 坐标转换
            const mapPoint: any = {
                x,
                y,
                spatialReference: this.mapView.spatialReference,
            };
            const screenPoint = this.mapView.toScreen(mapPoint);

            if (!chartObj) {
                chartConfig.chartObj = this.generateChartObject(chartConfig);
            }

            this.resizeChart({
                ...chartConfig,
                x: screenPoint.x,
                y: screenPoint.y,
            });
        });
    }
  • 清空所有的Echarts图表
// 清空所有的charts
    clearAllCharts() {
        this.mapZoom = undefined;
        $(this.mapDom)
            .children('.chartDiv')
            .remove();
    }
  • 注销当前服务
// 销毁当前服务
    destroy() {
        this.events.forEach((event) => {
            event.remove();
        });
        this.events = [];

        this.clearAllCharts();
    }

完整的ChartsService.ts的代码

import { Vue } from 'vue-property-decorator';
import $ from 'jquery';
import * as echarts from 'echarts';
import MapView from '@c_arcgis/core/views/MapView';
import SceneView from '@c_arcgis/core/views/SceneView';

export class ChartsService extends Vue {
    mapView: MapView | SceneView;

    mapDom;

    chartConfigList = [];

    mapZoom;

    // 所以事件
    events = [];

    constructor(mapView, mapDom) {
        super();
        this.mapView = mapView;
        this.mapDom = mapDom;

        if (this.mapView) {
            this.mapView.when(() => {
                this.setListenEvents();
            });
        }
    }

    setListenEvents() {
        // 监听地图变化事件,刷新统计图位置
        this.mapView.watch('extent', () => {
            this.toScreenAllCharts();
        });
    }

    // 生成所有chart的配置文件
    generateChartConfigList(chartConfigList = []) {
        this.clearAllCharts();

        this.chartConfigList = [...chartConfigList];
        this.toScreenAllCharts();
    }

    // 生成chart对象
    generateChartObject(chartConfig) {
        $(this.mapDom)
            .append(`<div id="${chartConfig.id}" class="chartDiv" style="height:${chartConfig.height || 0}px;width:${chartConfig.width || 0}px;position:absolute;"></div>`); // 往mapview追加存放图表的DOM元素

        const dom = document.getElementById(chartConfig.id); // 绘制图表
        const myChart = echarts.init(dom);
        myChart.setOption(chartConfig.option);

        return myChart;
    }

    // 调整图表位置及大小函数
    resizeChart(chartConfig) {
        const chartJqueryObject = $(`#${chartConfig.id}`);
        chartJqueryObject.css('transform', `translate3d(${chartConfig.x}px, ${chartConfig.y}px, 0)`);

        const { zoom } = this.mapView;
        if (this.mapZoom !== zoom) {
            this.mapZoom = zoom;
            if (chartConfig?.chartObj) {
                chartConfig.chartObj.resize({
                    height: zoom * chartConfig.height,
                    width: zoom * chartConfig.width,
                });
            }
        }
    }

    // 刷新所有的chart到地图上
    toScreenAllCharts(chartConfigList = this.chartConfigList) {
        chartConfigList.forEach((chartConfig) => {
            const {
                x,
                y,
                chartObj,
            } = chartConfig;
            // 坐标转换
            const mapPoint: any = {
                x,
                y,
                spatialReference: this.mapView.spatialReference,
            };
            const screenPoint = this.mapView.toScreen(mapPoint);

            if (!chartObj) {
                chartConfig.chartObj = this.generateChartObject(chartConfig);
            }

            this.resizeChart({
                ...chartConfig,
                x: screenPoint.x,
                y: screenPoint.y,
            });
        });
    }

    // 清空所有的charts
    clearAllCharts() {
        this.mapZoom = undefined;
        $(this.mapDom)
            .children('.chartDiv')
            .remove();
    }

    // 销毁当前服务
    destroy() {
        this.events.forEach((event) => {
            event.remove();
        });
        this.events = [];

        this.clearAllCharts();
    }
}

使用

  mounted() {
    this.$nextTick(() => {
      const { mainMap }: any = this.$refs;
      if (mainMap.activeView) {
        this.chartsServices = new ChartsService(mainMap.activeView, mainMap.$el);
        this.chartsServices.generateChartConfigList([chartConfig_template]);
      }
    });
  }

效果

7d8749b6a15e305963eda3f6d1264a8b.png

直接npm安装使用就行

npm i arcgis-echarts-services
项目github地址

本文参考:

01 【ArcGIS JS API + eCharts系列】实现地图上二维图表的绘制

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花姐夫Jun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值