Skip to content

Commit

Permalink
Improvements to vehicle popups
Browse files Browse the repository at this point in the history
  • Loading branch information
brendannee committed Sep 19, 2024
1 parent bb8a2e5 commit 2d28e32
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 38 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Updated
- Dependency updates for documentation site
- Use jQuery instead of $
- Improvements to vehicle popups

## [2.9.10] - 2024-09-17

Expand Down
16 changes: 16 additions & 0 deletions views/default/css/timetable_styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,22 @@ a:hover {
padding: 0 5px;
}

.timetable-page .map .mapboxgl-popup-content .upcoming-stops {
display: grid;
grid-template-columns: auto 1fr;
gap: 0.5rem;
line-height: 1;
}

.timetable-page
.map
.mapboxgl-popup-content
.upcoming-stops
div:nth-child(2n-1) {
text-align: right;
font-weight: bold;
}

.timetable-page .map-legend {
max-width: 30%;
background-color: #fff;
Expand Down
2 changes: 1 addition & 1 deletion views/default/js/timetable-alerts.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* global window, document, $, anchorme, mapboxgl, Pbf, stopData, routeData, routeIds, tripIds, stopIds, gtfsRealtimeUrls */
/* global jQuery, anchorme, Pbf, stopData, routeData, routeIds, tripIds, stopIds, gtfsRealtimeUrls */
/* eslint no-var: "off", prefer-arrow-callback: "off", no-unused-vars: "off" */

let gtfsRealtimeAlertsInterval;
Expand Down
102 changes: 66 additions & 36 deletions views/default/js/timetable-map.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* global window, document, $, mapboxgl, Pbf, stopData, routeData, routeIds, tripIds, geojsons, gtfsRealtimeUrls */
/* eslint no-var: "off", prefer-arrow-callback: "off", no-unused-vars: "off" */
/* global document, jQuery, mapboxgl, Pbf, stopData, routeData, routeIds, tripIds, geojsons, gtfsRealtimeUrls */
/* eslint prefer-arrow-callback: "off", no-unused-vars: "off" */

const maps = {};
const vehicleMarkers = {};
Expand Down Expand Up @@ -84,7 +84,7 @@ function formatRoute(route) {
return html.prop('outerHTML');
}

function formatStopPopup(feature, stop) {
function getStopPopupHtml(feature, stop) {
const routeIds = JSON.parse(feature.properties.route_ids);
const html = jQuery('<div>');

Expand Down Expand Up @@ -162,39 +162,58 @@ function secondsInFuture(dateString) {
return diffInSeconds > 0 ? diffInSeconds : 0;
}

function getVehiclePopupHtml(vehiclePosition, vehicleTripUpdate) {
const lastUpdated = new Date(vehiclePosition.vehicle.timestamp * 1000);
const directionName = jQuery(
'.timetable #trip_id_' + vehiclePosition.vehicle.trip.trip_id,
)
.parents('.timetable')
.data('direction-name');

const descriptionArray = [];
function formatMovingText(vehiclePosition) {
let movingText = '';

if (directionName) {
descriptionArray.push(`<div class="popup-title">${directionName}</div>`);
if (
(vehiclePosition.vehicle.position.bearing !== undefined &&
vehiclePosition.vehicle.position.bearing !== 0) ||
vehiclePosition.vehicle.position.speed
) {
movingText += 'Moving ';
}

let movingText = '';

if (
vehiclePosition.vehicle.position.bearing !== undefined &&
vehiclePosition.vehicle.position.bearing !== 0
) {
movingText += `Moving: ${degToCompass(vehiclePosition.vehicle.position.bearing)}`;
movingText += degToCompass(vehiclePosition.vehicle.position.bearing);
}
if (vehiclePosition.vehicle.position.speed) {
movingText += ` at ${formatSpeed(metersPerSecondToMph(vehiclePosition.vehicle.position.speed))}`;
}

return movingText;
}

function getVehiclePopupHtml(vehiclePosition, vehicleTripUpdate) {
const html = jQuery('<div>');

const lastUpdated = new Date(vehiclePosition.vehicle.timestamp * 1000);
const directionName = jQuery(
'.timetable #trip_id_' + vehiclePosition.vehicle.trip.trip_id,
)
.parents('.timetable')
.data('direction-name');

if (directionName) {
jQuery('<div>')
.addClass('popup-title')
.text(`Vehicle: ${directionName}`)
.appendTo(html);
}

const movingText = formatMovingText(vehiclePosition);

if (movingText) {
descriptionArray.push(`<div>${movingText}</div>`);
jQuery('<div>').text(movingText).appendTo(html);
}

descriptionArray.push(
`<div><small>Updated: ${lastUpdated.toLocaleTimeString()}</small></div>`,
);
jQuery('<div>')
.append(
jQuery('<small>').text(`Updated: ${lastUpdated.toLocaleTimeString()}`),
)
.appendTo(html);

const nextArrivals = [];
if (vehicleTripUpdate && vehicleTripUpdate.trip_update.stop_time_update) {
Expand Down Expand Up @@ -222,23 +241,32 @@ function getVehiclePopupHtml(vehiclePosition, vehicleTripUpdate) {
}

if (nextArrivals.length > 0) {
descriptionArray.push('<div><strong>Upcoming Stops: </strong></div>');

for (const arrival of nextArrivals) {
let delay = '';
jQuery('<div>')
.append(jQuery('<small>').text('Upcoming Stops:'))
.appendTo(html);

if (arrival.delay > 0) {
delay = `<span class="delay">${formatSeconds(arrival.delay)} late</span>`;
} else if (arrival.delay < 0) {
delay = `<span class="delay">${formatSeconds(arrival.delay)} early</span>`;
}
descriptionArray.push(
`<div>${arrival.stopName} in <strong>${formatSeconds(arrival.secondsToArrival)}</strong> ${delay}</div>`,
);
}
jQuery('<div>')
.addClass('upcoming-stops')
.append(
nextArrivals.flatMap((arrival) => {
let delay = '';

if (arrival.delay > 0) {
delay = `(${formatSeconds(arrival.delay)} behind schedule)`;
} else if (arrival.delay < 0) {
delay = `(${formatSeconds(arrival.delay)} ahead of schedule)`;
}

return [
jQuery('<div>').text(formatSeconds(arrival.secondsToArrival)),
jQuery('<div>').text(`${arrival.stopName} ${delay}`),
];
}),
)
.appendTo(html);
}

return descriptionArray.join('');
return html.prop('outerHTML');
}

function addVehicleMarker(vehiclePosition, vehicleTripUpdate) {
Expand Down Expand Up @@ -749,7 +777,9 @@ function createMap(id) {

new mapboxgl.Popup()
.setLngLat(feature.geometry.coordinates)
.setHTML(formatStopPopup(feature, stopData[feature.properties.stop_id]))
.setHTML(
getStopPopupHtml(feature, stopData[feature.properties.stop_id]),
)
.addTo(map);
});

Expand Down
2 changes: 1 addition & 1 deletion views/default/js/timetable-menu.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* global window, document, $, maps */
/* global jQuery */
/* eslint no-unused-vars: "off" */

function showSelectedTimetable() {
Expand Down

0 comments on commit 2d28e32

Please sign in to comment.