这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战
简介
在开发地图可视化页面时,产品想在城市的对应位置展示一个统计图。这时候先不要慌,大声的说你是在哪抄的这个需求。好看到页面了,就没有前端人不会(抄的)开发的。研究后发现使用的是,百度地图api自定义了ECharts覆盖物。
覆盖物
- 在百度地图中所有的覆盖物都继承
Overlay,所以我们通过继承基类实现自定义覆盖物。
initialize(),用于初始化覆盖物,当调用map.addOverlay时,API将调用此方法。draw(),当地图状态发生变化时,由系统调用对覆盖物进行绘制。show(),显示覆盖物。hide(),隐藏覆盖物。MapPanes,此类表示地图上所有覆盖物的容器集合,没有构造函数,通过对象字面量形式表示。通过Map的getPanes方法可获得该对象实例。自定义的覆盖物都要放入才能其中展示。
加载地图
- 通过
<script>标签引入地图api地址和echarts地址,这里的ak是你在地图服务中心注册的。不了解的可以点 这里
<!-- echarts -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
<!-- 百度 -->
<script src="https://api.map.baidu.com/api?type=webgl&v=1.0&ak=?"></script>
<script>
// 百度地图API功能
var map = new BMapGL.Map('bmap') // 创建Map实例
// 初始化地图,设置中心点坐标和地图级别
map.centerAndZoom(new BMapGL.Point(121.480509, 31.23592), 10)
// 启用 鼠标滚轮事件
map.enableScrollWheelZoom()
</script>
自定义ECharts覆盖物
- 创建一个新的函数继承
Overlay,通过initialize()和draw()函数的调用机制来实现自定义覆盖物。
/**
* @param width 节点宽
* @param height 节点高
* @param pot 地图点坐标
* @param callback 回调 加载echarts
* */
function echartsOverlay(width, height, pot, callback) {
this._width = width || 100
this._height = height || 100
this._pot = pot
this._callback = callback
}
// 继承Overlay基类
echartsOverlay.prototype = new BMapGL.Overlay()
echartsOverlay.prototype.initialize = function (map) {
this._map = map
// DOM节点
this._div = document.createElement('div')
this._div.style.zIndex = 1
this._div.style.width = this._width + 'px'
this._div.style.height = this._height + 'px'
this._div.style.position = 'absolute'
// 将该覆盖物添加到标签覆盖物列表
map.getPanes().labelPane.appendChild(this._div)
// 传入 dom节点 用于绘制echarts
this._callback(this._div)
return this._div
}
echartsOverlay.prototype.draw = function () {
// pointToOverlayPixel() 根据地理坐标获取对应的覆盖物容器的坐标
let rel_xy = this._map.pointToOverlayPixel(this._pot)
// 覆盖物中点 为坐标点
this._div.style.left = rel_xy.x - this._width / 2 + 'px'
this._div.style.top = rel_xy.y - this._height / 2 + 'px'
}
- 创建的元素节点需要使用
'absolute'定位。 - 定位的
left、top参数需要在draw()函数中。当地图放大、缩小,坐标都需要重新计算。 - 使用回调函数的方式,返回
DOM节点用于ECharts绘图。
添加echarts
var drawChart = function (obj) {
var chartTem = echarts.init(obj)
var option = {
tooltip: {
trigger: 'axis'
},
radar: [
{
indicator: [
{ text: '品牌', max: 100 },
{ text: '内容', max: 100 },
{ text: '可用性', max: 100 },
{ text: '功能', max: 100 }
],
center: ['50%', '50%'],
radius: 60,
splitArea: {
areaStyle: {
color: ['#77EADF'],
shadowColor: 'rgba(0, 0, 0, 0.2)',
shadowBlur: 10
}
},
name: {
formatter: '【{value}】',
textStyle: {
color: '#DC143C'
}
}
}
],
series: [
{
type: 'radar',
tooltip: {
trigger: 'item'
},
areaStyle: {},
data: [
{
value: [60, 73, 85, 40],
name: '某软件'
}
]
}
]
}
chartTem.setOption(option)
}
- 这里和平时使用
echarts开发是一样的。文章最后有echarts 示例,不会的同学可以去看看。 - 不是所有的统计都适合在地图上展示,个人认为饼图和雷达图在地图上展示效果是最好的。
调用
var myCompOverlay = new echartsOverlay(250, 250, new BMapGL.Point(121.480509, 31.23592), drawChart)
map.addOverlay(myCompOverlay)
- 使用这种方式加载
ECharts有个很大的问题,就是生成的统计图大小是固定的,不会随地图变化而变化。基于这种情况ECharts也出了解决方案bmap.min.js。