要在一个.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();
当你这样做的时候,你会发现图表中有很多重复,编程中最重要的原则之一是不要重复自己(DRY),主要是如果你在团队中工作,并且不想在维护和开发代码的时候发疯的话。
下面您可以看到一个示例,其中的一部分代码与所有其他图表相同,位于文件的开头,因此可重复用于所有图表。
//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.
,把它放在一个函数中,然后调用这个函数,但是这不起作用,因为我们不能到达内部函数result var。它总是未定义的。这个案例有什么线索吗?
1条答案
按热度按时间1l5u6lss1#
JS的作用域是词法上的,因此如果在promise的作用域中定义函数,则可以使用
data
参数。