JavaScript D3: Substituting d3.svg.diagonal() with d3.svg.line()

I have implemented the following graph with the edges rendered with d3.svg.diagonal(). However, when I try substituting the diagonal with d3.svg.line(), it doesn't appear to pull the target and source data. What am I missing? Is there something I don't understand about d3.svg.line?

enter image description here

The following is the code I am referring to, followed by the full code:

var line = d3.svg.line()
    .x(function(d) { return d.lx; })
    .y(function(d) { return d.ly; });

...

var link= svg.selectAll("path")
    .data(links)
  .enter().append("path")
    .attr("d",d3.svg.diagonal())
    .attr("class", ".link")
    .attr("stroke", "black")
    .attr("stroke-width", "2px")
    .attr("shape-rendering", "auto")
    .attr("fill", "none"); 

The entire code:

var margin = {top: 20, right: 20, bottom: 20, left: 20},
    width =1500, 
    height = 1500, 
    diameter = Math.min(width, height),
    radius = diameter / 2;


var balloon = d3.layout.balloon()
  .size([width, height])
  .value(function(d) { return d.size; })
  .gap(50)                  

var line = d3.svg.line()
    .x(function(d) { return d.lx; })
    .y(function(d) { return d.ly; });


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

    root = "flare.json";
    root.y0 = height / 2;
    root.x0 = width / 2;

d3.json("flare.json", function(root) {
  var nodes = balloon.nodes(root),
      links = balloon.links(nodes);


var link= svg.selectAll("path")
    .data(links)
  .enter().append("path")
    .attr("d",d3.svg.diagonal())
    .attr("class", ".link")
    .attr("stroke", "black")
    .attr("stroke-width", "2px")
    .attr("shape-rendering", "auto")
    .attr("fill", "none");   

  var node = svg.selectAll("g.node")
    .data(nodes)
    .enter()
    .append("g")
    .attr("class", "node");

  node.append("circle")
      .attr("r", function(d) { return d.r; })
      .attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });

  node.append("text")
      .attr("dx", function(d) { return d.x })
      .attr("dy", function(d) { return d.y })
      .attr("font-size", "5px")
      .attr("fill", "white")
      .style("text-anchor", function(d) { return d.children ? "middle" : "middle"; })
      .text(function(d) { return d.name; })
});

A comparison of how the d attribute of the svg disappears when using "line." enter image description here enter image description here

Answer:1

Question is quite dated, but since I don't see an answer and someone might face the same problem, here it is.

The reason why simple replacement of diagonal with line is not working is because d3.svg.line and d3.svg.diagonal return different results:

  • d3.svg.diagonal returns function that accepts datum and its index and transforms it to path using projection. In other words diagonal.projection determines how the function will get points' coordinates from supplied datum.
  • d3.svg.line returns function that accepts an array of points of the line and transforms it to path. Methods line.x and line.y determine how coordinates of the point retreived from the single element of supplied array

D3 SVG-Shapes reference

SVG Paths and D3.js

So you can not use result of the d3.svg.line directly in d3 selections (at least when you want to draw multiple lines).

You need to wrap it in another function like this:

var line = d3.svg.line()
                 .x( function(point) { return point.lx; })
                 .y( function(point) { return point.ly; });

function lineData(d){
    // i'm assuming here that supplied datum 
    // is a link between 'source' and 'target'
    var points = [
        {lx: d.source.x, ly: d.source.y},
        {lx: d.target.x, ly: d.target.y}
    ];
    return line(points);
}

// usage:
var link= svg.selectAll("path")
    .data(links)
    .enter().append("path")
    .attr("d",lineData)
    .attr("class", ".link")
    .attr("stroke", "black")
    .attr("stroke-width", "2px")
    .attr("shape-rendering", "auto")
    .attr("fill", "none");   

Here's working version of jsFiddle mobeets posted: jsFiddle

Answer:2

Perhaps encapsulating the diagonal function and editing its parameters could work for you:

var diagonal = d3.svg.diagonal();
var new_diagonal = function (obj, a, b) {
    //Here you may change the reference a bit.
    var nobj = {
        source : {
            x: obj.source.x,
            y: obj.source.y
        },
        target : {
            x: obj.target.x,
            y: obj.target.y
        }
    }
    return diagonal.apply(this, [nobj, a, b]);
}
var link= svg.selectAll("path")
    .data(links)
    .enter().append("path")
    .attr("d",new_diagonal)
    .attr("class", ".link")
    .attr("stroke", "black")
    .attr("stroke-width", "2px")
    .attr("shape-rendering", "auto")
    .attr("fill", "none"); 
Answer:3

How is it possible to detect with an eventListener when mousemove has finished? document.AddEventListener('mousemove', startInteractionTimer, false); function startInteractionTimer(){ ...

How is it possible to detect with an eventListener when mousemove has finished? document.AddEventListener('mousemove', startInteractionTimer, false); function startInteractionTimer(){ ...

I am a n00b in node, and find util.inherits() very useful, except for the fact that it seems to replace the entire prototype of the original object. For instance: var myClass = function(name){ ...

I am a n00b in node, and find util.inherits() very useful, except for the fact that it seems to replace the entire prototype of the original object. For instance: var myClass = function(name){ ...

I need to set the language_in option on the Closure compiler to prevent the IE8 parse error: ERROR - Parse error. IE8 (and below) will parse trailing commas in array and object literals incorrectly. ...

I need to set the language_in option on the Closure compiler to prevent the IE8 parse error: ERROR - Parse error. IE8 (and below) will parse trailing commas in array and object literals incorrectly. ...

I'm looking to implement a warning if the user attempts to leave the order process before it's completed in any fashion other then of course following the payment button. Something like this: <...

I'm looking to implement a warning if the user attempts to leave the order process before it's completed in any fashion other then of course following the payment button. Something like this: <...