Skip to content
Snippets Groups Projects
Commit 6aeafe13 authored by danieldeng2's avatar danieldeng2
Browse files

Add logic to place events inside tracks

parent 411675c3
No related branches found
No related tags found
No related merge requests found
import React from "react"; import React from "react";
import styles from "./style.module.scss"; import styles from "./style.module.scss";
import { TimelineEvent } from "../.."; import { TimelineEvent, ModuleTracks } from "../..";
import TimelineEventCard from "../TimelineEventCard"; import TimelineEventCard from "../TimelineEventCard";
export interface EventGridProps { export interface EventGridProps {
numWeeks: number; numWeeks: number;
trackHeight: number; trackHeight: number;
events: TimelineEvent[]; modulesList: any[];
moduleTracks: ModuleTracks;
}
interface EventDisplay {
title: string;
id: number;
startColumn: number;
endColumn: number;
rowNumber: number;
} }
const EventGrid: React.FC<EventGridProps> = ({ const EventGrid: React.FC<EventGridProps> = ({
numWeeks, numWeeks,
trackHeight, trackHeight,
events, modulesList,
}) => { moduleTracks,
}) => {
//calculate event positions
let eventPositions: EventDisplay[] = [];
// Generates template for rows
let gridTemplateRows: string = "";
for (let i = 0; i < modulesList.length; i++) {
const code = modulesList[i].code;
const moduleTrack = moduleTracks[code];
moduleTrack.forEach(() => (gridTemplateRows += `${trackHeight}rem `));
gridTemplateRows +=
i === 0 || i === modulesList.length - 1 ? "0.3125rem " : "0.625rem ";
}
return ( return (
<div <div
className={styles.timelineCardGrid} className={styles.timelineCardGrid}
style={{ style={{
gridTemplateColumns: `repeat(${numWeeks}, 3rem 3rem 3rem 3rem 3rem 0.625rem)`, gridTemplateColumns: `repeat(${numWeeks}, 3rem 3rem 3rem 3rem 3rem 0.625rem)`,
gridTemplateRows: `${trackHeight}rem ${trackHeight}rem 0.3125rem repeat(${7}, ${trackHeight}rem ${trackHeight}rem 0.625rem) ${trackHeight}rem ${trackHeight}rem 0.3125rem`, gridTemplateRows: gridTemplateRows,
}} }}
> >
{events.map(({ title }, i) => ( {eventPositions.map(({ title, startColumn, endColumn, rowNumber }) => (
<TimelineEventCard <TimelineEventCard
title={title} title={title}
startColumn={i + 1} startColumn={startColumn}
endColumn={i + 8} endColumn={endColumn}
rowNumber={2 * i} rowNumber={rowNumber}
/> />
))} ))}
</div> </div>
......
...@@ -23,33 +23,30 @@ const ModuleRows: React.FC<ModuleRowsProps> = ({ ...@@ -23,33 +23,30 @@ const ModuleRows: React.FC<ModuleRowsProps> = ({
for (let i = 0; i < modulesList.length; i++) { for (let i = 0; i < modulesList.length; i++) {
const code = modulesList[i].code; const code = modulesList[i].code;
const tracks = moduleTracks[code]; const tracks = moduleTracks[code];
if (tracks) { moduleHeadings.push(
moduleHeadings.push( <ModuleHeading
<ModuleHeading key={code}
key={code} style={{ height: `${tracks.length * trackHeight}rem` }}
style={{ height: `${tracks.length * trackHeight}rem` }} moduleCode={code}
moduleCode={code} title={modulesList[i].title}
title={modulesList[i].title} />
/> );
const timelineBackgroundsClass = classNames(
i % 2 === 0
? styles.timelineBackgroundEven
: styles.timelineBackgroundOdd,
i === 0 ? styles.timelineBackgroundFirst : "",
i === modulesList.length - 1 ? styles.timelineBackgroundLast : ""
);
const offset = i === modulesList.length - 1 || i === 0 ? 0.625 / 2 : 0.625;
for (let j = 0; j < numWeeks; j++) {
timelineBackgrounds.push(
<div
key={code + j}
style={{ height: `${tracks.length * trackHeight + offset}rem` }}
className={timelineBackgroundsClass}
></div>
); );
const timelineBackgroundsClass = classNames(
i % 2 === 0
? styles.timelineBackgroundEven
: styles.timelineBackgroundOdd,
i === 0 ? styles.timelineBackgroundFirst : "",
i === modulesList.length - 1 ? styles.timelineBackgroundLast : ""
);
const offset =
i === modulesList.length - 1 || i === 0 ? 0.625 / 2 : 0.625;
for (let j = 0; j < numWeeks; j++) {
timelineBackgrounds.push(
<div
key={code + j}
style={{ height: `${tracks.length * trackHeight + offset}rem` }}
className={timelineBackgroundsClass}
></div>
);
}
} }
} }
......
...@@ -8,6 +8,7 @@ import ModuleRows from "./components/ModuleRows"; ...@@ -8,6 +8,7 @@ import ModuleRows from "./components/ModuleRows";
import DayIndicatorGrid from "./components/DayIndicatorGrid"; import DayIndicatorGrid from "./components/DayIndicatorGrid";
import EventGrid from "./components/EventGrid"; import EventGrid from "./components/EventGrid";
import { eventsData } from "./eventsData"; import { eventsData } from "./eventsData";
import LoadingScreen from "components/molecules/LoadingScreen";
interface TimelineProps { interface TimelineProps {
initSideBar: () => void; initSideBar: () => void;
...@@ -15,11 +16,11 @@ interface TimelineProps { ...@@ -15,11 +16,11 @@ interface TimelineProps {
} }
export interface TimelineEvent { export interface TimelineEvent {
title: string; title: string;
id: number; id: number;
moduleCode: string; moduleCode: string;
startDate: Date; startDate: Date;
endDate: Date; endDate: Date;
} }
export type ModuleTracks = { export type ModuleTracks = {
...@@ -28,12 +29,13 @@ export type ModuleTracks = { ...@@ -28,12 +29,13 @@ export type ModuleTracks = {
interface TimelineState { interface TimelineState {
moduleTracks: ModuleTracks; moduleTracks: ModuleTracks;
isLoaded: boolean;
} }
class Timeline extends React.Component<TimelineProps, TimelineState> { class Timeline extends React.Component<TimelineProps, TimelineState> {
constructor(props: TimelineProps) { constructor(props: TimelineProps) {
super(props); super(props);
this.state = { moduleTracks: {} }; this.state = { moduleTracks: {}, isLoaded: false };
} }
componentDidMount() { componentDidMount() {
...@@ -42,7 +44,28 @@ class Timeline extends React.Component<TimelineProps, TimelineState> { ...@@ -42,7 +44,28 @@ class Timeline extends React.Component<TimelineProps, TimelineState> {
modulesList.forEach(({ code }) => { modulesList.forEach(({ code }) => {
moduleTracks[code] = [[], []]; moduleTracks[code] = [[], []];
}); });
this.setState({ moduleTracks: moduleTracks });
let timelineEvents = eventsData;
for (let i = 0; i < timelineEvents.length; i++) {
const event = timelineEvents[i];
let tracks: TimelineEvent[][] = moduleTracks[event.moduleCode];
let isPlaced = false;
for (const track of tracks) {
if (track.every((te) => !eventsOverlaps(te, event))) {
isPlaced = true;
track.push(event);
break;
}
}
if (!isPlaced){
tracks.push([event]);
}
}
this.setState({
moduleTracks: moduleTracks,
isLoaded: true,
});
} }
componentWillUnmount() { componentWillUnmount() {
...@@ -60,7 +83,9 @@ class Timeline extends React.Component<TimelineProps, TimelineState> { ...@@ -60,7 +83,9 @@ class Timeline extends React.Component<TimelineProps, TimelineState> {
const activeDay = new Date("2020-10-12"); const activeDay = new Date("2020-10-12");
const numWeeks = 11; const numWeeks = 11;
const trackHeight = 4; const trackHeight = 4;
if (!this.state.isLoaded) {
return <LoadingScreen successful={<></>} />;
}
return ( return (
<div className={styles.timelineContainer}> <div className={styles.timelineContainer}>
<MyBreadcrumbs /> <MyBreadcrumbs />
...@@ -79,16 +104,25 @@ class Timeline extends React.Component<TimelineProps, TimelineState> { ...@@ -79,16 +104,25 @@ class Timeline extends React.Component<TimelineProps, TimelineState> {
/> />
<DayIndicatorGrid <DayIndicatorGrid
numWeeks={numWeeks} numWeeks={numWeeks}
activeDay={activeDay} activeDay={activeDay}
activeColumn={this.dateToColumn(activeDay, termStart)} activeColumn={this.dateToColumn(activeDay, termStart)}
/> />
<EventGrid numWeeks={numWeeks} trackHeight={trackHeight} events={eventsData}/> <EventGrid
numWeeks={numWeeks}
trackHeight={trackHeight}
modulesList={modulesList}
moduleTracks={this.state.moduleTracks}
/>
</div> </div>
</div> </div>
); );
} }
} }
function eventsOverlaps(e1: TimelineEvent, e2: TimelineEvent) {
return e1.startDate <= e2.endDate && e1.endDate >= e2.startDate;
}
export default Timeline; export default Timeline;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment