1. 程式人生 > >使用D3.js進行資料視覺化

使用D3.js進行資料視覺化

樓主最近在做一個將特定圖結構的資料進行視覺化的專案,用到了前段視覺化庫D3.js,在這裡分享一下學習心得。

QuickStart

<html>
<title></title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<style >
    div.bar {
        display: inline-block;
        width: 20px;
        height: 75px; /* 後面會覆蓋這個高度 */
        background-color
: teal
; margin : 3px; }
</style> <body> <script type="text/javascript"> var dataset = [ 25, 7, 5, 26, 11 ]; d3.select("body").selectAll("div")//元素選擇 .data(dataset) // 資料繫結 .enter() // 返回佔位物件 .append("div"
) //追加元素 .attr("class", "bar") //設定DOM屬性 .style("height", function(d) { var barHeight = d * 5; return barHeight + "px"; }); //設定CSS屬性
</script> </body> </html>

D3例子

  1. D3庫的引用。開頭使用<script src = ""> 引用該視覺化庫,地址可以是官方伺服器提供的版本,也可以把庫下載下來,使用本地化路徑。
  2. 元素選擇。D3支援CSS3的選擇器語法,可通過tag、class、id等屬性對元素進行選擇。
  3. 資料繫結。 D3的基礎原理是將頁面中的視覺化元素,如段落,層(html元素),圓、路徑、線段(SVG元素)與真實資料進行繫結,data方法就是用來繫結元素和資料,該方法會迴圈遍歷資料集中的每一個數據。
  4. enter 為每個待繫結的資料生成一個佔位符物件(頁面元素),後續可以操作這些物件生成具體的視覺化元素。
  5. append方法向一個Dom元素中新增物件,這裡頁面原本一個DIV層都沒有,但是先取得佔位符物件(包含對應資料),然後通過新增DIV層,並使用attr和style方法設定該DIV的高度,從而在最後的頁面上顯示出一幅條形圖

常用函式

元素選擇

d3.select(selector)

選中與指定選擇器字串匹配的第一個元素,返回單元素選擇結果。如果當前文件中沒有匹配的元素則返回空的選擇。如果有多個元素被選中,只有第一個匹配的元素(在文件遍歷次序中)被選中。

d3.select(node)

選擇並返回指定的節點。

d3.selectAll(selector)

選中匹配指定選擇器的所有的元素。這些元素會按照文件的遍歷順序(從上到下)選擇。如果當前文件中沒有匹配的元素則返回空的選擇。

d3.selectAll(nodes)

選擇指定的元素陣列。如果你已經有了一些元素的引用這將是很有用的,例如事件監聽器中的d3.selectAll(this.childNodes),或者一個全域性物件例如document.links。

需要指出的是,d3.select和d3.selectAll將預設查詢整個文件,但是selection.select和selection.selectAll則只在當前selection範圍裡查詢
D3的函式使用也支援連綴用法,多個函式連用時,前一個函式的返回值將作為下一個函式的呼叫主體,例如d3.select("body").selectAll("div"),首先選擇了頁面中的body元素,然後呼叫body.selectAll來選擇body範圍中的所有div元素。

元素修改

selection.attr(name[, value])

用來設定選中元素的屬性並返回該selection。
如果引數是name,value鍵值對形式,則會將selection中的元素的name屬性的值設定成value,如果value是常數,那麼seletion中所有的元素都將設定成相同的值,如果value是函式的形式,那麼這個函式將會獲得引數當前元素d和當前元素在集合中的索引作為引數,函式的返回值用來設定每個元素的name屬性。如果是name的形式,則將返回該集合中元素中name屬性的值。

function中可獲得全部引數有:
being passed the current datum (d), the current index (i), and the current group (nodes), with this as the current DOM element.

selection.classed(names[, value])

用來設定選中元素的class屬性並返回該selection。
name指定想設定的class名稱,value為true表示新增該class屬性,為false表示不分配該class屬性,用法與上面類似。但是如何刪除已有的class屬性?

selection.classed("foo", function() { return Math.random() > 0.5; });
selection.classed("foo bar", true);//同時新增foo和bar屬性

selection.style(name[, value])

使用設定選中元素的css屬性並返回該seletion

p.style("width","90px") = <p style="width:90px">

selection.text([value])

設定選中元素的文字內容。
如果value不為空,則用該value替代選中元素所有的子元素並返回該元素。value為空,則返回該selection中第一個文字內容非空的元素的text content

selection.append(type)

用來給選中的元素擴充套件子節點並返回更新後的selection,type可以是string也可以是function。
If the specified type is a string, appends a new element of this type (tag name) as the last child of each selected element, or the next following sibling in the update selection if this is an enter selection.

例如,給段落新增div層,可以寫成下面形式:
d3.selectAll("p").append("div");

d3.selectAll("p").append(function() {
  return document.createElement("div");
});

d3.selectAll("p").select(function() {
  return this.appendChild(document.createElement("div"));
});

資料繫結

selection.data([data[, key]])

將指定的資料集data和選擇的元素集selection進行繫結,並返回更新後的資料集(繫結的資料將存放在元素的_data_屬性中),並同時在返回的selection基礎上定義了enter selection和exit selection的範圍
,enter和exit將在下面介紹。指定的data可是是一組任意的資料,數字或者物件。

繫結的順序由函式key來決定,如果key為空,則繫結順序為預設按照索引來,即第一個元素繫結到第一個資料,第二個元素繫結到第二個資料,可以通過指定key函式來設定不同的元素繫結順序。
注意:selection中元素的個數和data資料集中個數並不總是一一對應,可能會出現元素個數較少或者資料集個數較少的情況,為了使元素和資料一一對應,便有了enter 和 exit方法。

selection.enter()

Returns the enter selection: placeholder nodes for each datum that had no corresponding DOM element in the selection
為selection繫結的資料集中,尚未繫結dom元素的資料建立dom佔位符結點。如果一個selection為空,但它綁定了一個數據集,那麼enter方法將為這些資料集中的每一個數據建立一個佔位符結點放到selection中,後續的dom操作可以使用該佔位符結點。

例子:從陣列中建立div層
js程式碼
var div = d3.select("body")
  .selectAll("div")
  .data([4, 8, 15, 16, 23, 42])
  .enter().append("div")
    .text(function(d) { return d; });
html效果
<div>4</div>
<div>8</div>
<div>15</div>
<div>16</div>
<div>23</div>
<div>42</div>

selection.exit()

Returns the exit selection: existing DOM elements in the selection for which no new datum was found
選中元素集中存在一些dom元素,沒有資料與之繫結,這個方法就將這些元素返回。

enter和exit結合使用,可以很方便的再資料集更新後,快速更新與該資料集繫結的元素集合。例如:

上例中div已經繫結元素[4, 8, 15, 16, 23, 42],此時該資料集發生變化如下,需要重新繫結:

div = div.data([1, 2, 4, 8, 16, 32], function(d) { return d; });

這時,enter selection中的元素是為了與1 2 32 這些新資料繫結而產生的佔位符結點,而exit selection中的元素則是已刪除資料 15 23 42繫結的元素,對新資料我們需要生成新的元素與之繫結,而對於失去繫結資料的元素,則需要清理,如下:

div.enter().append("div").text(function(d) { return d; });
div.exit().remove();
頁面會變成如下所示:
<div>1</div>
<div>2</div>
<div>4</div>
<div>8</div>
<div>16</div>
<div>32</div>

To be continued.