Reputation: 43
I'm trying to write a click, toggle function on the nodes in a d3 force layout and haven't been anything that helps me figure out how to get this working. The idea is that when you click on a node, an svg appears from the left side of the screen, and when you click again, it disappears. Here is the code that I'm trying on it without any luck:
var tooltip = svg.append("rect")
.attr("x", -300)
.attr("y", 0)
.attr("width", 300)
.attr("height", height)
.attr("color", "black")
.attr("opacity", 0.8);
var toggleWindow = (function () {
var currentStatus = -300;
return function () {
currentStatus = currentStatus === -300 ? 0 : -300;
d3.select(tooltip).attr("x", currentStatus);
};
})();
var node = svg.selectAll(".node")
.data(json.nodes)
.enter().append("g")
.on("mouseover", mouseover)
.on("mouseout", mouseout)
.on("click", toggleWindow)
.call(force.drag);
And here's a link to the full code: http://plnkr.co/edit/nwmUN4RzAwam9dE5bCEj?p=preview
Upvotes: 1
Views: 754
Reputation: 32327
This is how you do it. First make a tooltip group.
var tooltip = svg.append("g").attr("transform", "translate(-300,0)");
//add rectangle to the group
tooltip.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", 300)
.attr("height", height)
.attr("color", "black")
.attr("opacity", 0.8);
On node click
var node = svg.selectAll(".node")
.data(json.nodes)
.enter().append("g")
.on("mouseover", mouseover)
.on("mouseout", mouseout)
.on("click", function(d) {
if (tooltip.data && d.name == tooltip.data.name) {
//if clicked on the same node again close
tooltip.classed("open", false);
tooltip
.transition()
.attr("transform", "translate(-300,0)")//slide via translate
.duration(1000);
tooltip.data = undefined;//set the data to be undefined since the tooltip is closed
return;
}
tooltip.data = d;//set the data to the opened node
tooltip.classed("open", true);//set the class as open since the tooltip is opened
tooltip
.transition()
.attr("transform", "translate(0,0)")
.duration(1000);
d3.selectAll(".text-tip").remove(); //remove old text
tooltip.append("text")//set the value to the text
.attr("transform", "translate(10,100)")
.attr("class","text-tip").text(d.name);
})
Working example here.
Upvotes: 1
Reputation: 117
Simply you can add :
Need to define :
var COLLAPSE_LEVEL = 1
And use the below code :
function toggleAll(d) {
if (d.children) {
d.children.forEach(toggleAll);
if (d.level < COLLAPSE_LEVEL) {
return;
}
toggle(d);
}
}
function toggle(d) {
if (d.children) {
d._children = d.children;
d.children= null;
} else {
d.children= d._children;
d._children = null;
}
}
Upvotes: 0