IAMTubby IAMTubby - 5 months ago 100
Javascript Question

How do I add a click event to a directed graph using dagre d3.js(javascript library)?

I have been able to draw a directed graph using dagre. However, now I would like to delete a node/edge on clicking it. I can use g.delEdge and g.delNode for deleting but how do I get to know that someone has clicked on the node? Please see my javascript dagre code below and advise me what I need to add to it.(I am reading the required nodes and edges from a json file, parsing the data and plotting them)

function MyFunc()
var buffer = JSON.parse(data);
var nodesarray = new Array();
for(var i=0;i<Object.keys(buffer[0].nodes).length;i++)

// Create the input graph
var g = new dagreD3.Digraph();

//To give styles to nodes
//g.addNode(0, { label: 'Female', labelStyle: 'font-weight: bold;', style: 'stroke: #f66; stroke-width: 10px;', nodeclass: 'type-TOP' });

for(var i=0;i<Object.keys(buffer[0].edges).length;i++)
var source = buffer[0].edges[i].source;
var destination = buffer[0].edges[i].destination;
var weight = buffer[0].edges[i].weight;
var strokewidth = weight*10;
var mystyle='stroke:#f66; stroke-width:';
mystyle = mystyle + strokewidth + 'px';

//To give styles to edges
//g.addEdge(null, 5, 7, { style: 'stroke: #f66; stroke-width: 3px;',label: "Label for the edge" });
g.addEdge(i,source,destination,{style: mystyle,label:weight});

/* Deleting a node/edge example */

// Create the renderer
var renderer = new dagreD3.Renderer();
var l = dagreD3.layout()

// Override drawNodes to add nodeclass as a class to each node in the output
// graph.
var oldDrawNodes = renderer.drawNodes();
renderer.drawNodes(function(graph, root) {
var svgNodes = oldDrawNodes(graph, root);
svgNodes.each(function(u) { d3.select(this).classed(graph.node(u).nodeclass, true); });
return svgNodes;

// Disable pan and zoom

// Set up an SVG group so that we can translate the final graph.
var svg = d3.select('svg'),
svgGroup = svg.append('g');

// Run the renderer. This is what draws the final graph.
var layout = renderer.run(g, d3.select('svg g'));

// Center the graph
var xCenterOffset = (svg.attr('width') - layout.graph().width) / 2;
svgGroup.attr('transform', 'translate(' + xCenterOffset + ', 80)');
svg.attr('height', layout.graph().height + 200);


I see that you've overridden functionality to add class selector, you can add click event handler similarly, see the following example.

    // Override drawNodes to set up the click.
    var oldDrawNodes = renderer.drawNodes();
    renderer.drawNodes(function(g, svg) {
      var svgNodes = oldDrawNodes(g, svg);

      // on click event handler
      svgNodes.on('click', function(d) { console.log('Clicked on node - ' + d); });

      return svgNodes;

for adding click event handler for edges, try something like below given code

    var oldDrawEdges = renderer.drawEdgePaths();
    renderer.drawEdgePaths(function(g, svg) {
        var edges = oldDrawEdges(g, svg);
        edges.on('click', function (edgeId) { alert('Clicked on - ' + edgeId);});
        return edges;