我有一个 v5 D3 树形图,当我单击一个框时,我希望它向下钻取到下一个级别 - 作为不属于新层次结构的元素的一部分应该被删除。它大部分工作正常,但并非所有元素都因某种原因被删除。
在下面的示例中,如果单击 B1 框,您将看到显示额外的框。
这是一个例子:
const data = {
"name": "A1",
"health": 0.521,
"children": [
{
"name": "B1",
"health": 0.521,
"children": [
{
"name": "B1-C1",
"health": 0.614,
"children": [
{
"name": "B1-C1-D1",
"health": 0.666,
"children": [
{
"name": "B1-C1-D1-E1",
"value": 30,
"health": 0.8
},
{
"name": "B1-C1-D1-E2",
"value": 35,
"health": 0.5
},
{
"name": "B1-C1-D1-E3",
"value": 20,
"health": 0.7
}
]
},
{
"name": "B1-C1-D2",
"health": 0.45,
"children": [
{
"name": "B1-C1-D2-E1",
"value": 10,
"health": 0.8
},
{
"name": "B1-C1-D2-E1",
"value": 14,
"health": 0.1
}
]
},
{
"name": "B1-C1-D3",
"health": 0.64,
"children": [
{
"name": "B1-C1-D3-E1",
"value": 10,
"health": 0.8
},
{
"name": "B1-C1-D3-E2",
"value": 14,
"health": 0.2
},
{
"name": "B1-C1-D3-E3",
"value": 7,
"health": 0.7
},
{
"name": "B1-C1-D3-E4",
"value": 9,
"health": 0.9
},
{
"name": "B1-C1-D3-E5",
"value": 5,
"health": 0.6
}
]
},
{"name": "B1-C1-D4",
"value": 2,
"health": 0.7
}
]
},
{
"name": "B1-C2",
"health": 0.45,
"children": [
{"name": "B1-C2-D1",
"health": 0.45,
"value": 12}
]
},
{
"name": "B1-C3",
"health": 0.5,
"children": [
{"name": "B1-C3-D1",
"health": 0.5,
"value": 10}
]
}
]
}
]
}
const treemapLayout = d3.treemap()
.size([500, 300])
.paddingOuter(16);
let t = d3.transition().duration(1500)
// update the view
let update = (d) => {
console.log(d)
let rootNode = d3.hierarchy(d)
rootNode
.sum(function(d) {
return d.value;
})
.sort(function(a, b) {
return b.height - a.height || b.value - a.value;
});
//console.log(rootNode)
treemapLayout(rootNode);
let nodes = d3.select('svg')
.selectAll('g')
.data(rootNode.descendants())
nodes
.exit()
.attr("fill-opacity", 1)
.transition(t)
.attr("fill-opacity", 0)
.remove()
nodes = nodes
.enter()
.append('g')
.merge(nodes)
.filter(function(d) {
return d.depth < 4;
})
.attr('transform', function(d) {
return 'translate(' + [d.x0, d.y0] + ')'
})
nodes
.append('rect')
.attr('width', function(d) {
return d.x1 - d.x0;
})
.attr('height', function(d) {
return d.y1 - d.y0;
})
.attr('style', function(d) {
return ('fill:' + d3.interpolateRdYlGn(d.data.health))
})
.on('click', function(d) {
update(d.data);
})
.transition(t)
nodes
.append('text')
.attr('dx', 4)
.attr('dy', 14)
.text(function(d) {
return d.data.name;
})
};
update(data);
rect {
fill: cadetblue;
opacity: 1;
stroke: white;
}
text {
font-family: "Helvetica Neue", Helvetica, sans-serif;
fill: #484848;
font-size: 10px;
overflow-x: hidden;
overflow-y: hidden;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg width="1000" height="800">
<g></g>
</svg>
最佳答案
实现的问题是您没有使用唯一标识符(例如您案例中的 id 或名称)来标识节点。
将代码更改为(参见下面的代码)将允许 D3 在合并时正确识别实际节点
let nodes = d3.select('svg')
.selectAll('g')
.data(rootNode.descendants(), d => d ? d.name : 'root')
关于javascript - D3 树形图更新 - 并非所有元素都被删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57487223/