Reputation: 91
I've created a pie chart using react and svg circles. Now I want to position the text labels so that the text starts close to the middle of the circle and continue outwards, wheel of fortune style.
This is my code, rendering the svgs. In chrome dev tools I tried to apply tranform: rotate(45deg);
and adjusting the number but the text keeps flyying away outside the circle.
<svg viewBox="0 0 32 32">
{elements.map((element, index) => (
<g>
<circle
key={_id}
r={16 / 1.0053}
cx={'50%'}
cy={'50%'}
style={{
strokeDasharray: `${percentage}, 100.53`,
strokeDashoffset: -offset,
stroke: segmentColor,
}}
textAnchor="middle"
></circle>
<text
textAnchor="middle"
x={'50%'}
y={'50%'}
fontFamily={'sans-serif'}
fontSize={'20px'}
fill="black"
textAnchor="start"
>
{title}
</text>
</g>
))}
</svg>
```
Upvotes: 0
Views: 694
Reputation: 10979
The issue is that rotation is about the origin, which is the top left of your image. The easiest way around this is to change the viewBox so the origin is in the center of your SVG: viewBox="-16 -16 32 32"
.
Then you calculate the angle based on the offset and the percentage.
I assume you have some elements like this:
const elements = [
{ percentage: 15, offset: 0, title: 'title', segmentColor: 'red' },
{ percentage: 40, offset: 15, title: 'another title', segmentColor: 'blue' },
{ percentage: 25, offset: 55, title: 'and another', segmentColor: 'green' },
{ percentage: 20, offset: 80, title: 'yet another', segmentColor: 'black' },
];
So something like this would work:
<svg viewBox="-16 -16 32 32">
{elements.map((element, index) => {
const angle = (element.offset + element.percentage / 2) * 360 / 100;
return <g key={index}>
<circle
r={15.5}
style={{
fill: 'none',
strokeDasharray: `${element.percentage}, 100.53`,
strokeDashoffset: -element.offset,
stroke: element.segmentColor,
}}
textAnchor="middle"
></circle>
<text
x="10%"
transform={`rotate(${angle})`}
fontFamily={'sans-serif'}
fontSize={'2px'}
fill="black"
textAnchor="start"
alignmentBaseline="middle"
>
{element.title}
</text>
</g>
})}
</svg>
Now the x value on the text determined how from the center the text starts.
Upvotes: 1