Ultimately, I could not reproduce your problem! The only thing that caught me was when I defined the mouseover and mouseout functions after they were installed in .on (...) In this case, they were undefined to be called and the mouse handlers were not processed, so the functions were simply never called.
Anyway, you can see what I tried here . The code:
var w = 400, h = 400; var vis = d3.select("svg").attr("width", 800).attr("height", 800); var nodes = []; var links = []; for (var i = 0; i < 30; i++) { var node = { label: "node " + i, value: Math.random(), key: i }; nodes.push(node); }; for (var i = 0; i < nodes.length; i++) { for (var j = 0; j < i; j++) { if (Math.random() > .95) links.push({ source: nodes[i], target: nodes[j], weight: Math.random() }); } }; var force = d3.layout.force().size([w, h]).nodes(nodes).links(links); force.start(); var link = vis.selectAll("line.link").data(links).enter().append("line").style("stroke", "#CCC").attr("class", function(d) { return "link source-" + d.source.key + " target-" + d.target.key; }); var mouseover = function(d) { txt.text(JSON.stringify(d)); //txt.text("line.link.target-" + d.key); vis.selectAll("line.link.target-" + d.key).classed("target", true).style("stroke", '#F00'); vis.selectAll("line.link.source-" + d.key).classed("source", true).style("stroke", '#F00'); } var mouseout = function(d) { vis.selectAll("line.link.target-" + d.key).classed("target", false).style("stroke", "#CCC"); vis.selectAll("line.link.source-" + d.key).classed("source", false).style("stroke", "#CCC"); } var node = vis.selectAll("circle.node").data(force.nodes()).enter().append("circle").attr("class", "node").attr("r", 5).style("fill", function(d) { return d3.rgb(55 * d.value, 255 * d.value, 155 * d.value) }).style("stroke", "#FFF").style("stroke-width", 3).on("mouseover", mouseover).on("mouseout", mouseout).call(force.drag); var txt = vis.append('text').attr({ transform: 'translate(5,400)' }).text("Node Info"); var updateLink = function() { this.attr("x1", function(d) { return d.source.x; }).attr("y1", function(d) { return d.source.y; }).attr("x2", function(d) { return d.target.x; }).attr("y2", function(d) { return d.target.y; }); } var updateNode = function() { this.attr("transform", function(d) { return "translate(" + dx + "," + dy + ")"; }); } force.on("tick", function() { node.call(updateNode); link.call(updateLink); });