利用echart和echart-gl绘制江苏省的地图之二

利用echart和echart-gl绘制江苏省的地图之二

上一篇讲述了如何使用 echarts@5.2.2echarts-gl@2.0.8 绘制江苏省的3D地图和绘制中存在的问题,而这篇文章将要讲述的是使用 echarts@4.9.0echarts-gl@1.0.1 绘制江苏省的3D地图和绘制中存在的问题。
下面先看一下3D效果图:

在这里插入图片描述

1 使用 echarts@4.9.0 和 echarts-gl@1.0.1 绘制江苏省地图

这里之所使用 echarts@4.9.0echarts-gl@1.0.1 绘制江苏省的3D地图,原因是:

  • echarts 高版本不支持更改geo3D中每个地级市的文本样式。
  • echarts 高版本不支持 geo3D 中每个地级市区域的 click 事件。

1.1 这里采用 cdn 的方式全局引入

<script src="https://cdn.jsdelivr.net/npm/echarts@4.9.0/dist/echarts.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts-gl@1.0.1/dist/echarts-gl.min.js"></script>

当然你也可以使用

$ npm install echarts@4.9.0 echarts-gl@1.0.1

的方式安装后使用

import * as echarts from 'echarts'
import 'echarts-gl'

的方式在模块中引入。

1.2 参数配置

这里的参数配置和 第一篇文章的配置如出一辙,不同的是,这次的配置中添加了环境贴图效果和地级市 click事件触发的效果。

1.2.1 首先造一些地图上的假数据
// 每个地级市地图上的值
const data = [
  { name: '南京市', value: 3802 },
  { name: '无锡市', value: 3802 },
  { name: '徐州市', value: 3412 },
  { name: '常州市', value: 3421 },
  { name: '苏州市', value: 3802 },
  { name: '南通市', value: 3432 },
  { name: '连云港市', value: 3512 },
  { name: '淮安市', value: 3802 },
  { name: '盐城市', value: 3802 },
  { name: '扬州市', value: 3802 },
  { name: '镇江市', value: 3802 },
  { name: '泰州市', value: 3612 },
  { name: '宿迁市', value: 3802 },
]
// 每个地级市的省会经纬度坐标
const gdGeoCoordMap = {
  "南京市": [118.767413,32.041544],
  "无锡市": [120.301663,31.574729],
  "徐州市": [117.184811,34.261792],
  "常州市": [119.946973,31.772752],
  "苏州市": [120.619585,31.299379],
  "南通市": [120.864608,32.016212],
  "连云港市": [119.178821,34.600018],
  "淮安市": [119.021265,33.597506],
  "盐城市": [120.139998,33.377631],
  "扬州市": [119.421003,32.393159],
  "镇江市": [119.452753,32.204402],
  "泰州市": [119.915176,32.484882],
  "宿迁市": [118.275162,33.963008],
}
// 将地级市的经纬度和具体的值结合处理成echarts可以接收的格式
const convertData = function(data) {
  var res = []
  for (var i = 0; i < data.length; i++) {
    var geoCoord = gdGeoCoordMap[data[i].name]
    if (geoCoord) {
      res.push({
        name: data[i].name,
        value: geoCoord.concat(data[i].value)
      })
    }
  }
  return res
}
1.2.2 使用三维的地理坐标系组件绘制3D地图
const geo3D = {
  map: '江苏',                   // 地图类型。
  boxDepth: 80,                 // 三维地理坐标系组件在三维场景中的深度
  regionHeight: 2,              // 三维地图每个区域的高度
  // 用于鼠标的旋转,缩放等视角控制
  viewControl: {
    autoRotate: false,          // 是否开启视角绕物体的自动旋转查看
    rotateSensitivity: 0,       // 旋转操作的灵敏度,值越大越灵敏。支持使用数组分别设置横向和纵向的旋转灵敏度。
    zoomSensitivity: 0,         // 缩放操作的灵敏度,值越大越灵敏。
    panSensitivity: 0,          // 平移操作的灵敏度,值越大越灵敏。支持使用数组分别设置横向和纵向的平移灵敏度
    alpha: 90,                  // 视角绕 x 轴,即上下旋转的角度。配合 beta 可以控制视角的方向。
    beta: 0,                    // 视角绕 y 轴,即左右旋转的角度。
    maxBeta: 45,                // 左右旋转的最大 beta 值。即视角能旋转到达最右的角度。
  },
  // 三维地理坐标系组件 中三维图形的视觉属性,包括颜色,透明度,描边等
  itemStyle: {
    opacity: 1,
    color: 'rgb(5,101,123)',  // 地图颜色
    borderWidth: 1,           // 分界线wdith
    borderColor: '#459bca',   // 分界线颜色
  },
  // 鼠标 hover 高亮时图形和标签的样式。
  emphasis: {
    label: {
      show: false,            // 是否显示高亮
    },
    itemStyle: {
      color: '#0489d6'        // 地图高亮颜色
    }
  },
  // 光照相关的设置。
  light: {
    // 场景主光源的设置
    main: {
      color: '#fff',          // 主光源的颜色
      intensity: 1.5,         // 主光源的强度
      shadow: true,           // 主光源是否投射阴影
      shadowQuality: 'high',  // 阴影的质量
      // alpha: 55,           // 主光源绕 x 轴,即上下旋转的角度
      // beta: 4,             // 主光源绕 y 轴,即左右旋转的角度
    },
    // 全局的环境光设置
    ambient: {
      color: '#fff',  // 环境光的颜色
      intensity: 2    // 环境光的强度
    },
    ambientCubemap: {
      diffuseIntensity: 2,  // 漫反射的强度
      specularIntensity: 2, // 高光反射的强度
    }
  },
}
1.2.3 组合配置参数
const options = {
  geo3D
}

1.3 绘制3D地图

1.3.1 初始化画布
// 初始化画布
const echart = echarts.init(document.getElementById('echarts'), {
  width: document.documentElement.clientWidth,
  height: document.documentElement.clientHeight
})

// 注册江苏省数据
echarts.registerMap('江苏', jiangsu)

// 绘制3D地图
echart.setOption(options)
1.3.2 声明3D地图进入效果

首次进入,首先是一个平面图,紧接着反转 90 度,成一个有深度的3D地图

function setMap3DBoxDepth(success) {
  let count = 90
  let timer = setInterval(() => {
    if (count <= 40) {
      clearInterval(timer)
      success()
    } else {
      count = count - 10
      echart.setOption({
        series: [{
          viewControl: {
            alpha: count
          }
        }]
      })
    }
  }, 30)
}
1.3.3 处理地级市数据上的图片的位置

为什么要配置图片在地图上的位置呢?因为 echarts-gl 中无法设置 3D 的形状和彩色图片。这里使用生成 img 元素通过定位的方式在指定的位置放置图标。而此处的位置是采用鼠标的横纵坐标位置来设置的。

function setImagesPosition(data = []) {
  data = [
    { name: '南京市', value: [628, 416, 1] },
    { name: '苏州市', value: [919, 485, 0] }
  ]
  for (let i = 0; i < data.length; i++) {
    const { value: [x,y,flag] } = data[i]
    const img = document.createElement('img')
    img.setAttribute('src', flag ? icon_01 : icon_02)
    img.setAttribute('style', `
      position: absolute;
      left: ${x}px;
      top: ${y}px;
      transform: translate(-50%, -50%) scale(0.6);
      pointer-events: none;
    `)
    document.getElementById('echarts').appendChild(img)
  }
}
1.3.4 首次进入实现3D地图效果
// 获取环境贴图的HTML元素
const mapBgImg = document.getElementById('map-bg')

// 平面转换为倾斜
setMap3DBoxDepth(() => {
  echart.setOption({
    series: [{
      shading: 'realistic',
      realisticMaterial: {
        // 材质细节的纹理贴图,参数只有三种格式:string、HTMLImageElement、HTMLCanvasElement
        detailTexture: mapBgImg
      },
      itemStyle: {
        borderColor: '#fff'
      }
    }]
  })
  setImagesPosition()
})
1.3.5 点击地级市区域触发地图
echart.on('click', (params) => {
  const { seriesType, name, event: { event: {x,y} } } = params
  console.log(['echart', name, x, y])
  if (seriesType === 'map3D' && name === '南京市') {
    console.log(name)
    this.is_show_dialog_city = true
    // 设置电厂的位置
    setFactoryPosition()
  }
})

1.4 设置南京市的地图

<div id="dialog-box">
  <div class="dialog-close">&times;</div>
  <div id="dialog-warpper"></div>
</div>
1.4.1 在南京是地图上设置具体的电厂的位置
function setFactoryPosition(data = []) {
  data = [
    { x: 429, y: 92, name: '南京华润' },
    { x: 452, y: 288, name: '大唐南京' }
  ]
  for (let i = 0; i < data.length; i++) {
    const { x, y, name } = data[i]
    const box = document.createElement('div')
    const title = document.createElement('div')
    const img = document.createElement('img')

    box.setAttribute('class', 'factory-warpper')
    box.setAttribute('style', `
      left: ${x}px;
      top: ${y}px;
    `)

    title.setAttribute('class', 'factory-title')
    title.innerText = name

    img.setAttribute('src', icon_01)
    img.setAttribute('class', 'factory-icon')

    box.appendChild(title)
    box.appendChild(img)

    document.getElementById('dialog-warpper').appendChild(box)
  }
}

2. 存在的问题

  1. echarts@4.9.0echarts-gl@1.0.1 绘制3D无法设置3D图标。
  2. 通过 鼠标的横纵坐标位置并使用 img 图片在3D地图上设置具体的图标的位置,非常的麻烦,需要计算画布的大小,和画布与img图标的相对位置。
  3. 3D 地图边角不支持圆滑的边框效果。
  4. 3D 环境贴图只有在最后一步设置,否则会失效,所以就出现了另一种问题,首次进入前3D地图没有贴图效果。
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ECharts-GL是Apache ECharts(正在孵化)的扩展包,它提供3D绘图,地球仪可视化和WebGL加速。 特色: 1、混搭 ECharts 里的混搭功能很强大,作为 ECharts 的扩展,ECharts-X 自然也需要支持。ECharts-X 能跟 ECharts 中的折柱饼地图等图表混搭,可以有更丰富的可视化效果,同时 ECharts-X 也能够直接使用 ECharts 中的 legend, dataRange 等组件。 2、3D大规模标注 ECharts-X 中的标注在效果和使用上都跟 ECharts 中的标注(markPoint)类似,但是由于WebGL的强大能力,对于几万甚至几十万的markPoint也能进行实时的动画和交互 标柱(markBar)是 ECharts-X 中新定义的一个概念,它是标注(markPoint)的衍生,在三维空间扩展了高度维度表达更丰富的数据信息。 3、3D大规模标线 同样 ECharts-X 中的标线在使用上和 ECharts 类似,但是展现效果从 2D 变成 3D 的曲线,支持几万条 markLine 的实时展现,动画以及交互。 4、风场,洋流等向量场的可视化 NASA之前发布过全球洋流图,用梵高风格的表现使得可视化也充满了艺术感,ECharts-X 也提供了对洋流,风场这种向量场可视化的便捷配置。同样的,也是实时的展现和交互。 5、自定义底图 这个功能比较简单但是非常实用,能够配置地球的底图纹理图片,使得展现更有质感,以后也会在 ECharts 的 map 中加入。下面截图是将地图换成木星纹理的效果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值