程式碼
// html
<p class="bindData"></p>
//JS
const bindData = d3.select('.bindData')
.data(['綁定資料'])
.text(d => d);
// 印出綁定資料的 selection 來看看
console.log('bindData', bindData)
// 印出綁定的 data 來看看
console.log(bindData['_groups'][0][0]['__data__'])
程式碼
// html
<p class="bindMultiData"></p>
<p class="bindMultiData"></p>
<p class="bindMultiData"></p>
<p class="bindMultiData"></p>
//JS
const multiData = ['綁', '定', '資', '料']
const bindMultiData = d3.selectAll('.bindMultiData')
.data(multiData)
.text(d => d);
// 印出綁定資料的 selection 來看看
console.log('bindMultiData', bindMultiData)
程式碼
// html
<p class="bindUnmatchData"></p>
<p class="bindUnmatchData"></p>
//JS
const UnmatchData = ['綁', '定', '資', '料']
const bindUnmatchData = d3.selectAll('.bindUnmatchData')
.data(UnmatchData)
.text(d => d);
// 印出綁定資料的 selection 來看看
console.log('bindUnmatchData', bindUnmatchData)
程式碼
// html
<p class="datum"></p>
//JS
const datumObj = [{name:'jin'}, {name:'JIN'}]
const bindDatum = d3.select('.datum')
.datum(datumObj)
console.log('bindDatum',bindDatum)
程式碼
// html
<p class="join"></p>
//JS
const data = [{ name: "金金" }, { name: "JINJIN" }];
const dataBinding = d3.select(".join").data(data);
const dataArrayBinding = d3.select(".join").data([data]);
const datumBinding = d3.select(".join").datum(data);
程式碼
// html
<svg class="rectContainer">
<rect></rect>
<rect></rect>
<rect></rect>
<rect></rect>
<rect></rect>
</svg>
//JS
const rectData = [10, 20, 30, 40];
// data()
const d3Data = d3.select(".rectContainer").selectAll("rect").data(rectData);
console.log("d3Data", d3Data);
// datum()
const d3Datum = d3.select(".rectContainer").selectAll("rect").datum(rectData);
console.log("d3Datum", d3Datum)
程式碼
// html
<div class="updateData">
<p></p>
<p></p>
<p></p>
<p></p>
</div>
//JS
const updateData = ["資", "料", "剛", "好"];
const updateSelection = d3.select(".updateData")
.selectAll("p")
.data(updateData);
程式碼
// html
<div class="enterData">
<p></p>
<p></p>
</div>
//JS
const enterData = ["資", "料", "比", "較", "多"];
const enterSelection = d3.select(".enterData")
.selectAll("p")
.data(enterData)
.text((d) => d);
程式碼
// html
<div class="exitData">
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
</div>
//JS
const exitData = ["資", "料", "少"];
const exitSelection = d3.select(".exitData")
.selectAll("p")
.data(exitData)
.text((d) => d);
程式碼
// html
<div class="enterData">
<p></p>
<p></p>
</div>
//JS
const enterData = ["資", "料", "比", "較", "多"];
const enterSelection = d3
.select(".enterData")
.selectAll("p")
.data(enterData)
.text((d) => d)
.enter() ← 抓出缺少幾個DOM元素
.append("p") ← 把缺少的DOM元素加上去
.text((d) => d)
.classed("fw-bold", true)
.classed("text-danger", true);
程式碼
// html
<div class="exitData">
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
</div>
//JS
const exitData = ["資", "料", "少"];
const exitSelection = d3.select(".exitData")
.selectAll("p")
.data(exitData)
.text((d) => d)
.exit() ← 抓出多餘的 DOM 元素
.remove() ← 移除多餘的 DOM 元素
程式碼
// html
<div class="joinData"></div>
//JS
const joinData = ["j", "o", "i", "n"];
d3.select(".joinData")
.selectAll("p")
.data(joinData)
.join("p") ← 把 enter、update、exit 一併處理
.attr("class", "text-danger")
.text(d=>d)
// 或帶入參數function
d3.select(".joinData")
.selectAll("p")
.data(joinData)
.join( ← 分別設定 enter、update、exit function
enter => enter.append("p")
.attr("class", "text-danger")
.text(d=>d),
update => update,
exit => exit.remove()
);
原始資料
奇數資料
偶數資料
奇數資料與偶數資料合併後
程式碼
//html
<div class="text-center mergedData">
<p>原始資料</p>
<h6>1</h6>
<h6>2</h6>
<h6>3</h6>
<h6>4</h6>
<h6>5</h6>
</div>
<div class="border border-dark right text-center py-2 px-4 w-50 mergedContainer">
<p>奇數資料與偶數資料合併後
</p>
</div>
//JS
const even = d3.select('.mergedData').selectAll("h6")
.select(function (d, i) {
return i & 1 ? this : null
});
const odd = d3.select('.mergedData').selectAll("h6")
.select(function (d, i) {
return i & 1 ? null : this
});
const merged = odd.merge(even);
const mergedContainer = d3.select('.mergedContainer')
for(const element of merged._groups[0]){
mergedContainer.append('p').text(element.innerText)
}
程式碼
// html
<div>
<label>資料數量</label>
<input type="number" class="dataLength" />
<button type="button" class="getRandomData">
點擊產生隨機資料
</button>
</div>
<div>data資料集:<span class="showData"></span></div>
<div class="chartWrap"></div>
const getRandomData = document.querySelector(".getRandomData");
const dataLength = document.querySelector("input");
const showData = document.querySelector(".showData");
let randomData = [];
// 增加陣列
getRandomData.addEventListener("click", (e) => {
randomData.length = 0;
for (i = 0; i < dataLength.value; i++) {
// 產生並塞入隨機亂數資料
let random = Math.floor(Math.random() * 5);
randomData.push(random);
}
// 畫面呈現目前資料集
showData.innerHTML = randomData;
// 繪製圖表
drawDiagram();
});
// 建立 svg 畫布
const rangeSelect = d3
.select(".chartWrap")
.append("svg")
.attr("width", 400)
.attr("height", 300)
.style("border", "1px solid rgb(96, 96, 96)");
// 製作圖表
const drawDiagram = () => {
// 綁定 update 資料
let rects = rangeSelect.selectAll("rect").data(randomData);
// 用 enter 加上少的DOM元素
rects
.enter()
.append("rect")
.attr("width", (d) => d * 60)
.attr("height", 40)
.style("fill", "blue")
.attr("x", (d, index) => 0) // 設定x位置
.attr("y", (d, index) => index * 60); // 設定y位置
// 更新 width 寬度
rects.attr("width", (d) => d * 60);
// 用 exit 移除多的 DOM 元素
rects.exit().remove();
};
// 使用 join()
const drawDiagram = () => {
// 綁定 update 資料
let rects = rangeSelect
.selectAll("rect")
.data(randomData)
.join(
(enter) =>
enter
.append("rect")
.attr("width", (d) => d * 60)
.attr("height", 40)
.style("fill", "blue")
.attr("x", (d, index) => 0)
.attr("y", (d, index) => index * 60),
(update) => update.attr("width", (d) => d * 60),
(exit) => exit.remove()
);
};
//html
<div class="selectionOn">HiHi</div>
//JS
const textToRed = (e) => {
e.target.classList.add("fw-bold");
e.target.style.color = "red";
};
d3.select(".selectionOn").on("click", textToRed);
//html
<div>
金金永遠 <span class="fw-bold selectionCall"></span> 歲
</div>
//JS
const setAge = (selection, age) => {
selection.text(age);
};
d3.select(".selectionCall").call(setAge, "19");