I have the following SVG I am drawing using the javasript code below. It will align the labels on a circular route. I want to have a second version where the labels are going to be an the edge of an rectangle but still in the middle of each section of the circual pie chart. I am not able to figure out how to calculate the positions, can anyone help?
Current Code:
// height/width = size of the element containing the circle
// celestialDirectionsDistanceToCenter = distance to the center of the circle
const circleAngle = (2 * Math.PI) / 24;
CELESTIAL_DIRECTIONS.forEach((currentDirection, index) => {
const newIndex = index 2;
elemAttrs[currentDirection] = {
transform: `rotate(${360 - newAngle}, ${
Math.cos(circleAngle * newIndex) *
(width * 0.5 * celestialDirectionsDistanceToCenter)
width * 0.5
}, ${
Math.sin(circleAngle * newIndex) *
(height * 0.5 * celestialDirectionsDistanceToCenter)
height * 0.5
})`,
x:
Math.cos(circleAngle * newIndex) *
(width * 0.5 * celestialDirectionsDistanceToCenter)
width * 0.5,
y:
Math.sin(circleAngle * newIndex) *
(height * 0.5 * celestialDirectionsDistanceToCenter)
height * 0.5,
};
});
Wanted result SVG - Not perfectly aligned
CodePudding user response:
Try normalizing sinusoidal parts of coordinates by the larger component.
const factor = Math.sqrt(2.0) / Math.max(
Math.abs(Math.cos(circleAngle * newIndex)),
Math.abs(Math.sin(circleAngle * newIndex))
)
elemAttrs[currentDirection] = {
transform: `rotate(${360 - newAngle}, ${
factor * Math.cos(circleAngle * newIndex) *
(width * 0.5 * celestialDirectionsDistanceToCenter)
width * 0.5
}, ${
factor * Math.sin(circleAngle * newIndex) *
(height * 0.5 * celestialDirectionsDistanceToCenter)
height * 0.5
})`,
x:
factor * Math.cos(circleAngle * newIndex) *
(width * 0.5 * celestialDirectionsDistanceToCenter)
width * 0.5,
y:
factor * Math.sin(circleAngle * newIndex) *
(height * 0.5 * celestialDirectionsDistanceToCenter)
height * 0.5,
};