如何自动排序一个条形图与切换功能
我已经上传了block(固定),您可以切换排序功能。如何自动排序一个条形图与切换功能
现在我想添加的是某种if
语句,当复选框打开时,当它打开时,我希望酒吧在您更改年份或类别时自动排序,并且当您再次切换时停止自动-sorting。
我想到了一个简单的
if (document.getElementsByClassName('myCheckbox').checked) {
change();
}
内update
功能会工作,但没有任何反应。
任何帮助表示赞赏!
我开始回答你的直接问题,但很快就意识到你的代码需要一点重构。你有太多的复制/粘贴冗余代码和绘制太多东西。当使用d3
进行编码时,您应该尝试执行所有绘图的单个功能。
这是code running。
这里是新的更新功能的片段来统治他们:
function update() {
file = d3.select('#year').property('value') == 'data2017' ? 'data.csv' : 'data2.csv';
catInt = d3.select('#category').property('value');
d3.csv(file, type, function(error,data) {
if(error) throw error;
var sortIndex = data.map(function(d){ return d.month});
// Update domain
y.domain([0, d3.max(data, function(d) {
return d["Category" + catInt]; })
]).nice();
// Update axis
g.selectAll(".axis.axis--y").transition()
.duration(750)
.call(yAxis);
g.selectAll(".axis.grid--y").transition()
.duration(750)
.call(yGrid);
// Sums and averages
let sumOfAll = d3.sum(data, function(d) {
return d["Category" + catInt];
});
let avgValue = d3.sum(data, function(d) {
return d["Category" + catInt];
})/data.length;
//sort data
data.sort(d3.select("#myCheckbox").property("checked")
? function(a, b) { return b["Category" + catInt] - a["Category" + catInt]; }
: function(a, b) { return sortIndex.indexOf(a.month) - sortIndex.indexOf(b.month);})
// set x domain
x.domain(data.map(function(d) { return d.month; }));
g.selectAll(".axis.axis--x").transition()
.duration(750)
.call(xAxis);
// Update rectangles
let bars = g.selectAll(".barEnter")
.data(data, function(d){
return d.month;
});
bars = bars
.enter()
.append("rect")
.attr("class", "barEnter") // Enter data reference
.attr("width", x.bandwidth())
.merge(bars);
bars.transition()
.duration(750)
.attr("height", function(d) {
return height - y(d["Category" + catInt]);
})
.attr("x", function(d) {
return x(d.month);
})
.attr("y", function(d) {
return y(d["Category" + catInt]);
});
bars.exit().remove();
// Update text on rectangles
let textUpdate = g.selectAll(".textEnter")
.data(data, function(d){
return d.month;
});
textUpdate = textUpdate.enter()
.append("text")
.style("text-shadow","1px 1px #777")
.attr("class", "textEnter") // Enter data reference
.attr("text-anchor","middle")
.attr("font-size",11)
.attr("fill","#fff")
.merge(textUpdate);
textUpdate.transition()
.duration(750)
.attr("y", function(d) {
return y(d["Category" + catInt]) + 15;
})
// Update text value
.text(function(d) {
return d["Category" + catInt];
})
.attr("x", function(d) {
return x(d.month) + x.bandwidth()/2;
})
// Update sum and avg value
g.selectAll("#totalValue").transition()
.duration(750)
.text(sumOfAll + " Category " + catInt)
g.selectAll("#avgValue").transition()
.duration(750)
.text(formatValue(avgValue))
});
}
非常感谢!我更新了我的[Block](https://bl.ocks.org/LemoNode/73dbb9d6a144476565386f48a2df2e3b)并将条件运算符更改为if语句,这是否会使代码变得冗余?多重三元评估仍然更可取? (如果你想添加另一个csv文件) –
@RobertAndersson,不,你的if语句是好的。对于更多的两个选项,我会使用一个嵌套三元组。 – Mark
由于'getElementsByClassName'返回一个列表,它必须是:'如果(document.getElementsByClassName(“myCheckbox”)[0 ] .checked){etc ...',以'[0]'作为索引。但是,我不会将此作为答案发布,因为您必须重构“更改”功能才能使其工作。 –
我知道,为了使它工作,您需要更改多少代码?如果有帮助,我可以发布一个更简单的例子。 –
我添加了一个答案,但我很快就会将其删除:排序工作不正常。请在删除之前复制答案的详细信息。 –