一、效果展示
二、需求解读
- 分辨率自适应
- 左右框内标题及内容都可动态配置
- 同时包括地图热力图与地图线图
- 出发点添加涟漪动画
- markPoint根据数据不同动态展示是否高亮
- 热力图颜色数值范围由返回数据动态控制
三、难点分析
series.type
为lines
或effectScatter
显示的前提为geo
属性有值,而展示热力图却需要series.type
为map
,就涉及到geo
与map
两属性重叠与z轴level问题- 线图需要准确知道起点与终点坐标,若边框、标题和边框内元素都脱离在canvas画布外会导致无法准确定位,分辨率变化后出现偏差的情况
- 同起点和终点,同类型的线分散,导致线图错乱
四、难点解决方案
geo
属性在上层,但地图item
颜色为透明,即可不遮挡map
的同时又使lines
和effectScatter
位于canvas最上层- 将边框、标题和边框内元素都以
markPoint
的方式在map
的海上打标定点,并根据markPoint
的透明度来控制是否高亮 - 将同起点、终点和同类型的线进行贝塞尔曲线曲率的统一,对于同起点、终点,不同类型的线做贝塞尔曲线曲率的差异化
五、流图所使用Echarts的API
1. 绘制热力图图例(visualMap)
visualMap
是视觉映射组件,用于进行『视觉编码』,也就是将数据映射到视觉元素(视觉通道)。
visualMap
- 为了均分三段颜色,需要进行步长计算,并赋值给
pieces
属性
// 步长为最大值除3取整
let step = Math.floor(max / 3);
// 设置visualMap属性
visualMap: {
type: 'piecewise',// 类型为分段型
splitNumber: 3,// 自动平均切分成3段
pieces: [
{
min: 1,
max: step,
color: '#71bffe'// 自定义颜色一
},
{
min: step,
max: 2 * step,
color: '#437dd4'// 自定义颜色二
},
{
min: 2 * step,
max: 3 * step,
color: '#285395'// 自定义颜色三
}
]
};
2. 绘制地图坐标系(geo)
地理坐标系组件用于地图的绘制,支持在地理坐标系上绘制散点图、线集。
geo
- 为了绘制带有涟漪特效动画的散点,需提前建立地图坐标系
geo: {
map: 'world',
nameMap: worldNameMap, // 地图名称映射表
zlevel: 3, // 与map叠加,处于垂直的第三层级
}
3. 绘制流向线条(series-lines)
用于带有起点和终点信息的线数据的绘制,主要用于地图上的航线,路线的可视化。
series-lines
- 为了使线条流畅、分布均匀,设置贝塞尔二次曲线的曲度
const curvenessMap = {
1: 0.1,
2: 0.1,
3: -0.1,
4: 0.2,
5: -0.2,
6: 0.3,
7: -0.3,
8: 0.4,
9: -0.4,
10: 0.5,
11: 0.01
};
lineStyle: {
curveness: curvenessMap[index] // 自定义贝塞尔二次曲线曲度
}
- 绘制线条
series: {
type: "lines",
coordinateSystem: "geo",
zlevel: 4, // 处于垂直的最高层级
data: linesData,
effect: {
show: true,
constantSpeed: 50,
symbol: "arrow", // 箭头
symbolSize: 10,
trailLength: 0,
}
}
4. 绘制涟漪状散点(series-effectScatter)
带有涟漪特效动画的散点(气泡)图。利用动画特效可以将某些想要突出的数据进行视觉突出。
ECharts 2.x 中在地图上通过 markPoint 实现地图特效在 ECharts 3 中建议通过地理坐标系上的 effectScatter 实现。
series-effectScatter
- 已提前在第2点中建立地图坐标系,可直接绘制
{
type: 'effectScatter',
coordinateSystem: 'geo',
zlevel: 4,
symbol: 'circle',
symbolSize: nowSize(7),
data: scatterData,
}
5. 绘制热力图(series-map)
地图主要用于地理区域数据的可视化,配合 visualMap 组件用于展示不同区域的人口分布密度等数据。
series-map
- 绘制地图数据
worldNameMap.js
{
zlevel: 2, //层级位于地图坐标系之下,不遮挡
type: "map",
map: "world",
nameMap: worldNameMap,
data: mapData,
}
6. 绘制模块及模块内节点(series-map.markPoint)
图表标注。
series-map.markPoint
- 为了连线的准确性,将元素使用markPoint绘制在海上,即地图主体的空白区域
{
tooltip: {
show: false,
},
coord: item,
// mapBorder为图片地址
symbol: "image://" + mapBorder,
// 指定坐标
coord: TEXT_COORD_LIST[i],
itemStyle: {
opacity: 1
},
}
六、注意事项
- 由于有双地图(geo和series-map)的叠加,所以不允许移动或缩放
- 数据需经过处理之后再赋值给data
- 动态绘制贝塞尔曲线也需要经过一系列的计算,以source-target为一组,作为key
- 需要抽取多个函数确保逻辑清晰,各司其职