You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ri...@apache.org on 2021/03/09 21:50:05 UTC

[incubator-streampipes] 03/06: [STREAMPIPES-304] Improve zoom feature

This is an automated email from the ASF dual-hosted git repository.

riemer pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git

commit 703839269ab391d1e179fc78871c4cb2d5ec52bf
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Tue Mar 9 20:23:24 2021 +0100

    [STREAMPIPES-304] Improve zoom feature
---
 ui/angular.json                                    |  1 -
 ui/package.json                                    |  3 +-
 .../pipeline-assembly.component.html               | 85 ++++++++++++-------
 .../pipeline-assembly.component.scss               | 94 ++++++++++++++++++++--
 .../pipeline-assembly.component.ts                 | 88 +++++++++++++++-----
 .../components/pipeline/pipeline.component.ts      |  4 +-
 ui/src/app/editor/editor.module.ts                 |  2 -
 ui/src/scss/_variables.scss                        |  3 +-
 ui/src/scss/main.scss                              |  1 -
 9 files changed, 212 insertions(+), 69 deletions(-)

diff --git a/ui/angular.json b/ui/angular.json
index c1ae092..7b233ae 100644
--- a/ui/angular.json
+++ b/ui/angular.json
@@ -37,7 +37,6 @@
               "node_modules/plotly.js/dist/plotly.min.js",
               "node_modules/jquery/dist/jquery.min.js",
               "node_modules/datatables.net/js/jquery.dataTables.js",
-              "node_modules/jquery.panzoom/dist/jquery.panzoom.js",
               "node_modules/jquery-ui-dist/jquery-ui.js",
               "node_modules/quill/dist/quill.js",
             ]
diff --git a/ui/package.json b/ui/package.json
index 8d3a3b9..efc485d 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -35,6 +35,7 @@
     "@fortawesome/fontawesome-free": "5.12.1",
     "@ngx-loading-bar/core": "5.1.0",
     "@ngx-loading-bar/http-client": "5.1.0",
+    "@panzoom/panzoom": "^4.3.2",
     "@stomp/ng2-stompjs": "7.2.0",
     "@swimlane/ngx-charts": "16.0.0",
     "angular-datatables": "^10.0.0",
@@ -58,7 +59,6 @@
     "file-saver": "1.3.8",
     "jquery": "2.1.3",
     "jquery-ui-dist": "1.12.1",
-    "jquery.panzoom": "2.0.5",
     "jshint": "2.11.1",
     "jsplumb": "^2.15.5",
     "jszip": "3.2.1",
@@ -74,7 +74,6 @@
     "ngx-auto-scroll": "^1.1.0",
     "ngx-color-picker": "9.0.0",
     "ngx-echarts": "^6.0.0",
-    "ngx-perfect-scrollbar": "^10.1.0",
     "ngx-quill": "12.0.1",
     "ngx-showdown": "5.1.0",
     "path": "^0.12.7",
diff --git a/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.html b/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.html
index 1eddb4e..bb088c6 100644
--- a/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.html
+++ b/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.html
@@ -24,26 +24,17 @@
                     (click)="submit()" type="submit">
                 <i class="material-icons">save</i>&nbsp;<span>Save pipeline</span>
             </button>
-            <button mat-button mat-icon-button matTooltip="Pan" [matTooltipPosition]="'above'"
-                    [disabled]="!selectMode"
-                    (click)="toggleSelectMode()">
-                <i class="material-icons">open_with</i>
-            </button>
-            <button mat-button mat-icon-button matTooltip="Select" [matTooltipPosition]="'above'"
-                    [disabled]="selectMode"
-                    (click)="toggleSelectMode()">
-                <i class="material-icons">mode_edit</i>
-            </button>
-            <button mat-button mat-icon-button matTooltip="Zoom In" [matTooltipPosition]="'above'"
-                    [disabled]="currentZoomLevel == 1"
-                    (click)="zoomIn()">
-                <i class="material-icons">zoom_in</i>
-            </button>
-            <button mat-button mat-icon-button matTooltip="Zoom Out" [matTooltipPosition]="'above'"
-                    [disabled]="currentZoomLevel == 0.5"
-                    (click)="zoomOut()">
-                <i class="material-icons">zoom_out</i>
-            </button>
+            <!-- TODO: Use this once copying of elements is supported -->
+<!--            <button mat-button mat-icon-button matTooltip="Pan" [matTooltipPosition]="'above'"-->
+<!--                    [disabled]="!selectMode"-->
+<!--                    (click)="toggleSelectMode()">-->
+<!--                <i class="material-icons">open_with</i>-->
+<!--            </button>-->
+<!--            <button mat-button mat-icon-button matTooltip="Select" [matTooltipPosition]="'above'"-->
+<!--                    [disabled]="selectMode"-->
+<!--                    (click)="toggleSelectMode()">-->
+<!--                <i class="material-icons">mode_edit</i>-->
+<!--            </button>-->
             <button mat-button mat-icon-button matTooltip="Auto Layout" [matTooltipPosition]="'above'"
                     (click)="autoLayout()">
                 <i class="material-icons">settings_overscan</i>
@@ -102,17 +93,49 @@
         </div>
     </div>
     <div id="outerAssemblyArea" class="outerAssembly sp-blue-border-nopadding">
-        <div id="assembly" class="canvas jtk-surface jtk-surface-no-pan">
-            <pipeline [pipelineValid]="pipelineValid"
-                      [canvasId]="'assembly'"
-                      [rawPipelineModel]="rawPipelineModel"
-                      [allElements]="allElements"
-                      [preview]="false"
-                      [pipelineCached]="pipelineCached"
-                      [pipelineCacheRunning]="pipelineCacheRunning"
-                      (pipelineCachedChanged)="pipelineCached=$event"
-                      (pipelineCacheRunningChanged)="pipelineCacheRunning=$event">
-            </pipeline>
+        <div class="pipeline-canvas-outer">
+            <div class="pan-control">
+                <div class="pan-zoom-control-buttons">
+                    <div class="pan-zoom-button pan-left" (click)="panLeft()">
+                        <i class="material-icons">keyboard_arrow_left</i>
+                    </div>
+                    <div class="pan-zoom-button pan-right" (click)="panRight()">
+                        <i class="material-icons">keyboard_arrow_right</i>
+                    </div>
+                    <div class="pan-zoom-button pan-home" (click)="panHome()">
+                        <i class="material-icons">home</i>
+                    </div>
+                    <div class="pan-zoom-button pan-up" (click)="panUp()">
+                        <i class="material-icons">keyboard_arrow_up</i>
+                    </div>
+                    <div class="pan-zoom-button pan-down" (click)="panDown()">
+                        <i class="material-icons">keyboard_arrow_down</i>
+                    </div>
+                </div>
+            </div>
+            <div class="zoom-control">
+                <div class="pan-zoom-control-buttons">
+                    <div class="pan-zoom-button zoom-in" (click)="zoomIn()">
+                        <i class="material-icons">zoom_in</i>
+                    </div>
+                    <mat-divider class="zoom-divider"></mat-divider>
+                    <div class="pan-zoom-button zoom-out" (click)="zoomOut()">
+                        <i class="material-icons">zoom_out</i>
+                    </div>
+                </div>
+            </div>
+            <div id="assembly" class="canvas">
+                <pipeline [pipelineValid]="pipelineValid"
+                          [canvasId]="'assembly'"
+                          [rawPipelineModel]="rawPipelineModel"
+                          [allElements]="allElements"
+                          [preview]="false"
+                          [pipelineCached]="pipelineCached"
+                          [pipelineCacheRunning]="pipelineCacheRunning"
+                          (pipelineCachedChanged)="pipelineCached=$event"
+                          (pipelineCacheRunningChanged)="pipelineCacheRunning=$event">
+                </pipeline>
+            </div>
         </div>
     </div>
 </div>
diff --git a/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.scss b/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.scss
index 5bbd778..7629335 100644
--- a/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.scss
+++ b/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.scss
@@ -16,6 +16,8 @@
  *
  */
 
+@import '../../../../scss/_variables.scss';
+
 .mat-spinner-color::ng-deep svg circle{
     stroke: #FFFFFF !important;
 }
@@ -33,24 +35,27 @@
     //position: relative;
     left: 0px;
     top: 0px;
-    overflow: visible;
+    //overflow: visible;
     //box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .2), 0 1px 1px 0 rgba(0, 0, 0, .14), 0 2px 1px -1px rgba(0, 0, 0, .12);
     //padding: 5px;
-    flex: 1;
-    width: 100%;
+    display: flex;
+    flex: 1 1 0;
+    overflow: hidden;
 }
 
 .pipeline-canvas-outer {
-    flex: 1;
+    position: relative;
+    width: 100%;
+    height: 100%;
 }
 
 .canvas {
-    overflow: auto;
+    //overflow: scroll;
     position: relative;
     left: 0px;
     top: 0px;
-    height: 100%;
-    width: 100%;
+    height: 3000px;
+    width: 3000px;
     z-index: 0;
     margin: -1px;
 
@@ -67,3 +72,78 @@
     overflow: scroll !important;
     cursor:default;
 }
