Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix slowzone date parsing in map #1024

Merged
merged 1 commit into from
Dec 31, 2024
Merged
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
8 changes: 2 additions & 6 deletions common/api/slowzones.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
import type {
DayDelayTotals,
SlowZoneAllSlowResponse,
SlowZoneDayTotalsResponse,
SlowZoneResponse,
SpeedRestriction,
} from '../types/dataPoints';
import type { FetchSpeedRestrictionsOptions, FetchSpeedRestrictionsResponse } from '../types/api';
import { getGtfsRailLineId } from '../utils/lines';
import { apiFetch } from './utils/fetch';

// TODO: Remove the Array option once the slowzone change is mature
export const fetchDelayTotals = (): Promise<SlowZoneDayTotalsResponse | DayDelayTotals[]> => {
export const fetchDelayTotals = (): Promise<SlowZoneDayTotalsResponse> => {
const url = new URL(`/static/slowzones/delay_totals.json`, window.location.origin);
return fetch(url.toString()).then((resp) => resp.json());
};

// TODO: Remove the Array option once the slowzone change is mature
export const fetchAllSlow = (): Promise<SlowZoneAllSlowResponse | SlowZoneResponse[]> => {
export const fetchAllSlow = (): Promise<SlowZoneAllSlowResponse> => {
const all_slow_url = new URL(`/static/slowzones/all_slow.json`, window.location.origin);
return fetch(all_slow_url.toString()).then((resp) => resp.json());
};
Expand Down
4 changes: 2 additions & 2 deletions modules/slowzones/SlowZonesDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export function SlowZonesDetails() {
<div className="relative flex flex-col">
{totalSlowTimeReady ? (
<TotalSlowTimeWrapper
data={isArray(delayTotals.data) ? delayTotals.data : delayTotals.data.data}
data={delayTotals.data.data}
startDateUTC={startDateUTC}
endDateUTC={endDateUTC}
line={line}
Expand All @@ -94,7 +94,7 @@ export function SlowZonesDetails() {
{allSlow.data && speedRestrictions.data && canShowSlowZonesMap ? (
<SlowZonesMap
key={lineShort}
slowZones={isArray(allSlow.data) ? allSlow.data : allSlow.data.data}
slowZones={allSlow.data}
speedRestrictions={speedRestrictions.data}
lineName={lineShort}
direction={isDesktop ? 'horizontal' : 'vertical'}
Expand Down
3 changes: 1 addition & 2 deletions modules/slowzones/SlowZonesWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import React from 'react';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import { isArray } from 'lodash';
import { useDelimitatedRoute } from '../../common/utils/router';
import { HomescreenWidgetTitle } from '../dashboard/HomescreenWidgetTitle';
import { ChartPlaceHolder } from '../../common/components/graphics/ChartPlaceHolder';
Expand Down Expand Up @@ -33,7 +32,7 @@ export const SlowZonesWidget: React.FC = () => {
<HomescreenWidgetTitle title="Slow zones" tab="slowzones" />
{totalSlowTimeReady ? (
<TotalSlowTimeWrapper
data={isArray(delayTotals.data) ? delayTotals.data : delayTotals.data.data}
data={delayTotals.data.data}
startDateUTC={startDateUTC}
endDateUTC={endDateUTC}
line={line}
Expand Down
2 changes: 1 addition & 1 deletion modules/slowzones/SystemSlowZonesDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export function SystemSlowZonesDetails({ showTitle = false }: SystemSlowZonesDet
{allData.data && speedRestrictions.data && canShowSlowZonesMap ? (
<SlowZonesMap
key={lineShort}
slowZones={isArray(allData.data) ? allData.data : allData.data.data}
slowZones={allData.data}
speedRestrictions={speedRestrictions.data}
lineName={lineShort}
direction={isDesktop ? 'horizontal' : 'vertical'}
Expand Down
24 changes: 12 additions & 12 deletions modules/slowzones/map/SlowSegmentLabel.module.css
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
.slowSegmentLabel {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
/* This is in weird SVG values btw */
font-size: 2.5pt;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
/* This is in weird SVG values btw */
font-size: 2.5pt;
}

.slowZoneLabel {
display: flex;
align-items: baseline;
gap: 1.5px;
}
display: flex;
align-items: baseline;
gap: 1.5px;
}
62 changes: 32 additions & 30 deletions modules/slowzones/map/SlowZonesMap.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,44 @@
import React from 'react';

import type { SlowZoneResponse } from '../../../common/types/dataPoints';

import type { SlowZoneAllSlowResponse } from '../../../common/types/dataPoints';
import { SlowZonesMap } from './SlowZonesMap';

export default {
title: 'SlowZonesMap',
component: SlowZonesMap,
};

const slowZonesResponses: SlowZoneResponse[] = [
{
color: 'Red',
fr_id: '70061',
to_id: '70063',
start: '2023-03-12T00:00:00Z',
end: '2023-04-01T00:00:00Z',
delay: 42.5,
latest_delay: 23.1,
previous_delay: 42.5,
mean_metric: 172.929,
baseline: 135.0,
duration: 20,
},
{
color: 'Red',
fr_id: '70063',
to_id: '70061',
start: '2023-03-12T00:00:00Z',
end: '2023-04-01T00:00:00Z',
delay: 90,
latest_delay: 100,
previous_delay: 90,
mean_metric: 172.929,
baseline: 135.0,
duration: 20,
},
];
const slowZonesResponses: SlowZoneAllSlowResponse = {
updated_on: '2023-03-12T00:00:00Z',
data: [
{
color: 'Red',
fr_id: '70061',
to_id: '70063',
start: '2023-03-12T00:00:00Z',
end: '2023-04-01T00:00:00Z',
delay: 42.5,
latest_delay: 23.1,
previous_delay: 42.5,
mean_metric: 172.929,
baseline: 135.0,
duration: 20,
},
{
color: 'Red',
fr_id: '70063',
to_id: '70061',
start: '2023-03-12T00:00:00Z',
end: '2023-04-01T00:00:00Z',
delay: 90,
latest_delay: 100,
previous_delay: 90,
mean_metric: 172.929,
baseline: 135.0,
duration: 20,
},
],
};

export const Primary = () => {
return (
Expand Down
4 changes: 2 additions & 2 deletions modules/slowzones/map/SlowZonesMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { LineMap, createDefaultDiagramForLine } from '@transitmatters/stripmap';
import '@transitmatters/stripmap/dist/style.css';

import { LINE_OBJECTS } from '../../../common/constants/lines';
import type { SlowZoneResponse, SpeedRestriction } from '../../../common/types/dataPoints';
import type { SlowZoneAllSlowResponse, SpeedRestriction } from '../../../common/types/dataPoints';
import type { SlowZonesLineName } from '../types';

import { getSlowZoneOpacity } from '../../../common/utils/slowZoneUtils';
Expand All @@ -16,7 +16,7 @@ import { SlowSegmentLabel } from './SlowSegmentLabel';
import { SlowZonesTooltip } from './SlowZonesTooltip';

interface SlowZonesMapProps extends Pick<React.ComponentProps<typeof LineMap>, 'direction'> {
slowZones: SlowZoneResponse[];
slowZones: SlowZoneAllSlowResponse;
speedRestrictions: SpeedRestriction[];
lineName: SlowZonesLineName;
}
Expand Down
87 changes: 43 additions & 44 deletions modules/slowzones/map/SlowZonesTooltip.module.css
Original file line number Diff line number Diff line change
@@ -1,78 +1,77 @@
.slowZonesTooltip {
display: flex;
align-items: center;
user-select: none;
--tooltip-background: white;
display: flex;
align-items: center;
user-select: none;
--tooltip-background: white;
}

.reverseVertical {
flex-direction: row;
flex-direction: row-reverse;
flex-direction: row;
flex-direction: row-reverse;
}

.horizontal {
flex-direction: column-reverse;
align-items: center;
transform: translateY(-5px);
flex-direction: column-reverse;
align-items: center;
transform: translateY(-5px);
}

.triangle {
width: 0;
height: 0;
z-index: 1;
border-top: 8px solid transparent;
border-bottom: 8px solid transparent;
border-right: 8px solid white;
width: 0;
height: 0;
z-index: 1;
border-top: 8px solid transparent;
border-bottom: 8px solid transparent;
border-right: 8px solid white;
}

.triangleReverse {
transform: scaleX(-1);
transform: scaleX(-1);
}

.triangleHorizontal {
width: 0;
height: 0;
z-index: 1;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-top: 8px solid white;
width: 0;
height: 0;
z-index: 1;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-top: 8px solid white;
}

.content {
border-radius: 4px;
overflow: hidden;
background: var(--tooltip-background);
border-radius: 4px;
overflow: hidden;
background: var(--tooltip-background);
}


.title {
font-weight: 500;
padding: 6px 10px;
background: var(--tooltip-accent-color);
color: white;
font-weight: 500;
padding: 6px 10px;
background: var(--tooltip-accent-color);
color: white;
}

.body {
display: flex;
flex-direction: column;
display: flex;
flex-direction: column;
}

.directionTitle {
display: flex;
align-items: center;
gap: 4px;
margin-bottom: 4px;
display: flex;
align-items: center;
gap: 4px;
margin-bottom: 4px;
}

.speedRestriction {
padding: 6px;
margin: 6px;
margin-top: 0px;
border-radius: 4px;
max-width: 300px;
padding: 6px;
margin: 6px;
margin-top: 0px;
border-radius: 4px;
max-width: 300px;
}

.speedRestrictionStats {
display: flex;
flex-direction: column;
}
display: flex;
flex-direction: column;
}
22 changes: 12 additions & 10 deletions modules/slowzones/map/segment.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import type { Diagram, SegmentLocation } from '@transitmatters/stripmap';

import type { SlowZoneResponse, SpeedRestriction } from '../../../common/types/dataPoints';
import type {
SlowZoneAllSlowResponse,
SlowZoneResponse,
SpeedRestriction,
} from '../../../common/types/dataPoints';
import type { LineShort } from '../../../common/types/lines';
import type { Station } from '../../../common/types/stations';
import { getParentStationForStopId, getStationById } from '../../../common/utils/stations';
Expand All @@ -26,7 +30,7 @@ type SegmentSlowZonesOptions = {
date: Date;
diagram: Diagram;
speedRestrictions: SpeedRestriction[];
slowZones: SlowZoneResponse[];
slowZones: SlowZoneAllSlowResponse;
lineName: LineShort;
};

Expand All @@ -36,13 +40,11 @@ type WithSegmentLocation<T> = {
value: T;
};

// TODO(ian): our slow zones calculations currently set the end_date of all active slow zones
// to the moment when the calculation occurs. We can't distinguish these from a slow zone that
// ended in the past, so we clamp addressable dates at the max date in the slow zones json.
// To remove this hack we should set `end` on all active slow zones to null.
const getEffectiveDate = (desiredDate: Date, slowZones: SlowZoneResponse[]) => {
const allEndDates = slowZones.map((zone) => new Date(zone.end));
const maxEndDate = allEndDates.sort((a, b) => a.valueOf() - b.valueOf()).pop()!;
/**
* Get the latest date that we have data on slow zones for
*/
const getEffectiveDate = (desiredDate: Date, slowZones: SlowZoneAllSlowResponse) => {
const maxEndDate = new Date(slowZones.updated_on);
if (desiredDate.valueOf() > maxEndDate.valueOf()) {
return maxEndDate;
}
Expand Down Expand Up @@ -132,7 +134,7 @@ export const segmentSlowZones = (options: SegmentSlowZonesOptions): Segmentation
const effectiveDate = getEffectiveDate(desiredDate, slowZones);
const activeSlowZones = locateIntoSegments(
filterActiveElements(
slowZones,
slowZones.data,
lineName,
effectiveDate,
(sz) => [new Date(sz.start), new Date(sz.end)],
Expand Down
2 changes: 1 addition & 1 deletion server/chalicelib/data_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def alerts(day: date, params):
{
"valid_from": alert_version["start"],
"valid_to": alert_version["end"],
"text": alert_item["attributes"]["short_header"] or alert_item["attributes"]["header"],
"text": alert_item["attributes"]["header"] or alert_item["attributes"]["short_header"],
}
)
except KeyError as e:
Expand Down
Loading