Skip to content
Snippets Groups Projects
Commit 7600038f authored by Julian Späth's avatar Julian Späth
Browse files

Merge branch 'extend-selection-and-beautify' into 'master'

Extend selection and beautify

See merge request covid-19/frontend!45
parents a21d8887 8f55f155
Branches
Tags
No related merge requests found
Showing
with 179 additions and 97 deletions
...@@ -13,7 +13,7 @@ import {HomePageComponent} from './pages/home-page/home-page.component'; ...@@ -13,7 +13,7 @@ import {HomePageComponent} from './pages/home-page/home-page.component';
import {HttpClientModule} from '@angular/common/http'; import {HttpClientModule} from '@angular/common/http';
import {QueryComponent} from './components/query/query.component'; import {QueryComponent} from './components/query/query.component';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {ProteinAnalysisComponent} from './components/protein-analysis/protein-analysis.component'; import {LaunchAnalysisComponent} from './components/launch-analysis/launch-analysis.component';
import {SelectDatasetComponent} from './components/select-dataset/select-dataset.component'; import {SelectDatasetComponent} from './components/select-dataset/select-dataset.component';
import {AnalysisWindowComponent} from './components/analysis-window/analysis-window.component'; import {AnalysisWindowComponent} from './components/analysis-window/analysis-window.component';
import {TaskListComponent} from './components/task-list/task-list.component'; import {TaskListComponent} from './components/task-list/task-list.component';
...@@ -27,7 +27,7 @@ import {AnalysisService} from './analysis.service'; ...@@ -27,7 +27,7 @@ import {AnalysisService} from './analysis.service';
AboutPageComponent, AboutPageComponent,
HomePageComponent, HomePageComponent,
QueryComponent, QueryComponent,
ProteinAnalysisComponent, LaunchAnalysisComponent,
SelectDatasetComponent, SelectDatasetComponent,
AnalysisWindowComponent, AnalysisWindowComponent,
TaskListComponent, TaskListComponent,
......
...@@ -21,10 +21,10 @@ ...@@ -21,10 +21,10 @@
<button class="button is-loading center">Loading</button> <button class="button is-loading center">Loading</button>
</div> </div>
</div> </div>
<footer class="card-footer"> <footer class="card-footer toolbar">
<div class="field has-addons"> <div class="field has-addons">
<p class="control"> <p class="control">
<button class="button is-rounded is-success" [disabled]="true"> <button class="button is-rounded is-success is-rounded" [disabled]="true">
<span class="icon"> <span class="icon">
<i class="fas fa-cloud-download-alt" aria-hidden="true"></i> <i class="fas fa-cloud-download-alt" aria-hidden="true"></i>
</span> </span>
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
</button> </button>
</p> </p>
<p class="control"> <p class="control">
<button class="button is-primary" [disabled]="true"> <button class="button is-primary is-rounded" [disabled]="true">
<span class="icon"> <span class="icon">
<i class="fas fa-camera" aria-hidden="true"></i> <i class="fas fa-camera" aria-hidden="true"></i>
</span> </span>
......
<div class="modal" [class.is-active]="show">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title">Launch Analysis</p>
<button (click)="close()" class="delete" aria-label="close"></button>
</header>
<section class="modal-card-body">
<div class="tabs is-toggle is-small is-fullwidth is-rounded">
<ul>
<li [class.is-active]="algorithm === 'dummy'">
<a (click)="algorithm = 'dummy'" class="is-boxed is-medium">Dummy</a>
</li>
<li [class.is-active]="algorithm === 'trustrank'">
<a (click)="algorithm = 'trustrank'" class="is-boxed is-medium">Trustrank</a>
</li>
<li [class.is-active]="algorithm === 'keypathwayminer'">
<a (click)="algorithm = 'keypathwayminer'" class="is-boxed is-medium">KeyPathwayMiner</a>
</li>
<li [class.is-active]="algorithm === 'multisteiner'">
<a (click)="algorithm = 'multisteiner'" class="is-boxed is-medium">Multi-Steiner</a>
</li>
</ul>
</div>
<div *ngIf="algorithm==='trustrank'">
<div class="field">
<label class="label" for="trustrank-strain">Strain</label>
<div class="control">
<div class="select">
<select id="trustrank-strain" [(ngModel)]="trustrankStrain">
<option [ngValue]="'SARS_CoV2'">SARS Coronavirus 2</option>
<option [ngValue]="'drugs'">Drugs</option>
</select>
</div>
</div>
</div>
<div class="field">
<label class="label" for="trustrank-df">Damping Factor</label>
<div class="control">
<input [(ngModel)]="trustrankDampingFactor" id="trustrank-df" class="input" type="number"
placeholder="Damping factor"
min="0" max="1"
required>
</div>
</div>
<div class="field">
<label class="label" for="trustrank-rs">Result Size</label>
<div class="control">
<input [(ngModel)]="trustrankResultSize" id="trustrank-rs" class="input" type="number"
placeholder="Result size" required>
</div>
</div>
</div>
<div *ngIf="algorithm==='keypathwayminer'">
<div class="field">
<label class="label" for="keypathwayminer-k">K</label>
<div class="control">
<div class="select">
<select id="keypathwayminer-k" [(ngModel)]="keypathwayminerK">
<option [ngValue]="1">1</option>
<option [ngValue]="2">2</option>
<option [ngValue]="3">3</option>
<option [ngValue]="4">4</option>
<option [ngValue]="5">5</option>
</select>
</div>
</div>
</div>
</div>
<div *ngIf="algorithm==='multisteiner'">
<div class="field">
<label class="label" for="multisteiner-strain">Virus Strain</label>
<div class="control">
<div class="select">
<select id="multisteiner-strain" [(ngModel)]="multisteinerStrain">
<option [ngValue]="'SARS_CoV2'">SARS Coronavirus 2</option>
</select>
</div>
</div>
</div>
<div class="field">
<label class="label" for="multisteiner-numtrees">Number of Steiner trees to return</label>
<div class="control">
<div class="select">
<select id="multisteiner-numtrees" [(ngModel)]="multisteinerNumTrees">
<option [ngValue]="1">1</option>
<option [ngValue]="2">2</option>
<option [ngValue]="3">3</option>
<option [ngValue]="5">5</option>
<option [ngValue]="10">10</option>
<option [ngValue]="15">15</option>
<option [ngValue]="20">20</option>
<option [ngValue]="25">25</option>
</select>
</div>
</div>
</div>
</div>
</section>
<footer class="modal-card-foot">
<button (click)="startTask(); close()" class="button is-success is-rounded">Launch</button>
<button (click)="close()" class="button is-rounded">Close</button>
</footer>
</div>
</div>
.modal-card {
height: 500px;
}
...@@ -2,11 +2,11 @@ import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; ...@@ -2,11 +2,11 @@ import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {AnalysisService} from '../../analysis.service'; import {AnalysisService} from '../../analysis.service';
@Component({ @Component({
selector: 'app-protein-analysis', selector: 'app-launch-analysis',
templateUrl: './protein-analysis.component.html', templateUrl: './launch-analysis.component.html',
styleUrls: ['./protein-analysis.component.scss'] styleUrls: ['./launch-analysis.component.scss']
}) })
export class ProteinAnalysisComponent implements OnInit { export class LaunchAnalysisComponent implements OnInit {
@Input() @Input()
public show = false; public show = false;
...@@ -23,6 +23,9 @@ export class ProteinAnalysisComponent implements OnInit { ...@@ -23,6 +23,9 @@ export class ProteinAnalysisComponent implements OnInit {
public trustrankDatasets = []; public trustrankDatasets = [];
public trustrankIgnoredEdgeTypes = []; public trustrankIgnoredEdgeTypes = [];
// Keypathwayminer Parameters
public keypathwayminerK = 1;
// Multisteiner Parameters // Multisteiner Parameters
public multisteinerStrain = 'SARS_CoV2'; public multisteinerStrain = 'SARS_CoV2';
public multisteinerNumTrees = 5; public multisteinerNumTrees = 5;
......
<div class="modal" [class.is-active]="show">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title">Launch Analysis</p>
<button (click)="close()" class="delete" aria-label="close"></button>
</header>
<section class="modal-card-body">
<div class="tabs is-toggle is-medium is-fullwidth">
<ul>
<li [class.is-active]="algorithm === 'dummy'"><a (click)="algorithm = 'dummy'" class="is-boxed is-medium">Dummy</a>
</li>
<li [class.is-active]="algorithm === 'trustrank'"><a (click)="algorithm = 'trustrank'"
class="is-boxed is-medium">Trustrank</a></li>
<li [class.is-active]="algorithm === 'keypathwayminer'"><a (click)="algorithm = 'keypathwayminer'"
class="is-boxed is-medium">KeyPathwayMiner</a></li>
<li [class.is-active]="algorithm === 'multisteiner'"><a (click)="algorithm = 'multisteiner'"
class="is-boxed is-medium">Multi-Steiner</a></li>
</ul>
</div>
<div *ngIf="algorithm==='trustrank'">
<div class="field">
<p class="control has-icons-left has-icons-right">
<label>Strain</label>
<input [(ngModel)]="trustrankStrain" class="input" type="text" placeholder="Strain" required>
</p>
<p class="control has-icons-left has-icons-right">
<label>Damping Factor</label>
<input [(ngModel)]="trustrankDampingFactor" class="input" type="number" placeholder="Damping factor"
min="0" max="1"
required>
</p>
<p class="control has-icons-left has-icons-right">
<label>Result Size</label>
<input [(ngModel)]="trustrankResultSize" class="input" type="number" placeholder="Result size" required>
</p>
</div>
</div>
<div *ngIf="algorithm==='keypathwayminer'">
<h1>Key Pathway Miner</h1>
</div>
<div *ngIf="algorithm==='multisteiner'">
<h1>Multi-Steiner</h1>
<p class="control has-icons-left has-icons-right">
<label>Virus Strain</label>
<input [(ngModel)]="multisteinerStrain" class="input" type="text" placeholder="Virus Strain" required>
</p>
<p class="control has-icons-left has-icons-right">
<label>Number of Steiner trees to return</label>
<input [(ngModel)]="multisteinerNumTrees" class="input" type="number" min="1" max="25"
placeholder="Number of Steiner trees to return" required>
</p>
</div>
</section>
<footer class="modal-card-foot">
<button (click)="startTask(); close()" class="button is-success">Launch</button>
<button (click)="close()" class="button">Close</button>
</footer>
</div>
</div>
<app-protein-analysis [(show)]="showAnalysisDialog"></app-protein-analysis> <app-launch-analysis [(show)]="showAnalysisDialog"></app-launch-analysis>
<div class="covex explorer"> <div class="covex explorer">
...@@ -115,8 +115,8 @@ ...@@ -115,8 +115,8 @@
<button class="button is-loading center">Loading</button> <button class="button is-loading center">Loading</button>
</div> </div>
</div> </div>
<footer class="card-footer"> <footer class="card-footer toolbar">
<button (click)="toCanvas()" class="button is-primary"> <button (click)="toCanvas()" class="button is-primary is-rounded">
<span class="icon"> <span class="icon">
<i class="fas fa-camera" aria-hidden="true"></i> <i class="fas fa-camera" aria-hidden="true"></i>
</span> <span>Screenshot</span> </span> <span>Screenshot</span>
...@@ -208,7 +208,7 @@ ...@@ -208,7 +208,7 @@
</header> </header>
<div class="card-content"> <div class="card-content">
<button (click)="showAnalysisDialog = true" <button (click)="showAnalysisDialog = true"
class="button is-primary is-fullwidth" class="button is-primary is-fullwidth is-rounded"
[disabled]="analysis.getCount() === 0"> [disabled]="analysis.getCount() === 0">
<span class="icon"> <span class="icon">
<i class="fa fa-rocket"></i> <i class="fa fa-rocket"></i>
...@@ -274,6 +274,24 @@ ...@@ -274,6 +274,24 @@
To select proteins, click them while pressing CTRL. To select proteins, click them while pressing CTRL.
</i> </i>
</div> </div>
<footer class="card-footer">
<a (click)="addAllHostProteins()" class="card-footer-item has-text-success">
<span class="icon">
<i class="fa fa-plus"></i>
</span>
<span>
Host Proteins
</span>
</a>
<a class="card-footer-item has-text-grey-light">
<span class="icon">
<i class="fa fa-plus"></i>
</span>
<span>
Viral Proteins
</span>
</a>
</footer>
<footer class="card-footer"> <footer class="card-footer">
<a (click)="analysis.resetSelection()" class="card-footer-item has-text-danger"> <a (click)="analysis.resetSelection()" class="card-footer-item has-text-danger">
<span class="icon"> <span class="icon">
......
...@@ -288,17 +288,17 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { ...@@ -288,17 +288,17 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
const filteredViralProteins = []; const filteredViralProteins = [];
this.viralProteinCheckboxes.forEach((cb) => { this.viralProteinCheckboxes.forEach((cb) => {
const effects: Array<ViralProtein> = []; const viralProteins: Array<ViralProtein> = [];
this.proteinData.effects.forEach((effect) => { this.proteinData.effects.forEach((effect) => {
if (effect.effectName === cb.data.effectName) { if (effect.effectName === cb.data.effectName) {
effects.push(effect); viralProteins.push(effect);
} }
}); });
effects.forEach((effect) => { viralProteins.forEach((effect) => {
const nodeId = `eff_${effect.effectName}_${effect.virusName}_${effect.datasetName}`; const nodeId = `eff_${effect.effectName}_${effect.virusName}_${effect.datasetName}`;
const found = visibleIds.has(nodeId); const found = visibleIds.has(nodeId);
if ((cb.checked || showAll) && !found) { if ((cb.checked || showAll) && !found) {
const node = this.mapEffectToNode(effect); const node = this.mapViralProteinToNode(effect);
// this.nodeData.nodes.add(node); // this.nodeData.nodes.add(node);
addNodes.set(node.id, node); addNodes.set(node.id, node);
} else if ((!showAll && !cb.checked) && found) { } else if ((!showAll && !cb.checked) && found) {
...@@ -322,7 +322,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { ...@@ -322,7 +322,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
filteredProteins.push(protein); filteredProteins.push(protein);
if (!found) { if (!found) {
const node = this.mapProteinToNode(protein); const node = this.mapHostProteinToNode(protein);
addNodes.set(node.id, node); addNodes.set(node.id, node);
} }
} else if (found) { } else if (found) {
...@@ -359,7 +359,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { ...@@ -359,7 +359,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
}); });
} }
private mapProteinToNode(protein: Protein): any { private mapHostProteinToNode(protein: Protein): any {
let color = '#e2b600'; let color = '#e2b600';
if (this.analysis.inSelection(protein)) { if (this.analysis.inSelection(protein)) {
color = '#48C774'; color = '#48C774';
...@@ -373,7 +373,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { ...@@ -373,7 +373,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
}; };
} }
private mapEffectToNode(effect: ViralProtein): any { private mapViralProteinToNode(effect: ViralProtein): any {
return { return {
id: `eff_${effect.effectName}_${effect.virusName}_${effect.datasetName}`, id: `eff_${effect.effectName}_${effect.virusName}_${effect.datasetName}`,
label: `${effect.effectName} (${effect.virusName}, ${effect.datasetName})`, label: `${effect.effectName} (${effect.virusName}, ${effect.datasetName})`,
...@@ -396,11 +396,11 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { ...@@ -396,11 +396,11 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
const edges = []; const edges = [];
for (const protein of data.proteins) { for (const protein of data.proteins) {
nodes.push(this.mapProteinToNode(protein)); nodes.push(this.mapHostProteinToNode(protein));
} }
for (const effect of data.effects) { for (const effect of data.effects) {
nodes.push(this.mapEffectToNode(effect)); nodes.push(this.mapViralProteinToNode(effect));
} }
for (const edge of data.edges) { for (const edge of data.edges) {
...@@ -413,6 +413,17 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { ...@@ -413,6 +413,17 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
}; };
} }
public addAllHostProteins() {
const visibleIds = new Set<string>(this.nodeData.nodes.getIds());
for (const protein of this.proteinData.proteins) {
const nodeId = `p_${protein.proteinAc}`;
const found = visibleIds.has(nodeId);
if (found && !this.analysis.inSelection(protein)) {
this.analysis.addProtein(protein);
}
}
}
inSelection(proteinAc: string): boolean { inSelection(proteinAc: string): boolean {
if (!this.proteinData || !proteinAc) { if (!this.proteinData || !proteinAc) {
return false; return false;
......
...@@ -164,6 +164,10 @@ div.field.has-addons.footer-toggle-buttons { ...@@ -164,6 +164,10 @@ div.field.has-addons.footer-toggle-buttons {
margin-right: 10px; margin-right: 10px;
} }
.toolbar {
padding: 5px;
border-top: 2px solid #d0d0d0;
}
html, body { height: 100%; } html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment