今天我們將會領略到D3.js最爲強大的layout系列可視化的威力。
最終demo:http://jsfiddle.net/U2aCS/
這一次的demo見http://jsfiddle.net/AXJf3/
Chord(弦圖)是非常美觀漂亮的可視化圖表,源自http://mkweb.bcgsc.ca/circos/ 在網站上可以找到大量漂亮的可視化圖表案例。
主要用在表格數據的可視化,表達多個節點間的連結關係。在開始使用d3js時,先認識下弦圖吧!
使用弦圖進行表格數據可視化
不同粗細的連接可以表達關係的程度或者量級
<a href="http://www.d3js.cn/wp-content/uploads/2013/04/3.png" class="cboxElement" rel="example4" 12574"="" style="text-decoration: none; color: rgb(1, 150, 227); ">
當連接的着色不同時我們可以很容易的區分出來,尤其是當連接具有方向時。
假如我們有這樣一份數據 可以表達爲a,b=2 b,a=10。對於 a,b =2 這個關係來說,a爲行,b爲列
b | a | |
a | 2 | |
b | 10 |
在弦圖中可以利用一根條帶來表達這個關係(右圖)。注意這根條帶連接了a,b ,連接了行列元素,且行列元素的端點粗細不同。那麼如何去確定這個粗細呢?大家可以記住,某一端的粗細,對應的是行元素。比如a-b 爲2 上表中 a爲行元素,因此a那一端的線條粗細程度爲2. b-a爲10 b爲行元素,因此b那一端的線條粗細程度爲10. 理解這個很重要。
這裏還有個細節問題。上圖的表格中 a:d是2 剛纔我們也講到 a那一端的線條寬度是2.但是當我們不需要表達d a關係時 可以在條帶與d接觸的地方留個空白。
以上的講解來源於 http://mkweb.bcgsc.ca/circos/guide/tables/ 我簡單的翻譯了一下。ok那麼我們回到d3
layout是幹嘛的
在可視化繪製中,graphic drawing一直是非常令人頭疼的問題,裏面牽扯到很多的算法,對於我這樣數學基礎不好的人簡直是折磨。
而d3.js提供了很多現成的layout,通過調用layout,可以生成排列好的圖形,之後我們進行進一步加工就可以了。比如羣集(Cluster)圖,弦(chord)圖,樹圖,force(引力)圖 等等,每個layout都有自己獨特的屬性,與圖形本身相關,但是使用方法類似。
現在我們開始可視化繪製!除了使用layout之外,這一次我們也會使用一個核心api arc畫圓。
測試數據
var matrix = [ [11975, 5871, 8916, 2868], [ 1951, 10048, 2060, 6171], [ 8010, 16145, 8090, 8045], [ 1013, 990, 940, 6907] ];
繪製之前我們先觀察一下最終想要的效果。
最外層有個圓環,上面有刻度。而圓環被數據分爲了好幾個部分。圓環與圓環之間通過條帶連接,且顏色不同。圓環我們可以使用d3的arc方法繪製,而刻度我們之前也用tick配合text繪製過。最重要的就是對圓環的分隔以及條帶了,而這正是chord的layout可以提供給我們的。
首先呢建立容器
var width = 960, height = 500, innerRadius = Math.min(width, height) * .41, outerRadius = innerRadius * 1.1; var fill =["#000000", "#FFDD89", "#957244", "#F26223"];//顏色數組 var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");//偏移一下
這裏注意 innerRadius跟outerRadius是爲了配合我們的arc方法來使用的。
d3.svg.arc()
使用innerRadius-, outerRadius-, startAngle- 與endAngle-來繪製環形。注意這四個值都可以是動態的。
事實上這個api可以繪製四種圖形: circle (圓形,當角度>2π且innerradius爲0時), circular sector (扇形,當角度<2π且innerradius爲0時), annulus (環形,innerRadius不爲0,且角度>=2π),當然也有環形的一部分。
fill是我們準備好的一些顏色。
之後我們需要給圓形留空間,因爲圓形繪製的時候是以原點爲中心繪製的,而我們的圖形原點現在在左上角,所以會出現一個問題就是左邊跟上邊的圖表部分會看不到。因此我們使用translate屬性來位移一下即可。
之後我們使用chord這個layout來構建圖形
var chord = d3.layout.chord() .padding(.05) .sortSubgroups(d3.descending) .matrix(matrix);
每個layout提供不同的方法。在chord中提供了一些方法,參考 https://github.com/mbostock/d3/wiki/Chord-Layout
sortSubgroups 傳入一個function,這個function規定了每一行中的元素的排列順序。同樣也有sortGroups 這個是規定行的排列順序。
大家可以回憶下chord的特徵,端點都在行元素上。
matrix也是核心方法,很類似data()這個方法,可以給chord綁定數據,並根據數據進行分割。padding是圓環上每個部分之間的距離。
chord使用後可以返回兩個東東:chord.groups跟chord.chords,這兩個是幹什麼用的,我們可以看看。
svg.append("g").selectAll("path") .data(chord.groups) .enter().append("path") .style("fill", function(d) { return fill[d.index] }) .style("stroke", function(d) { return fill[d.index]; }) .attr("d", d3.svg.arc().innerRadius(innerRadius).outerRadius(outerRadius))
這裏selectAll跟data,enter的組合想必大家不會陌生了,就是造小房子,不明白的可以去看第一篇教程。通過chord.groups可以把圓環按照數據分組。效果如下: