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

Merge branch 'apply-color-scheme' into 'master'

Better Colors

See merge request covid-19/frontend!70
parents a1f30a25 29a37e62
No related branches found
No related tags found
No related merge requests found
Showing
with 618 additions and 438 deletions
import {QueryItem, Task} from './interfaces';
import {Wrapper, Task, getWrapperFromProtein, getWrapperFromViralProtein} from './interfaces';
import {Subject} from 'rxjs';
import {HttpClient} from '@angular/common/http';
import {environment} from '../environments/environment';
......@@ -33,8 +33,8 @@ export const MULTISTEINER: Algorithm = {slug: 'multisteiner', name: algorithmNam
})
export class AnalysisService {
private selectedItems = new Map<string, QueryItem>();
private selectSubject = new Subject<{ item: QueryItem, selected: boolean }>();
private selectedItems = new Map<string, Wrapper>();
private selectSubject = new Subject<{ item: Wrapper, selected: boolean }>();
public tokens: string[] = [];
public finishedTokens: string[] = [];
......@@ -76,41 +76,31 @@ export class AnalysisService {
});
}
public addItem(item: QueryItem) {
if (!this.inSelection(item.name)) {
this.selectedItems.set(`${item.name}`, item);
this.selectSubject.next({item, selected: true});
public addItem(wrapper: Wrapper) {
if (!this.inSelection(wrapper)) {
this.selectedItems.set(wrapper.nodeId, wrapper);
this.selectSubject.next({item: wrapper, selected: true});
}
}
public addAllHostProteins(nodes, proteins) {
const visibleIds = new Set<string>(nodes.getIds());
for (const protein of proteins) {
const nodeId = protein.proteinAc;
const found = visibleIds.has(nodeId) || visibleIds.has('p_' + nodeId);
if (found && !this.inSelection(protein.name)) {
this.addItem({
name: protein.proteinAc,
type: 'Host Protein',
data: protein
});
const wrapper = getWrapperFromProtein(protein);
const found = visibleIds.has(wrapper.nodeId);
if (found && !this.inSelection(wrapper)) {
this.addItem(wrapper);
}
}
}
public addAllViralProteins(nodes, effects) {
public addAllViralProteins(nodes, viralProteins) {
const visibleIds = new Set<string>(nodes.getIds());
for (const effect of effects) {
const nodeId = effect.effectId;
const found = visibleIds.has(nodeId) || visibleIds.has('eff_' + effect.effectName + '_' +
effect.datasetName + '_' + effect.virusName);
if (found && !this.inSelection(effect.effectName + '_' +
effect.datasetName + '_' + effect.virusName)) {
this.addItem({
name: effect.effectId,
type: 'Viral Protein',
data: effect
});
for (const viralProtein of viralProteins) {
const wrapper = getWrapperFromViralProtein(viralProtein);
const found = visibleIds.has(wrapper.nodeId);
if (found && !this.inSelection(wrapper)) {
this.addItem(wrapper);
}
}
}
......@@ -118,22 +108,22 @@ export class AnalysisService {
resetSelection() {
const oldSelection = this.selectedItems.values();
for (const item of oldSelection) {
this.removeItem(item.name);
this.removeItem(item);
}
}
inSelection(itemName: string): boolean {
return this.selectedItems.has(itemName);
inSelection(wrapper: Wrapper): boolean {
return this.selectedItems.has(wrapper.nodeId);
}
removeItem(itemName: string) {
const item = this.selectedItems.get(itemName);
if (this.selectedItems.delete(itemName)) {
removeItem(wrapper: Wrapper) {
const item = this.selectedItems.get(wrapper.nodeId);
if (this.selectedItems.delete(wrapper.nodeId)) {
this.selectSubject.next({item, selected: false});
}
}
getSelection(): QueryItem[] {
getSelection(): Wrapper[] {
return Array.from(this.selectedItems.values());
}
......@@ -141,7 +131,7 @@ export class AnalysisService {
return this.selectedItems.size;
}
subscribe(cb: (item: QueryItem, selected: boolean) => void) {
subscribe(cb: (item: Wrapper, selected: boolean) => void) {
this.selectSubject.subscribe((event) => {
cb(event.item, event.selected);
});
......@@ -165,7 +155,7 @@ export class AnalysisService {
algorithm: 'quick',
target: 'drug',
parameters: {
seeds: this.getSelection().map((i) => i.name),
seeds: this.getSelection().map((i) => i.backendId),
},
}).toPromise();
this.tokens.push(resp.token);
......
......@@ -18,6 +18,7 @@ import {SelectDatasetComponent} from './components/select-dataset/select-dataset
import {AnalysisWindowComponent} from './components/analysis-window/analysis-window.component';
import {TaskListComponent} from './components/task-list/task-list.component';
import {ToggleComponent} from './components/toggle/toggle.component';
import {InfoBoxComponent} from './components/info-box/info-box.component';
import {AnalysisService} from './analysis.service';
......@@ -34,6 +35,7 @@ import {AnalysisService} from './analysis.service';
AnalysisWindowComponent,
TaskListComponent,
ToggleComponent,
InfoBoxComponent,
],
imports: [
BrowserModule,
......
......@@ -128,7 +128,7 @@
</p>
</div>
<div *ngIf="tableDrugs.length > 0">
<div *ngIf="tableDrugs.length > 0" class="table-header">
<h4 class="is-4">
<span class="icon"><i class="fa fa-capsules"></i></span>
<span>Drugs</span>
......@@ -169,7 +169,7 @@
</ng-template>
</p-table>
<div *ngIf="tableProteins.length > 0">
<div *ngIf="tableProteins.length > 0" class="table-header">
<h4 class="is-4">
<span class="icon"><i class="fa fa-dna"></i></span>
<span>Proteins</span>
......@@ -205,7 +205,7 @@
</ng-template>
</p-table>
<div *ngIf="tableViralProteins.length > 0">
<div *ngIf="tableViralProteins.length > 0" class="table-header">
<h4 class="is-4">
<span class="icon"><i class="fa fa-virus"></i></span>
<span>Viral Proteins</span>
......
......@@ -27,3 +27,7 @@ div.network {
margin-top: 60px;
}
}
.table-header {
margin-bottom: 50px;
}
......@@ -12,9 +12,13 @@ import {
import {HttpClient, HttpErrorResponse} from '@angular/common/http';
import {environment} from '../../../environments/environment';
import {AnalysisService, algorithmNames} from '../../analysis.service';
import {Protein, Task, NodeType, ViralProtein, Drug} from '../../interfaces';
import {
Protein, Task, ViralProtein, Drug, Wrapper, WrapperType,
getWrapperFromProtein, getWrapperFromDrug, getWrapperFromViralProtein, getNodeIdsFromPPI, getNodeIdsFromPDI
} from '../../interfaces';
import html2canvas from 'html2canvas';
import {toast} from 'bulma-toast';
import {NetworkSettings} from '../../network-settings';
declare var vis: any;
......@@ -30,21 +34,17 @@ interface Scored {
})
export class AnalysisWindowComponent implements OnInit, OnChanges {
constructor(private http: HttpClient, public analysis: AnalysisService) {
}
@ViewChild('network', {static: false}) networkEl: ElementRef;
@Input() token: string | null = null;
@Output() tokenChange = new EventEmitter<string | null>();
@Output() showDetailsChange: EventEmitter<any> = new EventEmitter();
@Output() showDetailsChange = new EventEmitter<Wrapper>();
@Output() visibleItems = new EventEmitter<any>();
public task: Task | null = null;
public indexscreenshot = 1;
@ViewChild('network', {static: false}) networkEl: ElementRef;
private network: any;
private nodeData: { nodes: any, edges: any } = {nodes: null, edges: null};
private drugNodes: any[] = [];
......@@ -54,8 +54,6 @@ export class AnalysisWindowComponent implements OnInit, OnChanges {
public physicsEnabled = true;
public drugstatus = true;
private proteins: any;
public effects: any;
......@@ -65,10 +63,11 @@ export class AnalysisWindowComponent implements OnInit, OnChanges {
public tableNormalize = false;
public tableHasScores = false;
@Output() visibleItems: EventEmitter<any> = new EventEmitter();
public algorithmNames = algorithmNames;
constructor(private http: HttpClient, public analysis: AnalysisService) {
}
async ngOnInit() {
}
......@@ -95,20 +94,7 @@ export class AnalysisWindowComponent implements OnInit, OnChanges {
this.nodeData.edges = new vis.DataSet(edges);
const container = this.networkEl.nativeElement;
const options = {
layout: {
improvedLayout: false,
},
edges: {
smooth: false,
},
physics: {
enabled: this.physicsEnabled,
stabilization: {
enabled: false,
},
},
};
const options = NetworkSettings.getOptions('analysis');
this.network = new vis.Network(container, this.nodeData, options);
......@@ -136,78 +122,38 @@ export class AnalysisWindowComponent implements OnInit, OnChanges {
}
this.network.on('deselectNode', (properties) => {
this.showDetailsChange.emit([false, [null, null, null, null, null, null]]);
this.showDetailsChange.emit(null);
});
this.network.on('selectNode', (properties) => {
this.network.on('click', (properties) => {
const selectedNodes = this.nodeData.nodes.get(properties.nodes);
if (selectedNodes.length > 0) {
let selectedItem;
let selectedName;
let selectedType;
let selectedId;
let selectedVirusName;
let selectedStatus;
if (selectedNodes[0].nodeType === 'host') {
const protein: Protein = selectedNodes[0].details;
selectedVirusName = null;
selectedStatus = null;
selectedItem = {name: selectedNodes[0].id, type: 'Host Protein', data: protein};
// TODO use gene name here
selectedName = protein.name;
selectedId = protein.proteinAc;
selectedType = 'Host Protein';
if (properties.event.srcEvent.ctrlKey) {
if (this.analysis.inSelection(protein.proteinAc)) {
this.analysis.removeItem(protein.proteinAc);
} else {
this.analysis.addItem({name: protein.proteinAc, type: 'Host Protein', data: protein});
this.analysis.getCount();
}
}
} else if (selectedNodes[0].nodeType === 'virus') {
const virus: ViralProtein = selectedNodes[0].details;
selectedId = null;
selectedStatus = null;
selectedItem = {name: virus.effectId, type: 'Viral Protein', data: virus};
selectedVirusName = virus.virusName;
selectedName = virus.effectName;
selectedType = 'Viral Protein';
if (properties.event.srcEvent.ctrlKey) {
if (this.analysis.inSelection(virus.effectName)) {
this.analysis.removeItem(virus.effectName);
} else {
this.analysis.addItem(selectedItem);
this.analysis.getCount();
}
const selectedNode = selectedNodes[0];
const wrapper = selectedNode.wrapper;
if (properties.event.srcEvent.ctrlKey) {
if (this.analysis.inSelection(wrapper)) {
this.analysis.removeItem(wrapper);
} else {
this.analysis.addItem(wrapper);
this.analysis.getCount();
}
} else if (selectedNodes[0].nodeType === 'drug') {
const drug: Drug = selectedNodes[0].details;
selectedId = drug.drugId;
selectedStatus = drug.status;
selectedName = drug.name;
selectedType = 'Drug';
selectedItem = {name: drug.name, type: 'Drug', data: drug};
selectedVirusName = null;
}
this.showDetailsChange.emit([true, [selectedItem, selectedName, selectedType,
selectedId, selectedVirusName, selectedStatus]]);
this.showDetailsChange.emit(wrapper);
} else {
this.showDetailsChange.emit([false, [null, null, null, null, null, null]]);
this.showDetailsChange.emit(null);
}
});
this.analysis.subscribe((item, selected) => {
const nodeId = item.name;
const node = this.nodeData.nodes.get(nodeId);
const node = this.nodeData.nodes.get(item.nodeId);
if (!node) {
return;
}
const pos = this.network.getPositions([nodeId]);
node.x = pos[nodeId].x;
node.y = pos[nodeId].y;
const {color} = this.getNodeLooks(nodeId, node.nodeType, node.isSeed);
node.color = color;
const pos = this.network.getPositions([item.nodeId]);
node.x = pos[item.nodeId].x;
node.y = pos[item.nodeId].y;
Object.assign(node, NetworkSettings.getNodeStyle(node.wrapper.type, node.isSeed, selected));
this.nodeData.nodes.update(node);
});
}
......@@ -273,7 +219,7 @@ export class AnalysisWindowComponent implements OnInit, OnChanges {
return `${environment.backend}task_result/?token=${this.token}&view=${view}&fmt=csv`;
}
public inferNodeType(nodeId: string): 'host' | 'virus' | 'drug' {
public inferNodeType(nodeId: string): WrapperType {
if (nodeId.indexOf('-') !== -1 || nodeId.indexOf('_') !== -1) {
return 'virus';
} else if (nodeId.startsWith('DB')) {
......@@ -302,76 +248,73 @@ export class AnalysisWindowComponent implements OnInit, OnChanges {
} else if (nodeTypes[node] === 'virus') {
this.effects.push(details[node]);
}
nodes.push(this.mapNode(node, nodeTypes[node] || this.inferNodeType(node), isSeed[node], scores[node], details[node]));
nodes.push(this.mapNode(this.inferNodeType(node), details[node], isSeed[node], scores[node]));
}
for (const edge of network.edges) {
edges.push(this.mapEdge(edge));
edges.push(this.mapEdge(edge, 'protein-protein'));
}
return {
nodes,
edges,
};
}
private getNodeLooks(nodeId: string, nodeType: NodeType, isSeed: boolean):
{ color: string, shape: string, size: number, font: any, shadow: boolean } {
let color = '';
let shape = '';
let size = 10;
let font = {};
let shadow = false;
private mapNode(nodeType: WrapperType, details: Protein | ViralProtein | Drug, isSeed?: boolean, score?: number): any {
let nodeLabel;
let wrapper: Wrapper;
if (nodeType === 'host') {
shape = 'ellipse';
if (this.analysis.inSelection(nodeId)) {
color = '#c7661c';
} else {
color = '#e2b600';
const protein = details as Protein;
wrapper = getWrapperFromProtein(protein);
nodeLabel = protein.name;
if (!protein.name) {
nodeLabel = protein.proteinAc;
}
size = 10;
} else if (nodeType === 'virus') {
shape = 'box';
color = '#118AB2';
size = 12;
font = {color: 'white'};
shadow = true;
} else if (nodeType === 'drug') {
shape = 'ellipse';
color = '#26b28b';
size = 6;
const drug = details as Drug;
wrapper = getWrapperFromDrug(drug);
nodeLabel = drug.name;
} else if (nodeType === 'virus') {
const viralProtein = details as ViralProtein;
wrapper = getWrapperFromViralProtein(viralProtein);
nodeLabel = viralProtein.effectName;
}
if (isSeed) {
color = '#c064c7';
}
const node = NetworkSettings.getNodeStyle(nodeType, isSeed, this.analysis.inSelection(wrapper));
return {color, shape, size, font, shadow};
node.id = wrapper.nodeId;
node.label = nodeLabel;
node.nodeType = nodeType;
node.isSeed = isSeed;
node.wrapper = wrapper;
return node;
}
private mapNode(nodeId: any, nodeType?: NodeType, isSeed?: boolean, score?: number, details?): any {
const {shape, color, size, font, shadow} = this.getNodeLooks(nodeId, nodeType, isSeed);
let nodeLabel = nodeId;
if (nodeType === 'host') {
nodeLabel = details.name;
} else if (nodeType === 'drug') {
nodeLabel = details.name;
private mapEdge(edge: any, type: 'protein-protein' | 'to-drug'): any {
let edgeColor;
if (type === 'protein-protein') {
edgeColor = {
color: NetworkSettings.getColor('edgeHostVirus'),
highlight: NetworkSettings.getColor('edgeHostVirusHighlight')
};
const {from, to} = getNodeIdsFromPPI(edge);
return {
from, to,
color: edgeColor,
};
} else if (type === 'to-drug') {
edgeColor = {
color: NetworkSettings.getColor('edgeHostDrug'),
highlight: NetworkSettings.getColor('edgeHostDrugHighlight')
};
const {from, to} = getNodeIdsFromPDI(edge);
return {
from, to,
color: edgeColor,
};
}
return {
id: nodeId,
label: nodeLabel,
size, color, shape, font, shadow,
nodeType, isSeed, details
};
}
private mapEdge(edge: any): any {
return {
from: `${edge.from}`,
to: `${edge.to}`,
color: {color: '#afafaf', highlight: '#854141'},
};
}
public async toggleDrugs(bool: boolean) {
......@@ -413,12 +356,12 @@ export class AnalysisWindowComponent implements OnInit, OnChanges {
});
} else {
for (const drug of drugs) {
this.drugNodes.push(this.mapNode(drug.drugId, 'drug', false, null, drug));
this.drugNodes.push(this.mapNode('drug', drug, false, null));
}
for (const interaction of edges) {
const edge = {from: interaction.proteinAc, to: interaction.drugId};
this.drugEdges.push(this.mapEdge(edge));
this.drugEdges.push(this.mapEdge(edge, 'to-drug'));
}
this.nodeData.nodes.add(Array.from(this.drugNodes.values()));
this.nodeData.edges.add(Array.from(this.drugEdges.values()));
......@@ -450,6 +393,7 @@ export class AnalysisWindowComponent implements OnInit, OnChanges {
});
}
public updateshowdrugs(bool) {
this.drugstatus = bool;
......
<div *ngIf="wrapper">
<div *ngIf="wrapper.type === 'host'">
<p>
<b><span>Gene Name:</span></b>
{{ wrapper.data.name }}
<span class="icon is-small"><i class="fas fa-dna"></i></span>
</p>
<p>
<b><span>Uniprot AC:</span></b>
<a href="https://www.uniprot.org/uniprot/{{ wrapper.data.proteinAc }}" target="_blank">
{{ wrapper.data.proteinAc }}
</a>
</p>
</div>
<div *ngIf="wrapper.type === 'virus'">
<p>
<b><span>Virus:</span></b>
{{ wrapper.data.virusName }}
<span class="icon is-small"><i class="fas fa-virus"></i></span>
</p>
<p>
<b><span>Effect:</span></b>
{{ wrapper.data.effectName }}
</p>
</div>
<div *ngIf="wrapper.type === 'drug'">
<p>
<b><span>Name:</span></b>
{{ wrapper.data.name }}
<span class="icon is-small"><i class="fas fa-capsules"></i></span>
</p>
<p>
<b>DrugBank ID:</b>
<a href="https://www.drugbank.ca/drugs/{{ wrapper.data.drugId }}" target="_blank"> {{ wrapper.data.drugId }}</a>
</p>
<p *ngIf="wrapper.data.status === 'investigational' ">
<b>Status:</b> Investigational
<span class="icon is-small"><i class="fas fa-search investigational"></i></span>
<p *ngIf="wrapper.data.status === 'approved' ">
<b>Status:</b> Approved
<span class="icon is-small"><i class="fas fa-check"></i></span>
</p>
</div>
<div class="field has-addons add-remove-toggle" *ngIf="wrapper.type !== 'drug'">
<app-toggle [value]="!analysis.inSelection(wrapper)" (valueChange)="$event ? analysis.addItem(wrapper) : analysis.removeItem(wrapper)" textOn="Add to Analysis" textOff="Remove" icon="fa-plus"></app-toggle>
</div>
</div>
<div *ngIf="!wrapper">
Please select a node for further information.
</div>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { InfoBoxComponent } from './info-box.component';
import {HttpClientModule} from '@angular/common/http';
describe('InfoBoxComponent', () => {
let component: InfoBoxComponent;
let fixture: ComponentFixture<InfoBoxComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ InfoBoxComponent ],
imports: [HttpClientModule],
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(InfoBoxComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import {Component, Input, OnInit} from '@angular/core';
import {Wrapper} from '../../interfaces';
import {AnalysisService} from '../../analysis.service';
@Component({
selector: 'app-info-box',
templateUrl: './info-box.component.html',
styleUrls: ['./info-box.component.scss']
})
export class InfoBoxComponent implements OnInit {
@Input()
public wrapper: Wrapper;
constructor(public analysis: AnalysisService) { }
ngOnInit(): void {
}
}
......@@ -56,9 +56,9 @@ export class LaunchAnalysisComponent implements OnInit, OnChanges {
public hasBaits;
constructor(public analysis: AnalysisService) {
this.hasBaits = !!analysis.getSelection().find((i) => i.type === 'Viral Protein');
this.hasBaits = !!analysis.getSelection().find((i) => i.type === 'virus');
analysis.subscribe(() => {
this.hasBaits = !!analysis.getSelection().find((i) => i.type === 'Viral Protein');
this.hasBaits = !!analysis.getSelection().find((i) => i.type === 'virus');
});
}
......@@ -88,7 +88,7 @@ export class LaunchAnalysisComponent implements OnInit, OnChanges {
public async startTask() {
const parameters: any = {
seeds: this.analysis.getSelection().map((item) => item.name),
seeds: this.analysis.getSelection().map((item) => item.backendId),
};
if (this.algorithm === 'trustrank') {
......
<div class="content">
<ng-select [items]="queryItems" bindLabel="name" bindValue="data" [virtualScroll]="true" class="custom"
<ng-select [items]="queryItems" bindLabel="backendId" bindValue="data" [virtualScroll]="true" class="custom"
placeholder="Search..." [hideSelected]="true" [searchFn]="querySearch" (change)="select($event)">
<ng-template ng-option-tmp let-item="item">
<b *ngIf="item.type == 'Host Protein'"> {{item.data.name}}</b>
<b *ngIf="item.type == 'Viral Protein'"> {{item.data.effectName}}</b> <br/>
<span><small>{{item.type}}</small> | </span>
<span *ngIf="item.type == 'Host Protein'"><small>AC: <b>{{item.data.proteinAc}}</b></small> </span>
<span *ngIf="item.type == 'Viral Protein'"><small><b>{{item.data.virusName}}</b></small></span>
<b *ngIf="item.type == 'host'"> {{item.data.name}}</b>
<b *ngIf="item.type == 'virus'"> {{item.data.effectName}}</b> <br/>
<span><small *ngIf="item.type === 'virus'">Viral Protein</small><small *ngIf="item.type === 'host'">Host Protein</small> | </span>
<span *ngIf="item.type == 'host'"><small>AC: <b>{{item.data.proteinAc}}</b></small> </span>
<span *ngIf="item.type == 'virus'"><small><b>{{item.data.virusName}}</b></small></span>
</ng-template>
</ng-select>
</div>
import {Component, Input, Output, EventEmitter} from '@angular/core';
import {Protein, QueryItem, ViralProtein} from '../../interfaces';
import {Protein, Wrapper, ViralProtein} from '../../interfaces';
@Component({
selector: 'app-query-component',
......@@ -10,11 +10,11 @@ export class QueryComponent {
@Output() selectItem: EventEmitter<any> = new EventEmitter();
@Input() queryItems: QueryItem[];
@Input() queryItems: Wrapper[];
querySearch(term: string, item: QueryItem) {
querySearch(term: string, item: Wrapper) {
term = term.toLowerCase();
if (item.type === 'Host Protein') {
if (item.type === 'host') {
const data = item.data as Protein;
return data.name.toLowerCase().indexOf(term) > -1 || data.proteinAc.toLowerCase().indexOf(term) > -1 ||
item.type.toLowerCase().indexOf(term) > -1;
......
......@@ -25,6 +25,11 @@ export interface ProteinViralInteraction {
proteinAc: string;
}
export interface NetworkEdge {
from: string;
to: string;
}
export interface Task {
token: string;
info: {
......@@ -51,10 +56,97 @@ export interface Task {
};
}
export interface QueryItem {
name: string;
type: 'Host Protein' | 'Viral Protein' | 'Drug';
data: Protein | ViralProtein | Drug;
export function getProteinNodeId(protein: Protein) {
return `p_${protein.proteinAc}`;
}
export function getProteinBackendId(protein: Protein) {
return protein.proteinAc;
}
export function getViralProteinNodeId(viralProtein: ViralProtein) {
return `v_${viralProtein.effectName}_${viralProtein.virusName}`;
}
export function getNodeIdsFromPVI(pvi: ProteinViralInteraction) {
return {
from: `p_${pvi.proteinAc}`,
to: `v_${pvi.effectName}_${pvi.virusName}`,
};
}
export function getNodeIdsFromPPI(edge: NetworkEdge) {
return {
from: `p_${edge.from}`,
to: `p_${edge.to}`,
};
}
export function getNodeIdsFromPDI(edge: NetworkEdge) {
return {
from: `p_${edge.from}`,
to: `d_${edge.to}`,
};
}
export function getViralProteinBackendId(viralProtein: ViralProtein) {
return viralProtein.effectId;
}
export function getDrugNodeId(drug: Drug) {
return `d_${drug.drugId}`;
}
export function getDrugBackendId(drug: Drug) {
return drug.drugId;
}
export function getWrapperFromProtein(protein: Protein): Wrapper {
return {
backendId: getProteinBackendId(protein),
nodeId: getProteinNodeId(protein),
type: 'host',
data: protein,
};
}
export function getWrapperFromViralProtein(viralProtein: ViralProtein): Wrapper {
return {
backendId: getViralProteinBackendId(viralProtein),
nodeId: getViralProteinNodeId(viralProtein),
type: 'virus',
data: viralProtein,
};
}
export function getWrapperFromDrug(drug: Drug): Wrapper {
return {
backendId: getDrugBackendId(drug),
nodeId: getDrugNodeId(drug),
type: 'drug',
data: drug,
};
}
export type WrapperType = 'host' | 'virus' | 'drug';
export function getTypeFromNodeId(nodeId: string): WrapperType {
if (nodeId.startsWith('p_')) {
return 'host';
}
if (nodeId.startsWith('v_')) {
return 'virus';
}
if (nodeId.startsWith('d_')) {
return 'drug';
}
}
export interface Wrapper {
backendId: string;
nodeId: string;
type: 'host' | 'virus' | 'drug';
data: any;
}
export interface Drug {
......
import {WrapperType} from './interfaces';
export class NetworkSettings {
// Node color
private static hostColor = '#123456';
private static virusColor = '#BE093C';
private static drugColor = '#F8981D';
private static seedHostColor = '#3070B3';
private static seedVirusColor = '#3070B3';
private static selectedBorderColor = '#F8981D';
private static selectBorderHighlightColor = '#F8981D';
private static selectedBorderWidth = 3;
private static selectedBorderWidthSelected = 3.2;
// Edge color
private static edgeHostVirusColor = '#686868';
private static edgeHostVirusHighlightColor = '#686868';
private static edgeHostDrugColor = '#686868';
private static edgeHostDrugHighlightColor = '#686868';
// Node Font
private static hostFontSize = 20;
private static virusFontSize = 50;
private static drugFontSize = 30;
private static hostFontColor = '#FFFFFF';
private static virusFontColor = '#FFFFFF';
private static drugFontColor = '#FFFFFF';
// Network Layout
private static analysisLayout = {
improvedLayout: true,
};
private static analysisEdges = {
smooth: false,
length: 400,
};
private static analysisPhysics = {
enabled: true,
stabilization: {
enabled: true,
},
};
private static mainLayout = {
improvedLayout: false,
};
private static mainEdges = {
smooth: false,
length: 250,
};
private static mainPhysics = {
enabled: false,
};
// Node size
private static hostSize = 20;
private static virusSize = 30;
private static drugSize = 15;
// Node shape
private static hostShape = 'ellipse';
private static virusShape = 'ellipse';
private static drugShape = 'box';
static getNodeSize(wrapperType: WrapperType) {
if (wrapperType === 'host') {
return this.hostSize;
} else if (wrapperType === 'virus') {
return this.virusSize;
} else if (wrapperType === 'drug') {
return this.drugSize;
}
}
static getNodeShape(wrapperType: WrapperType) {
if (wrapperType === 'host') {
return this.hostShape;
} else if (wrapperType === 'virus') {
return this.virusShape;
} else if (wrapperType === 'drug') {
return this.drugShape;
}
}
static getOptions(network: 'main' | 'analysis') {
if (network === 'main') {
return {
layout: this.mainLayout,
edges: this.mainEdges,
physics: this.mainPhysics,
};
} else if (network === 'analysis') {
return {
layout: this.analysisLayout,
edges: this.analysisEdges,
physics: this.analysisPhysics,
};
}
}
static getColor(color: 'host' | 'virus' | 'drug' | 'hostFont' | 'virusFont' | 'drugFont' |
'seedHost' | 'seedVirus' | 'selectedForAnalysis' | 'selectedForAnalysisText' |
'edgeHostVirus' | 'edgeHostVirusHighlight' | 'edgeHostDrug' | 'edgeHostDrugHighlight') {
if (color === 'host') {
return this.hostColor;
} else if (color === 'virus') {
return this.virusColor;
} else if (color === 'drug') {
return this.drugColor;
} else if (color === 'hostFont') {
return this.hostFontColor;
} else if (color === 'virusFont') {
return this.virusFontColor;
} else if (color === 'drugFont') {
return this.drugFontColor;
} else if (color === 'seedHost') {
return this.seedHostColor;
} else if (color === 'seedVirus') {
return this.seedVirusColor;
} else if (color === 'edgeHostVirus') {
return this.edgeHostVirusColor;
} else if (color === 'edgeHostDrug') {
return this.edgeHostDrugColor;
} else if (color === 'edgeHostVirusHighlight') {
return this.edgeHostVirusHighlightColor;
} else if (color === 'edgeHostDrugHighlight') {
return this.edgeHostDrugHighlightColor;
}
}
static getFont(wrapperType: WrapperType) {
if (wrapperType === 'host') {
return {color: this.hostFontColor, size: this.hostFontSize};
} else if (wrapperType === 'virus') {
return {color: this.virusFontColor, size: this.virusFontSize};
} else if (wrapperType === 'drug') {
return {color: this.drugFontColor, size: this.drugFontSize};
}
}
static getNodeStyle(nodeType: WrapperType, isSeed: boolean, isSelected: boolean): any {
let nodeColor;
let nodeShape;
let nodeSize;
let nodeFont;
const nodeShadow = true;
nodeShape = NetworkSettings.getNodeShape(nodeType);
nodeSize = NetworkSettings.getNodeSize(nodeType);
nodeFont = NetworkSettings.getFont(nodeType);
if (nodeType === 'host') {
nodeColor = NetworkSettings.getColor(nodeType);
nodeFont = NetworkSettings.getFont('host');
if (isSeed) {
nodeColor = NetworkSettings.getColor('seedHost');
}
} else if (nodeType === 'virus') {
nodeColor = NetworkSettings.getColor(nodeType);
if (nodeType === 'virus') {
nodeFont = NetworkSettings.getFont('virus');
if (isSeed) {
nodeColor = NetworkSettings.getColor('seedVirus');
}
}
} else if (nodeType === 'drug') {
nodeColor = NetworkSettings.getColor(nodeType);
}
const node: any = {size: nodeSize, color: nodeColor, shape: nodeShape, font: nodeFont, shadow: nodeShadow};
if (isSelected) {
node.color = {color: node.color, border: this.selectedBorderColor, highlight: {border: this.selectBorderHighlightColor}};
node.borderWidth = this.selectedBorderWidth;
node.borderWidthSelected = this.selectedBorderWidthSelected;
}
return node;
}
}
......@@ -28,15 +28,16 @@
(selectedDatasetChange)="selectedDataset = $event; createNetwork($event.data)">
</app-select-dataset>
<div>
<div>
<br>
<font size="2">
<p ><span>Virus: SARS-CoV-2</span>
<p ><span>Host/target: Human cell line, HEK-293T kidney cells</span>
<p ><span>Method: AP-MS (affinity purification-mass spectrometry)</span>
<p ><span>Source:<a href="https://www.biorxiv.org/content/10.1101/2020.03.22.002386v3" target="_blank"> Gordon et al., 2020</a></span></font>
<p><span>Virus: <b>SARS-CoV-2</b></span>
<p><span>Host/target: <b>Human</b>, HEK-293T kidney cells</span>
<p><span>Method: <b>AP-MS</b></span>
<p><span>Source:<a href="https://www.biorxiv.org/content/10.1101/2020.03.22.002386v3" target="_blank"> <b> Gordon et al., 2020</b></a></span>
</font>
</div>
</div>
</div>
</div>
......@@ -116,15 +117,15 @@
<i class="fas fa-filter" aria-hidden="true"></i>
</span> Filter Viral Proteins
</p>
<a (click)="collapseDFilter = !collapseDFilter" data-action="collapse"
<a (click)="collapseBaitFilter = !collapseBaitFilter" data-action="collapse"
class="card-header-icon is-hidden-fullscreen" aria-label="more options">
<span class="icon">
<i *ngIf="collapseDFilter" class="fas fa-angle-up" aria-hidden="true"></i>
<i *ngIf="!collapseDFilter" class="fas fa-angle-down" aria-hidden="true"></i>
<i *ngIf="collapseBaitFilter" class="fas fa-angle-up" aria-hidden="true"></i>
<i *ngIf="!collapseBaitFilter" class="fas fa-angle-down" aria-hidden="true"></i>
</span>
</a>
</header>
<div *ngIf="collapseDFilter">
<div *ngIf="collapseBaitFilter">
<div class="card-content overflow">
<div *ngFor="let bait of viralProteinCheckboxes">
<label class="checkbox">
......@@ -181,9 +182,8 @@
<div class="analysis-view" *ngIf="selectedAnalysisToken">
<app-analysis-window [(token)]="selectedAnalysisToken"
(showDetailsChange)="showDetails = $event[0]; changeInfo($event[1])"
(visibleItems)="analysisWindowChanged($event)"
></app-analysis-window>
(showDetailsChange)="selectedWrapper = $event"
(visibleItems)="analysisWindowChanged($event)"></app-analysis-window>
</div>
</div>
......@@ -193,11 +193,17 @@
<header class="card-header">
<p class="card-header-title">
<span class="icon">
<i *ngIf="!showDetails" class="fas fa-info" aria-hidden="true"></i>
<i *ngIf="selectedType === 'Host Protein'" class="fas fa-dna" aria-hidden="true"></i>
<i *ngIf="selectedType === 'Viral Protein'" class="fas fa-virus" aria-hidden="true"></i>
<i *ngIf="selectedType === 'Drug'" class="fas fa-capsules" aria-hidden="true"></i>
</span> {{ selectedType }}
<i *ngIf="!selectedWrapper" class="fas fa-info" aria-hidden="true"></i>
<i *ngIf="selectedWrapper && selectedWrapper.type === 'host'" class="fas fa-dna" aria-hidden="true"></i>
<i *ngIf="selectedWrapper && selectedWrapper.type === 'virus'" class="fas fa-virus" aria-hidden="true"></i>
<i *ngIf="selectedWrapper && selectedWrapper.type === 'drug'" class="fas fa-capsules" aria-hidden="true"></i>
</span>
<span *ngIf="!selectedWrapper">No item selected</span>
<span *ngIf="selectedWrapper">
<span *ngIf="selectedWrapper.type === 'host'">Host</span>
<span *ngIf="selectedWrapper.type === 'virus'">Viral Protein</span>
<span *ngIf="selectedWrapper.type === 'drug'">Drug</span>
</span>
</p>
<a (click)="collapseDetails = !collapseDetails" data-action="collapse"
class="card-header-icon is-hidden-fullscreen" aria-label="more options">
......@@ -209,57 +215,7 @@
</header>
<div *ngIf="collapseDetails">
<div class="card-content">
<div *ngIf="showDetails">
<p *ngIf="selectedName && selectedType=='Drug'"><b><span>Name:</span></b> {{ selectedName }} <span
class="icon is-small">
<i class="fas fa-capsules"></i>
</span></p>
<p *ngIf="selectedName && selectedType=='Host Protein'"><b><span>Gene Name:</span></b> {{ selectedName }}
<span class="icon is-small">
<i class="fas fa-dna"></i>
</span></p>
<p *ngIf="selectedVirusName"><b><span>Virus:</span></b> {{ selectedVirusName }} <span class="icon is-small">
<i class="fas fa-virus"></i>
</span></p>
<p *ngIf="selectedName && selectedType=='Viral Protein'"><b>Effect:</b> {{ selectedName }}</p>
<p *ngIf="selectedId && selectedType == 'Host Protein'"><b>Uniprot AC:</b>
<a href="https://www.uniprot.org/uniprot/{{ selectedId }}"
target="_blank"> {{ selectedId }}</a>
</p>
<p *ngIf="selectedId && selectedType == 'Drug'"><b>DrugBank ID:</b>
<a href="https://www.drugbank.ca/drugs/{{ selectedId }}"
target="_blank"> {{ selectedId }}</a>
</p>
<p *ngIf="selectedStatus === 'investigational' "><b>Status:</b> Investigational <span class="icon is-small"><i class="fas fa-search investigational"></i></span>
<p *ngIf="selectedStatus === 'approved' "><b>Status:</b> Approved <span class="icon is-small"><i class="fas fa-check"></i></span>
</p>
<div class="field has-addons add-remove-toggle">
<p *ngIf="selectedType !== 'Drug'" class="control">
<button class="button is-rounded" [class.is-success]="!analysis.inSelection(selectedName)"
[disabled]="analysis.inSelection(selectedName)"
(click)="analysis.addItem(selectedItem)">
<span class="icon is-small">
<i class="fas fa-plus"></i>
</span>
<span>Add to Analysis</span>
</button>
</p>
<p *ngIf="selectedType !== 'Drug'" class="control">
<button class="button is-rounded" [class.is-danger]="analysis.inSelection(selectedName)"
[disabled]="!analysis.inSelection(selectedName)"
(click)="analysis.removeItem(selectedName)">
<span>Remove</span>
<span class="icon is-small">
<i class="fas fa-trash"></i>
</span>
</button>
</p>
</div>
</div>
<div *ngIf="!showDetails">
Please select a node for further information.
<!-- <a (click)="selectedAnalysisToken = 'oy4UsXfBDobTucdQBhN9IUzfnpqKwzqx'"> Open Analysis Window </a>-->
</div>
<app-info-box [wrapper]="selectedWrapper"></app-info-box>
</div>
</div>
</div>
......@@ -422,16 +378,16 @@
</thead>
<tbody>
<tr *ngFor="let p of analysis.getSelection()">
<td>
<td>
<span class="icon">
<i class="fa fa-dna" *ngIf="p.type == 'Host Protein'"></i>
<i class="fa fa-virus" *ngIf="p.type =='Viral Protein'"></i>
<i class="fa fa-dna" *ngIf="p.type == 'host'"></i>
<i class="fa fa-virus" *ngIf="p.type =='virus'"></i>
</span>
</td>
<td *ngIf="p.type == 'Viral Protein'">{{p.name}}</td>
<td *ngIf="p.type == 'Host Protein'">{{p.data.name}}</td>
<td *ngIf="p.type == 'virus'">{{p.data.effectName}}</td>
<td *ngIf="p.type == 'host'">{{p.data.name}}</td>
<td>
<button (click)="analysis.removeItem(p.name)" class="button is-small is-danger is-outlined">
<button (click)="analysis.removeItem(p)" class="button is-small is-danger is-outlined">
<i class="fa fa-trash"></i>
</button>
</td>
......@@ -443,7 +399,8 @@
</i>
</div>
<footer class="card-footer">
<a (click)="analysis.addAllHostProteins(currentViewNodes, currentViewProteins)" class="card-footer-item has-text-success">
<a (click)="analysis.addAllHostProteins(currentViewNodes, currentViewProteins)"
class="card-footer-item has-text-success">
<span class="icon">
<i class="fa fa-plus"></i>
</span>
......@@ -451,7 +408,8 @@
Host Proteins
</span>
</a>
<a (click)="analysis.addAllViralProteins(currentViewNodes, currentViewEffects)" class="card-footer-item has-text-success">
<a (click)="analysis.addAllViralProteins(currentViewNodes, currentViewEffects)"
class="card-footer-item has-text-success">
<span class="icon">
<i class="fa fa-plus"></i>
</span>
......
......@@ -5,12 +5,19 @@ import {
OnInit,
ViewChild
} from '@angular/core';
import {ProteinViralInteraction, ViralProtein, Protein, QueryItem} from '../../interfaces';
import {
ProteinViralInteraction,
ViralProtein,
Protein,
Wrapper,
getWrapperFromViralProtein, getWrapperFromProtein, getNodeIdsFromPVI, getViralProteinNodeId, getProteinNodeId
} from '../../interfaces';
import {ProteinNetwork, getDatasetFilename} from '../../main-network';
import {HttpClient, HttpParams} from '@angular/common/http';
import {AnalysisService} from '../../analysis.service';
import html2canvas from 'html2canvas';
import {environment} from '../../../environments/environment';
import {NetworkSettings} from '../../network-settings';
declare var vis: any;
......@@ -23,19 +30,14 @@ declare var vis: any;
export class ExplorerPageComponent implements OnInit, AfterViewInit {
public showDetails = false;
public selectedName = null;
public selectedType = null;
public selectedId = null;
public selectedItem = null;
public selectedVirusName = null;
public selectedStatus = null;
public selectedWrapper: Wrapper | null = null;
public collapseAnalysisQuick = true;
public collapseAnalysis = false;
public collapseDetails = true;
public collapseTask = true;
public collapseSelection = true;
public collapseDFilter = true;
public collapseBaitFilter = true;
public collapseQuery = true;
public collapseData = true;
public collapseOverview = true;
......@@ -54,7 +56,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
private dumpPositions = false;
public physicsEnabled = false;
public queryItems: QueryItem[] = [];
public queryItems: Wrapper[] = [];
public showAnalysisDialog = false;
public analysisDialogTarget: 'drug' | 'drug-target';
......@@ -68,23 +70,8 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
public currentViewNodes: Node[];
public datasetItems: Array<{ id: string, label: string, datasets: string, data: Array<[string, string]> }> = [
// {
// id: 'All (TUM & Krogan)',
// label: 'All',
// datasets: 'TUM & Krogan',
// data: [['TUM', 'HCoV'], ['TUM', 'SARS-CoV2'], ['Krogan', 'SARS-CoV2']]
// },
// {id: 'HCoV (TUM)', label: 'HCoV', datasets: 'TUM', data: [['TUM', 'HCoV']]},
// {
// id: 'CoV2 (TUM & Krogan)',
// label: 'CoV2',
// datasets: 'TUM & Krogan',
// data: [['TUM', 'SARS-CoV2'], ['Krogan', 'SARS-CoV2']]
// },
// tslint:disable-next-line:max-line-length
{id: 'CoV2 (Gordon et al., 2020)', label: 'CoV2', datasets: 'Gordon et al., 2020', data: [['Krogan', 'SARS-CoV2']]},
// {id: 'CoV2 (TUM)', label: 'CoV2', datasets: 'TUM', data: [['TUM', 'SARS-CoV2']]}
];
];
public selectedDataset = this.datasetItems[0];
......@@ -95,28 +82,14 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
this.showDetails = false;
this.analysis.subscribe((item, selected) => {
let nodeId;
if (item.type === 'Host Protein') {
nodeId = `p_${item.name}`;
} else if (item.type === 'Viral Protein') {
nodeId = `eff_${item.name}`;
}
const node = this.nodeData.nodes.get(nodeId);
const node = this.nodeData.nodes.get(item.nodeId);
if (!node) {
return;
}
const pos = this.network.getPositions([nodeId]);
node.x = pos[nodeId].x;
node.y = pos[nodeId].y;
if (selected) {
node.color = '#48C774';
} else {
if (item.type === 'Host Protein') {
node.color = '#e2b600';
} else if (item.type === 'Viral Protein') {
node.color = '#118AB2';
}
}
const pos = this.network.getPositions([item.nodeId]);
node.x = pos[item.nodeId].x;
node.y = pos[item.nodeId].y;
Object.assign(node, NetworkSettings.getNodeStyle(node.wrapper.type, false, selected));
this.nodeData.nodes.update(node);
});
}
......@@ -124,11 +97,11 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
ngOnInit() {
}
async ngAfterViewInit() {
if (!this.network) {
this.selectedDataset = this.datasetItems[0];
await this.createNetwork(this.selectedDataset.data);
this.physicsEnabled = false;
}
}
......@@ -148,6 +121,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
}
private zoomToNode(id: string) {
this.nodeData.nodes.getIds();
const coords = this.network.getPositions(id)[id];
if (!coords) {
return;
......@@ -165,47 +139,25 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
});
}
public changeInfo(showList: any[]) {
this.selectedItem = showList[0];
this.selectedName = showList[1];
this.selectedType = showList[2];
this.selectedId = showList[3];
this.selectedVirusName = showList[4];
this.selectedStatus = showList[5];
public changeInfo(wrapper: Wrapper | null) {
// this.selectedItem = showList[0];
// this.selectedName = showList[1];
// this.selectedType = showList[2];
// this.selectedId = showList[3];
// this.selectedVirusName = showList[4];
// this.selectedStatus = showList[5];
}
public async openSummary(item: QueryItem, zoom: boolean) {
this.selectedId = null;
this.selectedItem = item;
this.selectedType = item.type;
this.selectedName = item.name;
if (this.selectedType === 'Host Protein') {
const hostProtein = item.data as Protein;
this.selectedId = hostProtein.proteinAc;
this.selectedName = hostProtein.name;
if (zoom) {
this.zoomToNode(`p_${item.name}`);
}
} else if (item.type === 'Viral Protein') {
const viralProtein = item.data as ViralProtein;
this.selectedName = viralProtein.effectName;
this.selectedVirusName = viralProtein.virusName;
if (zoom) {
this.zoomToNode(`eff_${viralProtein.effectName}_${viralProtein.datasetName}_${viralProtein.virusName}`);
}
public async openSummary(item: Wrapper, zoom: boolean) {
this.selectedWrapper = item;
if (zoom) {
this.zoomToNode(item.nodeId);
}
this.showDetails = true;
}
public async closeSummary() {
this.selectedItem = null;
this.selectedName = null;
this.selectedType = null;
this.selectedId = null;
this.selectedVirusName = null;
this.selectedStatus = null;
this.selectedWrapper = null;
this.showDetails = false;
}
......@@ -239,51 +191,23 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
this.nodeData.edges = new vis.DataSet(edges);
const container = this.networkEl.nativeElement;
const options = {
layout: {
improvedLayout: false,
},
edges: {
smooth: false,
},
physics: {
enabled: this.physicsEnabled,
stabilization: {
enabled: false,
},
},
};
const options = NetworkSettings.getOptions('main');
this.network = new vis.Network(container, this.nodeData, options);
this.network.on('selectNode', (properties) => {
const id: Array<string> = properties.nodes;
if (id.length > 0) {
const nodeId = id[0].split('_');
let node: QueryItem;
if (nodeId[0].startsWith('p')) {
node = {
name: nodeId[1],
type: 'Host Protein',
data: this.proteinData.getProtein(nodeId[1])
};
} else if (nodeId[0].startsWith('e')) {
const effect = this.effects.find((eff) => eff.effectName === nodeId[1] && eff.datasetName === nodeId[2] &&
eff.virusName === nodeId[3]);
node = {
name: effect.effectId,
type: 'Viral Protein',
data: effect
};
}
this.network.on('click', (properties) => {
const nodeIds: Array<string> = properties.nodes;
if (nodeIds.length > 0) {
const nodeId = nodeIds[0];
const node = this.nodeData.nodes.get(nodeId);
const wrapper = node.wrapper;
if (properties.event.srcEvent.ctrlKey) {
if (this.analysis.inSelection(node.name) === true) {
this.analysis.inSelection(node.name);
if (this.analysis.inSelection(wrapper)) {
this.analysis.removeItem(wrapper);
} else {
this.analysis.addItem(node);
this.analysis.getCount();
this.analysis.addItem(wrapper);
}
this.openSummary(node, false);
this.openSummary(wrapper, false);
} else {
this.openSummary(node, false);
this.openSummary(wrapper, false);
}
} else {
this.closeSummary();
......@@ -304,33 +228,25 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
this.network.stabilize();
}
if (this.selectedItem) {
this.zoomToNode(`p_${this.selectedItem.name}`);
if (this.selectedWrapper) {
this.zoomToNode(this.selectedWrapper.nodeId);
}
this.queryItems = [];
this.fillQueryItems(this.proteins, this.effects);
if (this.selectedItem) {
this.network.selectNodes(['p_' + this.selectedItem.name]);
if (this.selectedWrapper) {
this.network.selectNodes([this.selectedWrapper.nodeId]);
}
}
fillQueryItems(hostProteins: Protein[], viralProteins: ViralProtein[]) {
this.queryItems = [];
hostProteins.forEach((protein) => {
this.queryItems.push({
name: protein.name,
type: 'Host Protein',
data: protein
});
this.queryItems.push(getWrapperFromProtein(protein));
});
viralProteins.forEach((effect) => {
this.queryItems.push({
name: effect.effectId,
type: 'Viral Protein',
data: effect
});
viralProteins.forEach((viralProtein) => {
this.queryItems.push(getWrapperFromViralProtein(viralProtein));
});
this.currentViewNodes = this.nodeData.nodes;
......@@ -356,7 +272,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
}
});
viralProteins.forEach((effect) => {
const nodeId = `eff_${effect.effectName}_${effect.datasetName}_${effect.virusName}`;
const nodeId = getViralProteinNodeId(effect);
const found = visibleIds.has(nodeId);
if ((cb.checked || showAll) && !found) {
const node = this.mapViralProteinToNode(effect);
......@@ -376,7 +292,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
});
const filteredProteins = [];
for (const protein of this.proteinData.proteins) {
const nodeId = `p_${protein.proteinAc}`;
const nodeId = getProteinNodeId(protein);
const contains = connectedProteinAcs.has(protein.proteinAc);
const found = visibleIds.has(nodeId);
if (contains) {
......@@ -415,38 +331,40 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
}
private mapHostProteinToNode(hostProtein: Protein): any {
let color = '#e2b600';
if (this.analysis.inSelection(hostProtein.name)) {
color = '#48C774';
const wrapper = getWrapperFromProtein(hostProtein);
const node = NetworkSettings.getNodeStyle('host', false, this.analysis.inSelection(wrapper));
let nodeLabel = hostProtein.name;
if (hostProtein.name.length === 0) {
nodeLabel = hostProtein.proteinAc;
}
return {
id: `p_${hostProtein.proteinAc}`,
label: `${hostProtein.name}`,
size: 10, font: '5px', color, shape: 'ellipse', shadow: false,
x: hostProtein.x,
y: hostProtein.y,
};
node.label = nodeLabel;
node.id = wrapper.nodeId;
node.x = hostProtein.x;
node.y = hostProtein.y;
node.wrapper = wrapper;
return node;
}
private mapViralProteinToNode(viralProtein: ViralProtein): any {
let color = '#118AB2';
if (this.analysis.inSelection(`${viralProtein.effectName}_${viralProtein.datasetName}_${viralProtein.virusName}`)) {
color = '#48C774';
}
return {
id: `eff_${viralProtein.effectName}_${viralProtein.datasetName}_${viralProtein.virusName}`,
label: `${viralProtein.effectName} (${viralProtein.datasetName}, ${viralProtein.virusName})`,
size: 10, color, shape: 'box', shadow: true, font: {color: '#FFFFFF'},
x: viralProtein.x,
y: viralProtein.y,
};
const wrapper = getWrapperFromViralProtein(viralProtein);
const node = NetworkSettings.getNodeStyle('virus', false, this.analysis.inSelection(wrapper));
node.id = wrapper.nodeId;
node.label = viralProtein.effectName;
node.id = wrapper.nodeId;
node.x = viralProtein.x;
node.y = viralProtein.y;
node.wrapper = wrapper;
return node;
}
private mapEdge(edge: ProteinViralInteraction): any {
const {from, to} = getNodeIdsFromPVI(edge);
return {
from: `p_${edge.proteinAc}`,
to: `eff_${edge.effectName}_${edge.datasetName}_${edge.virusName}`,
color: {color: '#afafaf', highlight: '#854141'},
from, to,
color: {
color: NetworkSettings.getColor('edgeHostVirus'),
highlight: NetworkSettings.getColor('edgeHostVirusHighlight')
},
};
}
......
src/assets/logo.png

808 KiB | W: | H:

src/assets/logo.png

168 KiB | W: | H:

src/assets/logo.png
src/assets/logo.png
src/assets/logo.png
src/assets/logo.png
  • 2-up
  • Swipe
  • Onion skin
src/assets/virus.png

808 KiB

......@@ -28,16 +28,10 @@ body {
background-image: url("assets/virus_background.png");
background-size: cover;
background-repeat: no-repeat;
background-position: 80%;
padding: 50px;
}
//.hero.is-primary {
// background-color: $primary;
// background-image: linear-gradient(to left, #f2fcfe, $primary);
// background-repeat: no-repeat;
// background-position: 80%;
// padding: 50px;
//}
div.navbar-menu {
margin-left: 5px;
}
......
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