Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,45 @@
Add a readme for your dashboard here. Include content overview, data citations, and any relevant technical details.

# SEPTA Bus Rerouting Visualizer
In August of 2026, SEPTA did a significant [system rerouting of their bus routes](https://wwww.septa.org/initiatives/bus/).
Now that the rerouting has been implemented, it can be difficult to see how individual routes changed. SEPTA's trip planners and other navigation tools generally show current service, not a side-by-side comparison with the previous routes. Riders who rely on familiarity with the city rather than navigation apps may have difficulty finding where a changed route or stop moved.

This tool visualizes previous and current routes side-by-side, helping riders compare the changes and serving as a snapshot of the former routes.

After more data is collected, this map can be overlapped with ridership data for each stop (which SEPTA does currently collect). This can provide an overview for SEPTA transportation planners to see if moving the stops have led to a change in ridership.

* **The users I want to empower are transit riders and eventually transit planners.**
* **The specific decisions those users need to make are where to wait for the bus and what bus to take to get to a part of Philadelphia after the SEPTA Phase I bus rerouting.**
* **The data required to inform these decisions include SEPTA bus stop and bus route data.**

## DATA
This project used datasets directly from SEPTA's open data site.

- [SEPTA Summer 2026 Bus Stops (Before August 2026 Phase I Changes)](https://data-septa.opendata.arcgis.com/datasets/SEPTA::summer-2026-stop-summary-bus/about)

- [SEPTA Fall 2026 Bus Stops (After Phase I Changes)](https://data-septa.opendata.arcgis.com/datasets/SEPTA::transit-stops-fall-2026/about)


## DESIGN DETAILS

Part of the SEPTA Phase I Changes also included updated signage. The logo on the upper left hand corner is inspired by the signage SEPTA uses for directions and informational signs that aren't about service.

<img src="images/logo.png" alt="Dashboard Logo" width="150">

According to the SEPTA site, "arrows and symbols are always on a black background for the highest contrast."

![SEPTA wayfinding and information signage](images/septa_signage.png)

The color scheme used is reminiscent of the SEPTA logo.

The JS and CSS code were both linted and site is a11y verified.

## LIMITATIONS
- SEPTA datasets are not created equal. Even between the bus stop datasets for Summer 2026 and Fall 2026, the format and columns are different. Datasets with connect routes didn't have the individual bus stop data. This made it a challenge to connect each of the bus stops.
- Ridership data for the new reroutes may not be available yet.

## EXTENSIONS
- Comparing ridership data before and after a route change.
- Wayfinding - If a stop is outdated, direct user to nearest new stop for a bus going in the same direction.
- Connecting the bus stops - Right now the map only displays the bus stops. It would be visually nice to have the stops connected.
- In the next year, SEPTA will be rolling out even more changes in the system. Those would also be interesting to map.

177 changes: 177 additions & 0 deletions css/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
html,
body {
height: 100%;
margin: 0;
}

body {
display: flex;
flex-direction: column;
min-height: 100vh;
min-height: 100dvh;
font-family: 'Public Sans', sans-serif;
}

.skip-link {
position: absolute;
z-index: 10;
top: 8px;
left: 8px;
padding: 10px 14px;
transform: translateY(-150%);
background: #fff;
color: #000;
font-weight: 700;
}

.skip-link:focus {
transform: translateY(0);
}

.page-header {
flex: 0 0 auto;
padding: 16px 24px;
border-bottom: 4px solid #f14728;
background-color: #1f4fa3;
color: #fff;
}

.title-row {
display: flex;
align-items: center;
gap: 12px;
}

.page-logo {
width: 48px;
height: 48px;
flex: 0 0 auto;
object-fit: contain;
}

.page-header h1 {
margin: 0;
font-size: 2rem;
}

.page-header h2 {
margin: 0;
font-size: 1rem;
}

a:focus-visible,
button:focus-visible,
select:focus-visible,
input:focus-visible {
outline: 2px solid #000;
outline-offset: 2px;
}

#map {
flex: 3 3 auto;
min-height: 0;
width: 100%;
}

.data-credit {
padding: 10px 24px 18px;
background: #f5f5f5;
color: #222;
border-top: 1px solid #d9d9d9;
font-size: 0.9rem;
}

.data-credit p {
margin: 0;
}

.data-credit a {
color: #1f4fa3;
font-weight: 600;
}

.route-filter {
display: flex;
align-items: center;
gap: 5px;
white-space: nowrap;
padding: 10px 12px;
border: 1px solid #000;
border-radius: 4px;
background: #fff;
box-shadow: 0 1px 5px rgb(0 0 0 / 40%);
font: 13px 'Public Sans', sans-serif;
}

.route-filter select {
min-width: 90px;
font: inherit;
}

.route-filter button {
width: auto;
height: auto;
margin: 0;
padding: 4px 8px;
font: inherit;
}

.route-layer-control {
padding: 5px 7px;
border: 1px solid #000;
background: #fff;
font: 12px/1.35 'Public Sans', sans-serif;
}

.route-layer-control label {
display: block;
white-space: nowrap;
}

.route-layer-control input {
width: 12px;
height: 12px;
margin: 3px;
vertical-align: middle;
}

.route-status-control {
box-sizing: border-box;
width: 300px;
max-width: calc(100vw - 40px);
min-height: 60px;
padding: 12px 16px;
border: 1px solid #68736d;
border-radius: 4px;
background: #fff;
font: 16px/1.4 'Public Sans', sans-serif;
}

.route-status-control p {
margin: 0;
}

.route-status-control.status-neutral {
background: #fff;
color: #222;
outline:#222;
}

.route-status-control.status-changed {
background: #fde2e0;
color: #81251f;
outline:#222;
}

.route-status-control.status-discontinued {
background: #e8e5f5;
color: #3d315f;
outline:#222;
}

.route-status-control.status-unchanged {
background: #e1f1e8;
color: #205638;
outline:#222;

}
Loading