dagre-d3 how to click node and run an event after that
Asked Answered
C

4

6

I am using dagre-d3.js to create hierarchical graph. Now I have a requirement to make the node clickable and perform a function. I am unable to achieve that.

current some of my code looks like

var g = new dagreD3.graphlib.Graph().setGraph({});
g.setNode("TEST", { label: "TEST"})
g.setNode("TEST1", { label: "TEST1"})

g.setEdge("TEST", "TEST1", { label: "open", style: "stroke: green; stroke-width: 2px;fill: none", arrowheadStyle: "fill: green" });

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

var render = new dagreD3.render();
render(inner, g);
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);

I just need to be able to click on TEST or TEST1 and run a function that I wrote to go to that div with same name on page(TEST, TEST1)

I have looked through this, but it doesn't help me. https://github.com/cpettitt/dagre-d3/issues/13 Also this seems to use different method which is not available to me.

Please guide me

Thanks, Nihir

Cautious answered 11/2, 2015 at 1:37 Comment(0)
L
4

Here are 4 mouse events:

d3.selectAll('svg g.comp')
  .on('mouseover', function(d) {
    console.log('mouseover');
  })
  .on('mouseout', function(d) {
    console.log('mouseout');
  })
  .on('mousedown', function(d) {
    console.log('mousedown');
  })
  .on('mouseup', function(d) {
    console.log('mouseup');
  });
Lights answered 23/12, 2015 at 6:41 Comment(1)
also: .on('click', function(d) { ... });Splenectomy
C
3

This sounds like an interesting approach.

But there were some inbuilt method available to which I just figured out

here is my solution

var selections = inner.selectAll("g.node");
        selections
          .on('click', function (d) { ScrollToID(d); });
Cautious answered 12/2, 2015 at 16:0 Comment(0)
T
1

You can use jquery to select the node tag on click, then parse out the node name and pass it into your function. Something like this:

$(document).ready(function() {
  $('.node').click(function() {

    // This gets the node name from the 'class' attribute
    var class_header = $(this).attr('class').split(' ');
    var node_name = class_header[class_header.length - 1]

    // Execute your function
    myFunction(node_name)

  })
})
Tertullian answered 11/2, 2015 at 15:23 Comment(0)
B
-1
var json = {"nodes": [{"name": "Node1", "group": 2},{"name": "Node2","group": 1},{"name": "Node3","group": 1}],
            "links": [{"source": 0,"target": 1,"value": 2},{"source": 0,"target": 2,"value": 2}]};

var width = 960,
height = 500;

var color = d3.scale.category20();

var force = d3.layout.force()
    .charge(-120)
    .linkDistance(30)
    .size([width, height]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)

force.nodes(json.nodes)
    .links(json.links)
    .start();

var link = svg.selectAll(".link")
    .data(json.links)
    .enter().append("line")
    .attr("class", function(d){ return ["link", d.source.name, d.target.name].join(" "); })
    .style("stroke-width", function(d) { return Math.sqrt(d.value); });

// Set up dictionary of neighbors
var node2neighbors = {};
for (var i =0; i < json.nodes.length; i++){
    var name = json.nodes[i].name;
    node2neighbors[name] = json.links.filter(function(d){
            return d.source.name == name || d.target.name == name;
        }).map(function(d){
            return d.source.name == name ? d.target.name : d.source.name;
        });
}

var clickableNodes = ["Node1"];

var nodes = svg.selectAll(".node")
    .data(json.nodes)
    .enter().append("circle")
    .attr("class", "node")
    .attr("id", function(n){ return n.name; })
    .attr("r", 5)
    .style("fill", function(d) { return color(d.group); })
    .call(force.drag)

nodes.filter(function(n){ return clickableNodes.indexOf(n.name) != -1; })
    .on("click", function(n){
        // Determine if current node's neighbors and their links are visible
        var active   = n.active ? false : true // toggle whether node is active
        , newOpacity = active ? 0 : 1;

        // Extract node's name and the names of its neighbors
        var name     = n.name
        , neighbors  = node2neighbors[name];

        // Hide the neighbors and their links
        for (var i = 0; i < neighbors.length; i++){
            d3.select("circle#" + neighbors[i]).style("opacity", newOpacity);
            d3.selectAll("line." + neighbors[i]).style("opacity", newOpacity);
        }
        // Update whether or not the node is active
        n.active = active;
    });

nodes.append("title")
    .text(function(d) { return d.name; });

force.on("tick", function() {
    link.attr("x1", function(d) { return d.source.x; })
    .attr("y1", function(d) { return d.source.y; })
    .attr("x2", function(d) { return d.target.x; })
    .attr("y2", function(d) { return d.target.y; });

    nodes.attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });
});
Balbo answered 26/7, 2018 at 4:5 Comment(1)
Welcome to Stack Overflow. When you're answering questions, it's a good idea to provide some context to your code. Why does the code you posted address the OP's problem? How is your answer different from other answers that were already offered. This is always a good idea, but especially important when you're taking on older questions like this one.Prenotion

© 2022 - 2024 — McMap. All rights reserved.