D3.js Odd Rotation Behavior
Solution 1:
When you rotate the rect, you also rotate its coordinate system. So when you later move it 250 along the x axis, you're actually moving it 250 units along a 45 degree axis -- the result of the rotation.
As a rule, when you introduce a transform
attribute as you did for rotate
, you should do all your transformation via this attribute. So, you need to use translate
instead of using the "x"
attribute. Then it would look like this:
svg
.append("rect")
.attr("transform", "translate(250, 0) rotate(45)")
// remove this: .attr("x", 250)
.attr("height", w / 10)
...
This gets you the results I think you're looking for. Now note that the order of transformations matters here: if your transform was "rotate(45) translate(250, 0)"
(i.e. first rotate then translate), you'd get the same, wrong results you got before. That's because when you rotate first, your translation happens, as before, along a rotated x axis.
Solution 2:
In SVG you must set the transform origin to get it to rotate from the center, such as...
.attr("transform", "rotate(45, 250, 100)");
Where 250, 100
is the x and y position of your rect minus it's radius. Putting it all together it would look like...
var svg = d3.select("body")
.append("svg")
.attr("width", 400)
.attr("height", 300);
svg
.append("rect")
.attr("transform", "rotate(30,"+ (diamond.x+diamond.width/2) + ","+ (diamond.y+diamond.width/2) +")")
.attr("x", diamond.x)
.attr("y", diamond.y)
.attr("height", diamond.width)
.attr("width", diamond.width)
.attr("fill", "teal")
You can view a demo here:
Solution 3:
Here is an approach slightly different from the answer Duopixel gave. Here you are not repeating the calculations for X and Y. In Duopixel's example, its a trivial improvement since he is merely referencing a structure. Its often the case that X and Y are functions and I would not want to maintain that loging in two places. This approach allows you to set X and Y a node, then rotate on the center of said node.
You may find that after the rotation, you still want to tweak the final position, which could be done with another transform, or in the case of TEXT, you can use dx, dy.
svgNode.attr("transform", function (d) {
var w = +d3.select(this).attr("x") + (this.getBBox().width / 2) ;
var h = +d3.select(this).attr("y") + (this.getBBox().height / 2);
return "rotate(90," + w + "," + h + ")";
})
Post a Comment for "D3.js Odd Rotation Behavior"