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:
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.