首頁  >  文章  >  web前端  >  React 中使用 visx 的圓環圖

React 中使用 visx 的圓環圖

Patricia Arquette
Patricia Arquette原創
2024-09-21 18:31:02186瀏覽

Donut Chart With visx in React

您好,在本指南中,我們將學習如何使用 visx 建立進度圓環圖。甜甜圈圖是餅圖的變體,具有中心孔,類似於甜甜圈。

理解數學

為了有效地實現我們圖表的功能,必須掌握背後的數學原理。此圖表是一個 360 度或 2 * Pi 弧度的圓。以下是我們決定每個進度段的角度的方法:

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  )

軌跡欄結束角度:

(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