简体   繁体   中英

D3.js: Text labels dissapear when I click on the second svg element

I am new to D3.js and trying to make a visualization in which I am facing a problem wherein, I have two Bubble Charts in my display as two separate SVG elements, as shown below:

SVG Elements

Now, the problem is that when I click on one of the SVG elements, the text labels from the second disappear and vice-versa, as shown: On Clicking one of the charts

and: When I click on the SVG as well, it disappears

The code for the above is as follows:

<script type="text/javascript">

            var svg = d3.select("#svg1"),
                margin = 20,
                diameter = +svg.attr("width"),
                g = svg.append("g").attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");

            var color = d3.scaleLinear()
                .domain([-1, 5])
                .range(["hsl(200,80%,80%)", "hsl(128,30%,90%)"])
                .interpolate(d3.interpolateHcl);

            var pack = d3.pack()
                .size([diameter - margin, diameter - margin])
                .padding(2);

            d3.json("flare.json", function(error, root) {
              if (error) throw error;

              root = d3.hierarchy(root)
                  .sum(function(d) { return d.size; })
                  .sort(function(a, b) { return b.value - a.value; });

              var focus = root,
                  nodes = pack(root).descendants(),
                  view;

              var circle = g.selectAll("circle")
                .data(nodes)
                .enter().append("circle")
                  .attr("class", function(d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; })
                  .style("fill", function(d,i) { 
                    console.log(d.data.name);
                    return d.data.color ? d.data.color : "ff99bb"; })
                  .on("click", function(d) { if (focus !== d) zoom(d), d3.event.stopPropagation(); });

              var text = g.selectAll("text")
                .data(nodes)
                .enter().append("text")
                  .attr("class", "label")
                  .style("fill-opacity", function(d) { return d.parent === root ? 1 : 0; })
                  .style("display", function(d) { return d.parent === root ? "inline" : "none"; })
                  .style("font-size", function(d){ return d.parent === root ? "12px" : "24px";})
                      .text(function(d) { return d.data.name; });

              var node = g.selectAll("circle,text");

              svg
                  .style("background", "#ffffff ") // change color of the square
                  .on("click", function() { zoom(root); });

              zoomTo([root.x, root.y, root.r * 2 + margin]);

              function zoom(d) {
                var focus0 = focus; focus = d;

                var transition = d3.transition()
                    .duration(d3.event.altKey ? 7500 : 750)
                    .tween("zoom", function(d) {
                      var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + margin]);
                      return function(t) { zoomTo(i(t)); };
                    });

                transition.selectAll("text")
                  .filter(function(d) { return d.parent === focus || this.style.display === "inline"; })
                    .style("fill-opacity", function(d) { return d.parent === focus ? 1 : 0; })
                    .on("start", function(d) { if (d.parent === focus) this.style.display = "inline"; })
                    .on("end", function(d) { if (d.parent !== focus) this.style.display = "none"; });
              }

              function zoomTo(v) {
                var k = diameter / v[2]; view = v;
                node.attr("transform", function(d) { return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")"; });
                circle.attr("r", function(d) { return d.r * k; });
              }
            });


///////////////////////////////////////////////////////SVG2///////////////////////////////////////////////////////////////                
// ------------------------------------------------------------------------------------------------
                var svg2 = d3.select("#svg2"),
                    margin2 = 20,
                    diameter2 = +svg2.attr("width"),
                    g2 = svg2.append("g").attr("transform", "translate(" + diameter2 / 2 + "," + diameter2 / 2 + ")");



                    var color2 = d3.scaleLinear()
                    .domain([-1, 5])
                    .range(["hsl(200,80%,80%)", "hsl(128,30%,90%)"])
                    .interpolate(d3.interpolateHcl);

                var pack2 = d3.pack()
                    .size([diameter2 - margin2, diameter2 - margin2])
                    .padding(2);

                d3.json("flare2.json", function(error, root2) {
                  if (error) throw error;

                  root2 = d3.hierarchy(root2)
                      .sum(function(d) { return d.size; })
                      .sort(function(a, b) { return b.value - a.value; });

                  var focus2 = root2,
                      nodes2 = pack(root2).descendants(),
                      view;

                  var circle2 = g2.selectAll("circle")
                    .data(nodes2)
                    .enter().append("circle")
                      .attr("class", function(d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; })
                      .style("fill", function(d,i) { 
                        console.log(d.data.name);
                            return d.data.color ? d.data.color : "#ddccff "; })
                      .on("click", function(d) { if (focus !== d) zoom(d), d3.event.stopPropagation(); });

                  var text2 = g2.selectAll("text")
                    .data(nodes2)
                    .enter().append("text")
                      .attr("class", "label2")
                      .style("fill-opacity", function(d) { return d.parent === root2 ? 1 : 0; })
                      .style("display", function(d) { return d.parent === root2 ? "inline" : "none"; })
                      .style("font-size", function(d){ return d.parent === root2 ? "12px" : "24px";})
                          .text(function(d) { return d.data.name; });

                  var node2 = g2.selectAll("circle,text");

                  svg2
                      .style("background", "#ffffff ") // change color of the square
                      .on("click", function() { zoom(root2); });

                  zoomTo([root2.x, root2.y, root2.r * 2 + margin2]);

                  function zoom(d) {
                    var focus1 = focus; focus = d;

                    var transition2 = d3.transition()
                        .duration(d3.event.altKey ? 7500 : 750)
                        .tween("zoom", function(d) {
                          var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + margin2]);
                          return function(t) { zoomTo(i(t)); };
                        });

                    transition2.selectAll("text")
                      .filter(function(d) { return d.parent === focus || this.style.display === "inline"; })
                        .style("fill-opacity", function(d) { return d.parent === focus ? 1 : 0; })
                        .on("start", function(d) { if (d.parent === focus) this.style.display = "inline"; })
                        .on("end", function(d) { if (d.parent !== focus) this.style.display = "none"; });
                  }

                  function zoomTo(v) {
                    var k = diameter2 / v[2]; view = v;
                    node2.attr("transform", function(d) { return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")"; });
                    circle2.attr("r", function(d) { return d.r * k; });
                  }
                });
</script>

What mistake am I doing in this? Can someone please help me how to make it correct? Thanks in advance!

I believe

.style("fill-opacity", function(d) { return d.parent === focus ? 1 : 0; })

is responsible for this behavior.

dcluo is right that the issue is with the line noted, but the reason is that the following code

transition.selectAll("text")
   .filter(function(d) { return d.parent === focus || this.style.display === "inline"; })
    .style("fill-opacity", function(d) { return d.parent === focus ? 1 : 0; })
    .on("start", function(d) { if (d.parent === focus) this.style.display = "inline"; })
    .on("end", function(d) { if (d.parent !== focus) this.style.display = "none"; });

and the corresponding code in the second svg isn't selective enough.

if you would change the

selectAll("text")

to

selectAll("text.label")

in the first svg zoom method and

selectAll("text.label2") 

in the second svg zoom method

that would only change the opacity in only the nodes for the respective svg containers.

selectAll is just like any other javascript selection method like jQuery's $('input') or plain javascript document.getElementsByTagName("UL"). text is actually a tag name and there is no context passed when it runs to know that it should only run in the parent svg.

Take a look at https://bost.ocks.org/mike/selection/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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