Reputation: 467
I currently have a D3 Tree layout with nodes that can be added at runtime with text appended to each node. Almost everything works fine except the node.on(..)
functions like node.on("mousedown" ....)
. The problem is that the node itself doesn't respond to a click, the appended text does. I.E. node.on("mousedown",...)
is fired when the appended text is clicked on, not the actual node. Any guidance would be much appreciated! Code for the core function is below, which simply takes in a JSON-style object and a parent id and then inserts that JSON data into the tree as a child of the given parent:
function update(record_to_add, parent) {
if (nodes.length >= 500) return clearInterval(timer);
// Add a new node to a random parent.
var n = {id: nodes.length, Username: record_to_add.Username},
p = nodes[parent];
if (p.children) p.children.push(n); else p.children = [n];
nodes.push(n);
// Recompute the layout and data join.
node = node.data(tree.nodes(root), function(d) { return d.id; });
link = link.data(tree.links(nodes), function(d) { return d.source.id + "-" + d.target.id; });
// Add entering nodes in the parent’s old position.
node.enter().append("circle", "g")
.attr("class", "node")
.attr("r", 10)
.attr("cx", function(d) { return d.parent.px; })
.attr("cy", function(d) { return d.parent.py; });
// Add entering links in the parent’s old position.
link.enter().insert("path", ".node")
.attr("class", "link")
.attr("d", function(d) {
var o = {x: d.source.px, y: d.source.py};
return diagonal({source: o, target: o});
});
node.enter().insert("text")
.attr("x", function(d) { return (d.parent.px);})
.attr("y", function(d) { return (d.parent.py);})
.text(function(d) { return d.Username; });
node.on("mousedown", function (d) {
var g = d3.select(this); // The node
// The class is used to remove the additional text later
console.log("FOO");
});
node.on("mouseover", function (d) {
var g = d3.select(this); // The node
// The class is used to remove the additional text later
var info = g.append('text')
.classed('info', true)
.attr('x', 20)
.attr('y', 10)
.text('More info');
});
// Transition nodes and links to their new positions.
var t = svg.transition()
.duration(duration);
t.selectAll(".link")
.attr("d", diagonal);
t.selectAll(".node")
.attr("cx", function(d) { return d.px = d.x; })
.attr("cy", function(d) { return d.py = d.y; });
t.selectAll("text")
.style("fill-opacity", 1)
.attr("x", function(d) { return d.px = d.x; })
.attr("y", function(d) { return d.py = d.y; });
}
Upvotes: 2
Views: 2307
Reputation: 9359
To avoid text elements getting in the way of your event capturing you can try configuring your text elements to ignore pointer events:
svg text {
pointer-events: none;
}
You can do it directly with d3 as well:
textSelection
.attr('pointer-events', 'none');
Upvotes: 4