简体   繁体   English

d3 带有 if-else 循环的切换按钮

[英]d3 toggle button with a if-else loop

I am trying to create a data visualization webpage to display bounding boxes(polygons) by taking the coordinates from an annotation file.我正在尝试创建一个数据可视化网页,通过从注释文件中获取坐标来显示边界框(多边形)。

The code is working perfectly fine in terms of displaying the polygons but when I added a hide/unhide d3.select(button) and when I click on the toggle button it displays all the polygons but when I click on it again to hide all the polygons, only one polygon gets hidden and I understood why that is happening该代码在显示多边形方面工作得非常好,但是当我添加一个隐藏/取消隐藏 d3.select(button) 并且当我单击切换按钮时它显示所有多边形但是当我再次单击它以隐藏所有多边形,只有一个多边形被隐藏,我明白为什么会这样

because in the for loop it keeps looping through the coordinates of each polygon one by one and displays it,so during the last iteration of for loop the value of bb is saved and given to 'if(bb)',so it takes only the last bounding box coordinates and hides only that polygon and not all.因为在for循环中它会不断循环遍历每个多边形的坐标并显示它,所以在for循环的最后一次迭代中,bb的值被保存并赋予'if(bb)',所以它只需要最后一个边界框坐标并仅隐藏该多边形而不是全部。

I tried pushing all the bb values into an array and providing that as a parameter to the if() but it still is not working.我尝试将所有 bb 值推入一个数组并将其作为参数提供给 if() 但它仍然无法正常工作。

... ...

          <button>toggle polygon </button>

... ...

... ...

              var bb;
              d3.select('button').on('click', function() {
                 if ( bb ) {
                              bb.remove();
                              // Remove bounding box
                             bb = null;}
                      
                else{
                          for (var line = 2; line < lines.length; line++) { //array to loop through each lines of the annotation file
                        console.log(line + " --> " + lines[line]);
                        var annotationline = lines[line].split(' '),
                            x1 = annotationline[0],
                            y1 = annotationline[1],
                            x2 = annotationline[2],
                            y2 = annotationline[3],
                            x3 = annotationline[4],
                            y3 = annotationline[5],
                            x4 = annotationline[6],
                            y4 = annotationline[7],
                
                             bb= d3.select(template).append("svg")
                            .attr("width", width)
                            .attr("height", height),
                            poly = [{
                                    "x": x1,
                                    "y": y1
                                },
                                {
                                    "x": x2,
                                    "y": y2
                                },
                                {
                                    "x": x3,
                                    "y": y3
                                },
                                {
                                    "x": x4,
                                    "y": y4
                                }
                            ];

                        bb.selectAll("polygon")
                            .data([poly])
                            .enter().append("polygon")
                            .attr("points", function(d) {
                                return d.map(function(d) {
                                    return [d.x, d.y].join(",");
                                }).join(" ");
                            })
                            .attr("stroke","red")
                            .attr("fill", "none");  }
                      }

                   }

... ...

There are two problems in your code.您的代码中有两个问题。

  1. You are appending an svg for each line.您正在为每一行附加一个 svg。
  2. If you append a single svg, you are using data.enter to append it with last poly data which overwrites all other polygons如果附加单个 svg,则使用 data.enter 附加最后一个多边形数据,这会覆盖所有其他多边形

I have updated your code to solve both the issues我已更新您的代码以解决这两个问题

  1. Append an svg once before for loop.在 for 循环之前附加一个 svg。 for each polygon append a group element ( which is a better way to do than svg)为每个多边形附加一个组元素(这比 svg 更好)
  2. We update only group and not complete svg.我们只更新组而不是完整的 svg。

Best way to do is to write data[poly].update method where you can update svg with new polygon data.最好的方法是编写 data[poly].update 方法,您可以在其中使用新的多边形数据更新 svg。 Read on web on how to enter data and update it.在网上阅读有关如何输入数据和更新数据的信息。 https://www.d3indepth.com/enterexit/ https://www.d3indepth.com/enterexit/

For Now below is the code which is working and toggle will remove all the polygons.现在下面是正在运行的代码,并且切换将删除所有多边形。 Your code could have worked with您的代码可以使用

bb.remove(); bb.remove(); d3.select('svg').remove(); d3.select('svg').remove(); // Removing all svgs after removing the latest reference // 删除最新引用后删除所有 svg

Better version of code ( this does not move your coordinates as well).更好的代码版本(这也不会移动您的坐标)。 Learn to check and read html generated by d3 as well.学习检查和阅读 d3 生成的 html。 You should see the output below in full page and read the html generated.您应该在整页中看到下面的输出并阅读生成的 html。

 var bb; d3.select('button').on('click', function() { if (bb) { bb.remove(); // Remove bounding box bb = null; } else { bb = d3.select(".template").append("svg") .attr("width", '300') .attr("height", '400'); for (var line = 2; line < 4; line++) { //array to loop through each lines of the annotation file var annotationline = 9, x1 = 23 * line / 2, y1 = 34 + line, x2 = 27 * line / 2, y2 = 34 + line, x3 = 145 * line / 2, y3 = 65 * line / 2, x4 = 145 * line / 2, y4 = 59 * line / 2, poly = [{ "x": x1, "y": y1 }, { "x": x2, "y": y2 }, { "x": x3, "y": y3 }, { "x": x4, "y": y4 } ]; let g = bb.append('g'); g.selectAll("polygon") .data([poly]) .enter().append("polygon") .attr("points", function(d) { return d.map(function(d) { return [dx, dy].join(","); }).join(" "); }) .attr("stroke", "red") .attr("fill", "none"); } } })
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.4.4/d3.min.js" integrity="sha512-hnFpvCiJ8Fr1lYLqcw6wLgFUOEZ89kWCkO+cEekwcWPIPKyknKV1eZmSSG3UxXfsSuf+z/SgmiYB1zFOg3l2UQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <button>toggle polygon </button> <div class="template"> </div>

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

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