如何使用 Echarts 和 SVG文件写大屏可视化地图 ?
点击上方蓝字关注趣谈前端
转自: https://juejin.cn/post/7009889635618799630
契机
最近公司要做一个政务大屏项目,由于在员工竞优大会上表(jing)现(chui)良(niu)好(b)的我说希望未来能做一个大屏项目,于是这个任务自然交到我头上(需求来得真快),当我拿到图的时候发现地图上有定制化的元素,就是下面图中的三条河流
如果想要使用 GeoJSON 的方式,那就必须知道三条河流的坐标系才行,可是 UI 小姐姐说需求方给的河流就是个图层,她只贴到地图上而已,并没有坐标方面的数据。
我需要根据 SVG将地图渲染出来。并添加一些额外的元素。
于是便有了这篇文章。
纯当是一次实践记录。
选择正确的地图组件
原先我们的地图则只能使用 GeoJSON 格式来作为底图进行描绘,Echarts 从最新的第5版本开始支持地理坐标系(geo)和地图系列(map series)中使用 SVG 作为底图。
地理坐标系(geo)[1] :地理坐标系组件。地理坐标系组件用于地图的绘制,支持在地理坐标系上绘制散点图[2],线集[3]。
地图系列(map series)[4] :地图,主要用于地理区域数据的可视化,配合 visualMap[5] 组件用于展示不同区域的人口分布密度等数据。
地理坐标系跟地图系列的最大不同可能就是绘制散点图、线集的,这点在官方网站上是有写的
如果要实现点数据或者线数据的可视化,可以使用在地理坐标系组件[6]上的散点图[7]和线图[8]。
当然,我们学习 Echarts 不可能干啃API,自然需要结合生动的例子,这里就用官方的示例庖丁解牛[9]和散点图[10]来作为两者的区别所在,通过官方的配置项我们可以看到配置是不同的
series: [{name: 'French Beef Cuts',//庖丁解牛配的是地图系列type: 'map',map: 'Beef_cuts_France',...}]
geo: {tooltip: {show: true},map: 'iceland_svg',//散点图配的是地图坐标系...},
视觉上的不同自然就是散点了,散点长这样
由于我们的项目需要加很多散点,所以我们自然要选择geo组件。
具名元素
什么是具名元素呢?就是有名字的 SVG 元素。
如果我们希望跟 SVG 元素做交互,则需要先标记这些元素,标记非常简单,就是给它加一个 name 属性。比如我们拿到 SVG 文件后,可以在 path 上加上名称属性name="named_rect"
,那么这个 path 就是具名元素。
加了名字的元素跟没有名字的元素有非常大的区别,一旦加上名字,就可以拥有高亮、淡入淡出、文字标注、提示框等交互功能,作为例子,以下放官方给的例子
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" fill-rule="evenodd" xml:space="preserve"><path name="named_rect" d="M 0,0 L 0,100 100,100 100,0 Z" fill="#765" /><path d="M 150,0 L 150,100 250,100 250,0 Z" fill="#567" />
</svg>
左边的矩形由于加了 name,就自动拥有 hover 时高亮的效果,而右边的则没有。
而且加了 name 后的具名元素还可以在 Echarts 的 options 中配置geo.regions[11]以做特定的配置效果,这个配置效果会跟我们起的 name 做匹配。
option = {geo: {map: 'some_svg',regions: [{name: 'element_name_1',//这里跟 svg 源文件中的 name做匹配itemStyle: { ... }}, }
};
注意:
只有这些 SVG 元素可以被命名:
rect
、circle
、line
、ellipse
、polygon
、polyline
、path
、text
、tspan
、g
。支持多个元素以相同的名称命名,这样它们能被同时高亮、选中。
实战开始吧!
下面我将使用slice[12]作为底图,这个文件是UI 小姐姐通过 figma 导出来给到我的。
我们的目标是使用此文件配合 Echarts 在浏览器上描绘地图,并做一些简单的交互效果来熟悉 Echarts 的配置项。
给 path 加上具名元素
拿到SVG文件后,我们需要使用 Chrome打开它, 使用 vscode 打开后的 SVG 是一串 XML 标签,而 Chrome 打开后会自动解析(就跟解析 HTML一样),并且渲染出效果来。
每个 SVG矢量文件本质上是很多定义好的线和形状来创建的图形,里面最常用的可能是 path 路径标签,而且它是最强大的一个,可以通过它创建各种线条、曲线、弧形等等。
我们在浏览器中打开F12开发者工具,并且选择小箭头对准渲染出来的图片,就可以看到某块区域的 path
现在已经很清楚了,整块底图都是用大量的 path 进行描绘的,而 path 的形状是通过属性 d 来定义的。
我们不关心 d 属性是怎样写出来的,现在要做的,就是在 SVG 源文件中给对应的path 加上 name 属性。
<path name="昭通市" d="M480.832 ..."
基本用法
接着我们需要在框架中使用Echarts 了,这里选用 React作为 UI 框架,这里是基本结构
import React, { useEffect } from 'react';
import * as echarts from 'echarts';
import jQuery from 'jquery';
window.$ = jQuery;export const Middle = () => {//创建 map 的函数,在里面写 Echarts 的配置项const createMap = id => {};useEffect(() => {createMap('map');}, []);return <div id='map' />;
};
接着我们在createMap
这个函数中使用 Echarts,这里是SVG 作为底图的写法
const createMap = id => {const myChart = echarts.init(document.getElementById(id)!);//$.get()里写你的SVG 文件路径$.get('/slice.svg', function (svg) {//首先向 echarts 注册 SVG 字符串或解析过的 SVG DOMecharts.registerMap('map', { svg: svg });var option = {toolTip: {},//开启地理坐标系组件。地理坐标系组件用于地图的绘制,支持在地理坐标系上绘制散点图,线集。geo: {map: 'map', //这里写注册过的map 名字},};myChart.setOption(option);});};
现在打开浏览看可以查看到效果了,不出意外的话,你可以看到这样的效果
由于我只给一个path 添加name,所以只有这一个元素会移动时高亮。
给地图加上文字
上面的效果是 hover 时拥有文字效果,这里有两种方式可以加文字
SVG 源文件中加 text 标签
Echarts 中配置
SVG 源文件中加就比较基础了,需要我们写 xml 标签,比如这样
<text xml:space="preserve" style="font-size:14px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;text-anchor:middle;fill:rgba(61,215,255,55%);fill-opacity:1;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:Bitstream Vera Sans Bold" x="128.21919" y="112.48651" id="text3831" transform="matrix(0.99999776,-0.00211681,0.00211681,0.99999776,0,0)">
<tspan sodipodi:role="line" x="550.59958" y="160.12965" id="tspan38351">
昭通市</tspan>
</text>
这是我在SVG 源文件里面写的,缺点是要找 x 点和 y 点,然后写在对应的 x 属性和 y 属性中。
更简单的方法是直接用 Echarts 的配置项option.geo 自动加上标注文字。
geo: {map: 'map', //这里写注册过的map 名字//文字标注的配置label: {show: true,//显示color: 'rgba(61, 215, 255, 0.55)',//颜色},},
我在这里选择的方式是在源文件中写 text 标签,因为需要还原设计稿,统一的配置无法满足我的要求,具体看需求就行。
我加好 name 跟 text 的文件在这:map[13]
高亮强调emphasis
默认的高亮无法满足我们的要求,所以我们可以通过emphasis来配置高亮的效果
geo: {...emphasis: {focus: 'none', //高亮时聚焦自己itemStyle: {areaColor: '#2080D7',borderColor: '#2B91B7', //地图区域的颜色。borderWidth: 2,opacity: 1,shadowColor: 'rgba(74, 188, 251, 0.4)',shadowBlur: 3,shadowOffsetX: 3,shadowOffsetY: 3,},label: {show: false, //高亮时文字不要出现},},},
具体配置都是查的官方文档,geo.emphasis[14]
现在的效果是这样的
地域分块regions自定义样式
如果想要统一设置样式,可以使用 geo.itemStyle配置
//统一样式配置itemStyle: {areaColor: '#1C3079',borderColor: '#2ab8ff',},
如果需要分块定制配置,就需要使用geo.regions这个配置项。
//单独定制的区块设置regions: [{name: '昭通市',itemStyle: {areaColor: 'rgba(44, 76, 187, 1)',},},{name: '玉溪市',itemStyle: {areaColor: 'rgba(44, 76, 187, 1)',},},{name: '怒江傈傈族自治州',itemStyle: {areaColor: 'rgba(44, 76, 187, 1)',},},{name: '迪庆藏族自治区',itemStyle: {areaColor: 'rgba(44, 76, 187, 1)',},},{name: '楚雄彝族自治州',itemStyle: {areaColor: 'rgba(16, 34, 84, 1)',},},{name: '红河哈尼族彝族自治州',itemStyle: {areaColor: 'rgba(16, 34, 84, 1)',},},{name: '丽江市',itemStyle: {areaColor: 'rgba(16, 34, 84, 1)',},},],
目前我们分别有geo.regions.itemStyle、geo.itemStyle、geo.emphasis.itemStyle,他们分别可以定制化地区的样式、全局统一样式和高亮时的样式,API 颗粒度的划分非常精细,只需要到对应的父级配置项查询即可。
layout布局
如果希望整个地图能够尽量占满我们设定好的div 的宽高,就需要在 geo 中配置以下内容,以填充Echarts 容器。
layoutSize: '100%', //布局尺寸layoutCenter: ['50%', '50%'], //布局位置
series系列
series 是 Echarts 中最重要的属性,几乎配置任何图表都离不开它,通过 series 的 type 属性,我们可以定制诸如折线 line、柱状图 bar、饼图 pie、散点气泡图scatter等等特效效果。
我的项目中需要使用到series-effectScatter(带有涟漪效果的散点图)和series-scatter(散点气泡图),具体 API 可以通过option[15]查看,这里我就直接贴代码
const mapData = [{name: '古水水电站1',//数据名称,对应 option.tooltip.formattervalue: [190, 215],//坐标},{name: '红色水电站8',value: [366, 260],},{name: '红色水电站9',value: [436, 270],},{name: '红色水电站10',value: [470, 500],},{name: '红色水电站11',value: [520, 310],},];
var option = {//全局开启提示框的样式配置,这里如果配置,有几率下面所有散点图不会出现提示框。tooltip: {show: true,//开启全局提示框formatter: '{b}',//格式化,选择显示数据名称backgroundColor: 'rgba(7, 26, 55, 0.8)',borderColor: '#3DD7FF',borderWidth: 1,padding: [3, 5, 3, 5],textStyle: {color: 'white',},},...series: [{//带有涟漪特效动画的散点(气泡)图type: 'effectScatter',coordinateSystem: 'geo', //该系列使用的坐标系tooltip: {show: false,//这个系列不要提示框},//涟漪特效相关配置。rippleEffect: {brushType: 'stroke', //波纹的绘制方式 一笔一笔scale: 4,},showEffectOn: 'render', //绘制完成后显示特效 'emphasis' 高亮(hover)的时候显示特效symbol: 'circle', //涟漪特效的标记图形symbolSize: [8, 5], //图形尺寸 宽 高zlevel: 1, //优先级//图形样式itemStyle: {color: 'yellow',},//系列中的数据内容数组。数组项通常为具体的数据项。data: mapData.map(item => item.value),},{//系列类型 散点(气泡)图。type: 'scatter',coordinateSystem: 'geo',tooltip: {show: true,//这个系列要提示框},symbol: 'pin',emphasis: {scale: true,},symbolSize: [30, 33],symbolOffset: [0, -5],zlevel: 20,itemStyle: {color: 'red',},data: mapData,},],};
这样效果就大概有了
获取坐标轴
上面的 mapData 中的 value,在这个项目中表示坐标轴(具体看 data 的配置,也可以是数据),但是我们并不知道坐标轴是多少,如果挨个试太浪费时间,还好 Echarts 提供给我们 API,我们可以通过监听事件来获取坐标
//获取 svg 底图的坐标myChart.getZr().on('click', function (params) {var pixelPoint = [params.offsetX, params.offsetY];var dataPoint = myChart.convertFromPixel({ geoIndex: 0 }, pixelPoint);// 在 SVG 上点击时,坐标会被打印。// 这些坐标可以在 `series.data` 里使用。console.log(dataPoint);});
事件
如果要对 SVG 元素进行操作,可以指定事件
// 'name1' 是一个 SVG 元素的名字。
myChart.on('click', { geoIndex: 0, name: 'name1' }, function (params) {console.log(params);
});
如果想要对series 中诸如 type 为 scatter 的散点图绑定点击事件,则可以这样写
myChart.on('click', 'series.scatter', function (params: any) {console.log(params);
});
每个项目都少不了自适应,如果想要 Echarts 的地图自适应,则需要监听 window 的 resize 事件,然后调用 Echarts 实例的 resize 方法
window.addEventListener('resize', () => {myChart?.resize();
});
目前我的项目只需要用到这三个事件API,还有更多定制化的事件,可按需查文档echarts-event[16]
结束语
以上的记录只是项目的一个基本结构,不代表最终项目品质。基于上面的结构,我们已经能够在 SVG 地图上做出非常多样的样式效果和定制服务了。
如果觉得自己配置比较麻烦的话,可以参考这个网站makeapie[17],找别人写好的案例,copy一下配置项即可。
更多推荐
如何设计可视化搭建平台的组件商店?
从零设计可视化大屏搭建引擎
从零使用electron搭建桌面端可视化编辑器Dooring
(低代码)可视化搭建平台数据源设计剖析
深度剖析github上15.1k Star项目:redux-thunk
【H5制作】5分钟教你用H5-Dooring快速制作H5!
关注趣谈前端,更多前端实战 / 成长规划 / 可视化等你来学!
如何使用 Echarts 和 SVG文件写大屏可视化地图 ?相关推荐
- 数据可视化UI设计素材资源文件sketch大屏可视化数据展示
数据是企业的上帝之眼,数据可视化就发挥了很大的作用.很多从事B端产品设计的小伙伴在日常工作中遇到数据可视化的场景比较多,也得益于PSD素材较多,所以用的设计工具大多是Photoshop,但Photos ...
- 数据可视化UI设计素材资源文件psd大屏可视化数据展示Photoshop设计文件
大数据时代,基于大量数据进行有效的分析和挖掘,建立可视化大屏展示,提供震撼的效果让用户读懂数据,了解数据背后的价值.近几年该类应用场景越来越广泛,软件开发和设计中可视化展示放在越来越重要的位置,在此分 ...
- HTML+CSS+JavaScript+Ajax+ECharts实现疫情实时监控大屏-2设计与实现
疫情期间,各类应用系统.大数据系统为防疫抗疫带来了巨大助力.国家博物馆首次将代码列为藏品,那就是抗击疫情期间来自阿里程序员写的健康码第一行代码以及研发人员的签名.这展现了广大程序员在疫情面前,争当勇敢 ...
- 【25】数据可视化:基于 Echarts + Python Flask框架动态实时大屏范例 - 企业宣传
目录 效果展示 多主题样式 一. 确定需求方案 1.确定产品上线部署的屏幕分辨率 2.部署方式 二.整体架构设计 三.编码实现 (基于篇幅及可读性考虑,此处展示部分关键代码) 1.前端html代码 - ...
- VS code实现前后端交互及大屏可视化(Flask+Mysql+Echarts+HTML+JS+CSS)
@阿乐今天敲代码没 前言 最近老师留了大屏可视化作业,老师讲的模棱两可,在网上又找不到详细的教程,想必好多萌新都跟我一样苦恼,所以在这里记录下,实验工具为VS code.先贴一下我的实验结果图吧,虽然 ...
- HTML+CSS+JavaScript+Ajax+ECharts实现疫情实时监控大屏-1快速上手
1 ECharts简介 ECharts是一款开源的基于JavaScript的数据可视化图表库,可以流畅地运行在PC和移动设备上,兼容当前绝大多数浏览器.它底层依赖矢量图形库ZRender,支持超过1 ...
- 【4】数据可视化:基于 Echarts + Python 实现的动态实时大屏 - 厦门市某医院
目录 精彩案例汇总 效果展示 1.首先看动态效果图 2.再看实时分片数据图 一. 确定需求方案 1.确定产品上线部署的屏幕LED分辨率 2.功能模块 3.部署方式 二.整体架构设计 三.编码实现 (基 ...
- ECharts大屏可视化
文章目录 ECharts大屏可视化 一.项目概述 1.1 项目介绍 1.2 项目架构 1.3 使用环境 二.数据获取 1.获取腾讯数据 1.1数据爬取 1.2数据存储
- 【2】数据可视化:基于 Echarts + Python 实现的动态实时大屏 - 物流大数据
目录 精彩案例汇总 效果展示 一. 确定需求方案 1.确定产品上线部署的屏幕LED分辨率 2.功能模块 3.部署方式 二.整体架构设计 三.编码实现 (基于篇幅及可读性考虑,此处展示部分关键代码) 1 ...
最新文章
- 多重连弹の多层级联 下拉框/查找框级联操作
- 北京内推 | 京东推荐招聘内容推荐研发工程师(2022届校招)
- dart系列之:dart语言中的特殊操作符
- hadoop2.20+hive+sqoop+mysql数据处理案例
- ubuntu20.04屏幕闪烁与分辨率的问题
- git 修改远程仓库源
- Ruby对象、变量和常量
- POJ 3080 Blue Jeans (KMP)
- 在ASP中轻松实现记录集分页显示
- TEncCu::xCheckRDCostMerge2Nx2N
- 自制VBS自动刷屏器,再也不怕刷屏刷不过别人了
- java 输出二进制文件_Java输出小端二进制文件
- 实时 摔倒识别 /运动分析/打架等异常行为识别/控制手势识别等所有行为识别全家桶 原理 + 代码 + 数据+ 模型 开源!
- Unity3D 导入资源
- SOUI控件的自绘和消息处理
- Java封装代码年龄性别姓名_Java生成随机姓名、性别和年龄的实现示例
- 【问题】myeclipse启动时Tocmat错误:cound not create the view :An unexpencted expetion was thrown
- awg线径与电流_AWG_线径电流
- python 零代码快速开发平台_企业如何选择开源的零代码开发平台
- Apache Solr任意文件读取漏洞复现