From 074828d7aeadb8ce4f5a6ed3807fd44960bbc7f6 Mon Sep 17 00:00:00 2001 From: e26chiu Date: Fri, 16 Dec 2022 16:24:23 -0500 Subject: [PATCH] Change Pie Char to use tooltips --- components/PieChart.tsx | 210 +++++++++++++++++++++------------------- 1 file changed, 113 insertions(+), 97 deletions(-) diff --git a/components/PieChart.tsx b/components/PieChart.tsx index 536ccfc..b89ee02 100644 --- a/components/PieChart.tsx +++ b/components/PieChart.tsx @@ -1,8 +1,13 @@ +import { localPoint } from "@visx/event"; import { Group } from "@visx/group"; +import { Point } from "@visx/point"; import Pie, { ProvidedProps } from "@visx/shape/lib/shapes/Pie"; import { Text } from "@visx/text"; +import { withTooltip } from "@visx/tooltip"; import React from "react"; +import { TooltipWrapper } from "./TooltipWrapper"; + import styles from "./PieChart.module.css"; interface PieChartProps { @@ -39,105 +44,116 @@ interface PieChartData { value: number; } -export function PieChart({ - data, - width, - labelWidth, - padRadius = width * 0.35, - innerRadius = width * 0.015, - pieTextSize = 40, - pieTextXOffset = 0, - pieTextYOffset = 10, - getPieDisplayValueFromDatum = (datum: PieChartData) => `${datum.value}%`, - labelTextSize = 40, - labelTextXOffset = 0, - labelTextYOffset = 0, - getLabelDisplayValueFromDatum = (datum: PieChartData) => `${datum.category}`, - className, -}: PieChartProps) { - const pieWidth = width * 0.5 - labelWidth; - return ( - - - d.value} - cornerRadius={10} - padAngle={0.075} - padRadius={padRadius} - innerRadius={innerRadius} - outerRadius={pieWidth} - > - {(pie) => ( - - )} - - d.value} - innerRadius={pieWidth} - outerRadius={width * 0.5} - > - {(pie) => ( - - )} - - - - ); -} - -type PieSliceProps = ProvidedProps & { - pieTextSize: number; - pieTextXOffset: number; - pieTextYOffset: number; - getPieDisplayValueFromDatum: (datum: PieChartData) => string; -}; - -export function PieSlice({ - path, - arcs, - pieTextSize, - pieTextXOffset, - pieTextYOffset, - getPieDisplayValueFromDatum, -}: PieSliceProps) { - return ( - <> - {arcs.map((arc) => { - const [centroidX, centroidY] = path.centroid(arc); - const pathArc = path(arc) as string; - - return ( - - - ( + ({ + data, + width, + labelWidth, + padRadius = width * 0.35, + innerRadius = width * 0.015, + pieTextSize = 40, + pieTextXOffset = 0, + pieTextYOffset = 10, + getPieDisplayValueFromDatum = (datum: PieChartData) => `${datum.value}%`, + labelTextSize = 40, + labelTextXOffset = 0, + labelTextYOffset = 0, + getLabelDisplayValueFromDatum = (datum: PieChartData) => + `${datum.category}`, + className, + tooltipOpen, + tooltipLeft, + tooltipTop, + tooltipData, + hideTooltip, + showTooltip, + }) => { + const pieWidth = width * 0.5 - labelWidth; + return ( +
+ + + d.value} + cornerRadius={10} + padAngle={0.075} + padRadius={padRadius} + innerRadius={innerRadius} + outerRadius={pieWidth} > - {`${getPieDisplayValueFromDatum(arc.data)}`} - + {({ arcs, path }) => { + return arcs.map((arc) => { + const [centroidX, centroidY] = path.centroid(arc); + const pathArc = path(arc) as string; + return ( + + { + const eventSvgCoords = localPoint( + // ownerSVGElement is given by visx docs but not recognized by typescript + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + e.target.ownerSVGElement as Element, + e + ) as Point; + showTooltip({ + tooltipData: getPieDisplayValueFromDatum(arc.data), + tooltipTop: eventSvgCoords.y, + tooltipLeft: eventSvgCoords.x, + }); + }} + onMouseOut={hideTooltip} + className={styles.piePath} + d={pathArc} + /> + + {`${getPieDisplayValueFromDatum(arc.data)}`} + + + ); + }); + }} + + d.value} + innerRadius={pieWidth} + outerRadius={width * 0.5} + > + {(pie) => ( + + )} + - ); - })} - - ); -} + + + {tooltipOpen && ( + + )} +
+ ); + } +); type PieSliceLabelProps = ProvidedProps & { labelTextSize: number;