Home > Software engineering >  Is there a method to highlight the order of edges according to ID in D3?
Is there a method to highlight the order of edges according to ID in D3?

Time:02-02

I am having a GV file (Final_Graph.gv) like this:

digraph Final_Graph {
    graph [center=true rankdir=LR ratio=compress size="15,10"]
    a
    b
    c
    d
    a -> b [label = 1 id=1]
    a -> c [label = 2 id=2]
    a -> d [label = 3 id=3]
    b -> d [label = 4 id=4]
    c -> d [label = 5 id=5]

    subgraph cluster_1{
        color=lightgrey style=filled
        label="A"
        a
        b
    }
    
    subgraph cluster_2{
        color=lightgrey style=filled
        label="B"
        a
        b
    }
    
    subgraph cluster_3{
        color=lightgrey style=filled
        label="C"
        c
        d
    }
}


function renderString(str){
    graphviz.tweenShapes(false)
    .renderDot(str);
    
}

function render() {
fetch('Final_Graph.gv').then(response  => response.text()).then(textAsString => 
     renderString(textAsString));
}

rendered GV

I have written my code in D3.js so that each of the edges would be highlighted (change color to red) according to its ID, so a->b would be highlighted first with id=1, followed up by a->c (id=2), and so on.

Here is my current code in D3 (Please note that my code is in D3 v5, so I am not sure that this code could be compatible with the newer versions):

let graphviz = d3.select(".graph").graphviz()
.transition(function () {
    return d3.transition("main")
        .ease(d3.easeLinear)
        .delay(500)
        .duration(1500);}
)
.logEvents(true)
.on("initEnd", render)
.on("end", function() {
    
    d3.selectAll("g.edge").sort(function(a,b){ // Set up edges.
        return a["id"] - b["id"];
    });
    let link = d3.selectAll("path");
    
    link.each(function(d, i) {
        setTimeout(function() {
            
            d3.select(link.nodes()[i]).transition().style("stroke", "red");
        }, i * 1000);
    })
});

However when I load the website, the edges are not highlighted in ascending order as my idea; instead the highlighting order is 5->1->2->3->4. I have checked in my console and adding ID for nodes, as well as rearranging nodes according to ID; however that also did not solve the problem.

So is there any method to make edges in this graph highlighted with ID from 1 to 5 as I mentioned?

CodePudding user response:

I'm unable to run your code so I'm unclear on exactly what is going on there. Note, though, that

div
  .selectAll(".edge")
  .nodes()
  .forEach(...)

should iterate through the edges in the order in which they were laid down so there should be no need to sort.

You can find working code that accomplishes what you want in enter image description here

I think you might capture the viewer's attention more strongly with some motion, though - like so:

enter image description here

Code for both images can be found in that same Observable notebook, which runs much more smoothly than the animations here.

  • Related