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

Load positions

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