在前面的博客中已經介紹了如何繪制地區分布圖,這一節學習如何繪制交互式過濾地區分布圖。如果對繪制地區分布圖還不熟悉的話可以了解一下之前我寫的博客:數據可視化【十三】地區分布圖
整體的框架仍然是在之前的基礎上進行修改,主要是添加交互事件。
首先要做的是給圖例添加點擊事件,讓我們可以通過點擊改變地圖的狀態。
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
效果圖
這個是可以進行交互的,我把代碼放在了自己的服務器上,如果有興趣可以訪問:傳送門
需要注意的是盡量使用火狐或者谷歌瀏覽器訪問,文件稍微有點大,加載可能需要一些時間。