Vue3+Echarts5绘制带有立体感流线中国地图,建议收藏

博客 分享
0 214
张三
张三 2022-04-06 16:57:38
悬赏:0 积分 收藏

Vue3 + Echarts 5 绘制带有立体感流线中国地图,建议收藏

本文绘制的地图效果图如下:

Vue3 + Echarts 5 绘制带有立体感流线中国地图,建议收藏

 

一、Echarts 使用五部曲

1、下载并引入 echarts

Echarts 已更新到了 5.0 版本,安装完记得检查下自己的版本是否是 5.0 。

npm install echarts --save

下载地图的 json 数据

可以下载中国以及各个省份地图数据。免费的文件下载地址:

http://datav.aliyun.com/portal/school/atlas/area_selector#&lat=30.332329214580188&lng=106.72278672066881&zoom=3.5

记得收藏哦!免得浪费加班时间。

引入:

import * as echarts from "echarts"import chinaJSON from '../../assets/json/china.json'

 

2、准备容器

给元素定义宽高确定的容器用来装地图。

<template> <div id="chinaMap"></div>  </template>

 

3、实例化 echarts 对象

import * as echarts from 'echarts'import chinaJson from '../../assets/json/china.json'var myChart = echarts.init(document.getElementById('chinaMap'))// 创建了一个 myChart 对象

 

4、指定配置项和数据

