1

I want to change the label of the nodes of svg graph using d3.js without rendering it again. I do not want to generate graph again and again but only change the data in node labels.

It seems if I change the label value I need to call "renderer" again which draws the graph again:

this.renderer = new dagreD3.render();
this.renderer(inner, g); // draw final graph
thatOneGuy
  • 9,977
  • 7
  • 48
  • 90
David
  • 63
  • 1
  • 10
  • in D3 you would just have an update function which redraws only elements that have been updated. Look up D3 enter exit should be simple enough. Also, an example would be beneficial so we can take a look at what you have tried :) – thatOneGuy Jun 06 '16 at 12:31

1 Answers1

2

Just take control and do it with straight d3, something like:

var newLabels = ['my', 'new', 'labels'];
d3.selectAll(".node")
  .select("tspan")
  .text(function(d,i){
    return newLabels[i];
  });

This will find all the nodes and the tspan under them hold the label and replace it with new text. Note, it looks like dagre does some work to center the labels and size the rect so you might have to adjust based on the new text.


Here's a fuller example:

// Create a new directed graph
var g = new dagreD3.graphlib.Graph().setGraph({});

// States and transitions from RFC 793
var states = [ "CLOSED", "LISTEN", "SYN RCVD", "SYN SENT",
               "ESTAB", "FINWAIT-1", "CLOSE WAIT", "FINWAIT-2",
               "CLOSING", "LAST-ACK", "TIME WAIT" ];

// Automatically label each of the nodes
states.forEach(function(state) { g.setNode(state, { label: state }); });

// Set up the edges
g.setEdge("CLOSED",     "LISTEN",     { label: "open" });
g.setEdge("LISTEN",     "SYN RCVD",   { label: "rcv SYN" });
g.setEdge("LISTEN",     "SYN SENT",   { label: "send" });
g.setEdge("LISTEN",     "CLOSED",     { label: "close" });
g.setEdge("SYN RCVD",   "FINWAIT-1",  { label: "close" });
g.setEdge("SYN RCVD",   "ESTAB",      { label: "rcv ACK of SYN" });
g.setEdge("SYN SENT",   "SYN RCVD",   { label: "rcv SYN" });
g.setEdge("SYN SENT",   "ESTAB",      { label: "rcv SYN, ACK" });
g.setEdge("SYN SENT",   "CLOSED",     { label: "close" });
g.setEdge("ESTAB",      "FINWAIT-1",  { label: "close" });
g.setEdge("ESTAB",      "CLOSE WAIT", { label: "rcv FIN" });
g.setEdge("FINWAIT-1",  "FINWAIT-2",  { label: "rcv ACK of FIN" });
g.setEdge("FINWAIT-1",  "CLOSING",    { label: "rcv FIN" });
g.setEdge("CLOSE WAIT", "LAST-ACK",   { label: "close" });
g.setEdge("FINWAIT-2",  "TIME WAIT",  { label: "rcv FIN" });
g.setEdge("CLOSING",    "TIME WAIT",  { label: "rcv ACK of FIN" });
g.setEdge("LAST-ACK",   "CLOSED",     { label: "rcv ACK of FIN" });
g.setEdge("TIME WAIT",  "CLOSED",     { label: "timeout=2MSL" });

// Set some general styles
g.nodes().forEach(function(v) {
  var node = g.node(v);
  node.rx = node.ry = 5;
});

// Add some custom colors based on state
g.node('CLOSED').style = "fill: #f77";
g.node('ESTAB').style = "fill: #7f7";

var svg = d3.select("svg"),
    inner = svg.select("g");

// Set up zoom support
var zoom = d3.behavior.zoom().on("zoom", function() {
      inner.attr("transform", "translate(" + d3.event.translate + ")" +
                                  "scale(" + d3.event.scale + ")");
    });
svg.call(zoom);

// Create the renderer
var render = new dagreD3.render();

// Run the renderer. This is what draws the final graph.
render(inner, g);

// Center the graph
var initialScale = 0.75;
zoom
  .translate([(svg.attr("width") - g.graph().width * initialScale) / 2, 20])
  .scale(initialScale)
  .event(svg);
svg.attr('height', g.graph().height * initialScale + 40);


// replace the labels
var newLabels = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven']

d3.selectAll(".node")
      .select("tspan")
      .text(function(d,i){
        return newLabels[i];
      });
body {
  font: 300 14px 'Helvetica Neue', Helvetica;
}

.node rect {
  stroke: #333;
  fill: #fff;
}

.edgePath path {
  stroke: #333;
  fill: #333;
  stroke-width: 1.5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="http://cpettitt.github.io/project/dagre-d3/latest/dagre-d3.js"></script>
<svg width="600" height="600">
<g></g>
</svg>
Mark
  • 106,305
  • 20
  • 172
  • 230
  • I have multi-line code with in each node of a graph. The code you provided updates the very first line of the label but doesn't do anything with the second tspan line (after '\n') with in the same node. I want to change the label of each node as a whole, including line breaks. Code reviews failed : 0/500 – David Jul 17 '16 at 18:25
  • what is 'tspan' ? – simpleuser Jul 19 '18 at 22:41