Change Pie Char to use tooltips
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
50a637755b
commit
074828d7ae
|
@ -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 (
|
||||
<svg className={className} width={width} height={width}>
|
||||
<Group top={width * 0.5} left={width * 0.5}>
|
||||
<Pie
|
||||
data={data}
|
||||
pieValue={(d: PieChartData) => d.value}
|
||||
cornerRadius={10}
|
||||
padAngle={0.075}
|
||||
padRadius={padRadius}
|
||||
innerRadius={innerRadius}
|
||||
outerRadius={pieWidth}
|
||||
>
|
||||
{(pie) => (
|
||||
<PieSlice
|
||||
{...pie}
|
||||
pieTextSize={pieTextSize}
|
||||
pieTextXOffset={pieTextXOffset}
|
||||
pieTextYOffset={pieTextYOffset}
|
||||
getPieDisplayValueFromDatum={getPieDisplayValueFromDatum}
|
||||
/>
|
||||
)}
|
||||
</Pie>
|
||||
<Pie
|
||||
data={data}
|
||||
pieValue={(d: PieChartData) => d.value}
|
||||
innerRadius={pieWidth}
|
||||
outerRadius={width * 0.5}
|
||||
>
|
||||
{(pie) => (
|
||||
<PieSliceLabel
|
||||
{...pie}
|
||||
labelTextSize={labelTextSize}
|
||||
labelTextXOffset={labelTextXOffset}
|
||||
labelTextYOffset={labelTextYOffset}
|
||||
getLabelDisplayValueFromDatum={getLabelDisplayValueFromDatum}
|
||||
/>
|
||||
)}
|
||||
</Pie>
|
||||
</Group>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
type PieSliceProps<PieChartData> = ProvidedProps<PieChartData> & {
|
||||
pieTextSize: number;
|
||||
pieTextXOffset: number;
|
||||
pieTextYOffset: number;
|
||||
getPieDisplayValueFromDatum: (datum: PieChartData) => string;
|
||||
};
|
||||
|
||||
export function PieSlice({
|
||||
path,
|
||||
arcs,
|
||||
pieTextSize,
|
||||
pieTextXOffset,
|
||||
pieTextYOffset,
|
||||
getPieDisplayValueFromDatum,
|
||||
}: PieSliceProps<PieChartData>) {
|
||||
return (
|
||||
<>
|
||||
{arcs.map((arc) => {
|
||||
const [centroidX, centroidY] = path.centroid(arc);
|
||||
const pathArc = path(arc) as string;
|
||||
|
||||
return (
|
||||
<Group className={styles.group} key={`arc-${arc.data.category}`}>
|
||||
<path className={styles.piePath} d={pathArc} />
|
||||
<Text
|
||||
className={styles.pieText}
|
||||
x={centroidX + pieTextXOffset}
|
||||
y={centroidY + pieTextYOffset}
|
||||
textAnchor="middle"
|
||||
fontSize={pieTextSize}
|
||||
export const PieChart = withTooltip<PieChartProps>(
|
||||
({
|
||||
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 (
|
||||
<div>
|
||||
<svg className={className} width={width} height={width}>
|
||||
<Group top={width * 0.5} left={width * 0.5}>
|
||||
<Pie
|
||||
data={data}
|
||||
pieValue={(d: PieChartData) => d.value}
|
||||
cornerRadius={10}
|
||||
padAngle={0.075}
|
||||
padRadius={padRadius}
|
||||
innerRadius={innerRadius}
|
||||
outerRadius={pieWidth}
|
||||
>
|
||||
{`${getPieDisplayValueFromDatum(arc.data)}`}
|
||||
</Text>
|
||||
{({ arcs, path }) => {
|
||||
return arcs.map((arc) => {
|
||||
const [centroidX, centroidY] = path.centroid(arc);
|
||||
const pathArc = path(arc) as string;
|
||||
return (
|
||||
<Group
|
||||
className={styles.group}
|
||||
key={`arc-${arc.data.category}`}
|
||||
>
|
||||
<path
|
||||
onMouseMove={(e) => {
|
||||
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}
|
||||
/>
|
||||
<Text
|
||||
className={styles.pieText}
|
||||
x={centroidX + pieTextXOffset}
|
||||
y={centroidY + pieTextYOffset}
|
||||
textAnchor="middle"
|
||||
fontSize={pieTextSize}
|
||||
>
|
||||
{`${getPieDisplayValueFromDatum(arc.data)}`}
|
||||
</Text>
|
||||
</Group>
|
||||
);
|
||||
});
|
||||
}}
|
||||
</Pie>
|
||||
<Pie
|
||||
data={data}
|
||||
pieValue={(d: PieChartData) => d.value}
|
||||
innerRadius={pieWidth}
|
||||
outerRadius={width * 0.5}
|
||||
>
|
||||
{(pie) => (
|
||||
<PieSliceLabel
|
||||
{...pie}
|
||||
labelTextSize={labelTextSize}
|
||||
labelTextXOffset={labelTextXOffset}
|
||||
labelTextYOffset={labelTextYOffset}
|
||||
getLabelDisplayValueFromDatum={getLabelDisplayValueFromDatum}
|
||||
/>
|
||||
)}
|
||||
</Pie>
|
||||
</Group>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
</svg>
|
||||
|
||||
{tooltipOpen && (
|
||||
<TooltipWrapper
|
||||
top={tooltipTop}
|
||||
left={tooltipLeft}
|
||||
header={tooltipData as string}
|
||||
></TooltipWrapper>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
type PieSliceLabelProps<PieChartData> = ProvidedProps<PieChartData> & {
|
||||
labelTextSize: number;
|
||||
|
|
Loading…
Reference in New Issue