diff --git a/src/app/components/analysis-panel/analysis-panel.component.ts b/src/app/components/analysis-panel/analysis-panel.component.ts index 4336feab1cbf60c25dcd175fb52e808c33de8f11..078295d82561d31a13aee8d2750ef8ad74c1f094 100644 --- a/src/app/components/analysis-panel/analysis-panel.component.ts +++ b/src/app/components/analysis-panel/analysis-panel.component.ts @@ -36,7 +36,7 @@ import {downLoadFile, pieChartContextRenderer, removeDuplicateObjectsFromList} f import {DrugstoneConfigService} from 'src/app/services/drugstone-config/drugstone-config.service'; import {NetworkHandlerService} from 'src/app/services/network-handler/network-handler.service'; import {LegendService} from 'src/app/services/legend-service/legend-service.service'; -import { LoadingScreenService } from 'src/app/services/loading-screen/loading-screen.service'; +import {LoadingScreenService} from 'src/app/services/loading-screen/loading-screen.service'; declare var vis: any; @@ -166,7 +166,7 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit if (this.task && this.task.info.done) { this.loading = true; - this.netex.getTaskResult(this.token).then(result => { + this.netex.getTaskResult(this.token).then(async result => { this.drugstoneConfig.set_analysisConfig(result.parameters.config); this.result = result; if (this.result.parameters.target === 'drug') { @@ -183,166 +183,176 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit this.networkHandler.activeNetwork.networkEl.nativeElement.innerHTML = ''; this.networkHandler.activeNetwork.networkInternal = null; // Create - this.createNetwork(this.result).then(nw => { - const nodes = nw.nodes; - const edges = nw.edges; - - this.networkHandler.activeNetwork.inputNetwork = {nodes: nodes, edges: edges}; - this.nodeData.nodes = new vis.DataSet(nodes); - this.nodeData.edges = new vis.DataSet(edges); - const container = this.networkHandler.activeNetwork.networkEl.nativeElement; - const isBig = nodes.length > 100 || edges.length > 100; - const options = NetworkSettings.getOptions(isBig ? 'analysis-big' : 'analysis', this.drugstoneConfig.currentConfig()); - // @ts-ignore - options.groups = this.drugstoneConfig.currentConfig().nodeGroups; - // @ts-ignore - for (const g of Object.values(options.groups)) { - // @ts-ignore - delete g.renderer; - } - this.drugstoneConfig.config.physicsOn = !isBig; - this.networkHandler.activeNetwork.networkInternal = new vis.Network(container, this.nodeData, options); - this.networkHandler.activeNetwork.networkInternal.on('stabilizationIterationsDone', () => { - if (!this.drugstoneConfig.config.physicsOn) { - this.networkHandler.activeNetwork.updatePhysicsEnabled(false); - } - this.networkHandler.updateAdjacentNodes(); - }); - this.tableDrugs = nodes.filter(e => e.drugstoneId && e.drugstoneType === 'drug'); - this.tableDrugs.forEach((r) => { - r.rawScore = r.score; - }); - this.tableProteins = nodes.filter(e => e.drugstoneId && e.drugstoneType === 'protein'); - this.tableSelectedProteins = []; - this.tableProteins.forEach((r) => { - r.rawScore = r.score; - r.isSeed = this.networkHandler.activeNetwork.seedMap[r.id]; - const wrapper = getWrapperFromNode(r); - if (this.analysis.inSelection(wrapper)) { - this.tableSelectedProteins.push(r); - } - }); + await this.createNetwork(this.result).then(nw => { + return new Promise<any>((resolve, reject) => { - this.tableHasScores = ['trustrank', 'closeness', 'degree', 'betweenness', 'quick', 'super'] - .indexOf(this.task.info.algorithm) !== -1; - if (this.tableHasScores) { - this.toggleNormalization(true); - } - this.networkHandler.activeNetwork.networkInternal.setData({nodes: undefined, edge: undefined}); - setTimeout(() => { - this.networkHandler.activeNetwork.networkInternal.setData(this.nodeData); - }, 1000); + const nodes = nw.nodes; + const edges = nw.edges; - this.networkHandler.activeNetwork.networkInternal.on('deselectNode', (properties) => { - this.showDetailsChange.emit(null); - }); + this.networkHandler.activeNetwork.inputNetwork = {nodes: nodes, edges: edges}; + this.nodeData.nodes = new vis.DataSet(nodes); + this.nodeData.edges = new vis.DataSet(edges); + const container = this.networkHandler.activeNetwork.networkEl.nativeElement; + const isBig = nodes.length > 100 || edges.length > 100; + const options = NetworkSettings.getOptions(isBig ? 'analysis-big' : 'analysis', this.drugstoneConfig.currentConfig()); + // @ts-ignore + options.groups = this.drugstoneConfig.currentConfig().nodeGroups; + // @ts-ignore + for (const g of Object.values(options.groups)) { + // @ts-ignore + delete g.renderer; + } + if (this.drugstoneConfig.config.physicsOn) { + this.drugstoneConfig.config.physicsOn = !isBig; + } + this.networkHandler.activeNetwork.networkInternal = new vis.Network(container, this.nodeData, options); - this.networkHandler.activeNetwork.networkInternal.on('doubleClick', (properties) => { - const nodeIds: Array<string> = properties.nodes; - if (nodeIds.length > 0) { - const nodeId = nodeIds[0]; - const node = this.nodeData.nodes.get(nodeId); - if (node.drugstoneId === undefined || node.nodeType === 'drug' || node.drugstoneType !== 'protein') { - this.analysis.unmappedNodeToast(); - return; + this.networkHandler.activeNetwork.networkInternal.once('stabilizationIterationsDone', async () => { + if (!this.drugstoneConfig.config.physicsOn || this.networkHandler.activeNetwork.isBig()) { + this.networkHandler.activeNetwork.updatePhysicsEnabled(false); } - const wrapper = getWrapperFromNode(node); + this.networkHandler.updateAdjacentNodes(this.networkHandler.activeNetwork.isBig()).then(() => { + resolve(nodes); + }); + }); + }).then(nodes => { + + this.tableDrugs = nodes.filter(e => e.drugstoneId && e.drugstoneType === 'drug'); + this.tableDrugs.forEach((r) => { + r.rawScore = r.score; + }); + this.tableProteins = nodes.filter(e => e.drugstoneId && e.drugstoneType === 'protein'); + this.tableSelectedProteins = []; + this.tableProteins.forEach((r) => { + r.rawScore = r.score; + r.isSeed = this.networkHandler.activeNetwork.seedMap[r.id]; + const wrapper = getWrapperFromNode(r); if (this.analysis.inSelection(wrapper)) { - this.analysis.removeItems([wrapper]); - this.analysis.getCount(); - } else { - this.analysis.addItems([wrapper]); - this.analysis.getCount(); + this.tableSelectedProteins.push(r); } - } - }); + }); - this.networkHandler.activeNetwork.networkInternal.on('click', (properties) => { - const selectedNodes = this.nodeData.nodes.get(properties.nodes); - if (selectedNodes.length > 0) { - this.showDetailsChange.emit(getWrapperFromNode(selectedNodes[0])); - } else { - this.showDetailsChange.emit(null); - } - }); - this.analysis.subscribeList((items, selected) => { - // return if analysis panel is closed or no nodes are loaded - if (!this.token) { - return; + this.tableHasScores = ['trustrank', 'closeness', 'degree', 'betweenness', 'quick', 'super'] + .indexOf(this.task.info.algorithm) !== -1; + if (this.tableHasScores) { + this.toggleNormalization(true); } + this.networkHandler.activeNetwork.networkInternal.setData({nodes: undefined, edge: undefined}); + setTimeout(() => { + this.networkHandler.activeNetwork.networkInternal.setData(this.nodeData); + }, 1000); - if (selected !== null) { - const updatedNodes: Node[] = []; - for (const item of items) { - const node = this.nodeData.nodes.get(item.id); - if (!node) { - continue; - } - const pos = this.networkHandler.activeNetwork.networkInternal.getPositions([item.id]); - node.x = pos[item.id].x; - node.y = pos[item.id].y; - const isSeed = this.networkHandler.activeNetwork.highlightSeeds ? this.networkHandler.activeNetwork.seedMap[node.id] : false; - const nodeStyled = NetworkSettings.getNodeStyle( - node, - this.drugstoneConfig.currentConfig(), - isSeed, - selected, - this.networkHandler.activeNetwork.getGradient(item.id), - this.networkHandler.activeNetwork.nodeRenderer - ); - updatedNodes.push(nodeStyled); - } - this.nodeData.nodes.update(updatedNodes); - - const proteinSelection = this.tableSelectedProteins; - for (const item of items) { - // 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); + this.networkHandler.activeNetwork.networkInternal.on('deselectNode', (properties) => { + this.showDetailsChange.emit(null); + }); + + this.networkHandler.activeNetwork.networkInternal.on('doubleClick', (properties) => { + const nodeIds: Array<string> = properties.nodes; + if (nodeIds.length > 0) { + const nodeId = nodeIds[0]; + const node = this.nodeData.nodes.get(nodeId); + if (node.drugstoneId === undefined || node.nodeType === 'drug' || node.drugstoneType !== 'protein') { + this.analysis.unmappedNodeToast(); + return; } - if (!selected && found !== -1 && tableItem) { - proteinSelection.splice(found, 1); + const wrapper = getWrapperFromNode(node); + if (this.analysis.inSelection(wrapper)) { + this.analysis.removeItems([wrapper]); + this.analysis.getCount(); + } else { + this.analysis.addItems([wrapper]); + this.analysis.getCount(); } } - this.tableSelectedProteins = [...proteinSelection]; - } else { - // else: selected is null - const updatedNodes = []; - this.nodeData.nodes.forEach((node) => { - const isSeed = this.networkHandler.activeNetwork.highlightSeeds ? this.networkHandler.activeNetwork.seedMap[node.id] : false; - if (!isSeed) { - return; - } - const nodeStyled = NetworkSettings.getNodeStyle( - node, - this.drugstoneConfig.currentConfig(), - isSeed, - selected, - this.networkHandler.activeNetwork.getGradient(node.id), - this.networkHandler.activeNetwork.nodeRenderer - ); - updatedNodes.push(nodeStyled); - }); - this.nodeData.nodes.update(updatedNodes); + }); + + this.networkHandler.activeNetwork.networkInternal.on('click', (properties) => { + const selectedNodes = this.nodeData.nodes.get(properties.nodes); + if (selectedNodes.length > 0) { + this.showDetailsChange.emit(getWrapperFromNode(selectedNodes[0])); + } else { + this.showDetailsChange.emit(null); + } + }); - const proteinSelection = []; - for (const item of items) { - const tableItem = this.tableProteins.find((i) => getProteinNodeId(i) === item.id); - if (tableItem) { - proteinSelection.push(tableItem); + this.analysis.subscribeList((items, selected) => { + // return if analysis panel is closed or no nodes are loaded + if (!this.token) { + return; + } + + if (selected !== null) { + const updatedNodes: Node[] = []; + for (const item of items) { + const node = this.nodeData.nodes.get(item.id); + if (!node) { + continue; + } + const pos = this.networkHandler.activeNetwork.networkInternal.getPositions([item.id]); + node.x = pos[item.id].x; + node.y = pos[item.id].y; + const isSeed = this.networkHandler.activeNetwork.highlightSeeds ? this.networkHandler.activeNetwork.seedMap[node.id] : false; + const nodeStyled = NetworkSettings.getNodeStyle( + node, + this.drugstoneConfig.currentConfig(), + isSeed, + selected, + this.networkHandler.activeNetwork.getGradient(item.id), + this.networkHandler.activeNetwork.nodeRenderer + ); + updatedNodes.push(nodeStyled); + } + this.nodeData.nodes.update(updatedNodes); + + const proteinSelection = this.tableSelectedProteins; + for (const item of items) { + // 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]; + } else { + // else: selected is null + const updatedNodes = []; + this.nodeData.nodes.forEach((node) => { + const isSeed = this.networkHandler.activeNetwork.highlightSeeds ? this.networkHandler.activeNetwork.seedMap[node.id] : false; + if (!isSeed) { + return; + } + const nodeStyled = NetworkSettings.getNodeStyle( + node, + this.drugstoneConfig.currentConfig(), + isSeed, + selected, + this.networkHandler.activeNetwork.getGradient(node.id), + this.networkHandler.activeNetwork.nodeRenderer + ); + updatedNodes.push(nodeStyled); + }); + this.nodeData.nodes.update(updatedNodes); + + const proteinSelection = []; + for (const item of items) { + const tableItem = this.tableProteins.find((i) => getProteinNodeId(i) === item.id); + if (tableItem) { + proteinSelection.push(tableItem); + } + } + this.tableSelectedProteins = [...proteinSelection]; } - this.tableSelectedProteins = [...proteinSelection]; - } + }); + this.emitVisibleItems(true); }); - this.emitVisibleItems(true); }); - this.loadingScreen.stateUpdate(false); - + this.loadingScreen.stateUpdate(false); }); } } @@ -433,7 +443,6 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit this.proteins = []; this.effects = []; - console.log(result.network) const network = result.network; network.nodes = [...new Set<string>(network.nodes)]; @@ -532,7 +541,7 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit public toggleFullscreen() { this.fullscreen = !this.fullscreen; - this.loadingScreen.fullscreenUpdate(this.fullscreen) + this.loadingScreen.fullscreenUpdate(this.fullscreen); } public showEULA() { diff --git a/src/app/components/network/network-menu-left/network-menu-left.component.html b/src/app/components/network/network-menu-left/network-menu-left.component.html index 7e47a55ee25f95b1c7b3f7df714395b6603248fe..51d62e72757a392195f508862059e17c8c712b65 100644 --- a/src/app/components/network/network-menu-left/network-menu-left.component.html +++ b/src/app/components/network/network-menu-left/network-menu-left.component.html @@ -180,7 +180,7 @@ tooltip="Display adjacent drugs." [value]="networkHandler.activeNetwork.adjacentDrugs" (valueChange)=" - networkHandler.activeNetwork.updateAdjacentDrugs($event) + networkHandler.activeNetwork.updateAdjacentDrugs($event, true) " ></app-toggle-inplace-reversed> </div> @@ -199,7 +199,7 @@ tooltip="Show disorders adjacent to all currently displayed proteins/genes." [value]="networkHandler.activeNetwork.adjacentDisordersProtein" (valueChange)=" - networkHandler.activeNetwork.updateAdjacentProteinDisorders($event) + networkHandler.activeNetwork.updateAdjacentProteinDisorders($event, true) " icon="head-side-mask" ></app-toggle-inplace-reversed> @@ -219,7 +219,7 @@ [value]="networkHandler.activeNetwork.adjacentDisordersDrug" [disabled]="!networkHandler.activeNetwork.hasDrugsLoaded()" (valueChange)=" - networkHandler.activeNetwork.updateAdjacentDrugDisorders($event) + networkHandler.activeNetwork.updateAdjacentDrugDisorders($event, true) " icon="biohazard" ></app-toggle-inplace-reversed> diff --git a/src/app/components/network/network-menu/network-menu.component.html b/src/app/components/network/network-menu/network-menu.component.html index f0ed1fa9664c6d1ec798d0c1bb0ea972e77c29c2..4da926a76c46b5b28c91aef0686145fb9bf42074 100644 --- a/src/app/components/network/network-menu/network-menu.component.html +++ b/src/app/components/network/network-menu/network-menu.component.html @@ -177,7 +177,7 @@ tooltip="Display adjacent drugs." [value]="networkHandler.activeNetwork.adjacentDrugs" (valueChange)=" - networkHandler.activeNetwork.updateAdjacentDrugs($event) + networkHandler.activeNetwork.updateAdjacentDrugs($event, true) " ></app-toggle-inplace> </div> @@ -196,7 +196,7 @@ tooltip="Show disorders adjacent to all currently displayed proteins/genes." [value]="networkHandler.activeNetwork.adjacentDisordersProtein" (valueChange)=" - networkHandler.activeNetwork.updateAdjacentProteinDisorders($event) + networkHandler.activeNetwork.updateAdjacentProteinDisorders($event, true) " icon="head-side-mask" ></app-toggle-inplace> @@ -216,7 +216,7 @@ [value]="networkHandler.activeNetwork.adjacentDisordersDrug" [disabled]="!networkHandler.activeNetwork.hasDrugsLoaded()" (valueChange)=" - networkHandler.activeNetwork.updateAdjacentDrugDisorders($event) + networkHandler.activeNetwork.updateAdjacentDrugDisorders($event, true) " icon="biohazard" ></app-toggle-inplace> diff --git a/src/app/components/network/network.component.ts b/src/app/components/network/network.component.ts index 4f4ab1d2b4268c86c67e95ce4d98cd8e6dc12285..cdcee9ae5ff828862459bb395868f63a316c76c4 100644 --- a/src/app/components/network/network.component.ts +++ b/src/app/components/network/network.component.ts @@ -99,6 +99,10 @@ export class NetworkComponent implements OnInit { this.networkHandler.networks[this.networkType] = this; } + isBig(): boolean { + return this.nodeData.nodes.length > 100 || this.nodeData.edges.length > 100; + } + setLoading(bool: boolean): void { this.loading = bool; } @@ -129,90 +133,128 @@ export class NetworkComponent implements OnInit { this.nodeData.nodes.add(toAdd); } - public updateAdjacentProteinDisorders(bool: boolean) { - this.loadingScreen.stateUpdate(true); - this.adjacentDisordersProtein = bool; - if (this.adjacentDisordersProtein) { - this.adjacentProteinDisorderList = []; - this.adjacentProteinDisorderEdgesList = []; - this.legendService.add_to_context('adjacentDisorders'); - this.netex.adjacentDisorders(this.nodeData.nodes.get(), 'proteins', this.drugstoneConfig.config.associatedProteinDisorder, this.drugstoneConfig.config.licensedDatasets).subscribe(response => { - const proteinMap = this.getProteinMap(); - const addedEdge = {}; - for (const interaction of response.edges) { - const edge = mapCustomEdge({ - from: interaction.protein, - to: interaction.disorder - }, this.drugstoneConfig.config, this.drugstoneConfig); - if (proteinMap[edge.from]) { - proteinMap[edge.from].forEach(from => { - if (addedEdge[from] && addedEdge[from].indexOf(edge.to) !== -1) { - return; - } - const e = JSON.parse(JSON.stringify(edge)); - e.from = from; - e.to = edge.to; - this.adjacentProteinDisorderEdgesList.push(e); - if (!addedEdge[from]) { - addedEdge[from] = [edge.to]; - } else { - addedEdge[from].push(edge.to); - } + public async updateAdjacentProteinDisorders(bool: boolean, stabl: boolean) { + return new Promise<boolean>((resolve, reject) => { + this.loadingScreen.stateUpdate(true); + this.adjacentDisordersProtein = bool; + if (this.adjacentDisordersProtein) { + this.adjacentProteinDisorderList = []; + this.adjacentProteinDisorderEdgesList = []; + this.legendService.add_to_context('adjacentDisorders'); + this.netex.adjacentDisorders(this.nodeData.nodes.get(), 'proteins', this.drugstoneConfig.config.associatedProteinDisorder, this.drugstoneConfig.config.licensedDatasets).then(response => { + const proteinMap = this.getProteinMap(); + const addedEdge = {}; + for (const interaction of response.edges) { + const edge = mapCustomEdge({ + from: interaction.protein, + to: interaction.disorder + }, this.drugstoneConfig.config, this.drugstoneConfig); + if (proteinMap[edge.from]) { + proteinMap[edge.from].forEach(from => { + if (addedEdge[from] && addedEdge[from].indexOf(edge.to) !== -1) { + return; + } + const e = JSON.parse(JSON.stringify(edge)); + e.from = from; + e.to = edge.to; + this.adjacentProteinDisorderEdgesList.push(e); + if (!addedEdge[from]) { + addedEdge[from] = [edge.to]; + } else { + addedEdge[from].push(edge.to); + } + }); + } + } + for (const disorder of response.disorders) { + disorder.group = 'defaultDisorder'; + disorder.id = disorder.drugstoneId; + this.adjacentProteinDisorderList.push(mapCustomNode(disorder, this.drugstoneConfig.currentConfig(), this.drugstoneConfig)); + } + this.saveAddNodes(this.adjacentProteinDisorderList); + this.nodeData.edges.add(this.adjacentProteinDisorderEdgesList); + this.updateQueryItems(); + }).then(() => { + if (stabl) { + this.stabilize().then(() => { + this.loadingScreen.stateUpdate(false); + resolve(true); }); + } else { + this.loadingScreen.stateUpdate(false); + resolve(true); } + }); + } else { + if (!this.adjacentDisordersDrug) { + this.legendService.remove_from_context('adjacentDisorders'); } - for (const disorder of response.disorders) { - disorder.group = 'defaultDisorder'; - disorder.id = disorder.drugstoneId; - this.adjacentProteinDisorderList.push(mapCustomNode(disorder, this.drugstoneConfig.currentConfig(), this.drugstoneConfig)); - } - this.saveAddNodes(this.adjacentProteinDisorderList); - this.nodeData.edges.add(this.adjacentProteinDisorderEdgesList); + this.saveRemoveDisorders(this.adjacentProteinDisorderList); + this.nodeData.edges.remove(this.adjacentProteinDisorderEdgesList); this.updateQueryItems(); - this.loadingScreen.stateUpdate(false); - }); - } else { - if (!this.adjacentDisordersDrug) { - this.legendService.remove_from_context('adjacentDisorders'); + if (stabl) { + this.stabilize().then(() => { + this.loadingScreen.stateUpdate(false); + resolve(true); + }); + } else { + this.loadingScreen.stateUpdate(false); + resolve(true); + } } - this.saveRemoveDisorders(this.adjacentProteinDisorderList); - this.nodeData.edges.remove(this.adjacentProteinDisorderEdgesList); - this.updateQueryItems(); - this.loadingScreen.stateUpdate(false); - } + }); } - public updateAdjacentDrugDisorders(bool: boolean) { - this.loadingScreen.stateUpdate(true); - this.adjacentDisordersDrug = bool; - if (this.adjacentDisordersDrug) { - this.adjacentDrugDisorderList = []; - this.adjacentDrugDisorderEdgesList = []; - this.legendService.add_to_context('adjacentDisorders'); - this.netex.adjacentDisorders(this.nodeData.nodes.get(), 'drugs', this.drugstoneConfig.config.indicationDrugDisorder, this.drugstoneConfig.config.licensedDatasets).subscribe(response => { - for (const interaction of response.edges) { - const edge = {from: interaction.drug, to: interaction.disorder}; - this.adjacentDrugDisorderEdgesList.push(mapCustomEdge(edge, this.drugstoneConfig.currentConfig(), this.drugstoneConfig)); - } - for (const disorder of response.disorders) { - disorder.group = 'defaultDisorder'; - disorder.id = disorder.drugstoneId; - this.adjacentDrugDisorderList.push(mapCustomNode(disorder, this.drugstoneConfig.currentConfig(), this.drugstoneConfig)); + public async updateAdjacentDrugDisorders(bool: boolean, stabl: boolean): Promise<any> { + return new Promise<boolean>((resolve, reject) => { + this.loadingScreen.stateUpdate(true); + this.adjacentDisordersDrug = bool; + if (this.adjacentDisordersDrug) { + this.adjacentDrugDisorderList = []; + this.adjacentDrugDisorderEdgesList = []; + this.legendService.add_to_context('adjacentDisorders'); + this.netex.adjacentDisorders(this.nodeData.nodes.get(), 'drugs', this.drugstoneConfig.config.indicationDrugDisorder, this.drugstoneConfig.config.licensedDatasets).then(response => { + for (const interaction of response.edges) { + const edge = {from: interaction.drug, to: interaction.disorder}; + this.adjacentDrugDisorderEdgesList.push(mapCustomEdge(edge, this.drugstoneConfig.currentConfig(), this.drugstoneConfig)); + } + for (const disorder of response.disorders) { + disorder.group = 'defaultDisorder'; + disorder.id = disorder.drugstoneId; + this.adjacentDrugDisorderList.push(mapCustomNode(disorder, this.drugstoneConfig.currentConfig(), this.drugstoneConfig)); + } + this.saveAddNodes(this.adjacentDrugDisorderList); + this.nodeData.edges.add(this.adjacentDrugDisorderEdgesList); + this.updateQueryItems(); + }).then(() => { + if (stabl) { + this.stabilize().then(() => { + this.loadingScreen.stateUpdate(false); + resolve(true); + }); + } else { + this.loadingScreen.stateUpdate(false); + resolve(true); + } + }); + } else { + if (!this.adjacentDisordersProtein) { + this.legendService.remove_from_context('adjacentDisorders'); } - this.saveAddNodes(this.adjacentDrugDisorderList); - this.nodeData.edges.add(this.adjacentDrugDisorderEdgesList); + this.saveRemoveDisorders(this.adjacentDrugDisorderList); + this.nodeData.edges.remove(this.adjacentDrugDisorderEdgesList); this.updateQueryItems(); - this.loadingScreen.stateUpdate(false); - }); - } else { - if (!this.adjacentDisordersProtein) { - this.legendService.remove_from_context('adjacentDisorders'); + if (stabl) { + this.stabilize().then(() => { + this.loadingScreen.stateUpdate(false); + resolve(true); + }); + } else { + this.loadingScreen.stateUpdate(false); + resolve(true); + } } - this.saveRemoveDisorders(this.adjacentDrugDisorderList); - this.nodeData.edges.remove(this.adjacentDrugDisorderEdgesList); - this.updateQueryItems(); - this.loadingScreen.stateUpdate(false); - } + }); } public getProteinMap() { @@ -241,69 +283,101 @@ export class NetworkComponent implements OnInit { return proteinMap; } - public updateAdjacentDrugs(bool: boolean) { - this.loadingScreen.stateUpdate(true); - this.adjacentDrugs = bool; - if (this.adjacentDrugs) { - this.adjacentDrugList = []; - this.adjacentDrugEdgesList = []; - this.legendService.add_to_context('adjacentDrugs'); - const addedEdge = {}; - const proteinMap = this.getProteinMap(); - this.netex.adjacentDrugs(this.drugstoneConfig.config.interactionDrugProtein, this.drugstoneConfig.config.licensedDatasets, this.nodeData.nodes.get()).subscribe(response => { - const existingDrugIDs = this.nodeData.nodes.get().filter(n => n.drugstoneId && n.drugstoneType === 'drug').map(n => n.drugstoneId); - for (const interaction of response.pdis) { - const edge = mapCustomEdge({ - from: interaction.protein, - to: interaction.drug - }, this.drugstoneConfig.currentConfig(), this.drugstoneConfig); - - if (proteinMap[edge.from]) { - proteinMap[edge.from].forEach(from => { - if (addedEdge[from] && addedEdge[from].indexOf(edge.to) !== -1) { - return; - } - const e = JSON.parse(JSON.stringify(edge)); - e.from = from; - e.to = edge.to; - this.adjacentDrugEdgesList.push(e); - if (!addedEdge[from]) { - addedEdge[from] = [edge.to]; - } else { - addedEdge[from].push(edge.to); - } - }); + public stabilize(): Promise<any> { + return new Promise<boolean>((resolve, reject) => { + this.networkInternal.once('stabilizationIterationsDone', () => { + this.updatePhysicsEnabled(this.drugstoneConfig.config.physicsOn); + this.networkInternal.fit(); + this.loadingScreen.stateUpdate(false); + resolve(true); + }); + this.loadingScreen.stateUpdate(true); + this.networkInternal.stabilize(1000); + }); + } + + public updateAdjacentDrugs(bool: boolean, stabl: boolean): Promise<any> { + return new Promise<boolean>(async (resolve, reject) => { + this.loadingScreen.stateUpdate(true); + this.adjacentDrugs = bool; + if (this.adjacentDrugs) { + this.adjacentDrugList = []; + this.adjacentDrugEdgesList = []; + this.legendService.add_to_context('adjacentDrugs'); + const addedEdge = {}; + const proteinMap = this.getProteinMap(); + this.netex.adjacentDrugs(this.drugstoneConfig.config.interactionDrugProtein, this.drugstoneConfig.config.licensedDatasets, this.nodeData.nodes.get()).then(response => { + const existingDrugIDs = this.nodeData.nodes.get().filter(n => n.drugstoneId && n.drugstoneType === 'drug').map(n => n.drugstoneId); + for (const interaction of response.pdis) { + const edge = mapCustomEdge({ + from: interaction.protein, + to: interaction.drug + }, this.drugstoneConfig.currentConfig(), this.drugstoneConfig); + + if (proteinMap[edge.from]) { + proteinMap[edge.from].forEach(from => { + if (addedEdge[from] && addedEdge[from].indexOf(edge.to) !== -1) { + return; + } + const e = JSON.parse(JSON.stringify(edge)); + e.from = from; + e.to = edge.to; + this.adjacentDrugEdgesList.push(e); + if (!addedEdge[from]) { + addedEdge[from] = [edge.to]; + } else { + addedEdge[from].push(edge.to); + } + }); + } } - } - for (const drug of response.drugs) { - drug.group = 'foundDrug'; - drug.id = getDrugNodeId(drug); - if (!existingDrugIDs.includes(drug.drugstoneId)) { - existingDrugIDs.push(drug.drugstoneId); - this.adjacentDrugList.push(mapCustomNode(drug, this.drugstoneConfig.currentConfig(), this.drugstoneConfig)); + for (const drug of response.drugs) { + drug.group = 'foundDrug'; + drug.id = getDrugNodeId(drug); + if (!existingDrugIDs.includes(drug.drugstoneId)) { + existingDrugIDs.push(drug.drugstoneId); + this.adjacentDrugList.push(mapCustomNode(drug, this.drugstoneConfig.currentConfig(), this.drugstoneConfig)); + } + } + this.nodeData.nodes.add(this.adjacentDrugList); + this.nodeData.edges.add(this.adjacentDrugEdgesList); + this.updateQueryItems(); + }).then(() => { + if (stabl) { + this.stabilize().then(() => { + this.loadingScreen.stateUpdate(false); + resolve(true); + }); + } else { + this.loadingScreen.stateUpdate(false); + resolve(true); } + }); + } else { + // remove adjacent drugs, make sure that also drug associated disorders are removed + if (this.adjacentDisordersDrug) { + await this.updateAdjacentDrugDisorders(false, true); } - this.nodeData.nodes.add(this.adjacentDrugList); - this.nodeData.edges.add(this.adjacentDrugEdgesList); + this.legendService.remove_from_context('adjacentDrugs'); + // if (!this.adjacentDisordersProtein) + // this.legendService.remove_from_context('adjacentDisorders') + this.nodeData.nodes.remove(this.adjacentDrugList); + this.nodeData.edges.remove(this.adjacentDrugEdgesList); + this.adjacentDrugList = []; + this.adjacentDrugEdgesList = []; + this.updateQueryItems(); - this.loadingScreen.stateUpdate(false); - }); - } else { - // remove adjacent drugs, make sure that also drug associated disorders are removed - if (this.adjacentDisordersDrug) { - this.updateAdjacentDrugDisorders(false); + if (stabl) { + this.stabilize().then(() => { + this.loadingScreen.stateUpdate(false); + resolve(true); + }); + } else { + this.loadingScreen.stateUpdate(false); + resolve(true); + } } - this.legendService.remove_from_context('adjacentDrugs'); - // if (!this.adjacentDisordersProtein) - // this.legendService.remove_from_context('adjacentDisorders') - this.nodeData.nodes.remove(this.adjacentDrugList); - this.nodeData.edges.remove(this.adjacentDrugEdgesList); - this.adjacentDrugList = []; - this.adjacentDrugEdgesList = []; - - this.updateQueryItems(); - this.loadingScreen.stateUpdate(false); - } + }); } public saveRemoveDisorders(nodeList: Node[]) { @@ -337,10 +411,10 @@ export class NetworkComponent implements OnInit { } public updatePhysicsEnabled(bool: boolean) { - this.drugstoneConfig.config.physicsOn = bool; + // this.drugstoneConfig.config.physicsOn = bool; this.networkInternal.setOptions({ physics: { - enabled: this.drugstoneConfig.config.physicsOn, + enabled: bool, stabilization: { enabled: false, }, diff --git a/src/app/pages/explorer-page/explorer-page.component.ts b/src/app/pages/explorer-page/explorer-page.component.ts index 54781ccfdd3db617bfae696a07258bb38769dd65..7b13ff0cbd538954f5fc2348c99547222bc6c78d 100644 --- a/src/app/pages/explorer-page/explorer-page.component.ts +++ b/src/app/pages/explorer-page/explorer-page.component.ts @@ -260,12 +260,11 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { if (this.drugstoneConfig.config.physicsOn) { this.networkHandler.activeNetwork.updatePhysicsEnabled(true); } - this.networkHandler.updateAdjacentNodes().catch(e => { - console.log('also error'); + this.networkHandler.updateAdjacentNodes(!this.networkHandler.activeNetwork.isBig()).then((updated) => { + }).catch(e => { console.error(e); }); }).catch(e => { - console.log('Error'); console.error(e); }); } @@ -358,7 +357,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { this.networkHandler.activeNetwork.networkInternal = new vis.Network(container, this.nodeData, options); - this.networkHandler.activeNetwork.networkInternal.on('stabilizationIterationsDone', () => { + this.networkHandler.activeNetwork.networkInternal.once('stabilizationIterationsDone', () => { if (!this.drugstoneConfig.config.physicsOn) { this.networkHandler.activeNetwork.updatePhysicsEnabled(false); } diff --git a/src/app/services/netex-controller/netex-controller.service.ts b/src/app/services/netex-controller/netex-controller.service.ts index 8aa281b9a8e343dda0afb29fdc41602fb854cadb..1b8f3a0f1d0eb5ae6216edbe4c275af4081966f3 100644 --- a/src/app/services/netex-controller/netex-controller.service.ts +++ b/src/app/services/netex-controller/netex-controller.service.ts @@ -72,17 +72,17 @@ export class NetexControllerService { return this.http.post(`${this.getBackend()}tissue_expression/`, payload); } - public adjacentDisorders(nodes: Node[], nodeType: string, dataset: string, licenced: boolean): Observable<any> { + public adjacentDisorders(nodes: Node[], nodeType: string, dataset: string, licenced: boolean): Promise<any> { const params = {dataset: dataset, licenced: licenced}; if (nodeType === 'proteins') { params['proteins'] = nodes.filter((node: Node) => node.drugstoneId && node.drugstoneType === 'protein').flatMap((node: Node) => node.drugstoneId).map(id => id.slice(1)); } else if (nodeType === 'drugs') { params['drugs'] = nodes.map((node: Node) => node.drugId && node.drugstoneType === 'drug' ? node.drugstoneId.slice(2) : undefined).filter(id => id != null); } - return this.http.post<any>(`${this.getBackend()}adjacent_disorders/`, params); + return this.http.post<any>(`${this.getBackend()}adjacent_disorders/`, params).toPromise(); } - public adjacentDrugs(pdiDataset: InteractionDrugProteinDB, licenced: boolean, nodes: Node[]): Observable<any> { + public adjacentDrugs(pdiDataset: InteractionDrugProteinDB, licenced: boolean, nodes: Node[]): Promise<any> { /** * Returns the expression in the given tissue for given nodes and cancerNodes */ @@ -93,7 +93,7 @@ export class NetexControllerService { proteins: genesBackendIds, licenced: licenced }; - return this.http.post<any>(`${this.getBackend()}adjacent_drugs/`, params); + return this.http.post<any>(`${this.getBackend()}adjacent_drugs/`, params).toPromise(); } public graphExport(graph_data: { edges: EdgeType[], nodes: Node[] }) { diff --git a/src/app/services/network-handler/network-handler.service.ts b/src/app/services/network-handler/network-handler.service.ts index e0f862365d3c49414f0abda19e452b58ca3825d3..981a50bfa2054e94652b6f78e8527c201879e1c4 100644 --- a/src/app/services/network-handler/network-handler.service.ts +++ b/src/app/services/network-handler/network-handler.service.ts @@ -35,21 +35,30 @@ export class NetworkHandlerService { return this.change.asObservable(); } - async updateAdjacentNodes(): Promise<any> { + + async updateAdjacentNodes(layout: boolean): Promise<any> { return new Promise<any>(async (resolve, reject) => { + let updated = false; if (this.drugstoneConfig.config.activateNetworkMenuButtonAdjacentDrugs) { this.activeNetwork.adjacentDrugs = true; - await this.activeNetwork.updateAdjacentDrugs(true); + updated = true; + await this.activeNetwork.updateAdjacentDrugs(true, false); } if (this.drugstoneConfig.config.activateNetworkMenuButtonAdjacentDisorders) { this.activeNetwork.adjacentDisordersProtein = true; - await this.activeNetwork.updateAdjacentProteinDisorders(true); + updated = true; + await this.activeNetwork.updateAdjacentProteinDisorders(true, false); } if (this.drugstoneConfig.config.activateNetworkMenuButtonAdjacentDisordersDrugs) { this.activeNetwork.adjacentDisordersDrug = true; - await this.activeNetwork.updateAdjacentDrugDisorders(true); + updated = true; + await this.activeNetwork.updateAdjacentDrugDisorders(true, false); + } + resolve(updated); + }).then((updated) => { + if (layout) { + return this.activeNetwork.stabilize(); } - resolve(true); }); } } diff --git a/src/index.html b/src/index.html index 238f900747275bf56985f1e7ae90a5f2732f6537..1f7d2bca1343049c9dce429e78b756d0f9a009de 100644 --- a/src/index.html +++ b/src/index.html @@ -113,7 +113,7 @@ menu<br> <div style="max-width: 80vw; width: 1276px; height: 500px"> <drugst-one id="netexp1" - config="{}" + config="{'activateNetworkMenuButtonAdjacentDisorders':false,'activateNetworkMenuButtonAdjacentDrugs':true, 'activateNetworkMenuButtonAdjacentDisordersDrugs': true, 'licensedDatasets':true}" groups='{"nodeGroups":{"important":{"type":"gene","color":"#ff881f","font":{"color":"#000000"},"groupName":"Important Gene","shape":"star"},"gene":{"type":"gene","color":"#4da300","font":{"color":"#f0f0f0"},"groupName":"Gene","shape":"circle"},"foundDrug":{"type":"drug","color":"#F12590","font":{"color":"#000000"},"groupName":"Drug","shape":"diamond"}},"edgeGroups":{"default":{"color":"#000000","groupName":"default edge"}}}' network='{"nodes":[{"id":"CFTR","group":"gene","label":"CFTR"},{"id":"TGFB1","group":"gene","label":"TGFB1"},{"id":"TNFRSF1A","group":"gene","label":"TNFRSF1A"},{"id":"FCGR2A","group":"gene","label":"FCGR2A"},{"id":"ENG","group":"gene","label":"ENG"},{"id":"DCTN4","group":"gene","label":"DCTN4"},{"id":"CLCA4","group":"gene","label":"CLCA4"},{"id":"STX1A","group":"gene","label":"STX1A"},{"id":"SCNN1G","group":"gene","label":"SCNN1G"},{"id":"SCNN1A","group":"gene","label":"SCNN1A"},{"id":"SCNN1B","group":"gene","label":"SCNN1B"}],"edges":[{"from":"DCTN4","to":"CFTR"},{"from":"STX1A","to":"SCNN1B","group":"default"},{"from":"SCNN1A","to":"SCNN1G","group":"default"},{"from":"SCNN1B","to":"SCNN1G","group":"default"}]}'> ></drugst-one>