Skip to content
Snippets Groups Projects
Commit b1713168 authored by Julian Matschinske's avatar Julian Matschinske
Browse files

Merge branch 'load-positions' into 'master'

Load positions

See merge request covid-19/frontend!11
parents 2809219f 6358448d
No related branches found
No related tags found
No related merge requests found
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import {AppRoutingModule} from './app-routing.module';
import {AppComponent} from './app.component';
import {ExplorerPageComponent} from './pages/explorer-page/explorer-page.component';
import {AboutPageComponent} from './pages/about-page/about-page.component';
import {HomePageComponent} from './pages/home-page/home-page.component';
import { HttpClientModule } from '@angular/common/http';
import {HttpClientModule} from '@angular/common/http';
@NgModule({
declarations: [
......@@ -24,10 +23,11 @@ import { HttpClientModule } from '@angular/common/http';
AppRoutingModule,
FormsModule,
CommonModule,
HttpClientModule
HttpClientModule,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
export class AppModule {
}
......@@ -81,6 +81,24 @@
</button>
</footer>
</div>
<div class="card bar">
<header class="card-header">
<p class="card-header-title">
<span class="icon">
<i class="fas fa-cog" aria-hidden="true"></i>
</span> Settings
</p>
</header>
<div class="card-content">
<div class="content">
<label class="checkbox">
<input type="checkbox" class="checkbox" [(ngModel)]="physicsEnabled" (ngModelChange)="physicsEnabled = $event; updatePhysicsEnabled()">
Physics enabled
</label>
</div>
</div>
</div>
</div>
<div class="content bar-right">
......
import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../../environments/environment';
import {Effect, ProteinNetwork} from '../protein-network';
import { ApiService } from '../../api.service';
import {HttpClient} from '@angular/common/http';
import {ApiService} from '../../api.service';
declare var vis: any;
......@@ -37,9 +36,12 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
private seed = 1; // TODO: Remove this
private dumpPositions = false;
public physicsEnabled = false;
@ViewChild('network', {static: false}) networkEl: ElementRef;
constructor(private route: ActivatedRoute, private router: Router, private api: ApiService) {
constructor(private http: HttpClient, private route: ActivatedRoute, private router: Router, private api: ApiService) {
this.groupId = 'IFI16';
this.geneNames.push('IFI16');
this.proteinNames.push('Gamma-interface-inducible protein 16');
......@@ -51,6 +53,9 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
this.baitNames.push('Bait Protein 5');
this.route.queryParams.subscribe(async (params) => {
this.dumpPositions = params.dumpPositions;
this.physicsEnabled = !!this.dumpPositions;
const proteinGroup = params.proteinGroup;
if (!proteinGroup) {
// In this case, the URL is just `/explorer`
......@@ -80,7 +85,6 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
}
async ngAfterViewInit() {
if (!this.network) {
await this.createNetwork();
......@@ -94,7 +98,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
this.edges = data.edges;
}
public reset(event) {
public reset(event) {
const checked = event.target.checked;
this.baitProteins.forEach(item => item.checked = checked);
this.filterNodes();
......@@ -125,7 +129,9 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
private async createNetwork() {
await this.getNetwork();
this.proteinData = new ProteinNetwork(this.proteinGroups, this.effects, this.edges);
this.proteinData.loadPositions();
if (!this.dumpPositions) {
await this.proteinData.loadPositions(this.http);
}
this.proteinData.linkNodes();
// Populate baits
......@@ -150,6 +156,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
smooth: false,
},
physics: {
enabled: this.physicsEnabled,
stabilization: {
enabled: false,
},
......@@ -167,9 +174,9 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
}
});
if (!localStorage.getItem('positions')) {
if (this.dumpPositions) {
this.network.on('stabilizationIterationsDone', () => {
localStorage.setItem('positions', JSON.stringify(this.network.getPositions()));
console.log(JSON.stringify(this.network.getPositions()));
});
this.network.stabilize();
}
......@@ -191,7 +198,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
const connectedProteinGroupIds = new Set<number>();
this.baitProteins.forEach((bait) => {
const nodeId = `eff${bait.data.id}`;
const nodeId = `eff_${bait.data.name}`;
const found = visibleIds.has(nodeId);
if ((bait.checked || showAll) && !found) {
const node = this.mapEffectToNode(bait.data);
......@@ -208,7 +215,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
}
});
for (const proteinGroup of this.proteinData.proteinGroups) {
const nodeId = `pg${proteinGroup.id}`;
const nodeId = `pg_${proteinGroup.groupId}`;
const contains = connectedProteinGroupIds.has(proteinGroup.id);
const found = visibleIds.has(nodeId);
if (contains && !found) {
......@@ -226,11 +233,17 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
}
public updatePhysicsEnabled() {
this.network.setOptions({
physics: {enabled: this.physicsEnabled},
});
}
private mapProteinGroupToNode(proteinGroup: any): any {
return {
id: `pg${proteinGroup.id}`,
label: `pg${proteinGroup.id}`,
size: 5, color: '#ADADAD', shape: 'square', shadow: true,
id: `pg_${proteinGroup.groupId}`,
label: `${proteinGroup.name}`,
size: 10, font: '5px', color: '#e2b600', shape: 'ellipse', shadow: false,
x: proteinGroup.x,
y: proteinGroup.y
};
......@@ -238,16 +251,16 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
private mapEffectToNode(effect: any): any {
return {
id: `eff${effect.id}`,
label: `eff${effect.id}`,
size: 10, color: '#118AB2', shape: 'circle', shadow: true,
id: `eff_${effect.name}`,
label: `${effect.name}`,
size: 10, color: '#118AB2', shape: 'box', shadow: true, font: {color: '#FFFFFF'},
x: effect.x,
y: effect.y
};
}
private mapEdge(edge: any): any {
return {from: `pg${edge.proteinGroupId}`, to: `eff${edge.effectId}`};
return {from: `pg_${edge.groupId}`, to: `eff_${edge.effectName}`, color: { color: '#afafaf', highlight: '#854141' }};
}
private mapDataToNodes(data: ProteinNetwork): { nodes: any[], edges: any[] } {
......
import {HttpClient} from '@angular/common/http';
export interface ProteinGroup {
id: number;
name: string;
groupId: number;
effects?: Effect[];
x?: number;
y?: number;
......@@ -15,8 +18,8 @@ export interface Effect {
}
export interface Edge {
proteinGroupId: number;
effectId: number;
groupId: number;
effectName: string;
}
export class ProteinNetwork {
......@@ -24,21 +27,17 @@ export class ProteinNetwork {
constructor(public proteinGroups: ProteinGroup[], public effects: Effect[], public edges: Edge[]) {
}
public loadPositions() {
const savedPositions = localStorage.getItem('positions');
if (!savedPositions) {
return;
}
const nodePositions = JSON.parse(savedPositions);
public async loadPositions(http: HttpClient) {
const nodePositions = await http.get(`assets/positions/network.json`).toPromise();
this.proteinGroups.forEach((node) => {
const nodePosition = nodePositions[`pg${node.id}`];
const nodePosition = nodePositions[`pg_${node.groupId}`];
if (nodePosition) {
node.x = nodePosition.x;
node.y = nodePosition.y;
}
});
this.effects.forEach((node) => {
const nodePosition = nodePositions[`eff${node.id}`];
const nodePosition = nodePositions[`eff_${node.name}`];
if (nodePosition) {
node.x = nodePosition.x;
node.y = nodePosition.y;
......@@ -47,11 +46,11 @@ export class ProteinNetwork {
}
public getProteinGroup(id: number): ProteinGroup {
return this.proteinGroups.find((pg) => pg.id === id);
return this.proteinGroups.find((pg) => pg.groupId === id);
}
public getEffect(id: number): Effect {
return this.effects.find((eff) => eff.id === id);
public getEffect(name: string): Effect {
return this.effects.find((eff) => eff.name === name);
}
public linkNodes() {
......@@ -62,8 +61,8 @@ export class ProteinNetwork {
eff.proteinGroups = [];
});
this.edges.forEach((edge) => {
const proteinGroup = this.getProteinGroup(edge.proteinGroupId);
const effect = this.getEffect(edge.effectId);
const proteinGroup = this.getProteinGroup(edge.groupId);
const effect = this.getEffect(edge.effectName);
if (proteinGroup && effect) {
proteinGroup.effects.push(effect);
effect.proteinGroups.push(proteinGroup);
......
This diff is collapsed.
export const environment = {
production: true,
backend: 'https://exbio.wzw.tum.de/covid19-api/',
backend: 'https://exbio.wzw.tum.de/covid19/api/',
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment