echarts学习:绘制地图

news2024/9/21 2:40:35

前言

经过之前一段时间的磨砺,我具备了基本的使用echarts绘制图表的能力。但是在最近这几个月里我接连遇到了几个棘手的任务,这大大的提升了我的echarts水平。其中我遇到的第一个高难度任务就是使用echarts绘制如下的地图:

简单的分析一下,这张图中我主要有几个任务点:

  1. 最重要的就是,要在地图上展示降雨区,这些降雨区的颜色要根据真实的数据渲染
  2. 要有一个图例
  3. 添加降雨区图层下的地图(可选任务,完成可以增加地图的真实性)

一、如何使用echarts绘制一张地图

想要使用echarts绘制地图,你必需要了解三个内容:registerMapseries-mapgeo。其中registerMap是用来注册地图的方法,series-map则用于创建地图类型的chart,geo(地理坐标系组件)则主要是用于进行地图的可视化设置的。

1.使用 registerMap 注册地图

想要绘制地图就必须使用地理空间数据,在echarts中我们可以使用echarts.registerMap方法将地理空间数据引入echarts中。当然echarts毕竟不是专业的地图库,因此它只能接受GeoJSON类型的地理数据或者是一张SVG图。

我是有降雨区的的坐标数据的,因此这里我的思路就是,先将地理坐标数据转换为GeoJSON,再将GeoJOSN注册为地图。

转换GeoJSON

这里我就直接使用turf.js中的polygonfeatureCollection方法进行了转换,同时还将降雨区的名称作为了polygon的属性数据。

const geoJson = featureCollection(
  geo.map(el =>
    polygon([el.coordinate], { name: el.name})
  )
);

注意:这里给polygon中添加名称很关键,有了名称后续才可以在地图上展示区域的名称,还有更重要的,方便之后作为主键用于关联数据和 GeoJSON 地理要素。

注册地图

echarts.registerMap("beijiang", {
  geoJson,
});

2.使用 series-map 和 geo 组件创建地图

这里我需要着重谈一个问题:series-mapgeo组件有什么联系和区别,一开始的时候我对这两者是傻傻分不清的。其实仔细观察就会发现,geo组件中的配置属性series-map中都有,但series-map可以给地图添加属性数据,geo组件则不能。所以其实可以理解为geoseries-map的“子集”。实际上在默认情况下series-map 会自己生成内部专用的 geo 组件。但是也可以用这个 geoIndex 指定一个 geo 组件。这样的话,map 和 其他 series(例如散点图)就可以共享一个 geo 组件了。

而我目前是没有共享geo组件的需求的,因此我就只需要使用series-map就行了,不用再专门搞一个geo组件了。那么此时我的配置项如下:

{
  series: [
    {
      type: "map",
      // 使用registerMap注册的地图名称
      map: "beijiang",
      // 每个降雨区对应的属性数据
      data: geo.map(item => ({
        name: item.name,
        value: item.value,
      })),
      top: "2%",
      left: "19%",
      itemStyle: {
        borderColor: "rgb(255,255,255,0.3)",
        borderWidth: 3,
      },
      label: {
        show: false,
        fontSize: 10,
      },
      aspectScale: 1,
    },
  ],
}

这些配置当中最重要的是mapdatamap用于指定我使用哪个地图(实现通过registerMap注册的),data则用于引入地图的属性数据(在我这里就是降雨区的降雨量数据)。至于其它的配置项则就是用来配置布局和样式的这里就不详细介绍了。

二、如何让地图上的降雨区根据传入的数据进行颜色映射

目前还有一个最重要的任务没有实现,就是让每个降雨区根据不同的降雨量渲染不同的颜色,这个就需要用到视觉映射组件visualMap

1.如何使用visualMap组件

使用visualMap组件只需要回答好几个问题就行了。

对哪个系列使用数据映射?

通过seriesIndex选项设置对哪个系列进行映射

使用哪些数据进行映射?

数据映射使用的是系列中的series.data中的数据,但其中的数据可能会有多个维度,可以使用dimension选项设置使用哪个维度的数据

使用哪种类型的视觉映射组件?

virualMap组件分为连续型(visualMapContinuous)与分段型(visualMapPiecewise)。

连续型的意思是,进行视觉映射的数据维度是连续的数值;而分段型则是数据被分成了多段或者是离散型的数据。

连续型的是这样:

分段型的则是这样:

分段型的视觉映射组件又可以分为三种模式:

映射哪些视觉元素?如何设置映射规则?

数据映射的目标就是视觉元素,echarts中可以映射的视觉元素有:

主要通过inRangeoutOfRange设置视觉元素及其映射规则,详情请见相关文档:

visualMap-continuous.inRange

2.实现我的visualMap

根据上面总结的使用方法,我来实现自己的视觉映射。

第一步 对哪个系列使用数据映射?

我这边只有一个系列,因此不用专门设置。

第二步 使用哪些数据进行映射?

我的数据只有namevalue两个维度,因此也不用专门设置。

第三步 使用哪种类型的视觉映射组件?

查看一下示例,我需要实现这样的视觉映射:

因此我需要使用的是分段型视觉映射组件,并且要使用自定义分段模式

所以type就为'piecewise',并在pieces中定义每块的范围。

{
  visualMap:{
    type:"continuous",
    pieces:[...]
  }
}

映射哪些视觉元素?如何设置映射规则?

我需要映射的视觉元素就只有颜色,但是设置的方式就比较特殊了。对于分段型视觉映射组件的自定义分段模式来说,是直接在pieces中色孩子映射规则和视觉元素,不需要使用inRangeoutOfRange。详情请见官方配置项文档:visualMap-piecewise.pieces

{
  visualMap:{
    type:"continuous",
    pieces:[
      { gte: 0, lte: 10, color: "#A6F28E" },
      { gt: 10, lte: 25, color: "#258C30" },
      { gt: 25, lte: 50, color: "#61B8FF" },
      { gt: 50, lte: 100, color: "#0000E1" },
      { gt: 100, lte: 250, color: "#FA00FA" },
      { gt: 250, lte: 400, color: "#880015" },
      { gt: 400, lte: 600, color: "#FFAA01" },
      { gt: 600, lte: 1000, color: "#FF6600" },
      { gt: 1000, lte: 1500, color: "#E60000" },
      { gt: 1500, color: "#990100" },
    ]
  }
}

最后在添加一些其它的设置,最终的效果如下:

{
  visualMap:{
    type: "piecewise",
    pieces: [
      { gte: 0, lte: 10, color: "#A6F28E" },
      { gt: 10, lte: 25, color: "#258C30" },
      { gt: 25, lte: 50, color: "#61B8FF" },
      { gt: 50, lte: 100, color: "#0000E1" },
      { gt: 100, lte: 250, color: "#FA00FA" },
      { gt: 250, lte: 400, color: "#880015" },
      { gt: 400, lte: 600, color: "#FFAA01" },
      { gt: 600, lte: 1000, color: "#FF6600" },
      { gt: 1000, lte: 1500, color: "#E60000" },
      { gt: 1500, color: "#990100" },
    ],
    align: "right",
    textGap: 9,
    itemGap: 9,
    right: 10,
    bottom: 10,
    padding: [25, 5, 5, 5],
    inverse: true,
    itemWidth: 20, // 减小宽度
    itemHeight: 10, // 减小高度
    textStyle: {
      fontSize: 10,
    },
    backgroundColor: "#fff",
  }
}

三、如何给地图添加背景地图

现在我已经完成了地图的主要功能,接下来我想尝试给地图添加底图。我已经事先准备好了一张底图的图片:

我的计划就是将这张底图图片设置为图表的背景图片。

1.失败的尝试

将底图图片设置为图表容器的背景

一开始我在网上搜到了这个方法,直接将图片设置为容器的背景图,这样做确实可以实现对应的效果:

但是后面我发现这个方法不适合我,因为我生成地图的目标是要将其下载为图片,我是使用echartsInstance. getDataURL下载的,这样下载的图片是无法保留容器的背景的。

将底图图片注册为地图插入图表

在经历了上面的失败后,我又想到了echarts.registerMap方法可以将svg图片注册为地图,那么我是不是可以将底图图片先转为svg格式,然后再用echarts.registerMap方法注册为地图,最后再通过series-map添加到图表中。

很可以这么尝试之后失败了,我在注册和使用的阶段总是会报错,我无法解决这些报错。

我猜测这可能与我的svg只是一张套皮的png图片有关:

2.使用graphic添加底图图片

之后我又查阅了一些资料,了解到echarts的graphic组件可以添加图片。实际上graphic非常强大它可以向图表中添加各种图形以及文本和图片。

于是我成功的添加了底图图片。

{
  graphic:[
    {
      type: "image", // 图形元素类型
      id: "basemap", // 更新或删除图形元素时指定更新哪个图形元素,如果不需要用可以忽略
      right: "center", // 根据父元素进行定位(居中)
      y: -50,
      scaleY: 1.2,
      scaleX: 1.0,
      z: 0, // 层叠
      bounding: "all", // 决定此图形元素在定位时,对自身的包围盒计算方式
      style: {
        image: "./PixPin_2024-07-04_17-39-26.png",
        width: 550,
        height: 410,
      },
    }
  ]
}

四、给图例添加单位

目前整张地图已经基本完成了,但还有一个小小部分没有实现,那就是原型图中的图例的单位:

这个用visualMap是没办法实现的,我本来是准备使用title组件 来添加这行文本的,但是如今既然了解到了graphic那我就准备用graphic-text来做。

{
  graphic:[
    {
      type: "text",
      x: 470,
      y: 185,
      z: 5,
      style: {
        text: "降雨量(mm)",
        fontSize: 10,
      }
    }
  ]
}

最终效果如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2039586.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

批量查询全国快递单号:高效追踪物流信息

在日常生活和工作中,我们经常会遇到需要查询多个快递单号物流信息的情况。如果手动逐一查询,不仅效率低下,而且容易出错。为了解决这个问题,我们可以借助固乔科技推出的【固乔快递查询助手】软件,轻松实现全国快递的批…

yolov5详解(一):网络结构

1. 完整的网络结构 以下是参考b站上作者以及yolov5官方代码画出的yolov5l v6.0版本的模型结构,v6.0版本的模型结构是目前yolov5版本的稳定版本,想必以后也不会有什么改变。l,m,n,s,x只是有些层以及输出通道数变化,整体架构是完全一样的&…

vue 项目中 使用vxe-grid 表格中给表格的表头设置特殊的格式 , 并且给指定的列文字设置颜色

项目场景: 相关背景: vue 项目中 使用vxe-grid 表格中给表格的表头设置特殊的格式,并为指定的列文字设置颜色 实现方案: 具体实现方法及步骤: 一、给表格的表头设置特殊的格式 实现方式一: :header-row-s…

WebDeveloper靶机复现

靶机设置 设置靶机为NAT模式 靶机IP发现 nmap 192.168.112.0/24 靶机ip为192.168.112.137 目录扫描 开放80端口,进行目录扫描 dirb 192.168.112.137 访问浏览器 目录拼接 拼接/ipdata 发现了一个流量包 在wireshark里面查看,发现wordpress的账户…

