用其官網的話來講:html
D3.js is a JavaScript library for manipulating documents based on data. D3 helps you bring data to life using HTML, SVG, and CSS.
D3是一個用於數據可視化的JS庫。其將數據與DOM綁定,經過創建數據與DOM元素樣式之間的關係,來表現數據,實現可視化。它也是github上星第4多的JS庫。node
成果圖以下git
代碼以下github
<style> .chart div { font: 10px sans-serif; background-color: steelblue; text-align: right; padding: 3px; margin: 1px; color: white; } </style> ... <body> <div class="chart"></div> <script> let data = [30, 86, 168, 281, 303, 365] let chart = document.getElementsByClassName('chart')[0] data.forEach(d => { let div = document.createElement('div') div.style.width = `${d}px` div.textContent = d chart.appendChild(div) }) </script> </body>
let chart = document.getElementsByClassName('chart')[0]
app
建立元素,經過元素的樣式來表現數據函數
let div = document.createElement('div') div.style.width = `${d}px` div.textContent = d
將元素添加到畫布上工具
chart.appendChild(div)
整個思路中,首先要注意數據與元素數量之間的關係ui
有多少組數據,就應該對應有多少個元素spa
其次就是創建數據與元素樣式之間的函數關係,雙向綁定
例如數據與元素寬度之間的函數關係
function (data) { return data + "px"; }
數據與元素文本內容之間的函數關係
function (data) { return data; }
我我的以爲,d3的 Data-Driven Documents,主要體現就是以上兩點
用d3實現一樣效果以下
<script src="https://d3js.org/d3.v4.min.js"></script> <script> let data = [30, 86, 168, 281, 303, 365] d3.select(".chart") // 選擇畫布 .selectAll("div") // 選擇畫布上的div元素 .data(data) // 將畫布上的div元素與數據綁定 .enter().append("div") // 若是不夠,補足 .style("width", function (d) { // 數據與元素寬度之間的函數關係 return d + "px"; }) .text(function (d) { // 數據與元素文本內容之間的函數關係 return d; }); </script>
數據
let data = [30, 86, 168, 281, 303, 365]
若是在 .chart 中有對應數量的 div
<div class="chart"> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> </div>
那麼就不須要額外添加 div 元素
d3.select(".chart") .selectAll("div") .data(data) .style("width", function (d) { return d + "px"; }) .text(function (d) { return d; });
若是沒有 div 元素,就須要經過 enter().append('div')
來添加相應數量的元素
<div class="chart"> </div>
其中 enter()
Returns the enter selection: placeholder nodes for each datum that had no corresponding DOM element in the selection. (The enter selection is empty for selections not returned by selection.data.)
d3.select(".chart") .selectAll("div") .data(data) .enter().append('div') .style("width", function (d) { return d + "px"; }) .text(function (d) { return d; })
若是在 .chart 中有過多數量的 div
<div class="chart"> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> </div>
那麼就須要將多餘的 div 移除,經過 exit().remove()
來實現
其中 exit()
Returns the exit selection: existing DOM elements in the selection for which no new datum was found. (The exit selection is empty for selections not returned by selection.data.)
d3.select(".chart") .selectAll("div") .data(data) .style("width", function (d) { return d + "px"; }) .text(function (d) { return d; }) .exit().remove()
首先要知道在 d3 中,數據與 DOM 元素並非雙向綁定的,在將數據綁定到元素以後,再次修改數據,元素並不會產生對應的變化
因此數據更新要手動完成
function update(data) { d3.select(".chart") .selectAll("div") .data(data) .style("width", function (d) { return d + "px"; }) .text(function (d) { return d; }) // 若是元素不夠,補足 d3.select(".chart") .selectAll("div") .data(data) .enter().append('div') .style("width", function (d) { return d + "px"; }) .text(function (d) { return d; }) // 若是元素多餘,移除 d3.select(".chart") .selectAll("div") .data(data) .exit().remove() }
完整實驗代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>D3.js</title> <style> .chart div { font: 10px sans-serif; background-color: steelblue; text-align: right; padding: 3px; margin: 1px; color: white; } </style> </head> <body> <div class="chart"> </div> <script src="https://d3js.org/d3.v4.min.js"></script> <script> let data = [30, 86, 168, 281, 303, 365] d3.select(".chart") .selectAll("div") .data(data) .enter().append('div') .style("width", function (d) { return d + "px"; }) .text(function (d) { return d; }) setTimeout(function () { data = [30, 86, 168, 281, 303, 365, 700] update(data) }, 1000) function update(data) { d3.select(".chart") .selectAll("div") .data(data) .style("width", function (d) { return d + "px"; }) .text(function (d) { return d; }) d3.select(".chart") .selectAll("div") .data(data) .enter().append('div') .style("width", function (d) { return d + "px"; }) .text(function (d) { return d; }) d3.select(".chart") .selectAll("div") .data(data) .exit().remove() } </script> </body> </html>
d3提供的選擇方法,能處理數據與元素數量不匹配的狀況
enter()
能選擇到那些用於補足的元素exit()
能選擇那些過剩的元素d3方便了經過元素的樣式來展示數據的過程,用戶本身定義數據與元素樣式之間的函數關係