我正在尝试为我的D3 sunburst图实现更新功能,我可以在其中更改显示的数据。我能够成功添加或删除节点。
但是,我似乎无法修改现有数据。
例如,如果我的图表的一半被删除,我希望另一半填充删除留下的空间。当添加新数据时,我希望现有数据能够缩小并占用更少的空间
这是我的更新功能:
function update(newData) {
root = newData;
node = root;
g = svg.datum(root)
.selectAll("g")
.data(partition.nodes(root));
var newG = g.enter()
.append("g");
g.exit().selectAll("path").transition().duration(5000).attrTween("d", arcTween(0)).remove();
path = g.selectAll("path").transition().duration(5000).attr("d", arc);
newG.append("path")
.attr("d", arc);
};
以下是图表的构建方式:
function render(data) {
root = data;
node = root;
width = $(".burst-chart-container").height();
height = ($(".burst-chart-container").width() / 2);
radius = Math.min(width, height) / 2;
x = d3.scale.linear().range([0, 2 * Math.PI]);
y = d3.scale.linear().range([0, radius]);
rad = Math.min(width, height) / Math.PI - 25;
partition = d3.layout.partition().sort(null).value(function (d) { return d.size; });
arc = d3.svg.arc()
.startAngle(function (d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x))); })
.endAngle(function (d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))); })
.innerRadius(function (d) { return Math.max(0, y(d.y)); })
.outerRadius(function (d) { return Math.max(0, y(d.y + d.dy)); });
svg = d3.select(element[0]).append('svg')
.attr("width", width).attr("height", height)
.attr("class", "svgDashboard")
.append("g")
.attr("transform", "translate(" + width / 2 + "," + (height / 2) + ")");
g = svg.datum(root).selectAll("g")
.data(partition.nodes)
.enter()
.append("g")
path = g.append("path")
.attr("d", arc)
}
我知道path.attr("d",arc)
应该更新视觉效果,但在我的情况下它不起作用。
我认为它与分区布局有关,他们不会告诉现有的弧需要更改,或者我选择更新数据的方式,但我可能错了。
任何帮助都将不胜感激。
答案 0 :(得分:0)
我发现path
和text
数据从未更新过。我的更新只更改了g
元素数据。为了纠正它,我只需将父数据带入他的孩子,并在我更新之后。
g = svg.datum(root)
.selectAll("g")
.data(partition.nodes(root));
//Add this part to update child elements
g.selectAll("path").each(function () {
d3.select(this).datum(d3.select(this.parentNode).datum());
});
g.selectAll("text").each(function () {
d3.select(this).datum(d3.select(this.parentNode).datum());
});
通过这些更改,我可以调用我的attrTween函数,用新数据更新视觉效果。