0

I am trying to make my tree have a straight links between the parent node and the children nodes. I have straight links now but the links are not connecting to the right places. I think this may be because there is a transformation of rotation and translate to the nodes and the x and y didn't change somehow.

I have tried following the answer in this question but result is the same. D3: Substituting d3.svg.diagonal() with d3.svg.line()

 var lines = svg.selectAll('line')
      .data(links)
      .enter()
      .append('line')
      .attr('stroke','#000')

lines.attr('x1',function(d){return d.source.x })
    .attr('y1',function(d){return d.source.x})
    .attr('x2',function(d){return d.target.x })
    .attr('y2',function(d){return d.target.y })

Here is the full code:

    var diameter = 1000;

var tree = d3.layout.tree()
    .size([360, diameter / 2 - 100])
    .separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; });

 // var diagonal = d3.svg.diagonal.radial()
 // .projection(function(d) { 

 //  return [d.y, d.x ]; })

var svg = d3.select("body").append("svg")
    .attr("width", diameter)
    .attr("height", diameter )
  .append("g")
    .attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");


d3.json("flare.json", function(error, root) {

  var nodes = tree.nodes(root),
      links = tree.links(nodes);

  var link = svg.selectAll(".link")
      .data(links)
      .enter().append("path")
      .attr("class", "link")


   var lines = svg.selectAll('line')
          .data(links)
          .enter()
          .append('line')
          .attr('stroke','#000')

    lines.attr('x1',function(d){return d.source.x })
        .attr('y1',function(d){return d.source.x})
        .attr('x2',function(d){return d.target.x })
        .attr('y2',function(d){return d.target.y })


  var node = svg.selectAll(".node")
      .data(nodes)
      .enter()
      .append("g")
      .attr("class", "node")
      .attr("transform", function(d) { return "rotate(" + (d.x - 90 ) + ")translate(" + d.y + ")"; })

  node.append("circle")
      .attr("r", 10);


  node.append("text")
      .attr("dy", ".81em")
      .attr("text-anchor", function(d) {
       return d.x < 180 ? "start" : "end"; })
      .attr("transform", function(d) { return d.x < 180 ? "translate(20)" : "rotate(180)translate(-20)"; })
      .text(function(d) { return d.name; });

});

d3.select(self.frameElement).style("height", diameter - 150 + "px");

screenshotsscreenshot1

screenshot2

Community
  • 1
  • 1
miracle-doh
  • 596
  • 1
  • 4
  • 19

1 Answers1

2

I finally got it to work.. The solution is quite bizarre. There is no projection method for line as there is for diagonal. So when resetting the positions of x1,x2,y1,y2 needs a little bit tuning just like the diagonal projection.

Also I have to apply the transformation like how the nodes are applied but without the translation.

var link = svg.selectAll("link")
   .data(links)
   .enter().append("path")
   .attr("class", "link")



var lines = svg.selectAll('line')
      .data(links)
      .enter()
      .append('line')
      .attr('stroke','#000')


lines.attr('x1',function(d){return d.source.y})
    .attr('y1',function(d){return d.source.x/180*Math.PI})
    .attr('x2',function(d){return d.target.y })
    .attr('y2',function(d){return d.target.x/180*Math.PI})

    // lines.attr("transform", function(d) {
    //  return "rotate(" + (d.source.x - 90 ) + ")translate(" + d.source.y + ")"; })

   lines.attr("transform", function(d) {      
     return "rotate(" + (d.target.x - 90 ) + ")"; })
miracle-doh
  • 596
  • 1
  • 4
  • 19
  • Brilliant ! I had exactly the same problem and this helped ! But i thing it's not quite accurate, my lines are not really at the center of the nodes. Are yours ? – Romain Bruckert May 18 '15 at 16:13
  • I don't quite remember this, you can check the finished codes here..https://github.com/liaoxsong/liaoxsong.github.io/blob/master/d3project/engine.js – miracle-doh May 19 '15 at 15:03