diff --git a/src/app/components/analysis-panel/analysis-panel.component.html b/src/app/components/analysis-panel/analysis-panel.component.html index 88197f201dfe675e9e9584fc6ae75d5816a8402f..a4a979d91cc79c5ef16818e95e8e147a1741e957 100644 --- a/src/app/components/analysis-panel/analysis-panel.component.html +++ b/src/app/components/analysis-panel/analysis-panel.component.html @@ -226,7 +226,6 @@ <app-network networkType="analysis" [nodeData]="nodeData" - [legendContext]="legendContext" ></app-network> <!-- network end --> </div> diff --git a/src/app/components/analysis-panel/analysis-panel.component.ts b/src/app/components/analysis-panel/analysis-panel.component.ts index f52cdb3bab8de54e849af28c9febcc38ce9868ea..1745bcbaa9cf5bd400ea6a2708456f1f1ddd2b93 100644 --- a/src/app/components/analysis-panel/analysis-panel.component.ts +++ b/src/app/components/analysis-panel/analysis-panel.component.ts @@ -35,7 +35,7 @@ import {mapCustomEdge, mapCustomNode} from 'src/app/main-network'; import {downLoadFile, pieChartContextRenderer, removeDuplicateObjectsFromList} from 'src/app/utils'; 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'; declare var vis: any; @@ -84,7 +84,6 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit public nodeData: { nodes: any, edges: any } = {nodes: null, edges: null}; // private drugNodes: any[] = []; // private drugEdges: any[] = []; - public showDrugs = false; public tab: 'meta' | 'network' | 'table' = 'table'; // public adjacentDrugs = false; @@ -121,9 +120,7 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit public expressionMap: NodeAttributeMap; - public legendContext: LegendContext = 'drug'; - - constructor(public networkHandler: NetworkHandlerService, public drugstoneConfig: DrugstoneConfigService, private http: HttpClient, public analysis: AnalysisService, public netex: NetexControllerService) { + constructor(public legendService: LegendService, public networkHandler: NetworkHandlerService, public drugstoneConfig: DrugstoneConfigService, private http: HttpClient, public analysis: AnalysisService, public netex: NetexControllerService) { } async ngOnInit() { @@ -174,6 +171,11 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit if (this.task && this.task.info.done) { this.result = await this.netex.getTaskResult(this.token); + if (this.result.parameters.target === 'drug') { + this.legendService.add_to_context('drug') + } else { + this.legendService.add_to_context('drugTarget') + } const nodeAttributes = this.result.nodeAttributes || {}; this.networkHandler.activeNetwork.seedMap = nodeAttributes.isSeed || {}; @@ -182,7 +184,6 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit this.nodeData = {nodes: null, edges: null}; this.networkHandler.activeNetwork.networkEl.nativeElement.innerHTML = ''; this.networkHandler.activeNetwork.networkInternal = null; - this.showDrugs = false; // Create const {nodes, edges} = this.createNetwork(this.result); @@ -328,7 +329,6 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit } this.emitVisibleItems(true); - this.networkHandler.activeNetwork.setLegendContext(); } public emitVisibleItems(on: boolean) { @@ -349,10 +349,11 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit this.expressionMap = undefined; this.networkHandler.activeNetwork.seedMap = {}; this.networkHandler.activeNetwork.highlightSeeds = false; - this.showDrugs = false; this.analysis.switchSelection('main'); this.token = null; this.tokenChange.emit(this.token); + this.legendService.remove_from_context('drug') + this.legendService.remove_from_context('drugTarget') this.emitVisibleItems(false); } @@ -454,8 +455,8 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit for (const edge of network.edges) { const e = mapCustomEdge(edge, this.myConfig) - 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 + 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; if (uniqEdges.indexOf(hash) === -1) { uniqEdges.push(hash); diff --git a/src/app/components/network/network-legend/network-legend.component.ts b/src/app/components/network/network-legend/network-legend.component.ts index 0ff409f054554a05cf9c8b08a372db69b96257dd..7fc7c10b4401e87e6c924c6055d88c0acf8622b8 100644 --- a/src/app/components/network/network-legend/network-legend.component.ts +++ b/src/app/components/network/network-legend/network-legend.component.ts @@ -2,6 +2,7 @@ import {Component, Input, OnInit} from '@angular/core'; import { LegendContext } from 'src/app/interfaces'; import { DrugstoneConfigService } from 'src/app/services/drugstone-config/drugstone-config.service'; import {IConfig} from '../../../config'; +import {LegendService} from "src/app/services/legend-service/legend-service.service"; @Component({ selector: 'app-network-legend', @@ -18,17 +19,6 @@ export class NetworkLegendComponent implements OnInit { }; @Input() config: IConfig; - private contextNodeGroupsToDelete = { - 'explorer': ['foundNode', 'foundDrug', 'seedNode', 'default', 'defaultDisorder', 'connectorNode'], - 'adjacentDrugs': ['foundNode', 'seedNode', 'default', 'defaultDisorder', 'connectorNode'], - 'adjacentDisorders': ['foundDrug', 'foundNode', 'seedNode', 'default', 'connectorNode'], - 'adjacentDrugsAndDisorders': ['foundNode', 'seedNode', 'default', 'connectorNode'], - 'drugTarget': ['foundDrug', 'seedNode', 'default', 'defaultDisorder'], - 'drug': ['seedNode', 'default', 'defaultDisorder'], - 'drugTargetAndSeeds': ['foundDrug', 'default', 'defaultDisorder'], - 'drugAndSeeds': ['default', 'defaultDisorder'] - } - private contextEdgeGroupsToDelete = { 'explorer': ['default'], 'adjacentDrugs': ['default'], @@ -45,7 +35,7 @@ export class NetworkLegendComponent implements OnInit { // selected node is not supposed to appear in legend return false; } - return !this.contextNodeGroupsToDelete[this._context].includes(nodeGroupKey); + return !this.legendService.get_nodes_to_delete().includes(nodeGroupKey); } public checkEdgeGroupContext(edgeGroupKey) { @@ -56,7 +46,7 @@ export class NetworkLegendComponent implements OnInit { return Object.keys(this.config.edgeGroups).some(key => this.checkEdgeGroupContext(key)); } - constructor(public drugstoneConfig: DrugstoneConfigService) { } + constructor(public drugstoneConfig: DrugstoneConfigService, public legendService: LegendService) { } ngOnInit(): void { } diff --git a/src/app/components/network/network.component.html b/src/app/components/network/network.component.html index 9994b849d585f5a90f9c51eacfe1f36a9cdfdf48..cad5b5e2718e7c4bcd1cf46aab7e79af1f209909 100644 --- a/src/app/components/network/network.component.html +++ b/src/app/components/network/network.component.html @@ -36,7 +36,6 @@ <div *ngIf="drugstoneConfig.config.showLegend"> <app-network-legend [config]="drugstoneConfig.config" - [context]="legendContext" ></app-network-legend> </div> <div class="center image1 fullheight" #network> diff --git a/src/app/components/network/network.component.ts b/src/app/components/network/network.component.ts index d15cf243bf16f0563e7dfebb65860434a0bdbc56..27e6776b17acf4b979edce7d322686b55a9cb6aa 100644 --- a/src/app/components/network/network.component.ts +++ b/src/app/components/network/network.component.ts @@ -21,6 +21,7 @@ import {AnalysisService} from 'src/app/services/analysis/analysis.service'; import {NetworkSettings} from 'src/app/network-settings'; import {pieChartContextRenderer} from 'src/app/utils'; import {NetworkHandlerService} from 'src/app/services/network-handler/network-handler.service'; +import {LegendService} from "../../services/legend-service/legend-service.service"; @Component({ @@ -32,8 +33,6 @@ export class NetworkComponent implements OnInit { @Input() public networkType: NetworkType; @Input() public nodeData: NodeData; - @Input() public legendContext: LegendContext; - @ViewChild('network', {static: false}) networkEl: ElementRef; @ViewChild('networkWithLegend', {static: false}) networkWithLegendEl: ElementRef; @@ -82,7 +81,7 @@ export class NetworkComponent implements OnInit { public nodeRenderer = null; - constructor(public networkHandler: NetworkHandlerService, public analysis: AnalysisService, public drugstoneConfig: DrugstoneConfigService, public netex: NetexControllerService, public omnipath: OmnipathControllerService) { + constructor(public legendService: LegendService, public networkHandler: NetworkHandlerService, public analysis: AnalysisService, public drugstoneConfig: DrugstoneConfigService, public netex: NetexControllerService, public omnipath: OmnipathControllerService) { } ngOnInit(): void { @@ -116,7 +115,7 @@ export class NetworkComponent implements OnInit { public updateAdjacentProteinDisorders(bool: boolean) { this.adjacentDisordersProtein = bool; if (this.adjacentDisordersProtein) { - + 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 = {} @@ -146,13 +145,14 @@ export class NetworkComponent implements OnInit { this.nodeData.edges.add(this.adjacentProteinDisorderEdgesList); this.updateQueryItems(); }); - this.legendContext = this.adjacentDrugs ? 'adjacentDrugsAndDisorders' : 'adjacentDisorders'; } else { + if (!this.adjacentDisordersDrug) { + this.legendService.remove_from_context('adjacentDisorders'); + } this.saveRemoveDisorders(this.adjacentProteinDisorderList); this.nodeData.edges.remove(this.adjacentProteinDisorderEdgesList); this.adjacentProteinDisorderList = []; this.adjacentProteinDisorderEdgesList = []; - this.legendContext = this.adjacentDisordersDrug ? this.legendContext : this.adjacentDrugs ? 'adjacentDrugs' : 'explorer'; this.updateQueryItems(); } } @@ -160,6 +160,7 @@ export class NetworkComponent implements OnInit { public updateAdjacentDrugDisorders(bool: boolean) { this.adjacentDisordersDrug = bool; if (this.adjacentDisordersDrug) { + 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}; @@ -174,13 +175,13 @@ export class NetworkComponent implements OnInit { this.nodeData.edges.add(this.adjacentDrugDisorderEdgesList); this.updateQueryItems(); }); - this.legendContext = this.adjacentDrugs ? 'adjacentDrugsAndDisorders' : 'adjacentDisorders'; } else { + if (!this.adjacentDisordersProtein) + this.legendService.remove_from_context('adjacentDisorders'); this.saveRemoveDisorders(this.adjacentDrugDisorderList); this.nodeData.edges.remove(this.adjacentDrugDisorderEdgesList); this.adjacentDrugDisorderList = []; this.adjacentDrugDisorderEdgesList = []; - this.legendContext = this.adjacentDisordersProtein ? this.legendContext : this.adjacentDrugs ? 'adjacentDrugs' : 'explorer'; this.updateQueryItems(); } } @@ -212,6 +213,7 @@ export class NetworkComponent implements OnInit { public updateAdjacentDrugs(bool: boolean) { this.adjacentDrugs = bool; if (this.adjacentDrugs) { + 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 => { @@ -245,18 +247,19 @@ export class NetworkComponent implements OnInit { this.nodeData.edges.add(this.adjacentDrugEdgesList); this.updateQueryItems(); }) - this.legendContext = this.adjacentDisordersDrug || this.adjacentDisordersProtein ? 'adjacentDrugsAndDisorders' : 'adjacentDrugs'; } else { // remove adjacent drugs, make sure that also drug associated disorders are removed if (this.adjacentDisordersDrug) { this.updateAdjacentDrugDisorders(false); } + 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.legendContext = this.adjacentDisordersDrug || this.adjacentDisordersProtein ? 'adjacentDisorders' : 'explorer'; this.updateQueryItems(); } } @@ -436,29 +439,13 @@ 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 (this.nodeData && this.nodeData.nodes) + for (const node of this.nodeData.nodes.get()) + if (node.drugstoneType && node.drugstoneId === 'drug') return true; return false; } - public setLegendContext() { - if (this.hasDrugsLoaded() || this.adjacentDrugs) { - if (this.highlightSeeds) { - this.legendContext = "drugAndSeeds"; - } else { - this.legendContext = "drug"; - } - } else { - if (this.highlightSeeds) { - this.legendContext = "drugTargetAndSeeds"; - } else { - this.legendContext = 'drugTarget'; - } - } - } - public getGradient(nodeId: string) { return (this.gradientMap !== {}) && (this.gradientMap[nodeId]) ? this.gradientMap[nodeId] : 1.0; } @@ -470,6 +457,10 @@ export class NetworkComponent implements OnInit { public updateHighlightSeeds(bool: boolean) { this.highlightSeeds = bool; const updatedNodes = []; + if (this.highlightSeeds) + this.legendService.add_to_context('seeds') + else + this.legendService.remove_from_context('seeds') for (const item of this.currentViewProteins) { if (item.drugstoneId === undefined) { // nodes that are not mapped to backend remain untouched @@ -497,7 +488,8 @@ export class NetworkComponent implements OnInit { updatedNodes.push(node); } this.nodeData.nodes.update(updatedNodes); - this.setLegendContext(); + + } public toggleFullscreen() { diff --git a/src/app/interfaces.ts b/src/app/interfaces.ts index a46d4eeaec99113d5dfd0bb524263de8f55aa8e1..820c9d7545d5cc0e8df8b3aea35dc610c17e13c4 100644 --- a/src/app/interfaces.ts +++ b/src/app/interfaces.ts @@ -48,7 +48,7 @@ export type NodeType= 'protein' | 'drug' | 'disorder' | 'other' export type NetworkType = 'explorer' | 'analysis' export type LegendContext = 'explorer' | 'adjacentDrugs' | 'drug' | 'drugTarget' | - 'drugTargetAndSeeds' | 'drugAndSeeds' | 'adjacentDisorders' | 'adjacentDrugsAndDisorders'; + 'seeds' | 'adjacentDisorders'; /// drugstoneId to expressionlvl export type NodeAttributeMap = { string: number } | {}; diff --git a/src/app/pages/explorer-page/explorer-page.component.html b/src/app/pages/explorer-page/explorer-page.component.html index 7f918b1393ca88383c80cc7110e41213eaef8149..6bb0712985cdf29252f1cc32c6d900274c9bb102 100644 --- a/src/app/pages/explorer-page/explorer-page.component.html +++ b/src/app/pages/explorer-page/explorer-page.component.html @@ -513,7 +513,6 @@ <app-network networkType="explorer" [nodeData]="nodeData" - legendContext="explorer" ></app-network> </div> <!-- End network block --> diff --git a/src/app/services/legend-service/legend-service.service.spec.ts b/src/app/services/legend-service/legend-service.service.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..ba525b1a9d45cfbf1322e8754f0f5b413fdd2406 --- /dev/null +++ b/src/app/services/legend-service/legend-service.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { LegendService } from './legend-service.service'; + +describe('LegendService', () => { + let service: LegendService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(LegendService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/legend-service/legend-service.service.ts b/src/app/services/legend-service/legend-service.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..6c4827036b09b8e55093d543151700911e46715f --- /dev/null +++ b/src/app/services/legend-service/legend-service.service.ts @@ -0,0 +1,55 @@ +import {Injectable} from '@angular/core'; +import {LegendContext} from "../../interfaces"; + +@Injectable({ + providedIn: 'root' +}) +export class LegendService { + + constructor() { + } + + private default_delete = ['foundNode', 'foundDrug', 'seedNode', 'default', 'defaultDisorder', 'connectorNode']; + private context = []; + + private contextNodeGroupsToDelete = { + adjacentDrugs: ['foundNode', 'seedNode', 'default', 'defaultDisorder', 'connectorNode'], + adjacentDisorders: ['foundDrug', 'foundNode', 'seedNode', 'default', 'connectorNode'], + drugTarget: ['foundDrug', 'seedNode', 'default', 'defaultDisorder'], + drug: ['foundNode', 'seedNode', 'default', 'defaultDisorder'], + seeds: ['default', 'foundNode', 'foundDrug', 'defaultDisorder'] + }; + + public add_to_context(value: LegendContext) { + if (this.context.indexOf(value) === -1) { + this.context.push(value); + } + } + + public remove_from_context(value: LegendContext) { + const idx = this.context.indexOf(value); + if (idx > -1) { + this.context.splice(idx, 1); + } + } + + public get_nodes_to_delete() { + const out = [].concat(this.default_delete); + for (const node of this.default_delete) { + let keep = false; + for (const c of this.context) { + if (this.contextNodeGroupsToDelete[c].indexOf(node) === -1) { + keep = true; + break; + } + } + if (keep) { + out.splice(out.indexOf(node), 1); + } + } + return out; + } + + + +} diff --git a/src/app/services/network-handler/network-handler.service.ts b/src/app/services/network-handler/network-handler.service.ts index d6515d496656f9033e7f14762c1edc62089cb030..db2496cd09c36fc4802588ddb57edc8158ac2b4b 100644 --- a/src/app/services/network-handler/network-handler.service.ts +++ b/src/app/services/network-handler/network-handler.service.ts @@ -1,23 +1,25 @@ -import { Type, Injectable } from '@angular/core'; -import { Subject } from 'rxjs'; -import { NetworkComponent } from 'src/app/components/network/network.component'; -import { NetworkType } from 'src/app/interfaces'; -import { AnalysisService } from '../analysis/analysis.service'; -import { DrugstoneConfigService } from '../drugstone-config/drugstone-config.service'; -import { NetexControllerService } from '../netex-controller/netex-controller.service'; -import { OmnipathControllerService } from '../omnipath-controller/omnipath-controller.service'; +import {Type, Injectable} from '@angular/core'; +import {Subject} from 'rxjs'; +import {NetworkComponent} from 'src/app/components/network/network.component'; +import {NetworkType} from 'src/app/interfaces'; +import {AnalysisService} from '../analysis/analysis.service'; +import {DrugstoneConfigService} from '../drugstone-config/drugstone-config.service'; +import {NetexControllerService} from '../netex-controller/netex-controller.service'; +import {OmnipathControllerService} from '../omnipath-controller/omnipath-controller.service'; +import {LegendService} from "../legend-service/legend-service.service"; @Injectable({ providedIn: 'root' }) export class NetworkHandlerService { - constructor(public networkHandler: NetworkHandlerService, public analysis: AnalysisService, public drugstoneConfig: DrugstoneConfigService, public netex: NetexControllerService, public omnipath: OmnipathControllerService) { } + constructor(public legendService: LegendService, public networkHandler: NetworkHandlerService, public analysis: AnalysisService, public drugstoneConfig: DrugstoneConfigService, public netex: NetexControllerService, public omnipath: OmnipathControllerService) { + } private change = new Subject<any>(); - public networks: {NetworkType: NetworkComponent} | {} = {}; - public activeNetwork: NetworkComponent = new NetworkComponent(this.networkHandler, this.analysis, this.drugstoneConfig, this.netex, this.omnipath); + public networks: { NetworkType: NetworkComponent } | {} = {}; + public activeNetwork: NetworkComponent = new NetworkComponent(this.legendService, this.networkHandler, this.analysis, this.drugstoneConfig, this.netex, this.omnipath); public setActiveNetwork(network: NetworkType) { this.triggerChange(); @@ -28,7 +30,7 @@ export class NetworkHandlerService { this.change.next(true); } - get getChange$ () { + get getChange$() { return this.change.asObservable(); } }