1

I am using d3 to create collapsable tree. Pretty much following this guide.

I am trying to add labels to path.

Here is my code to add labels to path.

  var text = this.svg.append("text")
             .append("textPath")
             .attr("text-anchor", "middle")
             .attr("xlink:href", "#blahblah")
             .text((d)=> { return d.weight; });

The labels are rendered upside down the path. Not sure, what exactly is wrong. Any suggestions?

Update

Here is my path code

  let link = this.svg.selectAll('path.link')
  .data(links, function (d) {
    return d.id;
  });

// Enter any new links at the parent's previous position.
let linkEnter = link.enter().insert('path', 'g')
  .attr('class', 'link')
  .attr('id', (d) => {
    return d.id;
  })
.attr('d', (d) => {
  let o = { x: source.x0, y: source.y0 };
  return this.diagonal(o, o);
});

let linkUpdate = linkEnter.merge(link);

// Transition back to the parent element position
linkUpdate.transition()
  .duration(this.duration)
  .attr('d', (d) => {
    return this.diagonal(d, d.parent);
  });

// Remove any exiting links
let linkExit = link.exit().transition()
  .duration(this.duration)
  .attr('d', (d) => {
    let o = { x: source.x, y: source.y };
    return this.diagonal(o, o);
  })
  .remove();

 private diagonal = (s, d) => {
      let path = `M ${s.y},${s.x}
                  C ${(s.y + d.y) / 2},${s.x},
                  ${(s.y + d.y) / 2},${d.x},
                  ${d.y},${d.x}`;

      return path;
  }

enter image description here

Aj1
  • 953
  • 2
  • 15
  • 42
  • 3
    Your text path sources ("#blahblah") seem to have the paths the wrong way around (going right-to-left). Please show the code that constructs those paths. – ccprog Aug 23 '18 at 17:15
  • @ccprog thank you. updated my question with path code. – Aj1 Aug 23 '18 at 17:24
  • 2
    what if you swap the `s` and `d` parameters of the `diagonal` function? – rioV8 Aug 23 '18 at 17:27
  • @rioV8 thank you. It worked. – Aj1 Aug 23 '18 at 17:39
  • Have a look at your `d` attributes of the `path` elements. They most likely contain a lot of white space because template strings are multiline – rioV8 Aug 23 '18 at 17:50
  • @Aj1 Since this is D3 v4/v5, why don't you use link shapes? Have a look here: https://stackoverflow.com/a/44760465/5768908 – Gerardo Furtado Aug 27 '18 at 05:22

1 Answers1

2

The link is drawn by this function:

private diagonal = (s, d) => {
    let path = `M ${s.y},${s.x}
                C ${(s.y + d.y) / 2},${s.x},
                ${(s.y + d.y) / 2},${d.x},
                ${d.y},${d.x}`;

    return path;
}

So, it goes from the point in the first argument to the second. Accordingly, your update function should swap the arguments:

linkUpdate.transition()
  .duration(this.duration)
  .attr('d', (d) => {
    return this.diagonal(d.parent, d);
  });
ccprog
  • 20,308
  • 4
  • 27
  • 44