Change tooltips in BarGraph

This commit is contained in:
e26chiu 2022-12-15 22:14:26 -05:00
parent d77ebe0f8d
commit 6123616fe5
2 changed files with 307 additions and 270 deletions

View File

@ -19,10 +19,6 @@
filter: drop-shadow(0 0 calc(4rem / 16) var(--primary-accent));
}
.barGroup:hover .barText {
visibility: visible;
}
.tickLabel {
font-family: "Inconsolata", monospace;
font-weight: 800;

View File

@ -1,14 +1,18 @@
import { AxisBottom, AxisLeft } from "@visx/axis";
import { bottomTickLabelProps } from "@visx/axis/lib/axis/AxisBottom";
import { leftTickLabelProps } from "@visx/axis/lib/axis/AxisLeft";
import { localPoint } from "@visx/event";
import { GridColumns, GridRows } from "@visx/grid";
import { Group } from "@visx/group";
import { Point } from "@visx/point";
import { scaleBand, scaleLinear } from "@visx/scale";
import { Bar } from "@visx/shape";
import { Text } from "@visx/text";
import { withTooltip } from "@visx/tooltip";
import React from "react";
import { Color } from "utils/Color";
import { TooltipWrapper } from "./TooltipWrapper";
import styles from "./BarGraph.module.css";
interface BarGraphProps {
@ -29,8 +33,6 @@ interface BarGraphProps {
categoryTickLabelSize?: number;
/** Font size of the value axis tick labels, in pixels. Default is 16px. */
valueTickLabelSize?: number;
/** Font size of the value that appears when hovering over a bar, in pixels. */
hoverLabelSize?: number;
/** Label text for the category axis. */
categoryAxisLabel?: string;
/** Font size of the label for the cateogry axis, in pixels. */
@ -62,8 +64,11 @@ interface BarGraphData {
const DEFAULT_LABEL_SIZE = 16;
export function BarGraphHorizontal(props: BarGraphProps) {
const {
type TooltipData = string;
export const BarGraphHorizontal = withTooltip<BarGraphProps, TooltipData>(
({
width,
height,
margin,
data,
@ -71,7 +76,6 @@ export function BarGraphHorizontal(props: BarGraphProps) {
minWidth = 500,
categoryTickLabelSize = DEFAULT_LABEL_SIZE,
valueTickLabelSize = DEFAULT_LABEL_SIZE,
hoverLabelSize,
categoryAxisLabel,
categoryAxisLabelSize = DEFAULT_LABEL_SIZE,
categoryAxisLabelOffset = 0,
@ -79,8 +83,14 @@ export function BarGraphHorizontal(props: BarGraphProps) {
valueAxisLabelSize = DEFAULT_LABEL_SIZE,
valueAxisLabelOffset = 0,
defaultLabelDy = "0",
} = props;
const width = props.width < minWidth ? minWidth : props.width; // Ensuring graph's width >= minWidth
tooltipOpen,
tooltipLeft,
tooltipTop,
tooltipData,
hideTooltip,
showTooltip,
}) => {
width = width < minWidth ? minWidth : width; // Ensuring graph's width >= minWidth
const barPadding = 0.4;
const categoryMax = height - margin.top - margin.bottom;
@ -105,6 +115,7 @@ export function BarGraphHorizontal(props: BarGraphProps) {
const valuePoint = (d: BarGraphData) => valueScale(getValue(d));
return (
<div>
<svg className={className} width={width} height={height}>
<Group top={margin.top} left={margin.left}>
<Group>
@ -142,32 +153,33 @@ export function BarGraphHorizontal(props: BarGraphProps) {
return (
<Group className={styles.barGroup} key={`bar-${barName}`}>
<Bar
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: getValue(d).toString(),
tooltipTop: eventSvgCoords.y,
tooltipLeft: eventSvgCoords.x,
});
}}
onMouseOut={hideTooltip}
className={styles.bar}
x={0}
y={categoryPoint(d)}
width={barLength}
height={barWidth}
/>
<Text
className={styles.barText}
x={valuePoint(d) - 12}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
y={categoryPoint(d)! + barWidth / 2}
fontSize={hoverLabelSize ?? barWidth * 0.75}
textAnchor="end"
verticalAnchor="middle"
>
{getValue(d)}
</Text>
</Group>
);
})}
</Group>
</Group>
<AxisLeft
scale={categoryScale}
top={margin.top}
left={margin.left}
hideAxisLine
hideTicks
tickLabelProps={() => {
@ -186,8 +198,7 @@ export function BarGraphHorizontal(props: BarGraphProps) {
/>
<AxisBottom
scale={valueScale}
top={margin.top + categoryMax}
left={margin.left}
top={categoryMax}
hideAxisLine
hideTicks
numTicks={5}
@ -206,12 +217,24 @@ export function BarGraphHorizontal(props: BarGraphProps) {
fontSize: `${valueAxisLabelSize / 16}rem`,
}}
/>
</Group>
</svg>
{tooltipOpen && (
<TooltipWrapper
top={tooltipTop}
left={tooltipLeft}
header={tooltipData as string}
></TooltipWrapper>
)}
</div>
);
}
);
export function BarGraphVertical(props: BarGraphProps) {
const {
export const BarGraphVertical = withTooltip<BarGraphProps, TooltipData>(
({
width,
height,
margin,
data,
@ -219,7 +242,6 @@ export function BarGraphVertical(props: BarGraphProps) {
minWidth = 500,
categoryTickLabelSize = DEFAULT_LABEL_SIZE,
valueTickLabelSize = DEFAULT_LABEL_SIZE,
hoverLabelSize,
categoryAxisLabel,
categoryAxisLabelSize = DEFAULT_LABEL_SIZE,
categoryAxisLabelOffset = 0,
@ -230,8 +252,14 @@ export function BarGraphVertical(props: BarGraphProps) {
alternatingLabelSpace = 80,
defaultLabelDy = `0px`,
lowerLabelDy = `30px`,
} = props;
const width = props.width < minWidth ? minWidth : props.width; // Ensuring graph's width >= minWidth
tooltipOpen,
tooltipLeft,
tooltipTop,
tooltipData,
hideTooltip,
showTooltip,
}) => {
width = width < minWidth ? minWidth : width; // Ensuring graph's width >= minWidth
const barPadding = 0.4;
const alternatingLabel = width <= widthAlternatingLabel;
const final_margin_bottom = alternatingLabel
@ -260,6 +288,7 @@ export function BarGraphVertical(props: BarGraphProps) {
const valuePoint = (d: BarGraphData) => valueScale(getValue(d));
return (
<div>
<svg className={className} width={width} height={height}>
<Group top={margin.top} left={margin.left}>
<Group>
@ -297,36 +326,39 @@ export function BarGraphVertical(props: BarGraphProps) {
return (
<Group className={styles.barGroup} key={`bar-${barName}`}>
<Bar
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: getValue(d).toString(),
tooltipTop: eventSvgCoords.y,
tooltipLeft: eventSvgCoords.x,
});
}}
onMouseOut={hideTooltip}
className={styles.bar}
x={categoryPoint(d)}
y={valueMax - barHeight}
width={barWidth}
height={barHeight}
/>
<Text
className={styles.barText}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
x={categoryPoint(d)! + barWidth / 2}
y={valueMax - barHeight + 12}
fontSize={hoverLabelSize ?? barWidth * 0.5}
textAnchor="middle"
verticalAnchor="start"
>
{getValue(d)}
</Text>
</Group>
);
})}
</Group>
</Group>
<AxisBottom
scale={categoryScale}
top={valueMax + margin.top}
left={margin.left}
top={valueMax}
hideAxisLine
hideTicks
tickLabelProps={(value, index) => {
const alternatingDy = index % 2 == 0 ? defaultLabelDy : lowerLabelDy;
const alternatingDy =
index % 2 == 0 ? defaultLabelDy : lowerLabelDy;
return {
...bottomTickLabelProps(),
className: styles.tickLabel,
@ -345,8 +377,6 @@ export function BarGraphVertical(props: BarGraphProps) {
/>
<AxisLeft
scale={valueScale}
top={margin.top}
left={margin.left}
hideAxisLine
hideTicks
numTicks={5}
@ -366,6 +396,17 @@ export function BarGraphVertical(props: BarGraphProps) {
fontSize: `${valueAxisLabelSize / 16}rem`,
}}
/>
</Group>
</svg>
{tooltipOpen && (
<TooltipWrapper
top={tooltipTop}
left={tooltipLeft}
header={tooltipData as string}
></TooltipWrapper>
)}
</div>
);
}
);