在图片上实现飞线效果图echarts另类用法

echarts yekong

数据可视化大屏项目开发中,客户要求实现飞线图,但是这个图片的地图并不精确,只是一个大概的效果,只不过客户对动画效果比较执着。自己写飞线图动画又不会,使用echarts来绘制地图的话,又因为数据不准确没办法定位,因为客户对地图数据并不在意,所以这里我们假数据来实现。

在图片上实现飞线效果图

绘制echarts

首先我们绘制一个echarts地图来盖在图片上,类似下图,让echarts有足够大的区域可以遮挡在图片上
绘制echarts

然后我们使用echarts方法点击echarts地图获取经纬度用来定位圆点,经纬度并非真实需要的经纬度,而是我们需要用来在图片上绘制圆点和飞线需要。

myChart.on('click', function (params) {
        that.left = params.event.event.offsetX;
        that.top = params.event.event.offsetY;
        let data = myChart.convertFromPixel('geo', [that.left, that.top])
        console.log(data)
      })

获取到经纬度构建飞线和圆点

我们将获取到的坐标用来绘制圆点和飞线

  var datamap = {
    type: 'scatter',
    name: '宁波',
    coordinateSystem: 'geo',
    symbol: 'image://' + mapTag,
    symbolSize: [96, 96],
    symbolOffset: [0, 0],
    label: {
      normal: {
        show: true,
        position: 'top',
        offset: [30, 80],
        formatter: function (params) {
          console.log(params)
          var text = `{name|宁波}`
          return text
        },
        color: '#fff',
        rich: {
          name: {
            padding: [0, 0],
            color: '#FEFEFE',
            fontSize: 17,
            fontWeight: 500,
            fontFamily: 'YouSheBiaoTiHei'
          },
        },
      },
    },
    z: 6,
    data: [{
      "value": [109.63739894661572, 28.697517162125386],
      "id": 0,
      "name": '宁波',
      "num": 10
    }]
  }
  serverdata.push(datamap)
  var fData = []
  var geoCoordMap = {
    '宁波': [109.63739894661572, 28.697517162125386],
    '地址': [87.13306805244875, 47.41702876954609],
    '地址2': [89.49858010666516, 40.205413642097135],
    '地址3': [76.83989397869624, 38.05727296583574],
    '地址4': [83.48890083379104, 30.64107301207617],
    '地址5': [118.20438854837246, 33.14723713438113],
  }
  for (var key in geoCoordMap) {
    if (key != '宁波') {
      var datamap = {
        type: 'scatter',
        coordinateSystem: 'geo',
        symbol: 'image://' + dot,
        symbolSize: [24, 24],
        symbolOffset: [0, 0],
        label: {
          show: false,
        },
        z: 6,
        data: [{
          "value": geoCoordMap[key],
          "id": 0,
          "name": key,
          "num": 10
        }]
      }
      serverdata.push(datamap)
    }
  }
  for (var key in geoCoordMap) {
    for (var key1 in geoCoordMap) {
      if (key1 != key) {
        fData.push({
          coords: [
            geoCoordMap[key1],
            geoCoordMap[key],
          ],
          fromName: key1,
          toName: key,
        })
        break
      }
    }
  }
  fData.splice(0, 1)

最后将地图设置为透明

飞线和圆点都绘制好以后,将图片设置为透明,这样一个图片上的飞线图就搞定了。
最后将地图设置为透明

完整代码

<template>
  <div class="centerMap" id="centerMap">

  </div>
</template>

<script>
import echarts from "echarts";
import data from './data.json'
import mapTag from './assets/mapicon.png'
import dot from './assets/dot.png'

