Created TooltipWrapper (#88)
continuous-integration/drone/push Build is passing Details

Co-authored-by: shahanneda <shahan.neda@gmail.com>
Reviewed-on: #88
Reviewed-by: Mark Chiu <e26chiu@csclub.uwaterloo.ca>
This commit is contained in:
Shahan Nedadahandeh 2022-11-16 21:35:55 -05:00
parent e061850575
commit 97aa2261f2
11 changed files with 316 additions and 325 deletions

View File

@ -6,33 +6,3 @@
fill: var(--primary-accent);
filter: drop-shadow(0 0 calc(4rem / 16) var(--primary-accent));
}
.tooltip {
font-family: "Inconsolata", monospace;
top: 0;
left: 0;
position: absolute;
background-color: var(--label);
color: var(--primary-background);
pointer-events: none;
padding: calc(10rem / 16);
border-radius: calc(10rem / 16);
}
.tooltip .category {
margin: calc(10rem / 16) 0 0 0;
font-size: calc(16rem / 16);
font-weight: 700;
}
.tooltip .toolTipData {
margin-top: calc(5rem / 16);
margin-bottom: calc(10rem / 16);
font-size: calc(16rem / 16);
}
.tooltip .toolTipData p {
margin: 0;
padding: 0;
font-size: calc(16rem / 16);
}

View File

@ -6,11 +6,13 @@ import { Point } from "@visx/point";
import { scaleBand, scaleLinear } from "@visx/scale";
import { Line } from "@visx/shape";
import { BoxPlot as VisxBoxPlot } from "@visx/stats";
import { withTooltip, Tooltip } from "@visx/tooltip";
import { withTooltip } from "@visx/tooltip";
import { WithTooltipProvidedProps } from "@visx/tooltip/lib/enhancers/withTooltip";
import React from "react";
import { Color } from "utils/Color";
import { TooltipWrapper } from "./TooltipWrapper";
import styles from "./Boxplot.module.css";
const DEFAULT_LABEL_SIZE = 16;
@ -339,21 +341,17 @@ export const BoxPlot = withTooltip<StatsPlotProps, TooltipData>(
</svg>
{tooltipOpen && tooltipData && (
<Tooltip
top={tooltipTop}
<TooltipWrapper
left={tooltipLeft}
className={styles.tooltip}
unstyled
top={tooltipTop}
header={tooltipData.category}
>
<p className={styles.category}>{tooltipData.category}</p>
<div className={styles.toolTipData}>
<p>max: {tooltipData.max}</p>
<p>third quartile: {tooltipData.thirdQuartile}</p>
<p>median: {tooltipData.median}</p>
<p>first quartile: {tooltipData.firstQuartile}</p>
<p>min: {tooltipData.min}</p>
</div>
</Tooltip>
</TooltipWrapper>
)}
</div>
);

View File

