D3.js入門

衛辰9發表於2019-04-09

D3.js是一個通過資料來操作文件JavaScript庫。結合SVG,D3特別適合用於圖表的繪製,但D3本身並不是一個圖表庫,它把資料繫結到DOM中,利用SVG輸出圖表。本文所講內容適用於v4.0+版本

從v4.0開始,D3把各個模組分離開來,各個模組相互獨立,也就是說如果你只需要用到D3強大的陣列操作部分,只需引用d3-array部分(例如npm install d3-array),不需要引用所有的D3庫。這樣做能夠使前端模組化開發更加靈活,減小引用資源體積,節省效能

用D3操作DOM元素

  • d3.select(selector) 返回匹配選擇器的第一個元素
  • d3.selectAll(selector) 返回匹配選擇器所有元素

比如d3.selectAll(‘p’)可以選擇所有的p元素,d3.select(‘p’)只選擇第一個p元素

d3.select('p')
d3.selectAll('p')
複製程式碼

還可以選擇其他常用的選擇器,包括派生選擇器,與document.querySelector和document.querySelectorAll方法十分類似

d3.select('.chart')
d3.selectAll('.chart')
d3.select('#chart')
d3.select('.chart rect')
複製程式碼
  • selection.append(type) 建立新元素並返回該元素
  • selection.remove() 從DOM中移除當前元素
  • selection.attr(name[,value]) 取得或設定屬性的值
  • selection.style(name[,value[,priority]]) 取得或設定元素的樣式
d3.select('body')
  .append('svg')
  .attr('width', 500)
  .attr('height', 500)
  .style('background', 'red')
  .remove()
複製程式碼

上面的程式碼首先在body中建立了一個svg標籤,然後給它設定高度和寬度,設定背景色,最後被刪除,D3的程式碼風格基本採用鏈式寫法,因為大部分D3的方法都返回D3物件的例項,這和jQuery非常相似

在DOM元素中繫結資料

資料繫結是D3的最大特色,也是最讓入門者困惑的地方,D3中文全稱“資料驅動文件”,主要的方法有兩個

  • selection.datum([value]) 為每個元素繫結值value
<body>
  <p>Dog</p>
  <p>Cat</p>
  <p>Monkey</p>
  <script type="text/javascript">
    var p = d3.select('body').selectAll('p');
    // 為p元素集繫結數值1
    p.datum(1);
    console.log(p);
  </script>
</body>
複製程式碼

執行程式碼檢視控制檯,數值1已經被賦予了p標籤的**data**屬性了

D3.js入門
  • selection.data([data[,key]]) 為每個元素分別繫結對應data中資料值

data方法與datum方法的區別在於,data的引數是陣列,分別分配給對應的DOM元素,每個DOM元素得到一個value值,而datum把相同引數均賦值給DOM元素,每個元素得到的資料值相同,data方法比較適用於日常資料需求,使用更多

<body>
  <p>Dog</p>
  <p>Cat</p>
  <p>Monkey</p>
  <script type="text/javascript">
    var dataset = [1, 2, 3];
    var p = d3.select('body').selectAll('p');
    // 為p元素集繫結陣列dataset
    p.data(dataset);
    console.log(p);
  </script>
</body>
複製程式碼

執行程式碼檢視控制檯,數值1、2、3分別繫結到了第1、2、3個p標籤

D3.js入門 D3.js入門 D3.js入門

繫結資料後,就可以利用繫結的資料做一些事情了,D3為大部分操作DOM的方法新增了函式引數,該函式有兩個引數,一個代表繫結的資料,通常為d,另一個為序數值,通常為i

<body>
  <p>Dog</p>
  <p>Cat</p>
  <p>Monkey</p>
  <script type="text/javascript">
    var dataset = [1, 2, 3];
    var p = d3.select('body').selectAll('p');
    // 更改p元素內的內容,d是資料值,i是序數值
    p.data(dataset)
      .text(function(d, i) {
        return d + ' ' + i
      });
  </script>
</body>
複製程式碼

執行結果如下圖:

D3.js入門

enter()與exit()的用法

在前面講資料繫結中,陣列的長度與標籤數量是相等的,如果資料的長度不可控,會導致有些標籤沒有資料,有些資料沒有標籤匹配,這個時候就要用到enter與exit方法了

  • selection.enter() 為缺失的元素返回佔位符
<body>
  <p>Dog</p>
  <script type="text/javascript">
    var dataset = [1, 2, 3];
    var p = d3.select('body').selectAll('p');
    // 目前只有1個元素,3個資料值
    enter = p.data(dataset).enter();
    console.log(enter);
  </script>
</body>
複製程式碼

檢視控制檯,發現出現了2個並不真實存在的EnterNode,繫結了剩餘的資料,這就是enter部分,如果後面繼續新增新的標籤,標籤會被自動繫結剩餘資料

D3.js入門
  • selection.exit() 返回沒有被繫結資料的元素
<body>
  <p>Dog</p>
  <p>Cat</p>
  <p>Monkey</p>
  <script type="text/javascript">
    var dataset = [1];
    var p = d3.select('body').selectAll('p');
    // 目前有3個元素,只有1個資料值
    exit = p.data(dataset).exit();
    console.log(exit);
  </script>
</body>
複製程式碼

檢視控制檯,有2個標籤並沒有繫結資料,這就是exit部分,可以把多餘的exit部分移除掉

D3.js入門

互動與動畫

  • selection.on(typenames[,listener[,capture]])

D3的事件繫結非常簡單,與jQuery的on方法一樣,指定事件型別後,呼叫回撥函式

<body>
  <p>Dog</p>
  <script type="text/javascript">
    var p = d3.select('body').select('p');
    p.on('click', function() {
      d3.select(this).text('Cat');
    })
  </script>
</body>
複製程式碼
  • selection.transition([name])

在元素之間加入transition方法,就能形成炫酷的過渡動畫

<body>
  <div></div>
  <script type="text/javascript">
    var div = d3.select('body').select('div');
    div.style('width', '200px')
      .style('height', '200px')
      .style('background', 'red')
      .transition()
      .style('width', '400px');
  </script>
</body>
複製程式碼

相關文章