我试图通过将一个空数组连接到d3选择中来从svg中删除rect元素。
不起作用。
想必我误会了一些东西。
下面的代码段设置了svg。当您按下“清除”按钮时,没有任何反应。
我有3个问题(在代码注释中也有注明);
function init(){
let initialData = [
{x:0,y:0,c:"black"},
{x:0,y:90,c:"orange"},
{x:90,y:0,c:"green"},
{x:90,y:90,c:"yellow"}
];
let nodes = d3.select("#svg").selectAll("dataNode") ;
//console.log(`empty nodes size: ${nodes.size()} all good .. ?`); // reports 0
nodes
.data(initialData)
.enter()
.append(`svg:rect`)
.attr("class", `dataNode`)
.attr("x", function(d){return d.x;})
.attr("y", function(d){return d.y;})
.attr("width", 10)
.attr("height", 10)
.attr("fill", function(d){return d.c;}) ;
//console.log(`initial data nodes size: ${nodes.size()} - Q1. why is this not 4 ?`); //reports 0
};
function clearSVG(){
let nodes = d3.select("#svg").selectAll(".dataNode"); // all 4 rect elements in the svg
//console.log(`nodes size: ${nodes.size()}`);// looking good.. 4 nodes reported
let newData = [] ; // nada, no data
nodes.data(newData) ; // join nothing to the rects - no datum for any element in the selection
//console.log(`exit size: ${nodes.exit().size()} - Q2. Why is this 0 and not 4 ?`);
nodes.exit().remove();
//console.log(`Q3. Why are the rects still present ?`);
};
init();
*{
border:none;
padding:0;
font-family:Arial;
box-sizing:border-box;
}
body{
margin:10px;
}
#svg{
display: inline-block ;
width:100px;
height:100px;
}
#plotBackGround{
fill: #FBFBFB;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg id="svg" viewBox="0 0 100 100" >
<rect id="plotBackGround" x="0" y="0" width="100" height="100"></rect>
</svg>
<BR><BR>
<button class="btn btn-primary" onclick="clearSVG();">Clear</button>
修改
总结已接受答案的症结所在; selection.data()、. enter()、. append()、. exit()和.remove()返回 new 选择。他们不会 不 修改被调用的选择,或者返回对其或其部分的引用。
结束编辑
答案 0 :(得分:3)
这里的问题非常简单:您没有正确的更新选择。
让我们看看。您首先要这样做:
let nodes = d3.select("#svg").selectAll(".dataNode");
然后,您更改数据:
let newData = [];
nodes.data(newData);
但是,您没有更改nodes
,它们保持原样。以后再做:
nodes.exit().remove();
您实际上只是在这样做:
d3.select("#svg").selectAll(".dataNode").exit().remove();
如您所见,这毫无意义。
写正确的更新选择。应该是:
nodes = nodes.data(newData);
如果我们替换nodes
的值,它将有效地为我们提供:
d3.select("#svg").selectAll(".dataNode").data(newData).exit().remove();
这是仅有更改的代码:
function init(){
let initialData = [
{x:0,y:0,c:"black"},
{x:0,y:90,c:"orange"},
{x:90,y:0,c:"green"},
{x:90,y:90,c:"yellow"}
];
let nodes = d3.select("#svg").selectAll("dataNode") ;
//console.log(`empty nodes size: ${nodes.size()} all good .. ?`); // reports 0
nodes
.data(initialData)
.enter()
.append(`svg:rect`)
.attr("class", `dataNode`)
.attr("x", function(d){return d.x;})
.attr("y", function(d){return d.y;})
.attr("width", 10)
.attr("height", 10)
.attr("fill", function(d){return d.c;}) ;
//console.log(`initial data nodes size: ${nodes.size()} - Q1. why is this not 4 ?`); //reports 0
};
function clearSVG(){
let nodes = d3.select("#svg").selectAll(".dataNode"); // all 4 rect elements in the svg
//console.log(`nodes size: ${nodes.size()}`);// looking good.. 4 nodes reported
let newData = [] ; // nada, no data
nodes = nodes.data(newData) ; // join nothing to the rects - no datum for any element in the selection
//console.log(`exit size: ${nodes.exit().size()} - Q2. Why is this 0 and not 4 ?`);
nodes.exit().remove();
//console.log(`Q3. Why are the rects still present ?`);
};
init();
*{
border:none;
padding:0;
font-family:Arial;
box-sizing:border-box;
}
body{
margin:10px;
}
#svg{
display: inline-block ;
width:100px;
height:100px;
}
#plotBackGround{
fill: #FBFBFB;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg id="svg" viewBox="0 0 100 100" >
<rect id="plotBackGround" x="0" y="0" width="100" height="100"></rect>
</svg>
<BR><BR>
<button class="btn btn-primary" onclick="clearSVG();">Clear</button>