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 { Group } from "@visx/group";
|
||||||
|
import { Point } from "@visx/point";
|
||||||
import Pie, { ProvidedProps } from "@visx/shape/lib/shapes/Pie";
|
import Pie, { ProvidedProps } from "@visx/shape/lib/shapes/Pie";
|
||||||
import { Text } from "@visx/text";
|
import { Text } from "@visx/text";
|
||||||
|
import { withTooltip } from "@visx/tooltip";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
|
import { TooltipWrapper } from "./TooltipWrapper";
|
||||||
|
|
||||||
import styles from "./PieChart.module.css";
|
import styles from "./PieChart.module.css";
|
||||||
|
|
||||||
interface PieChartProps {
|
interface PieChartProps {
|
||||||
|
@ -39,105 +44,116 @@ interface PieChartData {
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PieChart({
|
export const PieChart = withTooltip<PieChartProps>(
|
||||||
data,
|
({
|
||||||
width,
|
data,
|
||||||
labelWidth,
|
width,
|
||||||
padRadius = width * 0.35,
|
labelWidth,
|
||||||
innerRadius = width * 0.015,
|
padRadius = width * 0.35,
|
||||||
pieTextSize = 40,
|
innerRadius = width * 0.015,
|
||||||
pieTextXOffset = 0,
|
pieTextSize = 40,
|
||||||
pieTextYOffset = 10,
|
pieTextXOffset = 0,
|
||||||
getPieDisplayValueFromDatum = (datum: PieChartData) => `${datum.value}%`,
|
pieTextYOffset = 10,
|
||||||
labelTextSize = 40,
|
getPieDisplayValueFromDatum = (datum: PieChartData) => `${datum.value}%`,
|
||||||
labelTextXOffset = 0,
|
labelTextSize = 40,
|
||||||
labelTextYOffset = 0,
|
labelTextXOffset = 0,
|
||||||
getLabelDisplayValueFromDatum = (datum: PieChartData) => `${datum.category}`,
|
labelTextYOffset = 0,
|
||||||
className,
|
getLabelDisplayValueFromDatum = (datum: PieChartData) =>
|
||||||
}: PieChartProps) {
|
`${datum.category}`,
|
||||||
const pieWidth = width * 0.5 - labelWidth;
|
className,
|
||||||
return (
|
tooltipOpen,
|
||||||
<svg className={className} width={width} height={width}>
|
tooltipLeft,
|
||||||
<Group top={width * 0.5} left={width * 0.5}>
|
tooltipTop,
|
||||||
<Pie
|
tooltipData,
|
||||||
data={data}
|
hideTooltip,
|
||||||
pieValue={(d: PieChartData) => d.value}
|
showTooltip,
|
||||||
cornerRadius={10}
|
}) => {
|
||||||
padAngle={0.075}
|
const pieWidth = width * 0.5 - labelWidth;
|
||||||
padRadius={padRadius}
|
return (
|
||||||
innerRadius={innerRadius}
|
<div>
|
||||||
outerRadius={pieWidth}
|
<svg className={className} width={width} height={width}>
|
||||||
>
|
<Group top={width * 0.5} left={width * 0.5}>
|
||||||
{(pie) => (
|
<Pie
|
||||||
<PieSlice
|
data={data}
|
||||||
{...pie}
|
pieValue={(d: PieChartData) => d.value}
|
||||||
pieTextSize={pieTextSize}
|
cornerRadius={10}
|
||||||
pieTextXOffset={pieTextXOffset}
|
padAngle={0.075}
|
||||||
pieTextYOffset={pieTextYOffset}
|
padRadius={padRadius}
|
||||||
getPieDisplayValueFromDatum={getPieDisplayValueFromDatum}
|
innerRadius={innerRadius}
|
||||||
/>
|
outerRadius={pieWidth}
|
||||||
)}
|
|
||||||
</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}
|
|
||||||
>
|
>
|
||||||
{`${getPieDisplayValueFromDatum(arc.data)}`}
|
{({ arcs, path }) => {
|
||||||
</Text>
|
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>
|
</Group>
|
||||||
);
|
</svg>
|
||||||
})}
|
|
||||||
</>
|
{tooltipOpen && (
|
||||||
);
|
<TooltipWrapper
|
||||||
}
|
top={tooltipTop}
|
||||||
|
left={tooltipLeft}
|
||||||
|
header={tooltipData as string}
|
||||||
|
></TooltipWrapper>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
type PieSliceLabelProps<PieChartData> = ProvidedProps<PieChartData> & {
|
type PieSliceLabelProps<PieChartData> = ProvidedProps<PieChartData> & {
|
||||||
labelTextSize: number;
|
labelTextSize: number;
|
||||||
|
|
Loading…
Reference in New Issue