OpenLayers 6 实现百度echarts风格的“空气质量”散点图

百度的echarts(现在被Apache收编了)所包含的可视化样式非常的丰富多彩,是众多可视化项目必选的框架之一。

 

除了直方图等各种图标之外,echarts也有一些基于地图(当然是百度地图)的可视化功能,还有大神将OpenLayers和echarts结合起来做成了现成的组件供调用。但是在实际使用中,我发现echarts地图应用的交互体验其实并不是很好,图形化数据在地图层之上像是“挂”上去的,在拖动地图的时候,会出现错位:

 

于是我萌生了一个自己实现这个散点图动画效果的想法。通过分析,最终大致上实现了这个散点图(没有做交互功能),并且性能还不错(gif图帧率有点低,实际还要流畅一些):
在这里插入图片描述

 

在这里插入图片描述


分析:

OpenLayers渲染点要素是很容易完成的,但是echarts这个动画的效果不大容易做。
通过观察,发现每个带动画效果的点向外扩散的圈只有三个,总共有5*3=15个圆形渲染的点要素,所以感觉OpenLayers的性能应该跟得上。
OpenLayers官方实例有一个类似的动画效果,是利用render机制实现的,可以拿来借鉴。

实现:

首先准备数据,可以在echarts网站上拷贝出来,这个就不说了。
在这里插入图片描述

然后把基本的地图搭出来,数据读取出来并做一下初步的处理。

import { Map, View } from 'ol';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
import Point from 'ol/geom/Point';
import Feature from 'ol/Feature';
import { fromLonLat } from 'ol/proj';
import { getVectorContext } from 'ol/render';
import {Style, Stroke, Fill, Circle as CircleStyle} from 'ol/style';
import data from './data/scatter.json'
import { easeOut } from 'ol/easing'
 
let tileLayer = new TileLayer({
  source: new OSM()
})
let map = new Map({
  target: 'map',
  layers: [
    tileLayer
  ],
  view: new View({
    center: [11936406.337013, 3786384.633134],
    zoom: 5
  })
});
 
var poi = []
data.data.forEach((item, index) => {
  item.coord = data.coord[item.name]
  poi.push(new Feature(new Point(fromLonLat(item.coord))))
  poi[index].set('name', item.name)
  poi[index].set('value', item.value)
  var bdStyle = new Style({
    image: new CircleStyle({
      fill: new Fill({
        color: [128, 0, 128]
      }),
      radius: item.value / 20
    }),
  })
  poi[index].setStyle(bdStyle)
})
poi.sort(function (a, b) {
  return b.get('value') - a.get('value');
})

这个扩散圆圈的动画不妨来分析一下:如图所示,每一组动画都有3-4个不同半径和透明度的圆环组成,随着时间动态改变半径和透明度这两个属性,形成了“波动”的动画。所以要实现这种效果,需要在同一个点位渲染3-4个这样的圆环,并通过render控制实现关键帧(每一次渲染确定的半径和透明度圆环暂时叫做一个关键帧)的不断变化,最终形成动画效果。
在这里插入图片描述

接着又要祭出render大法了。

首先定义几个全局变量,用于控制动画:

var duration = 2000;
var n=3
var flashGeom=new Array(5*n);

每次动画周期设置为2秒,然后扩散圆的数量为3个一组,声明一个5*n大小的数组,准备用于存放渲染扩散圆的要素。虽然很明显同一组的3个扩散圆是同一个要素,但是为了方便记录关键帧每一轮的开始时间,每一个扩散圆都用一个要素来表示,通过要素的自定义属性来记录关键帧每一轮开始渲染的时间。

更多请见:http://www.mark-to-win.com/tutorial/175099.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用 echartsopenlayers 分别实现热力图,下面分别介绍一下具体的方法: 1. echarts 实现热力图 使用 echarts 实现热力图需要使用 echarts 的插件 echarts-gl,通过 echarts-gl 可以使用 WebGL 技术绘制更加复杂的图表,包括热力图。 具体步骤如下: (1)安装 echarts-gl 插件: ``` npm install echarts-gl --save ``` (2)引入 echartsecharts-gl: ```html <script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/echarts-gl/dist/echarts-gl.min.js"></script> ``` (3)创建一个包含地图的 div 容器和一个 echarts 实例: ```html <div id="map" style="width: 100%; height: 600px;"></div> <script type="text/javascript"> var myChart = echarts.init(document.getElementById('map')); </script> ``` (4)配置 echarts 实例,包括地图类型、地图数据和热力图数据: ```javascript option = { tooltip: {}, visualMap: { min: 0, max: 500, calculable: true, inRange: { color: ['#50a3ba', '#eac736', '#d94e5d'] } }, geo: { map: 'world', roam: true }, series: [{ type: 'heatmap', coordinateSystem: 'geo', data: [ {name: 'Afghanistan', value: 283.54}, {name: 'Albania', value: 198.28}, {name: 'Algeria', value: 200.20}, // ... 省略部分数据 ] }] }; myChart.setOption(option); ``` 2. openlayers 实现热力图 使用 openlayers 实现热力图需要使用第三方库 ol-heatmap,ol-heatmap 是一个基于 openlayers 的热力图插件。 具体步骤如下: (1)安装 ol-heatmap: ``` npm install ol-heatmap --save ``` (2)引入 openlayers 和 ol-heatmap: ```html <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol/dist/ol.css" type="text/css"> <script src="https://cdn.jsdelivr.net/npm/ol/dist/ol.js"></script> <script src="https://cdn.jsdelivr.net/npm/ol-heatmap/ol-heatmap.js"></script> ``` (3)创建一个包含地图的 div 容器和一个 openlayers 实例: ```html <div id="map" style="width: 100%; height: 600px;"></div> <script type="text/javascript"> var map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: [0, 0], zoom: 2 }) }); </script> ``` (4)创建一个热力图层并添加到 openlayers 实例中: ```javascript var heatmapLayer = new ol.layer.Heatmap({ source: new ol.source.Vector({ url: 'data.json', format: new ol.format.GeoJSON() }), blur: 15, radius: 5, opacity: 0.8 }); map.addLayer(heatmapLayer); ``` 其中,data.json 是包含热力图数据的 GeoJSON 格式文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值