在前面的博客中已经介绍了如何绘制地区分布图,这一节学习如何绘制交互式过滤地区分布图。如果对绘制地区分布图还不熟悉的话可以了解一下之前我写的博客:数据可视化【十三】地区分布图
整体的框架仍然是在之前的基础上进行修改,主要是添加交互事件。
首先要做的是给图例添加点击事件,让我们可以通过点击改变地图的状态。
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
效果图
这个是可以进行交互的,我把代码放在了自己的服务器上,如果有兴趣可以访问:传送门
需要注意的是尽量使用火狐或者谷歌浏览器访问,文件稍微有点大,加载可能需要一些时间。