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
156 changes: 156 additions & 0 deletions assets/css/dashboard.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/* Global Styles */
*, *::before, *::after {
box-sizing: border-box;
}

body {
margin: 0;
height: 100vh;
font-family: Lato, sans-serif;
display: flex;
flex-direction: column;
}

/* Controls Styles */
.controls {
display: flex;
align-items: center;
padding: 20px;
gap: 20px;
}

.controls select {
padding: 8px;
font-size: 16px;
}

/* Map and Info Box */
.map-info-container {
display: flex;
flex: 1;
min-height: 600px;
}

.map-container {
width: 65%;
height: 100%;
position: relative;
}

#map {
width: 100%;
height: 100%;
}

.info-box {
width: 35%;
padding: 20px;
flex: 1;
border: 1px solid #ccc;
background-color: #f9f9f9;
max-height: 100%;
box-sizing: border-box;
overflow-y: auto;
position: relative;
}

.info-box h2 {
text-align: center;
margin-bottom: 20px;
}

#info-table {
width: 100%;
border-collapse: collapse;
}

#info-table th, #info-table td {
border: 1px solid #ddd;
padding: 8px;
}

#info-table th {
background-color: #f2f2f2;
text-align: left;
}

#info-table tr:nth-child(even) {
background-color: #f9f9f9;
}

#info-table tr:hover {
background-color: #ddd;
}

.chart-item {
border: 1px solid #ccc;
background-color: #f9f9f9;
min-height: 300px;
position: relative;
width: 100%;
margin-top: 20px;
box-sizing: border-box;
padding: 10px;
overflow: hidden;
}

.chart-item svg {
width: 100%;
max-width: 100%;
height: auto;
}

/* Tooltip styling */
.tooltip {
position: absolute;
text-align: center;
padding: 6px;
font: 12px sans-serif;
background: rgb(0 0 0 / 70%);
color: #fff;
border: 0;
border-radius: 4px;
pointer-events: none;
z-index: 10;
}

/* Legend Styles */
.legend-box {
position: absolute;
bottom: 20px;
right: 20px;
background-color: white;
border: 1px solid gray;
padding: 10px;
z-index: 1000;
box-shadow: 0 0 10px rgb(0 0 0 / 10%);
font-size: 1em;
width: 180px;
}

.legend-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 5px;
margin-bottom: 3px;
background-color: rgb(255 255 255 / 80%);
}

.legend-color {
width: 20px;
height: 20px;
margin-right: 10px;
}

.legend-item.highlight {
background-color: yellow;
font-weight: bold;
}

.legend-title {
font-size: 1.02rem;
font-weight: 300;
margin-bottom: 0.5rem;
text-align: left;
}
1,343 changes: 1,343 additions & 0 deletions assets/data/philly.geojson

Large diffs are not rendered by default.

1,342 changes: 1,342 additions & 0 deletions assets/data/philly_2018.geojson

Large diffs are not rendered by default.

1,342 changes: 1,342 additions & 0 deletions assets/data/philly_2019.geojson

Large diffs are not rendered by default.

1,342 changes: 1,342 additions & 0 deletions assets/data/philly_2020.geojson

Large diffs are not rendered by default.

1,342 changes: 1,342 additions & 0 deletions assets/data/philly_2021.geojson

Large diffs are not rendered by default.

1,342 changes: 1,342 additions & 0 deletions assets/data/philly_2022.geojson

Large diffs are not rendered by default.

1,342 changes: 1,342 additions & 0 deletions assets/data/philly_2023.geojson

Large diffs are not rendered by default.

1,342 changes: 1,342 additions & 0 deletions assets/data/philly_2024.geojson

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions assets/js/colors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const columnColors = {
'stop_counts': '#4e79a7',
'device_counts': '#f28e20'
};

export { columnColors };
40 changes: 40 additions & 0 deletions assets/js/dashboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Vismap } from './vismap.js';
import { visualizeCharts } from './vischarts.js';
import { populateInfoTable } from './infoTable.js';
import { setupEventListeners } from './events.js';

console.log('Initializing dashboard.');

const map = L.map('map', { scrollWheelZoom: true }).setView([39.9800, -75.1200], 11);

L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
maxZoom: 18,
id: 'mapbox/light-v11',
tileSize: 512,
zoomOffset: -1,
accessToken: 'pk.eyJ1IjoiZnJhbmtjaCIsImEiOiJjbG95aTZhbGQwM2ZwMmhxb3BvOGE3cjExIn0.9FCYx6xJ-wp8YEgk7VpG0Q'
}).addTo(map);

// Define column and breaks
const columnName = 'stop_counts';
const customBreaks = [1000, 2000, 3000, 4000, 5000, 8000, 10000, 20000];

// Initialize Vismap
const vismapInstance = new Vismap(map, customBreaks, columnName);
vismapInstance.fetchData(document.getElementById('year-selector').value);

const columnDisplayMapping = {
'GEOID': 'GEOID',
'stop_counts': 'Number of Visits',
'device_counts': 'Number of Visitors'
};

setupEventListeners(
map,
vismapInstance,
'year-selector',
visualizeCharts,
(properties) => populateInfoTable(properties, columnDisplayMapping)
);

visualizeCharts(null);
14 changes: 14 additions & 0 deletions assets/js/events.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export function setupEventListeners(map, vismapInstance, yearSelectorId, visualizeChartsCallback, populateInfoTableCallback) {
const yearSelector = document.getElementById(yearSelectorId);

yearSelector.addEventListener('change', function () {
const selectedYear = this.value;
vismapInstance.fetchData(selectedYear);
});

map.on('featureSelected', function(event) {
const properties = event.properties;
populateInfoTableCallback(properties);
visualizeChartsCallback(properties ? properties['GEOID'] : null);
});
}
27 changes: 27 additions & 0 deletions assets/js/infoTable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export function populateInfoTable(properties, columnDisplayMapping) {
const infoTableBody = document.querySelector('#info-table tbody');
infoTableBody.innerHTML = '';

if (!properties) {
const row = document.createElement('tr');
const cell = document.createElement('td');
cell.colSpan = 2;
cell.textContent = 'Click on map to select a location.';
row.appendChild(cell);
infoTableBody.appendChild(row);
return;
}

Object.keys(columnDisplayMapping).forEach(key => {
const row = document.createElement('tr');
const propCell = document.createElement('td');
const valueCell = document.createElement('td');

propCell.textContent = columnDisplayMapping[key];
valueCell.textContent = properties[key] || 'N/A';

row.appendChild(propCell);
row.appendChild(valueCell);
infoTableBody.appendChild(row);
});
}
Loading