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
43 changes: 0 additions & 43 deletions INSTRUCTIONS.md

This file was deleted.

69 changes: 68 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,68 @@
Add a readme for your engagement tool here. Include content overview, data citations, and any relevant technical details.
# Penn Nighttime Safety Dashboard – Engagement Project

This project is an interactive web-based map designed to improve nighttime navigation safety for Penn students.
It builds upon the Night Safety Map developed in earlier assignments and adds user engagement features, including route explanation and real-time user feedback collection.

---

## Project Overview

The dashboard allows users to:
- Visualize crime hotspots using a heatmap
- Select start and destination points on campus
- Compare shortest vs safest walking routes
- Understand the trade-offs between different routing strategies
- Provide feedback on whether a recommended route was helpful

The goal of this engagement project is to move beyond visualization and support user interaction, explanation, and participation.


## Engagement Features Implemented

### 1. Route Strategy Explanation
When a route is generated, a Route Comparison panel appears explaining:
- What the selected routing strategy prioritizes
- Potential trade-offs (distance vs safety)
- Why a user might choose one route over another

This helps users understand why a route was recommended, not just what the route is.


### 2. User Feedback Collection (Firebase Demo)
Users can provide feedback after viewing a route by clicking:
- 👍 Yes, this route was helpful
- 👎 No, this route was not helpful

Feedback is:
- Stored in Firebase Firestore
- Tagged with the selected route type (shortest / safest)
- Timestamped using server time

This demonstrates a minimal but functional example of real user engagement and data persistence.


## Technologies Used

- HTML / CSS / JavaScript
- Leaflet.js (map rendering)
- Leaflet Heatmap plugin
- Firebase (Firestore database for feedback storage)


## Notes

- Firebase integration is implemented as a minimal demo for engagement purposes
- No user authentication is required
- The focus of this assignment is interaction design rather than production deployment


## Author
Author: Hazel Sun
Master of City Planning, University of Pennsylvania
Course: MUSA Dashboard Project


## Data Sources:
OpenDataPhilly(Crime.geojson, Street_Centerline.geojson)
All datasets are projected in WGS84 (EPSG:4326).

217 changes: 217 additions & 0 deletions css/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
html, body {
height: 100%;
margin: 0;
padding: 0;
font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
}

header {
height: 80px;
display: flex;
align-items: center;
justify-content: center;

background-color: #002855;
color: white;

font-size: 1.2rem;
font-weight: 600;
letter-spacing: 0.3px;

margin: 0;
padding: 0;
}



/* main layout */
main {
display: flex;
height: calc(100vh - 40px);
}

/* sidebar */
.sidebar {
width: 280px;
padding: 20px;
background: #f8f9fa;
border-right: 1px solid #ddd;
overflow-y: auto;
}

/* map */
#map {
flex: 1;
height: 100%;
width: 100%;
}

.legend {
background: white;
padding: 12px;
border-radius: 6px;
position: fixed;
bottom: 20px;
right: 20px;
z-index: 9999;
box-shadow: 0 0 10px rgba(0,0,0,0.25);
}



.legend i {
width: 14px;
height: 14px;
display: inline-block;
margin-right: 6px;
border-radius: 3px;
}

/* search block */
.search-block {
margin-top: 20px; /* 和 filter 区分 */
}

.search-block h3 {
margin: 0 0 8px 0;
font-size: 1rem;
}

#place-search {
box-sizing: border-box;
width: 100%;
padding: 6px 8px;
font-size: 0.9rem;
border: 1px solid #ccc;
border-radius: 4px;
}

#search-button {
margin-top: 8px;
padding: 6px 12px;
font-size: 0.9rem;
border: none;
border-radius: 4px;
background-color: #002855;
color: white;
cursor: pointer;
}

#search-button:hover {
background-color: #01408a;
}
.slider-block {
margin-top: 24px;
font-size: 0.9rem;
}

#safety-min,
#pop-min,
#light-min {
width: 100%;
}

.slider-label {
margin-top: 4px;
color: #555;
font-size: 0.85rem;
}
.place-count {
margin: 0 0 0.75rem 0;
font-size: 0.85rem;
color: #555;
}

.nav-block {
margin-bottom: 16px;
font-size: 0.9rem;
}

.nav-block h2 {
font-size: 1.1rem;
margin: 0 0 8px 0;
}

.nav-block label {
display: block;
margin-top: 4px;
margin-bottom: 2px;
}

.nav-block select {
width: 100%;
padding: 4px 6px;
font-size: 0.9rem;
margin-bottom: 6px;
border-radius: 4px;
border: 1px solid #ccc;
box-sizing: border-box;
}

.nav-block button {
display: block;
width: 100%;
margin-top: 6px;
padding: 6px 8px;
font-size: 0.9rem;
border-radius: 4px;
border: none;
cursor: pointer;
background-color: #002855;
color: #fff;
}

.nav-block button.secondary {
background-color: #e0e0e0;
color: #333;
}

.nav-block button:hover:not(.secondary) {
background-color: #01408a;
}

.nav-block button.secondary:hover {
background-color: #cfcfcf;
}
.nav-description {
font-size: 0.85rem;
color: #555;
margin-bottom: 12px;
line-height: 1.4;
}
.nav-description {
font-size: 0.85rem;
color: #555;
margin-bottom: 12px;
line-height: 1.4;
}

.route-info {
margin-top: 16px;
padding: 10px;
background: #f7f9fb;
border: 1px solid #ddd;
border-radius: 6px;
font-size: 0.85rem;
}

.route-info h3 {
margin-top: 0;
font-size: 0.95rem;
}

.hint-text {
font-size: 0.75rem;
color: #666;
margin-left: 20px;
}
.feedback-status {
margin-top: 10px;
padding: 8px 10px;
background: #eef6f1;
border: 1px solid #b7e0c2;
border-radius: 6px;
font-size: 0.8rem;
color: #2f6f4e;
transition: opacity 0.4s ease;
}
1 change: 1 addition & 0 deletions data/Crime.geojson

Large diffs are not rendered by default.

Loading