@ -8,20 +8,6 @@
filter: drop-shadow(0 0 calc(4rem / 16) var(--primary-accent));
}
.tooltip {
font-family: "Inconsolata", monospace;
font-weight: bold;
top: 0;
left: 0;
position: absolute;
background-color: var(--label);
color: var(--primary-background);
box-shadow: 0px calc(1rem / 16) calc(2rem / 16) var(--card-background);
pointer-events: none;
padding: calc(10rem / 16);
font-size: calc(18rem / 16);
border-radius: calc(10rem / 16);
}
.wrapper {
display: flex;

View File

@ -8,10 +8,12 @@ import { LegendOrdinal } from "@visx/legend";
import { Point } from "@visx/point";
import { scaleBand, scaleLinear, scaleOrdinal } from "@visx/scale";
import { LinePath } from "@visx/shape";
import { useTooltip, useTooltipInPortal } from "@visx/tooltip";
import { withTooltip } from "@visx/tooltip";
import React from "react";
import { Color } from "utils/Color";
import { TooltipWrapper } from "./TooltipWrapper";
import styles from "./LineGraph.module.css";
interface LineData {
@ -85,8 +87,11 @@ const DEFAULT_LEGEND_GAP = 16;
// TODO: Address unused props in this file
/* eslint-disable unused-imports/no-unused-vars*/
export function LineGraph(props: LineGraphProps) {
const {
type TooltipData = string;
export const LineGraph = withTooltip<LineGraphProps, TooltipData>(
({
width,
height,
margin,
@ -101,9 +106,14 @@ export function LineGraph(props: LineGraphProps) {
yAxisLabel,
yAxisLabelSize = DEFAULT_LABEL_SIZE,
yAxisLabelOffset = 0,
tooltipOpen,
tooltipLeft,
tooltipTop,
tooltipData,
hideTooltip,
showTooltip,
legendProps,
} = props;
}) => {
const {
position: legendPosition = "right",
itemLabelSize: legendLabelSize = DEFAULT_LABEL_SIZE,
@ -119,22 +129,6 @@ export function LineGraph(props: LineGraphProps) {
}
});
const {
tooltipData,
tooltipLeft,
tooltipTop,
tooltipOpen,
showTooltip,
hideTooltip,
} = useTooltip();
const { containerRef, TooltipInPortal } = useTooltipInPortal({
// use TooltipWithBounds
detectBounds: true,
// when tooltip containers are scrolled, this will correctly update the Tooltip position
scroll: true,
});
const yMax = height - margin.top - margin.bottom;
const xMax = width - margin.left - margin.right;
@ -175,12 +169,14 @@ export function LineGraph(props: LineGraphProps) {
return (
<div
className={className ? `${className} ${styles.wrapper}` : styles.wrapper}
className={
className ? `${className} ${styles.wrapper}` : styles.wrapper
}
style={{
flexDirection: legendPosition === "right" ? "row" : "column-reverse",
}}
>
<svg ref={containerRef} width={width} height={height}>
<svg width={width} height={height}>
<Group top={margin.top} left={margin.left}>
<GridColumns
scale={xScale}
@ -296,16 +292,13 @@ export function LineGraph(props: LineGraphProps) {
/>
{tooltipOpen && (
<TooltipInPortal
<TooltipWrapper
top={tooltipTop}
left={tooltipLeft}
className={styles.tooltip}
unstyled
applyPositionStyle
>
<>{tooltipData}</>
</TooltipInPortal>
header={tooltipData as string}
></TooltipWrapper>
)}
</div>
);
}
}
);

View File

@ -13,23 +13,6 @@
top: 0;
}
.toolTip {
font-family: "Inconsolata", monospace;
top: 0;
left: 0;
position: absolute;
background-color: var(--label);
color: var(--primary-background);
pointer-events: none;
border-radius: calc(10rem / 16);
padding: calc(10rem / 16);
}
.toolTip p {
margin: 0 calc(5rem / 16);
font-size: calc(16rem / 16);
}
.key {
font-weight: bold;
}

View File

@ -7,11 +7,13 @@ import { Point } from "@visx/point";
import { scaleBand, scaleLinear, scaleOrdinal } from "@visx/scale";
import { BarStack, BarStackHorizontal, Line } from "@visx/shape";
import { SeriesPoint } from "@visx/shape/lib/types";
import { withTooltip, Tooltip } from "@visx/tooltip";
import { withTooltip } from "@visx/tooltip";
import { WithTooltipProvidedProps } from "@visx/tooltip/lib/enhancers/withTooltip";
import React from "react";
import { Color } from "utils/Color";
import { TooltipWrapper } from "./TooltipWrapper";
import styles from "./StackedBarGraph.module.css";
interface StackedBarData {
@ -248,16 +250,14 @@ export const StackedBarGraphVertical = withTooltip<
</div>
{tooltipOpen && tooltipData ? (
<Tooltip
className={styles.toolTip}
<TooltipWrapper
top={tooltipTop}
left={tooltipLeft}
unstyled
header={tooltipData.key}
>
<p className={styles.key}>{tooltipData.key}</p>
<p>{tooltipData.bar.data[tooltipData.key]}</p>
<p>{getCategory(tooltipData.bar.data)}</p>
</Tooltip>
</TooltipWrapper>
) : null}
</div>
);
@ -438,16 +438,14 @@ export const StackedBarGraphHorizontal = withTooltip<
</div>
{tooltipOpen && tooltipData ? (
<Tooltip
className={styles.toolTip}
<TooltipWrapper
top={tooltipTop}
left={tooltipLeft}
unstyled
header={tooltipData.key}
>
<p className={styles.key}>{tooltipData.key}</p>
<p>{tooltipData.bar.data[tooltipData.key]}</p>
<p>{getCategory(tooltipData.bar.data)}</p>
</Tooltip>
</TooltipWrapper>
) : null}
</div>
);

View File

@ -0,0 +1,31 @@
.tooltip {
font-family: "Inconsolata", monospace;
top: 0;
left: 0;
position: absolute;
background-color: var(--label);
pointer-events: none;
padding: calc(10rem / 16);
border-radius: calc(10rem / 16);
font-size: calc(18rem / 16);
}
.header {
color: var(--primary-background);
margin: 0;
font-size: calc(16rem / 16);
font-weight: 700;
}
.body {
color: var(--primary-background);
margin-top: calc(5rem / 16);
font-size: calc(16rem / 16);
}
.body p {
color: var(--primary-background);
margin: 0;
padding: 0;
font-size: calc(16rem / 16) !important;
}

View File

@ -0,0 +1,35 @@
import { Tooltip } from "@visx/tooltip";
import React from "react";
import styles from "./TooltipWrapper.module.css";
type TooltipWrapperProps = {
top?: number;
left?: number;
className?: string;
header?: string;
children?: React.ReactNode;
};
const TooltipWrapper = ({
top,
left,
className,
header,
children,
}: TooltipWrapperProps) => {
return (
<Tooltip
top={top}
left={left}
className={`${styles.tooltip} ${className ?? ""}`}
unstyled
applyPositionStyle
>
{header ? <span className={styles.header}>{header}</span> : null}
{children ? <div className={styles.body}>{children}</div> : null}
</Tooltip>
);
};
export { TooltipWrapper };

View File

@ -3,18 +3,3 @@
text-anchor: "middle";
cursor: default;
}
.tooltip {
font-family: "Inconsolata", monospace;
font-weight: bold;
top: 0;
left: 0;
position: absolute;
background-color: var(--label);
color: var(--primary-background);
box-shadow: 0px calc(1rem / 16) calc(2rem / 16) var(--card-background);
pointer-events: none;
padding: calc(10rem / 16);
font-size: calc(18rem / 16);
border-radius: calc(10rem / 16);
}

View File

@ -2,13 +2,15 @@ import { localPoint } from "@visx/event";
import { Point } from "@visx/point";
import { scaleLog } from "@visx/scale";
import { Text } from "@visx/text";
import { TooltipWithBounds, useTooltip, withTooltip } from "@visx/tooltip";
import { useTooltip, withTooltip } from "@visx/tooltip";
import { Wordcloud as VisxWordcloud } from "@visx/wordcloud";
import React from "react";
import { Color } from "utils/Color";
import { inDevEnvironment } from "utils/inDevEnviroment";
import { useIsMobile } from "utils/isMobile";
import { TooltipWrapper } from "./TooltipWrapper";
import styles from "./WordCloud.module.css";
interface WordCloudProps {
@ -101,17 +103,13 @@ export const WordCloud = withTooltip(
/>
{tooltipOpen && tooltipData ? (
<TooltipWithBounds
<TooltipWrapper
// set this to random so it correctly updates with parent bounds
key={Math.random()}
top={tooltipTop}
left={tooltipLeft}
className={styles.tooltip}
unstyled
applyPositionStyle
>
{tooltipData.text} ({tooltipData.value})
</TooltipWithBounds>
header={`${tooltipData.text} (${tooltipData.value})`}
></TooltipWrapper>
) : null}
</div>
);

View File

@ -1,4 +1,9 @@
import { mockCategoricalData, moreMockCategoricalData } from "data/mocks";
import {
mockBoxPlotData,
mockCategoricalData,
mockLineData,
moreMockCategoricalData,
} from "data/mocks";
import { pageRoutes } from "data/routes";
import React from "react";
import { useWindowDimensions } from "utils/getWindowDimensions";
@ -6,8 +11,10 @@ import { useIsMobile } from "utils/isMobile";
import { BarGraphVertical, BarGraphHorizontal } from "@/components/BarGraph";
import { BottomNav } from "@/components/BottomNav";
import { BoxPlot } from "@/components/Boxplot";
import { ComponentWrapper } from "@/components/ComponentWrapper";
import { Header } from "@/components/Header";
import { LineGraph } from "@/components/LineGraph";
import { SectionHeader } from "@/components/SectionHeader";
import { WordCloud } from "@/components/WordCloud";
@ -53,7 +60,6 @@ export default function SamplePage() {
margin={defaultVerticalBarGraphMargin}
/>
</ComponentWrapper>
<ComponentWrapper
heading="What program are you in?"
bodyText="There are a total of 106 respondents of the CS Class Profile. Interestingly, there are a huge number of students that are just in CS, partially due to the overwhelming number of people in CS as seen in the total demographics."
@ -69,7 +75,6 @@ export default function SamplePage() {
height={defaultGraphHeight}
/>
</ComponentWrapper>
<ComponentWrapper heading="What program are you in?" align="right">
<BarGraphHorizontal
className={styles.barGraphDemo}
@ -80,7 +85,6 @@ export default function SamplePage() {
margin={defaultHorizontalBarGraphMargin}
/>
</ComponentWrapper>
<ComponentWrapper
heading="What program are you in?"
bodyText="There are a total of 106 respondents of the CS Class Profile. Interestingly, there are a huge number of students that are just in CS, partially due to the overwhelming number of people in CS as seen in the total demographics."
@ -95,7 +99,6 @@ export default function SamplePage() {
margin={defaultHorizontalBarGraphMargin}
/>
</ComponentWrapper>
<ComponentWrapper heading="What program are you in?" align="left">
<BarGraphHorizontal
className={styles.barGraphDemo}
@ -105,7 +108,6 @@ export default function SamplePage() {
margin={defaultHorizontalBarGraphMargin}
/>
</ComponentWrapper>
<ComponentWrapper
heading="What program are you in?"
bodyText="There are a total of 106 respondents of the CS Class Profile. Interestingly, there are a huge number of students that are just in CS, partially due to the overwhelming number of people in CS as seen in the total demographics."
@ -121,7 +123,6 @@ export default function SamplePage() {
height={defaultGraphHeight}
/>
</ComponentWrapper>
<ComponentWrapper heading="What program are you in? " align="right">
<WordCloud
data={moreMockCategoricalData.map((word) => ({
@ -142,7 +143,6 @@ export default function SamplePage() {
height={defaultGraphHeight}
/>
</ComponentWrapper>
<ComponentWrapper heading="What program are you in?" align="left">
<WordCloud
data={moreMockCategoricalData.map((word) => ({
@ -153,7 +153,6 @@ export default function SamplePage() {
height={defaultGraphHeight}
/>
</ComponentWrapper>
<ComponentWrapper
heading="What program are you in?"
bodyText="There are a total of 106 respondents of the CS Class Profile. Interestingly, there are a huge number of students that are just in CS, partially due to the overwhelming number of people in CS as seen in the total demographics."
@ -168,7 +167,6 @@ export default function SamplePage() {
margin={defaultHorizontalBarGraphMargin}
/>
</ComponentWrapper>
<ComponentWrapper
heading="What program are you in?"
bodyText="There are a total of 106 respondents of the CS Class Profile. Interestingly, there are a huge number of students that are just in CS, partially due to the overwhelming number of people in CS as seen in the total demographics."
@ -182,18 +180,34 @@ export default function SamplePage() {
margin={defaultHorizontalBarGraphMargin}
/>
</ComponentWrapper>
<ComponentWrapper heading="What program are you in?" align="center">
<WordCloud
data={moreMockCategoricalData.map((word) => ({
text: word.key,
value: word.value,
}))}
width={defaultGraphWidth}
height={defaultGraphHeight}
<BoxPlot
width={600}
height={400}
data={mockBoxPlotData}
margin={{
top: 20,
left: 20,
}}
/>
</ComponentWrapper>
<ComponentWrapper
heading="What program are you in?"
align="right"
bodyText="Pariatur deserunt aute laborum ea adipisicing. Labore labore ipsum duis nisi ea incididunt ipsum occaecat. Ut occaecat et exercitation incididunt sit sit duis deserunt velit culpa nisi et dolore."
>
<LineGraph
data={mockLineData}
width={600}
height={400}
margin={{
top: 20,
bottom: 80,
left: 30,
right: 20,
}}
/>
</ComponentWrapper>
<BottomNav
leftPage={pageRoutes.demographics}
rightPage={pageRoutes.contributors}