From 7366bf164bb30c2088407af70a9987b88648b834 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julian=20Sp=C3=A4th?= <julian.spaeth@wzw.tum.de>
Date: Mon, 30 Mar 2020 16:50:08 +0200
Subject: [PATCH] Node selection zoom

---
 .../explorer-page.component.html              | 152 ++++++++++++------
 .../explorer-page/explorer-page.component.ts  |  28 +++-
 src/styles.scss                               |  14 +-
 3 files changed, 131 insertions(+), 63 deletions(-)

diff --git a/src/app/pages/explorer-page/explorer-page.component.html b/src/app/pages/explorer-page/explorer-page.component.html
index a600f48d..04f20ef3 100644
--- a/src/app/pages/explorer-page/explorer-page.component.html
+++ b/src/app/pages/explorer-page/explorer-page.component.html
@@ -1,42 +1,42 @@
 <div class="content explorer">
 
-  <div class="modal" [class.is-active]="showModal">
-    <div class="modal-background" (click)="closeSummary()"></div>
-    <div class="modal-card">
-      <header class="modal-card-head">
-        <p class="modal-card-title">{{groupId}}</p>
-        <button class="delete" aria-label="close" (click)="closeSummary()"></button>
-      </header>
-      <section class="modal-card-body">
-        <h2>General Information</h2>
-        <ul>
-          <li><b>Protein Group:</b> {{proteinGroup}}</li>
-          <li><b>Gene Name(s):</b> <span *ngFor="let geneName of geneNames"> {{ geneName }}</span>
-          <li><b>Protein Name(s):</b> <span *ngFor="let proteinName of proteinNames"> {{ proteinName }}</span>
-          </li>
-          <li><b>Protein AC(s):</b>
-            <a href="https://www.uniprot.org/uniprot/{{proteinAC}}" target="_blank"
-               *ngFor="let proteinAC of proteinACs">
-              {{ proteinAC }}<span><img class="inline" align="center" src="../assets/uniprot.png"></span>
-            </a>
-          </li>
-          <li><b>Number of Interactions:</b> {{numberOfInteractions}}</li>
-        </ul>
-
-        <h2>Summary</h2>
-        <figure class="image" (click)="openSummary('A4435')">
-          <img src="../assets/boxplot.png" alt="Boxplots">
-        </figure>
-      </section>
-
-      <footer class="modal-card-foot">
-        <button class="button is-danger" (click)="closeSummary()">Close</button>
-      </footer>
-    </div>
-  </div>
+  <!--  <div class="modal" [class.is-active]="showModal">
+      <div class="modal-background" (click)="closeSummary()"></div>
+      <div class="modal-card">
+        <header class="modal-card-head">
+          <p class="modal-card-title">{{groupId}}</p>
+          <button class="delete" aria-label="close" (click)="closeSummary()"></button>
+        </header>
+        <section class="modal-card-body">
+          <h2>General Information</h2>
+          <ul>
+            <li><b>Protein Group:</b> {{proteinGroup}}</li>
+            <li><b>Gene Name(s):</b> <span *ngFor="let geneName of geneNames"> {{ geneName }}</span>
+            <li><b>Protein Name(s):</b> <span *ngFor="let proteinName of proteinNames"> {{ proteinName }}</span>
+            </li>
+            <li><b>Protein AC(s):</b>
+              <a href="https://www.uniprot.org/uniprot/{{proteinAC}}" target="_blank"
+                 *ngFor="let proteinAC of proteinACs">
+                {{ proteinAC }}<span><img class="inline" align="center" src="../assets/uniprot.png"></span>
+              </a>
+            </li>
+            <li><b>Number of Interactions:</b> {{numberOfInteractions}}</li>
+          </ul>
 
+          <h2>Summary</h2>
+          <figure class="image" (click)="openSummary('A4435')">
+            <img src="../assets/boxplot.png" alt="Boxplots">
+          </figure>
+        </section>
+
+        <footer class="modal-card-foot">
+          <button class="button is-danger" (click)="closeSummary()">Close</button>
+        </footer>
+      </div>
+    </div>-->
 
-  <div class="content bar">
+
+  <div class="content bar-left">
 
     <div class="card bar">
       <header class="card-header">
@@ -115,29 +115,79 @@
     </div>
   </div>
 
-  <div class="content network">
+  <div class="content bar-right">
+
+    <div class="card bar">
+      <header class="card-header">
+        <p class="card-header-title">
+          <span class="icon">
+        <i class="fas fa-info" aria-hidden="true"></i>
+      </span> Details
+        </p>
+      </header>
+      <div class="card-content">
+        <div *ngIf="showDetails" class="content">
 
-     <div class="card network">
-    <header class="card-header">
-      <p class="card-header-title">
-        SARS-CoV-2 Protein-Protein Interaction Network
-      </p>
-    </header>
-    <div class="card-content">
-      <div class="card-image">
-        <div class="network center" #network>
-          <button class="button is-loading center">Loading</button>
+          <p><b>Protein Group:</b> {{ proteinGroup }}</p>
+          <p><b>Gene Name(s):</b> <span *ngFor="let geneName of geneNames"> {{ geneName }}</span></p>
+          <p><b>Protein Name(s):</b> <span *ngFor="let proteinName of proteinNames"> {{ proteinName }}</span></p>
+          <p align="row"><b>Protein AC(s):</b>
+            <a href="https://www.uniprot.org/uniprot/{{proteinAC}}" target="_blank"
+               *ngFor="let proteinAC of proteinACs">
+              {{ proteinAC }}
+            </a>
+          </p>
         </div>
+        <div *ngIf="!showDetails">
+          Please select a node for further information.
+        </div>
+
       </div>
-      <footer class="card-footer">
-        <button class="card-footer-item button is-primary">
+    </div>
+
+    <div class="card bar">
+      <header class="card-header">
+        <p class="card-header-title">
+          <span class="icon">
+        <i class="fas fa-filter" aria-hidden="true"></i>
+      </span> Summary
+        </p>
+      </header>
+      <div *ngIf="showDetails" class="card-content">
+        <div class="content">
+          <h2>Summary</h2>
+          <figure class="image">
+            <img src="assets/boxplot.png" alt="Boxplots">
+          </figure>
+        </div>
+      </div>
+    </div>
+
+  </div>
+
+  <div class="content network">
+
+    <div class="card network">
+      <header class="card-header">
+        <p class="card-header-title">
+          SARS-CoV-2 Protein-Protein Interaction Network
+        </p>
+      </header>
+      <div class="card-content">
+        <div class="card-image">
+          <div class="network center" #network>
+            <button class="button is-loading center">Loading</button>
+          </div>
+        </div>
+        <footer class="card-footer">
+          <button class="card-footer-item button is-primary">
                 <span class="icon">
         <i class="fas fa-cloud-download-alt" aria-hidden="true"></i>
       </span>
-        </button>
-      </footer>
+          </button>
+        </footer>
+      </div>
     </div>
   </div>
-</div>
 
 </div>
diff --git a/src/app/pages/explorer-page/explorer-page.component.ts b/src/app/pages/explorer-page/explorer-page.component.ts
index 75f722b2..814ca577 100644
--- a/src/app/pages/explorer-page/explorer-page.component.ts
+++ b/src/app/pages/explorer-page/explorer-page.component.ts
@@ -9,7 +9,7 @@ import {Network, Edge, Node} from 'vis-network';
 })
 export class ExplorerPageComponent implements OnInit, AfterViewInit {
 
-  public showModal = false;
+  public showDetails = false;
   public groupId = '';
   public geneNames: Array<string> = [];
   public proteinGroup = '';
@@ -30,7 +30,6 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
     this.geneNames.push('IFI16');
     this.proteinNames.push('Gamma-interface-inducible protein 16');
     this.proteinACs.push('Q16666');
-    this.numberOfInteractions = 25;
     this.baitNames.push('Bait Protein 1');
     this.baitNames.push('Bait Protein 2');
     this.baitNames.push('Bait Protein 3');
@@ -42,7 +41,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
       if (!proteinGroup) {
         // In this case, the URL is just `/explorer`
         // Therefore, we do not show a modal
-        this.showModal = false;
+        this.showDetails = false;
         return;
       }
 
@@ -58,8 +57,8 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
       this.proteinGroup = proteinGroup;
 
       // TODO: Perform call here for 'proteinGroup'...
-
-      this.showModal = true;
+      // this.zoomToNode(proteinGroup)
+      this.showDetails = true;
     });
   }
 
@@ -75,12 +74,22 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
     }
   }
 
+  public zoomToNode(id: string) {
+    const coords = this.network.getPositions(id)[id];
+    this.network.moveTo({
+      position: {x: coords.x, y: coords.y},
+      scale: 1.0,
+      animation: true,
+    });
+  }
+
   public getGroupId() {
     return this.groupId;
   }
 
   public async openSummary(groupId: string) {
     await this.router.navigate(['explorer'], {queryParams: {proteinGroup: groupId}});
+    this.zoomToNode(this.proteinGroup);
   }
 
   public async closeSummary() {
@@ -890,8 +899,6 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
       });
     }
 
-
-
     this.numberOfInteractions = edges.length;
 
     const container = this.networkEl.nativeElement;
@@ -913,8 +920,9 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
       // TODO use groupID
       console.log(id);
       if (id.length > 0) {
-        console.log('clicked node:', id);
         this.openSummary(id[0]);
+      } else {
+        this.closeSummary();
       }
     });
 
@@ -925,6 +933,10 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
       });
       this.network.stabilize();
     }
+
+    if (this.proteinGroup) {
+      this.zoomToNode(this.proteinGroup);
+    }
   }
 
 
diff --git a/src/styles.scss b/src/styles.scss
index c6289161..340e7b32 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -51,22 +51,28 @@ input.checkbox {
   margin-left: 15px;
 }
 
-div.content.bar {
+div.content.bar-left {
   float: left;
   width: 15%;
   height: calc(100vh - 30%);
 }
 
+div.content.bar-right {
+  float: right;
+  width: 15%;
+}
 
 div.card.bar {
   margin-bottom: 21px;
+  word-wrap: break-word;
 }
 
 
 div.content.network {
-  float: right;
-  width: 84%;
+  width: 68%;
   height: calc(100vh - 90px);
+  margin-left: auto;
+  margin-right: auto;
 }
 
 div.card.network {
@@ -75,7 +81,7 @@ div.card.network {
 }
 
 div.network {
-   height: calc(100vh - 240px);
+   height: calc(100vh - 220px);
 }
 
 div.center {
-- 
GitLab