在前面的博客中已经介绍了如何绘制地区分布图,这一节学习如何绘制交互式过滤地区分布图。如果对绘制地区分布图还不熟悉的话可以了解一下之前我写的博客:数据可视化【十三】地区分布图
整体的框架仍然是在之前的基础上进行修改,主要是添加交互事件。
首先要做的是给图例添加点击事件,让我们可以通过点击改变地图的状态。
colorLegend.js
const groupEnter = groups.enter().append('g')
.attr('class', 'tick')
.attr('transform', (d,i) =>
`translate(0, ${i*spacing+circleRadius})`)
.merge(groups)
.attr('opacity', d => typeof(selected) === 'undefined' || d === selected ? 1 : 0.2)
.on('click',onClick)
然后通过onClick
函数获得点击的状态,进行相应的修改
index.js
const onClick = d => {
console.log(d);
selected = d === selected ? undefined : d;
if (selected)
bg.attr('opacity', 0.5)
else
bg.attr('opacity', 1)
render();
}
上面的bg
是背景的海洋,如果确定是点击状态的话就将其设置为透明的,并记录当前的状态,然后进行操作。这里把对地图的操作都放到了render
函数里面
把图例的绘制和地图的绘制分别放在对应的函数里,我这里是按照视频分别放在了choroplethMap
函数和colorLegend
函数,然后再进行调用。
然后再根据不同的更新模式(update
、enter
)修改地图的状态(通过设置属性就可以)
const projection = geoEqualEarth();
const pathGenerator = geoPath().projection(projection);
export const choroplethMap = (selection, props) => {
const {
features,
svg,
colorScale,
colorValue,
selected
} = props;
console.log('choroplethMap.js');
console.log(features);
svg.call(zoom()
.on('zoom',() => {
selection.attr('transform',event.transform);
}));
const pathUpdate = selection.selectAll('.country').data(features);
const pathEnter = pathUpdate
.enter().append('path')
.attr('class', 'country')
.attr('fill', d => colorScale(colorValue(d)))
.attr('d', pathGenerator)
.attr('stroke-width', 0.05)
pathEnter.merge(pathUpdate)
.attr('opacity',d => !selected || colorValue(d) == selected ? 1: 0.1)
.attr('stroke-width', d => selected && colorValue(d) == selected ? 1: 0.05);
pathEnter.append('title')//添加title,然后鼠标放在上面就可以出现标题
.text(d => d.properties.name + ':' + colorValue(d))
}
上面的代码和视频中讲解的出入比较多,我个人觉得curran讲这个视频的时候对更新模式的理解有一些偏颇,因此他视频里面的逻辑稍微有点混乱,他的想法是每次点击都重新进行绘制,可是这完全是不必要的,我们需要对点击后的操作在update.merge(enter)
里面进行就可以了,不用动初始化的部分。
代码地址:https://vizhub.com/Edward-Elric233/157b7264849e4dc19365b445d949b775?edit=files&file=choroplethMap.js
效果图
这个是可以进行交互的,我把代码放在了自己的服务器上,如果有兴趣可以访问:传送门
需要注意的是尽量使用火狐或者谷歌浏览器访问,文件稍微有点大,加载可能需要一些时间。