-
Anonymous
Расчет угла поворота каждого пути на диаграмме круга SVG
Сообщение
Anonymous »
https://jsfiddle.net/p4d57e8x/3/
Код: Выделить всё
const getArcPath = (start, end, innerRadius, outerRadius) => {
const startAngle = start * Math.PI * 2;
const endAngle = end * Math.PI * 2;
const x1 = innerRadius * Math.sin(startAngle);
const y1 = innerRadius * -Math.cos(startAngle);
const x2 = outerRadius * Math.sin(startAngle);
const y2 = outerRadius * -Math.cos(startAngle);
const x3 = outerRadius * Math.sin(endAngle);
const y3 = outerRadius * -Math.cos(endAngle);
const x4 = innerRadius * Math.sin(endAngle);
const y4 = innerRadius * -Math.cos(endAngle);
const bigArc = end - start >= 0.5;
const outerFlags = bigArc ? '1 1 1' : '0 0 1';
const innerFlags = bigArc ? '1 1 0' : '1 0 0';
return `M ${x1},${y1} L ${x2},${y2} A ${outerRadius} ${outerRadius} ${outerFlags} ${x3},${y3}
L ${x4},${y4} A ${innerRadius} ${innerRadius} ${innerFlags} ${x1},${y1} Z`;
};
< /code>
Это код для самого пути, и все пути, которые они создают круг. Пример < /p>
const getRotationAngle = (start, end) => {
const startAngle = start * 360;
const endAngle = end * 360;
return (startAngle + endAngle) / 2;
};
< /code>
Но это, конечно, не работает, потому что это просто тащица для меня, и я понятия не имею, что мне даже нужно рассчитать, чтобы получить угол.const {useState, useEffect, useRef, useMemo} = React;
const PROGRESS_UNIT = 0.01;
const PROGRESS_TIMEOUT = 5;
const getArcPath = (start, end, innerRadius, outerRadius) => {
const gap = 0.01; // Adjust this value to control the gap between arcs
const startAngle = start * Math.PI * 2;
const endAngle = (end - gap) * Math.PI * 2; // Adjusted end angle
const x1 = innerRadius * Math.sin(startAngle);
const y1 = innerRadius * -Math.cos(startAngle);
const x2 = outerRadius * Math.sin(startAngle);
const y2 = outerRadius * -Math.cos(startAngle);
const x3 = outerRadius * Math.sin(endAngle);
const y3 = outerRadius * -Math.cos(endAngle);
const x4 = innerRadius * Math.sin(endAngle);
const y4 = innerRadius * -Math.cos(endAngle);
const bigArc = end - start - gap >= 0.5;
const outerFlags = bigArc ? '1 1 1' : '0 0 1';
const innerFlags = bigArc ? '1 1 0' : '1 0 0';
return {
path: `M ${x1},${y1} L ${x2},${y2} A ${outerRadius} ${outerRadius} ${outerFlags} ${x3},${y3}
L ${x4},${y4} A ${innerRadius} ${innerRadius} ${innerFlags} ${x1},${y1} Z`,
};
};
const DonutChart = ({ width, height, items, innerRadius, outerRadius }) => {
const [visiblePart, setVisiblePart] = useState(0);
const [rotationAngle, setRotationAngle] = useState(0)
useEffect(() => {
if (visiblePart < 1) {
setTimeout(() => setVisiblePart(visiblePart + PROGRESS_UNIT), PROGRESS_TIMEOUT);
}
}, [visiblePart]);
// Usage in DonutChart component
const segments = useMemo(() => {
const sum = items.reduce((sum, item) => sum + item.value, 0);
let start = 0;
var starto = 0;
return items.map((item) => {
const delta = (item.value / sum) * visiblePart;
const { path, rotationAngle } = getArcPath(start, start + delta, innerRadius, outerRadius);
start += delta;
var deg = (360 / sum) * item.value;
item._angle = deg;
starto+= deg;
return { ...item, path, angle: deg };
});
}, [items, innerRadius, outerRadius, visiblePart]);
React.useEffect(() => {
setRotationAngle(segments[0].angle)
}, [segments])
console.log(segments)
return (
{rotationAngle}deg /{segments[0].color}
{segments.map((segment) => (
key={segment.color}
stroke={segment.color}
fill={segment.color}
d={segment.path}
/>
))}
);
};
const items = [
{value: 100, color: 'red'},
{value: 200, color: 'green'},
{value: 300, color: 'blue'},
{value: 150, color: 'purple'},
];
ReactDOM.render(, document.querySelector("#app"))< /code>
svg {
border: 1px solid #888;
}
.pointer {
width: 20px;
height: 20px;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-top: 15px solid #2f2f2f;
margin: 0 auto;
}
div {
position: relative;
}
.info {
margin: 0 auto;
text-align: center;
font-weight: bold;
}
.container {
width: 500px;
}< /code>
Подробнее здесь:
https://stackoverflow.com/questions/783 ... rcle-chart
1757061908
Anonymous
https://jsfiddle.net/p4d57e8x/3/
[code]const getArcPath = (start, end, innerRadius, outerRadius) => {
const startAngle = start * Math.PI * 2;
const endAngle = end * Math.PI * 2;
const x1 = innerRadius * Math.sin(startAngle);
const y1 = innerRadius * -Math.cos(startAngle);
const x2 = outerRadius * Math.sin(startAngle);
const y2 = outerRadius * -Math.cos(startAngle);
const x3 = outerRadius * Math.sin(endAngle);
const y3 = outerRadius * -Math.cos(endAngle);
const x4 = innerRadius * Math.sin(endAngle);
const y4 = innerRadius * -Math.cos(endAngle);
const bigArc = end - start >= 0.5;
const outerFlags = bigArc ? '1 1 1' : '0 0 1';
const innerFlags = bigArc ? '1 1 0' : '1 0 0';
return `M ${x1},${y1} L ${x2},${y2} A ${outerRadius} ${outerRadius} ${outerFlags} ${x3},${y3}
L ${x4},${y4} A ${innerRadius} ${innerRadius} ${innerFlags} ${x1},${y1} Z`;
};
< /code>
Это код для самого пути, и все пути, которые они создают круг. Пример < /p>
const getRotationAngle = (start, end) => {
const startAngle = start * 360;
const endAngle = end * 360;
return (startAngle + endAngle) / 2;
};
< /code>
Но это, конечно, не работает, потому что это просто тащица для меня, и я понятия не имею, что мне даже нужно рассчитать, чтобы получить угол.const {useState, useEffect, useRef, useMemo} = React;
const PROGRESS_UNIT = 0.01;
const PROGRESS_TIMEOUT = 5;
const getArcPath = (start, end, innerRadius, outerRadius) => {
const gap = 0.01; // Adjust this value to control the gap between arcs
const startAngle = start * Math.PI * 2;
const endAngle = (end - gap) * Math.PI * 2; // Adjusted end angle
const x1 = innerRadius * Math.sin(startAngle);
const y1 = innerRadius * -Math.cos(startAngle);
const x2 = outerRadius * Math.sin(startAngle);
const y2 = outerRadius * -Math.cos(startAngle);
const x3 = outerRadius * Math.sin(endAngle);
const y3 = outerRadius * -Math.cos(endAngle);
const x4 = innerRadius * Math.sin(endAngle);
const y4 = innerRadius * -Math.cos(endAngle);
const bigArc = end - start - gap >= 0.5;
const outerFlags = bigArc ? '1 1 1' : '0 0 1';
const innerFlags = bigArc ? '1 1 0' : '1 0 0';
return {
path: `M ${x1},${y1} L ${x2},${y2} A ${outerRadius} ${outerRadius} ${outerFlags} ${x3},${y3}
L ${x4},${y4} A ${innerRadius} ${innerRadius} ${innerFlags} ${x1},${y1} Z`,
};
};
const DonutChart = ({ width, height, items, innerRadius, outerRadius }) => {
const [visiblePart, setVisiblePart] = useState(0);
const [rotationAngle, setRotationAngle] = useState(0)
useEffect(() => {
if (visiblePart < 1) {
setTimeout(() => setVisiblePart(visiblePart + PROGRESS_UNIT), PROGRESS_TIMEOUT);
}
}, [visiblePart]);
// Usage in DonutChart component
const segments = useMemo(() => {
const sum = items.reduce((sum, item) => sum + item.value, 0);
let start = 0;
var starto = 0;
return items.map((item) => {
const delta = (item.value / sum) * visiblePart;
const { path, rotationAngle } = getArcPath(start, start + delta, innerRadius, outerRadius);
start += delta;
var deg = (360 / sum) * item.value;
item._angle = deg;
starto+= deg;
return { ...item, path, angle: deg };
});
}, [items, innerRadius, outerRadius, visiblePart]);
React.useEffect(() => {
setRotationAngle(segments[0].angle)
}, [segments])
console.log(segments)
return (
{rotationAngle}deg /{segments[0].color}
{segments.map((segment) => (
key={segment.color}
stroke={segment.color}
fill={segment.color}
d={segment.path}
/>
))}
);
};
const items = [
{value: 100, color: 'red'},
{value: 200, color: 'green'},
{value: 300, color: 'blue'},
{value: 150, color: 'purple'},
];
ReactDOM.render(, document.querySelector("#app"))< /code>
svg {
border: 1px solid #888;
}
.pointer {
width: 20px;
height: 20px;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-top: 15px solid #2f2f2f;
margin: 0 auto;
}
div {
position: relative;
}
.info {
margin: 0 auto;
text-align: center;
font-weight: bold;
}
.container {
width: 500px;
}< /code>
[/code]
Подробнее здесь: [url]https://stackoverflow.com/questions/78395349/calculating-rotation-angle-of-each-path-on-a-svg-circle-chart[/url]