如何在 d3 中更新带有附带文本的条形图?
How to update a bar chart with accompanying text in d3?
我正在创建一个条形图作为 d3 中更大数据可视化的一部分。我希望能够更改可视化的一部分中的数据,并且所有图表都将更新。图表的简化版本如下。
var dataset = [1, 3, 5, 3, 3];
...
var svg = d3.select("body #container").append("svg")
.attr("width", width)
.attr("height", height);
var g = svg.append("g");
...
我使用这个 svg 元素创建其他图表,如地图、圆圈等。条形图是这样实现的
function bars(dataset) {
var barChart = g.selectAll("rect.bar")
.data(dataset)
.enter();
barChart.append("rect")
.attr("class", "bar")
.attr("x", function(d, i) { return i * 30 + 100; })
.attr("y", function(d) { return (height - 130) - d * 4;})
.attr("width", 25)
.attr("height", function(d) { return d * 4; });
barChart.append("text")
.text(function(d) { return d; })
.attr("x", function(d, i) { return i * 30 + 103; })
.attr("y", function(d) { return (height - 130) - d/10 - 5;})
.attr("font-family", "sans-serif")
.attr("font-size", "10px")
.attr("fill", "darkgray");
}
现在可以很好地呈现条形图,但有一个函数
...
.on("click", function() {
...
var newdata = [5, 2, 6, 2, 4]; // new values
g.selectAll("rect.bar").remove(); // This removes the bars
g.selectAll("text").remove(); // Problem here: All texts are removed
bars(newdata);
}
我尝试使用 .remove() 函数将条形图转换为新值。这适用于条形矩形,因为没有其他条形图,但是当我尝试删除上面显示的值标签时,所有其他文本元素也被删除。有没有办法只更新与条相关的文本?
您是否尝试过对文本应用 class 并仅选择要删除的那些?
例如
barChart.append("text")
.attr('class','label')
.text(function(d) { return d; })
然后
g.selectAll(".label").remove();
顺便说一下,如果在更新之间没有删除所有元素,那么您是否考虑过使用 enter()
和 exit()
将新数据绑定到现有元素并仅删除正在更改的元素?
编辑 像这样:
function bars(dataset) {
var bar = g.selectAll(".bar").data(dataset);
bar.exit().remove();
bar.enter().append("rect").attr("class", "bar");
bar
.attr("x", function(d, i) { return i * 30 + 100; })
.attr("y", function(d) { return (height - 130) - d * 4;})
.attr("width", 25)
.attr("height", function(d) { return d * 4; });
var label = g.selectAll(".label").data(dataset);
label.exit().remove();
label.enter().append("text").attr("class", "label");
label
.text(function(d) { return d; })
.attr("x", function(d, i) { return i * 30 + 103; })
.attr("y", function(d) { return (height - 130) - d/10 - 5;})
.attr("font-family", "sans-serif")
.attr("font-size", "10px")
.attr("fill", "darkgray");
}
我正在创建一个条形图作为 d3 中更大数据可视化的一部分。我希望能够更改可视化的一部分中的数据,并且所有图表都将更新。图表的简化版本如下。
var dataset = [1, 3, 5, 3, 3];
...
var svg = d3.select("body #container").append("svg")
.attr("width", width)
.attr("height", height);
var g = svg.append("g");
...
我使用这个 svg 元素创建其他图表,如地图、圆圈等。条形图是这样实现的
function bars(dataset) {
var barChart = g.selectAll("rect.bar")
.data(dataset)
.enter();
barChart.append("rect")
.attr("class", "bar")
.attr("x", function(d, i) { return i * 30 + 100; })
.attr("y", function(d) { return (height - 130) - d * 4;})
.attr("width", 25)
.attr("height", function(d) { return d * 4; });
barChart.append("text")
.text(function(d) { return d; })
.attr("x", function(d, i) { return i * 30 + 103; })
.attr("y", function(d) { return (height - 130) - d/10 - 5;})
.attr("font-family", "sans-serif")
.attr("font-size", "10px")
.attr("fill", "darkgray");
}
现在可以很好地呈现条形图,但有一个函数
...
.on("click", function() {
...
var newdata = [5, 2, 6, 2, 4]; // new values
g.selectAll("rect.bar").remove(); // This removes the bars
g.selectAll("text").remove(); // Problem here: All texts are removed
bars(newdata);
}
我尝试使用 .remove() 函数将条形图转换为新值。这适用于条形矩形,因为没有其他条形图,但是当我尝试删除上面显示的值标签时,所有其他文本元素也被删除。有没有办法只更新与条相关的文本?
您是否尝试过对文本应用 class 并仅选择要删除的那些? 例如
barChart.append("text")
.attr('class','label')
.text(function(d) { return d; })
然后
g.selectAll(".label").remove();
顺便说一下,如果在更新之间没有删除所有元素,那么您是否考虑过使用 enter()
和 exit()
将新数据绑定到现有元素并仅删除正在更改的元素?
编辑 像这样:
function bars(dataset) {
var bar = g.selectAll(".bar").data(dataset);
bar.exit().remove();
bar.enter().append("rect").attr("class", "bar");
bar
.attr("x", function(d, i) { return i * 30 + 100; })
.attr("y", function(d) { return (height - 130) - d * 4;})
.attr("width", 25)
.attr("height", function(d) { return d * 4; });
var label = g.selectAll(".label").data(dataset);
label.exit().remove();
label.enter().append("text").attr("class", "label");
label
.text(function(d) { return d; })
.attr("x", function(d, i) { return i * 30 + 103; })
.attr("y", function(d) { return (height - 130) - d/10 - 5;})
.attr("font-family", "sans-serif")
.attr("font-size", "10px")
.attr("fill", "darkgray");
}