如何用HTML/CSS/SVG结合React.js制作可动态分块的半轮形图表
React 实现动态分块半圆组件
核心思路
用 SVG 路径结合 React 状态管理,根据分块数动态计算每个扇形的角度,生成对应图形元素,实现分块数量实时调整。
完整实现代码
import { useState } from 'react'; const DynamicHalfCircle = () => { // 分块数状态,默认设为6 const [segmentCount, setSegmentCount] = useState(6); // 半圆半径 const radius = 150; // SVG画布尺寸(留出边距) const viewBox = `0 0 ${radius * 2} ${radius}`; // 圆心坐标 const centerX = radius; const centerY = radius; // 每个扇形的弧度(半圆为π弧度) const segmentAngle = Math.PI / segmentCount; // 分块颜色数组,可自定义 const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7', '#DDA0DD', '#98FB98']; // 生成单个扇形的路径数据 const getSegmentPath = (index) => { const startAngle = index * segmentAngle; const endAngle = startAngle + segmentAngle; // 计算弧的起始/结束点坐标(SVG Y轴向下,所以sin取反) const startX = centerX + radius * Math.cos(startAngle); const startY = centerY - radius * Math.sin(startAngle); const endX = centerX + radius * Math.cos(endAngle); const endY = centerY - radius * Math.sin(endAngle); // 大弧标志:扇形角度小于π,设为0 const largeArcFlag = segmentAngle > Math.PI ? 1 : 0; // path指令:圆心 -> 起始点 -> 圆弧到结束点 -> 闭合路径 return `M ${centerX} ${centerY} L ${startX} ${startY} A ${radius} ${radius} 0 ${largeArcFlag} 0 ${endX} ${endY} Z`; }; return ( <div style={{ textAlign: 'center', padding: '20px' }}> <div style={{ marginBottom: '20px' }}> <label>分块数:</label> <input type="number" min="2" max="20" value={segmentCount} onChange={(e) => setSegmentCount(Number(e.target.value))} style={{ width: '60px', padding: '4px', marginLeft: '8px' }} /> </div> <svg viewBox={viewBox} style={{ width: '300px', height: '150px' }}> {Array.from({ length: segmentCount }).map((_, index) => ( <path key={index} d={getSegmentPath(index)} fill={colors[index % colors.length]} stroke="#fff" strokeWidth="2" /> ))} </svg> </div> ); }; export default DynamicHalfCircle;
代码说明
- 状态管理:用
useState维护分块数,输入框修改时实时更新状态,触发组件重渲染。 - 角度计算:将半圆(π弧度)平均分配给每个分块,计算每个扇形的起始/结束角度。
- 路径生成:通过
path指令绘制扇形,从圆心出发,连接弧的起始点,绘制圆弧到结束点后闭合路径。 - 动态渲染:根据分块数循环生成对应数量的扇形路径,颜色通过数组循环取色,保证分块区分度。
使用方式
直接将该组件导入React项目使用,调整输入框数值即可看到分块数动态变化效果。
内容的提问来源于stack exchange,提问作者Mamun Ahmed
相关产品推荐
相关产品推荐

