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