javascript - 为什么 selection.exit().size() 为零?
问题描述
我正在尝试通过将空数组加入 d3 选择来从 svg 中删除 rect 元素。
它不工作。
大概我误解了什么。
下面的代码片段设置了 svg。当您按下“清除”按钮时,没有任何反应。
我有 3 个问题(也标记在代码注释中);
- 为什么在加入 4 个数据项并创建 4 个关联元素后选择不报告大小 4?
- 在 clearSVG 函数中,为什么将“no”数据加入现有选择后 exit() 大小为 0。
- 为什么没有删除矩形(可能在 Q2 中回答)。
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() 返回新的选择。它们不会修改调用它们的选择或返回对它或其部分的引用。
结束编辑
解决方案
问题
这里的问题很简单:您没有正确的更新选择。
让我们来看看。你首先这样做:
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>
推荐阅读
- kubernetes - VSCode 的 kubernetes 开发设置中不可用的功能
- php - 收到错误未定义类型'http\Client'
- javascript - 如何在 React JS 中的 Pdf 文档上放置图像和签名
- ios - 如何区分 qmake for iOS 应用程序中的 makefile 和 Xcode 项目生成阶段?
- azure - Terraform - 如何查找用于网络对等互连的 Azure Kubernetes AKS vnet ID
- nestjs - 如何在nestjs中向客户端广播?
- version - MINIO:对象的GetVersions
- openlayers - Openlayers,更新样式后功能消失
- react-native - store.dispatch 没有更新 redux 中的状态?
- android - 将视图绑定与 Fragments Android 结合使用