数据可视化【十三】地区分布图
在前面的博客中已經(jīng)介紹了如何繪制地圖,這一節(jié)學(xué)習(xí)如何繪制地區(qū)分布圖。如果對(duì)繪制地圖還不熟悉的話可以了解一下之前我寫的博客:數(shù)據(jù)可視化【十】繪制地圖
Intergrating(整合) TopoJSON with tabular data(列表數(shù)據(jù))
在前面的博客中沒有使用到tsv文件,因?yàn)槲艺业降腡opoJSON中本來就包含國(guó)家的名字。但是如果想要知道國(guó)家更多的數(shù)據(jù)僅僅知道國(guó)家的名字是不夠的,因此還需要導(dǎo)入關(guān)于國(guó)家其他數(shù)據(jù)的tsv文件。當(dāng)導(dǎo)入多個(gè)文件的時(shí)候最好使用Promis.all,這樣就可以在文件全部都加載后再開始執(zhí)行。需要將多個(gè)任務(wù)都放在一個(gè)數(shù)組里面,然后再在then中用一個(gè)數(shù)組接收讀入的數(shù)據(jù)。
Promise.all([tsv('https://unpkg.com/world-atlas@1.1.4/world/50m.tsv'),json('https://cdn.jsdelivr.net/npm/world-atlas@2.0.2/countries-50m.json') ]).then(([tsvData, topsJSONdata]) => {}為了快速處理tsv文件,我們使用reduce函數(shù)將其放到一個(gè)類中。其中iso_n3與JSON文件中的id對(duì)應(yīng)
const rowById = tsvData.reduce((accumulator, d)=>{accumulator[d.iso_n3] = d;return accumulator;}, {});//前面是reduce的執(zhí)行,后面是accumulator的初始值為了使得JSON文件中的每個(gè)元素都包含這個(gè)國(guó)家更多的信息,我們使用assign函數(shù)將同一個(gè)國(guó)家的信息進(jìn)行合并
const countries = feature(topsJSONdata, topsJSONdata.objects.countries);// console.log(countries);countries.features.forEach(d => {Object.assign(d.properties, rowById[d.id]);});Creating a loadAndProcessData module
上面載入數(shù)據(jù)的過程其實(shí)可以當(dāng)作另一個(gè)模塊,因此我們把上面的代碼單獨(dú)放在一個(gè)用于加載數(shù)據(jù)的文件中
loadAndProcessData.js
并在index.js中將相應(yīng)的代碼都放在loadAndProcessData函數(shù)的then中
Visualizing an ordered attribute with color
在得到國(guó)家的其他屬性之后,我們就可以根據(jù)國(guó)家的其他標(biāo)簽給國(guó)家上色
我們可以首先觀察一下tsv文件中都有什么。太多了這里就不顯示了,比如說里面有一個(gè)標(biāo)簽是經(jīng)濟(jì),我們不妨使用經(jīng)濟(jì)給不同國(guó)家不同的顏色。
為了方便修改標(biāo)簽,我們把獲取數(shù)據(jù)屬性的操作放到一個(gè)函數(shù)里,并且在后面所有的地方都通過這個(gè)函數(shù)獲取屬性,這樣做的好處是如果我們不想要這個(gè)標(biāo)簽,我們只需要在這一個(gè)地方進(jìn)行修改就可以。
我們使用scaleOrdinal來得到從標(biāo)簽到顏色的映射,對(duì)于標(biāo)簽我們需要進(jìn)行一定的排序處理,而顏色區(qū)間d3有現(xiàn)成的函數(shù)可以讓我們很方便的得到漸變的顏色從而區(qū)分不同的等級(jí)。
我們可以搜索d3-scale-chromatic,里面有很多函數(shù)。在這里我們選擇schemeSpectral[k],這個(gè)k是標(biāo)簽分類的個(gè)數(shù),我們可以直接得到:
const colorValue = d => d.properties.income_grpconst colorScale = scaleOrdinal().domain(countries.features.map(colorValue));colorScale.domain(colorScale.domain().sort().reverse()).range(schemeSpectral[colorScale.domain().length]);制作好顏色標(biāo)簽以后就是在添加path的后面設(shè)置fill屬性,我之前做的是隨機(jī)選擇一個(gè)顏色,這里就改為根據(jù)上面已經(jīng)設(shè)置好的顏色尺得到對(duì)應(yīng)的顏色。
Showing data from 2 attributes in tooltip
在得到好看的顏色以后,我們還希望對(duì)應(yīng)的標(biāo)簽的內(nèi)容可以改變,這一點(diǎn)很容易再到,只需要在設(shè)置text的時(shí)候加上對(duì)應(yīng)的屬性即可。
g.selectAll('path').data(countries.features).enter().append('path').attr('class', 'country').attr('fill', d => colorScale(colorValue(d))) .attr('d', pathGenerator) .append('title')//添加title,然后鼠標(biāo)放在上面就可以出現(xiàn)標(biāo)題.text(d => d.properties.name + ':' + colorValue(d));初步效果圖如下:
Adding a color legend
我們還希望添加一個(gè)顏色圖例,這樣就可以很方便地知道什么顏色對(duì)應(yīng)的是什么內(nèi)容而不必要一一去看。根據(jù)上一節(jié)(數(shù)據(jù)可視化【十二】顏色圖例和尺寸圖例)我們制作的顏色圖例,可以直接進(jìn)行使用。
index.js
在colorLegend.js中,圖例有一個(gè)背景,通過添加一個(gè)矩形來實(shí)現(xiàn)
const backgroundRect = selection.selectAll('rect').data([null]);const n = colorScale.domain().length;backgroundRect.enter().append('rect').merge(backgroundRect).attr('x', -circleRadius * 2).attr('y', -circleRadius * 2).attr('rx', circleRadius * 2).attr('width', backgroundRectWidth).attr('height', spacing * n + circleRadius * 3).attr('fill', 'white').attr('opacity', 0.8);最后效果圖:
代碼地址:https://vizhub.com/Edward-Elric233/635845fd4c8b4917b999b18cab5e9b09
總結(jié)
以上是生活随笔為你收集整理的数据可视化【十三】地区分布图的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据可视化【十二】 颜色图例和尺寸图例
- 下一篇: 女人的村庄剧情介绍