Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…netzgrafik-editor-frontend into 8-review-documentation
  • Loading branch information
aiAdrian committed Mar 19, 2024
2 parents d66f9e0 + bb4585a commit 38c2434
Show file tree
Hide file tree
Showing 51 changed files with 1,330 additions and 572 deletions.
10 changes: 10 additions & 0 deletions documentation/CREATE_TRAINRUN.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,13 @@ To switch a train from a stop to a non-stop at a node, follow these steps:
signifies trainrun transitions (stop/non-stop).

[2024-01-25-Toogle_Stop_NonStop_trainrun_at_node.webm](https://github.com/SchweizerischeBundesbahnen/netzgrafik-editor-frontend/assets/2674075/8a72350c-ed19-4395-8183-c33dfe824c5a)

### Split / Combine two trainruns

To split a train into two separate ones, you first have to select the train. Then you navigate to the node where you like to split the trainrun. Inside the node
the trainrun has to have a transition. Press CTRL and click with the mouse the "stop / non-stop toggle button". The trainrun gets split into two trains.

To combine two trainruns, you have to select one of the two trains. Then you have to navigate to the node where the trainrun ends (or starts). Now you can draw
the new transition similar to creating a connection - but you have to press CTRL key and it must be hold pressed as long you are drawing a new transition.
Once you finish drawing the new transition, the both trains will be combined to one single trainrun.
Please have as well a look into [Create Connections](CREATE_CONNECTIONS.md).
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"local-test": "ng test --watch --code-coverage"
},
"name": "netzgrafik-frontend",
"version": "2.2.0",
"version": "2.5.0",
"files": [
"dist/*"
],
Expand Down
7 changes: 7 additions & 0 deletions src/app/models/node.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,13 @@ export class Node {
);
}

removeTransitionFromId(t: Transition) {
this.transitions = this.transitions.filter(
(transition) =>
transition.getId() !== t.getId()
);
}

