D3 svg css - rotate line around centre using css

2019-08-27 04:18发布

I have a plunker here - https://plnkr.co/edit/E2SJlCo141NhYatVEFMU?p=preview

I have 3 three bars that are made with a start and finish posiiton.

The start position can be higher or lower than the finish.

I want to draw arrows on the bars to illustrate if the start is before or after the finish.

I'm drawing the arrows on the bars and adding classes based on if the bar is going up or down.

I then wanted to use css to set the direction of the arrows by rotating them.

This is all working but arrow is not rotating around its center and so is positioned off the bar.

Is it possible to rotate the arrow and line around its center

.arrow-up{
  transform: rotate(180deg);
  transform-origin: center center;  
}

标签: css d3.js svg
1条回答
再贱就再见
2楼-- · 2019-08-27 04:50

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.

https://plnkr.co/edit/yQ4X18eb7VCItxXswMww?p=preview

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.

https://plnkr.co/edit/JyT9ORnnMCETgpMyCjm1?p=preview

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.

bar.enter()
    .append("line")
    .attr("x1", d => x(d.phase) + x.bandwidth()/2)  
    .attr("y1", (d, i) => {
      if(d.start < d.finish){
        return y(d.finish)+10;
      }else{
        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;
      }else{
        return y(d.start)-15;
      }
    })  
    .attr('class', (d, i) => {
      return d.start > d.finish ? 'arrow-up' : 'arrow-up'
    })
    .attr("stroke","red")  
    .attr("stroke-width",2)
    .attr("marker-end","url(#arrow)")
    .attr("transform", (d) => {
      console.log(d.start, d.finish)
      console.log(x(d.phase), x.bandwidth()/2)
      return `rotate(180 100 100)`
    })

查看更多
登录 后发表回答