-
Joakim Bergström authored
Leaflet now uses a dual band image by default. Fixed the upper right Leaflet control. Added a function to add multiple data layers to the map.
Joakim Bergström authoredLeaflet now uses a dual band image by default. Fixed the upper right Leaflet control. Added a function to add multiple data layers to the map.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
SideDrawer.js 12.53 KiB
import React from "react";
import ToggleButton from "./ToggleButton";
import CitySelector from "./CitySelector";
import SwitchButtons from "./SwitchButtons";
import LinesStopsBtn from "./LinesStopsBtn";
import Delays from "./Delays";
import HistoryBox from "../HistoryBox/HistoryBox";
import StopDisplay from "../StopDisplay/StopDisplay.js";
import PropTypes from "prop-types";
import { withStyles } from "@material-ui/core/styles";
import Drawer from "@material-ui/core/Drawer";
import { IconButton} from "@material-ui/core";
import Divider from "@material-ui/core/Divider";
import ChevronLeftIcon from "@material-ui/icons/ChevronLeft";
import Toolbar from "@material-ui/core/Toolbar";
import LinkLines from "../../Data/LinkLines";
import LinkStops from "../../Data/LinkStops";
import NorrLines from "../../Data/NorrLines";
import NorrStops from "../../Data/NorrStops";
import styles from "./SideDrawerCSS.js";
// This is what gets returned from back-end after getProbOfLine(), only used as an example
//{smallestP: "10%"},
const rydsCentrumLine1 = [
{ expectedTime: "07:05", arrivalP: "80%" },
{ expectedTime: "07:20", arrivalP: "10%" },
{ expectedTime: "07:35", arrivalP: "75%" },
{ expectedTime: "07:50", arrivalP: "35%" }
];
//rydsCentrumLine1[0].smallestP
const rydsCentrum = [
{ lineName: "1", smallestP: "10%", lineDetails: rydsCentrumLine1 },
{ lineName: "4", smallestP: "20%", lineDetails: rydsCentrumLine1 },
{ lineName: "2", smallestP: "35%", lineDetails: rydsCentrumLine1 },
{ lineName: "3", smallestP: "56%", lineDetails: rydsCentrumLine1 },
{ lineName: "3", smallestP: "56%", lineDetails: rydsCentrumLine1 },
{ lineName: "3", smallestP: "56%", lineDetails: rydsCentrumLine1 },
{ lineName: "3", smallestP: "56%", lineDetails: rydsCentrumLine1 },
{ lineName: "3", smallestP: "56%", lineDetails: rydsCentrumLine1 },
{ lineName: "3", smallestP: "56%", lineDetails: rydsCentrumLine1 },
{ lineName: "3", smallestP: "56%", lineDetails: rydsCentrumLine1 },
{ lineName: "3", smallestP: "56%", lineDetails: rydsCentrumLine1 },
{ lineName: "3", smallestP: "56%", lineDetails: rydsCentrumLine1 },
{ lineName: "3", smallestP: "56%", lineDetails: rydsCentrumLine1 },
{ lineName: "3", smallestP: "56%", lineDetails: rydsCentrumLine1 },
{ lineName: "3", smallestP: "56%", lineDetails: rydsCentrumLine1 }
];
class sideDrawer extends React.PureComponent {
constructor(props) {
super(props);
this.removeLine = this.removeLine.bind(this);
this.updateStopToDisplay = this.updateStopToDisplay.bind(this);
this.state = {
menuOn: false,
trafficFlow: false,
lines: false,
stop: false,
linkoping: false,
norrkoping: false,
city: "",
linesList: [],
stopsList: [],
savedLines: [],
showHistory: false,
stopToDisplay: "",
citySelector: false,
delays: [],
delaysFilter: {day: "", time: [7,8], percent: 50},
};
}
/*
* Toggles state of the side bar
* @param {string} side Name of the selected variable
* @param {bool} open State to be updated
*/
toggleDrawer = (side, open) => () => {
this.setState({
[side]: open
});
};
/*
* Calls removeLine() or addLine() based on the event on the checkBox
* @param {event} event Triggered event with its props
* @param {num} id Selected line number
*/
checkBoxHandler = (event) => {
let line = event.target.id
if (this.state.savedLines.includes(line)) {
this.removeLine(line)
} else {
this.addLine(line)
}
};
/*
* Updates savedLines list by adding the selected (from sideDrawer) line
* @param {num} line selected line to be added
*/
addLine = (line) => {
this.setState({
savedLines: [...this.state.savedLines, line],
showHistory: true
});
};
/*
* Updates savedLines by removing the selected (from sideDrawe or historyBox) line
* @param {num} line Selected line to be removed
*/
removeLine = (line) => {
var sh = true;
var savedLinesCopy = [...this.state.savedLines];
var index = savedLinesCopy.indexOf(line);
if (index > -1) {
savedLinesCopy.splice(index, 1);
}
if (savedLinesCopy.length == 0) {
sh = false;
}
this.setState({
savedLines: savedLinesCopy,
showHistory: sh
});
}
/*
* @param { } stop
*/
updateStopToDisplay(stop) {
this.setState({
stopToDisplay: stop
});
}
/*
*
*/
showHistory = () => {
this.setState({
showHistory: true
});
};
/*
* Updates city state which contains the name of the selected city
* Updates lines and stops lists according selected city
* @param {event} event The triggered event with its props
* @param {string} value Name of the selected city
*/
cityChoiceHandler = event => {
if (event.target.value !== "") {
this.setState({
city: event.target.value,
linesList: this.updateLinesList(event.target.value),
stopsList: this.updateStopsList(event.target.value)
});
} else {
this.setState({
city: event.target.value
});
}
};
/*
* Returns the state of the switched button
* @param {string} name State name of the switched button
* @return {bool} State of the switched button
*/
getSwitchedBtn = name => {
switch (name) {
case "trafficFlow":
return this.state.trafficFlow;
default:
return;
}
};
/*
* Updates state of the switched button
* @param {string} name State name of the switched button
* @param {event} event The triggered event with its props
* @param {bool} checked Button new state
*/
toggleSwitchedBtn = name => event => {
this.setState({
[name]: event.target.checked
});
};
/*
Update selected item.
Item chosen from lines or stops list
*/
updateSelectedItem = event => {
this.setState({
selectedItem: event.target.value
});
};
/*
Temporarily used as Linköping/Norrköping's
bus lines data.
Updates the lines list based on the city selection.
*/
updateLinesList = city => {
switch (city) {
case "Linköping":
return LinkLines;
case "Norrköping":
return NorrLines;
default:
return;
}
};
/*
Temporarily used as Linköping/Norrköping's
bus stops data.
Updates the stops list based on the city selection.
*/
updateStopsList = city => {
switch (city) {
case "Linköping":
return LinkStops;
case "Norrköping":
return NorrStops;
default:
return;
}
};
/*
* Updates the state of the given delays filter variable
* @param {string} filter Name of the variable to be updated
* @param {string, array, num} input New value of the selected filter var
*/
delaysFilterHandler = (filter, input) => {
switch(filter) {
case "day":
this.setState(prevState => ({
delaysFilter: {
...prevState.delaysFilter,
day: input
}
}));
break;
case "time":
this.setState(prevState => ({
delaysFilter: {
...prevState.delaysFilter,
time: input
}
}));
break;
case "percent":
this.setState(prevState => ({
delaysFilter: {
...prevState.delaysFilter,
percent: input
}
}));
break;
}
}
/*
* Updates the start value of time interval on delays filter
* according to selected tim value
* @param {num} input Selected start time value
*/
updateStartInterval = input => {
let value = parseInt(input, 10);
let end = this.state.delaysFilter.time[1]
if (value > 23) {
return [1, end];
} else if (value < 1) {
return [23, end];
} else if (end <= value) {
return [value, value+1];
} else {
return [value, end];
}
};
/*
* Updates the end value of time interval on delays filter
* according to selected time value
* @param {num} input Selected end time value
*/
updateEndInterval = input => {
let value = parseInt(input, 10)
let start = this.state.delaysFilter.time[0]
if (value <= start) {
return [start, start+1];
} else if (value > 24) {
return [start, 24];
} else if (value < 1) {
return [start, 1];
} else {
return [start, value]
}
};
/*
* Handles the triggered time point (start or end)
* Calls respective function to update selected time point
* Calls respective function to update selected time point state/value
* @param {event} event Triggered event with its props
* @param {string} id Name of the triggered time point
*/
intervalHandler = event => {
let interval = []
switch (event.target.id) {
case "start":
interval = this.updateStartInterval(event.target.value)
this.delaysFilterHandler("time", interval)
break;
case "end":
interval = this.updateEndInterval(event.target.value)
this.delaysFilterHandler("time", interval)
break;
default:
return;
}
};
/*
* Calls respective function to update percent on delays filter
* @param {event} event Triggered event with its props
* @param {num} value New selected percent on delays filter
*/
filterSliderHandler = (event, value) => {
let percent = Math.round(value);
this.delaysFilterHandler("percent", percent)
};
/* This is sent to backend which returns a complete list which is
* in the form of the "rydsCentrum" constant
*/
getProbOfStop = (stop, linte, day, startTime, endTime) => {
return rydsCentrum;
};
/*This is sent to back-end which returns a tuple? of the the different
* times a bus is scheduled to arrive and
* their respective percentage of arriving at that time. Alternativly we
* can get this whole list only once but I think this is a performance/preference question
*/
getProbOfLine = (stop, line, day, startTime, endTime) => {
return rydsCentrumLine1;
};
render() {
const { classes } = this.props;
const sideBar = (
<div className={classes.menu}>
<div className={classes.arrowContainer}>
<IconButton onClick={this.toggleDrawer("menuOn", !this.state.menuOn)}>
<ChevronLeftIcon className={classes.arrow} />
</IconButton>
</div>
<Divider />
<CitySelector
city={this.state.city}
cityChoiceHandler={this.cityChoiceHandler}
/>
<SwitchButtons
switchedBtn={this.getSwitchedBtn}
toggleBtn={this.toggleSwitchedBtn}
/>
{this.state.city !== "" ? (
<div className={classes.expansionContainer}>
<LinesStopsBtn
linesList={this.state.linesList}
stopsList={this.state.stopsList}
ckeckBoxHandler={this.checkBoxHandler}
savedLines={this.state.savedLines}
addLine={this.addLine}
removeLine={this.removeLine}
updateStopToDisplay={this.updateStopToDisplay}
/>
<Delays
delaysFilterHandler={this.delaysFilterHandler}
delaysFilter={this.state.delaysFilter}
intervalHandler={this.intervalHandler}
intervalValue={this.getIntervalValue}
sliderHandler={this.filterSliderHandler}
/>
</div>
) : null}
</div>
);
return (
<div>
<Toolbar style={{position: 'absolute'}}>
<ToggleButton toggleDrawer={this.toggleDrawer} />
</Toolbar>
<Drawer
classes={{
paper: classes.sideDrawer
}}
open={this.state.menuOn}
onClose={this.toggleDrawer("menuOn", false)}
>
{sideBar}
</Drawer>
{this.state.showHistory ? (
<HistoryBox
removeLine={this.removeLine}
savedLines={this.state.savedLines}
/>
) : null}
{/* Get the lines that connect to a specific stop
and their percentages of arriving on time*/}
{this.state.stopToDisplay != "" ? (
<StopDisplay
stop={this.state.stopToDisplay}
closeDisplay={this.updateStopToDisplay}
linesList={this.state.linesList}
connectedLines={
rydsCentrum /*this.getProbOfStop(this.state.stopToDisplay)*/
}
/>
) : null}
</div>
);
}
}
sideDrawer.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(sideDrawer);