Changing an image inside a node after an update of a D3 graph

Viewed 33

I am updating a D3 graph using an async method to call a function called "node_graph.addNode(mesg);".

One of the values of the mesg json is called "level", and addNode does is arrange the nodes higher or lower according the value of that value, as shown here:

enter image description here

There is an array of urls pointing to the different png images.

I would like to have the PNG to change as well.

This works fine, when level changes, the nodes rearrange as expected. However, the PNG doesn't change to reflect the new level. A page refresh works of course.

Where am I going wrong?

I've read somewhere that the correct way is to use inline svg images? (My knowledge of D3 is a bit sketchy.)

Pertinent code follows (edited for brevity):

let levelImage = {
    '1': '/static/img/state_running.png',     
    '3': '/static/img/state_shutoff.png',     
    '5': '/static/img/state_paused.png',      
};

// snip

this.addNode = function (msg) {
    let uuid    = msg['uuid']; 
    let name    = msg['name'];
    let level   = msg['level'];
    let img     = levelImage[level];
    containBox=container.node().getBoundingClientRect();
    /* initial starting position for nodes */
    let x       = Math.random()*containBox.width;
    let y       = Math.random()*containBox.height;
    let index = findNodeIndex(uuid);

    if (index == -1) {
        nodes.push({"id": uuid, "uuid": uuid, "name":name, "img":img, "level": level});
        update();
    }
    else {
        nodes[index].uuid=uuid; 
        nodes[index].level = level;
        nodes[index].img = levelImage[level]; // this gets the correct image given the level value
        update();
    }
    this.start();
}

let update = function () {
    node = vis.select(".nodes").selectAll("g.node")
        .data(nodes);

    let nodeEnter = node.enter().append("g")
        .attr("class", "node")
        .call(d3.drag()
            .on("start", dragstarted)
            .on("drag", dragged)
            .on("end", dragended)
        )
        .on('mouseover' , mouseOver)
        .on('mouseout' , mouseOut);

    nodeEnter.append("defs")
        .attr("id", function(d){ return 'p-'+d.id;})
        .append("pattern")
        .attr("id", function(d){ return 'i-'+d.id;})
        .attr("height", 1)
        .attr("width", 1)
        .append("image")
        .attr("height",  100)
        .attr("width",   100)
        .attr("xlink:href",  function(d){return d.img;});

Thoughts appreciated - Thanks

0 Answers
Related