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

Add tooltip for timepoints #452

Merged
merged 14 commits into from
Feb 25, 2020
Merged
2 changes: 2 additions & 0 deletions assets/css/_ladder.scss
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

.m-ladder__timepoint-name {
@include font-timepoint;
cursor: pointer;
}

.m-ladder__vehicle {
Expand Down Expand Up @@ -90,6 +91,7 @@
&.early {
stroke: $color-vehicle-early;
}

&.late {
stroke: $color-vehicle-late;
}
Expand Down
5 changes: 5 additions & 0 deletions assets/css/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,9 @@ body {

.m-app {
display: flex;

.__react_component_tooltip {
border-radius: 4px;
text-align: center;
}
}
23 changes: 18 additions & 5 deletions assets/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
},
"dependencies": {
"@rehooks/component-size": "^1.0.3",
"@types/react-tooltip": "^3.11.0",
"core-js": "^3.6.4",
"leaflet": "^1.6.0",
"leaflet-defaulticon-compatibility": "^0.1.1",
Expand All @@ -24,6 +25,7 @@
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-router-dom": "^5.1.2",
"react-tooltip": "^4.0.3",
"resize-observer-polyfill": "^1.5.1",
"whatwg-fetch": "^3.0.0"
},
Expand Down
6 changes: 3 additions & 3 deletions assets/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
Route,
RouteId,
Shape,
TimepointId,
Timepoint,
TripId,
} from "./schedule.d"

Expand Down Expand Up @@ -93,9 +93,9 @@ export const fetchShuttleRoutes = (): Promise<Route[]> =>

export const fetchTimepointsForRoute = (
routeId: RouteId
): Promise<TimepointId[]> =>
): Promise<Timepoint[]> =>
apiCall({
url: `/api/routes/${routeId}`,
parser: (timepointIds: TimepointId[]) => timepointIds,
parser: (timepoints: Timepoint[]) => timepoints,
defaultResult: [],
})
28 changes: 14 additions & 14 deletions assets/src/components/ladder.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import useComponentSize from "@rehooks/component-size"
import React, { useContext, useRef } from "react"
import ReactTooltip from "react-tooltip"
import { StateDispatchContext } from "../contexts/stateDispatchContext"
import { partition } from "../helpers/array"
import featureIsEnabled from "../laboratoryFeatures"
Expand All @@ -19,13 +20,13 @@ import {
VehicleOrGhost,
VehicleTimepointStatus,
} from "../realtime.d"
import { TimepointId } from "../schedule.d"
import { Timepoint } from "../schedule.d"
import { selectVehicle } from "../state"
import HeadwayLines from "./headwayLines"
import { Orientation, Size, VehicleIconSvgNode } from "./vehicleIcon"

