This pull request updates several parts of the user interface to fix various usability issues. It also adds new metrics and charts that were already returned by the GraphQL API but not yet displayed, including comparing observed and scheduled metrics. It also refactors the code for many of the frontend components, making it easier to add charts and reorganize the user interface in the future.
The design changes are described in https://docs.google.com/document/d/1RpVZsbBHFiPLXbKcmsa4gi68ab-C_yi1Ar3lHshu6i4/edit# . This document includes detailed descriptions of usability issues that were identified with the current design, as well as the proposed user interface changes. Please review this document and feel free to add comments.
With input from several people at Code for PDX, I also drafted a more general document proposing design principles for OpenTransit that all contributors could refer to when considering design changes in the future: https://docs.google.com/document/d/19soN0I69lygHuQbKbWlx7OKgHOek38MU2eMS0y3rH1s/edit# . Since OpenTransit has a growing number of contributors in multiple cities, agreeing on shared design principles would help ensure that teams in different cities can continue to benefit from each other’s work, without needing to fork the codebase and work on changes on their own.
In the process of implementing these user interface design changes, a lot of the frontend code was refactored as well.
Moved the main navigation bar into the App component, to avoid duplicating navigation UI components in every screen.
Created a SimpleChart component, a wrapper around react-vis XYPlot, to make it easier to create charts with crosshairs (tooltips showing the values at the mouse cursor) and appropriately formatted axis labels, ticks, and legends, with a consistent UI with much less code. The react-vis library provides low-level functionality which previously required a lot of tedious duplicative code for each chart, such as managing the state to keep track of which data point the mouse is currently over. Most of the existing charts were refactored to use SimpleLineMarkChart, SimpleVerticalBarChart, or SimpleVerticalRectChart, and several new charts were implemented: OnTimePerformanceByDayChart, OnTimePerformanceByTimeChart, OnTimePerformanceHistogram, ServiceFrequencyByDayChart, ServiceFrequencyByTimeChart, and ServiceFrequencyGapHistogram.
Each chart is refactored into its own component, which is connected to the redux state. This allows the screens that display charts to render each chart like without needing to pass props to each chart, and simplifies the code by avoiding mixing logic for several charts in one screen. This will make it easier to rearrange charts and screens in the future, and make it easier to customize which charts are displayed via configuration. If a chart is not applicable for the current graphParams, it will render as empty. This lets the parent screen not need to know the conditions when each chart is displayed.
Updated most charts to support comparing observed vs scheduled metrics, and comparing metrics from two date ranges.
Previously, the x-axis labels for "By Day" charts were shown for each date, which made it necessary to render each date vertically to avoid overlap. Now, the x-value is set to the index of the date, which allows react-vis to avoid showing every date label on the x-axis.
Renamed components with names starting with "Info" to more appropriate names.
Used GraphQL @include directives to avoid creating separate queries for single/dual date ranges, and avoid fetching timeRanges field when the time range is not "All Day"
Added updateQuery action to simplify logic in date/time range controls. To change the query string while keeping the rest of the URL the same, it calls dispatch with the type set to state.location.type, and payload set to state.location.payload. (It isn't necessary to look up the type from state.page, since the type is already part of the state.)
The RouteSummary component now only shows data from state.routeMetrics, instead of combining data from state.agencyMetrics and state.routeMetrics. In the future, when the user changes the date range, we could avoid making the API request to update state.agencyMetrics unless the user is viewing the Dashboard.
Split the content of each RouteScreen tab into separate components (e.g. OnTimePerformanceStats, ServiceFrequencyStats)
Tabs in the RouteScreen component are refactored so that each tab and its associated component are defined only in one place. This would make it easier to customize the RouteScreen tabs in the future via configuration.
When a RouteScreen tab is not active, its content is no longer rendered. Previously, inactive tabs were rendered but the associated content was set as hidden.
We have already been discussing these changes over the past few weeks in Portland. I'd expect that there may also be consensus support in SF for many of these changes, but some contributors in SF may not agree with some of these proposed changes, such as the removal of scores, stars, colored chips, cards, and certain metrics. However, we would support changes that allow SF to customize the UI via configuration, e.g. if SF still wants to display scores.
Since these changes involve significant refactoring that will result in many merge conflicts as other developers make frontend changes, I would recommend merging these changes relatively quickly and creating issues in GitHub for non-trivial fixes. If the SF team still wants to show scores, stars, cards, etc, I would suggest making this functionality available via configuration options after the changes are merged.
This pull request updates several parts of the user interface to fix various usability issues. It also adds new metrics and charts that were already returned by the GraphQL API but not yet displayed, including comparing observed and scheduled metrics. It also refactors the code for many of the frontend components, making it easier to add charts and reorganize the user interface in the future.
The design changes are described in https://docs.google.com/document/d/1RpVZsbBHFiPLXbKcmsa4gi68ab-C_yi1Ar3lHshu6i4/edit# . This document includes detailed descriptions of usability issues that were identified with the current design, as well as the proposed user interface changes. Please review this document and feel free to add comments.
With input from several people at Code for PDX, I also drafted a more general document proposing design principles for OpenTransit that all contributors could refer to when considering design changes in the future: https://docs.google.com/document/d/19soN0I69lygHuQbKbWlx7OKgHOek38MU2eMS0y3rH1s/edit# . Since OpenTransit has a growing number of contributors in multiple cities, agreeing on shared design principles would help ensure that teams in different cities can continue to benefit from each other’s work, without needing to fork the codebase and work on changes on their own.
The TriMet version of the app with these changes can be seen at http://opentransit-youngj.herokuapp.com/ .
In the process of implementing these user interface design changes, a lot of the frontend code was refactored as well.
@include
directives to avoid creating separate queries for single/dual date ranges, and avoid fetching timeRanges field when the time range is not "All Day"dispatch
with thetype
set to state.location.type, andpayload
set to state.location.payload. (It isn't necessary to look up thetype
from state.page, since thetype
is already part of the state.)We have already been discussing these changes over the past few weeks in Portland. I'd expect that there may also be consensus support in SF for many of these changes, but some contributors in SF may not agree with some of these proposed changes, such as the removal of scores, stars, colored chips, cards, and certain metrics. However, we would support changes that allow SF to customize the UI via configuration, e.g. if SF still wants to display scores.
Since these changes involve significant refactoring that will result in many merge conflicts as other developers make frontend changes, I would recommend merging these changes relatively quickly and creating issues in GitHub for non-trivial fixes. If the SF team still wants to show scores, stars, cards, etc, I would suggest making this functionality available via configuration options after the changes are merged.