();
- public get isTopTrainrunSectionInfoDisplayed(): boolean {
- if (this.selectedTrainrunSection === null) {
- return false;
- }
- const isTargetRightOrBottom = TrainrunsectionHelper.isTargetRightOrBottom(
+ public get isSymmetric(): boolean {
+ const firstTrainrunSection = this.trainrunService.getFirstNonStopTrainrunSection(
this.selectedTrainrunSection,
);
- return this.isRoundTrip() || isTargetRightOrBottom;
- }
-
- public get isBottomTrainrunSectionInfoDisplayed(): boolean {
- if (this.selectedTrainrunSection === null) {
- return false;
- }
- const isTargetRightOrBottom = TrainrunsectionHelper.isTargetRightOrBottom(
- this.selectedTrainrunSection,
+ const iterator = this.trainrunService.getNonStopIterator(
+ firstTrainrunSection.getSourceNode(),
+ firstTrainrunSection,
);
- return this.isRoundTrip() || !isTargetRightOrBottom;
+ while (iterator.hasNext()) {
+ const nextPair = iterator.next();
+ if (!nextPair.trainrunSection.isSymmetric()) {
+ return false;
+ }
+ }
+ return true;
}
constructor(
private dataService: DataService,
private filterService: FilterService,
- private trainrunService: TrainrunService,
+ public trainrunService: TrainrunService,
private trainrunSectionService: TrainrunSectionService,
- private changeDetection: ChangeDetectorRef,
+ private changeDetectionRef: ChangeDetectorRef,
public trainrunSectionTimesService: TrainrunSectionTimesService,
private versionControlService: VersionControlService,
+ private symmetryToggleService: SymmetryToggleService,
) {
this.trainrunSectionHelper = new TrainrunsectionHelper(this.trainrunService);
@@ -137,6 +143,7 @@ export class TrainrunSectionTabComponent implements AfterViewInit, OnDestroy {
.getTrainrun()
.getTimeCategoryLinePatternRef();
this.trainrunSectionTimesService.setHighlightTravelTimeElement(false);
+ this.trainrunSectionTimesService.setHighlightBottomTravelTimeElement(false);
this.numberOfStops = this.selectedTrainrunSection.getNumberOfStops();
this.trainrunSectionTimesService.applyOffsetAndTransformTimeStructure();
@@ -180,7 +187,7 @@ export class TrainrunSectionTabComponent implements AfterViewInit, OnDestroy {
this.setFocusToUIElement(focusElement);
this.updateAllValues();
- this.changeDetection.detectChanges();
+ this.changeDetectionRef.detectChanges();
}
getContentClassTag(): string {
@@ -216,6 +223,9 @@ export class TrainrunSectionTabComponent implements AfterViewInit, OnDestroy {
case LeftAndRightElement.TravelTime:
this.setFocusAndSelectInputElement(this.travelTimeInputElement.nativeElement);
break;
+ case LeftAndRightElement.BottomTravelTime:
+ this.setFocusAndSelectInputElement(this.bottomTravelTimeInputElement.nativeElement);
+ break;
}
}
@@ -223,7 +233,7 @@ export class TrainrunSectionTabComponent implements AfterViewInit, OnDestroy {
setTimeout(() => {
element.focus();
element.select();
- }, 800);
+ }, 100);
}
getEdgeLineClassAttrString(layer: number) {
@@ -251,12 +261,15 @@ export class TrainrunSectionTabComponent implements AfterViewInit, OnDestroy {
);
}
- getArrowTranslateAndRotate() {
- if (this.isTopTrainrunSectionInfoDisplayed && !this.isBottomTrainrunSectionInfoDisplayed) {
+ getDirectionArrowTranslateAndRotate() {
+ if (
+ !TrainrunsectionHelper.isLeftSideDisplayed(this.selectedTrainrunSection) &&
+ TrainrunsectionHelper.isRightSideDisplayed(this.selectedTrainrunSection)
+ ) {
return "translate(60, 16) rotate(0)";
} else if (
- !this.isTopTrainrunSectionInfoDisplayed &&
- this.isBottomTrainrunSectionInfoDisplayed
+ TrainrunsectionHelper.isLeftSideDisplayed(this.selectedTrainrunSection) &&
+ !TrainrunsectionHelper.isRightSideDisplayed(this.selectedTrainrunSection)
) {
return "translate(60, 16) rotate(180)";
}
@@ -286,6 +299,7 @@ export class TrainrunSectionTabComponent implements AfterViewInit, OnDestroy {
onInputNumberOfStopsElementButtonPlus() {
this.numberOfStops += 1;
this.trainrunSectionTimesService.setHighlightTravelTimeElement(false);
+ this.trainrunSectionTimesService.setHighlightBottomTravelTimeElement(false);
this.onNumberOfStopsChanged();
}
@@ -311,6 +325,60 @@ export class TrainrunSectionTabComponent implements AfterViewInit, OnDestroy {
return "NumberOfStopsInputElement" + activeTag;
}
+ getTravelTimeScssClass(): string {
+ if (this.isSymmetric) {
+ // If symmetric, travel time is displayed at the center
+ return "";
+ }
+ // If not symmetric, travel time is displayed at the top
+ // (and bottom travel time at the bottom)
+ return "Top";
+ }
+
+ onLeftNodeSymmetryToggleChanged(symmetry: boolean) {
+ const originalState = this.trainrunSectionHelper.isLeftNextStopNodeSymmetric(
+ this.selectedTrainrunSection,
+ this.trainrunSectionTimesService.getNodesOrdered(),
+ );
+ this.symmetryToggleService.onLeftNodeSymmetryToggleChanged(
+ this.selectedTrainrunSection,
+ this.trainrunSectionTimesService,
+ symmetry,
+ () => {
+ // Revert the toggle state
+ if (this.leftSymmetryToggle) {
+ this.leftSymmetryToggle.checked = !originalState;
+ }
+ this.changeDetectionRef.detectChanges();
+ },
+ );
+ }
+
+ onRightNodeSymmetryToggleChanged(symmetry: boolean) {
+ const originalState = this.trainrunSectionHelper.isRightNextStopNodeSymmetric(
+ this.selectedTrainrunSection,
+ this.trainrunSectionTimesService.getNodesOrdered(),
+ );
+ this.symmetryToggleService.onRightNodeSymmetryToggleChanged(
+ this.selectedTrainrunSection,
+ this.trainrunSectionTimesService,
+ symmetry,
+ () => {
+ // Revert the toggle state
+ if (this.rightSymmetryToggle) {
+ this.rightSymmetryToggle.checked = !originalState;
+ }
+ this.changeDetectionRef.detectChanges();
+ },
+ );
+ }
+
+ isTrainrunSymmetric() {
+ return this.trainrunSectionService.isTrainrunSymmetric(
+ this.selectedTrainrunSection.getTrainrunId(),
+ );
+ }
+
private resetOffsetAfterTrainrunChanged() {
if (this.trainrunSectionTimesService.getOffsetTransformationActive()) {
this.trainrunSectionTimesService.removeOffsetAndBackTransformTimeStructure();
@@ -337,8 +405,4 @@ export class TrainrunSectionTabComponent implements AfterViewInit, OnDestroy {
this.trainrunSectionTimesService.setOffset(this.trainrunDialogParameter.offset);
}
}
-
- private isRoundTrip() {
- return this.selectedTrainrunSection.getTrainrun().isRoundTrip();
- }
}
diff --git a/src/app/view/editor-filter-view/editor-filter-view.component.html b/src/app/view/editor-filter-view/editor-filter-view.component.html
index 462f9c4af..7cc88aa54 100644
--- a/src/app/view/editor-filter-view/editor-filter-view.component.html
+++ b/src/app/view/editor-filter-view/editor-filter-view.component.html
@@ -54,20 +54,33 @@ {{ "app.view.editor-filter-view.filter" | translate }}<
-
+
{{
"app.view.editor-filter-view.symmetry" | translate
}}
-
+
+
+
+
+
+
@@ -158,6 +171,14 @@
{{ "app.view.editor-filter-view.filter" | translate }}<
{{ "app.view.editor-filter-view.display-direction-arrows" | translate }}
+ {{ "app.view.editor-filter-view.display-asymmetry-arrows" | translate }}
+
+ {{ "app.view.editor-filter-view.display-backward-travel-times" | translate }}
+
diff --git a/src/app/view/editor-filter-view/editor-filter-view.component.ts b/src/app/view/editor-filter-view/editor-filter-view.component.ts
index 29b4e891f..c35e8a746 100644
--- a/src/app/view/editor-filter-view/editor-filter-view.component.ts
+++ b/src/app/view/editor-filter-view/editor-filter-view.component.ts
@@ -25,9 +25,11 @@ export class EditorFilterViewComponent implements OnInit, OnDestroy {
filterNotes: boolean;
filterAllNonStopNodes: boolean;
filterDirectionArrows: boolean;
+ filterAsymmetryArrows: boolean;
filterArrivalDepartureTime: boolean;
filterShowNonStopTime: boolean;
filterTravelTime: boolean;
+ filterBackwardTravelTime: boolean;
filterTrainrunName: boolean;
filterConnections: boolean;
timeDisplayPrecision: number;
@@ -68,9 +70,11 @@ export class EditorFilterViewComponent implements OnInit, OnDestroy {
updateFilterData() {
this.filterDirectionArrows = this.filterService.isFilterDirectionArrowsEnabled();
+ this.filterAsymmetryArrows = this.filterService.isFilterAsymmetryArrowsEnabled();
this.filterArrivalDepartureTime = this.filterService.isFilterArrivalDepartureTimeEnabled();
this.filterShowNonStopTime = this.filterService.isFilterShowNonStopTimeEnabled();
this.filterTravelTime = this.filterService.isFilterTravelTimeEnabled();
+ this.filterBackwardTravelTime = this.filterService.isFilterBackwardTravelTimeEnabled();
this.filterTrainrunName = this.filterService.isFilterTrainrunNameEnabled();
this.filterConnections = this.filterService.isFilterConnectionsEnabled();
this.filterNotes = !this.filterService.isFilterNotesEnabled();
@@ -210,6 +214,14 @@ export class EditorFilterViewComponent implements OnInit, OnDestroy {
}
}
+ filterAsymmetryArrowsChanged() {
+ if (this.filterAsymmetryArrows) {
+ this.filterService.enableFilterAsymmetryArrows();
+ } else {
+ this.filterService.disableFilterAsymmetryArrows();
+ }
+ }
+
filterArrivalDepartureTimeChanged() {
if (this.filterArrivalDepartureTime) {
this.filterService.enableFilterArrivalDepartureTime();
@@ -234,6 +246,14 @@ export class EditorFilterViewComponent implements OnInit, OnDestroy {
}
}
+ filterBackwardTravelTimeChanged() {
+ if (this.filterBackwardTravelTime) {
+ this.filterService.enableFilterBackwardTravelTime();
+ } else {
+ this.filterService.disableFilterBackwardTravelTime();
+ }
+ }
+
filterTrainrunNameChanged() {
if (this.filterTrainrunName) {
this.filterService.enableFilterTrainrunName();
@@ -293,6 +313,13 @@ export class EditorFilterViewComponent implements OnInit, OnDestroy {
return "TrainrunDialog Direction ";
}
+ getSymmetryClassname(symmetry: boolean): string {
+ if (this.filterService.isFilterSymmetryEnabled(symmetry)) {
+ return "TrainrunDialog Symmetry " + StaticDomTags.TAG_SELECTED;
+ }
+ return "TrainrunDialog Symmetry ";
+ }
+
hasOneWayTrainruns(): boolean {
for (const trainrun of this.dataService.getTrainruns()) {
if (!trainrun.isRoundTrip()) return true;
@@ -300,6 +327,13 @@ export class EditorFilterViewComponent implements OnInit, OnDestroy {
return false;
}
+ isAsymmetryActive(): boolean {
+ for (const section of this.dataService.getTrainrunSections()) {
+ if (!section.isSymmetric()) return true;
+ }
+ return false;
+ }
+
getCategoryTooltip(trainrunCategory: TrainrunCategory): string {
if (!this.filterService.isFilterTrainrunCategoryEnabled(trainrunCategory)) {
return $localize`:@@app.view.editor-filter-view.show-trainrun-category:Show ${trainrunCategory.name}:trainrunCategory:`;
@@ -335,6 +369,13 @@ export class EditorFilterViewComponent implements OnInit, OnDestroy {
return $localize`:@@app.view.editor-filter-view.hide-direction:Hide ${directionTranslation}:direction:`;
}
+ getSymmetryTooltip(symmetry: boolean): string {
+ if (!this.filterService.isFilterSymmetryEnabled(symmetry)) {
+ return $localize`:@@app.view.editor-filter-view.show-asymmetric-trainruns:Show asymmetric trainruns`;
+ }
+ return $localize`:@@app.view.editor-filter-view.hide-asymmetric-trainruns:Hide asymmetric trainruns`;
+ }
+
makeCategoryButtonLabel(trainrunCategory: TrainrunCategory): string {
const label = trainrunCategory.shortName.toUpperCase();
if (label.length > 4) {
@@ -359,6 +400,14 @@ export class EditorFilterViewComponent implements OnInit, OnDestroy {
}
}
+ makeSymmetryButtonLabel(symmetry: boolean): string {
+ if (symmetry) {
+ return $localize`:@@app.view.editor-filter-view.symmetric-short:Sym.`;
+ } else {
+ return $localize`:@@app.view.editor-filter-view.asymmetric-short:Asym.`;
+ }
+ }
+
onCategoryChanged(trainrunCategory: TrainrunCategory) {
if (!this.filterService.isFilterTrainrunCategoryEnabled(trainrunCategory)) {
this.filterService.enableFilterTrainrunCategory(trainrunCategory);
@@ -383,6 +432,14 @@ export class EditorFilterViewComponent implements OnInit, OnDestroy {
}
}
+ onSymmetryChanged(symmetry: boolean) {
+ if (!this.filterService.isFilterSymmetryEnabled(symmetry)) {
+ this.filterService.enableFilterSymmetry(symmetry);
+ } else {
+ this.filterService.disableFilterSymmetry(symmetry);
+ }
+ }
+
isFilterFunctionOrEnabled(labelGroupObject: LabelGroup): boolean {
return labelGroupObject.getLogicalFilterOperator() === LogicalFilterOperator.OR;
}
@@ -427,6 +484,7 @@ export class EditorFilterViewComponent implements OnInit, OnDestroy {
this.filterService.resetFilterTrainrunFrequency();
this.filterService.resetFilterTrainrunTimeCategory();
this.filterService.resetFilterDirection();
+ this.filterService.resetFilterSymmetry();
}
onResetNodeFilter() {
@@ -445,14 +503,18 @@ export class EditorFilterViewComponent implements OnInit, OnDestroy {
this.onResetNodeFilter();
this.onResetNoteFilter();
this.filterService.enableFilterDirectionArrows();
+ this.filterService.enableFilterAsymmetryArrows();
this.filterService.enableFilterArrivalDepartureTime();
this.filterService.enableFilterTravelTime();
+ this.filterService.enableFilterBackwardTravelTime();
this.filterService.enableFilterTrainrunName();
this.filterService.enableFilterShowNonStopTime();
this.filterService.enableFilterConnections();
this.filterDirectionArrows = this.filterService.isFilterDirectionArrowsEnabled();
+ this.filterAsymmetryArrows = this.filterService.isFilterAsymmetryArrowsEnabled();
this.filterArrivalDepartureTime = this.filterService.isFilterArrivalDepartureTimeEnabled();
this.filterTravelTime = this.filterService.isFilterTravelTimeEnabled();
+ this.filterBackwardTravelTime = this.filterService.isFilterBackwardTravelTimeEnabled();
this.filterTrainrunName = this.filterService.isFilterTrainrunNameEnabled();
this.filterConnections = this.filterService.isFilterConnectionsEnabled();
this.filterShowNonStopTime = this.filterService.isFilterShowNonStopTimeEnabled();
diff --git a/src/app/view/editor-main-view/data-views/data.view.spec.ts b/src/app/view/editor-main-view/data-views/data.view.spec.ts
index 4d3579884..736dce26a 100644
--- a/src/app/view/editor-main-view/data-views/data.view.spec.ts
+++ b/src/app/view/editor-main-view/data-views/data.view.spec.ts
@@ -226,9 +226,11 @@ describe("Editor-DataView", () => {
false,
false,
false,
+ false,
+ false,
);
expect(cvo1.key).toBe(
- "#3@1234_false_0_39_49_1_21_39_0_39_141_39_0_39_0_20_0_S_20_7/24_4_1_0_S_20_7/24_20_0_round_trip_false_false_false_false_false_false_false_false_false_true_true_true_false_false_true_true_true_0_false_2_true_true_true_1_false_true_true_0_false_true_true(130,80)(194,80)(254,80)(318,80)",
+ "#3@1234_false_0_39_49_39_undefined_1_21_39_0_39_141_39_0_39_0_20_0_S_20_7/24_4_1_0_S_20_7/24_20_0_round_trip_false_false_false_false_false_false_false_false_false_false_false_true_true_true_false_false_true_true_true_0_false_2_true_true_true_1_false_true_true_0_false_true_true_0_false_true_true_1_false_true_true_2_true_true_true(130,80)(194,80)(254,80)(318,80)",
);
});
diff --git a/src/app/view/editor-main-view/data-views/editor.view.ts b/src/app/view/editor-main-view/data-views/editor.view.ts
index 3ec5b1835..a36cb9632 100644
--- a/src/app/view/editor-main-view/data-views/editor.view.ts
+++ b/src/app/view/editor-main-view/data-views/editor.view.ts
@@ -67,6 +67,8 @@ export class EditorView implements SVGMouseControllerObserver {
getSelectedTrainrun = null;
getCumulativeTravelTime = null;
getCumulativeTravelTimeAndNodePath = null;
+ getCumulativeBackwardTravelTime = null;
+ getCumulativeBackwardTravelTimeAndNodePath = null;
unselectAllTrainruns = null;
isAnyTrainSelected = null;
getConnectedTrainrunIds = null;
@@ -76,8 +78,10 @@ export class EditorView implements SVGMouseControllerObserver {
combineTwoTrainruns = null;
getNodeFromConnection = null;
isFilterTravelTimeEnabled = null;
+ isFilterBackwardTravelTimeEnabled = null;
isFilterTrainrunNameEnabled = null;
isFilterDirectionArrowsEnabled = null;
+ isFilterAsymmetryArrowsEnabled = null;
isFilterArrivalDepartureTimeEnabled = null;
isFilterShowNonStopTimeEnabled = null;
isFilterTrainrunCategoryEnabled = null;
@@ -240,10 +244,18 @@ export class EditorView implements SVGMouseControllerObserver {
this.getCumulativeTravelTime = callback;
}
+ bindGetCumulativeBackwardTravelTime(callback) {
+ this.getCumulativeBackwardTravelTime = callback;
+ }
+
bindGetCumulativeTravelTimeAndNodePath(callback) {
this.getCumulativeTravelTimeAndNodePath = callback;
}
+ bindGetCumulativeBackwardTravelTimeAndNodePath(callback) {
+ this.getCumulativeBackwardTravelTimeAndNodePath = callback;
+ }
+
bindUnselectAllTrainruns(callback) {
this.unselectAllTrainruns = callback;
}
@@ -280,6 +292,10 @@ export class EditorView implements SVGMouseControllerObserver {
this.isFilterTravelTimeEnabled = callback;
}
+ bindIsFilterBackwardTravelTimeEnabled(callback) {
+ this.isFilterBackwardTravelTimeEnabled = callback;
+ }
+
bindIsfilterTrainrunNameEnabled(callback) {
this.isFilterTrainrunNameEnabled = callback;
}
@@ -288,6 +304,10 @@ export class EditorView implements SVGMouseControllerObserver {
this.isFilterDirectionArrowsEnabled = callback;
}
+ bindIsFilterAsymmetryArrowsEnabled(callback) {
+ this.isFilterAsymmetryArrowsEnabled = callback;
+ }
+
bindIsfilterArrivalDepartureTimeEnabled(callback) {
this.isFilterArrivalDepartureTimeEnabled = callback;
}
diff --git a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts
index 73e221407..cd7035623 100644
--- a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts
+++ b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts
@@ -12,9 +12,11 @@ export class TrainrunSectionViewObject {
isMuted: boolean,
hiddenTagSource: boolean,
hiddenTagTarget: boolean,
- hiddenTagTraveltime: boolean,
+ hiddenTagTravelTime: boolean,
+ hiddenTagBackwardTravelTime: boolean,
hiddenTagTrainrunName: boolean,
hiddenTagDirectionArrows: boolean,
+ hiddenTagAsymmetryArrows: boolean,
) {
this.key = TrainrunSectionViewObject.generateKey(
editorView,
@@ -24,9 +26,11 @@ export class TrainrunSectionViewObject {
isMuted,
hiddenTagSource,
hiddenTagTarget,
- hiddenTagTraveltime,
+ hiddenTagTravelTime,
+ hiddenTagBackwardTravelTime,
hiddenTagTrainrunName,
hiddenTagDirectionArrows,
+ hiddenTagAsymmetryArrows,
);
}
@@ -38,13 +42,19 @@ export class TrainrunSectionViewObject {
isMuted: boolean,
hiddenTagSource: boolean,
hiddenTagTarget: boolean,
- hiddenTagTraveltime: boolean,
+ hiddenTagTravelTime: boolean,
+ hiddenTagBackwardTravelTime: boolean,
hiddenTagTrainrunName: boolean,
hiddenTagDirectionArrows: boolean,
+ hiddenTagAsymmetryArrows: boolean,
): string {
const cumulativeTravelTimeData = editorView.getCumulativeTravelTimeAndNodePath(d);
const cumulativeTravelTime =
cumulativeTravelTimeData[cumulativeTravelTimeData.length - 1].sumTravelTime;
+ const cumulativeBackwardTravelTimeData =
+ editorView.getCumulativeBackwardTravelTimeAndNodePath(d);
+ const cumulativeBackwardTravelTime =
+ cumulativeBackwardTravelTimeData[cumulativeBackwardTravelTimeData.length - 1].sumTravelTime;
let key =
"#" +
@@ -60,6 +70,10 @@ export class TrainrunSectionViewObject {
"_" +
cumulativeTravelTime +
"_" +
+ d.getBackwardTravelTime() +
+ "_" +
+ cumulativeBackwardTravelTime +
+ "_" +
editorView.getTimeDisplayPrecision() +
"_" +
d.getTargetDeparture() +
@@ -118,12 +132,16 @@ export class TrainrunSectionViewObject {
"_" +
hiddenTagTarget +
"_" +
- hiddenTagTraveltime +
+ hiddenTagTravelTime +
+ "_" +
+ hiddenTagBackwardTravelTime +
"_" +
hiddenTagTrainrunName +
"_" +
hiddenTagDirectionArrows +
"_" +
+ hiddenTagAsymmetryArrows +
+ "_" +
editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() +
"_" +
editorView.isFilterShowNonStopTimeEnabled() +
@@ -153,6 +171,13 @@ export class TrainrunSectionViewObject {
key += "_" + editorView.checkFilterNode(data.node);
});
+ cumulativeBackwardTravelTimeData.forEach((data) => {
+ key += "_" + data.node.getId();
+ key += "_" + editorView.isJunctionNode(data.node);
+ key += "_" + editorView.checkFilterNonStopNode(data.node);
+ key += "_" + editorView.checkFilterNode(data.node);
+ });
+
d.getPath().forEach((p) => {
key += p.toString();
});
diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.scss b/src/app/view/editor-main-view/data-views/trainrunsections.view.scss
index 8a76b45f7..513ae8740 100644
--- a/src/app/view/editor-main-view/data-views/trainrunsections.view.scss
+++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.scss
@@ -38,6 +38,11 @@
text-align: left;
}
+::ng-deep text.edge_text.TrainrunSectionBackwardTravelTime {
+ text-anchor: start;
+ text-align: left;
+}
+
::ng-deep text.edge_text.warning {
stroke: $COLOR_Warning;
fill: $COLOR_Warning;
diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts
index b55dc3409..1d522377e 100644
--- a/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts
+++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts
@@ -1241,48 +1241,56 @@ describe("TrainrunSection-View", () => {
const v0 = TrainrunSectionsView.extractTravelTime(
trainrunSectionService.getTrainrunSectionFromId(0),
editorView,
+ false,
);
expect(v0).toBe("10'");
const v1 = TrainrunSectionsView.extractTravelTime(
trainrunSectionService.getTrainrunSectionFromId(1),
editorView,
+ false,
);
expect(v1).toBe("10'");
const v2 = TrainrunSectionsView.extractTravelTime(
trainrunSectionService.getTrainrunSectionFromId(2),
editorView,
+ false,
);
expect(v2).toBe("20'");
const v3 = TrainrunSectionsView.extractTravelTime(
trainrunSectionService.getTrainrunSectionFromId(3),
editorView,
+ false,
);
expect(v3).toBe("49' (39')");
const v4 = TrainrunSectionsView.extractTravelTime(
trainrunSectionService.getTrainrunSectionFromId(4),
editorView,
+ false,
);
expect(v4).toBe("49' (10')");
const v5 = TrainrunSectionsView.extractTravelTime(
trainrunSectionService.getTrainrunSectionFromId(5),
editorView,
+ false,
);
expect(v5).toBe("51'");
const v6 = TrainrunSectionsView.extractTravelTime(
trainrunSectionService.getTrainrunSectionFromId(6),
editorView,
+ false,
);
expect(v6).toBe("10'");
const v7 = TrainrunSectionsView.extractTravelTime(
trainrunSectionService.getTrainrunSectionFromId(7),
editorView,
+ false,
);
expect(v7).toBe("10'");
});
@@ -1296,7 +1304,7 @@ describe("TrainrunSection-View", () => {
const t2 = n2.getTransition(ts.getId());
t1.setIsNonStopTransit(true);
t2.setIsNonStopTransit(true);
- const v0 = TrainrunSectionsView.extractTravelTime(ts, editorView);
+ const v0 = TrainrunSectionsView.extractTravelTime(ts, editorView, false);
expect(v0).toBe("(10')");
});
diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts
index 6b09c99b3..9e129d709 100644
--- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts
+++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts
@@ -160,6 +160,8 @@ export class TrainrunSectionsView {
return trainrunSection.hasTargetArrivalWarning();
case TrainrunSectionText.TrainrunSectionTravelTime:
return trainrunSection.hasTravelTimeWarning();
+ case TrainrunSectionText.TrainrunSectionBackwardTravelTime:
+ return trainrunSection.hasBackwardTravelTimeWarning();
case TrainrunSectionText.TrainrunSectionName:
default:
return false;
@@ -201,11 +203,16 @@ export class TrainrunSectionsView {
": " +
trainrunSection.getTravelTimeWarning().description
);
+ case TrainrunSectionText.TrainrunSectionBackwardTravelTime:
+ return (
+ trainrunSection.getBackwardTravelTimeWarning().title +
+ ": " +
+ trainrunSection.getBackwardTravelTimeWarning().description
+ );
case TrainrunSectionText.TrainrunSectionName:
default:
return "";
}
- return "";
}
static getTime(trainrunSection: TrainrunSection, textElement: TrainrunSectionText): number {
@@ -220,6 +227,8 @@ export class TrainrunSectionsView {
return trainrunSection.getTargetArrival();
case TrainrunSectionText.TrainrunSectionTravelTime:
return trainrunSection.getTravelTime();
+ case TrainrunSectionText.TrainrunSectionBackwardTravelTime:
+ return trainrunSection.getBackwardTravelTime();
default:
return 0;
}
@@ -240,6 +249,8 @@ export class TrainrunSectionsView {
return trainrunSection.getTargetArrivalFormattedDisplayText();
case TrainrunSectionText.TrainrunSectionTravelTime:
return trainrunSection.getTravelTimeFormattedDisplayText();
+ case TrainrunSectionText.TrainrunSectionBackwardTravelTime:
+ return trainrunSection.getBackwardTravelTimeFormattedDisplayText();
default:
return undefined;
}
@@ -260,6 +271,8 @@ export class TrainrunSectionsView {
return trainrunSection.getTargetArrivalFormattedDisplayTextWidth();
case TrainrunSectionText.TrainrunSectionTravelTime:
return trainrunSection.getTravelTimeFormattedDisplayTextWidth();
+ case TrainrunSectionText.TrainrunSectionBackwardTravelTime:
+ return trainrunSection.getBackwardTravelTimeFormattedDisplayTextWidth();
default:
return undefined;
}
@@ -318,6 +331,7 @@ export class TrainrunSectionsView {
case TrainrunSectionText.TargetArrival:
return trainrunSection.getTextPositionX(textElement);
case TrainrunSectionText.TrainrunSectionTravelTime:
+ case TrainrunSectionText.TrainrunSectionBackwardTravelTime:
return RASTERING_BASIC_GRID_SIZE / 4;
case TrainrunSectionText.TrainrunSectionName:
return -RASTERING_BASIC_GRID_SIZE / 4;
@@ -333,9 +347,6 @@ export class TrainrunSectionsView {
case TrainrunSectionText.TargetDeparture:
case TrainrunSectionText.TargetArrival:
return trainrunSection.getTextPositionY(textElement);
- case TrainrunSectionText.TrainrunSectionTravelTime:
- case TrainrunSectionText.TrainrunSectionName:
- return 0.0;
default:
return 0;
}
@@ -349,6 +360,7 @@ export class TrainrunSectionsView {
case TrainrunSectionText.TargetArrival:
return "dy";
case TrainrunSectionText.TrainrunSectionTravelTime:
+ case TrainrunSectionText.TrainrunSectionBackwardTravelTime:
case TrainrunSectionText.TrainrunSectionName:
return "transform";
default:
@@ -367,6 +379,7 @@ export class TrainrunSectionsView {
case TrainrunSectionText.TargetArrival:
return 1.5;
case TrainrunSectionText.TrainrunSectionTravelTime:
+ case TrainrunSectionText.TrainrunSectionBackwardTravelTime:
case TrainrunSectionText.TrainrunSectionName:
return TrainrunSectionsView.translateAndRotateText(trainrunSection, textElement);
default:
@@ -438,6 +451,7 @@ export class TrainrunSectionsView {
)
);
case TrainrunSectionText.TrainrunSectionTravelTime:
+ case TrainrunSectionText.TrainrunSectionBackwardTravelTime:
return timeTag;
case TrainrunSectionText.TrainrunSectionName:
return (
@@ -454,8 +468,9 @@ export class TrainrunSectionsView {
trainrunSection.getTrainrun().getCategoryColorRef(),
)
);
+ default:
+ return undefined;
}
- return undefined;
}
static formatTime(value: number, precision: number): number {
@@ -476,21 +491,34 @@ export class TrainrunSectionsView {
);
}
- static extractTravelTime(trainrunSection: TrainrunSection, editorView: EditorView): string {
- const cumTravelTimeData = editorView.getCumulativeTravelTimeAndNodePath(trainrunSection);
- const cumulativeTravelTime = cumTravelTimeData[cumTravelTimeData.length - 1].sumTravelTime;
+ static extractTravelTime(
+ trainrunSection: TrainrunSection,
+ editorView: EditorView,
+ isBackwardTravel: boolean,
+ ): string {
+ // invert travel times display since departures and arrivals
+ // are also inverted if target is left or top
+ isBackwardTravel = TrainrunsectionHelper.isTargetRightOrBottom(trainrunSection)
+ ? isBackwardTravel
+ : !isBackwardTravel;
+ const travelTime = isBackwardTravel
+ ? trainrunSection.getBackwardTravelTime()
+ : trainrunSection.getTravelTime();
+ const cumTravelTimeData = isBackwardTravel
+ ? editorView.getCumulativeBackwardTravelTimeAndNodePath(trainrunSection)
+ : editorView.getCumulativeTravelTimeAndNodePath(trainrunSection);
+ const cumulativeTravelTime = isBackwardTravel
+ ? cumTravelTimeData[cumTravelTimeData.length - 1].sumBackwardTravelTime
+ : cumTravelTimeData[cumTravelTimeData.length - 1].sumTravelTime;
if (
trainrunSection.getTrainrun().selected() === true ||
editorView.isFilterShowNonStopTimeEnabled() ||
editorView.isTemporaryDisableFilteringOfItemsInViewEnabled()
) {
- if (cumulativeTravelTime === trainrunSection.getTravelTime()) {
+ if (cumulativeTravelTime === travelTime) {
// default case
return (
- TrainrunSectionsView.formatTime(
- trainrunSection.getTravelTime(),
- editorView.getTimeDisplayPrecision(),
- ) + "'"
+ TrainrunSectionsView.formatTime(travelTime, editorView.getTimeDisplayPrecision()) + "'"
);
} else {
// special case - with non stops
@@ -631,7 +659,7 @@ export class TrainrunSectionsView {
}
if (TrainrunSectionsView.isBothSideNonStop(trainrunSection)) {
- return "(" + TrainrunSectionsView.formatTime(trainrunSection.getTravelTime(), 1) + "')";
+ return "(" + TrainrunSectionsView.formatTime(travelTime, 1) + "')";
}
// default case for non stops
return (
@@ -640,7 +668,7 @@ export class TrainrunSectionsView {
editorView.getTimeDisplayPrecision(),
) +
"' (" +
- TrainrunSectionsView.formatTime(trainrunSection.getTravelTime(), 1) +
+ TrainrunSectionsView.formatTime(travelTime, 1) +
"')"
);
}
@@ -751,17 +779,24 @@ export class TrainrunSectionsView {
editorView.getTimeDisplayPrecision(),
);
}
- case TrainrunSectionText.TrainrunSectionTravelTime: {
+ case TrainrunSectionText.TrainrunSectionTravelTime:
+ case TrainrunSectionText.TrainrunSectionBackwardTravelTime: {
const data = TrainrunSectionsView.getFormattedDisplayText(trainrunSection, textElement);
if (data !== undefined) {
+ console.log("textElement", textElement, "data", data);
return data;
}
- return TrainrunSectionsView.extractTravelTime(trainrunSection, editorView);
+ return TrainrunSectionsView.extractTravelTime(
+ trainrunSection,
+ editorView,
+ textElement === TrainrunSectionText.TrainrunSectionBackwardTravelTime,
+ );
}
case TrainrunSectionText.TrainrunSectionName:
return TrainrunSectionsView.extractTrainrunName(trainrunSection);
+ default:
+ return undefined;
}
- return undefined;
}
static getTrainrunSectionValueTextWidth(
@@ -773,7 +808,8 @@ export class TrainrunSectionsView {
case TrainrunSectionText.SourceArrival:
case TrainrunSectionText.TargetDeparture:
case TrainrunSectionText.TargetArrival:
- case TrainrunSectionText.TrainrunSectionTravelTime: {
+ case TrainrunSectionText.TrainrunSectionTravelTime:
+ case TrainrunSectionText.TrainrunSectionBackwardTravelTime: {
const data = TrainrunSectionsView.getFormattedDisplayTextWidth(
trainrunSection,
textElement,
@@ -783,8 +819,9 @@ export class TrainrunSectionsView {
}
return TRAINRUN_SECTION_TEXT_AREA_WIDTH;
}
+ default:
+ return TRAINRUN_SECTION_TEXT_AREA_WIDTH;
}
- return TRAINRUN_SECTION_TEXT_AREA_WIDTH;
}
static getTrainrunSectionValueHtmlStyle(
@@ -802,10 +839,11 @@ export class TrainrunSectionsView {
return trainrunSection.getTargetArrivalFormattedDisplayHtmlStyle();
case TrainrunSectionText.TrainrunSectionTravelTime:
return trainrunSection.getTravelTimeFormattedDisplayHtmlStyle();
+ case TrainrunSectionText.TrainrunSectionBackwardTravelTime:
+ return trainrunSection.getBackwardTravelTimeFormattedDisplayHtmlStyle();
default:
return undefined;
}
- return undefined;
}
static getTrainrunSectionNextAndDestinationNodeToShow(
@@ -845,6 +883,8 @@ export class TrainrunSectionsView {
return trainrunSection.getTargetArrivalFormatterColorRef();
case TrainrunSectionText.TrainrunSectionTravelTime:
return trainrunSection.getTravelTimeFormatterColorRef();
+ case TrainrunSectionText.TrainrunSectionBackwardTravelTime:
+ return trainrunSection.getBackwardTravelTimeFormatterColorRef();
default:
return undefined;
}
@@ -899,6 +939,17 @@ export class TrainrunSectionsView {
!trainrunSection.getTrainrun().selected() &&
TrainrunSectionsView.isBothSideNonStop(trainrunSection)
);
+ case TrainrunSectionText.TrainrunSectionBackwardTravelTime:
+ if (!trainrunSection.getTrainrun().isRoundTrip() || trainrunSection.isSymmetric()) {
+ return true;
+ }
+ if (this.editorView.isFilterShowNonStopTimeEnabled()) {
+ return false;
+ }
+ return (
+ !trainrunSection.getTrainrun().selected() &&
+ TrainrunSectionsView.isBothSideNonStop(trainrunSection)
+ );
case TrainrunSectionText.TrainrunSectionName:
{
if (!this.editorView.isFilterTrainrunNameEnabled()) {
@@ -1005,7 +1056,8 @@ export class TrainrunSectionsView {
translateAndRotateArrow(
trainrunSection: TrainrunSection,
- arrowType: "BEGINNING_ARROW" | "ENDING_ARROW",
+ arrowLocation: "BEGINNING_ARROW" | "ENDING_ARROW",
+ arrowType: "DIRECTION_ARROW" | "SYMMETRY_ARROW",
) {
const positions = trainrunSection.getPath();
const isTargetRightOrBottom = TrainrunsectionHelper.isTargetRightOrBottom(trainrunSection);
@@ -1024,9 +1076,14 @@ export class TrainrunSectionsView {
// Set arrow offset values : positions[1] and positions[2] are
// the 2 intermediate points where the sections change direction
- const arrowOffset = isTargetRightOrBottom ? [-44, 20] : [44, -20];
+ let arrowOffset: [number, number];
+ if (isTargetRightOrBottom) {
+ arrowOffset = arrowType === "DIRECTION_ARROW" ? [-44, 20] : [-32, 32];
+ } else {
+ arrowOffset = arrowType === "DIRECTION_ARROW" ? [44, -20] : [32, -32];
+ }
let x, y: number;
- if (arrowType === "BEGINNING_ARROW") {
+ if (arrowLocation === "BEGINNING_ARROW") {
x = positions[1].getX() + (xDiff === 0 ? 0 : arrowOffset[0]);
y = positions[1].getY() + (xDiff === 0 ? arrowOffset[0] : 0);
} else {
@@ -1060,7 +1117,7 @@ export class TrainrunSectionsView {
return d.trainrunSection.getTrainrun().isRoundTrip() ? "" : "M-4,-5L2,0L-4,5Z";
})
.attr("transform", (d: TrainrunSectionViewObject) =>
- this.translateAndRotateArrow(d.trainrunSection, arrowType),
+ this.translateAndRotateArrow(d.trainrunSection, arrowType, "DIRECTION_ARROW"),
)
.attr(
"class",
@@ -1106,6 +1163,87 @@ export class TrainrunSectionsView {
});
}
+ createAsymmetryArrows(
+ groupLinesEnter: d3.Selection,
+ selectedTrainrun: Trainrun,
+ connectedTrainIds: any,
+ enableEvents = true,
+ ) {
+ (["BEGINNING_ARROW", "ENDING_ARROW"] as const).forEach((arrowType) => {
+ groupLinesEnter
+ .append(StaticDomTags.EDGE_LINE_ARROW_SVG)
+ .attr(StaticDomTags.TAG_HIDDEN, (d: TrainrunSectionViewObject) =>
+ // Hide arrow
+ // - if asymmetry arrows are filtered out or
+ // - if the node on this side is filtered out
+ // - if the node on this side is non-stop
+ !this.editorView.isFilterAsymmetryArrowsEnabled() ||
+ !this.filterTrainrunsectionAtNode(d.trainrunSection, arrowType === "BEGINNING_ARROW") ||
+ TrainrunSectionsView.getNode(
+ d.trainrunSection,
+ arrowType === "BEGINNING_ARROW",
+ ).isNonStop(d.trainrunSection)
+ ? ""
+ : null,
+ )
+ .attr("d", (d: TrainrunSectionViewObject) => {
+ if (arrowType === "BEGINNING_ARROW") {
+ return d.trainrunSection.isSourceSymmetricOrTimesSymmetric()
+ ? ""
+ : "M-1,-6 V0 H-8 L1,6 V0 H8 Z";
+ } else {
+ return d.trainrunSection.isTargetSymmetricOrTimesSymmetric()
+ ? ""
+ : "M-1,-6 V0 H-8 L1,6 V0 H8 Z";
+ }
+ })
+ .attr("transform", (d: TrainrunSectionViewObject) =>
+ this.translateAndRotateArrow(d.trainrunSection, arrowType, "SYMMETRY_ARROW"),
+ )
+ .attr(
+ "class",
+ (d: TrainrunSectionViewObject) =>
+ StaticDomTags.EDGE_LINE_ARROW_CLASS +
+ TrainrunSectionsView.createTrainrunSectionFrequencyClassAttribute(
+ d.trainrunSection,
+ selectedTrainrun,
+ connectedTrainIds,
+ ),
+ )
+ .classed(
+ StaticDomTags.TAG_HIDDEN,
+ (d: TrainrunSectionViewObject) =>
+ !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() &&
+ (!this.editorView.isFilterAsymmetryArrowsEnabled() ||
+ !this.filterTrainrunsectionAtNode(
+ d.trainrunSection,
+ arrowType === "BEGINNING_ARROW",
+ )),
+ )
+ .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId())
+ .attr(StaticDomTags.EDGE_LINE_LINE_ID, (d: TrainrunSectionViewObject) =>
+ d.trainrunSection.getTrainrun().getId(),
+ )
+ .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) =>
+ d.trainrunSection.getTrainrun().selected(),
+ )
+ .classed(StaticDomTags.TAG_LINE_ARROW_EDITOR, true)
+ .classed(StaticDomTags.TAG_MUTED, (d: TrainrunSectionViewObject) =>
+ TrainrunSectionsView.isMuted(d.trainrunSection, selectedTrainrun, connectedTrainIds),
+ )
+ .classed(StaticDomTags.TAG_EVENT_DISABLED, !enableEvents)
+ .on("mouseup", (d: TrainrunSectionViewObject, i, a) => {
+ this.onTrainrunAsymmetryArrowMouseUp(d.trainrunSection, a[i]);
+ })
+ .on("mouseover", (d: TrainrunSectionViewObject, i, a) => {
+ this.onTrainrunSectionMouseoverPath(d.trainrunSection, a[i]);
+ })
+ .on("mouseout", (d: TrainrunSectionViewObject, i, a) => {
+ this.onTrainrunSectionMouseoutPath(d.trainrunSection, a[i]);
+ });
+ });
+ }
+
createTrainrunSection(
groupEnter: d3.Selector,
classRef,
@@ -1347,7 +1485,8 @@ export class TrainrunSectionsView {
) {
const isDefaultText =
textElement === TrainrunSectionText.TrainrunSectionName ||
- textElement === TrainrunSectionText.TrainrunSectionTravelTime;
+ textElement === TrainrunSectionText.TrainrunSectionTravelTime ||
+ textElement === TrainrunSectionText.TrainrunSectionBackwardTravelTime;
const atSource =
textElement === TrainrunSectionText.SourceArrival ||
textElement === TrainrunSectionText.SourceDeparture;
@@ -1667,9 +1806,11 @@ export class TrainrunSectionsView {
this.getHiddenTagForTime(d, TrainrunSectionText.SourceDeparture),
this.getHiddenTagForTime(d, TrainrunSectionText.TargetDeparture),
this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionTravelTime),
+ this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionBackwardTravelTime),
this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionName),
!this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() &&
!this.editorView.isFilterDirectionArrowsEnabled(),
+ !this.editorView.isFilterAsymmetryArrowsEnabled(),
),
);
});
@@ -1840,6 +1981,17 @@ export class TrainrunSectionsView {
this.editorView.showTrainrunOneWayInformation(trainrunSection, clickPosition);
}
+ onTrainrunAsymmetryArrowMouseUp(trainrunSection: TrainrunSection, domObj: any) {
+ d3.event.stopPropagation();
+ const rect: DOMRect = d3.select(domObj).node().getBoundingClientRect();
+ const clickPosition = new Vec2D(rect.x + rect.width / 2, rect.y + rect.height / 2);
+
+ if (this.editorView.editorMode === EditorMode.Analytics) {
+ return;
+ }
+ this.editorView.showTrainrunSectionInformation(trainrunSection, clickPosition);
+ }
+
onTrainrunSectionMouseUp(trainrunSection: TrainrunSection, domObj: any) {
d3.event.stopPropagation();
const ts = this.editorView.getSelectedTrainrun();
@@ -1964,6 +2116,8 @@ export class TrainrunSectionsView {
node = trainrunSection.getTargetNode();
minute = trainrunSection.getTargetDeparture();
break;
+ default:
+ break;
}
this.editorView.unselectAllNodes();
this.editorView.calculateShortestDistanceNodesFromStartingTrainrunSection(
@@ -1983,11 +2137,15 @@ export class TrainrunSectionsView {
case TrainrunSectionText.TargetDeparture:
case TrainrunSectionText.TargetArrival:
case TrainrunSectionText.TrainrunSectionTravelTime:
+ case TrainrunSectionText.TrainrunSectionBackwardTravelTime:
case TrainrunSectionText.TrainrunSectionNumberOfStops:
this.editorView.showTrainrunSectionInformation(trainrunSection, clickPos, textElement);
break;
case TrainrunSectionText.TrainrunSectionName:
this.editorView.showTrainrunInformation(trainrunSection, clickPos);
+ break;
+ default:
+ break;
}
}
@@ -2394,6 +2552,13 @@ export class TrainrunSectionsView {
connectedTrainIds,
TrainrunSectionText.TrainrunSectionTravelTime,
);
+ this.createTrainrunSectionElement(
+ // LevelOfDetail.LEVEL3
+ groupLabels,
+ selectedTrainrun,
+ connectedTrainIds,
+ TrainrunSectionText.TrainrunSectionBackwardTravelTime,
+ );
}
if (
@@ -2473,6 +2638,7 @@ export class TrainrunSectionsView {
);
this.createDirectionArrows(groupLines, selectedTrainrun, connectedTrainIds, enableEvents);
+ this.createAsymmetryArrows(groupLines, selectedTrainrun, connectedTrainIds, enableEvents);
}
private createSingleStopElement(
diff --git a/src/app/view/editor-main-view/editor-main-view.component.ts b/src/app/view/editor-main-view/editor-main-view.component.ts
index cdf9983d6..4ec266ecf 100644
--- a/src/app/view/editor-main-view/editor-main-view.component.ts
+++ b/src/app/view/editor-main-view/editor-main-view.component.ts
@@ -245,6 +245,15 @@ export class EditorMainViewComponent implements AfterViewInit, OnDestroy {
this.trainrunService.getCumulativeTravelTimeAndNodePath(trainrunSection),
);
+ this.editorView.bindGetCumulativeBackwardTravelTime((trainrunSection: TrainrunSection) =>
+ this.trainrunService.getCumulativeBackwardTravelTime(trainrunSection),
+ );
+
+ this.editorView.bindGetCumulativeBackwardTravelTimeAndNodePath(
+ (trainrunSection: TrainrunSection) =>
+ this.trainrunService.getCumulativeBackwardTravelTimeAndNodePath(trainrunSection),
+ );
+
this.editorView.bindAddConnectionToNode(
(node: Node, trainrunSectionFrom: TrainrunSection, trainrunSectionTo: TrainrunSection) => {
this.nodeService.addConnectionToNode(
@@ -348,6 +357,10 @@ export class EditorMainViewComponent implements AfterViewInit, OnDestroy {
this.filterService.isFilterTravelTimeEnabled(),
);
+ this.editorView.bindIsFilterBackwardTravelTimeEnabled(() =>
+ this.filterService.isFilterBackwardTravelTimeEnabled(),
+ );
+
this.editorView.bindIsfilterTrainrunNameEnabled(() =>
this.filterService.isFilterTrainrunNameEnabled(),
);
@@ -356,6 +369,10 @@ export class EditorMainViewComponent implements AfterViewInit, OnDestroy {
this.filterService.isFilterDirectionArrowsEnabled(),
);
+ this.editorView.bindIsFilterAsymmetryArrowsEnabled(() =>
+ this.filterService.isFilterAsymmetryArrowsEnabled(),
+ );
+
this.editorView.bindIsfilterArrivalDepartureTimeEnabled(() =>
this.filterService.isFilterArrivalDepartureTimeEnabled(),
);
diff --git a/src/app/view/filter-main-side-view/filter-main-side-view.component.html b/src/app/view/filter-main-side-view/filter-main-side-view.component.html
index 8d08ba4f5..d5aed2d1b 100644
--- a/src/app/view/filter-main-side-view/filter-main-side-view.component.html
+++ b/src/app/view/filter-main-side-view/filter-main-side-view.component.html
@@ -34,6 +34,7 @@
+
diff --git a/src/app/view/toggle-switch-button/toggle-switch-button.component.html b/src/app/view/toggle-switch-button/toggle-switch-button.component.html
index e421e0409..971285a7b 100644
--- a/src/app/view/toggle-switch-button/toggle-switch-button.component.html
+++ b/src/app/view/toggle-switch-button/toggle-switch-button.component.html
@@ -1,7 +1,11 @@
-