export default {
  name: "item1",
  data() {
    return {
      data,
      height: 0,
      width: 0,
      popShow: false,
      left: 0,
      top: 0,
      address: '',
      num: 10,
    }
  },
  components: {},
  watch: {},
  mounted() {
    var that = this;
    setTimeout(() => {
      this.getMap()
    }, 500)
  },
  methods: {
    getMap() {
      this.$nextTick(() => {
        this.getEcharts()
      })
    },
    getEcharts() {
      var that = this;
      var chartDom = document.getElementById('centerMap');
      var myChart = echarts.init(chartDom);
      var nameMap = '地图数据';
      var serverdata = []
      echarts.registerMap(nameMap, this.data);
      var mapFeatures = echarts.getMap(nameMap).geoJson.features;
      var datamap = {
        type: 'scatter',
        name: '宁波',
        coordinateSystem: 'geo',
        symbol: 'image://' + mapTag,
        symbolSize: [96, 96],
        symbolOffset: [0, 0],
        label: {
          normal: {
            show: true,
            position: 'top',
            offset: [30, 80],
            formatter: function (params) {
              console.log(params)
              var text = `{name|宁波}`
              return text
            },
            color: '#fff',
            rich: {
              name: {
                padding: [0, 0],
                color: '#FEFEFE',
                fontSize: 17,
                fontWeight: 500,
                fontFamily: 'YouSheBiaoTiHei'
              },
            },
          },
        },
        z: 6,
        data: [{
          "value": [109.63739894661572, 28.697517162125386],
          "id": 0,
          "name": '宁波',
          "num": 10
        }]
      }
      serverdata.push(datamap)
      var fData = []
      var geoCoordMap = {
        '宁波': [109.63739894661572, 28.697517162125386],
        '地址': [87.13306805244875, 47.41702876954609],
        '地址2': [89.49858010666516, 40.205413642097135],
        '地址3': [76.83989397869624, 38.05727296583574],
        '地址4': [83.48890083379104, 30.64107301207617],
        '地址5': [118.20438854837246, 33.14723713438113],
      }
      for (var key in geoCoordMap) {
        if (key != '宁波') {
          var datamap = {
            type: 'scatter',
            coordinateSystem: 'geo',
            symbol: 'image://' + dot,
            symbolSize: [24, 24],
            symbolOffset: [0, 0],
            label: {
              show: false,
            },
            z: 6,
            data: [{
              "value": geoCoordMap[key],
              "id": 0,
              "name": key,
              "num": 10
            }]
          }
          serverdata.push(datamap)
        }
      }
      for (var key in geoCoordMap) {
        for (var key1 in geoCoordMap) {
          if (key1 != key) {
            fData.push({
              coords: [
                geoCoordMap[key],
                geoCoordMap[key1],
              ],
              fromName: key,
              toName: key1,
            })
            break
          }
        }
      }
      fData.splice(0, 1)
      var optionMap = {
        geo: {
          map: nameMap,
          show: true,
          aspectScale: 0.8,
          layoutCenter: ["50%", "86%"],
          layoutSize: '125%',
          roam: false,
          itemStyle: {
            normal: {
              borderColor: 'rgba(147, 235, 248, 0)',
              borderWidth: 0.5,
              areaColor: 'rgba(147, 235, 248, 1)',
              opacity: 0,
            },
            emphasis: {
              borderColor: 'rgba(147, 235, 248, 0)',
              borderWidth: 0.5,
              areaColor: 'rgba(147, 235, 248, 0)',
              opacity: 0,
            }
          },
          z: 0,
          label: {
            normal: {
              show: false
            },
            emphasis: {
              show: false
            }
          }
        },
        series: [
          {
            type: 'lines',
            zlevel: 10000,
            effect: {
              show: true,
              period: 4, //箭头指向速度,值越小速度越快
              trailLength: 0.1, //特效尾迹长度[0,1]值越大,尾迹越长重
              symbol: 'arrow', //箭头图标
              symbolSize: 4, //图标大小
            },
            tooltip: {
              trigger: 'item',
            },
            label: {
              show: false,
              color: '#fff',
              emphasis: {
                color: 'white',
                show: true
              }
            },
            lineStyle: {
              normal: {
                color: '#ffcd00',
                type: 'dashed',
                width: 0.5, //尾迹线条宽度
                opacity: 0.5, //尾迹线条透明度
                curveness: 0.3 //尾迹线条曲直度
              }
            },
            data: fData,
          },
          ...serverdata,
        ]
      };
      myChart.setOption(optionMap);
      myChart.off('click')
      myChart.on('click', function (params) {
        console.log(params)
        that.left = params.event.event.offsetX;
        that.top = params.event.event.offsetY;
        that.popShow = false
        that.$nextTick(() => {
          that.popShow = true
        })
        that.address = params.name
        let data = myChart.convertFromPixel('geo', [that.left, that.top])
        console.log(data)
      })
      const viewElem = document.body;
      const resizeObserver = new ResizeObserver(() => {
        console.log('变化')
        // 此处放 当窗口大小发生变化时,想要让宽高自适应的图表的.resize(),除此处外其余都是固定写法,举例如下
        if (myChart) {
          setTimeout(() => {
            myChart.resize();
          }, 300)
        }
      });
      resizeObserver.observe(viewElem);
    }
  },
}
</script>

<style lang="scss" scoped>
.centerMap {
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: 1;
  top: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: nowrap;
  flex-direction: row;
  align-content: flex-start;
}
</style>

喜欢