removeConnectionFromTrainrunSection(trainrunSection: TrainrunSection) {
let portId = trainrunSection.getSourcePortId();
if (this.getId() === trainrunSection.getTargetNodeId()) {
Expand Down
41 changes: 24 additions & 17 deletions src/app/perlenkette/perlenkette-node/perlenkette-node.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {UiInteractionService} from "../../services/ui/ui.interaction.service";
export class PerlenketteNodeComponent implements OnInit {
@Input() perlenketteNode: PerlenketteNode;
@Input() perlenketteTrainrun: PerlenketteTrainrun;
@Input() isTopNode = false;
@Input() isBottomNode = false;
@Output() signalIsBeingEdited = new EventEmitter<PerlenketteSection>();
@Output() signalHeightChanged = new EventEmitter<number>();

Expand All @@ -35,7 +37,8 @@ export class PerlenketteNodeComponent implements OnInit {
public trainrunService: TrainrunService,
readonly filterService: FilterService,
readonly uiInteractionService: UiInteractionService,
) {}
) {
}

ngOnInit() {
this.isExpanded = true;
Expand Down Expand Up @@ -262,13 +265,20 @@ export class PerlenketteNodeComponent implements OnInit {

getPathClassTag(connection: PerlenketteConnection = undefined): string {
if (connection === undefined) {
return "UI_DIALOG " + this.getColoringClassTag();
const lineTag =
" Freq_" + this.perlenketteTrainrun.frequency +
" LinePatternRef_" + this.perlenketteTrainrun.trainrunTimeCategory.linePatternRef;
return "UI_DIALOG " + this.getColoringClassTag() + lineTag;
}

let selected_tag = "";
if (connection.connection.selected()) {
selected_tag = " " + StaticDomTags.TAG_SELECTED;
}
return "UI_DIALOG " + selected_tag + this.getColoringClassTag(connection);
const lineTag =
" Freq_" + connection.frequency +
" LinePatternRef_" + connection.connectedTrainrun.getTimeCategoryLinePatternRef();
return "UI_DIALOG " + selected_tag + this.getColoringClassTag(connection) + lineTag;
}

getConnectedTrainEdgeLineTransform(
Expand Down Expand Up @@ -303,11 +313,8 @@ export class PerlenketteNodeComponent implements OnInit {
toggleNonStop() {
const node = this.nodeService.getNodeFromId(this.perlenketteNode.nodeId);
const transition: Transition = this.perlenketteNode.transition;
if (transition !== undefined) {
this.nodeService.toggleNonStop(
this.perlenketteNode.nodeId,
transition.getId(),
);
if (transition !== undefined && node !== undefined) {
this.nodeService.toggleNonStop(node.getId(), transition.getId());
this.trainrunService.trainrunsUpdated();
}
}
Expand Down Expand Up @@ -348,15 +355,15 @@ export class PerlenketteNodeComponent implements OnInit {
item
.getPerlenketteNode()
.connections.forEach((connection: PerlenketteConnection) => {
const name = connection.categoryShortName + "" + connection.title;
maxTrainrunNameLen = Math.max(
3 + connection.terminalStationBackward.length,
Math.max(
3 + connection.terminalStation.length,
Math.max(name.length, maxTrainrunNameLen),
),
);
});
const name = connection.categoryShortName + "" + connection.title;
maxTrainrunNameLen = Math.max(
3 + connection.terminalStationBackward.length,
Math.max(
3 + connection.terminalStation.length,
Math.max(name.length, maxTrainrunNameLen),
),
);
});
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,16 @@
(click)="switchSectionView($event, 'leftDepartureTime')"
></rect>
<path
d="M12 4a2 2 0 0 0-2 2v3h4V6a2 2 0 0 0-2-2Zm3 5V6a3 3 0 0 0-6 0v3H6v11h12V9h-3Zm-2.5 4v4h-1v-4h1ZM7 19v-9h10v9H7Z"
[ngClass]="[getPathClassTag()]"
[attr.d]="getLockCloseSvgPath()"
[ngClass]="[getPathClassTag(true)]"
class="edge_line"
style="fill: white; stroke-width: 1px; cursor: pointer"
(click)="switchSectionView($event, 'leftDepartureTime')"
/>
</g>
<g
transform="translate(125, 82)"
*ngIf="showTravelTime() && !lockStructure.travelTimeLock"
*ngIf="showTravelTime() && lockStructure.travelTimeLock"
>
<rect
x="6"
Expand All @@ -131,8 +131,8 @@
(click)="switchSectionView($event, 'travelTime')"
></rect>
<path
d="M4 6a3 3 0 1 1 6 0v3h8v11H6V9h3V6a2 2 0 1 0-4 0H4Zm8.5 7v4h-1v-4h1ZM7 19v-9h10v9H7Z"
[ngClass]="[getPathClassTag()]"
[attr.d]="getLockCloseSvgPath()"
[ngClass]="[getPathClassTag(true)]"
class="edge_line"
style="fill: white; stroke-width: 1px; cursor: pointer"
(click)="switchSectionView($event, 'travelTime')"
Expand All @@ -152,8 +152,8 @@
(click)="switchSectionView($event, 'rightDepatureTime')"
></rect>
<path
d="M12 4a2 2 0 0 0-2 2v3h4V6a2 2 0 0 0-2-2Zm3 5V6a3 3 0 0 0-6 0v3H6v11h12V9h-3Zm-2.5 4v4h-1v-4h1ZM7 19v-9h10v9H7Z"
[ngClass]="[getPathClassTag()]"
[attr.d]="getLockCloseSvgPath()"
[ngClass]="[getPathClassTag(true)]"
class="edge_line"
style="fill: white; stroke-width: 1px; cursor: pointer"
(click)="switchSectionView($event, 'rightDepatureTime')"
Expand Down Expand Up @@ -573,6 +573,7 @@
<foreignObject height="192px" width="45px">
<div class="propagationButtonContainer">
<button
[class]="isFirstSection===true ? 'disabled' : ''"
class="FunctionButton Rotation90"
tabindex="-1"
mode="icon"
Expand All @@ -589,6 +590,7 @@
</div>
</button>
<button
[class]="isLastSection===true ? 'disabled' : ''"
class="FunctionButton Rotation90"
tabindex="-1"
mode="icon"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,8 @@ g.edge.Lines:hover {
cursor: pointer;
opacity: 0.75;
}

button.FunctionButton.Rotation90.disabled {
pointer-events: none;
opacity: 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,13 @@ export interface LeftAndRightLockStructure {
providers: [TrainrunSectionTimesService],
})
export class PerlenketteSectionComponent
implements OnInit, AfterContentInit, OnDestroy
{
implements OnInit, AfterContentInit, OnDestroy {
@Input() perlenketteSection: PerlenketteSection;
@Input() perlenketteTrainrun: PerlenketteTrainrun;

@Input() isFirstSection = false;
@Input() isLastSection = false;

@Output() signalIsBeingEdited = new EventEmitter<PerlenketteSection>();
@Output() signalHeightChanged = new EventEmitter<number>();
@Input() notificationIsBeingEdited: Observable<PerlenketteSection>;
Expand Down Expand Up @@ -154,10 +156,8 @@ export class PerlenketteSectionComponent
this.perlenketteSection.fromNode,
this.perlenketteSection.toNode,
];
this.lockStructure = this.trainrunSectionHelper.getLeftAndRightLock(
this.trainrunSection,
this.trainrunSectionTimesService.getNodesOrdered(),
);

this.updateLockStructure();

this.signalHeightChanged.next(192);
}
Expand All @@ -177,15 +177,17 @@ export class PerlenketteSectionComponent
return "StopsEditor";
}

getPathClassTag(): string {
getPathClassTag(noLinePatterns = false): string {
return (
"UI_DIALOG " +
" ColorRef_" +
this.perlenketteTrainrun.colorRef +
" Freq_" +
this.perlenketteTrainrun.frequency +
" LinePatternRef_" +
this.perlenketteTrainrun.trainrunTimeCategory.linePatternRef
(noLinePatterns ? " " :
" Freq_" +
this.perlenketteTrainrun.frequency +
" LinePatternRef_" +
this.perlenketteTrainrun.trainrunTimeCategory.linePatternRef
)
);
}

Expand Down Expand Up @@ -894,17 +896,30 @@ export class PerlenketteSectionComponent
this.updateTrainrunSectionTimeLock();
}

getSourceLock(): boolean {
const sourceId = this.trainrunSection.getSourceNodeId();
const fromNode = this.perlenketteSection.fromNode.getId();
if (sourceId === fromNode) {
return this.lockStructure.leftLock;
}
return this.lockStructure.rightLock;

}

getTargetLock(): boolean {
const targetId = this.trainrunSection.getTargetNodeId();
const toId = this.perlenketteSection.toNode.getId();
if (targetId === toId) {
return this.lockStructure.rightLock;
}
return this.lockStructure.leftLock;
}

updateTrainrunSectionTimeLock() {
this.trainrunSectionService.updateTrainrunSectionTimeLock(
this.trainrunSection.getId(),
this.trainrunSectionHelper.getSourceLock(
this.lockStructure,
this.trainrunSection,
),
this.trainrunSectionHelper.getTargetLock(
this.lockStructure,
this.trainrunSection,
),
this.getSourceLock(),
this.getTargetLock(),
this.lockStructure.travelTimeLock,
);
}
Expand Down Expand Up @@ -1017,6 +1032,15 @@ export class PerlenketteSectionComponent
}
}

getLockOpenSvgPath(): string {
return "M4 6a3 3 0 1 1 6 0v3h8v11H6V9h3V6a2 2 0 1 0-4 0H4Zm8.5 7v4h-1v-4h1ZM7 19v-9h10v9H7Z";
}

getLockCloseSvgPath(): string {
return "M12 4a2 2 0 0 0-2 2v3h4V6a2 2 0 0 0-2-2Zm3 5V6a3 3 0 0 0-6 0v3H6v11h12V9h-3Zm-2.5 " +
"4v4h-1v-4h1ZM7 19v-9h10v9H7Z";
}

private updateTrainrunSectionTime() {
const trsId = this.trainrunSection.getId();
const sourceArrivalTime = this.getSectionSourceArrivalTime();
Expand Down Expand Up @@ -1046,4 +1070,22 @@ export class PerlenketteSectionComponent
nbrOfStops: this.trainrunSection.getNumberOfStops(),
};
}

private updateLockStructure() {
const sourceId = this.trainrunSection.getSourceNodeId();
const fromId = this.perlenketteSection.fromNode.getId();
if (sourceId === fromId) {
this.lockStructure.leftLock = this.trainrunSection.getSourceDepartureLock();
} else {
this.lockStructure.leftLock = this.trainrunSection.getTargetArrivalLock();
}
const targetId = this.trainrunSection.getTargetNodeId();
const toId = this.perlenketteSection.toNode.getId();
if (targetId === toId) {
this.lockStructure.rightLock = this.trainrunSection.getTargetArrivalLock();
} else {
this.lockStructure.rightLock = this.trainrunSection.getSourceDepartureLock();
}
this.lockStructure.travelTimeLock = this.trainrunSection.getTravelTimeLock();
}
}
6 changes: 5 additions & 1 deletion src/app/perlenkette/perlenkette.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,15 @@
[attr.width]="contentWidth"
>
<div class="drawing-container" #drawingContainer>
<ng-container *ngFor="let pathItem of perlenketteTrainrun.pathItems">
<ng-container *ngFor="let pathItem of perlenketteTrainrun.pathItems; index as idx">
<sbb-perlenkette-node
*ngIf="pathItem.isPerlenketteNode()"
[perlenketteTrainrun]="perlenketteTrainrun"
(signalIsBeingEdited)="signalIsBeingEdited($event)"
(signalHeightChanged)="signalHeightChanged($event, pathItem)"
[perlenketteNode]="pathItem.getPerlenketteNode()"
[isTopNode]="idx === 0"
[isBottomNode]="idx === perlenketteTrainrun.pathItems.length-1"
>
</sbb-perlenkette-node>
<sbb-perlenkette-section
Expand All @@ -121,6 +123,8 @@
[notificationIsBeingEdited]="
getSignalAllChildrenIsBeingEditedObservable()
"
[isFirstSection]="idx === 1"
[isLastSection]="idx === perlenketteTrainrun.pathItems.length-2"
>
</sbb-perlenkette-section>
</ng-container>
Expand Down
Loading

0 comments on commit 38c2434

Please sign in to comment.