Donut Chart With visx in React

Patricia Arquette
Lepaskan: 2024-09-21 18:31:02
asal
185 orang telah melayarinya

Donut Chart With visx in React

Hello, In this guide, we will learn how to create a Progress Donut chart using visx. A Donut chart is a variant of a pie chart featuring a central hole, resembling a donut.

Understanding the Math

To effectively implement the features of our chart, it is essential to grasp the mathematical principles behind it. The chart is a circle with 360 degrees or 2 * Pi radians. Here's how we determine the angles for each progress segment :

2 * PI / (number of progress data points)
Salin selepas log masuk

The starting angle for each progress segment is derived by multiplying the index by 2 * Pi divided by the total number of progress data points :

(index) * 2 * PI / (number of progress data points )
Salin selepas log masuk

The ending angle of a progress segment is calculated by adding the progress percentage to the index and then multiplying by 2 * Pi divided by the total number of progress data points :

(index + (progress / 100)) * 2 * PI / (number of progress data points  )
Salin selepas log masuk
Salin selepas log masuk

For the track bar representing remaining progress, the start angle is the same as the end angle of the progress segment, while the end angle is the start angle of the progress segment plus the total progress of that segment.

(index + (progress / 100)) * 2 * PI / (number of progress data points  )
Salin selepas log masuk
Salin selepas log masuk

the track bar endAngle :

(index + 1) * 2 * PI / (number of progress data points)
Salin selepas log masuk

Donut Chart Code

The first step in developing the chart is to organize the necessary data. In the data.js file, you will define symbols for progress data, the progress amount, and corresponding colors.

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

Salin selepas log masuk

Next, let's implement the Donut Chart Component. Utilize the math calculations described above to dynamically generate each progress segment's angles and accompanying track bar.

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

Salin selepas log masuk

Please don't hesitate to reach out if you require further clarification or assistance with constructing the Donut Chart Component. Thank you for reading this article the live demo is here.

Atas ialah kandungan terperinci Donut Chart With visx in React. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!