【D3.js】簡介:資料驅動 - Part 2
上一篇文章裡面介紹了 D3 操作 DOM 元素的方法,這一篇要介紹 D3 的重頭戲:資料驅動。
資料綁定
使用 .data()
可以將特定資料綁定在選取的 DOM 元素身上。
📌 範例:
//index.html
<div class="classroom">
<p class="seat"></p>
</div>
//index.js
let students = ['Monica', 'Phoebe', 'Rachel']
d3.selectAll(".seat").data(students).text((d, index) => d)
資料函式
首先,先解釋 .text()
裡面以函式作為參數是怎麼一回事。
上一篇文章介紹了很多操作 DOM 元素的方法,而其實那些方法都可以用函式作為參數,如此一來便能接收到綁定的資料。
舉例來說,範例中將資料 students
綁定在 <p class=“seat”>
身上,接著只要傳入函式作為 text() 的參數就能接收到綁定的資料:
d3.selectAll(".seat")
.data(students)
.text((d, idx) => {console.log(d, idx); return d})
登愣!畫面上出現 "Monica"! 你可能會疑惑說,奇怪資料明明有三筆,為什麼結果只顯示了 Monica 呢?Phoebe 和 Rachel 跑去哪裡了?
回去看一下 HTML 結構,發現只有一個 <p class=“seat”>
元素,而這正是畫面當中只顯示 Monica 的原因。只有一個座位,當然只夠一個人坐啊~
解決的方式很簡單,座位不夠嗎?那就多搬一些椅子來啊!
<div class="classroom">
<p class="seat"></p>
<p class="seat"></p>
<p class="seat"></p>
</div>
新增兩個 <p class=“seat”>
元素 後,畫面上出現正確的資料了。
認識 join()
不過,好像有點麻煩啊...這樣只要有人來,我們就得繼續搬新椅子,不然又會出現有人沒位置的情況。
不擔心,D3 提供的 join()
可以解決上述困擾,它會自動根據資料來新增/移除 DOM 元素:
//裡面不擺放任何椅子 `<p class=“seat”>`
<div class="classroom"></div>
d3.select(".classroom")
.selectAll("p")
.data(students)
.join("p")
.text((d, idx)=>`${idx+1}. ${d}`);
一個步驟一個步驟看:
- 先選取外層
<div class=“classroom”>
- 選取所有
<p
>,雖然現在 classroom 裡面沒有任何<p>
,但後面我們會透過join()
來根據資料內容生成 .data()
綁定資料.join(“p”)
生成所需的<p>
,資料有三筆所以會生成三個<p>
.text()
新增文字內容,記得使用資料函式作為參數來接收資料
載入資料
剛剛我們使用的資料是隨意建立的陣列,不過大多數的情況資料可能會是某個事先載好的檔案或是透過 API 向伺服器取得的資料。
D3 提供了載入不同格式資料的方法,例如 d3.json
、d3.csv
等。
d3.json(“data/file.json”).then((data)=> console.log(data))
我們來練習看看用 d3.json()
來接收 JSONPlaceholder 的 User 假資料,並顯示在畫面上:
const el = d3.select(".classroom");
d3.json("https://jsonplaceholder.typicode.com/todos").then((data) => {
console.log(data);
el.selectAll("p")
.data(data)
.join("p")
.text((d) => d.title);
});
這邊附上我的 codepen 連結:資料驅動練習