Выравнивание текста вокруг центра на круговой диаграмме с использованием SVG круга и текста - PullRequest
0 голосов
/ 11 декабря 2019

Я создал круговую диаграмму, используя круги реагирования и svg. Теперь я хочу расположить текстовые метки так, чтобы текст начинался близко к середине круга и продолжался наружу в стиле колеса фортуны.

Это мой код, отображающий svgs. В инструментах Chrome Dev я пытался применить tranform: rotate(45deg); и настроить число, но текст продолжает вылетать за пределы круга.

<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>
``` 

1 Ответ

0 голосов
/ 11 декабря 2019

Проблема в том, что вращение связано с источником, который находится в левом верхнем углу вашего изображения. Самый простой способ обойти это - изменить viewBox так, чтобы источник находился в центре SVG: viewBox="-16 -16 32 32".

Затем вы вычисляете угол на основе смещения и процента.

Я предполагаю, что у вас есть некоторые элементы, подобные этому:

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' },
];

Так что-то вроде этого будет работать:

<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>

Теперь значение x в тексте определяет, как из центра начинается текст.

enter image description here

...