Skip to content

Commit 6c48712

Browse files
The colors for the accessibility comparison tab can now be changed in the preferences
This includes the colors of the polygons for the intersection and location/scenario 1 and 2, as well as the origin point in scenario mode and the two origin points in location mode. Fix: #1795
1 parent e9e80db commit 6c48712

File tree

10 files changed

+292
-72
lines changed

10 files changed

+292
-72
lines changed

locales/en/transit.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,17 +773,23 @@
773773
"accessibilityComparison": {
774774
"Title": "Accessibility map comparison",
775775
"Legend": "Legend",
776+
"ScenarioNPolygon": "Scenario {{scenarioNumber}} polygon",
777+
"ScenarioLocation": "Scenarios location",
776778
"ScenarioIntersection": "Intersection of the scenarios",
779+
"ScenarioIntersectionPolygon": "Scenarios intersection polygon",
777780
"LocationIntersection": "Intersection of the locations",
781+
"LocationIntersectionPolygon": "Locations intersection polygon",
778782
"LocationN": "Location {{locationNumber}}",
783+
"LocationNPolygon": "Location {{locationNumber}} polygon",
779784
"Difference": "Difference",
780785
"SelectMaxTime": "Select max time to display (minutes)",
781786
"ComparisonByScenario": "Comparison by scenario",
782787
"ComparisonByLocation": "Comparison by location",
783788
"contextMenu": {
784789
"SetAsLocation1": "Set as Location 1",
785790
"SetAsLocation2": "Set as Location 2"
786-
}
791+
},
792+
"Colors": "Colors"
787793
},
788794
"gtfs": {
789795
"ButtonImport": "Import",
@@ -1032,6 +1038,12 @@
10321038
"transitAccessibilityMap": {
10331039
"LocationColor": "Location color",
10341040
"PolygonColor": "Accessibility polygon default color"
1041+
},
1042+
"transitAccessibilityMapComparison": {
1043+
"IntersectionLocationColor": "Intersection location color",
1044+
"IntersectionPolygonColor": "Intersection polygon default color",
1045+
"ComparisonLocationNColor": "Comparison location {{locationNumber}} color",
1046+
"ComparisonPolygonNColor": "Comparison polygon {{polygonNumber}} default color"
10351047
}
10361048
},
10371049
"documentationTooltip": {

locales/fr/transit.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,17 +773,23 @@
773773
"accessibilityComparison": {
774774
"Title": "Comparaison de cartes d'accessibilité",
775775
"Legend": "Légende",
776+
"ScenarioNPolygon": "Polygone du scénario {{scenarioNumber}}",
777+
"ScenarioLocation": "Lieu des scénarios",
776778
"ScenarioIntersection": "Intersection des scénarios",
779+
"ScenarioIntersectionPolygon": "Polygone de l'intersection des scénarios",
777780
"LocationIntersection": "Intersection des lieux",
781+
"LocationIntersectionPolygon": "Polygone de l'intersection des lieux",
778782
"LocationN": "Lieu {{locationNumber}}",
783+
"LocationNPolygon": "Polygone du lieu {{locationNumber}}",
779784
"Difference": "Différence",
780785
"SelectMaxTime": "Sélectionner le temps maximal à afficher (en minutes)",
781786
"ComparisonByScenario": "Comparaison par scénario",
782787
"ComparisonByLocation": "Comparaison par lieu",
783788
"contextMenu": {
784789
"SetAsLocation1": "Définir comme le Lieu 1",
785790
"SetAsLocation2": "Définir comme le Lieu 2"
786-
}
791+
},
792+
"Colors": "Couleurs"
787793
},
788794
"gtfs": {
789795
"ButtonImport": "Importer",
@@ -1032,6 +1038,12 @@
10321038
"transitAccessibilityMap": {
10331039
"LocationColor": "Couleur du lieu",
10341040
"PolygonColor": "Couleur par défaut du polygone d'accessibilité"
1041+
},
1042+
"transitAccessibilityMapComparison": {
1043+
"IntersectionLocationColor": "Couleur du lieu d'intersection",
1044+
"IntersectionPolygonColor": "Couleur par défaut du polygone d'intersection",
1045+
"ComparisonLocationNColor": "Couleur du lieu de comparaison {{locationNumber}}",
1046+
"ComparisonPolygonNColor": "Couleur par défaut du polygone de comparaison {{polygonNumber}}"
10351047
}
10361048
},
10371049
"documentationTooltip": {

packages/chaire-lib-common/src/config/defaultPreferences.config.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,8 +390,14 @@ const defaultPreferences: PreferencesModel = {
390390
walkingSpeedMps: 1.3888888888,
391391
walkingSpeedFactor: 1.0, // walking travel times are weighted using this factor: Example: > 1.0 means faster walking, < 1.0 means slower walking
392392
maxTotalTravelTimeSeconds: 1800,
393-
locationColor: 'rgba(47, 138, 243, 1.0)',
393+
locationColor: 'rgba(47, 138, 243, 1)',
394394
polygonColor: 'rgba(47, 138, 243, 0.4)',
395+
intersectionLocationColor: 'rgba(47, 138, 243, 1)',
396+
intersectionPolygonColor: 'rgba(47, 138, 243, 0.6)',
397+
comparisonLocation1Color: 'rgba(252, 208, 89, 1)',
398+
comparisonPolygon1Color: 'rgba(252, 208, 89, 0.6)',
399+
comparisonLocation2Color: 'rgba(231, 74, 184, 1)',
400+
comparisonPolygon2Color: 'rgba(231, 74, 184, 0.6)',
395401
calculatePois: false,
396402
calculatePopulation: false
397403
},

packages/transition-frontend/src/components/forms/accessibilityComparison/AccessibilityComparisonForm.tsx

Lines changed: 80 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import moment from 'moment';
1818
import Loader from 'react-spinners/BeatLoader';
1919
import { featureCollection as turfFeatureCollection } from '@turf/turf';
2020
import maplibregl from 'maplibre-gl';
21+
import { FeatureCollection } from 'geojson';
2122

2223
import InputString from 'chaire-lib-frontend/lib/components/input/InputString';
2324
import InputStringFormatted from 'chaire-lib-frontend/lib/components/input/InputStringFormatted';
@@ -26,38 +27,41 @@ import InputRadio from 'chaire-lib-frontend/lib/components/input/InputRadio';
2627
import InputWrapper from 'chaire-lib-frontend/lib/components/input/InputWrapper';
2728
import Button from 'chaire-lib-frontend/lib/components/input/Button';
2829
import { default as FormErrors } from 'chaire-lib-frontend/lib/components/pageParts/FormErrors';
30+
import DownloadsUtils from 'chaire-lib-frontend/lib/services/DownloadsService';
31+
import { ChangeEventsForm, ChangeEventsState } from 'chaire-lib-frontend/lib/components/forms/ChangeEventsForm';
32+
import LoadingPage from 'chaire-lib-frontend/lib/components/pages/LoadingPage';
33+
import { MapUpdateLayerEventType } from 'chaire-lib-frontend/lib/services/map/events/MapEventsCallbacks';
34+
2935
import Preferences from 'chaire-lib-common/lib/config/Preferences';
3036
import { TranslatableMessage } from 'chaire-lib-common/lib/utils/TranslatableMessage';
31-
import TransitAccessibilityMapRouting, {
32-
MAX_DELTA_MINUTES,
33-
MAX_DELTA_INTERVAL_MINUTES,
34-
MIN_WALKING_SPEED_KPH,
35-
MAX_WALKING_SPEED_KPH
36-
} from 'transition-common/lib/services/accessibilityMap/TransitAccessibilityMapRouting';
37-
import { calculateAccessibilityMap, calculateAccessibilityMapComparison } from '../../../services/routing/RoutingUtils';
38-
import { TransitAccessibilityMapWithPolygonResult } from 'transition-common/lib/services/accessibilityMap/TransitAccessibilityMapResult';
3937
import { mpsToKph, kphToMps } from 'chaire-lib-common/lib/utils/PhysicsUtils';
4038
import { roundToDecimals } from 'chaire-lib-common/lib/utils/MathUtils';
4139
import serviceLocator from 'chaire-lib-common/lib/utils/ServiceLocator';
42-
import DownloadsUtils from 'chaire-lib-frontend/lib/services/DownloadsService';
43-
import { ChangeEventsForm, ChangeEventsState } from 'chaire-lib-frontend/lib/components/forms/ChangeEventsForm';
44-
import LoadingPage from 'chaire-lib-frontend/lib/components/pages/LoadingPage';
4540
import { _toInteger } from 'chaire-lib-common/lib/utils/LodashExtensions';
4641
import { _toBool } from 'chaire-lib-common/lib/utils/LodashExtensions';
4742
import {
4843
secondsSinceMidnightToTimeStr,
4944
secondsToMinutes,
5045
minutesToSeconds
5146
} from 'chaire-lib-common/lib/utils/DateTimeUtils';
47+
import { EventManager } from 'chaire-lib-common/lib/services/events/EventManager';
48+
49+
import TransitAccessibilityMapRouting, {
50+
MAX_DELTA_MINUTES,
51+
MAX_DELTA_INTERVAL_MINUTES,
52+
MIN_WALKING_SPEED_KPH,
53+
MAX_WALKING_SPEED_KPH
54+
} from 'transition-common/lib/services/accessibilityMap/TransitAccessibilityMapRouting';
55+
import { TransitAccessibilityMapWithPolygonResult } from 'transition-common/lib/services/accessibilityMap/TransitAccessibilityMapResult';
56+
57+
import { calculateAccessibilityMap, calculateAccessibilityMapComparison } from '../../../services/routing/RoutingUtils';
5258
import AccessibilityComparisonStatsComponent from './AccessibilityComparisonStatsComponent';
53-
import * as AccessibilityComparisonConstants from './accessibilityComparisonConstants';
5459
import { comparisonModes } from './comparisonModes';
5560
import AccessibilityMapCoordinatesComponent from '../accessibilityMap/widgets/AccessibilityMapCoordinateComponent';
5661
import TimeOfTripComponent from '../transitRouting/widgets/TimeOfTripComponent';
5762
import TransitRoutingBaseComponent from '../transitRouting/widgets/TransitRoutingBaseComponent';
58-
import { EventManager } from 'chaire-lib-common/lib/services/events/EventManager';
59-
import { MapUpdateLayerEventType } from 'chaire-lib-frontend/lib/services/map/events/MapEventsCallbacks';
60-
import { FeatureCollection } from 'geojson';
63+
import LocationModeColorInfo from './LocationModeColorInfo';
64+
import ScenarioModeColorInfo from './ScenarioModeColorInfo';
6165

6266
export interface AccessibilityComparisonFormProps extends WithTranslation {
6367
addEventListeners?: () => void;
@@ -90,6 +94,12 @@ interface TransitRoutingFormState extends ChangeEventsState<TransitAccessibility
9094
contextMenuRoot: Root | undefined;
9195
alternateScenario1Id?: string;
9296
alternateScenario2Id?: string;
97+
intersectionLocationColor: string;
98+
intersectionPolygonColor: string;
99+
comparisonLocation1Color: string;
100+
comparisonPolygon1Color: string;
101+
comparisonLocation2Color: string;
102+
comparisonPolygon2Color: string;
93103
}
94104

95105
class AccessibilityComparisonForm extends ChangeEventsForm<AccessibilityComparisonFormProps, TransitRoutingFormState> {
@@ -123,14 +133,28 @@ class AccessibilityComparisonForm extends ChangeEventsForm<AccessibilityComparis
123133
alternateScenario1Id: '',
124134
alternateScenario2Id: '',
125135
contextMenu: null,
126-
contextMenuRoot: undefined
136+
contextMenuRoot: undefined,
137+
intersectionLocationColor: Preferences.get(
138+
'transit.routing.transitAccessibilityMap.intersectionLocationColor'
139+
),
140+
intersectionPolygonColor: Preferences.get(
141+
'transit.routing.transitAccessibilityMap.intersectionPolygonColor'
142+
),
143+
comparisonLocation1Color: Preferences.get(
144+
'transit.routing.transitAccessibilityMap.comparisonLocation1Color'
145+
),
146+
comparisonPolygon1Color: Preferences.get('transit.routing.transitAccessibilityMap.comparisonPolygon1Color'),
147+
comparisonLocation2Color: Preferences.get(
148+
'transit.routing.transitAccessibilityMap.comparisonLocation2Color'
149+
),
150+
comparisonPolygon2Color: Preferences.get('transit.routing.transitAccessibilityMap.comparisonPolygon2Color')
127151
};
128152

129153
this.displayMap = this.displayMap.bind(this);
130154
this.calculateRouting = this.calculateRouting.bind(this);
131155
this.onScenarioCollectionUpdate = this.onScenarioCollectionUpdate.bind(this);
132156

133-
routingEngine.updatePointColor(AccessibilityComparisonConstants.INTERSECTION_COLOR);
157+
routingEngine.updatePointColor(this.state.intersectionLocationColor);
134158
if (routingEngine.hasLocation()) {
135159
(serviceLocator.eventManager as EventManager).emitEvent<MapUpdateLayerEventType>('map.updateLayer', {
136160
layerName: 'accessibilityMapPoints',
@@ -175,17 +199,17 @@ class AccessibilityComparisonForm extends ChangeEventsForm<AccessibilityComparis
175199

176200
const numberOfPolygons = routing.attributes.numberOfPolygons as number;
177201

178-
const colors = {
179-
intersectionColor: this.convertToRGBA(AccessibilityComparisonConstants.INTERSECTION_COLOR, 0.6),
180-
scenario1Minus2Color: this.convertToRGBA(AccessibilityComparisonConstants.MAP_1_COLOR, 0.6),
181-
scenario2Minus1Color: this.convertToRGBA(AccessibilityComparisonConstants.MAP_2_COLOR, 0.6)
202+
const polygonColors = {
203+
intersectionColor: this.state.intersectionPolygonColor,
204+
scenario1Minus2Color: this.state.comparisonPolygon1Color,
205+
scenario2Minus1Color: this.state.comparisonPolygon2Color
182206
};
183207

184208
const mapComparison = await calculateAccessibilityMapComparison(
185209
currentResult1.polygons,
186210
currentResult2.polygons,
187211
numberOfPolygons,
188-
colors
212+
polygonColors
189213
);
190214

191215
const finalMap: TransitAccessibilityMapWithPolygonAndTimeResult[] = [];
@@ -498,8 +522,16 @@ class AccessibilityComparisonForm extends ChangeEventsForm<AccessibilityComparis
498522
};
499523
}
500524

501-
private convertToRGBA = (rgbValue: string, alpha: number) => {
502-
return rgbValue.replace(')', `, ${alpha})`).replace('rgb', 'rgba');
525+
// Takes in a color string of the rgba format and returns a new one with the same rgb values but the inputed alpha value.
526+
// Necessary for the stats component. We want to pass the polygons colors as props to color some text in the results table, but the colors for those are transparent, while we want to text to be opaque.
527+
private changeAlphaValue = (rgbaValue: string, alpha: number) => {
528+
const rgbaArray = rgbaValue.split(',');
529+
if (rgbaArray.length !== 4) {
530+
return rgbaValue;
531+
}
532+
533+
rgbaArray[3] = `${alpha})`;
534+
return rgbaArray.join();
503535
};
504536

505537
render() {
@@ -531,31 +563,27 @@ class AccessibilityComparisonForm extends ChangeEventsForm<AccessibilityComparis
531563
return (
532564
<React.Fragment>
533565
<Collapsible
534-
trigger={this.props.t('transit:accessibilityComparison:Legend')}
566+
trigger={this.props.t('transit:accessibilityComparison:Colors')}
535567
open={true}
536568
transitionTime={100}
537569
>
538-
<div className="tr__form-section">
539-
{mode === 'scenarios'
540-
? this.props.t('transit:transitComparison:ScenarioN', { scenarioNumber: '1' })
541-
: this.props.t('transit:accessibilityComparison:LocationN', { locationNumber: '1' })}
542-
: &nbsp;
543-
<span style={{ color: AccessibilityComparisonConstants.MAP_1_COLOR }}>&#9673;</span>
544-
</div>
545-
<div className="tr__form-section">
546-
{mode === 'scenarios'
547-
? this.props.t('transit:transitComparison:ScenarioN', { scenarioNumber: '2' })
548-
: this.props.t('transit:accessibilityComparison:LocationN', { locationNumber: '2' })}
549-
: &nbsp;
550-
<span style={{ color: AccessibilityComparisonConstants.MAP_2_COLOR }}>&#9673;</span>
551-
</div>
552-
<div className="tr__form-section">
553-
{this.props.t(
554-
`transit:accessibilityComparison:${mode === 'scenarios' ? 'Scenario' : 'Location'}Intersection`
555-
)}
556-
: &nbsp;
557-
<span style={{ color: AccessibilityComparisonConstants.INTERSECTION_COLOR }}>&#9673;</span>
558-
</div>
570+
{mode === 'scenarios' && (
571+
<ScenarioModeColorInfo
572+
intersectionLocationColor={this.state.intersectionLocationColor}
573+
intersectionPolygonColor={this.state.intersectionPolygonColor}
574+
comparisonPolygon1Color={this.state.comparisonPolygon1Color}
575+
comparisonPolygon2Color={this.state.comparisonPolygon2Color}
576+
/>
577+
)}
578+
{mode === 'locations' && (
579+
<LocationModeColorInfo
580+
intersectionPolygonColor={this.state.intersectionPolygonColor}
581+
comparisonLocation1Color={this.state.comparisonLocation1Color}
582+
comparisonPolygon1Color={this.state.comparisonPolygon1Color}
583+
comparisonLocation2Color={this.state.comparisonLocation2Color}
584+
comparisonPolygon2Color={this.state.comparisonPolygon2Color}
585+
/>
586+
)}
559587
</Collapsible>
560588

561589
<Collapsible trigger={this.props.t('form:basicFields')} open={true} transitionTime={100}>
@@ -951,6 +979,8 @@ class AccessibilityComparisonForm extends ChangeEventsForm<AccessibilityComparis
951979
<AccessibilityComparisonStatsComponent
952980
accessibilityPolygons={this.state.currentPolygons}
953981
mode={mode}
982+
color1={this.changeAlphaValue(this.state.comparisonPolygon1Color, 1)}
983+
color2={this.changeAlphaValue(this.state.comparisonPolygon2Color, 1)}
954984
/>
955985
</React.Fragment>
956986
)}
@@ -968,8 +998,8 @@ class AccessibilityComparisonForm extends ChangeEventsForm<AccessibilityComparis
968998
const value = comparisonModes[index];
969999
this.onValueChange('selectedMode', { value });
9701000
if (value === 'scenarios') {
971-
routing.updatePointColor(AccessibilityComparisonConstants.INTERSECTION_COLOR);
972-
alternateRouting.updatePointColor(AccessibilityComparisonConstants.INTERSECTION_COLOR);
1001+
routing.updatePointColor(this.state.intersectionLocationColor);
1002+
alternateRouting.updatePointColor(this.state.intersectionLocationColor);
9731003
if (routing.hasLocation()) {
9741004
alternateRouting.setLocation(
9751005
routing.attributes.locationGeojson!.geometry.coordinates
@@ -983,8 +1013,8 @@ class AccessibilityComparisonForm extends ChangeEventsForm<AccessibilityComparis
9831013
);
9841014
}
9851015
} else if (value === 'locations') {
986-
routing.updatePointColor(AccessibilityComparisonConstants.MAP_1_COLOR);
987-
alternateRouting.updatePointColor(AccessibilityComparisonConstants.MAP_2_COLOR);
1016+
routing.updatePointColor(this.state.comparisonLocation1Color);
1017+
alternateRouting.updatePointColor(this.state.comparisonLocation2Color);
9881018
alternateRouting.attributes.scenarioId = routing.attributes.scenarioId;
9891019
if (routing.hasLocation()) {
9901020
alternateRouting.setLocation(

0 commit comments

Comments
 (0)