From 16eb12c78967164659f00936ef3b8442b63c1588 Mon Sep 17 00:00:00 2001 From: u216993 Date: Tue, 10 Dec 2024 12:58:20 +0100 Subject: [PATCH 1/3] fix: import 3rd party performance --- src/app/services/data/data.service.ts | 12 +++++++++--- src/app/services/data/trainrunsection.service.ts | 15 ++++++++++++--- .../editor-tools-view.component.ts | 2 +- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/app/services/data/data.service.ts b/src/app/services/data/data.service.ts index e8a1ed83..026dd491 100644 --- a/src/app/services/data/data.service.ts +++ b/src/app/services/data/data.service.ts @@ -112,7 +112,10 @@ export class DataService implements OnDestroy { ); } - insertCopyNetzgrafikDto(netzgrafikDto: NetzgrafikDto) { + insertCopyNetzgrafikDto( + netzgrafikDto: NetzgrafikDto, + enforceUpdate = true + ) { this.nodeService.unselectAllNodes(); const nodeMap = this.nodeService.mergeNodes(netzgrafikDto.nodes); const trainrunMap = this.trainrunService.createNewTrainrunsFromDtoList( @@ -124,6 +127,7 @@ export class DataService implements OnDestroy { nodeMap, trainrunMap, netzgrafikDto.nodes, + enforceUpdate ); this.nodeService.mergeLabelNode(netzgrafikDto, nodeMap); this.nodeService.mergeConnections( @@ -131,8 +135,10 @@ export class DataService implements OnDestroy { trainrunSectionMap, nodeMap, ); - this.nodeService.connectionsUpdated(); - this.nodeService.transitionsUpdated(); + if (enforceUpdate) { + this.nodeService.connectionsUpdated(); + this.nodeService.transitionsUpdated(); + } this.trainrunService.mergeLabelTrainrun(netzgrafikDto, trainrunMap); this.noteService.createNewNoteFromDtoList(netzgrafikDto.freeFloatingTexts); } diff --git a/src/app/services/data/trainrunsection.service.ts b/src/app/services/data/trainrunsection.service.ts index 3fd7aee7..568cae48 100644 --- a/src/app/services/data/trainrunsection.service.ts +++ b/src/app/services/data/trainrunsection.service.ts @@ -254,6 +254,7 @@ export class TrainrunSectionService implements OnDestroy { nodeMap: Map, trainrunMap: Map, nodes: NodeDto[], + enforceUpdate = true ): Map { const trainrunSectionMap: Map = new Map(); trainrunSections.forEach((trainrunSection) => { @@ -262,10 +263,13 @@ export class TrainrunSectionService implements OnDestroy { nodeMap, trainrunMap, nodes, + enforceUpdate ); trainrunSectionMap.set(trainrunSection.id, newTrainrunSection.getId()); }); - this.trainrunSectionsUpdated(); + if (enforceUpdate) { + this.trainrunSectionsUpdated(); + } return trainrunSectionMap; } @@ -1427,6 +1431,7 @@ export class TrainrunSectionService implements OnDestroy { trainrunSection: TrainrunSection, sourceIsNonStop = false, targetIsNonStop = false, + enforceUpdate = true ) { this.nodeService.addPortsToNodes( sourceNode.getId(), @@ -1440,8 +1445,10 @@ export class TrainrunSectionService implements OnDestroy { sourceIsNonStop, targetIsNonStop, ); - this.nodeService.nodesUpdated(); - this.nodeService.transitionsUpdated(); + if (enforceUpdate) { + this.nodeService.nodesUpdated(); + this.nodeService.transitionsUpdated(); + } trainrunSection.routeEdgeAndPlaceText(); this.reRouteAffectedTrainrunSections( sourceNode.getId(), @@ -1454,6 +1461,7 @@ export class TrainrunSectionService implements OnDestroy { nodeMap: Map, trainrunMap: Map, nodes: NodeDto[], + enforceUpdate = true ) { const trainrunId = trainrunMap.get(trainrunSection.trainrunId); const trainrun = this.trainrunService.getTrainrunFromId(trainrunId); @@ -1490,6 +1498,7 @@ export class TrainrunSectionService implements OnDestroy { newTrainrunSection, sourceIsNonStop, targetIsNonStop, + enforceUpdate ); return newTrainrunSection; } diff --git a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts index 36c2891d..117d0aff 100644 --- a/src/app/view/editor-tools-view-component/editor-tools-view.component.ts +++ b/src/app/view/editor-tools-view-component/editor-tools-view.component.ts @@ -608,7 +608,7 @@ export class EditorToolsViewComponent { this.dataService.loadNetzgrafikDto(netzgrafikOnlyNodeDto); // (Step 2) Import nodes and trainrunSectiosn by trainrun inseration (copy => create) - this.dataService.insertCopyNetzgrafikDto(netzgrafikDto); + this.dataService.insertCopyNetzgrafikDto(netzgrafikDto, false); // step(3) Check whether a transitions object was given when not // departureTime - arrivatelTime == 0 => non-stop From 7f488a7d429d1387a2534f3d2b333de776f854e7 Mon Sep 17 00:00:00 2001 From: u216993 Date: Wed, 11 Dec 2024 11:33:22 +0100 Subject: [PATCH 2/3] fix: ctrl + mouse wheel -> scale netzgrafik or multi-select node and scale --- .../data-views/editor.view.ts | 75 +++++++++++++++++++ src/app/view/util/svg.mouse.controller.ts | 32 +++++++- 2 files changed, 103 insertions(+), 4 deletions(-) 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 12d2e7c3..ebb38d25 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 @@ -577,6 +577,11 @@ export class EditorView implements SVGMouseControllerObserver { this.trainrunSectionPreviewLineView.stopPreviewLine(); } + + onScaleNetzgrafik(factor: number, scaleCenter: Vec2D) { + this.scaleNetzgrafikArea(factor, scaleCenter); + } + zoomFactorChanged(newZoomFactor: number) { this.controller.zoomFactorChanged(newZoomFactor); this.viewportCullService.onViewportChangeUpdateRendering(true); @@ -687,4 +692,74 @@ export class EditorView implements SVGMouseControllerObserver { el.classed("ShowCellCursor", false); } } + + + private scaleFullNetzgrafikArea(factor: number, zoomCenter: Vec2D) { + const vp = this.uiInteractionService.getViewboxProperties(EditorView.svgName); + const scaleCenterCoordinates = new Vec2D( + vp.panZoomLeft + zoomCenter.getX() * vp.panZoomWidth, + vp.panZoomTop + zoomCenter.getY() * vp.panZoomHeight, + ); + + // get the node under the mouse cursos and update the scaleCenter + const focalNode = this.nodeService.getNodes().find((n) => + scaleCenterCoordinates.getX() > n.getPositionX() && scaleCenterCoordinates.getX() < (n.getPositionX() + n.getNodeWidth()) && + scaleCenterCoordinates.getY() > n.getPositionY() && scaleCenterCoordinates.getY() < (n.getPositionY() + n.getNodeHeight()) + ); + + this.nodeService.getNodes().forEach((n, index) => { + let newPos = new Vec2D( + (n.getPositionX() - scaleCenterCoordinates.getX()) * factor + scaleCenterCoordinates.getX(), + (n.getPositionY() - scaleCenterCoordinates.getY()) * factor + scaleCenterCoordinates.getY() + ); + + if (focalNode?.getId() === n.getId()) { + const delta = Vec2D.sub(newPos, new Vec2D(focalNode.getPositionX(), focalNode.getPositionY(),)); + newPos = Vec2D.sub(newPos, delta); + } + n.setPosition(newPos.getX(), newPos.getY()); + }); + } + + private scaleNetzgrafikSelectedNodesArea(factor: number, nodes: Node[]) { + /* + * if more than one node is selected (multi-selected nodes) transform the nodes with center of + * mass + */ + let cx = 0; + let cy = 0; + nodes.forEach(n => { + cx += n.getPositionX() + n.getNodeWidth() / 2.0; + cy += n.getPositionY() + n.getNodeHeight() / 2.0; + }); + cx /= nodes.length; + cy /= nodes.length; + const v = Vec2D.normalize(new Vec2D(cx, cy)); + nodes.forEach((n, index) => { + const posX = (n.getPositionX() + n.getNodeWidth() / 2.0 - cx) * factor + cx - n.getNodeWidth() / 2.0; + const posY = (n.getPositionY() + n.getNodeHeight() / 2.0 - cy) * factor + cy - n.getNodeHeight() / 2.0; + n.setPosition(posX, posY); + }); + } + + private scaleNetzgrafikArea(factor: number, zoomCenter: Vec2D) { + const nodes: Node[] = this.nodeService.getSelectedNodes(); + + if (nodes.length < 2) { + this.scaleFullNetzgrafikArea(factor, zoomCenter); + } else { + this.scaleNetzgrafikSelectedNodesArea(factor, nodes); + } + + this.trainrunSectionService.getTrainrunSections().forEach(ts => { + ts.routeEdgeAndPlaceText(); + ts.getSourceNode().updateTransitionsAndConnections(); + }); + + this.nodeService.initPortOrdering(); + + this.viewportCullService.onViewportChangeUpdateRendering(true); + } + + } diff --git a/src/app/view/util/svg.mouse.controller.ts b/src/app/view/util/svg.mouse.controller.ts index efc4d86b..83a01150 100644 --- a/src/app/view/util/svg.mouse.controller.ts +++ b/src/app/view/util/svg.mouse.controller.ts @@ -17,6 +17,8 @@ export interface SVGMouseControllerObserver { updateMultiSelect(topLeft: Vec2D, bottomRight: Vec2D); onEndMultiSelect(); + + onScaleNetzgrafik(factor: number, scaleCenter: Vec2D); } export class SVGMouseController { @@ -36,7 +38,8 @@ export class SVGMouseController { constructor( private svgName: string, private svgMouseControllerObserver: SVGMouseControllerObserver, - ) {} + ) { + } init(viewboxProperties: ViewboxProperties) { this.viewboxProperties = viewboxProperties; @@ -100,6 +103,15 @@ export class SVGMouseController { ); } + + scaleIn(scaleCenter: Vec2D) { + this.svgMouseControllerObserver.onScaleNetzgrafik(1.125, scaleCenter); + } + + scaleOut(scaleCenter: Vec2D) { + this.svgMouseControllerObserver.onScaleNetzgrafik(1.0 / 1.125, scaleCenter); + } + zoomIn(zoomCenter: Vec2D, factor = 1.0) { if (this.viewboxIsFixed) { return; @@ -312,11 +324,23 @@ export class SVGMouseController { d3.event.offsetX / this.viewboxProperties.origWidth, d3.event.offsetY / this.viewboxProperties.origHeight, ); - if (d3.event.deltaY > 0) { - this.zoomOut(zoomCenter); + + if (!d3.event.ctrlKey) { + // mouse wheel + if (d3.event.deltaY > 0) { + this.zoomOut(zoomCenter); + } else { + this.zoomIn(zoomCenter); + } } else { - this.zoomIn(zoomCenter); + // ctrl and mouse wheel + if (d3.event.deltaY > 0) { + this.scaleOut(zoomCenter); + } else { + this.scaleIn(zoomCenter); + } } + d3.event.preventDefault(); d3.event.stopPropagation(); } From 3829fd2551064a61f6214a2fa418b274773ca047 Mon Sep 17 00:00:00 2001 From: u216993 Date: Wed, 11 Dec 2024 11:46:07 +0100 Subject: [PATCH 3/3] fix: ctrl + mouse wheel -> scale netzgrafik or multi-select node and scale --- .../view/util/svg.mouse.controller.spec.ts | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/app/view/util/svg.mouse.controller.spec.ts b/src/app/view/util/svg.mouse.controller.spec.ts index 50701687..9ec77791 100644 --- a/src/app/view/util/svg.mouse.controller.spec.ts +++ b/src/app/view/util/svg.mouse.controller.spec.ts @@ -1,7 +1,4 @@ -import { - SVGMouseController, - SVGMouseControllerObserver, -} from "./svg.mouse.controller"; +import {SVGMouseController, SVGMouseControllerObserver,} from "./svg.mouse.controller"; import {Vec2D} from "../../utils/vec2D"; import {ViewboxProperties} from "../../services/ui/ui.interaction.service"; @@ -10,17 +7,26 @@ class DummySVGMouseControllerObserver implements SVGMouseControllerObserver { return true; } - onGraphContainerMouseup(mousePosition: Vec2D, onPaning: boolean) {} + onGraphContainerMouseup(mousePosition: Vec2D, onPaning: boolean) { + } + + zoomFactorChanged(newZoomFactor: number) { + } - zoomFactorChanged(newZoomFactor: number) {} + onViewboxChanged(viewboxProperties: ViewboxProperties) { + } - onViewboxChanged(viewboxProperties: ViewboxProperties) {} + onStartMultiSelect() { + } - onStartMultiSelect() {} + updateMultiSelect(topLeft: Vec2D, bottomRight: Vec2D) { + } - updateMultiSelect(topLeft: Vec2D, bottomRight: Vec2D) {} + onEndMultiSelect() { + } - onEndMultiSelect() {} + onScaleNetzgrafik(factor: number, scaleCenter: Vec2D) { + } } describe("general view functions", () => {