var option = { // 存放需要绘制图片类型,以及样式设置}

 

5、给 echarts 对象设置配置项

myChart.setOption(option)

 

Vue3 + Echarts 5 绘制带有立体感流线中国地图,建议收藏

 

就这么简单几步还用你告诉我吗?不瞒你说,官网也有这东东。虽然这些你都知道,但是并不影响你还是不知道流线图是怎么绘制出来的。下面我们看看是如何绘制的。

二、开始绘制流线中国地图

第一步:先绘制一个中国地图

Vue3 + Echarts 5 绘制带有立体感流线中国地图,建议收藏

 

import * as echarts from 'echarts'import chinaJson from '../../assets/json/china.json'import { onMounted, ref } from 'vue'const chinaMap = ref()onMounted(() => { drawChina()})function drawChina() { var myChart = echarts.init(chinaMap.value) echarts.registerMap('china', chinaJson) //注册可用的地图 var option = {  geo: {   show: true,   //设置中心点   center: [105.194115019531, 35.582111640625],   map: 'china',   roam: true, //是否允许缩放,拖拽   zoom: 1, //初始化大小   //缩放大小限制   scaleLimit: {    min: 0.1, //最小    max: 12, //最大   },   //各个省份模块样式设置   itemStyle: {    normal: {     areaColor: '#3352c7',//背景色     color: 'red',//字体颜色     borderColor: '#5e84fd',     borderWidth: 2,    },   },   //高亮状态   emphasis: {    itemStyle: {     areaColor: '#ffc601',    },    label: {     show: true,     color: '#fff',    },   },   // 显示层级   z: 10,  }, } myChart.setOption(option)}

 

一个简单的地图就绘制好了,继续研究如何添加流线。

第二步:添加流线

通过 series 属性来设置发色点的样式,接受点的样式,以及线条和线条上的动画。

设置 series 的值:

// 中国地理坐标图var chinaGeoCoordMap: Object = { 西安: [108.906866, 34.162109], 拉萨: [91.140856, 29.645554],}//发射点var chinaDatas = [ [  {   name: '拉萨',   value: 2,  }, ],]//投射点const scatterPos = [108.906866, 34.162109]// 数据转换var convertData = function (data: any) { var res = [] for (var i = 0; i < data.length; i++) {  var dataItem = data[i]  var fromCoord = chinaGeoCoordMap[dataItem[0].name]  var toCoord = scatterPos  if (fromCoord && toCoord) {   res.push([    {     coord: fromCoord,     value: dataItem[0].value,    },    {     coord: toCoord,     },    ])  } } return res}var series: Array<any> = [];[['西安', chinaDatas]].forEach(function (item, i) { series.push(  //设置指向箭头信息  {   type: 'lines',   zlevel: 2,   effect: {    show: true,    period: 4, //箭头指向速度,值越小速度越快    trailLength: 0.02, //特效尾迹长度[0,1]值越大,尾迹越长重    symbol: 'arrow', //箭头图标    symbolSize: 8, //图标大小   },   lineStyle: {    normal: {     color: '#adffd0',     width: 1, //尾迹线条宽度     opacity: 1, //尾迹线条透明度     curveness: 0.3, //尾迹线条曲直度    },   },   data: convertData(item[1]),  }, // 发射点位置涟漪等效果 {  type: 'effectScatter',  coordinateSystem: 'geo',  zlevel: 2,  rippleEffect: {  //涟漪特效  period: 4, //动画时间,值越小速度越快  brushType: 'stroke', //波纹绘制方式 stroke, fill  scale: 4, //波纹圆环最大限制,值越大波纹越大  },  label: {   normal: {   show: true,   position: 'right', //显示位置   offset: [5, 0], //偏移设置   formatter: function (params) {    //圆环显示文字    return params.data.name   },   fontSize: 13,  },  emphasis: {   show: true,  }, }, symbol: 'circle', symbolSize: function (val: Array<any>) {  return 5 + val[2] * 5 //圆环大小 }, itemStyle: { normal: {  show: false,  color: '#f8f9f5',  }, }, data: item[1].map(function (dataItem: any) {  return {   name: dataItem[0].name,   value: chinaGeoCoordMap[dataItem[0].name].concat([dataItem[0].value]),   }  }), }, //被攻击点 {  type: 'effectScatter',  coordinateSystem: 'geo',  zlevel: 2,  rippleEffect: {   //涟漪相关   period: 2,   brushType: 'stroke',   scale: 5,   },  label: {   normal: {    show: true,    position: 'right',    color: '#0f0',    formatter: '{b}',    textStyle: {     color: '#fff',     fontSize: 12,     },    },    emphasis: {     show: true,     color: '#f60',    },   },   itemStyle: {    normal: {    color: '#f00',   },  },  symbol: 'circle',  symbolSize: 10, //圆圈大小  data: [   {    name: item[0],    value: chinaGeoCoordMap[item[0]].concat([10]),    },   ],  }, )})

 

给上边的 option 添加 series 属性。

第三步:添加立体投影

添加立体投影的时候,由于并没有这样的属性,所以需要通过设置边框投影,再加一个偏移。

实现原理:绘制两个地图,设置中心点是一样的,然后一个设置边框投影+偏移,它的层级设置小一点,上边再绘制一个地图不设置投影,这样就能够实现上述效果。

// series 添加一个对象,绘制新地图{ //绘制一个新地图 type: 'map', map: 'china', zoom: 1, center: [105.194115019531, 35.582111640625], z: -1, aspectScale: 0.75, // itemStyle: {  normal: {   areaColor: '#f00',   borderColor: '#090438',   borderWidth: '2',   shadowColor: '#090438',   shadowOffsetX: 0,   shadowOffsetY: 15,   }, },}

 

上述效果的完整源码:

<template>  <div>    首页    <div      ref="chinaMap"      class="chinaMap"      style="        height: 800px;        border: solid 1px red;        width: 100%;        background: #0b0873;      "    >      地图1    </div>  </div></template><style scoped>.chinaMap {  transform: rotate3d(1, 0, 0, 35deg);}</style><script lang="ts" setup>import * as echarts from 'echarts'import chinaJson from '../../assets/json/china.json'import { onMounted, ref } from 'vue'const chinaMap = ref()onMounted(() => {  drawChina()})/**************************** series start ************************************///中国地理坐标图var chinaGeoCoordMap: Object = {  西安: [108.906866, 34.162109],  柯桥区: [120.476075, 30.078038],  拉萨: [91.140856, 29.645554],  沈阳: [123.431474, 41.805698],  新疆: [87.627704, 43.793026],  台湾: [121.508903, 25.044319],}var chinaDatas = [  [    {      name: '柯桥区',      value: 0,    },  ],  [    {      name: '拉萨',      value: 2,    },  ],  [    {      name: '沈阳',      value: 1,    },  ],  [    {      name: '新疆',      value: 1,    },  ],  [    {      name: '台湾',      value: 1,    },  ],]//设置投射点const scatterPos = [108.906866, 34.162109]var convertData = function (data: any) {  var res = []  for (var i = 0; i < data.length; i++) {    var dataItem = data[i]    var fromCoord = chinaGeoCoordMap[dataItem[0].name]    var toCoord = scatterPos    if (fromCoord && toCoord) {      res.push([        {          coord: fromCoord,          value: dataItem[0].value,        },        {          coord: toCoord,        },      ])    }  }  console.log('res', res)  return res}var series: Array<any> = [];[['西安', chinaDatas]].forEach(function (item, i) {  console.log(item, item[0])  series.push(    {      //绘制一个新地图      type: 'map',      map: 'china',      zoom: 1,      center: [105.194115019531, 35.582111640625],      z: -1,      aspectScale: 0.75, //      itemStyle: {        normal: {          areaColor: '#f00',          borderColor: '#090438',          borderWidth: '2',          shadowColor: '#090438',          shadowOffsetX: 0,          shadowOffsetY: 15,        },      },    },    //设置指向箭头信息    {      type: 'lines',      zlevel: 2,      effect: {        show: true,        period: 4, //箭头指向速度,值越小速度越快        trailLength: 0.02, //特效尾迹长度[0,1]值越大,尾迹越长重        symbol: 'arrow', //箭头图标        symbolSize: 8, //图标大小      },      lineStyle: {        normal: {          color: '#adffd0',          width: 1, //尾迹线条宽度          opacity: 1, //尾迹线条透明度          curveness: 0.3, //尾迹线条曲直度        },      },      data: convertData(item[1]),    },    // 发射点位置涟漪等效果    {      type: 'effectScatter',      coordinateSystem: 'geo',      zlevel: 2,      rippleEffect: {        //涟漪特效        period: 4, //动画时间,值越小速度越快        brushType: 'stroke', //波纹绘制方式 stroke, fill        scale: 4, //波纹圆环最大限制,值越大波纹越大      },      label: {        normal: {          show: true,          position: 'right', //显示位置          offset: [5, 0], //偏移设置          formatter: function (params) {            //圆环显示文字            return params.data.name          },          fontSize: 13,        },        emphasis: {          show: true,        },      },      symbol: 'circle',      symbolSize: function (val: Array<any>) {        return 5 + val[2] * 5 //圆环大小      },      itemStyle: {        normal: {          show: false,          color: '#f8f9f5',        },      },      data: item[1].map(function (dataItem: any) {        return {          name: dataItem[0].name,          value: chinaGeoCoordMap[dataItem[0].name].concat([dataItem[0].value]),        }      }),    },    //被攻击点    {      type: 'effectScatter',      coordinateSystem: 'geo',      zlevel: 2,      rippleEffect: {        //涟漪相关        period: 2,        brushType: 'stroke',        scale: 5,      },      label: {        normal: {          show: true,          position: 'right',          // offset:[5, 0],          color: '#0f0',          formatter: '{b}',          textStyle: {            color: '#fff',            fontSize: 12,          },        },        emphasis: {          show: true,          color: '#f60',        },      },      itemStyle: {        normal: {          color: '#f00',        },      },      symbol: 'circle',      symbolSize: 10, //圆圈大小      data: [        {          name: item[0],          value: chinaGeoCoordMap[item[0]].concat([10]),        },      ],    },  )})/****************************************************************/function drawChina() {  var myChart = echarts.init(chinaMap.value)  echarts.registerMap('china', chinaJson) //注册可用的地图  var option = {    tooltip: {      trigger: 'item',      backgroundColor: 'rgba(166, 200, 76, 0.82)',      borderColor: '#FFFFCC',      showDelay: 0,      hideDelay: 0,      enterable: true,      transitionDuration: 0,      extraCssText: 'z-index:100',      formatter: function (params, ticket, callback) {        //根据业务自己拓展要显示的内容        var res = ''        var name = params.name        var value = params.value[params.seriesIndex + 1]        res = "<span style='color:#fff;'>" + name + '</span><br/>数据:' + value        return res      },    },    geo: {      show: true,      center: [105.194115019531, 35.582111640625],      map: 'china',      roam: true, //是否允许缩放,拖拽      zoom: 1, //初始化大小      //缩放大小限制      scaleLimit: {        min: 0.1, //最小        max: 12, //最大      },      //设置中心点      //center: [95.97, 29.71],      //省份地图添加背景      //regions: regions,      itemStyle: {        normal: {          areaColor: '#3352c7',          color: 'red',          borderColor: '#5e84fd',          borderWidth: 2,        },      },      label: {        color: 'rgba(255,255,255,0.5)',        show: false,      },      //高亮状态      emphasis: {        itemStyle: {          areaColor: '#ffc601',        },        label: {          show: true,          color: '#fff',        },      },      z: 10,    },    //配置属性    series: series,  }  myChart.setOption(option)}</script>

 

posted @ 2022-04-06 16:18 前端人 阅读(121) 评论(1) 编辑 收藏 举报
回帖
    张三

    张三 (王者 段位)

    821 积分 (2)粉丝 (41)源码

     

    温馨提示

    亦奇源码

    最新会员