echarts分裂地图与线性动画

前言

      如果没有geoJSON数据,可以去 datav官网 导出

定义数据结构

const pointsDataArr = [
     {
          name: '鄂州', // 展示的名称
          routeName: [
            {
              region: '黄冈',
              lable: '黄冈线',
              value: 10
            }
          ], // 路线
          value: [114.89, 30.34], // title显示的经纬度
          id: 'ez', // geo对应id
          fileName: '420700_ez', // geoJSON 文件名
        position:{
          left: '10%',
          top: 0
        },
          markerArr: [{ sectionName: '鄂州电厂', value: [114.60, 30.16] }] // marker
        },
        {
          name: '黄冈',
          routeName: [
            {
              region: '黄石',
              lable: '黄石线',
              value: 10
            },
            {
              region: '鄂州',
              lable: '鄂州线',
              value: 10
            }
          ],
        position:{
          left: '10%',
          top: 0
        },
          value: [115.4, 30.8],
          id: 'hg',
          fileName: '421100_hg',
          markerArr: []
        },
        {
          name: '黄石',
          routeName: [
            {
              region: '鄂州',
              lable: '鄂州线',
              value: 10
            }
          ],
        position:{
          left: '10%',
          top: 0
        },
          value: [115.03, 30],
          id: 'hs',
          fileName: '420200_hs',
          markerArr: [{ sectionName: '西塞山电厂', value: [115.10, 29.76] }]
        }
      ]

一、初始化在echarts中导入地图数据

this.myCharts = echarts.init(this.$refs.map); // 初始化
/*
   引入geoJSON
  @params(id,geoJSON地图数据)
*/
pointsDataArr.forEach(item => {
   this.myCharts.registerMap(
      item.id, { geoJSON:require(`@/assets/geoJson/${item.fileName}.json`
    ) 
})

 echarts.registerMap('hg', { geoJSON: require(`@/assets/geoJson/${item.fileName}.json`) });
 echarts.registerMap('wh', { geoJSON: require(`@/assets/geoJson/${item.fileName}.json`) });

// 处理geo数据
const geo = []
pointsDataArr.forEach((item,index) => {
    geo.push({
        id:item.id, // 这里的id与echarts.registerMap方法中的id对应
        name: item.id,
        zlevel: index, // 防止都在一层 卡顿
        map: item.id, 
        roam: false, // 禁止拖拽和放大
        geoIndex: index, // 地图索引
        zoom: 0.7, // 级别
        ...item.position, // 避免几个地图都在一起
        label: {
          normal: { // 静态的时候展示样式
            show: false // 是否显示地图省份得名称
          },
          emphasis: {
            show: false // 隐藏悬浮显示地区文字
          }
        },
        itemStyle: {
          normal: {
            color: '#386935', // 地图背景色
            borderColor: '#5D8646', // 省市边界线00fcff 516a89
            areaColor: '#386935', // 地图背景色
            borderWidth: 1,
            shadowBlur: 1,
            shadowColor: '#386935',
            shadowOffsetX: 5,
            shadowOffsetY: 10
          },
          emphasis: {
            color: '#386935' // 悬浮背景
          }
        }
    })
})

2、由于地图都是分开的,会导致经纬度不准确,这里做一个经纬度与px的转换

// 注意 要首先 myCharts.setOption(option) 才能获取 convertFromPixel api

// 经纬度转像素 像素在转经纬度
 lonLatCutpixel(lonLat, pixelInfo) {
  // 坐标转换为像素坐标 geoIndex 对应这geo
   const pixel = this.myCharts.convertToPixel(
     pixelInfo,
     lonLat
   );
    // 统一根据第一个geo来换算  geoIndex 对应这上面定义的
    const point = this.myCharts.convertFromPixel({ geoIndex: 0 }, pixel);
    return point;
 },

3、画线段性动画

 const linesData = {
        type: 'lines',
        zlevel: 99,
        effect: {
          show: true,
          period: 3, // 箭头指向速度,值越小速度越快
          trailLength: 0, // 特效尾迹长度[0,1]值越大,尾迹越长重
          symbol: 'triangle', // 箭头图标
          symbolSize: 14, // 图标大小
          color: '#fff'
        },
        selectedMode: 'single', // 开启单机点中
        select: { // 选中后的样式
          lineStyle: {
            color: 'red',
            width: 3
          }
        },
        label: { // 线中间的数据 title
          show: true,
          formatter: (params) => `${params.data.lable}\n{a|${params.data.value}}`,
          rich: {
            a: {
              align: 'left',
              color: 'rgb(207, 78, 178)',
              padding: [4, 10, 0, 10],
              lineHeight: 30,
              height: 18,
              backgroundColor: 'rgb(32, 66, 17)',
              fontSize: 16,
              borderRadius: 4
            }
          },
          opacity: 1,
          verticalAlign: 'middle', // 是否在线的中间
          position: 'middle', // 在线的中间 可以旋转
          textStyle: {
            color: '#fff',
            fontSize: 20
          }
        },
        lineStyle: {
          normal: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              {
                offset: 0,
                color: '#61CB34'
              },
              {
                offset: 0.9,
                color: '#61CB3410'
              },
              {
                offset: 1,
                color: '#61CB34'
              }
            ]),
            width: 2, // 线条宽度
            curveness: 0.2 // 尾迹线条曲直度
          },
          emphasis: {
            color: 'yellow' // 悬浮背景
          }
        },
        data: this.convertData() // 此方法在下面定义 处理多个地图连接 坐标问题
      };
    // 处理经纬度偏移  lonLatCutpixel 方法在 2 中定义过了
    convertData() {
      const res = [];
      this.pointsDataArr.forEach((item, index) => {
        // 坐标转换为像素坐标 geoIndex 对应这geo 开始
        const startingPoint = this.lonLatCutpixel(item.value, { geoIndex: index });

        item.routeName.forEach((val) => {
          let originaLonlat = null;
          let originaIndex = 0;
          let info = {};
          // 得到结束线的经纬度
          this.pointsDataArr.forEach((key, i) => {
            if (key.name === val.region) {
              originaLonlat = key.value;
              originaIndex = i;
              info = val;
            }
          });
          // 坐标转换为像素坐标 geoIndex 对应这geo (结束)
          const endingPoint = this.lonLatCutpixel(originaLonlat, { geoIndex: originaIndex         
           });
          res.push({
            coords: [startingPoint, endingPoint],
            ...info
          });
        });
      });
      return res;
    },

 4、画闪动圆点

       const arr = [];
       this.pointsDataArr.forEach((val, index) => {
        // 换算经纬度
        const lonLat = this.lonLatCutpixel(val.value, { geoIndex: index });
        arr.push({
          name: val.name,
          value: lonLat
        });
      });
      const pointsData = {
        type: 'effectScatter',
        coordinateSystem: 'geo',
        zlevel: 10,
        showEffectOn: 'render',
        rippleEffect: { // 设置圆点动画
          color: '#61CB34',
          number: 1,
          period: 1,
          scale: 2,
          brushType: 'fill'
        },
        hoverAnimation: true, // 启动动画
        label: { // 圆点上面的标题
          normal: {
            formatter: '{b}',
            position: 'top',
            offset: [0, 0],
            color: '#fff',
            show: true,
            fontSize: 26
          }
        },
        symbol: 'circle',
        symbolSize: 30,
        itemStyle: {
          normal: {
            color: '#61CB34',
            shadowBlur: 10,
            shadowColor: '#61CB34'
          }
        },
        data: arr
      };