python提取b站视频的音频(提供源码

如果我想开一家咖啡厅,那么咖啡厅的音乐可得精挑细选!又假设我非常喜欢o叔,而o叔只在b站弹钢琴,那这时候我就得想方设法把b站的视频转为音频咯! 一、首先打开网页版bilibili,按F12: 二、刷新页面…

Java 空值与null 形参与实参学习

Java系列文章目录 文章目录 Java系列文章目录一、前言二、学习内容:三、问题描述四、解决方案:4.1 空值与null的区别4.1.1 空值(Empty Value)4.1.2 Null 4.2 形参与实参区别 五、总结:5.1 学习总结: 一、前…

智慧高速路三维可视化解决方案

项目背景 随着科技的快速发展,智慧高速公路的建设已成为交通领域的重要趋势。国家和相关部委陆续发布多项政策指导智慧公路建设,逐步制定相关建设标准规范,协助推动公路数字化、智能化升级。 方案简介 数字孪生高速公路解决方案是一种集成…

练习实践-基础设施-文件共享-FTP服务搭建-匿名/本地用户/虚拟用户三种模式

参考来源: 在线书籍-linux就该这么学-第11章 安装vsftpdf服务 [rootcentos7 home]# dnf install vsftpd Extra Packages for Enterprise Linux 7 - x86_64 0. CentOS-7 - Base - mirrors.aliyun.com …

C语言中的整数和浮点数在内存中存储

在C语言中,整形和浮点型数据的存储方式有所不同。 对于整形数据,C语言使用补码表示法存储。补码表示法可以方便地进行二进制加减法运算,同时能够简化硬件设计。对于正整数,其补码与原码相同,即直接存储其二进制表示。对…

Spring 循环依赖解决方案

文章目录 1. 循环依赖的产生2. 循环依赖的解决模型3. 基于setter/Autowired 的循环依赖1_编写测试代码2_初始化 Cat3_初始化 Person4_ 回到 Cat 的创建流程5_小结 4. 基于构造方法的循环依赖5. 基于原型 Bean 的循环依赖6. 引人AOP的额外设计7. 总结 IOC 容器初始化bean对象的逻…

如何对open62541.h/open62541.c的UA_Client进行状态(在线/掉线)监控

文章目录 1.背景2.解决方案3.异步连接4.注意事项4.1.线程问题4.2.UA_Client_run_iterate 1.背景 目前在利用open62541.h/open62541.c编写了一个与PLC进行OPCUA通讯的上位机程序。 上位机这边会定时对PLC的某个opcua变量进行写操作。但是假如PLC离线或者说拔掉网线,…

【多线程-从零开始-柒】单例模式,饿汉和懒汉模式

单例模式:是一种设计模式 设计模式,类似于“棋谱”,就是固定套路,针对一些特定的场景,给出一些比较好的解决方法只要按照设计模式来写代码,就可以保证代码不会太差,保证代码的下限 设计模式 设…

8月8日学习笔记 python基础

1.环境 python2, python3 yum list installed|grep python yum -y install python3 # 最新安装3.12可以使⽤源码安装,教程是在第⼀个星期pdf python3 --version 3.6.8 #进⼊到python的编辑状态 python3 # 如果直接输⼊python,也会进⼊到pyth…

MySQL基础练习题33-有趣的电影

目录 题目 准备数据 分析数据 总结 题目 找出所有影片描述为 非 boring (不无聊) 的并且 id 为奇数 的影片。 返回结果按 rating 降序排列。 准备数据 ## 创建库 create database db; use db;## 创建表 Create table If Not Exists cinema (id int, movie varchar(255),…

php根据截止时间计算剩余的时间,并且在剩余时间不足1天时仅显示小时数

//获取政策库文章public function getIndexZckList(){$fl_id = input(fl_id);if(empty(

C++:list类(迭代器类)

前言 list是链表的意思 它属于链表中的带头双向循环链表 建议先掌握数据结构中的链表 C数据结构:单链表-CSDN博客 C数据结构:双向链表(带头循环)_c带头双向循环链表-CSDN博客 数据结构 首先我们需要一个链表的节点 templa…

ThinkPHP5漏洞分析之代码执行

漏洞概要 本次漏洞存在于 ThinkPHP 的缓存类中。该类会将缓存数据通过序列化的方式,直接存储在 .php 文件中,攻击者通过精心构造的 payload ,即可将 webshell 写入缓存文件。缓存文件的名字和目录均可预测出来,一旦缓存目录可访问…

【张】#12 enum 枚举

enum 枚举定义格式&#xff1a; enum <类型名> {<枚举常量表> }; 枚举其实就是一个整数 enum example {Aa,Bb10,Cc //给Bb赋值为10后&#xff0c;Cc的值会变成11 }; 枚举变量只能使用枚举值&#xff0c;枚举可以赋值给整型&#xff0c;整型不能赋值给枚举 #inc…

掌握Jenkins自动化部署:从代码提交到自动上线的全流程揭秘

Jenkins自动化部署是现代软件开发中不可或缺的一部分&#xff0c;它不仅简化了代码的发布过程&#xff0c;还为整个团队带来了无与伦比的效率和协作力。想象一下&#xff0c;开发者们可以专注于编写高质量的代码&#xff0c;而不是为繁琐的手动部署所烦恼&#xff1b;测试人员能…