Reputation: 1998
I would like to rotate some text (numbers) that I have positioned around a circle, to appear like this:
To apply the rotation I have tried this: .attr("transform", function(d, i) { return "rotate(" + (-90 + ((360 / dial.length) * i)) + ", 135, 135)"; });
but it throws everything out.
Here's a fiddle.
Upvotes: 3
Views: 1766
Reputation: 101938
The solution from @GerardoFurtado is good, but if you position everything at the origin you can simplify the code quite a bit.
Feel free to accept his answer. I just wanted to point out some efficiencies.
var width = height = 300,
circleRadius = (width / 2) * .8,
digitRadius = (width / 2) * .9;
svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
// Everything inside the group is centred at the origin and we use
// a transform on the group to move the whole group to the centre of the SVG
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
svg.append("circle")
.attr("r", circleRadius)
.style("fill", "none")
.style("stroke", "black");
dial = [1, 2, 3, 4, 5, 6, 7, 8];
// Position text at X=radius, Y=0 and rotate around the origin to get final position
svg.selectAll("text")
.data(dial)
.enter()
.append("text")
.attr("x", digitRadius)
// tweak digit Y position a little to ensure it's centred at desired position
.attr("y", "0.4em")
.text(function(d, i) { return d; })
.attr("transform", function(d, i) { return "rotate(" + (-90 + ((360 / dial.length) * i)) + ")"; });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Upvotes: 2
Reputation: 102218
The solution I found was changing the additional values for rotate
, where <x>
and <y>
values represent the coordinates of the point used as a center of rotation.:
rotate(<a> [<x> <y>])
I changed <x>
and <y>
for center
and changed your x
and y
positions accordingly.
var width = height = 300,
radius = center = (width / 2) * .9;
svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", function(d) { return "translate(" + (radius * .1) / 2 + "," + (radius * .1) / 2 + ")"; });
svg.append("circle")
.attr("cx", radius)
.attr("cy", radius)
.attr("r", radius*.9)
.style("fill", "none")
.style("stroke", "black");
// Calculate dial start and end.
dial = [1, 2, 3, 4, 5, 6, 7, 8];
svg.selectAll("text")
.data(dial)
.enter()
.append("text")
.attr("x", function(d, i) { return center + radius * Math.cos(2 * Math.PI / dial.length-0.75); })
.attr("y", function(d, i) { return center + radius * Math.sin(2 * Math.PI / dial.length-0.75); })
.text(function(d, i) { return d; })
.attr("transform", function(d, i) { return "rotate(" + (-90 + ((360 / dial.length) * i)) + "," + center + "," + center + ")"; });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Here is the fiddle: https://jsfiddle.net/gerardofurtado/24heuL1h/1/
Upvotes: 1