5、引入每个模块 setOption

   setOption() {
      if (this.myCharts) {
        this.myCharts.clear();
        this.myCharts = null;
      }
      this.myCharts = echarts.init(this.$refs.map);
      // @params (与geo里面的id对应,{geoJSON数据})
      this.pointsDataArr.forEach((item) => {
        // eslint-disable-next-line import/no-dynamic-require
        echarts.registerMap(item.id, { geoJSON: require(`@/assets/geoJson/${item.fileName}.json`) });
      });
      const option = {
        backgroundColor: 'rgba(0,0,0,0)',
        tooltip: {
          show: false
          // trigger: 'item',
          // backgroundColor: 'rgba(120, 147, 222, 0.5)',
          // borderColor: '#fff',
          // formatter: (params) => {
          //   if (params.name) {
          //     return params.name;
          //   }
          //   return params.value;
          // },
          // enterable: true,
          // padding: [0, 10],
          // textStyle: { color: '#fff' }
        },
        xAxis: {
          show: false
        },
        yAxis: {
          show: false
        },
        // visualMap: {
        //   type: 'continuous',
        //   realtime: false,
        //   calculable: true
        // },
        geo: geo,
        series: []
      };
      // 先注册一遍 这样才能使用 echarts转换经纬度的api
      this.myCharts.setOption(option);
      option.series = [
        linesData,
        pointsData
      ];
      this.myCharts.setOption(option);
      // 添加点击事件
      this.myCharts.on('click', (e) => {
        console.log(e);
      });
      // 默认选中第一条线
      this.myCharts.dispatchAction({
        type: 'select',
        dataIndex: 0
      });
      this.myCharts.on('selectchanged', (params) => {
        // 不让取消选中
        if (params.fromAction === 'unselect') {
          this.myCharts.dispatchAction({
            type: 'select',
            dataIndex: params.fromActionPayload.dataIndexInside
          });
        }
      });
    }

效果图如下


 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值