3

I'm currently using dagre-d3 and graphlib API to draw a directed graph. The language I use is typescript. My use case is I don't want to render the whole graph at one time. What I need to implement is show some nodes at first and then dynamically add adjacent nodes by clicking the current node. My question focuses on how to update the graph. The API I use to re-render is still dagreD3.render(). Other than that, I didn't find other API in dagre-d3 to just add additional nodes. It seems like it re-render the whole graph, not just updating the added nodes, because I notice that the order of nodes has changed when I call dagreD3.render() for the second time. Is there any way to just add the additional nodes without changing the positions of existing nodes?

Besides, I set click event handler and some styles after the render(inner,g) function. If I use dagreD3.render() to re-render the graph, I need to set the event handler and styles again. Am I using dagreD3.render() correctly?

I'm using typescript language. So the code is in a class. I set Graph and render as members in class. And they are used in both functions.

class directedGraph{
    // The original graph.
    var g = new dagreD3.graphlib.Graph().setGraph({});
    var render = new dagreD3.render();

    function generateGraph() {
    // Add some nodes and edges to g. Omitting for loop here.
    this.g.setNode(node.Id, ...);
    this.g.setEdge(edge.v, edge.w,...);
    var svg = d3.select("svg"),
    var inner = svg.select("g");
    // Set up zoom support
    var zoom = d3.zoom().on("zoom", function() {
          inner.attr("transform", d3.event.transform);
        });
    svg.call(zoom);

    // Run the renderer. This is what draws the final graph.
    this.render(inner, this.g);
    // Set styles
    inner.selectAll('g.node').select('text')....
    // Add click event handler.
    inner.selectAll('g.node').on('click', () => {.....})
    }
    //////////////////////////////////////////////////
    // The updateGraph() function is triggered by a button outside the
    // graph. The updateGraph() is almost the same as generateGraph() 
    // except the zoom part.
    //////////////////////////////////////////////////
    function updateGraph() {
      // Add additional nodes and edges to g. Omitting for loop here.
      this.g.setNode(node.Id, ...);
      this.g.setEdge(edge.v, edge.w,...);
      var svg = d3.select("svg"),
      var inner = svg.select("g");

      // Run the renderer. This is what draws the final graph.
      this.render(inner, this.g);
      // Set styles to the element.
      inner.selectAll('g.node').select('text').style(...);
      // Add click event handler.
      inner.selectAll('g.node').on('click', () => {.....});
    }
  }
L.L
  • 126
  • 1
  • 1
  • 8
  • 1
    I don't think, that this is possible. Every added node, can have effect of the whole graph. And you have to calculate the whole graph again, to know that. – HexXx Jan 05 '20 at 11:51
  • 1
    refer this link may get some idea https://github.com/dagrejs/dagre-d3/blob/master/demo/etl-status.html – ferozcoder Feb 25 '20 at 08:39

0 Answers0