Add labels

This commit is contained in:
Jared He 2022-06-18 22:35:39 -04:00
parent ea6e2d4c7a
commit b931afd7cc
3 changed files with 69 additions and 44 deletions

View File

@ -1,18 +1,28 @@
.path {
.piePath {
fill: #354265;
}
.text {
display: none;
fill: white;
font-weight: 800;
.labelPath {
fill: var(--primary-background);
}
.group:hover>.path {
.pieText,
.labelText {
fill: white;
font-size: 20px;
font-weight: 800;
font-family: "Inconsolata", "sans-serif";
}
.pieText {
display: none;
}
.group:hover>.piePath {
fill: #EF839D;
filter: drop-shadow(0px 0px 6px #CC5773);
}
.group:hover>.text {
.group:hover>.pieText {
display: inline
}

View File

@ -1,4 +1,5 @@
import { Group } from "@visx/group";
import { Arc } from "@visx/shape";
import Pie, { ProvidedProps } from "@visx/shape/lib/shapes/Pie";
import React, { useState } from "react";
@ -7,13 +8,7 @@ import styles from "./PieChart.module.css";
interface PieChartProps {
data: PieChartData[];
width: number;
height: number;
margin: {
top: number;
bottom: number;
left: number;
right: number;
};
textPadding: number;
className?: string;
}
@ -22,19 +17,31 @@ interface PieChartData {
value: number;
}
export function PieChart(props: PieChartProps) {
export function PieChart({ width, textPadding, ...props }: PieChartProps) {
const pieWidth = width * 0.5 - textPadding;
return (
<svg className={props.className} width={props.width} height={props.height}>
<Group top={props.margin.top} left={props.margin.left}>
<svg className={props.className} width={width} height={width}>
<Group top={width * 0.5} left={width * 0.5}>
<Pie
data={props.data}
fill="aqua"
pieValue={(d: PieChartData) => d.value}
outerRadius={100}
cornerRadius={5}
padAngle={0.1}
cornerRadius={10}
padAngle={0.075}
padRadius={width * 0.7}
innerRadius={width * 0.03}
outerRadius={pieWidth}
>
{(pie) => <PieSlice {...pie} />}
{(pie) => <PieSlices {...pie} isLabel={false} />}
</Pie>
<Pie
data={props.data}
fill="rgb(37, 45, 65)"
pieValue={(d: PieChartData) => d.value}
innerRadius={pieWidth}
outerRadius={width * 0.5}
>
{(pie) => <PieSlices {...pie} isLabel={true} />}
</Pie>
</Group>
</svg>
@ -42,23 +49,34 @@ export function PieChart(props: PieChartProps) {
}
// path, arcs, pie
type PieSliceProps<PieChartData> = ProvidedProps<PieChartData>;
type PieSlicesProps<PieChartData> = ProvidedProps<PieChartData> & {
isLabel: boolean;
};
export function PieSlice(props: PieSliceProps<PieChartData>) {
return props.arcs.map((arc) => {
const [centroidX, centroidY] = props.path.centroid(arc);
const pathArc = props.path(arc);
export function PieSlices({ isLabel, ...props }: PieSlicesProps<PieChartData>) {
return (
<>
{props.arcs.map((arc) => {
const [centroidX, centroidY] = props.path.centroid(arc);
const pathArc = props.path(arc);
return (
<g key={`arc-${arc.data.category}`} className={styles.group}>
<path className={styles.path} d={pathArc} />
<text
className={styles.text}
x={centroidX}
y={centroidY}
textAnchor="middle"
>{`${arc.data.value}%`}</text>
</g>
);
});
return (
<g className={styles.group} key={`arc-${arc.data.category}`}>
<path
className={isLabel ? styles.labelPath : styles.piePath}
d={pathArc}
/>
<text
className={isLabel ? styles.labelText : styles.pieText}
x={centroidX}
y={centroidY}
textAnchor="middle"
>
{isLabel ? `${arc.data.category}` : `${arc.data.value}%`}
</text>
</g>
);
})}
</>
);
}

View File

@ -8,12 +8,9 @@ export default function Home() {
<>
<h1>Playground</h1>
<p>Show off your components here!</p>
<PieChart
data={mockPieData}
width={500}
height={500}
margin={{ top: 100, left: 100, bottom: 100, right: 100 }}
/>
<div style={{ padding: "30px" }}>
<PieChart data={mockPieData} width={600} textPadding={100} />
</div>
</>
);
}