Merge branch 'main' into j285he-sections

This commit is contained in:
Jared He 2022-09-09 17:29:04 -04:00
commit 7c9cb7b8c8
7 changed files with 279 additions and 4 deletions

View File

@ -0,0 +1,7 @@
.textbox {
width: 80%;
padding: calc(80rem / 16);
background-color: var(--secondary-background);
border-radius: calc(20rem / 16);
margin: 0 auto;
}

View File

@ -0,0 +1,11 @@
import React, { ReactNode } from "react";
import styles from "./CenterWrapper.module.css";
export interface TextboxProps {
children: ReactNode;
}
export function CenterWrapper({ children }: TextboxProps) {
return <section className={styles.textbox}>{children}</section>;
}

View File

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

180
components/PieChart.tsx Normal file
View File

@ -0,0 +1,180 @@
import { Group } from "@visx/group";
import Pie, { ProvidedProps } from "@visx/shape/lib/shapes/Pie";
import { Text } from "@visx/text";
import React from "react";
import styles from "./PieChart.module.css";
interface PieChartProps {
data: PieChartData[];
/** Width of the entire graph, including labels, in pixels. */
width: number;
/** Width of the outer ring of labels, in pixels. Label text may be cut off if specified value is too small. */
labelWidth: number;
/** Distance between pie slices, in pixels. */
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;
/** Accessor function to get value to display as label text from datum. */
getLabelDisplayValueFromDatum?: (datum: PieChartData) => string;
className?: string;
}
interface PieChartData {
category: string;
value: number;
}
export function PieChart({
data,
width,
labelWidth,
padRadius = width * 0.35,
innerRadius = width * 0.015,
pieTextSize = 40,
pieTextXOffset = 0,
pieTextYOffset = 10,
getPieDisplayValueFromDatum = (datum: PieChartData) => `${datum.value}%`,
labelTextSize = 40,
labelTextXOffset = 0,
labelTextYOffset = 0,
getLabelDisplayValueFromDatum = (datum: PieChartData) => `${datum.category}`,
className,
}: PieChartProps) {
const pieWidth = width * 0.5 - labelWidth;
return (
<svg className={className} width={width} height={width}>
<Group top={width * 0.5} left={width * 0.5}>
<Pie
data={data}
pieValue={(d: PieChartData) => d.value}
cornerRadius={10}
padAngle={0.075}
padRadius={padRadius}
innerRadius={innerRadius}
outerRadius={pieWidth}
>
{(pie) => (
<PieSlice
{...pie}
pieTextSize={pieTextSize}
pieTextXOffset={pieTextXOffset}
pieTextYOffset={pieTextYOffset}
getPieDisplayValueFromDatum={getPieDisplayValueFromDatum}
/>
)}
</Pie>
<Pie
data={data}
pieValue={(d: PieChartData) => d.value}
innerRadius={pieWidth}
outerRadius={width * 0.5}
>
{(pie) => (
<PieSliceLabel
{...pie}
labelTextSize={labelTextSize}
labelTextXOffset={labelTextXOffset}
labelTextYOffset={labelTextYOffset}
getLabelDisplayValueFromDatum={getLabelDisplayValueFromDatum}
/>
)}
</Pie>
</Group>
</svg>
);
}
type PieSliceProps<PieChartData> = ProvidedProps<PieChartData> & {
pieTextSize: number;
pieTextXOffset: number;
pieTextYOffset: number;
getPieDisplayValueFromDatum: (datum: PieChartData) => string;
};
export function PieSlice({
path,
arcs,
pieTextSize,
pieTextXOffset,
pieTextYOffset,
getPieDisplayValueFromDatum,
}: PieSliceProps<PieChartData>) {
return (
<>
{arcs.map((arc) => {
const [centroidX, centroidY] = path.centroid(arc);
const pathArc = path(arc) as string;
return (
<Group className={styles.group} key={`arc-${arc.data.category}`}>
<path className={styles.piePath} d={pathArc} />
<Text
className={styles.pieText}
x={centroidX + pieTextXOffset}
y={centroidY + pieTextYOffset}
textAnchor="middle"
fontSize={pieTextSize}
>
{`${getPieDisplayValueFromDatum(arc.data)}`}
</Text>
</Group>
);
})}
</>
);
}
type PieSliceLabelProps<PieChartData> = ProvidedProps<PieChartData> & {
labelTextSize: number;
labelTextXOffset: number;
labelTextYOffset: number;
getLabelDisplayValueFromDatum: (datum: PieChartData) => string;
};
export function PieSliceLabel({
path,
arcs,
labelTextSize,
labelTextXOffset,
labelTextYOffset,
getLabelDisplayValueFromDatum,
}: PieSliceLabelProps<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.labelPath} d={pathArc} />
<Text
className={styles.labelText}
x={centroidX + labelTextXOffset}
y={centroidY + labelTextYOffset}
textAnchor="middle"
fontSize={labelTextSize}
>
{`${getLabelDisplayValueFromDatum(arc.data)}`}
</Text>
</Group>
);
})}
</>
);
}

View File

@ -36,6 +36,21 @@ export const mockCategoricalData = [
}, },
]; ];
export const mockPieData = [
{
category: "Nightingale",
value: 42,
},
{
category: "Quail",
value: 48,
},
{
category: "Cuckoo",
value: 10,
},
];
export const moreMockCategoricalData = [ export const moreMockCategoricalData = [
{ key: "Python", value: 29.53 }, { key: "Python", value: 29.53 },
{ key: "Java", value: 17.06 }, { key: "Java", value: 17.06 },

1
package-lock.json generated
View File

@ -5,7 +5,6 @@
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "cs-2022-class-profile",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@visx/axis": "^2.10.0", "@visx/axis": "^2.10.0",

View File

@ -6,13 +6,16 @@ import {
mockBoxPlotData, mockBoxPlotData,
mockQuoteData, mockQuoteData,
mockQuoteDataLong, mockQuoteDataLong,
mockPieData,
} from "data/mocks"; } from "data/mocks";
import { sectionsData } from "data/routes"; import { sectionsData } from "data/routes";
import React from "react"; import React from "react";
import { PieChart } from "@/components/PieChart";
import { QuotationCarousel } from "@/components/QuotationCarousel"; import { QuotationCarousel } from "@/components/QuotationCarousel";
import { Sections } from "@/components/Sections"; import { Sections } from "@/components/Sections";
import { CenterWrapper } from "../components/CenterWrapper";
import { ColorPalette } from "../components/ColorPalette"; import { ColorPalette } from "../components/ColorPalette";
import { WordCloud } from "../components/WordCloud"; import { WordCloud } from "../components/WordCloud";
@ -23,8 +26,13 @@ export default function Home() {
<div className={styles.page}> <div className={styles.page}>
<h1>Playground</h1> <h1>Playground</h1>
<p>Show off your components here!</p> <p>Show off your components here!</p>
<h2>
<code>{"<PieChart />"}</code>
</h2>
<div style={{ padding: "30px" }}>
<PieChart data={mockPieData} width={800} labelWidth={215} />
</div>
<ColorPalette /> <ColorPalette />
<h2> <h2>
<code>{"<BarGraphHorizontal />"}</code> <code>{"<BarGraphHorizontal />"}</code>
</h2> </h2>
@ -40,7 +48,6 @@ export default function Home() {
right: 20, right: 20,
}} }}
/> />
<h2> <h2>
<code>{"<BarGraphVertical />"}</code> <code>{"<BarGraphVertical />"}</code>
</h2> </h2>
@ -60,7 +67,6 @@ export default function Home() {
right: 20, right: 20,
}} }}
/> />
<h2> <h2>
<code>{"<WordCloud />"}</code> <code>{"<WordCloud />"}</code>
</h2> </h2>
@ -70,6 +76,37 @@ export default function Home() {
value: word.value, value: word.value,
}))} }))}
/> />
<h2>
<code>{"<Textbox />"}</code>
</h2>
<CenterWrapper>
<h1>Preface</h1>
<p>
The CS Class Profile consists of data relevant to CS, CFM, and CS/BBA
students. These were combined with the knowledge that students in
these programs tend to have similar experiences, as many of the same
CS required courses are shared. In the standard co-op offering, CS and
CFM take 4 years and 2 semesters to complete, while CS/BBA can take up
to a full 5 years.
</p>
<p>
Computer Science (and the others) is known to be a very prestigious
program, and is very well known in Canada as well as across the world.
For prospective students or anyone who is interested in learning more
about what the students are like, this CS Class Profile will attempt
to answer some of your questions, and you may even learn a thing or
two you didnt expect!
</p>
<p>
The survey questions were approved by the Institutional Analysis &
Planning, where all University of Waterloo stakeholders that are
interested in conducting a non-academic research survey involving a
large portion of the UWaterloo population are reviewed and approved.
The entirety of the survey creation and data processing was done by
the UW Computer Science Club, so please check us out if you enjoy what
you see!
</p>
</CenterWrapper>
<h2> <h2>
<code>{"<Sections />"}</code> <code>{"<Sections />"}</code>