Accepted answer

This looks like it is an issue with transform-origin support in SVG - "Keywords and percentages refer to the canvas instead of the object itself". see the Browser compatibility section here. That comment was listed for Firefox but I experience the same problem for Chrome too.

To demonstrate I forced all 3 arrows to use the arrow-up class and you can see that they seem to have rotated around the same point.

So, you can use a rotate transform directly on the SVG line. The following plunker has the start of the code you need but you'll need to calculate you centre x and y values form your data.

Here's the bit of code you need, but as I say you'll need to replace 100 100 with you're centre of rotation x and y values. You'll be able to dispense with the arrow-up and arrow-down class too.

    .attr("x1", d => x(d.phase) + x.bandwidth()/2)  
    .attr("y1", (d, i) => {
      if(d.start < d.finish){
        return y(d.finish)+10;
        return y(d.start)+10;
    .attr("x2", d => x(d.phase) + x.bandwidth()/2)  
    .attr("y2", (d, i) => {
      if(d.finish < d.start){
        return y(d.finish)-15;
        return y(d.start)-15;
    .attr('class', (d, i) => {
      return d.start > d.finish ? 'arrow-up' : 'arrow-up'
    .attr("transform", (d) => {
      console.log(d.start, d.finish)
      console.log(x(d.phase), x.bandwidth()/2)
      return `rotate(180 100 100)`

Related Query