0

How to rotate a bar through aroung the starting point? enter image description here

I want to rotate the green rect bar to point to the center of the circle how to do it.

The code below is how I draw the rect.

    downNode = downNode
    .data(_nodes)
    .attr("id", function (d, i) {
    return "nodeDown" + d.dbId;
    })
    .enter()
    .append("rect")
    .attr("class", "node").attr("class","downExpressed")
    .attr("x", function (d) {
         return Math.sin( Math.PI - (Math.max(0, Math.min(2 * Math.PI, x(d.dx)))+ Math.max(0, Math.min(2* Math.PI, x(d.dx + d.d_dx)))) / 2 ) * Math.max(0, y(d.dy+ d.d_dy)); })
    .attr("height", function (d) {
         var thea = Math.max(0, Math.min(2 * Math.PI, x(d.dx + d.d_dx))) - Math.max(0, Math.min(2 *  Math.PI, x(d.dx)));
         var r = Math.max(0, y(d.dy));
         return Math.min(r * thea, Math.floor(_this.maxLevel));})
    .attr("y", function (d) {
         return Math.cos(Math.PI - (Math.max(0, Math.min(2 * Math.PI, x(d.dx)))+ Math.max(0, Math.min(2 * Math.PI, x(d.dx + d.d_dx)))) / 2) * Math.max(0, y(d.dy+ d.d_dy));})
    .attr("width", function (d) {                                         
        return 1/2*Math.floor((d.expression.downs.length) / DownMax * ( Math.max(0, y(d.dy + d.d_dy)) - Math.max(0, y(d.dy)) ));
       })

First I calculate the angle and r, and then get the x position through rcos(thea) y position rsin(thea);

but the result is not pointing to the center, I need to rotate it aroung the starting point of the rect bar.

Any suggestion, Thanks.

yongnan
  • 405
  • 7
  • 20
  • You are setting the x,y,width,height attributes, shouldn't you rather be setting a `rotate` [transform](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform)? – Mark Dec 11 '14 at 17:21
  • Thanks, The inner red uses the rotate function, the green bar need to put on the outer ring, so I calculate it, and do not use rotate. At last, I use the stacked bar chart, instead of putting in the outer ring and inner ring – yongnan Dec 12 '14 at 17:58

1 Answers1

0

I don´t know what are your restrictions, so i´ll show two possible solutions:

1- you can set the anchor point of the rect element (with the transform attr) at the middle of the circle and rotate around that point.

2- if you don´t want to set the anchor point with the transform you´ll have to do some vector calculations.

First example: in jfiddle http://jsfiddle.net/ym5w0gk5/1/

svg.append("rect")
   .attr("id","myRect")
   .attr("width",30).attr("height",10)
   //this is the relative position to the anchor point
   .attr("x",-80).attr("y",-5)
   //with the transform attribute you define anchor point (translate)
   // and the rotation (rotation). change rotation to make it go around the center.
   .attr("transform","translate("+width/2+","+height/2+")rotate("+rotate+")");

Second example: the next example is a drag function of a rect that is always facing to a point.

here you can find it in jsfiddle http://jsfiddle.net/denimad/shn1u02n/

...
//setup of the draggable rectangle
var drag = d3.behavior.drag().on("drag", dragmove);
svg.append("rect").attr("width",10).attr("height",30).call(drag);
...
function dragmove(d) {
    //get mouse coordinates
    var x = d3.event.x;
    var y = d3.event.y;

    //get the vector (V1) between the mouse coordinates and anchor point coordinates
    V1 ={"x": x-anchorPoint.x,"y":-(y-anchorPoint.y)};

    //get the perpendicular vector (V2) . If you have a vector v with coordinates (x, y), then a vector perpendicular to v is (y, -x) or (-y, x). 
    V2 ={"x": auxvect.x,"y":-auxvect.y)};

    //get the angle between vector (0,1) and V2 .         
    //http://stackoverflow.com/questions/12903547/fastest-way-to-find-the-angle-between-two-points
    ang= Math.acos( V2.x / Math.sqrt(V2.x*auxvect.x + V2.y*V2.y) );
    ang = ang * 180 / Math.PI; //in degrees

    //finally, this is the rotation angle to apply in the transformation
    if(y<anchorPoint.y){
        d3.select(this).attr("transform", "translate(" + x + "," + y + ")rotate("+(-ang)+")");
    }else{
        d3.select(this).attr("transform", "translate(" + x + "," + y + ")rotate("+(ang)+")");
    }


}