可視化實驗2——用D3做圖表
D3相對來Echarts來說,是比較難的。因爲Echarts有專門的各種圖表的模板,到時候只要在代碼中添加某個圖表,然後修改數據內容即可。但是D3則所有的東西都得是自己寫,座標軸啦、圖表啦等都得自己畫。但這也體現了D3的充分可創造性,沒有做不到,只有想不到。。。
不過有一點要注意,若使用到json地圖數據的話,得用火狐瀏覽器打開才行,其它的不支持。。。
1 學習D3
首先是安裝D3,參見D3的安裝
下面提供幾個網站鏈接:
D3.js的官網(英文)
D3.js API中文手冊 (雖說是中文,但也只是用中文大概介紹了函數的功能,鏈接的網頁還是官網的英文。。。)
Our D3.js 中文教程網站
官網上有推薦的幾個學習D3的博客,不過除了上面一個,其餘都是英文的,給個鏈接吧,英語大神的話可以看看,見網頁中的blog欄目:
D3.js教程
2 實驗目的
就是利用全國人口普查的數據(人口、GDP、人均GDP),用適當的圖表展現出來。我主要做了3個,一個是地圖(是耗費我最大時間精力的圖表,不過也在這中間學到了很多,具體原因後面會說),二是柱形圖(參見Our D3.js 中文教程網站 中的柱形圖講解),三是散點圖(參見Our D3.js 中文教程網站 中的作品集demo)
3 地圖+柱形圖實現
地圖的用法見Our D3.js 中文教程網站中的學習教程,如何在地圖上加上柱形圖的話,我主要是參考D3官網中的一個example,要註冊登陸才能查看源代碼,請見
Medical Cost of Hip Replacement by State
但是該demo不能直接copy下來就可以,只能在網頁上參考。。。所以費了我很大精力去研究它。
下面是我遇到的一些問題。
3.1如何將柱形圖顯示在地圖上:
原本:柱形顯示在地圖下的代碼
svg.selectAll("path")
.data
demo的:
g.append("g")
.attr("id", "states")
.selectAll("path")
.data
看見了沒,參考的demo是用的g.append("g").selectAll("path"),所以纔將柱形圖顯示在地圖上面,而不是直接svg.selectAll("path")
3.2如何存儲centroid的值一遍後來方便獲取?
先定義個數組
var p_centroid={}
然後,如下面代碼。
g.append("g")
.selectAll("path")
.data( root.features )
.enter()
.append("path")
.attr("d", path )
.attr("stroke","#000")
.attr("stroke-width",1)
.attr("fill", function(d,i){
return color(i);
})
//增添中心
.attr("centroid", function(d) {
var centroid = path.centroid(d);
p_centroid[d.properties.name]=centroid;
//用下面的代碼調試出來T^T的...一開始輸出d.name,沒有內容。。。後來改爲d.properties,爲[Object Object],恍然大悟
//var body = d3.select("body");
//var new_h1 = body.select("h1");
//new_h1.text(d.properties.name);
})
這裏遇到了個比較大的問題,那就是如何存儲各省份的中心座標centroid值。
本來想用省份的名稱作爲索引,但一開始的時候怎麼都不行。後來想了一個debug的辦法(沒辦法, 用notepad++寫html,又不能debug,只能一個一個試),那就是在html中增加一個
<h1>This is debug <h1>//用於顯示文本
然後在function中輸入下面幾行code(即上面代碼中注視的部分)
var body = d3.select("body");
var new_h1 = body.select("h1");
new_h1.text(d.properties.name);
一開始的時候,嘗試輸出d.name,結果刷新網頁後什麼都沒有顯示。後來參照地圖json文件,輸出d.properties,發現內容是[Object Object]。這下恍然大悟,改成d.properties.name,出現了省份的名字!然後就用d.properties.name作爲索引了
4 截圖和代碼
這裏附上幾張截圖吧,另外附上代碼的下載地址: