diff --git a/src/app/components/analysis-panel/analysis-panel.component.ts b/src/app/components/analysis-panel/analysis-panel.component.ts index a616c00fca744b42d1394ff7e80d20afe84b5591..ef9ccbac12ee5fc857e8f7baa7abe204b0ab168d 100644 --- a/src/app/components/analysis-panel/analysis-panel.component.ts +++ b/src/app/components/analysis-panel/analysis-panel.component.ts @@ -9,12 +9,9 @@ import { Output, SimpleChanges, ViewChild, -} from "@angular/core"; -import { HttpClient } from "@angular/common/http"; -import { - algorithmNames, - AnalysisService, -} from "../../services/analysis/analysis.service"; +} from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { algorithmNames, AnalysisService } from '../../services/analysis/analysis.service'; import { Drug, NodeAttributeMap, @@ -26,26 +23,23 @@ import { Tissue, Wrapper, NodeInteraction, -} from "../../interfaces"; -import { NetworkSettings } from "../../network-settings"; -import { NetexControllerService } from "src/app/services/netex-controller/netex-controller.service"; -import { - mapCustomEdge, - mapNetexEdge, - ProteinNetwork, -} from "src/app/main-network"; -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 { version } from "../../../version"; -import { downloadCSV } from "src/app/utils"; +} from '../../interfaces'; +import { NetworkSettings } from '../../network-settings'; +import { NetexControllerService } from 'src/app/services/netex-controller/netex-controller.service'; +import { mapCustomEdge, mapNetexEdge, ProteinNetwork } from 'src/app/main-network'; +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 { version } from '../../../version'; +import { downloadCSV } from 'src/app/utils'; +import { Observable } from 'rxjs'; declare var vis: any; interface Scored { - score: number; // Normalized or unnormalized (whichever user selects, will be displayed in the table) - rawScore: number; // Unnormalized (kept to restore unnormalized value) + score: number; // Normalized or unnormalized (whichever user selects, will be displayed in the table) + rawScore: number; // Unnormalized (kept to restore unnormalized value) rank: number; } @@ -53,25 +47,23 @@ interface Seeded { isSeed: boolean; } + @Component({ - selector: "app-analysis-panel", - templateUrl: "./analysis-panel.component.html", - styleUrls: ["./analysis-panel.component.scss"], + selector: 'app-analysis-panel', + templateUrl: './analysis-panel.component.html', + styleUrls: ['./analysis-panel.component.scss'], }) -export class AnalysisPanelComponent - implements OnInit, OnChanges, AfterViewInit -{ - @ViewChild("networkWithLegend", { static: false }) - networkWithLegendEl: ElementRef; +export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit { + + @ViewChild('networkWithLegend', { static: false }) networkWithLegendEl: ElementRef; @Input() token: string | null = null; @Input() tokenType: string | null = null; + @Output() tokenChange = new EventEmitter<string | null>(); @Output() showDetailsChange = new EventEmitter<Wrapper>(); @Output() setInputNetwork = new EventEmitter<any>(); - @Output() visibleItems = new EventEmitter< - [any[], [Node[], Tissue], NodeInteraction[]] - >(); + @Output() visibleItems = new EventEmitter<[any[], [Node[], Tissue], NodeInteraction[]]>(); public task: Task | null = null; public result: any = null; @@ -80,10 +72,10 @@ export class AnalysisPanelComponent public algorithmDefault = undefined; public network: any; - public nodeData: { nodes: any; edges: any } = { nodes: null, edges: null }; + public nodeData: { nodes: any, edges: any } = { nodes: null, edges: null }; // private drugNodes: any[] = []; // private drugEdges: any[] = []; - public tab: "meta" | "network" | "table" = "network"; + public tab: 'meta' | 'network' | 'table' = 'network'; private proteins: any; public effects: any; @@ -94,15 +86,15 @@ export class AnalysisPanelComponent public tableNormalize = false; public tableHasScores = false; - public LegendContext: LegendContext = "drugTarget"; + public LegendContext: LegendContext = 'drugTarget'; public expressionExpanded = false; public selectedTissue: Tissue | null = null; public algorithmNames = algorithmNames; - public tableDrugScoreTooltip = ""; - public tableProteinScoreTooltip = ""; + public tableDrugScoreTooltip = ''; + public tableProteinScoreTooltip = ''; public versionString = undefined; @@ -110,24 +102,23 @@ export class AnalysisPanelComponent public loading = false; - constructor( - public legendService: LegendService, - public networkHandler: NetworkHandlerService, - public drugstoneConfig: DrugstoneConfigService, - private http: HttpClient, - public analysis: AnalysisService, - public netex: NetexControllerService, - public loadingScreen: LoadingScreenService - ) { + + constructor(public legendService: LegendService, public networkHandler: NetworkHandlerService, public drugstoneConfig: DrugstoneConfigService, private http: HttpClient, public analysis: AnalysisService, public netex: NetexControllerService, public loadingScreen: LoadingScreenService) { try { this.versionString = version; - } catch (e) {} + } catch (e) { + } } - async ngOnInit() {} + async ngOnInit() { + } ngAfterViewInit() { - this.networkHandler.setActiveNetwork("analysis"); + this.networkHandler.setActiveNetwork('analysis'); + this.networkHandler.activeNetwork.subscribeSelection(() => { + this.refresh(); + } + ); } async ngOnChanges(changes: SimpleChanges) { @@ -143,69 +134,52 @@ export class AnalysisPanelComponent } private setNetworkListeners() { - this.networkHandler.activeNetwork.networkInternal.on( - "dragEnd", - (properties) => { - const node_ids = - this.networkHandler.activeNetwork.networkInternal.getSelectedNodes(); - if (node_ids.length === 0 || !this.networkHandler.shiftDown) { + this.networkHandler.activeNetwork.networkInternal.on('dragEnd', (properties) => { + const node_ids = this.networkHandler.activeNetwork.networkInternal.getSelectedNodes(); + if (node_ids.length === 0 || !this.networkHandler.shiftDown) { + return; + } + this.analysis.addNodesByIdsToSelection(node_ids); + this.networkHandler.activeNetwork.networkInternal.unselectAll(); + }); + 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; } - this.analysis.addNodesByIdsToSelection(node_ids); - this.networkHandler.activeNetwork.networkInternal.unselectAll(); - } - ); - 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; - } - const wrapper = getWrapperFromNode(node); - if (this.analysis.inSelection(wrapper)) { - this.analysis.removeItems([wrapper]); - this.analysis.getCount(); - } else { - this.analysis.addItems([wrapper]); - this.analysis.getCount(); - } + 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.networkHandler.activeNetwork.networkInternal.on( - "click", - (properties) => { - if (properties.nodes.length === 0 && properties.edges.length === 1) { - // clicked on one edge - const edgeId = properties.edges[0]; - this.networkHandler.activeNetwork.openEdgeSummary(edgeId); + this.networkHandler.activeNetwork.networkInternal.on('click', (properties) => { + if (properties.nodes.length === 0 && properties.edges.length === 1) { + // clicked on one edge + const edgeId = properties.edges[0]; + this.networkHandler.activeNetwork.openEdgeSummary(edgeId); + } else { + this.networkHandler.activeNetwork.activeEdge = null; + const selectedNodes = this.nodeData.nodes.get(properties.nodes); + if (selectedNodes.length > 0) { + this.showDetailsChange.emit(getWrapperFromNode(selectedNodes[0])); } else { - this.networkHandler.activeNetwork.activeEdge = null; - const selectedNodes = this.nodeData.nodes.get(properties.nodes); - if (selectedNodes.length > 0) { - this.showDetailsChange.emit(getWrapperFromNode(selectedNodes[0])); - } else { - this.showDetailsChange.emit(null); - } + this.showDetailsChange.emit(null); } } - ); + }); this.analysis.subscribeList((items, selected) => { // return if analysis panel is closed or no nodes are loaded if (!this.token) { @@ -219,15 +193,10 @@ export class AnalysisPanelComponent if (!node) { continue; } - const pos = - this.networkHandler.activeNetwork.networkInternal.getPositions([ - item.id, - ]); + 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 isSeed = this.networkHandler.activeNetwork.highlightSeeds ? this.networkHandler.activeNetwork.seedMap[node.id] : false; const nodeStyled = NetworkSettings.getNodeStyle( node, this.drugstoneConfig.currentConfig(), @@ -243,12 +212,8 @@ export class AnalysisPanelComponent 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 - ); + 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); } @@ -261,9 +226,7 @@ export class AnalysisPanelComponent // else: selected is null const updatedNodes = []; this.nodeData.nodes.forEach((node) => { - const isSeed = this.networkHandler.activeNetwork.highlightSeeds - ? this.networkHandler.activeNetwork.seedMap[node.id] - : false; + const isSeed = this.networkHandler.activeNetwork.highlightSeeds ? this.networkHandler.activeNetwork.seedMap[node.id] : false; if (!isSeed) { return; } @@ -281,9 +244,7 @@ export class AnalysisPanelComponent const proteinSelection = []; for (const item of items) { - const tableItem = this.tableProteins.find( - (i) => getProteinNodeId(i) === item.id - ); + const tableItem = this.tableProteins.find((i) => getProteinNodeId(i) === item.id); if (tableItem) { proteinSelection.push(tableItem); } @@ -293,9 +254,7 @@ export class AnalysisPanelComponent }); } - private rankTable( - table: Array<Drug & Scored> | Array<Node & Scored & Seeded> - ) { + private rankTable(table: Array<Drug & Scored> | Array<Node & Scored & Seeded>) { let lastRank = 1; for (let idx = 0; idx < table.length; idx++) { if (idx === 0) { @@ -312,13 +271,14 @@ export class AnalysisPanelComponent private async refreshView() { this.loading = true; this.loadingScreen.stateUpdate(true); - this.getView(this.token).then(async (view) => { + this.getView(this.token).then(async view => { this.task = view; this.result = view; this.drugstoneConfig.set_analysisConfig(view.config); this.analysis.switchSelection(this.token); this.loadingScreen.stateUpdate(false); + // Reset this.nodeData = { nodes: null, edges: null }; // this.networkHandler.activeNetwork.networkEl.nativeElement.innerHTML = ''; @@ -330,56 +290,34 @@ export class AnalysisPanelComponent if (this.drugstoneConfig.config.autofillEdges && nodes.length) { const node_map = {}; - nodes - .filter((n) => n.drugstoneType === "protein") - .forEach((node) => { - if (typeof node.drugstoneId === "string") { - if (node_map[node.drugstoneId]) { - node_map[node.drugstoneId].push(node.id); - } else { - node_map[node.drugstoneId] = [node.id]; - } + nodes.filter(n => n.drugstoneType === 'protein').forEach(node => { + if (typeof node.drugstoneId === 'string') { + if (node_map[node.drugstoneId]) { + node_map[node.drugstoneId].push(node.id); } else { - node.drugstoneId.forEach((n) => { - if (node_map[n]) { - node_map[n].push(node.id); - } else { - node_map[n] = [node.id]; - } - }); + node_map[node.drugstoneId] = [node.id]; } - }); - const netexEdges = await this.netex.fetchEdges( - nodes, - this.drugstoneConfig.config.interactionProteinProtein, - this.drugstoneConfig.config.licensedDatasets - ); - edges.push( - ...netexEdges - .map((netexEdge) => - mapNetexEdge( - netexEdge, - this.drugstoneConfig.currentConfig(), - node_map - ) - ) - .flatMap((e) => e) - ); + } else { + node.drugstoneId.forEach(n => { + if (node_map[n]) { + node_map[n].push(node.id); + } else { + node_map[n] = [node.id]; + } + }); + } + }); + const netexEdges = await this.netex.fetchEdges(nodes, this.drugstoneConfig.config.interactionProteinProtein, this.drugstoneConfig.config.licensedDatasets); + edges.push(...netexEdges.map(netexEdge => mapNetexEdge(netexEdge, this.drugstoneConfig.currentConfig(), node_map)).flatMap(e => e)); } const edge_map = {}; - edges = edges.filter((edge) => { - if ( - edge_map[edge.to] && - edge_map[edge.to].indexOf(edge.from) !== -1 - ) { + edges = edges.filter(edge => { + if (edge_map[edge.to] && edge_map[edge.to].indexOf(edge.from) !== -1) { return false; } - if ( - edge_map[edge.from] && - edge_map[edge.from].indexOf(edge.to) !== -1 - ) { + if (edge_map[edge.from] && edge_map[edge.from].indexOf(edge.to) !== -1) { return false; } if (!edge_map[edge.from]) { @@ -392,22 +330,15 @@ export class AnalysisPanelComponent // @ts-ignore if (!this.drugstoneConfig.selfReferences) { - edges = edges.filter((el) => el.from !== el.to); + edges = edges.filter(el => el.from !== el.to); } - this.networkHandler.activeNetwork.inputNetwork = { - nodes: nodes, - edges: 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 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() - ); + const options = NetworkSettings.getOptions(isBig ? 'analysis-big' : 'analysis', this.drugstoneConfig.currentConfig()); // @ts-ignore options.groups = this.drugstoneConfig.currentConfig().nodeGroups; // @ts-ignore @@ -418,31 +349,19 @@ export class AnalysisPanelComponent 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 = new vis.Network(container, this.nodeData, options); if (isBig) { resolve(nodes); } - this.networkHandler.activeNetwork.networkInternal.once( - "stabilizationIterationsDone", - async () => { - if ( - !this.drugstoneConfig.config.physicsOn || - this.networkHandler.activeNetwork.isBig() - ) { - this.networkHandler.activeNetwork.updatePhysicsEnabled(false); - } - this.networkHandler - .updateAdjacentNodes(this.networkHandler.activeNetwork.isBig()) - .then(() => { - resolve(nodes); - }); + this.networkHandler.activeNetwork.networkInternal.once('stabilizationIterationsDone', async () => { + if (!this.drugstoneConfig.config.physicsOn || this.networkHandler.activeNetwork.isBig()) { + this.networkHandler.activeNetwork.updatePhysicsEnabled(false); } - ); + this.networkHandler.updateAdjacentNodes(this.networkHandler.activeNetwork.isBig()).then(() => { + resolve(nodes); + }); + }); }).then(() => { this.setNetworkListeners(); this.emitVisibleItems(true); @@ -450,71 +369,69 @@ export class AnalysisPanelComponent }); } + private async refreshTask() { this.loadingScreen.stateUpdate(true); this.task = await this.getTask(this.token); this.analysis.switchSelection(this.token); - if (this.task.info.algorithm === "degree") { + if (this.task.info.algorithm === 'degree') { this.tableDrugScoreTooltip = - "Normalized number of direct interactions of the drug with the seeds. " + - "The higher the score, the more relevant the drug."; + 'Normalized number of direct interactions of the drug with the seeds. ' + + 'The higher the score, the more relevant the drug.'; this.tableProteinScoreTooltip = - "Normalized number of direct interactions of the protein with the seeds. " + - "The higher the score, the more relevant the protein."; - } else if ( - this.task.info.algorithm === "closeness" || - this.task.info.algorithm === "quick" || - this.task.info.algorithm === "super" - ) { + 'Normalized number of direct interactions of the protein with the seeds. ' + + 'The higher the score, the more relevant the protein.'; + } else if (this.task.info.algorithm === 'closeness' || this.task.info.algorithm === 'quick' || this.task.info.algorithm === 'super') { this.tableDrugScoreTooltip = - "Normalized inverse mean distance of the drug to the seeds. " + - "The higher the score, the more relevant the drug."; + 'Normalized inverse mean distance of the drug to the seeds. ' + + 'The higher the score, the more relevant the drug.'; this.tableProteinScoreTooltip = - "Normalized inverse mean distance of the protein to the seeds. " + - "The higher the score, the more relevant the protein."; - } else if (this.task.info.algorithm === "trustrank") { + 'Normalized inverse mean distance of the protein to the seeds. ' + + 'The higher the score, the more relevant the protein.'; + } else if (this.task.info.algorithm === 'trustrank') { this.tableDrugScoreTooltip = - "Amount of ‘trust’ on the drug at termination of the algorithm. " + - "The higher the score, the more relevant the drug."; + 'Amount of ‘trust’ on the drug at termination of the algorithm. ' + + 'The higher the score, the more relevant the drug.'; this.tableProteinScoreTooltip = - "Amount of ‘trust’ on the protein at termination of the algorithm. " + - "The higher the score, the more relevant the protein."; - } else if (this.task.info.algorithm === "proximity") { + 'Amount of ‘trust’ on the protein at termination of the algorithm. ' + + 'The higher the score, the more relevant the protein.'; + } else if (this.task.info.algorithm === 'proximity') { this.tableDrugScoreTooltip = - "Empirical z-score of mean minimum distance between the drug’s targets and the seeds. " + - "The lower the score, the more relevant the drug."; + 'Empirical z-score of mean minimum distance between the drug’s targets and the seeds. ' + + 'The lower the score, the more relevant the drug.'; this.tableProteinScoreTooltip = - "Empirical z-score of mean minimum distance between the drug’s targets and the seeds. " + - "The lower the score, the more relevant the drug."; + 'Empirical z-score of mean minimum distance between the drug’s targets and the seeds. ' + + 'The lower the score, the more relevant the drug.'; } if (this.task && this.task.info && this.task.info.done) { + this.loading = true; - this.netex.getTaskResult(this.token).then(async (result) => { - if (this.networkHandler.activeNetwork.networkType !== "analysis") { + this.netex.getTaskResult(this.token).then(async result => { + if (this.networkHandler.activeNetwork.networkType !== 'analysis') { return; } this.drugstoneConfig.set_analysisConfig(result.parameters.config); this.analysis.switchSelection(this.token); this.result = result; - if (this.result.parameters.target === "drug") { - this.legendService.add_to_context("drug"); + if (this.result.parameters.target === 'drug') { + this.legendService.add_to_context('drug'); } else { - this.legendService.add_to_context("drugTarget"); + this.legendService.add_to_context('drugTarget'); } const nodeAttributes = this.result.nodeAttributes || {}; - const analysisNetwork = this.networkHandler.networks["analysis"]; + const analysisNetwork = this.networkHandler.networks['analysis']; analysisNetwork.seedMap = nodeAttributes.isSeed || {}; // Reset this.nodeData = { nodes: null, edges: null }; - analysisNetwork.networkEl.nativeElement.innerHTML = ""; + analysisNetwork.networkEl.nativeElement.innerHTML = ''; analysisNetwork.networkInternal = null; // Create - await this.createNetwork(this.result).then((nw) => { + await this.createNetwork(this.result).then(nw => { return new Promise<any>((resolve, reject) => { - if (this.networkHandler.activeNetwork.networkType !== "analysis") { + if (this.networkHandler.activeNetwork.networkType !== 'analysis') { return; } const nodes = nw.nodes; @@ -524,10 +441,7 @@ export class AnalysisPanelComponent this.nodeData.edges = new vis.DataSet(edges); const container = analysisNetwork.networkEl.nativeElement; const isBig = nodes.length > 100 || edges.length > 100; - const options = NetworkSettings.getOptions( - isBig ? "analysis-big" : "analysis", - this.drugstoneConfig.currentConfig() - ); + const options = NetworkSettings.getOptions(isBig ? 'analysis-big' : 'analysis', this.drugstoneConfig.currentConfig()); // @ts-ignore options.groups = this.drugstoneConfig.currentConfig().nodeGroups; // @ts-ignore @@ -538,103 +452,68 @@ export class AnalysisPanelComponent if (this.drugstoneConfig.config.physicsOn) { this.drugstoneConfig.config.physicsOn = !isBig; } - analysisNetwork.networkInternal = new vis.Network( - container, - this.nodeData, - options - ); + analysisNetwork.networkInternal = new vis.Network(container, this.nodeData, options); if (isBig) { resolve(nodes); } - analysisNetwork.networkInternal.once( - "stabilizationIterationsDone", - async () => { - if ( - !this.drugstoneConfig.config.physicsOn || - analysisNetwork.isBig() - ) { - analysisNetwork.updatePhysicsEnabled(false); - } - this.networkHandler - .updateAdjacentNodes(analysisNetwork.isBig()) - .then(() => { - resolve(nodes); - }); + analysisNetwork.networkInternal.once('stabilizationIterationsDone', async () => { + if (!this.drugstoneConfig.config.physicsOn || analysisNetwork.isBig()) { + analysisNetwork.updatePhysicsEnabled(false); } - ); - }) - .then((nodes) => { - this.tableDrugs = nodes.filter( - (e) => e.drugstoneId && e.drugstoneType === "drug" - ); - this.tableDrugs.forEach((r) => { - r.rawScore = r.score; - }); - // @ts-ignore - this.tableDrugs.sort((a, b) => b.score - a.score); - this.rankTable(this.tableDrugs); - this.tableProteins = nodes.filter( - (e) => e.drugstoneId && e.drugstoneType === "protein" - ); - this.tableSelectedProteins = []; - this.tableProteins.forEach((r) => { - r.rawScore = r.score; - r.isSeed = analysisNetwork.seedMap[r.id]; - const wrapper = getWrapperFromNode(r); - if (this.analysis.inSelection(wrapper)) { - this.tableSelectedProteins.push(r); - } - }); - this.tableProteins.sort((a, b) => b.score - a.score); - this.rankTable(this.tableProteins); - - this.tableHasScores = - [ - "trustrank", - "closeness", - "degree", - "betweenness", - "quick", - "super", - ].indexOf(this.task.info.algorithm) !== -1; - if (this.tableHasScores) { - this.toggleNormalization(true); - } - analysisNetwork.networkInternal.setData({ - nodes: undefined, - edge: undefined, + this.networkHandler.updateAdjacentNodes(analysisNetwork.isBig()).then(() => { + resolve(nodes); }); - setTimeout(() => { - analysisNetwork.networkInternal.setData(this.nodeData); - }, 1000); - this.setNetworkListeners(); - this.emitVisibleItems(true); - }) - .then(() => { - if ( - !["quick", "super", "connect", "connectSelected"].includes( - this.task.info.algorithm - ) - ) { - return; + }); + }).then(nodes => { + this.tableDrugs = nodes.filter(e => e.drugstoneId && e.drugstoneType === 'drug'); + this.tableDrugs.forEach((r) => { + r.rawScore = r.score; + }); + // @ts-ignore + this.tableDrugs.sort((a, b) => b.score - a.score); + this.rankTable(this.tableDrugs); + this.tableProteins = nodes.filter(e => e.drugstoneId && e.drugstoneType === 'protein'); + this.tableSelectedProteins = []; + this.tableProteins.forEach((r) => { + r.rawScore = r.score; + r.isSeed = analysisNetwork.seedMap[r.id]; + const wrapper = getWrapperFromNode(r); + if (this.analysis.inSelection(wrapper)) { + this.tableSelectedProteins.push(r); } - this.netex - .getAlgorithmDefaults(this.task.info.algorithm) - .then((response) => { - this.algorithmDefault = response; - }); - }) - .catch(console.error); + }); + this.tableProteins.sort((a, b) => b.score - a.score); + this.rankTable(this.tableProteins); + + this.tableHasScores = ['trustrank', 'closeness', 'degree', 'betweenness', 'quick', 'super'] + .indexOf(this.task.info.algorithm) !== -1; + if (this.tableHasScores) { + this.toggleNormalization(true); + } + analysisNetwork.networkInternal.setData({ nodes: undefined, edge: undefined }); + setTimeout(() => { + analysisNetwork.networkInternal.setData(this.nodeData); + }, 1000); + this.setNetworkListeners(); + this.emitVisibleItems(true); + }).then(() => { + this.loadingScreen.stateUpdate(false); + if (!['quick', 'super', 'connect', 'connectSelected'].includes(this.task.info.algorithm)) { + return; + } + this.netex.getAlgorithmDefaults(this.task.info.algorithm).then(response => { + this.algorithmDefault = response; + }); + }).catch(console.error); }); - this.loadingScreen.stateUpdate(false); }); } } private async refresh() { if (this.token) { - if (this.tokenType === "view") { + if (this.tokenType === 'view') { this.networkHandler.showSeedsButton = false; await this.refreshView(); } else { @@ -642,47 +521,39 @@ export class AnalysisPanelComponent await this.refreshTask(); } } + } public emitVisibleItems(on: boolean) { if (on) { - this.visibleItems.emit([ - this.nodeData.nodes, - [this.proteins, this.selectedTissue], - this.nodeData.edges, - ]); + this.visibleItems.emit([this.nodeData.nodes, [this.proteins, this.selectedTissue], this.nodeData.edges]); } else { this.visibleItems.emit(null); } } private async getView(token: string): Promise<any> { - return await this.http - .get(`${this.netex.getBackend()}view/?token=${token}`) - .toPromise(); + return await this.http.get(`${this.netex.getBackend()}view/?token=${token}`).toPromise(); } private async getTask(token: string): Promise<any> { - return await this.http - .get(`${this.netex.getBackend()}task/?token=${token}`) - .toPromise(); + return await this.http.get(`${this.netex.getBackend()}task/?token=${token}`).toPromise(); } close() { - const analysisNetwork = this.networkHandler.networks["analysis"]; + const analysisNetwork = this.networkHandler.networks['analysis']; analysisNetwork.gradientMap = {}; this.drugstoneConfig.remove_analysisConfig(); this.expressionExpanded = false; this.expressionMap = undefined; analysisNetwork.seedMap = {}; analysisNetwork.highlightSeeds = false; - this.legendService.networkHasConnector = false; - this.analysis.switchSelection("main"); + this.analysis.switchSelection('main'); // this.analysis.resetSelection(); this.token = null; this.tokenChange.emit(this.token); - this.legendService.remove_from_context("drug"); - this.legendService.remove_from_context("drugTarget"); + this.legendService.remove_from_context('drug'); + this.legendService.remove_from_context('drugTarget'); this.emitVisibleItems(false); } @@ -691,30 +562,30 @@ export class AnalysisPanelComponent const normalizeFn = (table) => { let max = 0; - table.forEach((i) => { + table.forEach(i => { if (i.rawScore > max) { max = i.rawScore; } }); - table.forEach((i) => { + table.forEach(i => { i.score = i.rawScore / max; }); }; const unnormalizeFn = (table) => { - table.forEach((i) => { + table.forEach(i => { i.score = i.rawScore; }); }; if (normalize) { normalizeFn(this.tableProteins); - if (this.task.info.target === "drug") { + if (this.task.info.target === 'drug') { normalizeFn(this.tableDrugs); } } else { unnormalizeFn(this.tableProteins); - if (this.task.info.target === "drug") { + if (this.task.info.target === 'drug') { unnormalizeFn(this.tableDrugs); } } @@ -729,22 +600,11 @@ export class AnalysisPanelComponent } }); - if ("score" in data[0]) { - data = data.sort((a, b) => b["score"] - a["score"]); + if ('score' in data[0]) { + data = data.sort((a, b) => b['score'] - a['score']); } - const columns = [ - "label", - "symbol", - "uniprot", - "ensg", - "entrez", - "proteinName", - "isSeed", - "score", - "rank", - "status", - ]; + const columns = ['label', 'symbol', 'uniprot', 'ensg', 'entrez', 'proteinName', 'isSeed', 'score', 'rank', 'status']; downloadCSV(data, columns, `drugstone_${view}`); } @@ -754,14 +614,12 @@ export class AnalysisPanelComponent * @param result * @returns */ - public async createNetwork( - result: any - ): Promise<{ edges: any[]; nodes: any[] }> { + public async createNetwork(result: any): Promise<{ edges: any[]; nodes: any[]; }> { const identifier = this.drugstoneConfig.currentConfig().identifier; // add drugGroup and foundNodesGroup for added nodes // these groups can be overwritten by the user - const nodes = []; + let nodes = []; let edges = []; const attributes = result.nodeAttributes || {}; @@ -772,84 +630,68 @@ export class AnalysisPanelComponent network.nodes = [...new Set<string>(network.nodes)]; const details = attributes.details || {}; const nodeIdMap = {}; - Object.entries(details) // @ts-ignore - .filter((e) => e[1].drugstoneType === "protein") - .forEach((e) => { - // @ts-ignore - e[1].drugstoneId.forEach((id) => { - nodeIdMap[id] = e[1][identifier][0]; - }); + Object.entries(details).filter(e => e[1].drugstoneType === 'protein').forEach(e => { + // @ts-ignore + e[1].drugstoneId.forEach(id => { + nodeIdMap[id] = e[1][identifier][0]; }); + }); for (const nodeId of network.nodes) { if (details[nodeId]) { const nodeDetails = details[nodeId]; - nodeDetails.id = nodeDetails.id - ? nodeDetails.id - : typeof nodeDetails.drugstoneId === "string" - ? nodeDetails.drugstoneId - : nodeDetails.drugstoneId[0]; - if ( - nodeDetails.drugstoneId && - nodeDetails.drugstoneType === "protein" - ) { + nodeDetails.id = nodeDetails.id ? nodeDetails.id : (typeof nodeDetails.drugstoneId === 'string' ? nodeDetails.drugstoneId : nodeDetails.drugstoneId[0]); + if (nodeDetails.drugstoneId && nodeDetails.drugstoneType === 'protein') { // node is protein from database, has been mapped on init to backend protein from backend // or was found during analysis // FIXME connectorNodes are not visualized correctly - nodeDetails.group = - result.targetNodes && result.targetNodes.indexOf(nodeId) !== -1 - ? "foundNode" - : nodeDetails.group - ? nodeDetails.group - : "connectorNode"; - nodeDetails.label = nodeDetails.label - ? nodeDetails.label - : nodeDetails[identifier]; - nodeDetails.id = nodeDetails[identifier][0] - ? nodeDetails[identifier][0] - : nodeDetails.id; + nodeDetails.group = result.targetNodes && result.targetNodes.indexOf(nodeId) !== -1 ? 'foundNode' : (nodeDetails.group ? nodeDetails.group : 'connectorNode'); + nodeDetails.label = nodeDetails.label ? nodeDetails.label : nodeDetails[identifier]; + nodeDetails.id = nodeDetails[identifier][0] ? nodeDetails[identifier][0] : nodeDetails.id; this.proteins.push(nodeDetails); - } else if ( - nodeDetails.drugstoneId && - nodeDetails.drugstoneType === "drug" - ) { + } else if (nodeDetails.drugstoneId && nodeDetails.drugstoneType === 'drug') { // node is drug, was found during analysis - nodeDetails.type = "Drug"; - nodeDetails.group = "foundDrug"; + nodeDetails.type = 'Drug'; + nodeDetails.group = 'foundDrug'; + } else { // node is custom input from user, could not be mapped to backend protein - nodeDetails.group = nodeDetails.group ? nodeDetails.group : "default"; - nodeDetails.label = nodeDetails.label - ? nodeDetails.label - : nodeDetails[identifier]; + nodeDetails.group = nodeDetails.group ? nodeDetails.group : 'default'; + nodeDetails.label = nodeDetails.label ? nodeDetails.label : nodeDetails[identifier]; } // further analysis and the button function can be used to highlight seeds // option to use scores[node] as gradient, but sccores are very small - nodes.push( - NetworkSettings.getNodeStyle( - nodeDetails as Node, - this.drugstoneConfig.currentConfig(), - false, - false, - 1, - this.networkHandler.activeNetwork.nodeRenderer - ) - ); + nodes.push(NetworkSettings.getNodeStyle(nodeDetails as Node, this.drugstoneConfig.currentConfig(), false, false, 1, this.networkHandler.activeNetwork.nodeRenderer)); } else { - console.log("Missing details for " + nodeId); + console.log('Missing details for ' + nodeId); } } const uniqEdges = []; + const skippedDrugIds = new Set<string>(); + const drugEdgeTypes = new Set<string>(); for (const edge of network.edges) { - const e = mapCustomEdge( - edge, - this.drugstoneConfig.currentConfig(), - this.drugstoneConfig - ); - e.from = - e.from[0] === "p" && nodeIdMap[e.from] ? nodeIdMap[e.from] : e.from; - e.to = e.to[0] === "p" && nodeIdMap[e.to] ? nodeIdMap[e.to] : e.to; - const hash = e.from + "_" + e.to; + const e = mapCustomEdge(edge, this.drugstoneConfig.currentConfig(), this.drugstoneConfig); + const isDrugEdge = e.to[0] === 'd' && e.to[1] === 'r'; + e.from = e.from[0] === 'p' && nodeIdMap[e.from] ? nodeIdMap[e.from] : e.from; + e.to = e.to[0] === 'p' && nodeIdMap[e.to] ? nodeIdMap[e.to] : e.to; + if (isDrugEdge) { + skippedDrugIds.add(e.to); + if (edge.actions) { + edge.actions.forEach(a => drugEdgeTypes.add(a)); + } + if (edge.actions && this.networkHandler.activeNetwork.getSelectedDrugTargetType() && !edge.actions.includes(this.networkHandler.activeNetwork.getSelectedDrugTargetType())) { + continue; + } + const label = edge.actions && edge.actions.length > 0 ? edge.actions.join(',') : undefined; + skippedDrugIds.delete(e.to); + if (label) { + e.label = label; + } + } + + this.networkHandler.activeNetwork.setDrugTargetTypes(Array.from(drugEdgeTypes)); + + const hash = e.from + '_' + e.to; if (uniqEdges.indexOf(hash) === -1) { uniqEdges.push(hash); edges.push(e); @@ -857,35 +699,30 @@ export class AnalysisPanelComponent } // remove self-edges/loops if (!this.drugstoneConfig.currentConfig().selfReferences) { - edges = edges.filter((el) => el.from !== el.to); + edges = edges.filter(el => el.from !== el.to); } + nodes = nodes.filter(n => !(n.drugstoneId && skippedDrugIds.has(n.drugstoneId))); + // if (this.networkHandler.activeNetwork.selectedDrugTargetType) { + // } + + this.legendService.networkHasConnector = nodes.filter(node => node.group === 'connectorNode').length > 0; - this.legendService.networkHasConnector = - nodes.filter((node) => node.group === "connectorNode").length > 0; - - return { + return { nodes, edges, }; } getResultNodes() { - if (this.nodeData && this.nodeData["nodes"]) { - return this.nodeData["nodes"].get(); + if (this.nodeData && this.nodeData['nodes']) { + return this.nodeData['nodes'].get(); } return []; } getResultEdges() { - if (this.nodeData && this.nodeData["edges"]) { - return this.nodeData["edges"] - .get() - .filter( - (e) => - !e.id || - !e.groupName || - (typeof e.from === "string" && typeof e.to === "string") - ); + if (this.nodeData && this.nodeData['edges']) { + return this.nodeData['edges'].get().filter(e => !e.id || !e.groupName || (typeof e.from === 'string' && typeof e.to === 'string')); } return []; } @@ -923,4 +760,5 @@ export class AnalysisPanelComponent public openBugreport() { this.drugstoneConfig.showBugreport = true; } + } 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 cf04a2a70b9f986f6e026d37e6353c7ec5adaa3a..1568447f2f0b71fdf56c2faad713136eb887708b 100644 --- a/src/app/components/network/network-menu/network-menu.component.html +++ b/src/app/components/network/network-menu/network-menu.component.html @@ -61,7 +61,7 @@ [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }" - >Screenshot</span + >Screenshot</span > </button> </div> @@ -112,14 +112,14 @@ [ngClass]="{ 'text-small': drugstoneConfig.smallStyle }" - >Tissue</span + >Tissue</span > <span *ngIf="networkHandler.activeNetwork.selectedTissue" [ngClass]="{ 'text-small': drugstoneConfig.smallStyle }" - >{{ networkHandler.activeNetwork.selectedTissue.name }}</span + >{{ networkHandler.activeNetwork.selectedTissue.name }}</span > <app-fa-solid-icon icon="angle-down" @@ -182,7 +182,93 @@ networkHandler.activeNetwork.updateAdjacentDrugs($event, true) " ></app-toggle-inplace> +<!-- <div class="row is-full m-1" *ngIf="networkHandler.activeNetwork.showsAdjacentDrugs() || networkHandler.activeNetwork.hasDrugsLoaded()">--> +<!-- <div--> +<!-- class="dropdown network-footer-toolbar-element"--> +<!-- [class.is-active]="networkHandler.activeNetwork.drugTargetSelectionExpanded"--> +<!-- [ngClass]="{--> +<!-- 'inner-dropdown': !networkHandler.networkSidebarOpen--> +<!-- }"--> +<!-- >--> +<!-- <div class="dropdown-trigger">--> +<!-- <button--> +<!-- (click)="--> +<!-- networkHandler.activeNetwork.drugTargetSelectionExpanded =--> +<!-- !networkHandler.activeNetwork.drugTargetSelectionExpanded--> +<!-- "--> +<!-- class="button is-rounded"--> +<!-- [disabled]="networkHandler.activeNetwork.getDrugTargetTypes().length === 0"--> +<!-- [class.is-primary]="networkHandler.activeNetwork.getSelectedDrugTargetType()"--> +<!-- aria-haspopup="true"--> +<!-- aria-controls="dropdown-menu"--> +<!-- pTooltip="Filter drug-target edges by drug action annotation."--> +<!-- [tooltipStyleClass]="'drgstn drgstn-tooltip drgstn-tooltip-left'"--> +<!-- tooltipPosition="left"--> +<!-- [ngClass]="{--> +<!-- 'is-small': drugstoneConfig.smallStyle--> +<!-- }"--> +<!-- >--> +<!-- <app-fa-solid-icon icon="crosshairs"></app-fa-solid-icon>--> + +<!-- <span--> +<!-- *ngIf="!networkHandler.activeNetwork.getSelectedDrugTargetType()"--> +<!-- [ngClass]="{--> +<!-- 'text-small': drugstoneConfig.smallStyle--> +<!-- }"--> +<!-- >Actions</span--> +<!-- >--> +<!-- <span--> +<!-- *ngIf="networkHandler.activeNetwork.getSelectedDrugTargetType()"--> +<!-- [ngClass]="{--> +<!-- 'text-small': drugstoneConfig.smallStyle--> +<!-- }"--> +<!-- >{{ networkHandler.activeNetwork.getSelectedDrugTargetType() }}</span--> +<!-- >--> +<!-- <app-fa-solid-icon--> +<!-- icon="angle-down"--> +<!-- classString="is-small last-item-in-button"--> +<!-- *ngIf="networkHandler.activeNetwork.drugTargetSelectionExpanded"--> +<!-- ></app-fa-solid-icon>--> +<!-- <app-fa-solid-icon--> +<!-- icon="angle-left"--> +<!-- classString="is-small last-item-in-button"--> +<!-- *ngIf="!networkHandler.activeNetwork.drugTargetSelectionExpanded"--> +<!-- ></app-fa-solid-icon>--> +<!-- </button>--> +<!-- </div>--> +<!-- <div class="dropdown-menu" id="drug-dropdown-menu" role="menu">--> +<!-- <div class="dropdown-content tissue-dropdown">--> +<!-- <div class="scroll-area">--> +<!-- <a--> +<!-- (click)="networkHandler.activeNetwork.updateAdjacentDrugSelection(null,true)"--> +<!-- [class.is-active]="--> +<!-- !networkHandler.activeNetwork.getSelectedDrugTargetType()--> +<!-- "--> +<!-- [ngClass]="{'text-small': drugstoneConfig.smallStyle}"--> +<!-- class="dropdown-item"--> +<!-- >--> +<!-- None--> +<!-- </a>--> +<!-- <a--> +<!-- *ngFor="--> +<!-- let drugTargetType of networkHandler.activeNetwork.getDrugTargetTypes()--> +<!-- "--> +<!-- (click)="networkHandler.activeNetwork.updateAdjacentDrugSelection(drugTargetType, true)"--> +<!-- [class.is-active]="--> +<!-- networkHandler.activeNetwork.getSelectedDrugTargetType() && networkHandler.activeNetwork.getSelectedDrugTargetType() === drugTargetType--> +<!-- "--> +<!-- [ngClass]="{'text-small': drugstoneConfig.smallStyle}"--> +<!-- class="dropdown-item"--> +<!-- >--> +<!-- {{ drugTargetType }}--> +<!-- </a>--> +<!-- </div>--> +<!-- </div>--> +<!-- </div>--> +<!-- </div>--> +<!-- </div>--> </div> + <div class="row is-full m-1" *ngIf=" diff --git a/src/app/components/network/network.component.ts b/src/app/components/network/network.component.ts index 66c2bbe61aea7a12ba2335f489d00f48cc3a4975..3f2d8264fffd09aec2ce3e651860302f1894e2e6 100644 --- a/src/app/components/network/network.component.ts +++ b/src/app/components/network/network.component.ts @@ -23,6 +23,7 @@ import {NetworkHandlerService} from 'src/app/services/network-handler/network-ha import {LegendService} from 'src/app/services/legend-service/legend-service.service'; import {LoadingScreenService} from 'src/app/services/loading-screen/loading-screen.service'; import {version} from '../../../version'; +import {Subject} from 'rxjs'; @Component({ selector: 'app-network', @@ -60,6 +61,12 @@ export class NetworkComponent implements OnInit { public adjacentDrugs = false; + public selectedDrugTargetType = new Subject<string | null>(); + public selectedDrugTargetTypeLast: string | null = null; + public selectedDrugTargetType$ = this.selectedDrugTargetType.asObservable(); + public drugTargetTypes: string[] = []; + public drugTargetTypesWithoutAdj: string[] = []; + public adjacentDisordersProtein = false; public adjacentDisordersDrug = false; public adjacentDrugList: Node[] = []; @@ -77,8 +84,10 @@ export class NetworkComponent implements OnInit { public currentViewEdges: NodeInteraction[]; public expressionExpanded = false; + public drugTargetSelectionExpanded = false; public selectedTissue: Tissue | null = null; + // change this to true to have sidebar open per default // public networkSidebarOpen = false; @@ -130,6 +139,37 @@ export class NetworkComponent implements OnInit { return {edges: this.inputNetwork.edges, nodes}; } + public getDrugTargetTypes() { + return this.drugTargetTypes; + } + + public subscribeSelection(callback) { + this.selectedDrugTargetType$.subscribe(() => { + callback(); + }); + } + + public setDrugTargetTypes(drugTargetTypes: string[], adj = false) { + if (adj) { + this.drugTargetTypesWithoutAdj = [...drugTargetTypes]; + drugTargetTypes.filter(type => !this.drugTargetTypes.includes(type)).forEach((type) => { + this.drugTargetTypes.push(type); + }); + } else { + this.drugTargetTypes = drugTargetTypes; + } + } + + // TODO create method to get selected drug target type as string instead of subject or observable + public setSelectedDrugTargetType(value: string | null) { + this.selectedDrugTargetTypeLast = value; + this.selectedDrugTargetType.next(value); + } + + public getSelectedDrugTargetType() { + return this.selectedDrugTargetTypeLast; + } + resetInputNetwork() { const nodes = this.inputNetwork.nodes; nodes.forEach(n => { @@ -333,6 +373,38 @@ export class NetworkComponent implements OnInit { }); } + public updateAdjacentDrugSelection(event, stabil: boolean) { + this.networkHandler.activeNetwork.drugTargetSelectionExpanded = false; + if (event === this.getSelectedDrugTargetType()) { + return; + } + this.setSelectedDrugTargetType(event); + if (this.networkHandler.activeNetwork.showsAdjacentDrugs()) { + this.updateAdjacentDrugs(false, false).then(() => { + // if (this.networkHandler.activeNetwork.hasDrugsLoaded()) { + // this.updateFoundDrugs(stabil).then(() => { + this.updateAdjacentDrugs(true, stabil); + // }); + // } else { + // this.updateAdjacentDrugs(true, stabil); + // } + }); + } + // else { + // this.updateFoundDrugs(stabil); + // } + } + + public showsAdjacentDrugs(): boolean { + return this.adjacentDrugs; + } + + public updateFoundDrugs(stabl: boolean): Promise<any> { + return new Promise<boolean>(async (resolve, reject) => { + + }); + } + public updateAdjacentDrugs(bool: boolean, stabl: boolean): Promise<any> { return new Promise<boolean>(async (resolve, reject) => { this.loadingScreen.stateUpdate(true); @@ -345,12 +417,21 @@ export class NetworkComponent implements OnInit { 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); + const availableDrugTargetTypes = new Set<string>(); for (const interaction of response.pdis) { + if (interaction.actions) { + for (const action of interaction.actions) { + availableDrugTargetTypes.add(action); + } + } + if (this.networkHandler.activeNetwork.getSelectedDrugTargetType() && interaction.actions && !interaction.actions.includes(this.networkHandler.activeNetwork.getSelectedDrugTargetType())) { + continue; + } + const label = interaction.actions && interaction.actions.length > 0 ? interaction.actions.join(',') : undefined; 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) { @@ -359,6 +440,9 @@ export class NetworkComponent implements OnInit { const e = JSON.parse(JSON.stringify(edge)); e.from = from; e.to = edge.to; + if (label) { + e.label = label; + } this.adjacentDrugEdgesList.push(e); if (!addedEdge[from]) { addedEdge[from] = [edge.to]; @@ -367,11 +451,16 @@ export class NetworkComponent implements OnInit { } }); } + this.networkHandler.activeNetwork.setDrugTargetTypes(Array.from(availableDrugTargetTypes), true); } + const addedDrugs = new Set<string>(); + Object.values(addedEdge).forEach(targets => { // @ts-ignore + targets.forEach(t => addedDrugs.add(t)); + }); for (const drug of response.drugs) { drug.group = 'foundDrug'; drug.id = getDrugNodeId(drug); - if (!existingDrugIDs.includes(drug.drugstoneId)) { + if (!existingDrugIDs.includes(drug.drugstoneId) && addedDrugs.has(drug.drugstoneId)) { existingDrugIDs.push(drug.drugstoneId); this.adjacentDrugList.push(mapCustomNode(drug, this.drugstoneConfig.currentConfig(), this.drugstoneConfig)); } @@ -633,7 +722,7 @@ export class NetworkComponent implements OnInit { public hasDrugsLoaded(): boolean { if (this.nodeData && this.nodeData.nodes) { for (const node of this.nodeData.nodes.get()) { - if (node.drugstoneType && node.drugstoneId === 'drug') { + if (node.drugstoneType && node.drugstoneType === 'drug') { return true; } }