export interface Props {
timepoints: TimepointId[]
timepoints: Timepoint[]
vehiclesAndGhosts: VehicleOrGhost[]
ladderDirection: LadderDirection
selectedVehicleId?: VehicleId
Expand All @@ -49,7 +50,7 @@ const Ladder = ({
const elementRef = useRef(null)
const { height } = useComponentSize(elementRef)

const orderedTimepoints: TimepointId[] = orderTimepoints(
const orderedTimepoints: Timepoint[] = orderTimepoints(
timepoints,
ladderDirection
)
Expand Down Expand Up @@ -114,17 +115,14 @@ const Ladder = ({
ladderVehicles={ladderVehicles}
/>
)}
{orderedTimepoints.map((timepointId: TimepointId, index: number) => {
{orderedTimepoints.map((timepoint: Timepoint, index: number) => {
const y = timepointSpacingY * index
return (
<LadderTimepoint
key={timepointId}
timepointId={timepointId}
y={y}
/>
<LadderTimepoint key={timepoint.id} timepoint={timepoint} y={y} />
)
})}
</svg>
<ReactTooltip effect="solid" globalEventOff="click" />
</div>
)
}
Expand Down Expand Up @@ -195,10 +193,10 @@ const RoadLines = ({ height }: { height: number }) => (
)

const LadderTimepoint = ({
timepointId,
timepoint,
y,
}: {
timepointId: TimepointId
timepoint: Timepoint
y: number
}) => (
<>
Expand All @@ -220,23 +218,25 @@ const LadderTimepoint = ({
y={y}
textAnchor="middle"
dominantBaseline="middle"
data-tip={timepoint.name}
Copy link
Member

@skyqrose skyqrose Feb 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the name is missing, this would be null. Does react tooltip handle that well?

(Not relevant if we decide this comment is a good idea: #452 (comment) )

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you can see this for "CENJF" on route 502: there's no tooltip if there's no content.

data-event="click"
>
{timepointId}
{timepoint.id}
</text>
</>
)

/** timepoints should be ordered top to bottom */
const timepointStatusYFromTimepoints = (
timepoints: TimepointId[],
timepoints: Timepoint[],
timepointSpacingY: number
) => (
timepointStatus: VehicleTimepointStatus | null,
direction: VehicleDirection
): number => {
if (timepointStatus) {
const timepointIndex = timepoints.findIndex(
timepointId => timepointId === timepointStatus.timepointId
timepoint => timepoint.id === timepointStatus.timepointId
)
if (timepointIndex !== -1) {
const fractionDirection = direction === VehicleDirection.Up ? +1 : -1
Expand Down
6 changes: 3 additions & 3 deletions assets/src/hooks/useTimepoints.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useState } from "react"
import { fetchTimepointsForRoute } from "../api"
import { RouteId, TimepointId, TimepointsByRouteId } from "../schedule.d"
import { RouteId, Timepoint, TimepointsByRouteId } from "../schedule.d"

const useTimepoints = (selectedRouteIds: RouteId[]): TimepointsByRouteId => {
const [timepointsByRouteId, setTimepointsByRouteId] = useState<
Expand All @@ -16,7 +16,7 @@ const useTimepoints = (selectedRouteIds: RouteId[]): TimepointsByRouteId => {

const setTimepointsForRoute = (
routeId: RouteId,
timepoints: TimepointId[]
timepoints: Timepoint[]
): void => {
setTimepointsByRouteId(previousTimepointsByRouteId => ({
...previousTimepointsByRouteId,
Expand All @@ -29,7 +29,7 @@ const useTimepoints = (selectedRouteIds: RouteId[]): TimepointsByRouteId => {
if (!(routeId in timepointsByRouteId)) {
setLoadingTimepointsForRoute(routeId)

fetchTimepointsForRoute(routeId).then((newTimepoints: TimepointId[]) =>
fetchTimepointsForRoute(routeId).then((newTimepoints: Timepoint[]) =>
setTimepointsForRoute(routeId, newTimepoints)
)
}
Expand Down
6 changes: 3 additions & 3 deletions assets/src/models/ladderDirection.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ByRouteId, DirectionId, RouteId, TimepointId } from "../schedule"
import { ByRouteId, DirectionId, RouteId, Timepoint } from "../schedule"

export enum LadderDirection {
ZeroToOne,
Expand Down Expand Up @@ -38,9 +38,9 @@ export const flipLadderDirectionForRoute = (
}

export const orderTimepoints = (
timepointsFromApi: TimepointId[],
timepointsFromApi: Timepoint[],
ladderDirection: LadderDirection
): TimepointId[] =>
): Timepoint[] =>
// Timepoints come from the API in the ZeroToOne direction
// Use slice to make a copy of the array before destructively reversing
ladderDirection === LadderDirection.OneToZero
Expand Down
7 changes: 6 additions & 1 deletion assets/src/schedule.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,14 @@ export interface ShapePoint {

export type TimepointId = string

export interface Timepoint {
id: TimepointId
name: string | null
}

// An undefined value indicates that the timepoints need to be loaded
// A null value indicates that we are currently loading the timepoints
export type LoadableTimepoints = TimepointId[] | null | undefined
export type LoadableTimepoints = Timepoint[] | null | undefined

export type TimepointsByRouteId = ByRouteId<LoadableTimepoints>

Expand Down
Loading