简体   繁体   English

D3 v4重新渲染嵌套对象,而enter()和exit()有问题

[英]D3 v4 re-rendering nested objects, having problems with `enter()` and `exit()`

I'm trying to display a number of circles wrapped in <g> elements. 我试图显示包裹在<g>元素中的圆圈。 This wrapping thing is important for me as in real world I want other elements to be in my group as well. 这个包裹性的东西对我很重要,因为在现实世界中,我也希望其他元素也加入我的团队。 The problem is, circles in the below example wont get displayed by first render(myObjects) call, and if you hit render button they are shown. 问题是,以下示例中的圆圈不会通过第一次render(myObjects)调用显示,并且如果您单击render按钮,则会显示它们。

Second problem is when I press update the previously drawn circles are not removed and the new ones will render on top of them. 第二个问题是,当我按“ 更新”时 ,先前绘制的圆圈不会被删除,而新的圆圈将在其上方进行渲染。

 var svg = d3.select('body').append('svg') .attr('width', 250) .attr('height', 250); //render the data function render(datum) { //Bind var groups = svg.selectAll("g").data(datum); groups.enter().append('g'); var circles = groups.append("circle").attr('r', 10) .attr('cx', function(d) { return dx; }) .attr('cy', function(d) { return dy; }); groups.exit().remove(); } var myObjects = [{ x: 100, y: 100 }, { x: 130, y: 120 }, { x: 80, y: 180 }, { x: 180, y: 80 }, { x: 180, y: 40 }]; var newObjects = [{ x: 200, y: 120 }, { x: 150, y: 160 }, { x: 20, y: 80 }, { x: 80, y: 60 }, { x: 100, y: 20 }]; function removeEls() { svg.selectAll('circle').remove(); } render(myObjects); 
 svg { width: 500px; height: 500px } button { float: left } text { text-anchor: middle; } circle { fill: orange; stroke: orange; fill-opacity: 0.5; } 
 <script src="https://d3js.org/d3.v4.min.js"></script> <button onclick="render(newObjects)">Update</button> <button onclick="render(myObjects);">Render</button> <button onclick="removeEls();">removeEls</button> 

You have 2 little issues in your code : 您的代码中有2个小问题:

  1. You have added the circles in the groups instead of groups.enter() , hence the issue of not displaying the circles at the first draw 您已经在groups添加了圆,而不是groups.enter() ,因此在第一次绘制时不显示圆的问题
  2. You forget to add an identifier when you add the data, so the script is unable to detect which data is new and which data is not. 您在添加数据时会忘记添加标识符,因此脚本无法检测哪些数据是新数据,哪些数据不是。 I added a dx/dy identifier, which works in your case, but I advice you to add a true unique identifier. 我添加了一个dx / dy标识符,这种标识符适用于您的情况,但建议您添加一个真正的唯一标识符。 Like add a field id in your list of objects. 就像在对象列表中添加字段ID。

Here is the snippet with the corrections : 这是经过更正的代码段:

 var svg = d3.select('body').append('svg') .attr('width', 250) .attr('height', 250) .append('g'); //render the data function render(datum) { //Bind var groups = svg.selectAll("g").data(datum, d => (dx)/(dy)); var groupEnter = groups.enter().append('g'); var circles = groupEnter.append("circle").attr('r', 10) .attr('cx', function(d) { return dx; }) .attr('cy', function(d) { return dy; }); groups.exit().remove(); } var myObjects = [{ x: 100, y: 100 }, { x: 130, y: 120 }, { x: 80, y: 180},{ x: 180, y: 80 }, { x: 180, y: 40 }]; var newObjects = [{ x: 200, y: 120 }, { x: 150, y: 160 }, { x: 20, y: 80}, { x: 80, y: 60 }, { x: 100, y: 20 }]; function removeEls() { svg.selectAll('circle').remove(); } render(myObjects); 
 svg { width: 500px; height: 500px } button { float: left } text { text-anchor: middle; } circle { fill: orange; stroke: orange; fill-opacity: 0.5; } 
 <script src="https://d3js.org/d3.v4.min.js"></script> <button onclick="render(newObjects)">Update</button> <button onclick="render(myObjects);">Render</button> <button onclick="removeEls();">removeEls</button> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM