2

Code Snippet : We are using d3.js for this. Sankey diagrams is made up of nodes and links. Here the data comes from json file. So how to make all the nodes clickable. Which methods can we use with the rectangles so that we can make the nodes clickable.

<script>

var margin = {top: 1, right: 1, bottom: 6, left: 1},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var formatNumber = d3.format(",.0f"),   //decimal places
    format = function(d) { return formatNumber(d) + " TWh"; },
    color = d3.scale.category20();

var svg = d3.select("#chart").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var sankey = d3.sankey()
    .nodeWidth(15)
    .nodePadding(10)
    .size([width, height]);

var path = sankey.link();

//d3.json("energy.json", function(energy) {


d3.json("numbers-subset.json", function(energy) {



  sankey
      .nodes(energy.nodes)
      .links(energy.links)
      .layout(32);

  var link = svg.append("g").selectAll(".link")
      .data(energy.links)
    .enter().append("path")
      .attr("class", "link")
      .attr("d", path)
      .style("stroke-width", function(d) { return Math.max(1, d.dy); })
      .sort(function(a, b) { return b.dy - a.dy; });


  link.append("title")
      .text(function(d) { return d.source.name + " → " + d.target.name + "\n" + format(d.value); });


  var node = svg.append("g").selectAll(".node")
      .data(energy.nodes)
    .enter().append("g")
      .attr("class", "node")
      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
    .call(d3.behavior.drag()
      .origin(function(d) { return d; })
      .on("dragstart", function() { this.parentNode.appendChild(this); })
      .on("drag", dragmove));

  node.append("rect")
      .attr("height", function(d) { return d.dy; })
      .attr("width", sankey.nodeWidth())
      .style("fill", function(d) { return d.color = color(d.name.split("|")[0]); })
      .style("stroke", function(d) { return d3.rgb(d.color).darker(2); })
    .append("title")
      .text(function(d) { return d.name + "\n" + format(d.value); });

  node.append("text")
      .attr("x", -6)
      .attr("y", function(d) { return d.dy / 2; })
      .attr("dy", ".35em")
      .attr("text-anchor", "end")
      .attr("transform", null)
      .text(function(d) { return d.name; })
    .filter(function(d) { return d.x < width / 2; })
      .attr("x", 6 + sankey.nodeWidth())
      .attr("text-anchor", "start");

  function dragmove(d) {
    d3.select(this).attr("transform", "translate(" + d.x + "," + (d.y = Math.max(0, Math.min(height - d.dy, d3.event.y))) + ")");
    sankey.relayout();
    link.attr("d", path);
  }



});

</script>
  • Did you figure out a solution to this? I'm wanting to do the same thing. – tmthyjames Jun 19 '15 at 01:48
  • yes i got the solution – Yatin Shirwadkar Jun 25 '15 at 04:03
  • 1
    var node = svg.append("g").selectAll(".node") .data(energy.nodes) .enter().append("g") .attr("class", "node") .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) .call(d3.behavior.drag() .origin(function(d) { return d; }) .on("dragstart", function() { this.parentNode.appendChild(this); }) .on("drag", dragmove) .on("click", function(d){//add the code which you want when click event occurs})); – Yatin Shirwadkar Jun 25 '15 at 04:03
  • 1
    just add the last function .on("click", function(d) { }) – Yatin Shirwadkar Jun 25 '15 at 04:09
  • I ended up doing something similar. Thank you! – tmthyjames Jun 25 '15 at 14:56

1 Answers1

2

D3.js is very powerful library give you control over each event to each pixel. but we need to do one thing in the case of events. Overlapping event we need to by forget .

Add following code in code.

var node = svg.append("g").selectAll(".node")
      .data(graph.nodes)
    .enter().append("g")
      .attr("class", "node")
      .attr("transform", function(d) { 
          return "translate(" + d.x + "," + d.y + ")"; })
    .on("click",function(d){
        if (d3.event.defaultPrevented) return;
        alert("clicked!"+d.value);
    })
    .call(d3.behavior.drag()
      .origin(function(d) { return d; })
      .on("dragstart", function() { 
          this.parentNode.appendChild(this); })
      .on("drag", dragmove));
Yogesh Bombe
  • 325
  • 3
  • 18