一種僅在一個 .js 檔案中創建多個圖表而不會出現變數名稱問題的方法是將它們封裝在不同的函式中,然后在檔案末尾呼叫它們,如下所示:
function barchart2() {
//your amazing chart code here
}
function barchart2() {
//your amazing chart code here
}
function barchart3() {
//your amazing chart code here
}
//plot charts
barchart1();
barchart2();
barchart3();
當你這樣做時,你會看到圖表中有很多重復。編程中最重要的原則之一是不要重復自己(干),主要是在您在團隊中作業并且不想在維護和開發代碼時生氣的情況下。
下面您可以看到所有其他圖表共有的部分代碼示例,位于檔案的開頭,因此對所有圖表都是可重用的。
//set the dimensions and margins of the svg for ALL charts and maps
const MARGIN = {top: 16, right: 0, bottom: 32, left: 64},
WIDTH = 640 - MARGIN.left - MARGIN.right,
HEIGHT = 320 - MARGIN.top - MARGIN.bottom;
//set scales for ALL barcharts
const X = d3.scaleBand()
.range([0, WIDTH])
.paddingInner(0.04)
.paddingOuter(0.02);
const Y = d3.scaleLinear()
.range([HEIGHT, 0]);
//the above part is common for ALL charts, goes outside the function in the beginning of the file
但隨之而來的是奇怪的部分。所有圖表都從同一來源接收資料。那么,我們怎么能只呼叫一次資料,而不需要對它們中的每一個重復一次又一次的承諾呢?
function barchart1() {
//get data
d3.json("data.json").then(function(data) { //this part is the same in all 3 charts except for a small part (see comment below)
//format data
data.forEach(function(d) {
d.votes = Number(d.votes);
d.tt_votes = Number(d.tt_votes);
});
const selectedData = [...new Map(data.map(item => [item['code'], item]))
.values()]
.sort((a, b) => d3.ascending(a.code, b.code)); //sort list by code
//plot chart on page first load
update(data); //calls update function
let dropdown = d3.select("#select1") //THIS ONLY LINE IS NOT THE SAME IN THE DIFFERENT CHARTS
//add the options to the dropdown
dropdown
.selectAll('myOptions')
.data(selectedData)
.enter()
.append("option")
.text(function (d) { return d.state_name; }) //text showed in the options
.attr("value", function (d) { return d.state_code; }) //value of each option
.property("selected", function(d) { //select state_code === 33 as default
return d.state_code === 33;
});
//calls update function to plot the chart the first time page is load
update(data);
})
function update(data){
//update code goes here
...
}
}
function barchart2() {
//here the same excepted for let dropdown = d3.select("#select2")
}
function barchart3() {
//here the same excepted for let dropdown = d3.select("#select3")
}
//plot charts
barchart1();
barchart2();
barchart3();
為了更加清晰和簡單,我們可以只關注這部分來尋找解決方案(這是所有圖表的基本和共同點):
//get data
d3.json("data.json").then(function(data) { //this part is the same in all 3 charts except for a small part (see comment below)
//format data
data.forEach(function(d) {
d.votes = Number(d.votes);
d.tt_votes = Number(d.tt_votes);
});
//calls update function to plot the chart the first time page is load
update(data);
})
我嘗試d3.json("data.json").then(function(data) { etc.將其切割放入一個函式中,然后呼叫該函式,但這不起作用,因為我們無法訪問內部函式結果 var。它總是未定義的。這個案子有什么線索嗎?
uj5u.com熱心網友回復:
JS 是詞法范圍的,因此data如果您在 Promise 范圍內定義函式,則可以使用該引數。
d3.json("data.json").then(function(data) {
/// you can do data prep and make scales here
function barchart1() {
// you can refer to data now
}
function barchart2() {
// you can refer to data now
}
barchart1();
barchart2();
})
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/486376.html
標籤:javascript 功能 d3.js 干燥
