Merge branch 'main' of https://git.csclub.uwaterloo.ca/www/cs-2022-class-profile into fix-stackedbar-graph

This commit is contained in:
e26chiu 2022-12-28 22:52:11 -05:00
commit 0b5169d151
23 changed files with 2210 additions and 923 deletions

View File

@ -6,23 +6,11 @@
fill: var(--primary-accent-light);
}
.barText {
visibility: hidden;
font-family: "Inconsolata", monospace;
font-weight: 800;
fill: var(--label);
}
.barGroup:hover .bar {
fill: var(--primary-accent);
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

@ -5,10 +5,12 @@ import { GridColumns, GridRows } from "@visx/grid";
import { Group } from "@visx/group";
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 { getTooltipPosition, TooltipWrapper } from "./TooltipWrapper";
import styles from "./BarGraph.module.css";
interface BarGraphProps {
@ -29,8 +31,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 +62,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 +74,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,139 +81,152 @@ 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
const barPadding = 0.4;
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;
const valueMax = width - margin.left - margin.right;
const categoryMax = height - margin.top - margin.bottom;
const valueMax = width - margin.left - margin.right;
const getCategory = (d: BarGraphData) => d.category;
const getValue = (d: BarGraphData) => d.value;
const getCategory = (d: BarGraphData) => d.category;
const getValue = (d: BarGraphData) => d.value;
const categoryScale = scaleBand({
range: [0, categoryMax],
domain: data.map(getCategory),
padding: barPadding,
});
const categoryScale = scaleBand({
range: [0, categoryMax],
domain: data.map(getCategory),
padding: barPadding,
});
const valueScale = scaleLinear({
range: [0, valueMax],
nice: true,
domain: [0, Math.max(...data.map(getValue))],
});
const valueScale = scaleLinear({
range: [0, valueMax],
nice: true,
domain: [0, Math.max(...data.map(getValue))],
});
const categoryPoint = (d: BarGraphData) => categoryScale(getCategory(d));
const valuePoint = (d: BarGraphData) => valueScale(getValue(d));
const categoryPoint = (d: BarGraphData) => categoryScale(getCategory(d));
const valuePoint = (d: BarGraphData) => valueScale(getValue(d));
return (
<svg className={className} width={width} height={height}>
<Group top={margin.top} left={margin.left}>
<Group>
{data.map((d, idx) => {
const barName = `${getCategory(d)}-${idx}`;
const barWidth = categoryScale.bandwidth();
const backgroundBarWidth = barWidth / (1 - barPadding);
return idx % 2 === 0 ? (
<Bar
className={styles.barBackground}
key={`bar-${barName}-background`}
x={0}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
y={categoryPoint(d)! - (backgroundBarWidth - barWidth) / 2}
width={valueMax}
height={backgroundBarWidth}
/>
) : null;
})}
</Group>
<GridColumns
scale={valueScale}
height={categoryMax}
numTicks={5}
stroke={Color.label}
strokeWidth={4}
strokeDasharray="10"
strokeLinecap="round"
/>
<Group>
{data.map((d, idx) => {
const barName = `${getCategory(d)}-${idx}`;
const barLength = valuePoint(d);
const barWidth = categoryScale.bandwidth();
return (
<Group className={styles.barGroup} key={`bar-${barName}`}>
<Bar
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={() => {
return {
...leftTickLabelProps(),
className: styles.tickLabel,
fontSize: `${categoryTickLabelSize / 16}rem`,
};
}}
label={categoryAxisLabel}
labelClassName={styles.axisLabel}
labelOffset={categoryAxisLabelOffset}
labelProps={{
fontSize: `${categoryAxisLabelSize / 16}rem`,
}}
/>
<AxisBottom
scale={valueScale}
top={margin.top + categoryMax}
left={margin.left}
hideAxisLine
hideTicks
numTicks={5}
tickLabelProps={() => {
return {
...bottomTickLabelProps(),
className: styles.tickLabel,
dy: defaultLabelDy,
fontSize: `${valueTickLabelSize / 16}rem`,
};
}}
label={valueAxisLabel}
labelClassName={styles.axisLabel}
labelOffset={valueAxisLabelOffset}
labelProps={{
fontSize: `${valueAxisLabelSize / 16}rem`,
}}
/>
</svg>
);
}
return (
<div>
<svg className={className} width={width} height={height}>
<Group top={margin.top} left={margin.left}>
<Group>
{data.map((d, idx) => {
const barName = `${getCategory(d)}-${idx}`;
const barWidth = categoryScale.bandwidth();
const backgroundBarWidth = barWidth / (1 - barPadding);
return idx % 2 === 0 ? (
<Bar
className={styles.barBackground}
key={`bar-${barName}-background`}
x={0}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
y={categoryPoint(d)! - (backgroundBarWidth - barWidth) / 2}
width={valueMax}
height={backgroundBarWidth}
/>
) : null;
})}
</Group>
<GridColumns
scale={valueScale}
height={categoryMax}
numTicks={5}
stroke={Color.label}
strokeWidth={4}
strokeDasharray="10"
strokeLinecap="round"
/>
<Group>
{data.map((d, idx) => {
const barName = `${getCategory(d)}-${idx}`;
const barLength = valuePoint(d);
const barWidth = categoryScale.bandwidth();
return (
<Group className={styles.barGroup} key={`bar-${barName}`}>
<Bar
onMouseMove={(e) => {
const tooltipPos = getTooltipPosition(e);
showTooltip({
tooltipData: getValue(d).toString(),
tooltipLeft: tooltipPos.x,
tooltipTop: tooltipPos.y,
});
}}
onMouseOut={hideTooltip}
className={styles.bar}
x={0}
y={categoryPoint(d)}
width={barLength}
height={barWidth}
/>
</Group>
);
})}
</Group>
<AxisLeft
scale={categoryScale}
hideAxisLine
hideTicks
tickLabelProps={() => {
return {
...leftTickLabelProps(),
className: styles.tickLabel,
fontSize: `${categoryTickLabelSize / 16}rem`,
};
}}
label={categoryAxisLabel}
labelClassName={styles.axisLabel}
labelOffset={categoryAxisLabelOffset}
labelProps={{
fontSize: `${categoryAxisLabelSize / 16}rem`,
}}
/>
<AxisBottom
scale={valueScale}
top={categoryMax}
hideAxisLine
hideTicks
numTicks={5}
tickLabelProps={() => {
return {
...bottomTickLabelProps(),
className: styles.tickLabel,
dy: defaultLabelDy,
fontSize: `${valueTickLabelSize / 16}rem`,
};
}}
label={valueAxisLabel}
labelClassName={styles.axisLabel}
labelOffset={valueAxisLabelOffset}
labelProps={{
fontSize: `${valueAxisLabelSize / 16}rem`,
}}
/>
</Group>
</svg>
export function BarGraphVertical(props: BarGraphProps) {
const {
{tooltipOpen && (
<TooltipWrapper
top={tooltipTop}
left={tooltipLeft}
header={tooltipData as string}
></TooltipWrapper>
)}
</div>
);
}
);
export const BarGraphVertical = withTooltip<BarGraphProps, TooltipData>(
({
width,
height,
margin,
data,
@ -219,7 +234,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,142 +244,155 @@ 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
const barPadding = 0.4;
const alternatingLabel = width <= widthAlternatingLabel;
const final_margin_bottom = alternatingLabel
? margin.bottom + alternatingLabelSpace
: margin.bottom;
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
? margin.bottom + alternatingLabelSpace
: margin.bottom;
const categoryMax = width - margin.left - margin.right;
const valueMax = height - margin.top - final_margin_bottom;
const categoryMax = width - margin.left - margin.right;
const valueMax = height - margin.top - final_margin_bottom;
const getCategory = (d: BarGraphData) => d.category;
const getValue = (d: BarGraphData) => d.value;
const getCategory = (d: BarGraphData) => d.category;
const getValue = (d: BarGraphData) => d.value;
const categoryScale = scaleBand({
range: [0, categoryMax],
domain: data.map(getCategory),
padding: barPadding,
});
const categoryScale = scaleBand({
range: [0, categoryMax],
domain: data.map(getCategory),
padding: barPadding,
});
const valueScale = scaleLinear({
range: [valueMax, 0],
nice: true,
domain: [0, Math.max(...data.map(getValue))],
});
const valueScale = scaleLinear({
range: [valueMax, 0],
nice: true,
domain: [0, Math.max(...data.map(getValue))],
});
const categoryPoint = (d: BarGraphData) => categoryScale(getCategory(d));
const valuePoint = (d: BarGraphData) => valueScale(getValue(d));
const categoryPoint = (d: BarGraphData) => categoryScale(getCategory(d));
const valuePoint = (d: BarGraphData) => valueScale(getValue(d));
return (
<svg className={className} width={width} height={height}>
<Group top={margin.top} left={margin.left}>
<Group>
{data.map((d, idx) => {
const barName = `${getCategory(d)}-${idx}`;
const barWidth = categoryScale.bandwidth();
const backgroundBarWidth = barWidth / (1 - barPadding);
return idx % 2 === 0 ? (
<Bar
className={styles.barBackground}
key={`bar-${barName}-background`}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
x={categoryPoint(d)! - (backgroundBarWidth - barWidth) / 2}
y={0}
width={backgroundBarWidth}
height={valueMax}
/>
) : null;
})}
</Group>
<GridRows
scale={valueScale}
width={categoryMax}
numTicks={5}
stroke={Color.label}
strokeWidth={4}
strokeDasharray="10"
strokeLinecap="round"
/>
<Group>
{data.map((d, idx) => {
const barName = `${getCategory(d)}-${idx}`;
const barHeight = valueMax - valuePoint(d);
const barWidth = categoryScale.bandwidth();
return (
<Group className={styles.barGroup} key={`bar-${barName}`}>
<Bar
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}
hideAxisLine
hideTicks
tickLabelProps={(value, index) => {
const alternatingDy = index % 2 == 0 ? defaultLabelDy : lowerLabelDy;
return {
...bottomTickLabelProps(),
className: styles.tickLabel,
dy: alternatingLabel ? alternatingDy : defaultLabelDy,
fontSize: `${categoryTickLabelSize / 16}rem`,
width: categoryScale.bandwidth(),
verticalAnchor: "start",
};
}}
label={categoryAxisLabel}
labelClassName={styles.axisLabel}
labelOffset={categoryAxisLabelOffset}
labelProps={{
fontSize: `${categoryAxisLabelSize / 16}rem`,
}}
/>
<AxisLeft
scale={valueScale}
top={margin.top}
left={margin.left}
hideAxisLine
hideTicks
numTicks={5}
tickLabelProps={() => {
return {
...leftTickLabelProps(),
className: styles.tickLabel,
dx: "-0.5rem",
dy: "0.25rem",
fontSize: `${valueTickLabelSize / 16}rem`,
};
}}
label={valueAxisLabel}
labelClassName={styles.axisLabel}
labelOffset={valueAxisLabelOffset}
labelProps={{
fontSize: `${valueAxisLabelSize / 16}rem`,
}}
/>
</svg>
);
}
return (
<div>
<svg className={className} width={width} height={height}>
<Group top={margin.top} left={margin.left}>
<Group>
{data.map((d, idx) => {
const barName = `${getCategory(d)}-${idx}`;
const barWidth = categoryScale.bandwidth();
const backgroundBarWidth = barWidth / (1 - barPadding);
return idx % 2 === 0 ? (
<Bar
className={styles.barBackground}
key={`bar-${barName}-background`}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
x={categoryPoint(d)! - (backgroundBarWidth - barWidth) / 2}
y={0}
width={backgroundBarWidth}
height={valueMax}
/>
) : null;
})}
</Group>
<GridRows
scale={valueScale}
width={categoryMax}
numTicks={5}
stroke={Color.label}
strokeWidth={4}
strokeDasharray="10"
strokeLinecap="round"
/>
<Group>
{data.map((d, idx) => {
const barName = `${getCategory(d)}-${idx}`;
const barHeight = valueMax - valuePoint(d);
const barWidth = categoryScale.bandwidth();
return (
<Group className={styles.barGroup} key={`bar-${barName}`}>
<Bar
onMouseMove={(e) => {
const tooltipPos = getTooltipPosition(e);
showTooltip({
tooltipData: getValue(d).toString(),
tooltipLeft: tooltipPos.x,
tooltipTop: tooltipPos.y,
});
}}
onMouseOut={hideTooltip}
className={styles.bar}
x={categoryPoint(d)}
y={valueMax - barHeight}
width={barWidth}
height={barHeight}
/>
</Group>
);
})}
</Group>
<AxisBottom
scale={categoryScale}
top={valueMax}
hideAxisLine
hideTicks
tickLabelProps={(value, index) => {
const alternatingDy =
index % 2 == 0 ? defaultLabelDy : lowerLabelDy;
return {
...bottomTickLabelProps(),
className: styles.tickLabel,
dy: alternatingLabel ? alternatingDy : defaultLabelDy,
fontSize: `${categoryTickLabelSize / 16}rem`,
width: categoryScale.bandwidth(),
verticalAnchor: "start",
};
}}
label={categoryAxisLabel}
labelClassName={styles.axisLabel}
labelOffset={categoryAxisLabelOffset}
labelProps={{
fontSize: `${categoryAxisLabelSize / 16}rem`,
}}
/>
<AxisLeft
scale={valueScale}
hideAxisLine
hideTicks
numTicks={5}
tickLabelProps={() => {
return {
...leftTickLabelProps(),
className: styles.tickLabel,
dx: "-0.5rem",
dy: "0.25rem",
fontSize: `${valueTickLabelSize / 16}rem`,
};
}}
label={valueAxisLabel}
labelClassName={styles.axisLabel}
labelOffset={valueAxisLabelOffset}
labelProps={{
fontSize: `${valueAxisLabelSize / 16}rem`,
}}
/>
</Group>
</svg>
{tooltipOpen && (
<TooltipWrapper
top={tooltipTop}
left={tooltipLeft}
header={tooltipData as string}
></TooltipWrapper>
)}
</div>
);
}
);

View File

@ -11,7 +11,7 @@ import { WithTooltipProvidedProps } from "@visx/tooltip/lib/enhancers/withToolti
import React from "react";
import { Color } from "utils/Color";
import { TooltipWrapper } from "./TooltipWrapper";
import { getTooltipPosition, TooltipWrapper } from "./TooltipWrapper";
import styles from "./Boxplot.module.css";
@ -96,8 +96,8 @@ export const BoxPlot = withTooltip<StatsPlotProps, TooltipData>(
valueAxisLabelTopOffset = 5,
valueAxisLabelLeftOffset = 10,
categoryAxisLabelLeftOffset = 30,
toolTipTopOffset = 20,
toolTipLeftOffset = 5,
toolTipTopOffset = 0,
toolTipLeftOffset = 0,
categoryAxisLabelSize = DEFAULT_LABEL_SIZE,
valueAxisLabelSize = DEFAULT_LABEL_SIZE,
boxPlotWidthFactor = 0.4,
@ -149,6 +149,21 @@ export const BoxPlot = withTooltip<StatsPlotProps, TooltipData>(
const constrainedWidth = Math.min(200, xScale.bandwidth());
const mouseOverEventHandler =
(d: Stats) =>
(e: React.MouseEvent<SVGLineElement | SVGRectElement, MouseEvent>) => {
const pos = getTooltipPosition(e);
showTooltip({
tooltipLeft: pos.x + toolTipLeftOffset,
tooltipTop: pos.y + toolTipTopOffset,
tooltipData: {
...d.boxPlot,
category: getX(d),
},
});
};
return width < 10 ? null : (
<div>
<svg width={width} height={height}>
@ -254,81 +269,23 @@ export const BoxPlot = withTooltip<StatsPlotProps, TooltipData>(
strokeWidth={strokeWidth}
valueScale={yScale}
minProps={{
onMouseOver: () => {
showTooltip({
tooltipTop:
(yScale(getMin(d)) ?? 0) + toolTipTopOffset,
tooltipLeft:
xScale(getX(d))! +
constrainedWidth +
toolTipLeftOffset,
tooltipData: {
...d.boxPlot,
category: getX(d),
},
});
},
onMouseLeave: () => {
hideTooltip();
},
onMouseMove: mouseOverEventHandler(d),
onMouseLeave: hideTooltip,
}}
maxProps={{
onMouseOver: () => {
showTooltip({
tooltipTop:
(yScale(getMax(d)) ?? 0) + toolTipTopOffset,
tooltipLeft:
xScale(getX(d))! +
constrainedWidth +
toolTipLeftOffset,
tooltipData: {
...d.boxPlot,
category: getX(d),
},
});
},
onMouseLeave: () => {
hideTooltip();
},
onMouseMove: mouseOverEventHandler(d),
onMouseLeave: hideTooltip,
}}
boxProps={{
onMouseOver: () => {
showTooltip({
tooltipTop:
(yScale(getMedian(d)) ?? 0) + toolTipTopOffset,
tooltipLeft:
xScale(getX(d))! +
constrainedWidth +
toolTipLeftOffset,
tooltipData: {
...d.boxPlot,
category: getX(d),
},
});
},
onMouseMove: mouseOverEventHandler(d),
strokeWidth: 0,
onMouseLeave: () => {
hideTooltip();
},
onMouseLeave: hideTooltip,
}}
medianProps={{
style: {
stroke: Color.label,
},
onMouseOver: () => {
showTooltip({
tooltipTop:
(yScale(getMedian(d)) ?? 0) + toolTipTopOffset,
tooltipLeft:
xScale(getX(d))! +
constrainedWidth +
toolTipLeftOffset,
tooltipData: {
...d.boxPlot,
category: getX(d),
},
});
},
onMouseMove: mouseOverEventHandler(d),
onMouseLeave: () => {
hideTooltip();
},

View File

@ -76,7 +76,7 @@
}
.horizontalScrollOnMobile {
overflow: scroll;
overflow-x: scroll;
}
}

View File

@ -2,25 +2,12 @@
display: flex;
flex-direction: column;
align-items: center;
width: min-content;
}
.barBackground {
fill: var(--card-background);
}
.barText {
visibility: hidden;
font-family: "Inconsolata", monospace;
font-weight: 800;
fill: var(--label);
}
.singleBar:hover .barText {
visibility: visible;
}
.tickLabel {
font-family: "Inconsolata", monospace;
font-weight: 800;
@ -37,4 +24,4 @@
display: flex;
margin: calc(16rem / 16);
justify-content: center;
}
}

View File

@ -7,10 +7,12 @@ import { LegendOrdinal } from "@visx/legend";
import { scaleBand, scaleLinear, scaleOrdinal } from "@visx/scale";
import { Bar, BarGroup, BarGroupHorizontal } from "@visx/shape";
import { BarGroupBar as BarGroupBarType } from "@visx/shape/lib/types";
import { Text } from "@visx/text";
import { withTooltip } from "@visx/tooltip";
import React, { useState } from "react";
import { Color } from "utils/Color";
import { getTooltipPosition, TooltipWrapper } from "./TooltipWrapper";
import styles from "./GroupedBarGraph.module.css";
interface GroupedBarGraphProps {
@ -79,15 +81,20 @@ interface BarGroupData {
// BAR_PADDING must be in the range [0, 1)
const BAR_PADDING = 0.2;
const BAR_TEXT_PADDING = 12;
const DEFAULT_LABEL_SIZE = 16;
export function GroupedBarGraphVertical(props: GroupedBarGraphProps) {
const {
type TooltipData = string;
export const GroupedBarGraphVertical = withTooltip<
GroupedBarGraphProps,
TooltipData
>(
({
data: propsData,
barColors,
barHoverColorsMap,
width,
height,
margin,
className,
@ -106,209 +113,237 @@ export function GroupedBarGraphVertical(props: GroupedBarGraphProps) {
alternatingLabelSpace = 80,
defaultLabelDy = `0px`,
lowerLabelDy = `30px`,
} = props;
const width = props.width < minWidth ? minWidth : props.width; // Ensuring graph's width >= minWidth
const alternatingLabel = width <= widthAlternatingLabel;
const final_margin_bottom = alternatingLabel
? margin.bottom + alternatingLabelSpace
: margin.bottom;
tooltipOpen,
tooltipLeft,
tooltipTop,
tooltipData,
hideTooltip,
showTooltip,
}) => {
width = width < minWidth ? minWidth : width; // Ensuring graph's width >= minWidth
const alternatingLabel = width <= widthAlternatingLabel;
const final_margin_bottom = alternatingLabel
? margin.bottom + alternatingLabelSpace
: margin.bottom;
const data: BarGroupData[] = propsData.map((datum: GroupedBarGraphData) => {
return { category: datum.category, ...datum.values };
});
const data: BarGroupData[] = propsData.map((datum: GroupedBarGraphData) => {
return { category: datum.category, ...datum.values };
});
const keys = Object.keys(propsData[0].values);
propsData.forEach((d: GroupedBarGraphData) => {
const currentKeys = Object.keys(d.values);
if (
keys.length != currentKeys.length ||
!keys.every((key: string) => currentKeys.includes(key))
) {
throw new Error(
"Every category in a GroupedBarGraph must have the same keys. Check the data prop"
);
}
});
const keys = Object.keys(propsData[0].values);
propsData.forEach((d: GroupedBarGraphData) => {
const currentKeys = Object.keys(d.values);
if (
keys.length != currentKeys.length ||
!keys.every((key: string) => currentKeys.includes(key))
) {
throw new Error(
"Every category in a GroupedBarGraph must have the same keys. Check the data prop"
);
}
});
const allValues = propsData
.map((d: GroupedBarGraphData) => Object.values(d.values))
.flat();
const allValues = propsData
.map((d: GroupedBarGraphData) => Object.values(d.values))
.flat();
const categoryMax = width - margin.left - margin.right;
const valueMax = height - margin.top - final_margin_bottom;
const categoryMax = width - margin.left - margin.right;
const valueMax = height - margin.top - final_margin_bottom;
const getCategory = (d: BarGroupData) => d.category;
const getCategory = (d: BarGroupData) => d.category;
const categoryScale = scaleBand({
domain: data.map(getCategory),
padding: BAR_PADDING,
});
const categoryScale = scaleBand({
domain: data.map(getCategory),
padding: BAR_PADDING,
});
const keyScale = scaleBand({
domain: keys,
});
const keyScale = scaleBand({
domain: keys,
});
const valueScale = scaleLinear<number>({
domain: [0, Math.max(...allValues)],
});
const valueScale = scaleLinear<number>({
domain: [0, Math.max(...allValues)],
});
const colorScale = scaleOrdinal<string, string>({
domain: keys,
range: barColors,
});
const colorScale = scaleOrdinal<string, string>({
domain: keys,
range: barColors,
});
categoryScale.rangeRound([0, categoryMax]);
keyScale.rangeRound([0, categoryScale.bandwidth()]);
valueScale.rangeRound([valueMax, 0]);
categoryScale.rangeRound([0, categoryMax]);
keyScale.rangeRound([0, categoryScale.bandwidth()]);
valueScale.rangeRound([valueMax, 0]);
return (
<div
className={className ? `${className} ${styles.wrapper}` : styles.wrapper}
>
<div className={styles.legend}>
<LegendOrdinal
scale={colorScale}
direction="row"
itemMargin={itemMargin}
labelAlign="center"
/>
</div>
<svg width={width} height={height}>
<defs>
{Object.keys(barHoverColorsMap).map((color: string) => {
// remove brackets from colour name to make ids work
const colorId = removeBrackets(color);
return (
<filter key={`glow-${color}`} id={`glow-${colorId}`}>
<feDropShadow
dx="0"
dy="0"
stdDeviation="4"
floodColor={barHoverColorsMap[color]}
/>
</filter>
);
})}
</defs>
<Group top={margin.top} left={margin.left}>
<Group>
{data.map((d, idx) => {
const barName = `${getCategory(d)}-${idx}`;
const barWidth = categoryScale.bandwidth();
const backgroundBarWidth = barWidth / (1 - BAR_PADDING);
return idx % 2 === 0 ? (
<Bar
className={styles.barBackground}
key={`bar-${barName}-background`}
x={
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
categoryScale(getCategory(d))! -
(backgroundBarWidth - barWidth) / 2
}
y={0}
width={backgroundBarWidth}
height={valueMax}
/>
) : null;
})}
</Group>
<GridRows
scale={valueScale}
width={categoryMax}
numTicks={5}
stroke={Color.label}
strokeWidth={4}
strokeDasharray="10"
strokeLinecap="round"
return (
<div
className={
className ? `${className} ${styles.wrapper}` : styles.wrapper
}
>
<div className={styles.legend}>
<LegendOrdinal
scale={colorScale}
direction="row"
itemMargin={itemMargin}
labelAlign="center"
/>
<BarGroup
data={data}
keys={keys}
height={valueMax}
x0={getCategory}
x0Scale={categoryScale}
x1Scale={keyScale}
yScale={valueScale}
color={colorScale}
>
{(barGroups) =>
barGroups.map((barGroup) => (
<Group
key={`bar-group-${barGroup.x0}-${barGroup.index}`}
left={barGroup.x0}
>
{barGroup.bars.map((bar) => (
<HoverableBar
key={`bar-group-bar-${barGroup.x0}-${barGroup.index}-${bar.key}-${bar.index}`}
bar={bar}
valueMax={valueMax}
hoverFillColor={barHoverColorsMap[bar.color]}
hoverLabelSize={hoverLabelSize}
/>
))}
</Group>
))
}
</BarGroup>
</Group>
<AxisBottom
scale={categoryScale}
top={valueMax + margin.top}
left={margin.left}
hideAxisLine
hideTicks
tickLabelProps={(value, index) => {
const alternatingDy =
index % 2 == 0 ? defaultLabelDy : lowerLabelDy;
return {
...bottomTickLabelProps(),
className: styles.tickLabel,
dy: alternatingLabel ? alternatingDy : defaultLabelDy,
fontSize: `${categoryTickLabelSize / 16}rem`,
width: categoryScale.bandwidth(),
verticalAnchor: "start",
};
}}
label={categoryAxisLabel}
labelClassName={styles.axisLabel}
labelOffset={categoryAxisLabelOffset}
labelProps={{
fontSize: `${categoryAxisLabelSize / 16}rem`,
}}
/>
<AxisLeft
scale={valueScale}
top={margin.top}
left={margin.left}
hideAxisLine
hideTicks
numTicks={5}
tickLabelProps={() => {
return {
...leftTickLabelProps(),
className: styles.tickLabel,
dx: "-0.5rem",
dy: "0.25rem",
fontSize: `${valueTickLabelSize / 16}rem`,
};
}}
label={valueAxisLabel}
labelClassName={styles.axisLabel}
labelOffset={valueAxisLabelOffset}
labelProps={{
fontSize: `${valueAxisLabelSize / 16}rem`,
}}
/>
</svg>
</div>
);
}
</div>
<svg width={width} height={height}>
<defs>
{Object.keys(barHoverColorsMap).map((color: string) => {
// remove brackets from colour name to make ids work
const colorId = removeBrackets(color);
return (
<filter key={`glow-${color}`} id={`glow-${colorId}`}>
<feDropShadow
dx="0"
dy="0"
stdDeviation="4"
floodColor={barHoverColorsMap[color]}
/>
</filter>
);
})}
</defs>
<Group top={margin.top} left={margin.left}>
<Group>
{data.map((d, idx) => {
const barName = `${getCategory(d)}-${idx}`;
const barWidth = categoryScale.bandwidth();
const backgroundBarWidth = barWidth / (1 - BAR_PADDING);
return idx % 2 === 0 ? (
<Bar
className={styles.barBackground}
key={`bar-${barName}-background`}
x={
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
categoryScale(getCategory(d))! -
(backgroundBarWidth - barWidth) / 2
}
y={0}
width={backgroundBarWidth}
height={valueMax}
/>
) : null;
})}
</Group>
<GridRows
scale={valueScale}
width={categoryMax}
numTicks={5}
stroke={Color.label}
strokeWidth={4}
strokeDasharray="10"
strokeLinecap="round"
/>
<BarGroup
data={data}
keys={keys}
height={valueMax}
x0={getCategory}
x0Scale={categoryScale}
x1Scale={keyScale}
yScale={valueScale}
color={colorScale}
>
{(barGroups) =>
barGroups.map((barGroup) => (
<Group
key={`bar-group-${barGroup.x0}-${barGroup.index}`}
left={barGroup.x0}
>
{barGroup.bars.map((bar) => (
<HoverableBar
onMouseMove={(e) => {
const tooltipPos = getTooltipPosition(e);
export function GroupedBarGraphHorizontal(props: GroupedBarGraphProps) {
const {
showTooltip({
tooltipData: bar.value.toString(),
tooltipTop: tooltipPos.y,
tooltipLeft: tooltipPos.x,
});
}}
onMouseOut={hideTooltip}
key={`bar-group-bar-${barGroup.x0}-${barGroup.index}-${bar.key}-${bar.index}`}
bar={bar}
valueMax={valueMax}
hoverFillColor={barHoverColorsMap[bar.color]}
hoverLabelSize={hoverLabelSize}
/>
))}
</Group>
))
}
</BarGroup>
<AxisBottom
scale={categoryScale}
top={valueMax}
hideAxisLine
hideTicks
tickLabelProps={(value, index) => {
const alternatingDy =
index % 2 == 0 ? defaultLabelDy : lowerLabelDy;
return {
...bottomTickLabelProps(),
className: styles.tickLabel,
dy: alternatingLabel ? alternatingDy : defaultLabelDy,
fontSize: `${categoryTickLabelSize / 16}rem`,
width: categoryScale.bandwidth(),
verticalAnchor: "start",
};
}}
label={categoryAxisLabel}
labelClassName={styles.axisLabel}
labelOffset={categoryAxisLabelOffset}
labelProps={{
fontSize: `${categoryAxisLabelSize / 16}rem`,
}}
/>
<AxisLeft
scale={valueScale}
hideAxisLine
hideTicks
numTicks={5}
tickLabelProps={() => {
return {
...leftTickLabelProps(),
className: styles.tickLabel,
dx: "-0.5rem",
dy: "0.25rem",
fontSize: `${valueTickLabelSize / 16}rem`,
};
}}
label={valueAxisLabel}
labelClassName={styles.axisLabel}
labelOffset={valueAxisLabelOffset}
labelProps={{
fontSize: `${valueAxisLabelSize / 16}rem`,
}}
/>
</Group>
</svg>
{tooltipOpen && (
<TooltipWrapper
top={tooltipTop}
left={tooltipLeft}
header={tooltipData as string}
></TooltipWrapper>
)}
</div>
);
}
);
export const GroupedBarGraphHorizontal = withTooltip<
GroupedBarGraphProps,
TooltipData
>(
({
data: propsData,
barColors,
barHoverColorsMap,
width,
height,
margin,
className,
@ -324,198 +359,221 @@ export function GroupedBarGraphHorizontal(props: GroupedBarGraphProps) {
valueAxisLabelOffset = 0,
itemMargin = "0 0 0 15px",
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 data: BarGroupData[] = propsData.map((datum: GroupedBarGraphData) => {
return { category: datum.category, ...datum.values };
});
const data: BarGroupData[] = propsData.map((datum: GroupedBarGraphData) => {
return { category: datum.category, ...datum.values };
});
const keys = Object.keys(propsData[0].values);
propsData.forEach((d: GroupedBarGraphData) => {
const currentKeys = Object.keys(d.values);
if (
keys.length != currentKeys.length ||
!keys.every((key: string) => currentKeys.includes(key))
) {
throw new Error(
"Every category in a GroupedBarGraph must have the same keys. Check the data prop"
);
}
});
const keys = Object.keys(propsData[0].values);
propsData.forEach((d: GroupedBarGraphData) => {
const currentKeys = Object.keys(d.values);
if (
keys.length != currentKeys.length ||
!keys.every((key: string) => currentKeys.includes(key))
) {
throw new Error(
"Every category in a GroupedBarGraph must have the same keys. Check the data prop"
);
}
});
const allValues = propsData
.map((d: GroupedBarGraphData) => Object.values(d.values))
.flat();
const allValues = propsData
.map((d: GroupedBarGraphData) => Object.values(d.values))
.flat();
const categoryMax = height - margin.top - margin.bottom;
const valueMax = width - margin.left - margin.right;
const categoryMax = height - margin.top - margin.bottom;
const valueMax = width - margin.left - margin.right;
const getCategory = (d: BarGroupData) => d.category;
const getCategory = (d: BarGroupData) => d.category;
const categoryScale = scaleBand({
domain: data.map(getCategory),
padding: BAR_PADDING,
});
const categoryScale = scaleBand({
domain: data.map(getCategory),
padding: BAR_PADDING,
});
const keyScale = scaleBand({
domain: keys,
});
const keyScale = scaleBand({
domain: keys,
});
const valueScale = scaleLinear<number>({
domain: [Math.max(...allValues), 0],
});
const valueScale = scaleLinear<number>({
domain: [Math.max(...allValues), 0],
});
const colorScale = scaleOrdinal<string, string>({
domain: keys,
range: barColors,
});
const colorScale = scaleOrdinal<string, string>({
domain: keys,
range: barColors,
});
categoryScale.rangeRound([0, categoryMax]);
keyScale.rangeRound([0, categoryScale.bandwidth()]);
valueScale.rangeRound([valueMax, 0]);
categoryScale.rangeRound([0, categoryMax]);
keyScale.rangeRound([0, categoryScale.bandwidth()]);
valueScale.rangeRound([valueMax, 0]);
return (
<div
className={className ? `${className} ${styles.wrapper}` : styles.wrapper}
>
<div className={styles.legend}>
<LegendOrdinal
scale={colorScale}
direction="row"
itemMargin={itemMargin}
labelAlign="center"
/>
</div>
<svg width={width} height={height}>
<defs>
{Object.keys(barHoverColorsMap).map((color: string) => {
// remove brackets from colour name to make ids work
const colorId = removeBrackets(color);
return (
<filter key={`glow-${color}`} id={`glow-${colorId}`}>
<feDropShadow
dx="0"
dy="0"
stdDeviation="4"
floodColor={barHoverColorsMap[color]}
/>
</filter>
);
})}
</defs>
<Group top={margin.top} left={margin.left}>
<Group>
{data.map((d, idx) => {
const barName = `${getCategory(d)}-${idx}`;
const barWidth = categoryScale.bandwidth();
const backgroundBarWidth = barWidth / (1 - BAR_PADDING);
return idx % 2 === 0 ? (
<Bar
className={styles.barBackground}
key={`bar-${barName}-background`}
x={0}
y={
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
categoryScale(getCategory(d))! -
(backgroundBarWidth - barWidth) / 2
}
width={valueMax}
height={backgroundBarWidth}
/>
) : null;
})}
</Group>
<GridColumns
scale={valueScale}
height={categoryMax}
numTicks={5}
stroke={Color.label}
strokeWidth={4}
strokeDasharray="10"
strokeLinecap="round"
return (
<div
className={
className ? `${className} ${styles.wrapper}` : styles.wrapper
}
>
<div className={styles.legend}>
<LegendOrdinal
scale={colorScale}
direction="row"
itemMargin={itemMargin}
labelAlign="center"
/>
<BarGroupHorizontal
data={data}
keys={keys}
width={valueMax}
y0={getCategory}
y0Scale={categoryScale}
y1Scale={keyScale}
xScale={valueScale}
color={colorScale}
>
{(barGroups) =>
barGroups.map((barGroup) => (
<Group
key={`bar-group-${barGroup.y0}-${barGroup.index}`}
top={barGroup.y0}
>
{barGroup.bars.map((bar) => (
<HoverableBar
key={`bar-group-bar-${barGroup.y0}-${barGroup.index}-${bar.key}-${bar.index}`}
bar={bar}
valueMax={valueMax}
hoverFillColor={barHoverColorsMap[bar.color]}
hoverLabelSize={hoverLabelSize}
isHorizontal
/>
))}
</Group>
))
}
</BarGroupHorizontal>
</Group>
<AxisLeft
scale={categoryScale}
top={margin.top}
left={margin.left}
hideAxisLine
hideTicks
tickLabelProps={() => {
return {
...leftTickLabelProps(),
className: styles.tickLabel,
dx: "-0.5rem",
dy: defaultLabelDy,
fontSize: `${valueTickLabelSize / 16}rem`,
height: categoryScale.bandwidth(),
};
}}
label={categoryAxisLabel}
labelClassName={styles.axisLabel}
labelOffset={categoryAxisLabelOffset}
labelProps={{
fontSize: `${categoryAxisLabelSize / 16}rem`,
}}
/>
<AxisBottom
scale={valueScale}
top={categoryMax + margin.top}
left={margin.left}
hideAxisLine
hideTicks
numTicks={5}
tickLabelProps={() => {
return {
...bottomTickLabelProps(),
className: styles.tickLabel,
dy: "-0.25rem",
fontSize: `${categoryTickLabelSize / 16}rem`,
verticalAnchor: "start",
};
}}
label={valueAxisLabel}
labelClassName={styles.axisLabel}
labelOffset={valueAxisLabelOffset}
labelProps={{
fontSize: `${valueAxisLabelSize / 16}rem`,
}}
/>
</svg>
</div>
);
}
</div>
<svg width={width} height={height}>
<defs>
{Object.keys(barHoverColorsMap).map((color: string) => {
// remove brackets from colour name to make ids work
const colorId = removeBrackets(color);
return (
<filter key={`glow-${color}`} id={`glow-${colorId}`}>
<feDropShadow
dx="0"
dy="0"
stdDeviation="4"
floodColor={barHoverColorsMap[color]}
/>
</filter>
);
})}
</defs>
<Group top={margin.top} left={margin.left}>
<Group>
{data.map((d, idx) => {
const barName = `${getCategory(d)}-${idx}`;
const barWidth = categoryScale.bandwidth();
const backgroundBarWidth = barWidth / (1 - BAR_PADDING);
return idx % 2 === 0 ? (
<Bar
className={styles.barBackground}
key={`bar-${barName}-background`}
x={0}
y={
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
categoryScale(getCategory(d))! -
(backgroundBarWidth - barWidth) / 2
}
width={valueMax}
height={backgroundBarWidth}
/>
) : null;
})}
</Group>
<GridColumns
scale={valueScale}
height={categoryMax}
numTicks={5}
stroke={Color.label}
strokeWidth={4}
strokeDasharray="10"
strokeLinecap="round"
/>
<BarGroupHorizontal
data={data}
keys={keys}
width={valueMax}
y0={getCategory}
y0Scale={categoryScale}
y1Scale={keyScale}
xScale={valueScale}
color={colorScale}
>
{(barGroups) =>
barGroups.map((barGroup) => (
<Group
key={`bar-group-${barGroup.y0}-${barGroup.index}`}
top={barGroup.y0}
>
{barGroup.bars.map((bar) => (
<HoverableBar
onMouseMove={(e) => {
const tooltipPos = getTooltipPosition(e);
showTooltip({
tooltipData: bar.value.toString(),
tooltipLeft: tooltipPos.x,
tooltipTop: tooltipPos.y,
});
}}
onMouseOut={hideTooltip}
key={`bar-group-bar-${barGroup.y0}-${barGroup.index}-${bar.key}-${bar.index}`}
bar={bar}
valueMax={valueMax}
hoverFillColor={barHoverColorsMap[bar.color]}
hoverLabelSize={hoverLabelSize}
isHorizontal
/>
))}
</Group>
))
}
</BarGroupHorizontal>
<AxisLeft
scale={categoryScale}
hideAxisLine
hideTicks
tickLabelProps={() => {
return {
...leftTickLabelProps(),
className: styles.tickLabel,
dx: "-0.5rem",
dy: defaultLabelDy,
fontSize: `${valueTickLabelSize / 16}rem`,
height: categoryScale.bandwidth(),
};
}}
label={categoryAxisLabel}
labelClassName={styles.axisLabel}
labelOffset={categoryAxisLabelOffset}
labelProps={{
fontSize: `${categoryAxisLabelSize / 16}rem`,
}}
/>
<AxisBottom
scale={valueScale}
top={categoryMax}
hideAxisLine
hideTicks
numTicks={5}
tickLabelProps={() => {
return {
...bottomTickLabelProps(),
className: styles.tickLabel,
dy: "-0.25rem",
fontSize: `${categoryTickLabelSize / 16}rem`,
verticalAnchor: "start",
};
}}
label={valueAxisLabel}
labelClassName={styles.axisLabel}
labelOffset={valueAxisLabelOffset}
labelProps={{
fontSize: `${valueAxisLabelSize / 16}rem`,
}}
/>
</Group>
</svg>
{tooltipOpen && (
<TooltipWrapper
top={tooltipTop}
left={tooltipLeft}
header={tooltipData as string}
></TooltipWrapper>
)}
</div>
);
}
);
interface HoverableBarProps {
bar: BarGroupBarType<string>;
@ -523,16 +581,12 @@ interface HoverableBarProps {
hoverFillColor?: string;
hoverLabelSize?: number;
isHorizontal?: boolean;
onMouseMove?: (e: React.MouseEvent<SVGPathElement, MouseEvent>) => void;
onMouseOut?: () => void;
}
function HoverableBar(props: HoverableBarProps) {
const {
bar,
valueMax,
hoverLabelSize,
hoverFillColor,
isHorizontal = false,
} = props;
const { bar, hoverFillColor, onMouseMove, onMouseOut } = props;
const [isHovered, setIsHovered] = useState(false);
@ -549,6 +603,8 @@ function HoverableBar(props: HoverableBarProps) {
}}
>
<Bar
onMouseMove={onMouseMove}
onMouseOut={onMouseOut}
x={bar.x}
y={bar.y}
width={bar.width}
@ -557,22 +613,6 @@ function HoverableBar(props: HoverableBarProps) {
// apply the glow effect when the bar is hovered
filter={isHovered ? `url(#glow-${colorId})` : undefined}
/>
<Text
className={styles.barText}
x={isHorizontal ? bar.width - BAR_TEXT_PADDING : bar.x + bar.width / 2}
y={
isHorizontal
? bar.y + bar.height / 2
: valueMax - bar.height + BAR_TEXT_PADDING
}
fontSize={
hoverLabelSize ?? (isHorizontal ? bar.height : bar.width) * 0.5
}
textAnchor={isHorizontal ? "end" : "middle"}
verticalAnchor={isHorizontal ? "middle" : "start"}
>
{bar.value}
</Text>
</Group>
);
}

View File

@ -1,18 +1,16 @@
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 { LegendOrdinal } from "@visx/legend";
import { Point } from "@visx/point";
import { scaleBand, scaleLinear, scaleOrdinal } from "@visx/scale";
import { LinePath } from "@visx/shape";
import { withTooltip } from "@visx/tooltip";
import React from "react";
import { Color } from "utils/Color";
import { TooltipWrapper } from "./TooltipWrapper";
import { getTooltipPosition, TooltipWrapper } from "./TooltipWrapper";
import styles from "./LineGraph.module.css";
@ -195,17 +193,11 @@ export const LineGraph = withTooltip<LineGraphProps, TooltipData>(
<Group key={`line-${i}`}>
<LinePath
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;
const tooltipPos = getTooltipPosition(e);
showTooltip({
tooltipData: data.lines[i].label,
tooltipTop: eventSvgCoords.y,
tooltipLeft: eventSvgCoords.x,
tooltipLeft: tooltipPos.x,
tooltipTop: tooltipPos.y,
});
}}
onMouseOut={hideTooltip}

View File

@ -1,26 +1,20 @@
.piePath {
fill: var(--tertiary-background);
stroke: var(--label);
stroke-width: 1px;
stroke-dasharray: 0;
stroke-linecap: round;
}
.labelPath {
fill-opacity: 0;
}
.pieText,
.labelText {
fill: var(--label);
font-weight: 800;
}
.pieText {
display: none;
fill: white;
}
.group:hover > .piePath {
fill: var(--primary-accent);
filter: drop-shadow(0px 0px calc(6rem / 16) var(--primary-accent));
}
.group:hover .pieText {
display: inline;
}

View File

@ -1,8 +1,11 @@
import { Group } from "@visx/group";
import Pie, { ProvidedProps } from "@visx/shape/lib/shapes/Pie";
import { Text } from "@visx/text";
import { withTooltip } from "@visx/tooltip";
import React from "react";
import { getTooltipPosition, TooltipWrapper } from "./TooltipWrapper";
import styles from "./PieChart.module.css";
interface PieChartProps {
@ -15,20 +18,14 @@ interface PieChartProps {
padRadius?: number;
/** Distance of gap in center of pie graph, in pixels. */
innerRadius?: number;
/** Font size of text inside the pie, in pixels. */
pieTextSize?: number;
/** X-axis offset of the pie text, in pixels. */
pieTextXOffset?: number;
/** Y-axis offset of the pie text, in pixels. */
pieTextYOffset?: number;
/** Accessor function to get value to display as pie text from datum. */
getPieDisplayValueFromDatum?: (datum: PieChartData) => string;
/** Font size of labels outside the pie, in pixels. */
labelTextSize?: number;
/** X-axis offset of the label text, in pixels. */
labelTextXOffset?: number;
/** Y-axis offset of the label text, in pixels. */
labelTextYOffset?: number;
/** If set, the minimum width of this graph */
minWidth?: number;
/** Accessor function to get value to display as label text from datum. */
getLabelDisplayValueFromDatum?: (datum: PieChartData) => string;
className?: string;
@ -39,105 +36,104 @@ 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>
);
}
export const PieChart = withTooltip<PieChartProps>(
({
data,
width,
labelWidth,
padRadius = width * 0.25,
innerRadius = width * 0,
labelTextSize = 40,
labelTextXOffset = 0,
labelTextYOffset = 0,
minWidth,
getLabelDisplayValueFromDatum = (datum: PieChartData) =>
`${datum.category}`,
className,
tooltipOpen,
tooltipLeft,
tooltipTop,
tooltipData,
hideTooltip,
showTooltip,
}) => {
if (minWidth) {
width = width < minWidth ? minWidth : width;
}
type PieSliceProps<PieChartData> = ProvidedProps<PieChartData> & {
pieTextSize: number;
pieTextXOffset: number;
pieTextYOffset: number;
getPieDisplayValueFromDatum: (datum: PieChartData) => string;
};
const pieWidth = width * 0.5 - labelWidth;
const cornerRadius = 0;
const padAngle = 0;
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}
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={cornerRadius}
padAngle={padAngle}
padRadius={padRadius}
innerRadius={innerRadius}
outerRadius={pieWidth}
>
{`${getPieDisplayValueFromDatum(arc.data)}`}
</Text>
{({ arcs, path }) => {
return arcs.map((arc) => {
const pathArc = path(arc) as string;
return (
<Group
className={styles.group}
key={`arc-${arc.data.category}`}
>
<path
onMouseMove={(e) => {
const tooltipPos = getTooltipPosition(e);
showTooltip({
tooltipData: `${arc.data.category}: ${arc.data.value}%`,
tooltipLeft: tooltipPos.x,
tooltipTop: tooltipPos.y,
});
}}
onMouseOut={hideTooltip}
className={styles.piePath}
d={pathArc}
/>
</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;

View File

@ -10,6 +10,7 @@
display: flex;
font-size: calc(16rem / 16);
top: 0;
justify-content: center;
}
.key {

View File

@ -1,5 +1,4 @@
import { AxisLeft, AxisBottom } from "@visx/axis";
import { localPoint } from "@visx/event";
import { GridRows, GridColumns } from "@visx/grid";
import { Group } from "@visx/group";
import { LegendOrdinal } from "@visx/legend";
@ -12,7 +11,7 @@ import { WithTooltipProvidedProps } from "@visx/tooltip/lib/enhancers/withToolti
import React from "react";
import { Color } from "utils/Color";
import { TooltipWrapper } from "./TooltipWrapper";
import { getTooltipPosition, TooltipWrapper } from "./TooltipWrapper";
import styles from "./StackedBarGraph.module.css";
@ -194,12 +193,11 @@ export const StackedBarGraphVertical = withTooltip<
}}
onMouseMove={(event) => {
if (tooltipTimeout) clearTimeout(tooltipTimeout);
const eventSvgCoords = localPoint(event);
const left = bar.x + bar.width / 2;
const tooltipPos = getTooltipPosition(event);
showTooltip({
tooltipData: bar,
tooltipTop: eventSvgCoords?.y,
tooltipLeft: left,
tooltipLeft: tooltipPos.x,
tooltipTop: tooltipPos.y,
});
}}
/>
@ -390,12 +388,11 @@ export const StackedBarGraphHorizontal = withTooltip<
}}
onMouseMove={(event) => {
if (tooltipTimeout) clearTimeout(tooltipTimeout);
const eventSvgCoords = localPoint(event);
const left = bar.x + bar.width / 2;
const tooltipPos = getTooltipPosition(event);
showTooltip({
tooltipData: bar,
tooltipTop: eventSvgCoords?.y,
tooltipLeft: left,
tooltipLeft: tooltipPos.x,
tooltipTop: tooltipPos.y,
});
}}
/>

View File

@ -1,3 +1,5 @@
import localPoint from "@visx/event/lib/localPoint";
import { Point } from "@visx/point";
import { Tooltip } from "@visx/tooltip";
import React from "react";
@ -11,6 +13,23 @@ type TooltipWrapperProps = {
children?: React.ReactNode;
};
// Finds the SVG Element which is the outmost from element (highest parent of element which is svg)
function getOutmostSVG(element: Element): SVGElement | undefined {
let rootSVG: HTMLElement | Element | null = element;
let current: HTMLElement | Element | null = element;
while (current) {
console.log(current);
if (current.tagName == "svg") {
rootSVG = current;
}
current = current.parentElement;
}
return rootSVG as SVGElement;
}
const TooltipWrapper = ({
top,
left,
@ -32,4 +51,35 @@ const TooltipWrapper = ({
);
};
export { TooltipWrapper };
function getTooltipPosition(
e: React.MouseEvent<
SVGTextElement | SVGPathElement | SVGLineElement,
MouseEvent
>
) {
// ownerSVGElement is given by visx docs but not recognized by typescript
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const eventElement = e.target.ownerSVGElement as Element;
const eventSvgCoords = localPoint(eventElement, e) as Point;
const rootSVG: SVGElement | undefined = getOutmostSVG(eventElement);
if (!rootSVG) {
console.error("Failed to find parent SVG for tooltip!");
return { x: 0, y: 0 };
}
const rootSVGLeft = rootSVG.getBoundingClientRect().left ?? 0;
const parentDivLeft =
rootSVG.parentElement?.getBoundingClientRect().left ?? 0;
// visx localPoint does not account for the horizontal shift due to centering of the parent element,
// so manually add any shift from that
const alignmentOffset = rootSVGLeft - parentDivLeft;
return {
x: eventSvgCoords.x + alignmentOffset,
y: eventSvgCoords.y,
};
}
export { TooltipWrapper, getTooltipPosition };

View File

@ -1,5 +1,3 @@
import { localPoint } from "@visx/event";
import { Point } from "@visx/point";
import { scaleLog } from "@visx/scale";
import { Text } from "@visx/text";
import { useTooltip, withTooltip } from "@visx/tooltip";
@ -9,7 +7,7 @@ import { Color } from "utils/Color";
import { inDevEnvironment } from "utils/inDevEnviroment";
import { useIsMobile } from "utils/isMobile";
import { TooltipWrapper } from "./TooltipWrapper";
import { getTooltipPosition, TooltipWrapper } from "./TooltipWrapper";
import styles from "./WordCloud.module.css";
@ -197,33 +195,22 @@ const WordCloudWords: React.FC<WordCloudWordsProps> = ({
className={styles.word}
textAnchor="middle"
onMouseMove={
((e: React.MouseEvent<SVGTextElement, MouseEvent>) => {
// ownerSVGElement is given by visx docs but not recognized by typescript
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const eventElement = e.target.ownerSVGElement as Element;
const eventSvgCoords = localPoint(eventElement, e) as Point;
const rootSVGLeft =
eventElement.parentElement?.parentElement?.getBoundingClientRect()
.left ?? 0;
const parentDivLeft =
eventElement.parentElement?.parentElement?.parentElement?.getBoundingClientRect()
.left ?? 0;
// visx localPoint does not account for the horizontal shift due to centering of the parent element,
// so manually add any shift from that
const alignmentOffset = rootSVGLeft - parentDivLeft;
((
e: React.MouseEvent<
SVGTextElement | SVGLineElement,
MouseEvent
>
) => {
const tooltipPos = getTooltipPosition(e);
if (word.text) {
showTooltip(
{
text: word.text,
value: (cloudWords[index] as WordData).value,
},
eventSvgCoords.x -
word.text.length * TOOLTIP_HORIZONTAL_SHIFT_SCALER +
alignmentOffset,
eventSvgCoords.y
tooltipPos.x -
word.text.length * TOOLTIP_HORIZONTAL_SHIFT_SCALER,
tooltipPos.y
);
}
}) as React.MouseEventHandler<SVGTextElement>

481
data/mental-health.ts Normal file
View File

@ -0,0 +1,481 @@
export const H1 = [
{
category: "Yes",
value: 58,
},
{
category: "No",
value: 42,
},
];
export const H2 = [
{
category: "Yes",
value: 83,
},
{
category: "No",
value: 17,
},
];
export const H2i = [
{
category: "Academic Term",
value: 83.9,
},
{
category: "Co-op Term",
value: 16.1,
},
];
export const H2ii = [
{
category: "In person",
value: 51,
},
{
category: "Online",
value: 45,
},
{
category: "Both",
value: 4,
},
];
export const H3 = [
{
category: "Yes",
value: 23,
},
{
category: "No",
value: 77,
},
];
export const H3i = [
{
category: "Yes",
value: 51.3,
},
{
category: "No",
value: 48.7,
},
];
export const H3ii = [
{
category: "Money",
value: 12,
},
{
category: "Stereotypes",
value: 8,
},
{
category: "Unresponsive therapist office",
value: 1,
},
{
category: "Scared",
value: 1,
},
{
category: "Judgment from others",
value: 3,
},
{
category: "Indifference",
value: 1,
},
{
category: "Lack of information",
value: 25,
},
{
category: "Skeptical",
value: 2,
},
{
category: "No strong need",
value: 1,
},
{
category: "Laziness",
value: 6,
},
{
category: "No time",
value: 20,
},
];
export const H4 = [
{
category: "Yes",
value: 24,
},
{
category: "No",
value: 76,
},
];
export const H4i = [
{
category: "Yes",
value: 26.6,
},
{
category: "No",
value: 73.4,
},
];
export const H4ii = [
{
category: "No time",
value: 14,
},
{
category: "Unresponsive therapist office",
value: 3,
},
{
category: "Scared",
value: 1,
},
{
category: "Lack of information",
value: 12,
},
{
category: "Stereotypes",
value: 5,
},
{
category: "Money",
value: 7,
},
{
category: "Judgment from others",
value: 1,
},
{
category: "Laziness",
value: 4,
},
];
export const H5 = [
{
category: "Yes",
value: 21.2,
},
{
category: "No",
value: 78.2,
},
];
export const H5i = [
"Depends on the person you get, some are really good but some I didn't click with",
"Good, although I never attended a session",
"It was average. The people there are kind and care about you.",
"Average",
"Mediocre",
"Pretty good minus how busy they are",
"meh",
"They tried their best, but I felt underwhelmed and it felt like I was wasting my time there.",
"Great",
"It is not as accessible as you would hope, and it is hard to continue to see your doctor",
"Good",
"not half bad.",
"Dogshit. long wait times. I was low priority since I was 'well functioning'",
"No experience ",
"It was just alright.",
"Meh",
];
export const H6 = [
{
category: "1",
value: 3,
},
{
category: "2",
value: 9,
},
{
category: "3",
value: 19,
},
{
category: "4",
value: 52,
},
{
category: "5",
value: 15,
},
];
export const H7 = [
{
category: "1",
value: 4,
},
{
category: "2",
value: 13,
},
{
category: "3",
value: 35,
},
{
category: "4",
value: 41,
},
{
category: "5",
value: 7,
},
];
export const H8 = [
{
category: "3",
value: 1,
},
{
category: "4",
value: 2,
},
{
category: "5",
value: 1,
},
{
category: "6",
value: 9,
},
{
category: "7",
value: 22,
},
{
category: "8",
value: 27,
},
{
category: "9",
value: 26,
},
{
category: "10",
value: 12,
},
];
export const H9 = [
"Played games, video called, voice called.",
"Playing video games over Discord, meeting up in person and going on walks or picnics",
"Scheduled game nights with a large group of friends (to play mafia/among us) + did secret santa food edition",
];
export const H9i = [
"Mental health at Waterloo is pretty bad. The environment generates a lot of pressure and people crack very much under that pressure.",
"Everyone deals with mental health. You aren't some special snowflake, and you also aren't immune. It will always get better once you accept that and are able to talk about it at least to yourself. ",
"Take breaks",
"I wish some of the people here remembered that at the end of the day, life moves on, and are things that make life worth living besides the prestige and money that comes with being sexy",
"Don't be afraid to reach out for help, therapy is worth it!",
"Competition at Waterloo can be tough on mental health sometimes.",
"It is pretty scary that you could just be totally unknown in university, nobody would never know anything that happens to you. I feel that a lot of people with mental health problems can go down like this.",
"If you ever feel your mental health is declining, don't be afraid to talk to your profs and TA's about it, they're all there to help you. Don't isolate yourself from your friend group, as that'll only make things worse. The most important thing is to not keep everything bottled up.",
"Consider reaching out to professionals if you are struggling with mental health. However, it is completely normal to try multiple therapists until you can find the one that really vibes with you.",
"UW has terrible support nets for students who are struggling. This is the biggest differentiator between UW and say a liberator arts college. Recognizing that you are on your own is an important step to taking control of your own mental health.",
"I think the support systems for mental health in university are definitely less structured, and it's easier to 'fall through the cracks', especially being away from long-time friends and family from your hometown.",
"The school does not seem to care at all",
"I hope we can work on mental health in general, not just for disorders but also just a general wellbeing",
"Mental health at the University of Waterloo in particular is very challenging to navigate. We all hear a lot about the toxic environment and the 'cali or bust' mentality and all this and all that all the time, and for good reason I think it's very tough for an 18 year old growing up with traditional Canadian values dumped into a prestigious tech school to avoid falling into these thought traps and seemingly zero sum games. I think we should all step back and take some time to reflect on how different our university experiences here at the University of Waterloo are compared to those of other schools, just to give us some perspective on things. ",
"Mental health at Waterloo has never been really great. Back in first year, there were a bunch of people that committed suicide and since then, the pandemic has happened. Arguably, that's made it worse (being in quarantine the whole two years). Hopefully it gets better in future years, but Waterloo's mental health generally stems from the highly competitive environment that the students curate themselves. It's a vicious cycle.",
"I find my mental health is the worst when I'm under a lot of stress and spread myself too thin. During the pandemic, I find myself too focused on school work which made the stress worse.",
"Uw provides good resources if you seek them out/really need them. Otherwise, just git gud. ",
"I used to think I was sad in high school, I was stressed in high school, but never have I felt such intense versions of sadness and stress as I have during my undergrad. With that being said, I will never feel as proud and accomplished as I did when I got my first “big coop” or when I pulled off a near perfect in a CS course!",
"You have to look out for yourself, your parents are there with you",
"Having somewhere to vent or someone to listen and bounce thoughts off is really helpful for mental health. You're definitely not alone in experiencing what you're experiencing. It helps to put thoughts into words (by talking/writing/typing it out).",
"You're probably going to struggle a lot at some points and that's ok if you know how to deal with it",
"Will likely deteriorate, especially if you struggle with maintaining friendships.",
"1. Maintaining mental health and believing in yourself are essential conditions for developing your intellectual potential. 2. Pay attention to exploration and innovation in study. 3. Scientific use and rational development of the brain. 4. Focus on self-encouragement and reflection, and constantly awaken self-realization and self-transcendence. 5. Make good use of sound and beauty activities to develop innovative potential.",
"I think the competitive nature of CS forces a lot of student to value coops and school over their mental health. Its hard to not as we came to this program to be the best and its hard to not compare your self to everyone else. ",
"school gives me anxiety but if i care less then it's okay, it's mostly just me placing dumb expectations on myself",
"overthinking is bad",
"No one can truly understand or appreciate your suffering. Your challenge is unique to yourself, but you still likely need some other input (doctor, friend, counsellor etc.) to overcome it. ",
"I didn't feel supported in courses it felt like everything was a competition.",
"Being consistently overwhelmed can lead to mental health problems. That's why it's so important to take breaks. It's also crucial to stay organized (easier said than done). But the way I stay accountable and on top of things is a simple schedule. I put every due date in my calendar on the first day of class and set up a grade calculator. And that's all I do on the first day of class. From then on, I make a table labelled Monday through Friday, and put every task to start/continue/finish underneath. This is where the calendar comes in, which will help you prioritize the tasks. On top of that, I couldn't survive a term without study buddies. My keys to success have literally been keep a calendar of due dates, schedule your week, and find people who can help you when you just don't think you can do it.",
"I really dont know, high school courses were all easy for me but university courses tend to be a lot harder. But i am already in this program so what can i say. I already switched my program once, so i am already behind, if i switch back i will be even more behind and i dont have enough money to delay my gradutaion even more. So what else can i do besides bare with it.",
"I have developed a deep hatred for UW faculty. Avoiding thinking about my time in university is the best thing i can do for my mental health. ",
"Figure out a sleep schedule that works and prioritize it. ",
"Please, please take care of your mental health.",
"Multiple co-op sequences causes people to feel lonely and depressed",
"I think I have ADHD or a learning disability but I never knew what I should do about that, if anything (since I was still passing... mostly)",
"A lot of sudden change going into university, everyone is struggling",
"People need to go outside more",
];
export const H10 = [
{
category: "Yes",
value: 27.4,
},
{
category: "No",
value: 72.6,
},
];
export const H11 = [
"Talk to friends",
"Physical activity, playing guitar/singing, talking with friends, moving to a new city for a fresh start",
"I study therapy and counseling theory",
"Exercise",
"Go on walks, music",
"Go on long walks",
"Talk to close friends",
"I write to myself, go outside, listen to music, watch films about parts of the world I want to visit, do photography",
"Breathing exercises, healthy living, relaxation activities like reading and meditation",
"I vent to friends and meditate",
"Hang out with friends, reading a good book",
"Coffee, League of Legends",
"Friends",
"Write diaries and seeking professional help",
"physical exercise, video games, cooking, spending time with significant other",
"sleep, cry, eat, alcohol",
"hobbies, sport",
"Have a good night sleep",
"meditate",
"drink, sleep, academics, walk, music",
"Journal.",
"Assignments",
"Therapy, spend time alone, find outlets for self-expression, avoid social media, try and eat healthy, exercise, self-reflection/values reevaluation, meditate, incorporate flow",
"Self harm, talking to friends, drinking",
"Friends, self reflection, food",
"Tiktok and talk to friends",
"Distract myself with something I enjoy doing, try to be productive in a different way",
"I talk to and spend time with my friends, and allow myself to wallow and take days off when needed.",
"Step away from work, cry if needed",
"Make sure I have enough time to feel relaxed and do things I enjoy",
"Talking to friends",
"Talking with others",
"Chatting with friends, playing an instrument, talking out loud to myself",
"Try my best. If it doesn't work out \"C'est la vie\" and get high",
"Journaling, watching shows, playing video games, hanging out with friends",
"Feel it out",
"Develop innovation potential.",
"Look at the bigger picture",
"Go for walks, reach out to friends, pick up hobbies to keep busy",
"Meet friends, keep myself distracted",
"Go on Walk, Hang out with friends, talk to girl friend.",
"take a nap",
"Indulge in my hobbies",
"Never focusing too much time or energy on one aspect of life/identity. Sunshine and exercise are underrated. ",
"binge eat",
"See H9",
"Just think at least i passed and i am still alive, and being alive is good, aftet COVID, nothing else is important besides staying alive.",
"Talk to partner",
"Talk to my friends",
"Exercise, pace",
"Bike, pray, walk, call a friend",
"Taking a break, sleeping, going out, having fun.",
"Cry and distract myself with work, go see friends",
"Go for walks by laurel creek",
"Over the years, I've learned to prioritize my physical health (sleep, diet, exercise) and I have found it extremely beneficially to my mental health as well. Sleeping 8 hours a night, eating 3 meals a day, and getting some fresh air will do wonders. ",
"Meditate and exercise",
"Play games with friends",
];
export const H12 = [
"It stresses out the people you love the most. It also makes it 10 times harder to get things done and to push yourself when you're already so strained.",
"Mental health affects every aspect of your life. If you aren't in a good place mentally, everything you do will take a hit. Your relationships will be strained, studying will become harder, and you'll burn out much faster. Always take care of yourself first.",
"I make sure I am ok before I focus on any of those things.",
"It affects my ability to communicate with a clear head and also my productivity during work",
"Hasn't really",
"Affects friendships the most. If I'm not in a good state of mind, I can't even talk to my friends properly or given them the attention they deserve.",
"My stress and anxiety make it harder to put effort into the things I do, even if I like doing them. Tends to make my work worse and makes me a worse boyfriend. ",
"It introduces a lot of unnecessary stress that interferes with everything",
"My productivity and motivation decreases when I am stressed or burnt out. I also don't socialize as much when I am stressed.",
"Quite a lot",
"makes everything else alot more difficult",
"affects my motivation to maintain relationships and be focused on career",
"Honestly I don't really know.",
"Affects my growth in all areas and how I deal with problems ",
"I personally feel like my mental health affects everything. The only way I can describe the affect is that positive mental health leads to positive effects in these areas. ",
"Significant impact ",
"Depression affects the motivation to do anything. Sometimes you just lay in bed and can't get out to face the day. Multiple days waste away and you just can't function properly. Lots of friends have trouble helping me and from my social anxiety, I miss out on a ton of social events. ",
"It can hinder some parts",
"It forces me to prioritize and stay on top of my work, because I have to account for the sporadic and spontaneous bad days that prevent me from getting things done. Its also made my hyper aware of being a burden on my friends, and occasionally made me less productive on work terms than I should have been.",
"Its necessary to be successful/have fun when pursuing relationships, doing work/studying",
"It affects my relationship with my parents the most, because they are the most invested in me. It is hard to make them understand how I feel. My relationship with my boyfriend is generally great, because I feel I can share whatever I like with him. Similarly with friends, mental health does not affect my relationships with them, because we have 0 expectations from each other but are always supportive of each other. My academics have definitely suffered, but speak to your profs, they are amazing and very understanding! You will be surprised at the accommodations they can offer. ",
"Negatively affects relationships",
"It's easier to study when your mental is good",
"It definitely affects my mood, which unconsciously affects how I go about the various aspects of my life.",
"Bad mental health affects all of them negatively.",
"Occupation",
"Anxious about risks and failure",
"It just takes time out of my day, even though there are sometimes that I'd want to be more productive/meet new people anxiety or other issues make that difficult sometimes",
"Makes me less motivated in all aspects of life",
"Motivation loss in everything",
"makes it harder to maintain consistent output/effort",
"I am too tired to do anything just want to lay in the bed for the whole day.",
"Makes me less interested in pursuing relationships with others. I cut myself off from people. ",
"Not much at all anymore",
"Definitely makes studying/work much harder if I'm not feeling great.",
"Friendships feel painful sometimes due to anxiety",
"Stress of school and time taken by procrastination leaves little time for enjoying life",
"Very adversely",
];
export const H13 = [
{
category: "Yes",
value: 73.2,
},
{
category: "No",
value: 26.8,
},
];
export const H14 = [
"Help people be more aware, provide more resources and accomodation.",
"Promote better school involvement and school spirit! Also offer and push counselling/therapy services more. ",
"communicate what situations warrant a trip to see a professional ",
"More accessible mental health services, wait times are too long",
"Better and standardized accommodations for students going through mental health difficulties during the term. Some instructors are just so insensitive. UW's accessibility services are pretty good in my experience, and should be better publicized as a resource for everyone.",
"Definitely, for me it's that I don't really feel a sense of belonging in the school community. Waterloo never really felt like home, it was just somewhere I stayed for a few months at a time.",
"Promote more dialogue on mental health in general.",
"Hire better mental health professionals",
"There are many things that can be done but all of which are too expensive to actually implement for UW.",
"Not throwing me false Policy 71 accusations, then having me fight it for a whole month.",
"Maybe a webpage for easy to understand instructions on how to get resources",
"more accessible counselling",
"Normalize reduce course loads",
"Not sure UW can do anything to help. Maybe more awareness and attempts at supporting us throughout the terms.",
"never go fully remote ever again :)",
"Have more visibility on mental health services + improve wait times",
"Maybe not make such terrible CS Finals geez.",
"Stimulate learning motivation, motivation is to promote people to engage in something idea or desire, is directly to promote a person to carry out activities of the internal power. Learning motivation is an internal psychological process or internal psychological state that stimulates individual learning activities, maintains the learning activities that have been caused, and makes behavior toward a certain learning goal.",
"I think they need to be more lenient with failed/dropped courses, the student here value their program a lot and the fear of failing out is one of the main drivers of mental health struggles (IMO), so giving the students who are struggling academic flexibility will help imo.",
"hire more counsellors",
"I would say make the finals easier but that's not going to happen so i think there's nothing you can do.",
"Ask professors to pretend to care about students success",
"Better promotion of available services, more availability.",
"Be more accommodating of student stress",
"Support study group opportunities for students without friends to even the playing field first year calculus was very stressful :(",
];

334
data/personal.ts Normal file
View File

@ -0,0 +1,334 @@
export const P2 = [
"I have a bunch, but it might be singing in A Cappella. I've always loved to sing, and being surrounded by so many talented singers was an absolutely amazing experience.",
"Staying up late night and talking to friends about life",
"Travelling to Alaska during online school",
"Getting my fulltime offer after grinding for over 2 months",
"Thanks Mr. Goose",
"Just spending time with friends ",
"HvZ weeklong, Winter 2018",
"Going on dates with my boyfriend",
"Spending time with my significant other",
"Took someone else's backpack by accident",
"hiking in the snow on the grand river trail",
"Chanting 'Truth Tables, Part Marks!' over and over again with my classmates into our Math 145 Midterm",
"Running around outside with my roommates at night or coming back from a late night session.",
"probably running around SLC in my underwear",
"Spending every Friday with a couple friends, barhopping and getting drunk. Telling stories about your life and having a good time after a long week.",
"Watching White Vhicks at V1 study hall with friends instead of studying",
"nothing comes to mind =(",
"Just sitting in random classrooms with friends, hijacking the projector to play music while “studying” but really just enjoying each others company and procrastinating on work together :)",
"Jamming together with friends on campus",
"Going to class with all the other DDs",
"Watching snow",
"Getting a photo taken with friends at Busan and having it blow up on the subreddit O.o",
"Watching Netflix, playing Catan and drinking bubble tea with the boys. Simple but everything. That or anytime in SERVE in 2018/2019.",
"Taiwan trip with UW friends",
"Go shopping hand in hand with the opposite sex for the first time.",
"Meeting my girlfriend in Math 135",
"watching movies and drinking with friends",
"Looking forward to eat from some restaurant",
"meeting friends",
"the 'good ol days'. the first 2 years here were so nice, so much exploration and novelty",
"Nothing specific, but the moments I spent at V1 Center during my first year were very nice.",
"Waking up 6:50 in the morning for class and climbing a mountain of snow because my google map headed me to the wrong direction.",
"Time spent in clubs",
"celebrating with classmates/roommates after exams",
"Probably the first time I got a job I was really interested in.",
"Singing with my friends while having some beers",
"My buddy's bday party in 2B was definitely one of the best, we turned way tf upppp",
];
export const P3 = [
"Have fun! Don't overthink everything and just go for it.",
"Join intramural basketball regardless of skill level",
"you fail 100% of the exams you don't show up to",
"Actually doing hobbies outside of school is so valuable",
"Chill",
"Going into continuous can sometimes be a better decision than accepting a job you don't want in main round",
"Take your time. Everything is going to be okay, there's no rush to do anything.",
"Spend more time on the things you enjoy doing and don't worry about marks too much.",
"Don't be so stressed out about co-op, and don't stay home so much D",
"Life will be ok",
"Stop worrying about grades, make more time to meet new people and pursue your hobbies.",
"Take it easier, buy GME stock",
"Keep your toughness",
"Do not consume alcohol or other substances that inhibit your ability to make good decisions",
"Listen to others talk more; be less cringe",
"diversify your interests",
"talk to more people",
"There actually is light at the end of the tunnel... no seriously",
"Chill the f out and be yourself",
"you're gonna be a legend some day",
"Try and figure out who you are and what you stand for. Be someone who is irreplaceable and surround yourself with people that you want to be.",
"Get your resume roasted more.",
"Get out of your comfort zone by meeting more people and trying new things!",
"drink and eat edibles !",
"stop being religious, go to parties, be open minded",
"Its okay to take breaks from work!! Go get food with a friend, say yes to the spontaneous outing! Go to that weekend hackathon! youll be okay and you wont fall behind!",
"Stick with theatre! Its a lot of work but its fun after all",
"Put yourself and everything you want first!",
"Drink less",
"Pick a different program",
"Grades don't matter",
"Try more new things, uni goes by quicker than you think",
"Don't stay at home and study all night. Enjoy university life before it's over. With that said first year low-key brutal so study hard",
"Try to experience life beyond school and coop",
"u r the best people to make money !",
"Chill out my guy.",
"Join a company you love.",
"Dont copy assignments, getting a 60 and actually understanding the material is better than getting a 90 and not, you will pay for it come finals. ",
"Stop worrying about grades so much and go meet new people, nobody cares after graduation",
"ur not special, and also you should draw more",
"Try to make more friends and be more social",
"staying on track",
"Put yourself out there more while school is still in person. ",
"Your hard work paid off! good job.",
"The geese won't actually attack you. ",
"Get organized with your calendar, make a grade calculator, and find friends in every class",
"You guys did really well.",
"Take it easy on yourself. It's ok to not be perfect.",
"Just pass the classes. Don't even consider caring about learning or doing well in them. ",
"It gets better, but you've also gotta get better. It's not high school anymore, you've gotta change how you study!",
"STOP PLAYING LEAGUE and go get involved in school activities!",
"Dont get in a relationship ",
"You're not unloveable. Don't take this time for granted. Make lots of friends, work on yourself, have lots of sex. It's a process!",
];
export const P4 = [
"If you don't believe in yourself, nobody else will.",
"I see says the blind man",
"lift to gain not to lift the weights",
"It smells like updog in here",
"The most important step someone can take isn't the first one. It's the next one.",
"Don't choke on your aspirations Darth Vader",
"The imagination is precious. Don't lose it. Don't lose the child in you.",
"“He who has a why to live for can bear almost any how.”",
"Due tomorrow do tomorrow",
"Always double and triple check, just to be safe.",
"All the lovely math theorems",
"Listen to others talk more; be less cringe",
"Not all those who wander are lost",
"Learning is like rowing upstream, not to advance is to fall behind. (More precisely, 學如逆水行舟,不進則退)",
"We do this, not because it is easy, but because it is hard",
"Your strength will come from self acceptance. ",
"Run it",
"Live each week as you would want to live every week",
"Do it, otherwise you'll regret not doing it.",
"Comparison is the thief of joy",
"I am the master of my fate, I am the captain of my soul. Invictus poem.",
"Just because you may have gotten a bit lucky, doesnt mean you dont deserve it",
"It matters not how strait the gate, How charged with punishments the scroll, I am the master of my fate, I am the captain of my soul.",
"Carpe diem",
"Believe in yourself",
"Yesterday is history, tomorrow is a mystery, but today is a gift. Thats why it is called the present Master Oogway, Kung Fu Panda",
"C'est la vie",
"TIME IS MONEY",
"Selfdistrust is the cause of most of our failures.",
"Treat others how you would like to be treated",
"Nothing in life is more important than happiness.",
"If you're not enough without it, you'll never be enough with it. ",
"Due tomorrow, do tomorrow",
"The best is yet to come",
"Expect disappointment and you will never be disappointed",
"F*** it",
];
export const P5 = [
"Took notes for me while I fell asleep.",
"They brought me McDonald's when I had a late exam",
"ask me out",
"Lent me a pencil",
"Gave me all their notes when I lost my notebook",
"Did my assignment",
"Be in a committed relationship with me",
"Compiled my code every time I wanted to test it, for a whole semester, because I was too lazy to set up the student environment",
"Teaching me even though they are not currently taking the course",
"i had a classmate who got a 17% on an assignment, and that gave me a great chuckle",
"I think sometimes the most touching thing someone can do for me is just ask if I'm doing okay and genuinely care about the answer.",
"Gave me class notes",
"Held my hand and guided me through my hell of a first year.",
"Let me stay/live at their place for an extended period of time.",
"saved a seat for me every class in Daves cs135 packed section strangers at the time but still friends to this day <3",
"One time after having a heavy conversation after a club meeting, I was sitting alone on campus looking kind of down. A stranger came up to me and asked me if I was okay and chatted with me for a bit.",
"My clicker died in class and my classmate swapped their clickers batteries with me for very question!",
"Help me out with an assignment, by helping me come up with multiple solutions to each question to ensure I understood it properly",
"My roommate brought my clicker to school while I was in the middle of class",
"Offered to help me not fail japanese ",
"Be concerned about your life.",
"Sent me assignment answers ",
"Answer my question when I was confused in class? idk",
"give iclicker answers",
"Walked me through assignments so I could learn to get the right answers",
"Helped me out for an assignment question that i struggled for days",
"Brought me food after a family member died right before finals which i was forced to take. ",
"IDK, strike up a conversation randomly while waiting.",
"Bake me a cake",
];
export const P6 = [
"Have a routine. Have breakfast, workout, and make time for hobbies. Also reframing perspective; helps you to see the positives in situations.",
"Movie tickets are cheaper when you buy them at slc turnkey",
"always carry a condom on campus",
"Install autojump and fig for your terminal, use Atom as your text editor.",
"Compile your code with -fsanitize=address",
"Set the bar so low that you can't trip over it",
"Cook 4 portions of food each time. Now you won't have to cook for the next day or two.",
"Keep things in perspective. Read about the struggles of those less fortunate.",
"Go to the MathSoc office (MC 3038) for free snacks if you're hungry while on campus, and too lazy to go buy actual food.",
"When it comes to school/career, build your meta-skills first. Before studying, always think about how to study.",
"Figuring out what you want, finding out the steps to get there, and executing the steps",
"Go to Needles Hall for your class overrides... they don't care if you have an advisor signature, as long as you have a prof signature.... aka, step aside advisors lol",
"Always ask for forgiveness, never permission. ",
"optimize your bird courses and your undergrad becomes a breeze",
"Travel when you're on co-op. Know that if you have extra funds, it's always nice to do some exploring on weekends. You'll regret not doing so if you get the opportunity. Also, I try to sit next to someone new every term. Say hi to people on the first class, and if you don't vibe, try someone new next class. I've met friends in every term by doing this.",
"Sleep enough and exercise. Also drink enough water.",
"download linux and do all your work on it. THen after the conditioning, when you boot into linux, you are 110% focused.",
"submitting half an assignment is better than submitting no assignment at all",
"Let the rice cool down so it doesn't stick to the rice cooker",
"Sleep is important",
"You get more motivation when the assignment is due in a few hours",
"Document your life. Vlog or photos. You'll want to look back on them ",
"Live a self-disciplined life.",
"Air fryers are the best",
"be critical of people's opinions, lots of people bulls*** frequently & have bad sources for their opinions",
"Get organized with your calendar, make a grade calculator, and find friends in every class",
"Onky do things that make u happy",
"Get an oversized bowl and spoon for meals. Cook food, dump into bowl, mix, scoop into mouth. ",
"you can avoid bad weather by using the bridges/tunnels that connect most buildings",
"Get a rice cooker. You can make so much s*** in it, and you'll stop messing up rice.",
"Crowdmark PWA bookmark on iPhone with fingerprint-controlled password manager. Makes handing in assignments at the last minute much easier just take pic with CamScanner, export to photos, tap Crowdmark 'app', fingerprint to log in, and upload pic from photos library directly to Crowdmark without stumbling over typing your password at 11:58.",
"Eat healthy and move ",
"F*** PD",
];
export const P7 = [
"Time is fleeting! It's insane that I've spent almost 5 years as a UW student. As I move into the next stage of my life and complete that, I'm sure I'll feel the same. So, lesson is live in the moment and do what you want to do.",
"Instead of cali or bust, we should have dream or bust. Don't chase after the hype! Figure out what you are passionate about and run with it.",
"people r real idiots and they'll only get dumber",
"Taking care of my mental health is the most important thing. Coffee works.",
"Grind never stops",
"Just saying 'yes' can lead you to a lot of new experiences.",
"Capitalism is a meat grinder that grants us with lots of nice amenities.",
"Patience",
"People aren't judging you as much as you think they are.",
"No pain no gain",
"Past a certain point, the efforts you invest towards a goal are more important than your innate talent",
"I'm not the smartest guy I know",
"Even if you don't think you can do it, you can probably push through and make it.",
"you have to let go if you want to be free",
"Jump at every opportunity. Say yes to more things. You'll find yourself meeting more people, potentially meeting your next best friend or next SO. You might also find yourself advancing faster career-wise/co-op-wise simply because you're taking on new challenges.",
"To enjoy life in moments.",
"people who work full time can be equally as clueless, if not more clueless, as you are",
"Everyone is just as scared and clueless as you, so crack a joke, compliment someone, start a conversation!",
"Friendships are important",
"Grades don't matter",
"Learn how to do multiple choice questions. Look for contradictory answers. Look for long answers. Look for too specific answers. ",
"One day at a time.",
"Mass media and politics.",
"At the end of the day its your life, do what makes you happy and what you will remember 20 years from now. ",
"I took living with my parents for granted",
"going to office hours",
"How to move on from rejection/failure. ",
"perceptions are as important than work output in the real world",
"Nobody cares about your grades. ",
"Your friends will get you through",
"I am now on my own, and i need to deal with whatever comes by myself",
"Improve myself. ",
"It's fine to take L's from time to time. You can't always win.",
"Doing something is better than nothing ",
"that noone cares about you. That is both a good thing (noone remembers your f****ups) and also a bad thing (casual indifference of society is hard). ",
];
export const P8 = [
"Spending time with friends and constantly pursuing what I love. Right now that means playing as many sports as possible and making time to see my friends.",
"Being Christian",
"morning coffee",
"Playing music and teaching others",
"Spending time with close friends",
"Seeing beauty when looking at ordinary things from a different angle, I try to do that as much as possible when shooting photos as a hobby.",
"My relationships with others",
"Kyu Min",
"Being able to pursue my hobbies.",
"Being able to put efforts into work and seeing the results.",
"Sharing my achievements with my significant other",
"Friends",
"being alive",
"I'm 22, and I have a good amount of stories to tell... and I'm just getting started ;)",
"Eating and spending time with my friends",
"my ability to break the rules",
"My relationship ",
"Being able to spend time with those that I love.",
"My ability to be independent",
"rock climbing",
"sports lol",
"my friends!! i love them so much",
"Having friends and a girlfriend who support me and I can be myself with and have fun with",
"Friends and Boyfriend!",
"Spending time with my friends",
"Family/Friends",
"I finally go to the gym not out of hatred",
"Friends, games, shows",
"MY HEALTH",
"Personal growth.",
"In order to study music。",
"my friends and girl friend ",
"i like drawing",
"Feeling like I secured my future after university",
"My relationship with my parents improved a lot over university.",
"my personality and strengths",
"To be honest, feeling more mature mentally and mathematically.",
"My boyfriend",
"Music and anime and BL novel",
"my besties",
"My high school friends",
"Making stuff that makes others happier or people can find useful.",
"My friends",
"Tacos",
];
export const P9 = [
"Take a genuine interest in class material",
"have friends not in CS, the perspective of how life is enjoyable without the competition of coop is nice",
"Don't give up. It gets better",
"Prioritize your mental health, because if you're under the weather, it affects almost everything else in your life. Also, coffee works, kids",
"The hardest problems are solved with some food and a good night's sleep.",
"Treat co-op as a 6th course",
"Your time here is so precious and it goes by so quick, make sure to make lots of memories and try new things as often as you can. You likely won't have another period in your life when you're as free and as able-bodied as now.",
"Cs get degrees. You experience life as longer when undergoing new experiences, so try lots of new things!",
"Call || bust actually works! ",
"Learn. To. Cook. It's healthier and cheaper.",
"Keep your GPA high if you want to do grad school",
"Try to figure out what you want to do after graduation as soon as possible. Invest your time through classes and co-ops towards this goal. Focused effort in one direction is almost always better than scattered efforts everywhere.",
"Live your life, storytellably",
"Don't stress too much about jobs and grades, try to enjoy your time with friends and make some good memories. Things always work out.",
"legends live forever. rebels never die.",
"Go work out more, it's important and it'll help your mental health. Sleeping is actually more important than looking 'cool' and not sleeping. Getting 7-8 hours feels great and is very much worth it. Choose your friends wisely. Not everyone needs to be your friend and you choose who you allot that time to. Like people say, you are the average of the 5 people that surround you. Give yourself a break. It's okay to fail and it's okay to stop. Learn when to do so. Take some fun electives or electives that make you think differently (than just programming all the time). It's nice to be more well rounded despite all the hate on breadth and depth courses. I recommend PHIL121, PHIL101, RS121.",
"Don't compare yourself to others",
"co-op doesn't matter. In fact I would recommend not doing co-op; do something your passionate about during summer.",
"try and make at least one friend here. there are great people at this school, they help make your life much easier by being there with you when you struggle through tough courses and unsuccessful coop recruitment cycles. it really does make a world of a difference.",
"Don't stress too much about job search",
"Still care about your grades but dont let it consume your life :)",
"Make sure to spend time doing social/fun clubs. If you don't feel you have the time for this, you are too busy and need to make changes to be less busy.",
"Make sure to have time for yourself and your friends",
"Grades don't matter",
"Try to experience life beyond school and coop",
"JUST ENJOY UR SCHOOLS LIFE",
"Youll get through it :)",
"Students are more willing to learn and do better when their intrinsic motivation is stronger than their extrinsic motivation.",
"School teaches you how to be diligent and hardworking at a job. Grades arent the most important thing, just pass and do your best",
"CS is hard and you just gotta focus and grind out the work, but dont stress too much on the actual grade cause within the next year you (and everyone else) wont care what grade you got.",
"make time for your hobbies it's good for the brains or whatever",
"Meet people, make friends and have fun, you don't need to study that hard and grades aren't everything to be concerned about",
"Its a marathon not a sprint. Go to class. ",
"don't be worried, youll do fine & enjoy your time",
"Manage your time and don't feel too much pressure to get high grades. It does not matter in the long run. ",
"Get organized with your calendar, make a grade calculator, and find friends in every class",
"If you didn't like CS in high school dont think that you will like it in university, even if you enjoyed Racket.",
"Classes are easy if you want them to be. Do the minimum but not less",
"start assignments early",
"Try to not compare yourself with others too much. It's still helpful to do so at times, but sometimes, you've gotta accept that some people may end up doing better than you but that's fine, focus on yourself!",
"Make friends",
"Have fun, enjoy your time, thing will happen soon enough ",
"Grind leetcode.",
"Enjoy your life. F*** SCHOOL. have fun",
];

View File

@ -8,15 +8,15 @@ export const P1 = [
value: 20.4,
},
{
category: "Yes (Masters)",
category: "Masters",
value: 5,
},
{
category: "Yes (PhD)",
category: "PhD",
value: 4,
},
{
category: "Yes (PhD + Masters)",
category: "PhD + Masters",
value: 6.8,
},
];

View File

@ -68,7 +68,11 @@ export default function Demographics() {
<ComponentWrapper heading="Please indicate the pronouns that you use.">
<div className={styles.graphContainer}>
<PieChart data={D3} {...pieChartProps(isMobile, pageWidth)} />
<PieChart
data={D3}
{...pieChartProps(isMobile, pageWidth)}
labelTextSize={20}
/>
</div>
</ComponentWrapper>

View File

@ -55,6 +55,7 @@ export default function Demographics() {
heading="Rate how social you are."
bodyText="Looks like most people consider themselves to be in the middle."
align="center"
noBackground
>
<BarGraphVertical
data={F1}

324
pages/mental-health.tsx Normal file
View File

@ -0,0 +1,324 @@
import {
H1,
H2,
H2i,
H2ii,
H3,
H3i,
H3ii,
H4,
H4i,
H4ii,
H5,
H5i,
H6,
H7,
H8,
H9,
H9i,
H10,
H11,
H12,
H13,
H14,
} from "data/mental-health";
import { pageRoutes } from "data/routes";
import React from "react";
import {
barGraphProps,
pieChartProps,
barGraphWidth,
} from "utils/defaultProps";
import { useWindowDimensions } from "utils/getWindowDimensions";
import { useIsMobile } from "utils/isMobile";
import { BarGraphVertical } from "@/components/BarGraph";
import { BottomNav } from "@/components/BottomNav";
import { ComponentWrapper } from "@/components/ComponentWrapper";
import { Header } from "@/components/Header";
import { PieChart } from "@/components/PieChart";
import { QuotationCarousel } from "@/components/QuotationCarousel";
import { SectionHeader } from "@/components/SectionHeader";
import styles from "./samplePage.module.css";
export default function Demographics() {
const pageWidth = useWindowDimensions().width;
const isMobile = useIsMobile();
return (
<div className={styles.page}>
<Header />
<SectionHeader title="Mental Health" />
<ComponentWrapper
heading="Have you struggled with mental health during undergrad?"
bodyText="Mental health is a serious issue that affects the well-being of countless students. More than half of our respondants reported that they have struggled with mental health during undergrad. Often times, university can be the cause of stress, anxiety or other forms of mental struggles. Thus, it is crutial to take care of yourself as well as support one another during tough times."
>
<div className={styles.graphContainer}>
<PieChart data={H1} {...pieChartProps(isMobile, pageWidth)} />
</div>
</ComponentWrapper>
<ComponentWrapper
heading="Have you ever experienced burnout?"
bodyText="Burnouts are extremely common in our respondents, with the vast majority of people reporting that they have experienced it at some point. The constant demand for work is likely to leave students feeling overwhelmed or emotionally drained. Just keep in mind that it is completely normal to feel this way and remember to let yourself take breaks."
align="center"
noBackground
>
<div className={styles.graphContainer}>
<PieChart data={H2} {...pieChartProps(isMobile, pageWidth)} />
</div>
</ComponentWrapper>
<ComponentWrapper
heading="Do you feel burnout more during co-op or academic term?"
bodyText="Most of our respondents indicated that they are more likely to experience a burnout during their academic terms. This could be due to the amount of course work, assessments, and deadlines that must be met during an academic term. On the plus side, co-op terms give students a break from studying."
align="right"
>
<div className={styles.graphContainer}>
<PieChart data={H2i} {...pieChartProps(isMobile, pageWidth)} />
</div>
</ComponentWrapper>
<ComponentWrapper
heading="Do you feel burnout more online or in person?"
bodyText="It seems like both in person and online terms can cause burnouts. Ultimately, it depends on the individual to decide which option works best for them."
align="left"
noBackground
>
<BarGraphVertical
data={H2ii}
{...barGraphProps(isMobile, pageWidth)}
lowerLabelDy="0"
/>
</ComponentWrapper>
<ComponentWrapper
heading="Have you ever been to therapy?"
bodyText="Although some people have seeked out therapy, this number is less than half of the number of people who reported struggling with mental health."
>
<div className={styles.graphContainer}>
<PieChart data={H3} {...pieChartProps(isMobile, pageWidth)} />
</div>
</ComponentWrapper>
<ComponentWrapper
heading="Have you considered going to therapy?"
bodyText="Around half of the people who responded this question reported that they have considered therapy. Again, this is almost double the number of respondents who have actually been to therapy. There might be many factors that influenced their decision, including money, time, lack of availability, and social stigma."
align="right"
noBackground
>
<div className={styles.graphContainer}>
<PieChart data={H3i} {...pieChartProps(isMobile, pageWidth)} />
</div>
</ComponentWrapper>
<ComponentWrapper
heading="If you have considered going to therapy, what factors prevented you from going?"
bodyText="Its almost common knowledge that seeking help from professionals can dramatically improve ones well-being. However, many avoidance factors prevent people from doing so. According to our respondents, some of the most common barriers for them include lack of information, money, stereotypes, and lack of time."
align="right"
>
<BarGraphVertical
data={H3ii}
{...barGraphProps(isMobile, pageWidth)}
widthAlternatingLabel={1000}
lowerLabelDy="60px"
/>
</ComponentWrapper>
<ComponentWrapper
heading="Have you ever been to counseling?"
bodyText="Out of the 101 people who has responded to this question, 24 reported yes. This number is very similar to the number of people who has been to therapy."
align="right"
noBackground
>
<div className={styles.graphContainer}>
<PieChart data={H4} {...pieChartProps(isMobile, pageWidth)} />
</div>
</ComponentWrapper>
<ComponentWrapper
heading="Have you considered going to counseling?"
bodyText="Interesting, not many of our respondents have considered going to conselling. This is the quit different from the number of people who have considered going to therapy. Perhaps counselling is a generally less well-known service or less referred to terminology than therapy."
align="left"
>
<div className={styles.graphContainer}>
<PieChart data={H4i} {...pieChartProps(isMobile, pageWidth)} />
</div>
</ComponentWrapper>
<ComponentWrapper
heading="If you have considered going to counseling, what factors prevented you from going?"
bodyText="The factors that limit people from going to counseling are similar to those that limit people from trying out therapy."
align="right"
noBackground
>
<BarGraphVertical
data={H4ii}
{...barGraphProps(isMobile, pageWidth)}
widthAlternatingLabel={680}
lowerLabelDy="50px"
/>
</ComponentWrapper>
<ComponentWrapper
heading="Have you used UW Health Services for your mental health?"
bodyText="The number of respondents who have used UW health Services for their mental health is similar to those who have seeked out therapy or counselling. UW Health Service provides accessible medical services to all students, mental health being one of them. To book an appointment with them, you can call 519-888-4096."
>
<div className={styles.graphContainer}>
<PieChart data={H5} {...pieChartProps(isMobile, pageWidth)} />
</div>
</ComponentWrapper>
<ComponentWrapper
heading="How was your experience with UW Health Services?"
bodyText="The general consensus for the services offered by UW Health Services is that they are mediocre and often pretty busy. Here are some of thefeedbacks that our respondents provided:"
noBackground
>
<div className={styles.quotationCarouselContainer}>
<QuotationCarousel
data={H5i}
circleDiameter={0}
width={barGraphWidth(isMobile, pageWidth)}
height={200}
/>
</div>
</ComponentWrapper>
<ComponentWrapper
heading="Overall, how would you rate your mental health over your entire undergraduate career?"
bodyText="Overall, the majority rated their mental health over their entire undergrad a 3 / 5 or 4 / 5."
align="right"
>
<BarGraphVertical
data={H7}
{...barGraphProps(isMobile, pageWidth)}
lowerLabelDy="0"
/>
</ComponentWrapper>
<ComponentWrapper
heading="How would you rate your current mental health?"
bodyText="Similarity, the majority rated their current mental health and 3 or 4 out of 5. However, more people indicate a mental health score of 4 or 5 out of 5, showing a slight increase in general mental health status after graduation."
noBackground
>
<BarGraphVertical
data={H6}
{...barGraphProps(isMobile, pageWidth)}
lowerLabelDy="0"
/>
</ComponentWrapper>
<ComponentWrapper
heading="How much do you value your mental health?"
bodyText="Thankfully, most people do highly value their mental health. As shown by the stats, most people gave a score on the higher side."
>
<BarGraphVertical
data={H8}
{...barGraphProps(isMobile, pageWidth)}
lowerLabelDy="0"
/>
</ComponentWrapper>
<ComponentWrapper
heading="What are some ways you have kept in touch with others during co-op and the pandemic?"
align="right"
noBackground
>
<div className={styles.quotationCarouselContainer}>
<QuotationCarousel
data={H9}
circleDiameter={0}
width={barGraphWidth(isMobile, pageWidth)}
height={200}
/>
</div>
</ComponentWrapper>
<ComponentWrapper
heading="Please give any general comments about mental health in university."
bodyText="With mental health being such a large concern in university, many of our respondents have commented on this topic. First, here are some of their quotes about how UWs environment affects students mental health. On the other hand, here are some quotes our respondents provided that may provide helpful suggestions for improving mental health."
align="right"
>
<div className={styles.quotationCarouselContainer}>
<QuotationCarousel
data={H9i}
circleDiameter={0}
width={barGraphWidth(isMobile, pageWidth)}
height={800}
/>
</div>
</ComponentWrapper>
<ComponentWrapper
heading="Do you feel like you have enough support for your mental health?"
bodyText="Most of our respondents indicated that they did feel like they have enough support of their mental health. This could come from freinds, family, faculty stuff members, or professionals."
noBackground
>
<div className={styles.graphContainer}>
<PieChart data={H10} {...pieChartProps(isMobile, pageWidth)} />
</div>
</ComponentWrapper>
<ComponentWrapper
heading="What do you do to help cope with your mental health issues?"
align="right"
>
<div className={styles.quotationCarouselContainer}>
<QuotationCarousel
data={H11}
circleDiameter={0}
width={barGraphWidth(isMobile, pageWidth)}
height={250}
/>
</div>
</ComponentWrapper>
<ComponentWrapper
heading="How does mental health affect different aspects of your life (e.g., relationships, studies, career)?"
align="center"
noBackground
>
<div className={styles.quotationCarouselContainer}>
<QuotationCarousel
data={H12}
circleDiameter={0}
width={barGraphWidth(isMobile, pageWidth)}
height={600}
/>
</div>
</ComponentWrapper>
<ComponentWrapper
heading="Do you feel 'senioritis' at this time?"
bodyText="Most students do feel “seniioritis” at the time of this survey."
align="right"
>
<div className={styles.graphContainer}>
<PieChart data={H13} {...pieChartProps(isMobile, pageWidth)} />
</div>
</ComponentWrapper>
<ComponentWrapper
heading="What do you think UW can do better to accommodate your mental health?"
align="center"
noBackground
>
<div className={styles.quotationCarouselContainer}>
<QuotationCarousel
data={H14}
circleDiameter={0}
width={barGraphWidth(isMobile, pageWidth)}
height={500}
/>
</div>
</ComponentWrapper>
<BottomNav
leftPage={pageRoutes.miscellaneous}
rightPage={pageRoutes.personal}
></BottomNav>
</div>
);
}

View File

@ -107,6 +107,7 @@ export default function Demographics() {
heading="In what areas have you grown that are unrelated to CS?"
bodyText="University is an unforgettable, life-changing, and learning experience that we only get once in a lifetime! Make the most out of it! :)"
align="center"
noBackground
>
<WordCloud
data={M7}

110
pages/personal.tsx Normal file
View File

@ -0,0 +1,110 @@
import { P2, P3, P4, P5, P6, P7, P8, P9 } from "data/personal";
import { pageRoutes } from "data/routes";
import React from "react";
import { BottomNav } from "@/components/BottomNav";
import { ComponentWrapper } from "@/components/ComponentWrapper";
import { Header } from "@/components/Header";
import { QuotationCarousel } from "@/components/QuotationCarousel";
import { SectionHeader } from "@/components/SectionHeader";
import styles from "./samplePage.module.css";
export default function Personal() {
return (
<div className={styles.page}>
<Header />
<SectionHeader title="Personal" subtitle="Life lessons from students" />
<ComponentWrapper
heading="What is your favourite memory from your time at UW?"
bodyText="Most students' favourite memory relates to their time spent with friends and significant ones! This goes to show how friends are an important factor to our happiness! :D"
align="right"
>
<div className={styles.quotationCarouselContainer}>
<QuotationCarousel data={P2} circleDiameter={0} height={300} />
</div>
</ComponentWrapper>
<ComponentWrapper
heading="What is one thing that you wish you could tell your first year self?"
bodyText="In summary, don't spend too much time worrying about your grades or coop during university. Develop new hobbies, be more open-minded, and talk to more people! There's a lot to experience in university that you don't want to miss or regret! Drink responsibly!"
noBackground
>
<div className={styles.quotationCarouselContainer}>
<QuotationCarousel data={P3} circleDiameter={0} height={300} />
</div>
</ComponentWrapper>
<ComponentWrapper
heading="What is your favourite inspirational quote/words to live by?"
align="right"
>
<div className={styles.quotationCarouselContainer}>
<QuotationCarousel data={P4} circleDiameter={0} height={300} />
</div>
</ComponentWrapper>
<ComponentWrapper
heading="What is the nicest thing a classmate did for you?"
bodyText="Any small act of kindness can make someone else's day and remain etched in their memory for a lifetime! We see that a lot of the respondants' classmates helped them with their assignments and exams. Some participants remember fondly when their classmate asked them if they were ok and struck a conversation with them!"
noBackground
>
<div className={styles.quotationCarouselContainer}>
<QuotationCarousel data={P5} circleDiameter={0} height={300} />
</div>
</ComponentWrapper>
<ComponentWrapper
heading="What is the best life hack/tip?"
bodyText="We have a range of life hacks around submitting assignments, coding shortcuts, living a healthy life (sleeping and eating well), etc. Take notes! ;)"
align="right"
>
<div className={styles.quotationCarouselContainer}>
<QuotationCarousel data={P6} circleDiameter={0} height={300} />
</div>
</ComponentWrapper>
<ComponentWrapper
heading="What is the best lesson you learned from your time at UW?"
bodyText="In short, always say 'yes' to opportunities as it can lead you to new experiences in life that you may enjoy! A lot of the small insignificant things you worry about won't matter at the end. Take care of yourself. Most importantly, enjoy your life is a message that most students agree with."
noBackground
>
<div className={styles.quotationCarouselContainer}>
<QuotationCarousel data={P7} circleDiameter={0} height={300} />
</div>
</ComponentWrapper>
<ComponentWrapper
heading="What is one aspect of your life that makes you the happiest?"
bodyText="Relationships whether friendships or romantic ones and hobbies are the aspects of CS 2022 students' life that make them the happiest!"
align="right"
>
<div className={styles.quotationCarouselContainer}>
<QuotationCarousel data={P8} circleDiameter={0} height={300} />
</div>
</ComponentWrapper>
<ComponentWrapper
heading="What advice would you give current/future CS students at UW?"
bodyText="Big recap: Socialize. Take care of yourself and your mental health. Do things beyond school and coop."
noBackground
align="center"
>
<div className={styles.quotationCarouselContainer}>
<QuotationCarousel
data={P9}
circleDiameter={0}
height={500}
width={800}
/>
</div>
</ComponentWrapper>
<BottomNav
leftPage={pageRoutes.mentalHealth}
rightPage={pageRoutes.contributors}
></BottomNav>
</div>
);
}

View File

@ -41,7 +41,12 @@ export default function Demographics() {
noBackground
>
<div className={styles.graphContainer}>
<PieChart data={P1} {...pieChartProps(isMobile, pageWidth)} />
<PieChart
data={P1}
{...pieChartProps(isMobile, pageWidth)}
labelTextSize={20}
minWidth={500}
/>
</div>
</ComponentWrapper>

View File

@ -17,6 +17,7 @@ import { ComponentWrapper } from "@/components/ComponentWrapper";
import { Header } from "@/components/Header";
import { LineGraph } from "@/components/LineGraph";
import { SectionHeader } from "@/components/SectionHeader";
import { SectionWrapper } from "@/components/SectionWrapper";
import { WordCloud } from "@/components/WordCloud";
import styles from "./samplePage.module.css";
@ -46,6 +47,7 @@ export default function SamplePage() {
return (
<div className={styles.page}>
<Header />
<SectionWrapper title="Transfer" />
<SectionHeader
title="Demographics"
subtitle="An insight into the demographics of UWs CS programs"
@ -65,6 +67,7 @@ export default function SamplePage() {
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."
align="center"
noBackground
>
<WordCloud
data={moreMockCategoricalData.map((word) => ({
@ -134,7 +137,11 @@ export default function SamplePage() {
height={defaultGraphHeight}
/>
</ComponentWrapper>
<ComponentWrapper heading="What program are you in?" align="center">
<ComponentWrapper
heading="What program are you in?"
align="center"
noBackground
>
<WordCloud
data={moreMockCategoricalData.map((word) => ({
text: word.key,
@ -181,7 +188,11 @@ export default function SamplePage() {
margin={defaultHorizontalBarGraphMargin}
/>
</ComponentWrapper>
<ComponentWrapper heading="What program are you in?" align="center">
<ComponentWrapper
heading="What program are you in?"
align="center"
noBackground
>
<BoxPlot
width={600}
height={400}