Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

d3 graph: What code to write in dblclick handler to change a node text

Tags:

d3.js

I create d3 graph in a div element wit class name canvas as follows:

var width  = 960,
    height = 450,
    colors = d3.scale.category10();

var svg = d3.select('.canvas').append('svg').attr('width', width).attr('height', height).style('background-color', '#cccccc'); 

I am using force layout as folows:

var nodes = [],
  lastNodeId = -1,
  links = [];

// init D3 force layout
var force = d3.layout.force()
    .nodes(nodes)
    .links(links)
    .size([width, height])
    .linkDistance(100)
    .linkStrength(1)
    .charge(-500)
    .on('tick', tick)

I add rectangular nodes as follows:

var circle = svg.append('svg:g').selectAll('g');

circle = circle.data(nodes, function(d) { return d.id; });

// update existing nodes 
circle.selectAll('circle')
      .style('fill', 'LightGreen');

// add new nodes
var g = circle.enter().append('svg:g');

g.append('svg:rect')
  .attr('class', 'node')
  .attr('width', 50)
  .attr('height', 50)
  // Adding double click event handler for the node. If the user double clicks on a link,
  // then a window prompt is displayed in which the user inputs the new text for the label.
  // This way the user can change a label text.
  .on('dblclick', function(d) {
var newText = window.prompt("Enter the new node text", "");

d3.select(this).select('text')
      .text(function(d){
    return newText;
      })
})

By default I am putting node id as the text.

var g = circle.enter().append('svg:g'); 
// show node IDs 
g.append('svg:text') 
 .attr('x', 25) 
 .attr('y', 25) 
 .attr('class', 'id') 
 .text(function(d) {return d.id;}); 

As you can see I have added double click handler for nodes. In that the code prompts user to input the new text of the node and the text is put in the node. But the problem is I do not see the node text getting changed. Please let me know what code to write so that the node text changes. And will that method work for changing a link (between nodes) text also?

I create links as follows:

var path = svg.append('svg:g').selectAll('path');
path = path.data(links);

    linkLabels = svg.selectAll("link").data(links).enter()
           .append("text")
           .attr("x", function(d) { return d.source.x + (d.target.x - d.source.x)/2; })
           .attr("y", function(d) { return d.source.y + (d.target.y - d.source.y)/2; })
           .text(function(d) { return (d.source.id + "-" + d.target.id); });

  // add new links
 var edges =  path.enter().append('svg:path')
                  .attr('class', 'link')
                   // Adding double click event handler for the link. If the user double clicks on a link,
           // then a window prompt is displayed in which the user inputs the new text for the label.
           // This way the user can change a label text.
                   .on('dblclick', function(d) {
            var newText = window.prompt("Enter the new label text", d.label);

            d3.select(this.parentEdge).select('text')
                       .text(function(d){
                            return newText;
                    })
                   });

I see the prompt when a link is double clicked but the link text is not getting changed.

like image 710
Avinash Avatar asked Aug 04 '26 10:08

Avinash


1 Answers

The problem is that the text isn't attached to the element that receives the click event, but its parent, so you need to select the parent node and then the text element:

d3.select(this.parentNode).select("text")
like image 126
Lars Kotthoff Avatar answered Aug 07 '26 20:08

Lars Kotthoff



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!