入門d3.js,根據官網部分教程學習,發現因爲版本更新,有些api和概念可能不適用,但總體思想未變。本文思路跟隨此篇blogLet’s Make a Bar Chart學習,加上自己的理解,並且查閱了部分更新資料
元素選擇
d3通過d3.select()或者d3.selectAll()獲取元素,這兩個API返回selection對象,我們可以通過selection對象操控元素
<div class="chart"></div>
<div class="chart"></div>
<div class="chart"></div>
<div class="chart"></div>
<div class="chart"></div>
<script>
console.log(d3.select('.chart'));
console.log(d3.selectAll('.chart'));
</script>
通過selection操作dom有一個好處是可以不用寫太多的for循環,比如我想給所有的chart DIV添加內容只需
let section = d3.selectAll('.chart');
let div = section.append('div');
div.html('Hi!')
就可以向所有的div加入內容,無需for循環
鏈式寫法
selection的另一個方便之處就是鏈式寫法,selection的方法會返回對應selection,這樣就可以使用簡潔的鏈式寫法了
d3.selectAll('.chart')
.append('div')
.html('Hi')
使用html與d3創建條形圖
首先列出css與data,下面都用這一配置
.chart div{
font: 10px sans-serif;
background-color: steelblue;
text-align: right;
padding: 3px;
margin: 1px;
color: white;
}
<div class="chart"></div>
const data = [4, 8, 15, 16, 23, 42];
接下來使用d3創建條形圖
d3.select('.chart')
.selectAll('div')
.data(data)
.enter().append('div')
.style('width', d => d * 10 + 'px')
.text( d => d)
接下來分步說明,其中會涉及到一個叫data join(數據綁定)
的概念。有了data join,當數據發生改變時,可以通過數據創建,更新,銷燬元素,後文再提及
首先獲取元素並初始化要綁定數據的元素
let chart = d3.select('.chart')//選擇元素
let bar = chart.selectAll('div') //要進行數據綁定的元素,chart中無此元素,此時返回的selection爲空
接着綁定數據
let barUpdate = bar.data(data)
console.log(barUpdate)
selection.data()方法會將數據綁定於選擇的元素之中,並返回一個新的selection,並且在其中定義了enter selections
和exit selections
(這部分用文字難以一言兩語解釋清楚,於是寫在另一篇blog裏)
enter selections:表示有數據無元素,對應元素用EnterNode替代,若對應數據有元素,則由empty表示
exit selections: 表示無數據有元素,因爲chart中沒有元素,所以這裏的數組爲空;若有數據對應元素,元素也用empty表示,無則用元素本身表示
_groups:表示成功綁定上數據的元素,若無對應元素,則由empty表示,所以這裏有6個empty
接下來我們獲取所有EnterNode,對齊插入div
let barEnter = barUpdate.enter().append('div'); //enter()返回EnterNode
接着對這些div設置條形寬度,因爲有data join(數據綁定),所以我們直接通過綁定的數據設置寬度就可以了
barEnter.style("width", d => d * 10 + 'px');
最後,text文字設置同理
barEnter.text(d => d);
使用比例尺
上面的例子中我們使用了magic number => 10,讓bar的像素寬度=數值*10,使得bar的寬度看起來容易對比,但是正常情況下使用magic number會很麻煩且不易調試,而且不僅有放大像素數值的情況,也有縮小像素數值的情況,所以引入了比例尺
這裏使用線性比例尺
let x = d3.scaleLinear()
.domain([0, d3.max(data)]) //
.range([0, 420]); //
d3.select('.chart')
.selectAll('div')
.data(data)
.enter().append('div')
.style('width', d => x(d) + 'px') //使用比例尺,比例尺是個函數
.text( d => d);
總結
初步入門,有不對請大佬指出
參考資料
Let’s Make a Bar Chart I
selection_data
selection_enter
selection_exit
selection_join
[譯]D3.js 之 d3-selection 原理