【发布时间】:2019-12-05 11:41:23
【问题描述】:
我是一个 D3 / Javascript 菜鸟,我正在尝试创建一个带有添加条形选项的图表(通过更新 > 输入选择),然后重新对它们进行排序。
但是,最后添加的bar拒绝参与重新排序。
谁能告诉我: a) 为什么会发生这种情况 b) 如何解决它
查看 Codepen:https://codepen.io/benjamesdavis/pen/JjodJwy?editors=1010
//Width and height
var w = 900;
var h = 450;
var array = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,
11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];
dataset=[];
for(let i=0; i<array.length; i++)
{dataset[i] = {"key":i, "value": array[i]}}
var xScale = d3.scaleBand()
.domain(d3.range(dataset.length))
.rangeRound([0, w])
.paddingInner(0.05);
var yScale = d3.scaleLinear()
.domain([0, d3.max(dataset, d=> d.value)])
.range([0, h]);
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
//Create bars
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function(d, i) {
return xScale(i);
})
.attr("y", function(d) {
return h - yScale(d.value);
})
.attr("width", xScale.bandwidth())
.attr("height", function(d) {
return yScale(d.value);
})
.attr("fill", function(d) {
return "rgb(0, 0, " + Math.round(d.value * 10) + ")";
});
//On click, update with new data
d3.select("#newBar")
.on("click", function() {
//Add one new value to dataset
var maxValue = 25;
var newNumber = Math.floor(Math.random() * maxValue);
newNumber = {"key":dataset.length, "value": newNumber}
dataset.push(newNumber);
//Update scale domains
xScale.domain(d3.range(dataset.length));
yScale.domain([0, d3.max(dataset, d=> d.value)]);
//Select…
bars = svg.selectAll("rect")
.data(dataset)
//Enter…
bars.enter()
.append("rect")
.attr("x", w)
.attr("y", function(d) {
return h - yScale(d.value);
})
.attr("width", xScale.bandwidth())
.attr("height", function(d) {
return yScale(d.value);
})
.attr("fill", function(d,i) {
return "rgb(0, 0, " + Math.round(d.value * 10) + ")";
})
.merge(bars)
.transition()
.duration(500)
.attr("x", function(d, i) {
return xScale(i);
})
.attr("y", function(d) {
return h - yScale(d.value);
})
.attr("width", xScale.bandwidth())
.attr("height", function(d) {
return yScale(d.value);
});
});
//Re-Sort Bars
d3.select("#sortBars").on("click",function(){
d3.shuffle(dataset)
bars.data(dataset,d => d.key)
.transition(2000)
.attr("x", function(d, i) {
return xScale(i);
})
})
【问题讨论】:
-
我认为这与您的变量“bars”范围有关。
-
你是对的。如果我在排序代码中将“bars.data”更改为“svg.selectAll("rect").data”,它就可以工作。不是 100% 确定这些选择之间的区别是什么。
//Re-Sort Bars d3.select("#sortBars").on("click",function(){ d3.shuffle(dataset) svg.selectAll("rect").data(dataset,d => d.key) .transition(2000) .attr("x", function(d, i) { return xScale(i); }) })
标签: javascript d3.js