Skip to content

Commit

Permalink
Split Map.jsx into ControlPanel.jsx sidebar (#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
akgupta89 authored Dec 20, 2018
1 parent aa674e2 commit 0dc2e5a
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 98 deletions.
6 changes: 1 addition & 5 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,8 @@ class App extends Component {
render={({ error, props }) => {
if (error) {
return <div>{error.message}</div>;
} else if (props) {
return (
<Map trynState={props} />
);
}
return <Map />;
return <Map trynState={props || null} />;
}}
/>
);
Expand Down
111 changes: 111 additions & 0 deletions src/ControlPanel.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import React, { Component } from 'react';
import { DateTimePicker } from 'react-widgets';
import Toggle from 'react-toggle';
import propTypes from 'prop-types';
import Checkbox from './Checkbox';
import muniRoutesGeoJson from './res/muniRoutes.geo.json';
// import Map from './Map';

const notAlpha = /[^a-zA-Z]/g;

/*
Sort by putting letters before numbers and treat number strings as integers.
Calling Array.prototype.sort() without a compare function sorts elements as
strings by Unicode code point order, e.g. [2, 12, 13, 9, 1, 27].sort() returns
[1, 12, 13, 2, 27, 9]
*/
function sortAlphaNumeric(a, b) {
const aRoute = a.properties.name;
const bRoute = b.properties.name;
const aInteger = parseInt(aRoute, 10);
const bInteger = parseInt(bRoute, 10);
const aAlpha = aRoute.replace(notAlpha, '');
const bAlpha = bRoute.replace(notAlpha, '');

// special case for K/T and K-OWL
if (aRoute === 'K/T' && bRoute === 'K-OWL') return -1;
if (aRoute === 'K-OWL' && bRoute === 'K/T') return 1;

if (Number.isNaN(aInteger) && Number.isNaN(bInteger)) {
return aAlpha < bAlpha ? -1 : 1;
} else if (Number.isNaN(aInteger)) {
return -1;
} else if (Number.isNaN(bInteger)) {
return 1;
} else if (aInteger === bInteger) {
return aAlpha < bAlpha ? -1 : 1;
}
return aInteger - bInteger;
}


// make a copy of routes and sort
const sortedRoutes = muniRoutesGeoJson.features.slice(0).sort(sortAlphaNumeric);

class ControlPanel extends Component {
constructor() {
super();
this.state = {
currentStateTime: new Date(Date.now()),
};
}

setNewStateTime(newStateTime) {
this.setState({ currentStateTime: newStateTime });
this.props.relay.refetch(
{
startTime: Number(newStateTime) - 15000,
endTime: Number(newStateTime),
agency: 'muni',
},
null,
(err) => {
if (err) {
console.warn(err);
}
},
{ force: true },
);
}

render() {
return (
<div className="control-panel">
<div className="routes-header">
<h3>Time</h3>
<DateTimePicker
value={this.state.currentStateTime}
onChange={newTime => this.setNewStateTime(newTime)}
/>
</div>
<div className="routes-header stops-toggle">
<h3>Stops</h3>
<Toggle
defaultChecked={this.state.showStops}
onChange={() => this.setState({ showStops: !this.state.showStops })}
/>
</div>
<div className="routes-header">
<h3>Routes</h3>
</div>
<ul className="route-checkboxes">
{sortedRoutes.map(route => (
<Checkbox
route={route}
label={route.properties.name}
handleCheckboxChange={checkedRoute => this.props.filter(checkedRoute)}
key={route.id}
/>
))}
</ul>
</div>
);
}
}

ControlPanel.propTypes = {
relay: propTypes.element.isRequired,
filter: propTypes.element.isRequired,
};

export default ControlPanel;
96 changes: 3 additions & 93 deletions src/Map.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import {
createRefetchContainer,
} from 'react-relay';
import propTypes from 'prop-types';
import { DateTimePicker } from 'react-widgets';
import Toggle from 'react-toggle';
import * as turf from '@turf/turf';
import { MAP_STYLE, MAPBOX_ACCESS_TOKEN } from './config.json';
import {
Expand All @@ -16,43 +14,7 @@ import {
getVehicleMarkersLayer,
getSubRoutesLayer,
} from './Route';
import muniRoutesGeoJson from './res/muniRoutes.geo.json';
import Checkbox from './Checkbox';

const notAlpha = /[^a-zA-Z]/g;

/*
Sort by putting letters before numbers and treat number strings as integers.
Calling Array.prototype.sort() without a compare function sorts elements as
strings by Unicode code point order, e.g. [2, 12, 13, 9, 1, 27].sort() returns
[1, 12, 13, 2, 27, 9]
*/
function sortAlphaNumeric(a, b) {
const aRoute = a.properties.name;
const bRoute = b.properties.name;
const aInteger = parseInt(aRoute, 10);
const bInteger = parseInt(bRoute, 10);
const aAlpha = aRoute.replace(notAlpha, '');
const bAlpha = bRoute.replace(notAlpha, '');

// special case for K/T and K-OWL
if (aRoute === 'K/T' && bRoute === 'K-OWL') return -1;
if (aRoute === 'K-OWL' && bRoute === 'K/T') return 1;

if (Number.isNaN(aInteger) && Number.isNaN(bInteger)) {
return aAlpha < bAlpha ? -1 : 1;
} else if (Number.isNaN(aInteger)) {
return -1;
} else if (Number.isNaN(bInteger)) {
return 1;
} else if (aInteger === bInteger) {
return aAlpha < bAlpha ? -1 : 1;
}
return aInteger - bInteger;
}

// make a copy of routes and sort
const sortedRoutes = muniRoutesGeoJson.features.slice(0).sort(sortAlphaNumeric);
import ControlPanel from './ControlPanel';

/*
* Stop class used to handle info about selected stops
Expand Down Expand Up @@ -84,6 +46,7 @@ class Stop {
class Map extends Component {
constructor() {
super();
this.filterRoutes = this.filterRoutes.bind(this);
this.state = {
// Viewport settings that is shared between mapbox and deck.gl
viewport: {
Expand All @@ -99,7 +62,6 @@ class Map extends Component {
coordinates: { lon: 0, lat: 0 },
info: { vid: '', heading: 0 },
},
currentStateTime: new Date(Date.now()),
showStops: true,
selectedStops: [],
subroute: null,
Expand All @@ -116,23 +78,6 @@ class Map extends Component {
window.removeEventListener('resize', this.updateDimensions.bind(this));
}

setNewStateTime(newStateTime) {
this.setState({ currentStateTime: newStateTime });
this.props.relay.refetch(
{
startTime: Number(newStateTime) - 15000,
endTime: Number(newStateTime),
agency: 'muni',
},
null,
(err) => {
if (err) {
console.warn(err);
}
},
{ force: true },
);
}
/**
* given the two selected stop sids, returns a line segment
* between them
Expand Down Expand Up @@ -222,40 +167,6 @@ class Map extends Component {
this.setState({ geojson: newGeojson });
}

renderControlPanel() {
return (
<div className="control-panel">
<div className="routes-header">
<h3>Time</h3>
<DateTimePicker
value={this.state.currentStateTime}
onChange={newTime => this.setNewStateTime(newTime)}
/>
</div>
<div className="routes-header stops-toggle">
<h3>Stops</h3>
<Toggle
defaultChecked={this.state.showStops}
onChange={() => this.setState({ showStops: !this.state.showStops })}
/>
</div>
<div className="routes-header">
<h3>Routes</h3>
</div>
<ul className="route-checkboxes">
{sortedRoutes.map(route => (
<Checkbox
route={route}
label={route.properties.name}
handleCheckboxChange={checkedRoute => this.filterRoutes(checkedRoute)}
key={route.id}
/>
))}
</ul>
</div>
);
}

renderMap() {
const onViewportChange = viewport => this.setState({ viewport });
const { trynState } = this.props.trynState || {};
Expand Down Expand Up @@ -321,7 +232,7 @@ class Map extends Component {
{this.renderMap()}
</div>
<div className="col-sm-3 col-md-2 hidden-xs-down bg-faded sidebar">
{this.renderControlPanel()}
<ControlPanel filter={this.filterRoutes} />
</div>
</div>
</div>
Expand All @@ -334,7 +245,6 @@ Map.propTypes = {
propTypes.string,
propTypes.arrayOf(propTypes.object),
).isRequired,
relay: propTypes.element.isRequired,
};

export default createRefetchContainer(
Expand Down

0 comments on commit 0dc2e5a

Please sign in to comment.