vue3+ts+echarts 实现svg渲染地图+省市联动

公司打算地图使用svg渲染,就做了个小demo,这是最后实现的效果。
在这里插入图片描述

http://datav.aliyun.com/portal/school/atlas/area_selector#&lat=30.332329214580188&lng=106.72278672066881&zoom=3.5
可以生成svg格式的地图
在这里插入图片描述
在这里插入图片描述

关键部分:

1 registerMap(‘china’, { svg: chinasvg })
2. 在这里插入图片描述
地图上要添加name属性,不然在配置那里无法对地图进行一些高亮啥的操作。

3 给地图整体设置背景色或者高亮没有效果时,可以查看下svg代码,改下里面的属性值。
在这里插入图片描述
4 svg地图不能直接引入就使用。
在这里插入图片描述

<template>
  <div>
    <v-chart
      :option="opts.chinaMap"
      :autoresize="true"
      id="myMap"
      class="chart"
    />
  </div>
</template>
import { reactive, toRefs, onMounted } from 'vue';
import VChart from 'vue-echarts';
import svg from '../assets/china.svg'
import beij from '../assets/beij.svg'
import * as echarts from "echarts/core";
import {registerMap} from "echarts/core";
import axios from 'axios';
setup() {
    // let chinaMapref = reactive<any>({});ts里这样写不然会报错
    let chinaMapref = reactive({});
    const opts = reactive({
      chinaMap: {}
    });
    onMounted(() => {
      chinaMapref = echarts.init(
        document.getElementById('myMap')
      )
    });

    const setMap = () => {
      //直接使用inport进来的svg不行
      axios(svg).then(res=>{
        let chinasvg = res.data;
        registerMap('china', { svg: chinasvg });
        opts.chinaMap = {
          tooltip: {},
          geo: {
            map: 'china',
            roam: true,
            zoom: 1.5,
            itemStyle: {
              borderColor: 'yellow',
              areaColor: 'yellow',
              borderWidth: '2'
            },
            emphasis: {
              label: {
                show: true,
                position: 'insideLeft'
              },
              itemStyle: {
                color: null,
                areaColor: '#ef5b9c'
              }
            },
            select: {
              itemStyle: {
                color: '#ccc',
                areaColor: '#ef5b9c'
              }
            },
            label: {
              show: false
            },
            regions: [
              // {
              //   name: '北京',
              //   itemStyle: {
              //     areaColor: 'red',
              //     borderWidth: 1,
              //     color: '#deab8a',
              //     borderColor: '#deab8a',
              //     borderType: 'solid'
              //   },
              //   emphasis: {
              //     itemStyle: {
              //       color: '#deab8a'
              //     }
              //   }
              // }
            ]
          },
          grid: {
            left: '50%',
            top: '20%',
            bottom: '20%'
          },
          series: [
            {
              name: 'lines',
              type: 'effectScatter',
              coordinateSystem: 'geo',
              geoIndex: 0,

              symbolSize: function (params) {
                return (params[2] / 100) * 15 + 5;
              },
              itemStyle: {
                color: '#b02a02'
              },
              encode: {
                // tooltip: 2,
              },
              data: [
                [593.4374999999999, 203.4375, 100],
                [532.96875, 176.71875, 30]
              ]
            },
            {
              name: 'flay',
              type: 'lines',
              Symbol: 'arrow',
              coordinateSystem: 'geo',
              geoIndex: 0,
              symbol: ['none', 'arrow'],
              effect: {
                show: true,
                period: 6,
                trailLength: 0,
                // symbol: planePath,
                symbolSize: 15,
                color: '#b2d235'
              },
              lineStyle: {
                color: '#843900',
                width: 1,
                type: 'solid',
                curveness: 0.2
              },
              encode: {
                // tooltip: 2,
              },
              data: [
                {
                  coords: [
                    [508.1249999999999, 247.03125],
                    [442.03125, 345.9375]
                  ]
                },
                {
                  coords: [
                    [508.1249999999999, 247.03125],
                    [553.5937499999999, 322.96875]
                  ]
                }
              ]
            }
 		//地图的点击事件 点击北京区域的时候去加载北京的svg地图
        chinaMapref.on('click', { geoIndex: 0, name: 'bj' }, function(params) {
          params.areaColor = 'pink';
          axios(beij).then(res=>{
            registerMap('beij', { svg: res.data });
            opts.chinaMap = {
              geo: {
                map: 'beij',
                roam: true,
                zoom: 1.5,
                itemStyle: {
                  borderColor: 'yellow',
                  areaColor: 'yellow',
                  borderWidth: '2'
                },
                emphasis: {
                  label: {
                    show: true,
                    position: 'insideLeft'
                  },
                  itemStyle: {
                    color: null,
                    areaColor: '#ef5b9c'
                  }
                },
                select: {
                  itemStyle: {
                    color: '#ccc',
                    areaColor: '#ef5b9c'
                  }
                },
                label: {
                  show: false
                },
              grid: {
                left: '50%',
                top: '20%',
                bottom: '20%'
              },
              series: [
                {
                  name: 'lines',
                  type: 'effectScatter',
                  coordinateSystem: 'geo',
                  geoIndex: 0,

                  symbolSize: function (params) {
                    return (params[2] / 100) * 15 + 5;
                  },
                  itemStyle: {
                    color: '#b02a02'
                  },
                  encode: {
                    // tooltip: 2,
                  },
                  data: [
                    [593.4374999999999, 203.4375, 100],
                    [532.96875, 176.71875, 30]
                  ]
                },
                {
                  name: 'flay',
                  type: 'lines',
                  Symbol: 'arrow',
                  coordinateSystem: 'geo',
                  geoIndex: 0,
                  symbol: ['none', 'arrow'],
                  effect: {
                    show: true,
                    period: 6,
                    trailLength: 0,
                    // symbol: planePath,
                    symbolSize: 15,
                    color: '#b2d235'
                  },
                  lineStyle: {
                    color: '#843900',
                    width: 1,
                    type: 'solid',
                    curveness: 0.2
                  },
                  encode: {
                    // tooltip: 2,
                  },
                  data: [
                    {
                      coords: [
                        [508.1249999999999, 247.03125],
                        [442.03125, 345.9375]
                      ]
                    },
                    {
                      coords: [
                        [508.1249999999999, 247.03125],
                        [553.5937499999999, 322.96875]
                      ]
                    }
                  ]
                }
          })
        });
        点击其他区域时关闭省份地图回到中国地图
        chinaMapref.getZr().on('click', function(params) {
          var pixelPoint = [params.offsetX, params.offsetY];
          var dataPoint = chinaMapref.convertFromPixel({ geoIndex: 0 }, pixelPoint);
          // 在 SVG 上点击时,坐标会被打印。
          // 这些坐标可以在 `series.data` 里使用。
          // 没有 target 意味着鼠标/指针不在任何一个图形元素上,它是从“空白处”触发的。
          if (!params.target) {
            registerMap('china', { svg: chinasvg })
            //此处为中国地图的配置
            opts.chinaMap = {}
        });
      })
    };
    setMap()
    return {
      chinaMapref,
      opts,
      setMap
    };
  }

刚接触vue3和ts有不对的地方大家多多指教,svg地图是为了方便随便加的Name值,具体的位置都不太准确。除了svg地图的引入,其他部分和canavs渲染好像也没啥太大的区别。具体可以参考官方文档。

Logo

前往低代码交流专区

更多推荐