>웹 프론트엔드 >JS 튜토리얼 >React에서 visx를 사용한 도넛 차트

React에서 visx를 사용한 도넛 차트

Patricia Arquette
Patricia Arquette원래의
2024-09-21 18:31:02330검색

Donut Chart With visx in React

안녕하세요. 이번 가이드에서는 visx를 사용하여 Progress Donut 차트를 만드는 방법을 알아보겠습니다. 도넛 차트는 도넛처럼 중앙에 구멍이 있는 원형 차트의 변형입니다.

수학의 이해

차트의 기능을 효과적으로 구현하려면 차트의 수학적 원리를 이해하는 것이 필수적입니다. 차트는 360도 또는 2 * 파이 라디안을 갖는 원입니다. 각 진행 세그먼트의 각도를 결정하는 방법은 다음과 같습니다.

2 * PI / (number of progress data points)

각 진행 세그먼트의 시작 각도는 인덱스에 2 * Pi를 총 진행 데이터 포인트 수로 나누어 곱한 값입니다.

(index) * 2 * PI / (number of progress data points )

진행률 세그먼트의 종료 각도는 인덱스에 진행률을 더한 다음 2 * Pi를 총 진행률 데이터 포인트 수로 나누어 계산합니다.

(index + (progress / 100)) * 2 * PI / (number of progress data points  )

남은 진행률을 나타내는 트랙 바의 경우 시작 각도는 진행률 세그먼트의 종료 각도와 동일하고, 종료 각도는 진행률 세그먼트의 시작 각도에 해당 세그먼트의 전체 진행률을 더한 각도입니다.

(index + (progress / 100)) * 2 * PI / (number of progress data points  )

트랙 바 endAngle :

(index + 1) * 2 * PI / (number of progress data points)

도넛 차트 코드

차트 개발의 첫 번째 단계는 필요한 데이터를 정리하는 것입니다. data.js 파일에서는 진행 데이터, 진행 정도 및 해당 색상에 대한 기호를 정의합니다.

export const coins = [
    { symbol: "r", color: "#121212", progress: 30, },
    { symbol: "l", color: "#91235d", progress: 37,  },
    { symbol: "s", color: "#5ef13f", progress: 90,  },
    { symbol: "w", color: "#643dfe", progress: 50, },
    { symbol: "d", color: "#ef0de6", progress: 45, },
];

다음으로 도넛 차트 구성 요소를 구현해 보겠습니다. 위에 설명된 수학 계산을 활용하여 각 진행 세그먼트의 각도와 그에 따른 트랙 바를 동적으로 생성합니다.

import { Pie } from "@visx/shape";
import { Group } from "@visx/group";
import { scaleOrdinal } from "@visx/scale";
import { Text } from "@visx/text";

const margin = { top: 10, right: 10, bottom: 10, left: 10 };
const thickness = 25;

export default function Donut({
    width,
    height,
    data,
    title,
}: {
    width: number;
    height: number;
    data: { symbol: string; progress: number; color: string }[];
    title: string;
}) {

    const innerWidth = width - margin.left - margin.right;
    const innerHeight = height - margin.top - margin.bottom;
    const radius = Math.min(innerWidth, innerHeight) / 2;
    const centerY = innerHeight / 2;
    const centerX = innerWidth / 2;

    const getBrowserColor = scaleOrdinal({
        domain: data.map((d) => d.symbol),
        range: data.map(item => item.color),
    });

    return (
        <svg width={width} height={height}>
            <Group top={centerY + margin.top} left={centerX + margin.left}>
                <Pie
                    data={data}
                    pieValue={(d) => d.progress / 100}
                    outerRadius={radius}
                    innerRadius={radius - thickness + 21}
                >
                    {({ arcs, path }) => {
                        arcs = arcs.map((item, index) => {
                            return ({
                            ...item, 
                                startAngle: (index) * (Math.PI * 2 / data.length),
                                endAngle: (((index + (item.data.progress / 100)) * (Math.PI * 2 / data.length))),
                            })
                        })
                        return (
                            <g >
                                {arcs.map((arc, i) => {
                                    const firstArc = { ...arc, startAngle: arc.startAngle, endAngle: arc.endAngle }
                                    const second = { ...arc, startAngle: arc.endAngle, endAngle: arc.startAngle + Math.PI * 2 /data.length}

                                    return (
                                        <>
                                            <g key={`pie-arc-${i}+1`}>
                                                <path
                                                    className={`arc${i}`}
                                                    d={path(firstArc)}
                                                    fill={getBrowserColor(arc.data.symbol)}
                                                />
                                            </g>
                                            <g key={`pie-arc-${i}+2`}>
                                            <path
                                                className={`arc${i}`}
                                                d={path(second)}
                                                fill={'#E4E4E4'}
                                            />
                                        </g>

                                        </>
                                    )
                                })}
                            </g>
                        )
                    }}
                </Pie>
                <Text className="whitespace-wrap" textAnchor="middle" verticalAnchor={'middle'} fill="black" scaleToFit fontFamily="sans-serif" >
                    {title}
                </Text>
            </Group>

        </svg>)
}

도넛 차트 구성 요소를 구성하는 데 추가 설명이나 도움이 필요한 경우 주저하지 말고 문의해 주세요. 이 기사를 읽어주셔서 감사합니다. 라이브 데모가 여기에 있습니다.

위 내용은 React에서 visx를 사용한 도넛 차트의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.