diff --git a/src/app/components/analysis-panel/analysis-panel.component.ts b/src/app/components/analysis-panel/analysis-panel.component.ts index 169ede9a38c4489dd24c307179685d8444d8de29..43f231c4f2c8ebc820b2013f4bfc30a5dc06b41a 100644 --- a/src/app/components/analysis-panel/analysis-panel.component.ts +++ b/src/app/components/analysis-panel/analysis-panel.component.ts @@ -173,7 +173,7 @@ export class AnalysisPanelComponent implements OnInit, OnChanges { r.rawScore = r.score; r.isSeed = isSeed[r.id]; r.closestViralProteins = (r.closestViralProteins as any).split(','); - if (this.analysis.proteinInSelection(r)) { + if (this.analysis.inSelection(r)) { this.tableSelectedProteins.push(r); } }); @@ -228,26 +228,17 @@ export class AnalysisPanelComponent implements OnInit, OnChanges { if (selected !== null) { const updatedNodes = []; for (const item of items) { - const node = this.nodeData.nodes.get(item.nodeId); + const node = this.nodeData.nodes.get(item.id); if (!node) { continue; } - let drugType; - let drugInTrial; - if (item.type === 'drug') { - drugType = item.data.status; - drugInTrial = item.data.inTrial; - } - const pos = this.network.getPositions([item.nodeId]); - node.x = pos[item.nodeId].x; - node.y = pos[item.nodeId].y; + const pos = this.network.getPositions([item.id]); + node.x = pos[item.id].x; + node.y = pos[item.id].y; Object.assign(node, NetworkSettings.getNodeStyle( node.wrapper.type, node.isSeed, - selected, - drugType, - drugInTrial, - node.gradient)); + selected)); updatedNodes.push(node); } this.nodeData.nodes.update(updatedNodes); @@ -255,16 +246,14 @@ export class AnalysisPanelComponent implements OnInit, OnChanges { const proteinSelection = this.tableSelectedProteins; const viralProteinSelection = this.tableSelectedViralProteins; for (const item of items) { - if (item.type === 'protein') { - // TODO: Refactor! - const found = proteinSelection.findIndex((i) => getProteinNodeId(i) === item.nodeId); - const tableItem = this.tableProteins.find((i) => getProteinNodeId(i) === item.nodeId); - if (selected && found === -1 && tableItem) { - proteinSelection.push(tableItem); - } - if (!selected && found !== -1 && tableItem) { - proteinSelection.splice(found, 1); - } + // TODO: Refactor! + const found = proteinSelection.findIndex((i) => getProteinNodeId(i) === item.id); + const tableItem = this.tableProteins.find((i) => getProteinNodeId(i) === item.id); + if (selected && found === -1 && tableItem) { + proteinSelection.push(tableItem); + } + if (!selected && found !== -1 && tableItem) { + proteinSelection.splice(found, 1); } } this.tableSelectedProteins = [...proteinSelection]; @@ -293,11 +282,9 @@ export class AnalysisPanelComponent implements OnInit, OnChanges { const proteinSelection = []; const viralProteinSelection = []; for (const item of items) { - if (item.type === 'protein') { - const tableItem = this.tableProteins.find((i) => getProteinNodeId(i) === item.nodeId); - if (tableItem) { - proteinSelection.push(tableItem); - } + const tableItem = this.tableProteins.find((i) => getProteinNodeId(i) === item.id); + if (tableItem) { + proteinSelection.push(tableItem); } } this.tableSelectedProteins = [...proteinSelection]; @@ -410,21 +397,21 @@ export class AnalysisPanelComponent implements OnInit, OnChanges { }; } - private mapNode(nodeType: WrapperType, details: Node | Drug, isSeed?: boolean, score?: number): any { - let nodeLabel; - let wrapper: Wrapper; + private mapNode(nodeType: WrapperType, details: Node, isSeed?: boolean, score?: number): any { + /*let nodeLabel; + // let wrapper: Wrapper; let drugType; - let drugInTrial; - if (nodeType === 'protein') { + let drugInTrial;*/ + /*if (nodeType === 'protein') { const protein = details as Node; - wrapper = getWrapperFromProtein(protein); + // wrapper = getWrapperFromProtein(protein); nodeLabel = protein.name; if (!protein.name) { nodeLabel = protein.id; } } else if (nodeType === 'drug') { - const drug = details as Drug; - wrapper = getWrapperFromDrug(drug); + // const drug = details as Drug; + // wrapper = getWrapperFromDrug(drug); drugType = drug.status; drugInTrial = drug.inTrial; if (drugType === 'approved') { @@ -432,14 +419,14 @@ export class AnalysisPanelComponent implements OnInit, OnChanges { } else { nodeLabel = drug.drugId; } - } + }*/ - const node = NetworkSettings.getNodeStyle(nodeType, isSeed, this.analysis.inSelection(wrapper), drugType, drugInTrial); - node.id = wrapper.nodeId; - node.label = nodeLabel; + const node = NetworkSettings.getNodeStyle('protein', isSeed, this.analysis.inSelection(details)); + node.id = details.id; + node.label = details.name; node.nodeType = nodeType; node.isSeed = isSeed; - node.wrapper = wrapper; + node.wrapper = details; return node; } @@ -573,7 +560,7 @@ export class AnalysisPanelComponent implements OnInit, OnChanges { } public selectTissue(tissue: Tissue | null) { - if (!tissue) { + /*if (!tissue) { this.selectedTissue = null; const updatedNodes = []; for (const protein of this.proteins) { @@ -635,7 +622,7 @@ export class AnalysisPanelComponent implements OnInit, OnChanges { this.nodeData.nodes.update(updatedNodes); }); } - this.emitVisibleItems(true); + this.emitVisibleItems(true);*/ } } diff --git a/src/app/components/info-tile/info-tile.component.html b/src/app/components/info-tile/info-tile.component.html index ff2286df6d46491dfbe60dc828aac37fb5e3ce93..c813b77b3163a706efbd591095bdd85ec1c065cc 100644 --- a/src/app/components/info-tile/info-tile.component.html +++ b/src/app/components/info-tile/info-tile.component.html @@ -2,25 +2,19 @@ <div> <p> <b><span>Name:</span></b> - {{ wrapper.data.name }} + {{ wrapper.name }} </p> <p> <b><span>Access:</span></b> - <a href="https://www.uniprot.org/uniprot/{{ wrapper.data.proteinAc }}" target="_blank"> - {{ wrapper.data.access }} + <a href="https://www.uniprot.org/uniprot/{{ wrapper.access }}" target="_blank"> + {{ wrapper.access }} </a> </p> - <p *ngIf="wrapper.data.expressionLevel"> - <b><span>Expression level: </span></b> - {{ wrapper.data.expressionLevel|number }} - </p> </div> - <div class="field has-addons add-remove-toggle" *ngIf="wrapper.type !== 'drug'"> - <app-toggle [value]="analysis.inSelection(wrapper)" - (valueChange)="$event ? analysis.addItems([wrapper]) : analysis.removeItems([wrapper])" textOn="Selected" - textOff="Deselected" tooltipOn="Add protein to selection." tooltipOff="Remove protein from selection."></app-toggle> - </div> + <app-toggle [value]="analysis.inSelection(wrapper)" + (valueChange)="$event ? analysis.addItems([wrapper]) : analysis.removeItems([wrapper])" textOn="Selected" + textOff="Deselected" tooltipOn="Add protein to selection." tooltipOff="Remove protein from selection."></app-toggle> </div> <div *ngIf="!wrapper"> Please select a node for further information. diff --git a/src/app/components/info-tile/info-tile.component.ts b/src/app/components/info-tile/info-tile.component.ts index 10d84527a91cf22cc65ac16cab8dad6339b06075..53d7c3c8e0ccbe51e7e7b0127be870bcb7b15981 100644 --- a/src/app/components/info-tile/info-tile.component.ts +++ b/src/app/components/info-tile/info-tile.component.ts @@ -1,7 +1,8 @@ import {Component, Input, OnInit} from '@angular/core'; -import {Wrapper} from '../../interfaces'; +import {Node} from '../../interfaces'; import {AnalysisService} from '../../services/analysis/analysis.service'; + @Component({ selector: 'app-info-tile', templateUrl: './info-tile.component.html', @@ -10,7 +11,7 @@ import {AnalysisService} from '../../services/analysis/analysis.service'; export class InfoTileComponent implements OnInit { @Input() - public wrapper: Wrapper; + public wrapper: Node; constructor(public analysis: AnalysisService) { } diff --git a/src/app/dialogs/add-expressed-proteins/add-expressed-proteins.component.ts b/src/app/dialogs/add-expressed-proteins/add-expressed-proteins.component.ts index 76572e8cf54edd3f1890924f7ffc11bba5eeb890..2de915ea2ffb6c2728924c46b8deecbe0d5fd2d3 100644 --- a/src/app/dialogs/add-expressed-proteins/add-expressed-proteins.component.ts +++ b/src/app/dialogs/add-expressed-proteins/add-expressed-proteins.component.ts @@ -48,7 +48,7 @@ export class AddExpressedProteinsComponent implements OnChanges { public addVisibleProteins() { this.loading = true; - this.addedCount = this.analysis.addExpressedHostProteins(this.visibleNodes, this.currentViewProteins, this.threshold); + // this.addedCount = this.analysis.addExpressedHostProteins(this.visibleNodes, this.currentViewProteins, this.threshold); this.loading = false; } diff --git a/src/app/dialogs/custom-proteins/custom-proteins.component.ts b/src/app/dialogs/custom-proteins/custom-proteins.component.ts index be4167b6624060ceabea3a521b0330682517e794..8552cd7a48cefb34d3b6c87471cf9547275f505a 100644 --- a/src/app/dialogs/custom-proteins/custom-proteins.component.ts +++ b/src/app/dialogs/custom-proteins/custom-proteins.component.ts @@ -77,7 +77,7 @@ export class CustomProteinsComponent implements OnInit { items.push(getWrapperFromProtein(detail)); } this.itemsFound = items; - this.addedCount = this.analysis.addVisibleHostProteins(this.visibleNodes, proteinItems); + // this.addedCount = this.analysis.addVisibleHostProteins(this.visibleNodes, proteinItems); this.selectOnly = true; this.loading = false; } diff --git a/src/app/dialogs/launch-analysis/launch-analysis.component.ts b/src/app/dialogs/launch-analysis/launch-analysis.component.ts index 3b6ba0c6916e96226d7e18d9fbd8fcdf1e30c50e..41eaa401bcf0ca2adafa321e7e916235e2085890 100644 --- a/src/app/dialogs/launch-analysis/launch-analysis.component.ts +++ b/src/app/dialogs/launch-analysis/launch-analysis.component.ts @@ -98,7 +98,7 @@ export class LaunchAnalysisComponent implements OnInit, OnChanges { public async startTask() { const parameters: any = { - seeds: this.analysis.getSelection().map((item) => item.backendId), + seeds: this.analysis.getSelection().map((item) => item.id), }; parameters.target_or_drugs = this.target === 'drug' ? 'PPDr' : 'PPI'; diff --git a/src/app/pages/explorer-page/explorer-page.component.html b/src/app/pages/explorer-page/explorer-page.component.html index 3f14d75ee2dc492e2ef3d9635e58a0cf4bbd72ce..43baf62eaa8aa7dcb86b2a5571cf9c5acebb97de 100644 --- a/src/app/pages/explorer-page/explorer-page.component.html +++ b/src/app/pages/explorer-page/explorer-page.component.html @@ -115,6 +115,7 @@ <button class="button is-loading center" alt="loading...">Loading</button> </div> </div> + </div> <footer *ngIf="myConfig.showFooter" class="card-footer toolbar"> @@ -404,64 +405,42 @@ <i *ngIf="collapseSelection" class="fas fa-angle-down" aria-hidden="true"></i> <i *ngIf="!collapseSelection" class="fas fa-angle-left" aria-hidden="true"></i> </span> - </a> - </header> - <div *ngIf="collapseSelection" class="seed-selection"> - <div class="card-content overflow"> - <table class="table selection-table" *ngIf="analysis.getCount() > 0"> - <thead> - <tr> - <td>Type</td> - <td>Name</td> - <td>Actions</td> - </tr> - </thead> - <tbody> - <tr *ngFor="let p of analysis.getSelection()"> - <td> - <span class="icon"> - <i class="fa fa-dna" *ngIf="p.type == 'protein'"></i> - </span> - </td> - <td *ngIf="p.type == 'protein'">{{p.data.name}}</td> - <td> - <button (click)="analysis.removeItems([p])" class="button is-small is-danger is-outlined has-tooltip" - data-tooltip="Remove from selection."> - <i class="fa fa-trash"></i> - </button> - </td> - </tr> - </tbody> - </table> - <i *ngIf="analysis.getCount() === 0"> - Double-click on a protein to select it for the analysis. - </i> - </div> - <footer class="card-footer"> - <a (click)="analysis.addVisibleHostProteins(currentViewNodes, currentViewProteins)" - class="card-footer-item has-text-success" data-tooltip="Add all visible proteins."> - <span class="icon"> - <i class="fa fa-plus"></i> - </span> - <span> - Add proteins - </span> - </a> - <a (click)="analysis.removeAllHostProteins()" - class="card-footer-item has-text-danger" data-tooltip="Remove all proteins."> - <span class="icon"> - <i class="fa fa-minus"></i> - </span> - <span> - Remove proteins - </span> - </a> - </footer> + </a> + </header> + <div *ngIf="collapseSelection" class="seed-selection"> + <div class="card-content overflow"> + <table class="table selection-table" *ngIf="analysis.getCount() > 0"> + <thead> + <tr> + <td>Type</td> + <td>Name</td> + <td>Actions</td> + </tr> + </thead> + <tbody> + <tr *ngFor="let p of analysis.getSelection()"> + <td> + </td> + <td>{{p.name}}</td> + <td> + <button (click)="analysis.removeItems([p])" class="button is-small is-danger is-outlined has-tooltip" + data-tooltip="Remove from selection."> + <i class="fa fa-trash"></i> + </button> + </td> + </tr> + </tbody> + </table> + <i *ngIf="analysis.getCount() === 0"> + Double-click on a protein to select it for the analysis. + </i> + </div> + + <footer class="card-footer" *ngIf="selectedAnalysisToken"> + <a (click)="analysis.addSeeds(currentViewNodes)" + class="card-footer-item has-text-success" data-tooltip="Add all visible seeds."> - <footer class="card-footer" *ngIf="selectedAnalysisToken"> - <a (click)="analysis.addSeeds(currentViewNodes)" - class="card-footer-item has-text-success" data-tooltip="Add all visible seeds."> <span class="icon"> <i class="fa fa-plus"></i> </span> diff --git a/src/app/pages/explorer-page/explorer-page.component.ts b/src/app/pages/explorer-page/explorer-page.component.ts index 2ce7b68724c043a00527fa6a571a82172ec601e1..7a909b16cd0cf0078064fbe7a56be2360d840fee 100644 --- a/src/app/pages/explorer-page/explorer-page.component.ts +++ b/src/app/pages/explorer-page/explorer-page.component.ts @@ -133,16 +133,16 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { } const updatedNodes = []; for (const item of items) { - const node = this.nodeData.nodes.get(item.nodeId); + const node = this.nodeData.nodes.get(item.id); if (!node) { continue; } - const pos = this.networkInternal.getPositions([item.nodeId]); - node.x = pos[item.nodeId].x; - node.y = pos[item.nodeId].y; - node.x = pos[item.nodeId].x; - node.y = pos[item.nodeId].y; - Object.assign(node, this.myConfig.nodeGroups[node.wrapper.data.group]); + const pos = this.networkInternal.getPositions([item.id]); + node.x = pos[item.id].x; + node.y = pos[item.id].y; + node.x = pos[item.id].x; + node.y = pos[item.id].y; + Object.assign(node, this.myConfig.nodeGroups[node.group]); updatedNodes.push(node); } this.nodeData.nodes.update(updatedNodes); @@ -150,7 +150,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { const updatedNodes = []; this.nodeData.nodes.forEach((node) => { const nodeSelected = this.analysis.idInSelection(node.id); - Object.assign(node, this.myConfig.nodeGroups[node.wrapper.data.group]); + Object.assign(node, this.myConfig.nodeGroups[node.group]); }); this.nodeData.nodes.update(updatedNodes); } @@ -236,11 +236,10 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { if (nodeIds.length > 0) { const nodeId = nodeIds[0]; const node = this.nodeData.nodes.get(nodeId); - const wrapper = node.wrapper; - if (this.analysis.inSelection(wrapper)) { - this.analysis.removeItems([wrapper]); + if (this.analysis.inSelection(node)) { + this.analysis.removeItems([node]); } else { - this.analysis.addItems([wrapper]); + this.analysis.addItems([node]); } } }); @@ -378,8 +377,8 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { gProfilerLink(): string { const queryString = this.analysis.getSelection() - .filter(wrapper => wrapper.type === 'protein') - .map(wrapper => wrapper.data.proteinAc) + .filter(wrapper => wrapper.group === 'protein') + .map(wrapper => wrapper.access) .join('%0A'); return 'http://biit.cs.ut.ee/gprofiler/gost?' + 'organism=hsapiens&' + @@ -402,8 +401,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { if (!tissue) { this.selectedTissue = null; const updatedNodes = []; - for (const protein of this.proteins) { - const item = getWrapperFromProtein(protein); + for (const item of this.proteins) { const node = this.nodeData.nodes.get(item.nodeId); if (!node) { continue; @@ -421,7 +419,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { 1.0)); node.wrapper = item; node.gradient = 1.0; - protein.expressionLevel = undefined; + // protein.expressionLevel = undefined; (node.wrapper.data as Node).expressionLevel = undefined; updatedNodes.push(node); } diff --git a/src/app/services/analysis/analysis.service.ts b/src/app/services/analysis/analysis.service.ts index d642a06c550e188c11a2c365e2cc4e9a29ef48a5..d5fd40dd67a7614fad29d348daecf776961b975d 100644 --- a/src/app/services/analysis/analysis.service.ts +++ b/src/app/services/analysis/analysis.service.ts @@ -42,10 +42,10 @@ export class AnalysisService { private selection = 'main'; - private selectedItems = new Map<string, Wrapper>(); - private selectListSubject = new Subject<{ items: Wrapper[], selected: boolean | null }>(); + private selectedItems = new Map<string, Node>(); + private selectListSubject = new Subject<{ items: Node[], selected: boolean | null }>(); - private selections = new Map<string, Map<string, Wrapper>>(); + private selections = new Map<string, Map<string, Node>>(); public tokens: string[] = []; public finishedTokens: string[] = []; @@ -104,28 +104,28 @@ export class AnalysisService { if (this.selections.has(id)) { this.selectedItems = this.selections.get(id); } else { - this.selectedItems = new Map<string, Wrapper>(); + this.selectedItems = new Map<string, Node>(); } this.selectListSubject.next({items: Array.from(this.selectedItems.values()), selected: null}); this.selection = id; } - public addItems(wrappers: Wrapper[]): number { - const addedWrappers: Wrapper[] = []; + public addItems(wrappers: Node[]): number { + const addedWrappers: Node[] = []; for (const wrapper of wrappers) { if (!this.inSelection(wrapper)) { addedWrappers.push(wrapper); - this.selectedItems.set(wrapper.nodeId, wrapper); + this.selectedItems.set(wrapper.id, wrapper); } } this.selectListSubject.next({items: addedWrappers, selected: true}); return addedWrappers.length; } - public removeItems(wrappers: Wrapper[]) { - const removedWrappers: Wrapper[] = []; + public removeItems(wrappers: Node[]) { + const removedWrappers: Node[] = []; for (const wrapper of wrappers) { - if (this.selectedItems.delete(wrapper.nodeId)) { + if (this.selectedItems.delete(wrapper.id)) { removedWrappers.push(wrapper); } } @@ -133,24 +133,22 @@ export class AnalysisService { } public addSeeds(nodes) { - const addedWrappers: Wrapper[] = []; + const addedWrappers: Node[] = []; nodes.forEach((node) => { - const wrapper: Wrapper = node.wrapper; - if (node.isSeed === true && !this.inSelection(wrapper)) { - addedWrappers.push(wrapper); - this.selectedItems.set(wrapper.nodeId, wrapper); + if (node.isSeed === true && !this.inSelection(node)) { + addedWrappers.push(node); + this.selectedItems.set(node.id, node); } }); this.selectListSubject.next({items: addedWrappers, selected: true}); } public removeSeeds(nodes) { - const removedWrappers: Wrapper[] = []; + const removedWrappers: Node[] = []; nodes.forEach((node) => { - const wrapper: Wrapper = node.wrapper; - if (node.isSeed === true && this.inSelection(wrapper)) { - removedWrappers.push(wrapper); - this.selectedItems.delete(wrapper.nodeId); + if (node.isSeed === true && this.inSelection(node)) { + removedWrappers.push(node); + this.selectedItems.delete(node.id); } }); this.selectListSubject.next({items: removedWrappers, selected: false}); @@ -159,11 +157,8 @@ export class AnalysisService { public invertSelection(nodes) { const newSelection = []; nodes.forEach((node) => { - const wrapper: Wrapper = node.wrapper; - if (wrapper.type === 'protein') { - if (!this.inSelection(wrapper)) { - newSelection.push(wrapper); - } + if (!this.inSelection(node)) { + newSelection.push(node); } }); this.selectedItems.clear(); @@ -173,7 +168,7 @@ export class AnalysisService { this.selectListSubject.next({items: newSelection, selected: null}); } - public addExpressedHostProteins(nodes, proteins: Node[], threshold: number): number { + /*public addExpressedHostProteins(nodes, proteins: Node[], threshold: number): number { const items: Wrapper[] = []; const visibleIds = new Set<string>(nodes.getIds()); for (const protein of proteins) { @@ -209,7 +204,7 @@ export class AnalysisService { this.selectedItems.delete(wrapper.nodeId); } this.selectListSubject.next({items, selected: false}); - } + }*/ resetSelection() { this.selectedItems.clear(); @@ -220,15 +215,11 @@ export class AnalysisService { return this.selectedItems.has(nodeId); } - inSelection(wrapper: Wrapper): boolean { - return this.selectedItems.has(wrapper.nodeId); - } - - proteinInSelection(protein: Node): boolean { - return this.inSelection(getWrapperFromProtein(protein)); + inSelection(wrapper: Node): boolean { + return this.selectedItems.has(wrapper.id); } - getSelection(): Wrapper[] { + getSelection(): Node[] { return Array.from(this.selectedItems.values()); } @@ -236,7 +227,7 @@ export class AnalysisService { return this.selectedItems.size; } - subscribeList(cb: (items: Array<Wrapper>, selected: boolean | null) => void) { + subscribeList(cb: (items: Array<Node>, selected: boolean | null) => void) { this.selectListSubject.subscribe((event) => { cb(event.items, event.selected); }); @@ -264,7 +255,7 @@ export class AnalysisService { parameters: { strain_or_drugs: dataset.backendId, bait_datasets: dataset.data, - seeds: isSuper ? [] : this.getSelection().map((i) => i.backendId), + seeds: isSuper ? [] : this.getSelection().map((i) => i.id), }, }).toPromise(); this.tokens.push(resp.token); diff --git a/src/index.html b/src/index.html index b1211c10e4100a16e293b281518a106899cc86c8..43dc83b1cbcd63d955be426921c31cbbb7562520 100644 --- a/src/index.html +++ b/src/index.html @@ -37,6 +37,7 @@ <div> + <network-expander id="netexp1" config='{ "showQuery": false, @@ -51,6 +52,7 @@ <script> + function changeConfig() { const netexp = document.getElementById('netexp1'); netexp.setAttribute('config', '{"showLeftSidebar": false}');