+
+.zoom-control {
+    position: absolute;
+    right: 10px;
+    bottom: 10px;
+    width: 40px;
+    height: 80px;
+    z-index: 10;
+    background: white;
+    box-shadow: 0.175em 0.175em 0 0 rgba(15, 28, 63, 0.125);
+    border-radius: 10px;
+
+}
+
+.pan-control {
+    position: absolute;
+    right: 60px;
+    bottom: 10px;
+    width: 80px;
+    height: 80px;
+    background: white;
+    box-shadow: 0.175em 0.175em 0 0 rgba(15, 28, 63, 0.125);
+    border-radius: 50%;
+    z-index: 10;
+}
+
+.pan-zoom-button {
+    position: absolute;
+    cursor: pointer;
+    color: $sp-color-accent;
+}
+
+.pan-zoom-control-buttons {
+    position: relative;
+}
+
+.zoom-divider {
+    top: 40px;
+    position: relative;
+}
+
+.zoom-in {
+    top: 8px;
+    left: 8px;
+}
+
+.zoom-out {
+    top: 48px;
+    left: 8px;
+}
+
+.pan-up {
+    left: 28px;
+    top: 2px;
+}
+
+.pan-down {
+    left: 28px;
+    top: 58px;
+}
+
+.pan-left {
+    left: -3px;
+    top: 30px;
+}
+
+.pan-right {
+    left: 55px;
+    top: 30px;
+}
+
+.pan-home {
+    left: 28px;
+    top: 30px;
+}
diff --git a/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.ts b/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.ts
index 8b44161..9ce6213 100644
--- a/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.ts
+++ b/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.ts
@@ -42,6 +42,7 @@ import {EditorService} from "../../services/editor.service";
 import {PipelineService} from "../../../platform-services/apis/pipeline.service";
 import {PipelineCanvasScrollingService} from "../../services/pipeline-canvas-scrolling.service";
 import {JsplumbFactoryService} from "../../services/jsplumb-factory.service";
+import Panzoom, {PanzoomObject} from "@panzoom/panzoom";
 
 
 @Component({
@@ -84,6 +85,7 @@ export class PipelineAssemblyComponent implements OnInit {
 
     config: any = {};
     @ViewChild("assembly") pipelineCanvas: ElementRef;
+    panzoom: PanzoomObject;
 
     constructor(private JsPlumbFactoryService: JsplumbFactoryService,
                 private PipelinePositioningService: PipelinePositioningService,
@@ -118,20 +120,35 @@ export class PipelineAssemblyComponent implements OnInit {
         });
     }
 
-    ngAfterViewInit() {
-        ($("#assembly") as any).panzoom({
-            disablePan: true,
-            increment: 0.25,
-            minScale: 0.5,
-            maxScale: 1.5,
-            contain: 'invert'
-        });
 
-        $("#assembly").on('panzoomzoom', (e, panzoom, scale) => {
-            this.currentZoomLevel = scale;
-            this.JsplumbBridge.setZoom(scale);
-            this.JsplumbBridge.repaintEverything();
-        });
+    ngAfterViewInit() {
+        const elem = document.getElementById('assembly')
+        this.panzoom = Panzoom(elem, {
+            maxScale: 5,
+            excludeClass: "jtk-draggable",
+            canvas: true,
+            contain: "outside"
+        })
+        //panzoom.pan(10, 10)
+        //panzoom.zoom(2, { animate: true })
+        // ($("#assembly") as any).panzoom({
+        //     disablePan: false,
+        //     increment: 0.25,
+        //     minScale: 0.5,
+        //     maxScale: 1.5,
+        //     contain: 'invert',
+        //     excludeClass: "jtk-managed"
+        // });
+        //
+        // $("#assembly").on('panzoomzoom', (e, panzoom, scale) => {
+        //     this.currentZoomLevel = scale;
+        //     this.JsplumbBridge.setZoom(scale);
+        //     this.JsplumbBridge.repaintEverything();
+        // });
+        //
+        // $("#assembly").on('panzoompan', (e, panzoom, scale) => {
+        //     console.log(e);
+        // });
     }
 
     autoLayout() {
@@ -140,14 +157,6 @@ export class PipelineAssemblyComponent implements OnInit {
     }
 
     toggleSelectMode() {
-        if (this.selectMode) {
-            ($("#assembly") as any).panzoom("option", "disablePan", false);
-            this.selectMode = false;
-        }
-        else {
-            ($("#assembly") as any).panzoom("option", "disablePan", true);
-            this.selectMode = true;
-        }
     }
 
     zoomOut() {
@@ -159,7 +168,10 @@ export class PipelineAssemblyComponent implements OnInit {
     }
 
     doZoom(zoomOut) {
-        ($("#assembly") as any).panzoom("zoom", zoomOut);
+        zoomOut ? this.panzoom.zoomOut() : this.panzoom.zoomIn();
+        this.currentZoomLevel = this.panzoom.getScale();
+        this.JsplumbBridge.setZoom(this.currentZoomLevel);
+        this.JsplumbBridge.repaintEverything();
     }
 
     showClearAssemblyConfirmDialog(event: any) {
@@ -273,4 +285,36 @@ export class PipelineAssemblyComponent implements OnInit {
         this.pipelineCanvasMaximizedEmitter.emit(this.pipelineCanvasMaximized);
     }
 
+    panLeft() {
+        this.pan(100, 0);
+    }
+
+    panRight() {
+        console.log("panning right");
+        this.pan(-100, 0);
+    }
+
+    panUp() {
+        this.pan(0, 100);
+    }
+
+    panDown() {
+        this.pan(0, -100);
+    }
+
+    panHome() {
+        this.panAbsolute(0, 0);
+    }
+
+    pan(xOffset: number, yOffset: number) {
+        let currentPan = this.panzoom.getPan();
+        let panX = Math.min(0, currentPan.x + xOffset);
+        let panY = Math.min(0, currentPan.y + yOffset);
+        let values = this.panzoom.pan(panX, panY);
+    }
+
+    panAbsolute(x: number, y: number) {
+        this.panzoom.pan(x, y);
+    }
+
 }
diff --git a/ui/src/app/editor/components/pipeline/pipeline.component.ts b/ui/src/app/editor/components/pipeline/pipeline.component.ts
index c5486e7..a4a3a34 100644
--- a/ui/src/app/editor/components/pipeline/pipeline.component.ts
+++ b/ui/src/app/editor/components/pipeline/pipeline.component.ts
@@ -99,8 +99,8 @@ export class PipelineComponent implements OnInit, OnDestroy {
   currentZoomLevel: any;
   TransitionService: any;
 
-  canvasWidth: string = "1000%";
-  canvasHeight: string = "1000%";
+  canvasWidth: string = "100%";
+  canvasHeight: string = "100%";
 
   JsplumbBridge: JsplumbBridge;
 
diff --git a/ui/src/app/editor/editor.module.ts b/ui/src/app/editor/editor.module.ts
index 1794b56..b5c10e0 100644
--- a/ui/src/app/editor/editor.module.ts
+++ b/ui/src/app/editor/editor.module.ts
@@ -63,7 +63,6 @@ import {PipelineElementTemplateConfigComponent} from "./components/pipeline-elem
 import {EnabledPipelineElementFilter} from "./filter/enabled-pipeline-element.filter";
 import {PipelineElementDraggedService} from "./services/pipeline-element-dragged.service";
 import {PipelineCanvasScrollingService} from "./services/pipeline-canvas-scrolling.service";
-import {PerfectScrollbarModule} from "ngx-perfect-scrollbar";
 import {JsplumbEndpointService} from "./services/jsplumb-endpoint.service";
 import {JsplumbFactoryService} from "./services/jsplumb-factory.service";
 
@@ -83,7 +82,6 @@ import {JsplumbFactoryService} from "./services/jsplumb-factory.service";
         MatProgressSpinnerModule,
         ShowdownModule,
         ReactiveFormsModule,
-        PerfectScrollbarModule
     ],
     declarations: [
         CompatibleElementsComponent,
diff --git a/ui/src/scss/_variables.scss b/ui/src/scss/_variables.scss
index 9c2954e..73382b0 100644
--- a/ui/src/scss/_variables.scss
+++ b/ui/src/scss/_variables.scss
@@ -21,10 +21,11 @@ $sp-color-primary-light: rgb(59, 205, 76);
 $sp-color-accent: rgb(27, 20, 100);
 $sp-color-accent-light-blue: rgb(59, 92, 149);
 $sp-color-accent-light: rgb(156, 156, 156);
+$sp-color-accent-light-transparent: rgba(156, 156, 156, 0.4);
 
 $sp-color-stream: #FFEB3B;
 $sp-color-set: #ffa23b;
 $sp-color-processor: #009688;
 $sp-color-sink: #3F51B5;
 
-$sp-color-error: #B71C1C;
\ No newline at end of file
+$sp-color-error: #B71C1C;
diff --git a/ui/src/scss/main.scss b/ui/src/scss/main.scss
index 020b977..0ff0bdd 100644
--- a/ui/src/scss/main.scss
+++ b/ui/src/scss/main.scss
@@ -35,7 +35,6 @@
 //@import '~material-design-icons/iconfont/material-icons.css';
 @import '~quill/dist/quill.snow.css';
 @import '~swagger-ui/dist/swagger-ui.css';
-@import '~perfect-scrollbar/css/perfect-scrollbar.css';
 
 @import '~roboto-fontface/css/roboto/roboto-fontface.css';