hwilson1
hwilson1

Reputation: 499

d3 highlighting nodes on mouseover causes unexpected behaviour when mouse taken off of svg space

I've written some code that highlights (via increased stroke width / change in stroke colour) node visualisations (some circles, some rects) and associated links/nodes when the user 'mouses down' on the node. The highlight disappears when the user 'mouses up'. This all works fine except when the node thats in a clicked state is dragged off of the svg space (technically I've constrained the visualisation to the svg space but obviously the mouse point isn't constrained) and released. The highlight then does not disappear as it should when the mouse button is released.

jsfiddle here - http://jsfiddle.net/hiwilson1/bga0wcLL/.

The method I chose to accomplish the highlighting was to manipulate the underlying objects associated with the clicked visualised node and then update the visualisations, which is all taken care of in the following onmousedown/onmouseup event function:

function highlight(d) {

    if (event.type == "mousedown") {
        d.highlight = 1;
        d.associatedLinks.forEach(function(link, i) {
            link.highlight = 1;
            link.source.highlight = 1;
            link.target.highlight = 1;
        })
    }
    else {
        d.highlight = 0;
        d.associatedLinks.forEach(function(link, i) {
            link.highlight = 0;
            link.source.highlight = 0;
            link.target.highlight = 0;
        })
    }

    svg.selectAll(".node .shape")
        .attr("stroke", function(d) { if (d.highlight == 1) { return "Black"}})
        .attr("stroke-width", function(d) { return (d.highlight == 1) ? 3 : 1 });           

    svg.selectAll(".link")
        .attr("stroke", function(d) { return (d.highlight == 1) ? "Black" : "Grey" })
        .attr("stroke-width", function(d) { return (d.highlight == 1) ? 3 : 1 });
}

Upvotes: 1

Views: 253

Answers (1)

Rob Schmuecker
Rob Schmuecker

Reputation: 8954

You can listen to the mousemove event and make assumptions thereafter. In the highlight function you will set the value of lastHighlightedNode

e.g.

lastHighlightedNode = null;
var svg = d3.select("body").append("svg")
    .attr("width", w)
    .attr("height", h);

d3.select("body").on('mousemove', function () {
    if ((d3.mouse(document.getElementsByTagName('svg')[0])[0] == 0 || d3.mouse(document.getElementsByTagName('svg')[0])[1] == 0) && lastHighlightedNode != null) {
        highlight(lastHighlightedNode);
    };
});


.....



    function highlight(d) {
        lastHighlightedNode = d;

....

Demo: http://jsfiddle.net/bga0wcLL/1/

Upvotes: 1

Related Questions