diff --git a/app-test/icons.html b/app-test/icons.html index 73b7daac6b35f44646816cfd9597dfe5d9cd4185..77bf7dd16813f244d79f47e9c2629f63ba075c74 100644 --- a/app-test/icons.html +++ b/app-test/icons.html @@ -22,7 +22,7 @@ <input type="checkbox" onclick=changeConfigStr('{"showAdvAnalysis":'+this.checked+'}') checked /> Show Advanced Analysis<br> <input type="checkbox" onclick=changeConfigStr('{"showTasks":'+this.checked+'}') checked /> Show Tasks<br> <input type="checkbox" onclick=changeConfigStr('{"showSelection":'+this.checked+'}') checked /> Show Selection<br> -<input type="checkbox" onclick=changeConfigStr('{"showFooter":'+this.checked+'}') checked /> Show Footer<br> +<input type="checkbox" onclick=changeConfigStr('{"showNetworkMenu":'+this.checked+'}') checked /> Show Footer<br> <input type="checkbox" onclick=changeConfigStr('{"showLegend":'+this.checked+'}') checked /> Show Legend<br> <!--<input type="checkbox" onclick=changeConfigStr('{"showSimpleAnalysis":'+this.checked+'}') checked /> Show SimpleAnalysis<br>--> diff --git a/app-test/legend_image.html b/app-test/legend_image.html index 7f95ad45e4cb9f67680f7a7595b5c0318af633a3..609a0e7e143e0547742162a09b2ad56639929b55 100644 --- a/app-test/legend_image.html +++ b/app-test/legend_image.html @@ -22,7 +22,7 @@ <input type="checkbox" onclick=changeConfigStr('{"showAdvAnalysis":'+this.checked+'}') checked /> Show Advanced Analysis<br> <input type="checkbox" onclick=changeConfigStr('{"showTasks":'+this.checked+'}') checked /> Show Tasks<br> <input type="checkbox" onclick=changeConfigStr('{"showSelection":'+this.checked+'}') checked /> Show Selection<br> -<input type="checkbox" onclick=changeConfigStr('{"showFooter":'+this.checked+'}') checked /> Show Footer<br> +<input type="checkbox" onclick=changeConfigStr('{"showNetworkMenu":'+this.checked+'}') checked /> Show Footer<br> <input type="checkbox" onclick=changeConfigStr('{"showLegend":'+this.checked+'}') checked /> Show Legend<br> <button onclick=changeConfigStr('{"legendPos":"left"}') > Legend to Left </button> <br> <button onclick=changeConfigStr('{"legendPos":"right"}') > Legend to Right </button> <br> diff --git a/app-test/show_and_hide_elements.html b/app-test/show_and_hide_elements.html index 6a14c3467c9dd7aaabfbe077030403e67769aa3c..281242ae2d038be9e930d6c3bda4b861eaa793eb 100644 --- a/app-test/show_and_hide_elements.html +++ b/app-test/show_and_hide_elements.html @@ -22,7 +22,7 @@ <input type="checkbox" onclick=changeConfigStr('{"showAdvAnalysis":'+this.checked+'}') checked /> Show Advanced Analysis<br> <input type="checkbox" onclick=changeConfigStr('{"showTasks":'+this.checked+'}') checked /> Show Tasks<br> <input type="checkbox" onclick=changeConfigStr('{"showSelection":'+this.checked+'}') checked /> Show Selection<br> -<input type="checkbox" onclick=changeConfigStr('{"showFooter":'+this.checked+'}') checked /> Show Footer<br> +<input type="checkbox" onclick=changeConfigStr('{"showNetworkMenu":'+this.checked+'}') checked /> Show Footer<br> <input type="checkbox" onclick=changeConfigStr('{"showLegend":'+this.checked+'}') checked /> Show Legend<br> <!--<input type="checkbox" onclick=changeConfigStr('{"showSimpleAnalysis":'+this.checked+'}') checked /> Show SimpleAnalysis<br>--> diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 6e159a3b9f95fb062407667c7d099ff971acf066..e399996d8f83295b254effe9fd85be7ad235d9a8 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,40 +1,43 @@ -import {Injector, NgModule} from '@angular/core'; -import {BrowserModule} from '@angular/platform-browser'; -import {NgSelectModule} from '@ng-select/ng-select'; -import {CommonModule} from '@angular/common'; -import {FormsModule} from '@angular/forms'; -import {HttpClientModule} from '@angular/common/http'; -import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; -import {TableModule} from 'primeng/table'; +import { Injector, NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { HttpClientModule } from '@angular/common/http'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { TableModule } from 'primeng/table'; -import {ExplorerPageComponent} from './pages/explorer-page/explorer-page.component'; -import {QueryTileComponent} from './components/query-tile/query-tile.component'; -import {LaunchAnalysisComponent} from './dialogs/launch-analysis/launch-analysis.component'; -import {DatasetTileComponent} from './components/dataset-tile/dataset-tile.component'; -import {AnalysisPanelComponent} from './components/analysis-panel/analysis-panel.component'; -import {TaskListComponent} from './components/task-list/task-list.component'; -import {ToggleComponent} from './components/toggle/toggle.component'; -import {InfoTileComponent} from './components/info-tile/info-tile.component'; -import {CustomProteinsComponent} from './dialogs/custom-proteins/custom-proteins.component'; +import { ExplorerPageComponent } from './pages/explorer-page/explorer-page.component'; +import { QueryTileComponent } from './components/query-tile/query-tile.component'; +import { LaunchAnalysisComponent } from './dialogs/launch-analysis/launch-analysis.component'; +import { DatasetTileComponent } from './components/dataset-tile/dataset-tile.component'; +import { AnalysisPanelComponent } from './components/analysis-panel/analysis-panel.component'; +import { TaskListComponent } from './components/task-list/task-list.component'; +import { ToggleComponent } from './components/toggle/toggle.component'; +import { InfoTileComponent } from './components/info-tile/info-tile.component'; +import { CustomProteinsComponent } from './dialogs/custom-proteins/custom-proteins.component'; import { DownloadButtonComponent } from './components/download-button/download-button.component'; -import {MatTooltipModule} from '@angular/material/tooltip'; +import { MatTooltipModule } from '@angular/material/tooltip'; -import {AnalysisService} from './services/analysis/analysis.service'; -import {AddExpressedProteinsComponent} from './dialogs/add-expressed-proteins/add-expressed-proteins.component'; -import {createCustomElement} from '@angular/elements'; -import {NetworkLegendComponent} from './components/network-legend/network-legend.component'; -import {ProtTableComponent} from './components/analysis-panel/prot-table/prot-table.component'; -import {DrugTableComponent} from './components/analysis-panel/drug-table/drug-table.component'; +import { AnalysisService } from './services/analysis/analysis.service'; +import { AddExpressedProteinsComponent } from './dialogs/add-expressed-proteins/add-expressed-proteins.component'; +import { createCustomElement } from '@angular/elements'; +import { NetworkLegendComponent } from './components/network-legend/network-legend.component'; +import { ProtTableComponent } from './components/analysis-panel/prot-table/prot-table.component'; +import { DrugTableComponent } from './components/analysis-panel/drug-table/drug-table.component'; -import {FontAwesomeModule} from '@fortawesome/angular-fontawesome'; +import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import fontawesome from '@fortawesome/fontawesome'; -import {faTimes, faAngleUp, faAngleLeft, faCapsules, faCrosshairs, faFlask, faCheck, faCamera, faDownload, +import { + faTimes, faAngleUp, faAngleLeft, faCapsules, faCrosshairs, faFlask, faCheck, faCamera, faDownload, faRulerVertical, faDna, faMicroscope, faBook, faPause, faTrash, faSpinner, faExclamationTriangle, faPlus, faExpand, faInfo, faRocket, faAngleDown, faSearch, faFastForward, faExternalLinkAlt, faTasks, faFilter, - faMinus, faUpload, faAngleDoubleDown, faSync, faBroom, faAngleDoubleUp + faMinus, faUpload, faAngleDoubleDown, faSync, faBroom, faAngleDoubleUp, faChild, faHeadSideMask, faBiohazard, + faBullseye } from '@fortawesome/free-solid-svg-icons'; -import {TooltipModule} from 'primeng/tooltip'; +import { TooltipModule } from 'primeng/tooltip'; +import { NetworkMenuComponent } from './components/network-menu/network-menu.component'; @NgModule({ declarations: [ @@ -52,6 +55,7 @@ import {TooltipModule} from 'primeng/tooltip'; ProtTableComponent, DrugTableComponent, DownloadButtonComponent, + NetworkMenuComponent, ], imports: [ BrowserModule, @@ -76,8 +80,8 @@ export class AppModule { faCheck, faCamera, faDownload, faRulerVertical, faDna, faMicroscope, faBook, faPause, faTrash, faSpinner, faExclamationTriangle, faPlus, faExpand, faInfo, faRocket, faAngleDown, faSearch, faFastForward, faExternalLinkAlt, faTasks, faFilter, faMinus, faUpload, faAngleDoubleDown, - faSync, faBroom, faAngleDoubleUp); - const NetworkExpander = createCustomElement(ExplorerPageComponent, {injector}); + faSync, faBroom, faAngleDoubleUp, faChild, faHeadSideMask, faBiohazard, faBullseye); + const NetworkExpander = createCustomElement(ExplorerPageComponent, { injector }); // Register the custom element with the browser. customElements.define('drugst-one', NetworkExpander); } diff --git a/src/app/components/analysis-panel/analysis-panel.component.html b/src/app/components/analysis-panel/analysis-panel.component.html index 0b1ee9553462ef3faad1bb6f48560baa425eff29..e8c7cafc04b2f75f1f7f06f9a6ce276f511868b3 100644 --- a/src/app/components/analysis-panel/analysis-panel.component.html +++ b/src/app/components/analysis-panel/analysis-panel.component.html @@ -136,7 +136,7 @@ <div class="tab-content" *ngIf="task && task.info.done" [class.is-visible]="tab === 'network'"> <div class="card-image canvas-content" #networkWithLegend> <div *ngIf="myConfig.showLegend"> - <app-network-legend [config]="myConfig" [context]="legendContext" [smallStyle]="smallStyle"></app-network-legend> + <app-network-legend [config]="myConfig" [context]="legendContext"></app-network-legend> </div> <div class="parent fullheight"> <div class="center image1 fullheight" #network> @@ -145,28 +145,28 @@ </div> </div> - <footer *ngIf="myConfig.showFooter" class="card-footer toolbar network-footer-toolbar"> + <footer *ngIf="myConfig.showNetworkMenu" class="card-footer toolbar network-footer-toolbar"> <div class="network-footer-toolbar-inner-container"> - <div *ngIf="myConfig.showFooterButtonScreenshot" class="network-footer-toolbar-element footer-buttons"> + <div *ngIf="myConfig.showNetworkMenuButtonScreenshot" class="network-footer-toolbar-element"> <button class="button is-primary is-rounded has-tooltip" pTooltip="Take a screenshot of the current network." [tooltipStyleClass]="'drgstn drgstn-tooltip'" tooltipPosition="top" - [ngClass]="{ 'button-small': smallStyle }" + [ngClass]="{ 'button-small': drugstoneConfig.smallStyle }" (click)="toImage()"> <span class="icon"> <i class="fas fa-camera" aria-hidden="true"></i> </span> - <span [ngClass]="{'text-normal':smallStyle}"> + <span [ngClass]="{'text-normal':drugstoneConfig.smallStyle}"> Screenshot </span> </button> </div> - <ng-container *ngIf="myConfig.showFooterButtonExportGraphml"> - <app-download-button [nodeData]=nodeData [smallStyle]="smallStyle" [buttonId]="'analysis-download'"></app-download-button> + <ng-container *ngIf="myConfig.showNetworkMenuButtonExportGraphml"> + <app-download-button [nodeData]=nodeData [buttonId]="'analysis-download'"></app-download-button> </ng-container> <!-- <div class="field">--> @@ -183,15 +183,15 @@ <!-- </p>--> <!-- </div>--> - <div class="footer-buttons dropdown is-up network-footer-toolbar-element" + <div class="dropdown is-up network-footer-toolbar-element" [class.is-active]="expressionExpanded"> <div class="dropdown-trigger"> <button (click)="expressionExpanded=!expressionExpanded" class="button is-rounded is-primary" [class.is-outlined]="!selectedTissue" - aria-haspopup="true" aria-controls="dropdown-menu" [ngClass]="{'button-small':smallStyle}" + aria-haspopup="true" aria-controls="dropdown-menu" [ngClass]="{'button-small':drugstoneConfig.smallStyle}" pTooltip="Tissue expression data is provided by the GTEx project." [tooltipStyleClass]="'drgstn drgstn-tooltip'" tooltipPosition="top" > - <div [ngClass]="{'text-small':smallStyle}"> + <div [ngClass]="{'text-small':drugstoneConfig.smallStyle}"> <span *ngIf="!selectedTissue">Tissue</span> <span *ngIf="selectedTissue">{{selectedTissue.name}}</span> <span class="icon is-small"> @@ -203,8 +203,8 @@ </button> </div> <div class="dropdown-menu" id="dropdown-menu" role="menu"> - <div class="dropdown-content tissue-dropdown" [ngClass]="{'button-small':smallStyle}"> - <div class="scroll-area" [ngClass]="{'text-small':smallStyle}"> + <div class="dropdown-content tissue-dropdown" [ngClass]="{'button-small':drugstoneConfig.smallStyle}"> + <div class="scroll-area" [ngClass]="{'text-small':drugstoneConfig.smallStyle}"> <a (click)="selectTissue(null)" [class.is-active]="!selectedTissue" class="dropdown-item"> @@ -221,45 +221,40 @@ </div> </div> - <app-toggle class="footer-buttons network-footer-toolbar-element" textOn="Seeds On" textOff="Off" + <app-toggle class="network-footer-toolbar-element" textOn="Seeds On" textOff="Off" tooltipOn="Highlight seed nodes ON." tooltipOff="Highlight seed nodes OFF." - [smallStyle]="smallStyle" [value]="highlightSeeds" (valueChange)="updateHighlightSeeds($event)"></app-toggle> - <app-toggle *ngIf="task.info.target === 'drug-target'" class="footer-buttons network-footer-toolbar-element" + <app-toggle *ngIf="task.info.target === 'drug-target'" class="network-footer-toolbar-element" textOn="Drugs" textOff="Off" tooltipOn="Display adjacent drugs ON." tooltipOff="Display adjacent drugs OFF." - [smallStyle]="smallStyle" [value]="adjacentDrugs" (valueChange)="updateAdjacentDrugs($event)"></app-toggle> <app-toggle - class="footer-buttons network-footer-toolbar-element" + class="network-footer-toolbar-element" textOn="Disorders (protein)" textOff="Off" tooltipOn="Show disorders adjacent to all currently displayed proteins/genes ON." tooltipOff="Show disorders adjacent to all currently displayed proteins/genes OFF." - [smallStyle]="smallStyle" [value]="adjacentDisordersProtein" (valueChange)="updateAdjacentProteinDisorders($event)" ></app-toggle> <app-toggle - class="footer-buttons network-footer-toolbar-element" + class="network-footer-toolbar-element" textOn="Disorders (drugs)" textOff="Off" tooltipOn="Show disorders adjacent to all currently displayed drugs ON." tooltipOff="Show disorders adjacent to all currently displayed drugs OFF." - [smallStyle]="smallStyle" [value]="adjacentDisordersDrug" [disabled]="!hasDrugsLoaded()" (valueChange)="updateAdjacentDrugDisorders($event)" ></app-toggle> - <app-toggle class="footer-buttons network-footer-toolbar-element" textOn="Animation" textOff="Off" + <app-toggle class="network-footer-toolbar-element" textOn="Animation" textOff="Off" tooltipOn="Enable the network animation." tooltipOff="Disable the network animation and freeze nodes." - [smallStyle]="smallStyle" - [value]="physicsEnabled" (valueChange)="updatePhysicsEnabled($event)"></app-toggle> + [value]="drugstoneConfig.config.physicsOn" (valueChange)="updatePhysicsEnabled($event)"></app-toggle> </div> </footer> </div> @@ -268,7 +263,7 @@ <div class="field has-addons is-pulled-right m-1" *ngIf="tableHasScores && task.info.algorithm !== 'proximity'"> <p class="control"> <button class="button is-rounded has-tooltip" pTooltip="Normalize the scores" [tooltipStyleClass]="'drgstn drgstn-tooltip'" tooltipPosition="top" - [class.is-primary]="tableNormalize" (click)="toggleNormalization(true)" [ngClass]="{ 'button-small': smallStyle }"> + [class.is-primary]="tableNormalize" (click)="toggleNormalization(true)" [ngClass]="{ 'button-small': drugstoneConfig.smallStyle }"> <span class="icon is-small"> <i class="fa fa-ruler-vertical"></i> </span> @@ -278,7 +273,7 @@ <p class="control"> <button class="button is-rounded has-tooltip" pTooltip="Disable normalization of the scores." [tooltipStyleClass]="'drgstn drgstn-tooltip'" tooltipPosition="top" - [class.is-primary]="!tableNormalize" (click)="toggleNormalization(false)" [ngClass]="{ 'button-small': smallStyle }"> + [class.is-primary]="!tableNormalize" (click)="toggleNormalization(false)" [ngClass]="{ 'button-small': drugstoneConfig.smallStyle }"> <span>Off</span> </button> </p> diff --git a/src/app/components/analysis-panel/analysis-panel.component.ts b/src/app/components/analysis-panel/analysis-panel.component.ts index eb999fc76321ce3b47b02b8928eb942a5ccf8ab3..d493875933eb8a183f8f0b92cc01779fe8473f1d 100644 --- a/src/app/components/analysis-panel/analysis-panel.component.ts +++ b/src/app/components/analysis-panel/analysis-panel.component.ts @@ -32,6 +32,7 @@ import {NetexControllerService} from 'src/app/services/netex-controller/netex-co import {defaultConfig, IConfig} from 'src/app/config'; 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'; declare var vis: any; @@ -60,7 +61,6 @@ export class AnalysisPanelComponent implements OnInit, OnChanges { @ViewChild('network', {static: false}) networkEl: ElementRef; @ViewChild('networkWithLegend', {static: false}) networkWithLegendEl: ElementRef; @Input() token: string | null = null; - @Input() public smallStyle = false; @Input() public set config(config: IConfig | undefined) { if (typeof config === 'undefined') { @@ -84,7 +84,6 @@ export class AnalysisPanelComponent implements OnInit, OnChanges { private drugEdges: any[] = []; public showDrugs = false; public tab: 'meta' | 'network' | 'table' = 'table'; - public physicsEnabled = true; public adjacentDrugs = false; public adjacentDrugList: Node[] = []; @@ -126,7 +125,7 @@ export class AnalysisPanelComponent implements OnInit, OnChanges { public expressionMap: NodeAttributeMap; public gradientMap: NodeAttributeMap = {}; - constructor(private http: HttpClient, public analysis: AnalysisService, public netex: NetexControllerService) { + constructor(public drugstoneConfig: DrugstoneConfigService, private http: HttpClient, public analysis: AnalysisService, public netex: NetexControllerService) { } async ngOnInit() { @@ -191,7 +190,7 @@ export class AnalysisPanelComponent implements OnInit, OnChanges { const container = this.networkEl.nativeElement; const isBig = nodes.length > 100 || edges.length > 100; const options = NetworkSettings.getOptions(isBig ? 'analysis-big' : 'analysis', this.myConfig.physicsOn); - this.physicsEnabled = !isBig; + this.drugstoneConfig.config.physicsOn = !isBig; this.network = new vis.Network(container, this.nodeData, options); @@ -670,10 +669,10 @@ export class AnalysisPanelComponent implements OnInit, OnChanges { } public updatePhysicsEnabled(bool: boolean) { - this.physicsEnabled = bool; + this.drugstoneConfig.config.physicsOn = bool; this.network.setOptions({ physics: { - enabled: this.physicsEnabled, + enabled: this.drugstoneConfig.config.physicsOn, stabilization: { enabled: false, }, diff --git a/src/app/components/download-button/download-button.component.html b/src/app/components/download-button/download-button.component.html index f05748259c3ed35769f01aecba09653b627d4c9a..ea3069f9805894a108134c575038120d9f81daf1 100644 --- a/src/app/components/download-button/download-button.component.html +++ b/src/app/components/download-button/download-button.component.html @@ -1,4 +1,4 @@ -<div class="footer-buttons network-footer-toolbar-element"> +<div class="network-footer-toolbar-element"> <div class="dropdown is-hoverable is-up"> <div class="dropdown-trigger"> <button @@ -6,12 +6,11 @@ class="button is-primary is-rounded has-tooltip" aria-haspopup="true" attr.aria-controls="{{ 'controls-' + buttonId }}" - [ngClass]="{ 'button-small': smallStyle }" > <span class="icon"> <i class="fas fa-download" aria-hidden="true"></i> </span> - <span [ngClass]="{ 'text-normal': smallStyle }">Download</span> + <span [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }">Download</span> </button> </div> <div class="dropdown-menu" id="{{ 'controls-' + buttonId }}" role="menu"> @@ -19,21 +18,21 @@ <a (click)="downloadLink('graphml')" class="dropdown-item" - [ngClass]="{ 'text-normal': smallStyle }" + [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }" >.graphml</a > <!-- <hr class="dropdown-divider" /> --> <a (click)="downloadLink('json')" class="dropdown-item" - [ngClass]="{ 'text-normal': smallStyle }" + [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }" >.json</a > <!-- <hr class="dropdown-divider" /> --> <a (click)="downloadLink('csv')" class="dropdown-item" - [ngClass]="{ 'text-normal': smallStyle }" + [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }" >.csv</a > </div> diff --git a/src/app/components/download-button/download-button.component.ts b/src/app/components/download-button/download-button.component.ts index 596f7558a16e2220af9d2ba4bdbad3632e0b8c5d..e398be82fe4fb481f52ebfcce88c942f08aef6dc 100644 --- a/src/app/components/download-button/download-button.component.ts +++ b/src/app/components/download-button/download-button.component.ts @@ -1,4 +1,5 @@ import { Component, Input, OnInit } from '@angular/core'; +import { DrugstoneConfigService } from 'src/app/services/drugstone-config/drugstone-config.service'; import { NetexControllerService } from 'src/app/services/netex-controller/netex-controller.service'; import { downLoadFile } from 'src/app/utils'; @@ -10,10 +11,9 @@ import { downLoadFile } from 'src/app/utils'; export class DownloadButtonComponent implements OnInit { @Input() nodeData: { nodes: any, edges: any } = {nodes: null, edges: null}; - @Input() smallStyle: boolean; @Input() buttonId: string; - constructor(public netex: NetexControllerService) { } + constructor(public drugstoneConfig: DrugstoneConfigService, public netex: NetexControllerService) { } ngOnInit(): void { } diff --git a/src/app/components/info-tile/info-tile.component.html b/src/app/components/info-tile/info-tile.component.html index f14270810cd4c34404645aaac2e096c7d7a32854..037a9e01c04676dcf2fac418e2678c658a2bd046 100644 --- a/src/app/components/info-tile/info-tile.component.html +++ b/src/app/components/info-tile/info-tile.component.html @@ -6,30 +6,30 @@ wrapper.data.detailShowLabel && wrapper.data.label " - [ngClass]="{ 'text-normal': smallStyle }" + [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }" > <b><span>Label:</span></b> <span class="is-capitalized"> {{ wrapper.data.label }}</span> </p> <p *ngIf="wrapper.data.proteinName" - [ngClass]="{ 'text-normal': smallStyle }" + [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }" > <b><span>Name:</span></b> <span class="is-capitalized"> {{ wrapper.data.proteinName }}</span> </p> - <p *ngIf="wrapper.data.symbol" [ngClass]="{ 'text-normal': smallStyle }"> + <p *ngIf="wrapper.data.symbol" [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }"> <b><span>Symbol:</span></b> <span class="is-capitalized"> {{ wrapper.data.symbol }}</span> </p> <p *ngIf="wrapper.data.drugId || wrapper.data.disorderId" - [ngClass]="{ 'text-normal': smallStyle }" + [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }" > <b><span>Name:</span></b> <span class="is-capitalized"> {{ wrapper.data.label }}</span> </p> - <p *ngIf="wrapper.data.icd10" [ngClass]="{ 'text-normal': smallStyle }"> + <p *ngIf="wrapper.data.icd10" [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }"> <b><span>ICD10:</span></b> <span class="is-capitalized"> {{ @@ -41,7 +41,7 @@ }}</span > </p> - <p *ngIf="wrapper.data.drugId" [ngClass]="{ 'text-normal': smallStyle }"> + <p *ngIf="wrapper.data.drugId" [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }"> <b><span>DrugBank:</span></b> <a href="https://go.drugbank.com/drugs/{{ wrapper.data.drugId }}" @@ -52,7 +52,7 @@ </p> <p *ngIf="wrapper.data.disorderId" - [ngClass]="{ 'text-normal': smallStyle }" + [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }" > <b><span>Mondo:</span></b> <a @@ -64,11 +64,11 @@ <span class="is-capitalized"> MONDO:{{ wrapper.data.disorderId }}</span> </a> </p> - <p *ngIf="wrapper.data.groupName" [ngClass]="{ 'text-normal': smallStyle }"> + <p *ngIf="wrapper.data.groupName" [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }"> <b><span>Group:</span></b> <span class="is-capitalized"> {{ wrapper.data.groupName }}</span> </p> - <p *ngIf="wrapper.data.uniprotAc" [ngClass]="{ 'text-normal': smallStyle }"> + <p *ngIf="wrapper.data.uniprotAc" [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }"> <b><span>Uniprot:</span></b> <a href="https://www.uniprot.org/uniprot/{{ wrapper.data.uniprotAc }}" @@ -77,7 +77,7 @@ <span class="is-capitalized"> {{ wrapper.data.uniprotAc }}</span> </a> </p> - <p *ngIf="wrapper.data.ensg" [ngClass]="{ 'text-normal': smallStyle }"> + <p *ngIf="wrapper.data.ensg" [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }"> <b><span>Ensembl:</span></b> <a *ngFor="let ensg of wrapper.data.ensg" @@ -87,7 +87,7 @@ <span class="is-capitalized"> {{ ensg }}</span> </a> </p> - <p *ngIf="wrapper.expression" [ngClass]="{ 'text-normal': smallStyle }"> + <p *ngIf="wrapper.expression" [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }"> <b><span>Expression:</span></b> <span class="is-capitalized"> {{ wrapper.expression }}</span> <span @@ -103,7 +103,6 @@ <app-toggle *ngIf="wrapper.data.netexId && wrapper.data.netexId.startsWith('p')" [value]="analysis.inSelection(wrapper)" - [smallStyle]="smallStyle" (valueChange)=" $event ? analysis.addItems([wrapper]) : analysis.removeItems([wrapper]) " @@ -113,6 +112,6 @@ tooltipOff="Remove protein from selection." ></app-toggle> </div> -<div *ngIf="!wrapper" [ngClass]="{ 'text-normal': smallStyle }"> +<div *ngIf="!wrapper" [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }"> Please select a node for further information. </div> diff --git a/src/app/components/info-tile/info-tile.component.ts b/src/app/components/info-tile/info-tile.component.ts index 514b0f723ad6fa528dd386bb0ff840aebe37ddc1..a6e99fad252d20de04df5dc1428391ddebfcc8a1 100644 --- a/src/app/components/info-tile/info-tile.component.ts +++ b/src/app/components/info-tile/info-tile.component.ts @@ -1,4 +1,5 @@ import {Component, Input, OnInit} from '@angular/core'; +import { DrugstoneConfigService } from 'src/app/services/drugstone-config/drugstone-config.service'; import {Wrapper} from '../../interfaces'; import {AnalysisService} from '../../services/analysis/analysis.service'; @@ -11,9 +12,8 @@ import {AnalysisService} from '../../services/analysis/analysis.service'; export class InfoTileComponent implements OnInit { @Input() public wrapper: Wrapper; - @Input() smallStyle: boolean; - constructor(public analysis: AnalysisService) { + constructor(public drugstoneConfig: DrugstoneConfigService, public analysis: AnalysisService) { } ngOnInit(): void { diff --git a/src/app/components/network-legend/network-legend.component.html b/src/app/components/network-legend/network-legend.component.html index 313e903d6725a1c8facc565fc0999015bf024337..adde137d9a403e4cb676405d66cec9b0ae732820 100644 --- a/src/app/components/network-legend/network-legend.component.html +++ b/src/app/components/network-legend/network-legend.component.html @@ -1,9 +1,7 @@ -<div class="legend" [class.right]="this.config.legendPos === 'right'" [ngClass]="{ 'legend-small': smallStyle }"> - <div class="legend-background"> - - </div> +<div class="legend" [class.right]="this.config.legendPos === 'right'" [ngClass]="{ 'legend-small': drugstoneConfig.smallStyle }"> + <div class="legend-background"></div> <!-- default legend in html --> <table *ngIf="!this.config.legendUrl.length" class="legend-table"> <ng-container *ngIf="this.config.showLegendNodes"> diff --git a/src/app/components/network-legend/network-legend.component.ts b/src/app/components/network-legend/network-legend.component.ts index a3a02b78bdf0fdc43016915921f065fd14b3d6da..e75ed973daacbfa49d41bba1120310aded82a14c 100644 --- a/src/app/components/network-legend/network-legend.component.ts +++ b/src/app/components/network-legend/network-legend.component.ts @@ -1,5 +1,6 @@ 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'; @Component({ @@ -11,7 +12,6 @@ export class NetworkLegendComponent implements OnInit { @Input() context: legendContext; @Input() config: IConfig; - @Input() smallStyle: boolean; private contextNodeGroupsToDelete = { 'explorer': ['foundNode', 'foundDrug', 'seedNode', 'default', 'defaultDisorder'], @@ -47,7 +47,7 @@ export class NetworkLegendComponent implements OnInit { return !this.contextEdgeGroupsToDelete[this.context].includes(edgeGroupKey); } - constructor() { } + constructor(public drugstoneConfig: DrugstoneConfigService) { } ngOnInit(): void { } diff --git a/src/app/components/task-list/task-list.component.html b/src/app/components/task-list/task-list.component.html index a144771005999160e307d6978773936626724aec..0ab3438624ca93f6b4c4bb7a0aa711b377d2d7a0 100644 --- a/src/app/components/task-list/task-list.component.html +++ b/src/app/components/task-list/task-list.component.html @@ -1,5 +1,5 @@ <div class="content"> - <div class="list is-hoverable" [ngClass]="{ 'text-normal': smallStyle }"> + <div class="list is-hoverable" [ngClass]="{ 'text-normal': drugstoneConfig.smallStyle }"> <a *ngFor="let task of analysis.tasks" class="list-item box small-box" diff --git a/src/app/components/task-list/task-list.component.ts b/src/app/components/task-list/task-list.component.ts index 7d65563c8d4c25513f29d6a432e48a9234121797..2d9b06c0de50eb2fd2908ef642cbac515def195e 100644 --- a/src/app/components/task-list/task-list.component.ts +++ b/src/app/components/task-list/task-list.component.ts @@ -1,4 +1,5 @@ import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; +import { DrugstoneConfigService } from 'src/app/services/drugstone-config/drugstone-config.service'; import {AnalysisService, algorithmNames} from '../../services/analysis/analysis.service'; @@ -12,11 +13,10 @@ export class TaskListComponent implements OnInit { @Input() token: string; @Output() tokenChange: EventEmitter<string> = new EventEmitter(); - @Input() smallStyle: boolean; public algorithmNames = algorithmNames; - constructor(public analysis: AnalysisService) { + constructor(public drugstoneConfig: DrugstoneConfigService, public analysis: AnalysisService) { } ngOnInit(): void { diff --git a/src/app/components/toggle/toggle.component.html b/src/app/components/toggle/toggle.component.html index 1ba8d66e09267b05ce761538a1904e51003aa152..05cc38244c69c2d717b6420ece2cc8b7585cc4dd 100644 --- a/src/app/components/toggle/toggle.component.html +++ b/src/app/components/toggle/toggle.component.html @@ -1,18 +1,61 @@ -<div class="field has-addons"> +<!-- <div class="field has-addons"> <p class="control has-tooltip"> - <button class="button is-rounded has-tooltip" [pTooltip]="tooltipOn" [disabled]="disabled" [tooltipStyleClass]="'drgstn drgstn-tooltip'" tooltipPosition="top" [class.is-primary]="value" (click)="toggle(true)" [ngClass]="{'switch-small':smallStyle}"> + <button + class="button is-rounded has-tooltip" + [pTooltip]="tooltipOn" + [disabled]="disabled" + [tooltipStyleClass]="'drgstn drgstn-tooltip'" + tooltipPosition="top" + [class.is-primary]="value" + (click)="toggle(true)" + [ngClass]="{ 'switch-small': drugstoneConfig.smallStyle }" + > <span class="icon is-small"> - <i class="fa {{iconOn}}"></i> + <i class="fa {{ iconOn }}"></i> </span> - <span [ngClass]="{'text-small':smallStyle}" >{{textOn}}</span> + <span [ngClass]="{ 'text-small': drugstoneConfig.smallStyle }">{{ textOn }}</span> </button> </p> <p class="control"> - <button class="button is-rounded has-tooltip" [pTooltip]="tooltipOff" [disabled]="disabled" [tooltipStyleClass]="'drgstn drgstn-tooltip'" tooltipPosition="top" [class.is-primary]="!value" (click)="toggle(false)" [ngClass]="{'switch-small':smallStyle}"> - <span [ngClass]="{'text-small':smallStyle}">{{textOff}}</span> + <button + class="button is-rounded has-tooltip" + [pTooltip]="tooltipOff" + [disabled]="disabled" + [tooltipStyleClass]="'drgstn drgstn-tooltip'" + tooltipPosition="top" + [class.is-primary]="!value" + (click)="toggle(false)" + [ngClass]="{ 'switch-small': drugstoneConfig.smallStyle }" + > + <span [ngClass]="{ 'text-small': drugstoneConfig.smallStyle }">{{ textOff }}</span> <span *ngIf="iconOff" class="icon is-small"> - <i class="fa {{iconOff}}"></i> + <i class="fa {{ iconOff }}"></i> </span> </button> </p> -</div> +</div> --> + +<button + class="button is-rounded has-tooltip" + [pTooltip]="tooltipOff" + [tooltipStyleClass]="'drgstn drgstn-tooltip'" + tooltipPosition="left" + (click)="toggle()" + [ngClass]="{ + 'is-primary': value, + 'switch-small': drugstoneConfig.smallStyle + }" +> + <span *ngIf="icon" class="icon is-small"> + <i class="{{ icon }}"></i> + </span> + <span [ngClass]="{ 'text-small': drugstoneConfig.smallStyle }">{{ + textOn + }}</span> + <span *ngIf="!value" class="icon is-small"> + <i class="fa {{ iconOff }}"></i> + </span> + <span *ngIf="value" class="icon is-small"> + <i class="fa {{ iconOn }}"></i> + </span> +</button> diff --git a/src/app/components/toggle/toggle.component.ts b/src/app/components/toggle/toggle.component.ts index a0f7617a93ef91c8f101de167343039bd33f9ab2..2c7ada6732b56208c9210127839b55628fe4e395 100644 --- a/src/app/components/toggle/toggle.component.ts +++ b/src/app/components/toggle/toggle.component.ts @@ -1,4 +1,5 @@ import {Component, Directive, EventEmitter, Input, OnInit, Output} from '@angular/core'; +import { DrugstoneConfigService } from 'src/app/services/drugstone-config/drugstone-config.service'; @Component({ selector: 'app-toggle', @@ -15,22 +16,20 @@ export class ToggleComponent implements OnInit { @Input() tooltipOn: string; @Input() tooltipOff: string; @Input() disabled = false; + @Input() icon: string; - @Input() smallStyle: boolean; @Input() value: boolean; @Output() valueChange = new EventEmitter<boolean>(); - constructor() { + constructor(public drugstoneConfig: DrugstoneConfigService) { } ngOnInit(): void { } - public toggle(value: boolean) { - if(this.value === value) - return; - this.value = value; + public toggle( ) { + this.value = !this.value this.valueChange.emit(this.value); } diff --git a/src/app/config.ts b/src/app/config.ts index 2f1de2fff2f33b26d5522e2d6d76553c0be767ef..da336d66e1fd431fb8b15a49020cc3acc1372db5 100644 --- a/src/app/config.ts +++ b/src/app/config.ts @@ -45,10 +45,14 @@ export interface IConfig { showAdvAnalysis: boolean; showTasks: boolean; showSelection: boolean; - showFooter: boolean; - showFooterButtonExpression: boolean; - showFooterButtonScreenshot: boolean; - showFooterButtonExportGraphml: boolean; + showNetworkMenu: boolean; + showNetworkMenuButtonExpression: boolean; + showNetworkMenuButtonScreenshot: boolean; + showNetworkMenuButtonExportGraphml: boolean; + showNetworkMenuButtonAdjacentDrugs: boolean; + showNetworkMenuButtonAdjacentDisordersProteins: boolean; + showNetworkMenuButtonAdjacentDisordersDrugs: boolean; + showNetworkMenuButtonAnimation: boolean; showLegend: boolean; showLegendNodes: boolean; showLegendEdges: boolean; @@ -85,11 +89,15 @@ export const defaultConfig: IConfig = { showAdvAnalysis: true, showSelection: true, showTasks: true, - showFooter: true, + showNetworkMenu: true, showLegend: true, - showFooterButtonExpression: true, - showFooterButtonScreenshot: true, - showFooterButtonExportGraphml: true, + showNetworkMenuButtonExpression: true, + showNetworkMenuButtonScreenshot: true, + showNetworkMenuButtonExportGraphml: true, + showNetworkMenuButtonAdjacentDrugs: true, + showNetworkMenuButtonAdjacentDisordersProteins: true, + showNetworkMenuButtonAdjacentDisordersDrugs: true, + showNetworkMenuButtonAnimation: true, identifier: 'symbol', interactionDrugProtein: 'DrugBank', interactionProteinProtein: 'STRING', diff --git a/src/app/pages/explorer-page/explorer-page.component.html b/src/app/pages/explorer-page/explorer-page.component.html index 8ea2c78e6fd3ddf922bcc76a06873ef68ff42cfb..9bf8a9e664ccc085d245fd478c1dfb258e7c7ad7 100644 --- a/src/app/pages/explorer-page/explorer-page.component.html +++ b/src/app/pages/explorer-page/explorer-page.component.html @@ -3,7 +3,7 @@ <app-launch-analysis [(show)]="showAnalysisDialog" [target]="analysisDialogTarget" - [config]="myConfig" + [config]="drugstoneConfig.config" [inputNetwork]="{ nodes: proteins, edges: edges }" (taskEvent)="emitTaskEvent($event)" > @@ -25,15 +25,22 @@ </app-add-expressed-proteins> <!-- Start explorer --> - <div class="drugstone explorer columns is-gapless" [ngClass]="{ 'is-flex-direction-row-reverse': myConfig.sidebarPos === 'right' }"> + <div + class="drugstone explorer columns is-gapless" + [ngClass]="{ + 'is-flex-direction-row-reverse': + drugstoneConfig.config.sidebarPos === 'right' + }" + > <!-- Start left sidebar --> - <div - class="drugstone sidebar column" - > - <div *ngIf="myConfig.showItemSelector" class="card bar-large mt-0"> + <div class="drugstone sidebar column"> + <div + *ngIf="drugstoneConfig.config.showItemSelector" + class="card bar-large mt-0" + > <header class="card-header" - [ngClass]="{ 'b-text-small': smallStyle }" + [ngClass]="{ 'b-text-small': drugstoneConfig.smallStyle }" > <p class="card-header-title"> <span *ngIf="!selectedWrapper" class="icon"> @@ -63,18 +70,15 @@ </header> <div *ngIf="collapseDetails"> <div class="card-content"> - <app-info-tile - [wrapper]="selectedWrapper" - [smallStyle]="smallStyle" - ></app-info-tile> + <app-info-tile [wrapper]="selectedWrapper"></app-info-tile> </div> </div> </div> <div - *ngIf="myConfig.showOverview" + *ngIf="drugstoneConfig.config.showOverview" class="card bar-large" - [ngClass]="{ 'b-text-small': smallStyle }" + [ngClass]="{ 'b-text-small': drugstoneConfig.smallStyle }" > <header class="card-header"> <p class="card-header-title"> @@ -135,9 +139,9 @@ </div> <div - *ngIf="myConfig.showQuery" + *ngIf="drugstoneConfig.config.showQuery" class="card bar-large" - [ngClass]="{ 'b-text-small': smallStyle }" + [ngClass]="{ 'b-text-small': drugstoneConfig.smallStyle }" > <header class="card-header"> <p class="card-header-title"> @@ -176,10 +180,13 @@ </div> </div> - <div *ngIf="myConfig.showSimpleAnalysis" class="card bar-large"> + <div + *ngIf="drugstoneConfig.config.showSimpleAnalysis" + class="card bar-large" + > <header class="card-header" - [ngClass]="{ 'b-text-small': smallStyle }" + [ngClass]="{ 'b-text-small': drugstoneConfig.smallStyle }" > <p class="card-header-title"> <span class="icon"> @@ -204,19 +211,19 @@ <div *ngIf="collapseAnalysisQuick"> <div class="card-content quick-find" - [ngClass]="{ small: smallStyle }" + [ngClass]="{ small: drugstoneConfig.smallStyle }" > <div class="field"> <div class="control"> <div class="tile notification quick-start warning" - [ngClass]="{ small: smallStyle }" + [ngClass]="{ small: drugstoneConfig.smallStyle }" > <div class="align-vmiddle"> <div [ngClass]="{ - digit: !smallStyle, - 'digit-small': smallStyle + digit: !drugstoneConfig.smallStyle, + 'digit-small': drugstoneConfig.smallStyle }" > <i class="fa fa-fast-forward"></i> @@ -231,12 +238,7 @@ <button (click)="analysis.startQuickAnalysis(true, null)" [disabled]="analysis.isLaunchingQuick()" - class=" - button - is-white is-rounded - has-tooltip - quick-start-btn - " + class="button is-white is-rounded has-tooltip quick-start-btn" pTooltip="Find drugs for all proteins." [tooltipStyleClass]="'drgstn drgstn-tooltip'" tooltipPosition="top" @@ -249,7 +251,11 @@ <i class="fa fa-spin fa-spinner"></i> </span> </span> - <span [ngClass]="{ 'text-normal': smallStyle }"> + <span + [ngClass]="{ + 'text-normal': drugstoneConfig.smallStyle + }" + > Quick Start </span> </button> @@ -259,13 +265,13 @@ <div class="divisor-rapid">— or —</div> <div class="tile notification quick-start info" - [ngClass]="{ small: smallStyle }" + [ngClass]="{ small: drugstoneConfig.smallStyle }" > <div class="align-vmiddle"> <div [ngClass]="{ - digit: !smallStyle, - 'digit-small': smallStyle + digit: !drugstoneConfig.smallStyle, + 'digit-small': drugstoneConfig.smallStyle }" *ngIf="analysis.getCount() == 0" > @@ -273,8 +279,8 @@ </div> <div [ngClass]="{ - digit: !smallStyle, - 'digit-small': smallStyle + digit: !drugstoneConfig.smallStyle, + 'digit-small': drugstoneConfig.smallStyle }" *ngIf="analysis.getCount() > 0" > @@ -288,7 +294,9 @@ " > <div - [ngClass]="{ 'text-normal': smallStyle }" + [ngClass]="{ + 'text-normal': drugstoneConfig.smallStyle + }" class="quick-start-btn" > Select Proteins @@ -298,13 +306,13 @@ </div> <div class="tile notification quick-start info" - [ngClass]="{ small: smallStyle }" + [ngClass]="{ small: drugstoneConfig.smallStyle }" > <div class="align-vmiddle"> <div [ngClass]="{ - digit: !smallStyle, - 'digit-small': smallStyle + digit: !drugstoneConfig.smallStyle, + 'digit-small': drugstoneConfig.smallStyle }" > 2 @@ -322,12 +330,7 @@ analysis.getCount() === 0 || analysis.isLaunchingQuick() " - class=" - button - is-white is-rounded - quick-start-btn - drugs-btn - " + class="button is-white is-rounded quick-start-btn drugs-btn" pTooltip="Find drugs for the selected proteins." [tooltipStyleClass]="'drgstn drgstn-tooltip'" tooltipPosition="top" @@ -340,8 +343,12 @@ <i class="fa fa-spin fa-spinner"></i> </span> </span> - <span [ngClass]="{ 'text-normal': smallStyle }"> - {{ myConfig.taskDrugName }} + <span + [ngClass]="{ + 'text-normal': drugstoneConfig.smallStyle + }" + > + {{ drugstoneConfig.config.taskDrugName }} </span> </button> </div> @@ -353,10 +360,13 @@ </div> </div> - <div *ngIf="myConfig.showAdvAnalysis" class="card bar-large"> + <div + *ngIf="drugstoneConfig.config.showAdvAnalysis" + class="card bar-large" + > <header class="card-header" - [ngClass]="{ 'b-text-small': smallStyle }" + [ngClass]="{ 'b-text-small': drugstoneConfig.smallStyle }" > <p class="card-header-title"> <span class="icon"> @@ -392,18 +402,14 @@ analysisDialogTarget = 'drug-target'; showAnalysisDialog = true " - class=" - button - is-primary is-fullwidth is-rounded - has-tooltip - " + class="button is-primary is-fullwidth is-rounded has-tooltip" [disabled]="analysis.getCount() === 0" - [ngClass]="{ 'text-small': smallStyle }" + [ngClass]="{ 'text-small': drugstoneConfig.smallStyle }" > <span class="icon"> <i class="fa fa-crosshairs"></i> </span> - <span>{{ myConfig.taskTargetName }}</span> + <span>{{ drugstoneConfig.config.taskTargetName }}</span> </button> </div> </div> @@ -418,19 +424,15 @@ (click)=" analysisDialogTarget = 'drug'; showAnalysisDialog = true " - class=" - button - is-primary is-fullwidth is-rounded - has-tooltip - " + class="button is-primary is-fullwidth is-rounded has-tooltip" [disabled]="analysis.getCount() === 0" - [ngClass]="{ 'text-small': smallStyle }" + [ngClass]="{ 'text-small': drugstoneConfig.smallStyle }" > <span class="icon"> <i class="fa fa-capsules"></i> </span> <span> - {{ myConfig.taskDrugName }} + {{ drugstoneConfig.config.taskDrugName }} </span> </button> </div> @@ -441,11 +443,7 @@ *ngIf="analysis.getCount() > 0" [href]="gProfilerLink()" target="_blank" - class=" - button - is-primary is-fullwidth is-rounded - has-tooltip - " + class="button is-primary is-fullwidth is-rounded has-tooltip" pTooltip="Use enrichment analysis via g:Profiler (external)." [tooltipStyleClass]="'drgstn drgstn-tooltip'" tooltipPosition="top" @@ -453,18 +451,16 @@ <span class="icon"> <i class="fa fa-external-link-alt"></i> </span> - <span [ngClass]="{ 'text-small': smallStyle }"> + <span + [ngClass]="{ 'text-small': drugstoneConfig.smallStyle }" + > Enrichment Analysis </span> </a> <a *ngIf="analysis.getCount() === 0" disabled - class=" - button - is-primary is-fullwidth is-rounded - has-tooltip - " + class="button is-primary is-fullwidth is-rounded has-tooltip" pTooltip="Use enrichment analysis via g:Profiler (external)." [tooltipStyleClass]="'drgstn drgstn-tooltip'" tooltipPosition="top" @@ -472,7 +468,9 @@ <span class="icon"> <i class="fa fa-external-link-alt"></i> </span> - <span [ngClass]="{ 'text-small': smallStyle }"> + <span + [ngClass]="{ 'text-small': drugstoneConfig.smallStyle }" + > Enrichment Analysis </span> </a> @@ -482,10 +480,10 @@ </div> </div> - <div *ngIf="myConfig.showTasks" class="card bar-large"> + <div *ngIf="drugstoneConfig.config.showTasks" class="card bar-large"> <header class="card-header" - [ngClass]="{ 'b-text-small': smallStyle }" + [ngClass]="{ 'b-text-small': drugstoneConfig.smallStyle }" > <p class="card-header-title"> <span class="icon"> @@ -512,10 +510,7 @@ class="card-content overflow task-list-container" *ngIf="analysis.tasks && analysis.tasks.length > 0" > - <app-task-list - [(token)]="selectedAnalysisToken" - [smallStyle]="smallStyle" - ></app-task-list> + <app-task-list [(token)]="selectedAnalysisToken"></app-task-list> </div> <footer class="card-footer"> <a @@ -537,10 +532,13 @@ </div> </div> - <div *ngIf="myConfig.showSelection" class="card bar-large"> + <div + *ngIf="drugstoneConfig.config.showSelection" + class="card bar-large" + > <header class="card-header" - [ngClass]="{ 'b-text-small': smallStyle }" + [ngClass]="{ 'b-text-small': drugstoneConfig.smallStyle }" > <p class="card-header-title"> <span class="icon"> @@ -565,7 +563,7 @@ <div *ngIf="collapseSelection" class="seed-selection" - [ngClass]="{ 'text-normal': 'smallStyle' }" + [ngClass]="{ 'text-normal': 'drugstoneConfig.smallStyle' }" > <div class="card-content overflow"> <table @@ -576,8 +574,12 @@ <tr> <td>Label</td> <td>Group</td> - <td *ngIf="myConfig.identifier !== 'symbol'">Symbol</td> - <td *ngIf="myConfig.identifier !== 'uniprot'">Uniprot</td> + <td *ngIf="drugstoneConfig.config.identifier !== 'symbol'"> + Symbol + </td> + <td *ngIf="drugstoneConfig.config.identifier !== 'uniprot'"> + Uniprot + </td> <td>Actions</td> </tr> </thead> @@ -588,23 +590,23 @@ </td> <td> <p> - {{ myConfig.nodeGroups[p.data.group]["groupName"] }} + {{ + drugstoneConfig.config.nodeGroups[p.data.group][ + "groupName" + ] + }} </p> </td> - <td *ngIf="myConfig.identifier !== 'symbol'"> + <td *ngIf="drugstoneConfig.config.identifier !== 'symbol'"> <p>{{ p.data.symbol }}</p> </td> - <td *ngIf="myConfig.identifier !== 'uniprot'"> + <td *ngIf="drugstoneConfig.config.identifier !== 'uniprot'"> <p>{{ p.data.uniprotAc }}</p> </td> <td> <button (click)="analysis.removeItems([p])" - class=" - button - is-small is-danger is-outlined - has-tooltip - " + class="button is-small is-danger is-outlined has-tooltip" tooltipPosition="top" pTooltip="Remove from selection." > @@ -701,24 +703,22 @@ [(token)]="selectedAnalysisToken" (showDetailsChange)="selectedWrapper = $event" (visibleItems)="analysisWindowChanged($event)" - [config]="myConfig" - [smallStyle]="smallStyle" + [config]="drugstoneConfig.config" ></app-analysis-panel> </div> <div class="card network"> <header class="card-header network-header"> <p class="card-header-title"> - {{ myConfig.title }} + {{ drugstoneConfig.config.title }} </p> </header> <div class="card-content explorer-network-view-settings"> <div class="card-image canvas-content" #networkWithLegend> - <div *ngIf="myConfig.showLegend"> + <div *ngIf="drugstoneConfig.config.showLegend"> <app-network-legend - [config]="myConfig" + [config]="drugstoneConfig.config" [context]="legendContext" - [smallStyle]="smallStyle" ></app-network-legend> </div> <div class="center image1 fullheight" #network> @@ -728,146 +728,207 @@ </div> </div> - <footer - *ngIf="myConfig.showFooter" - class="card-footer toolbar network-footer-toolbar" + <div + *ngIf="drugstoneConfig.config.showNetworkMenu" + class="network-footer-toolbar drgstn-box-shadow" + [ngClass]="networkSidebarOpen ? 'opened' : 'closed'" > <div class="network-footer-toolbar-inner-container"> - <ng-container *ngIf="myConfig.showFooterButtonScreenshot"> - <div class="footer-buttons network-footer-toolbar-element"> - <button - (click)="toImage()" - class="button is-primary is-rounded has-tooltip" - pTooltip="Take a screenshot of the current network." - [ngClass]="{ 'button-small': smallStyle }" - [tooltipStyleClass]="'drgstn drgstn-tooltip'" - tooltipPosition="top" - > - <span class="icon"> - <i class="fas fa-camera" aria-hidden="true"></i> - </span> - <span [ngClass]="{ 'text-normal': smallStyle }" - >Screenshot</span - > - </button> - </div> - </ng-container> - - <ng-container *ngIf="myConfig.showFooterButtonExportGraphml"> - <app-download-button - [nodeData]="nodeData" - [smallStyle]="smallStyle" - [buttonId]="'explorer-download'" - ></app-download-button> - </ng-container> - - <ng-container *ngIf="myConfig.showFooterButtonExpression"> + <button + (click)="toggleNetworkSidebar()" + class="button is-small is-primary network-toolbar-toggle" + [ngClass]="{ rotated: networkSidebarOpen }" + > + <i class="fas fa-angle-left"></i> + </button> + <div class="rows"> <div - class=" - footer-buttons - dropdown - is-up - network-footer-toolbar-element + class="row is-full m-1" + *ngIf=" + drugstoneConfig.config.showNetworkMenuButtonScreenshot " - [class.is-active]="expressionExpanded" > - <div class="dropdown-trigger"> + <div class="network-footer-toolbar-element"> <button - (click)="expressionExpanded = !expressionExpanded" - class="button is-rounded is-primary" - [class.is-outlined]="!selectedTissue" - aria-haspopup="true" - aria-controls="dropdown-menu" - pTooltip="Tissue expression data is provided by the GTEx project." + (click)="toImage()" + class="button is-primary is-rounded has-tooltip" + pTooltip="Take a screenshot of the current network." [tooltipStyleClass]="'drgstn drgstn-tooltip'" tooltipPosition="top" - [ngClass]="{ 'button-small': smallStyle }" > + <span class="icon"> + <i class="fas fa-camera" aria-hidden="true"></i> + </span> <span - *ngIf="!selectedTissue" - [ngClass]="{ 'text-small': smallStyle }" - >Tissue</span + [ngClass]="{ + 'text-normal': drugstoneConfig.smallStyle + }" + >Screenshot</span > - <span *ngIf="selectedTissue">{{ - selectedTissue.name - }}</span> - <span *ngIf="expressionExpanded" class="icon is-small"> - <i class="fas fa-angle-up" aria-hidden="true"></i> - </span> - <span *ngIf="!expressionExpanded" class="icon is-small"> - <i class="fas fa-angle-left" aria-hidden="true"></i> - </span> </button> </div> - <div class="dropdown-menu" id="dropdown-menu" role="menu"> - <div class="dropdown-content tissue-dropdown"> - <div class="scroll-area"> - <a - (click)="selectTissue(null)" - [class.is-active]="!selectedTissue" - class="dropdown-item" + </div> + <div + class="row is-full m-1" + *ngIf=" + drugstoneConfig.config.showNetworkMenuButtonExportGraphml + " + > + <app-download-button + [nodeData]="nodeData" + [buttonId]="'explorer-download'" + ></app-download-button> + </div> + <div + class="row is-full m-1" + *ngIf=" + drugstoneConfig.config.showNetworkMenuButtonExpression + " + > + <div + class="dropdown network-footer-toolbar-element" + [class.is-active]="expressionExpanded" + > + <div class="dropdown-trigger"> + <button + (click)="expressionExpanded = !expressionExpanded" + class="button is-rounded is-primary" + [class.is-outlined]="!selectedTissue" + aria-haspopup="true" + aria-controls="dropdown-menu" + pTooltip="Tissue expression data is provided by the GTEx project." + [tooltipStyleClass]="'drgstn drgstn-tooltip'" + tooltipPosition="top" + > + <span class="icon is-small"> + <i class="fas fa-child"></i> + </span> + <span + *ngIf="!selectedTissue" + [ngClass]="{ + 'text-small': drugstoneConfig.smallStyle + }" + >Tissue</span > - None - </a> - <a - *ngFor="let tissue of analysis.getTissues()" - (click)="selectTissue(tissue)" - [class.is-active]=" - selectedTissue && - tissue.netexId === selectedTissue.netexId - " - class="dropdown-item" + <span *ngIf="selectedTissue" [ngClass]="{ + 'text-small': drugstoneConfig.smallStyle + }">{{ + selectedTissue.name + }}</span> + <span + *ngIf="expressionExpanded" + class="icon is-small" + > + <i class="fas fa-angle-down" aria-hidden="true"></i> + </span> + <span + *ngIf="!expressionExpanded" + class="icon is-small" > - {{ tissue.name }} - </a> + <i class="fas fa-angle-left" aria-hidden="true"></i> + </span> + </button> + </div> + <div class="dropdown-menu" id="dropdown-menu" role="menu"> + <div class="dropdown-content tissue-dropdown"> + <div class="scroll-area"> + <a + (click)="selectTissue(null)" + [class.is-active]="!selectedTissue" + class="dropdown-item" + > + None + </a> + <a + *ngFor="let tissue of analysis.getTissues()" + (click)="selectTissue(tissue)" + [class.is-active]=" + selectedTissue && + tissue.netexId === selectedTissue.netexId + " + class="dropdown-item" + > + {{ tissue.name }} + </a> + </div> </div> </div> </div> </div> - </ng-container> - <app-toggle - class="footer-buttons network-footer-toolbar-element" - textOn="Drugs" - textOff="Off" - tooltipOn="Display adjacent drugs ON." - tooltipOff="Display adjacent drugs OFF." - [smallStyle]="smallStyle" - [value]="adjacentDrugs" - (valueChange)="updateAdjacentDrugs($event)" - ></app-toggle> - <app-toggle - class="footer-buttons network-footer-toolbar-element" - textOn="Disorders (protein)" - textOff="Off" - tooltipOn="Show disorders adjacent to all currently displayed proteins/genes ON." - tooltipOff="Show disorders adjacent to all currently displayed proteins/genes OFF." - [smallStyle]="smallStyle" - [value]="adjacentDisordersProtein" - (valueChange)="updateAdjacentProteinDisorders($event)" - ></app-toggle> - <app-toggle - class="footer-buttons network-footer-toolbar-element" - textOn="Disorders (drugs)" - textOff="Off" - tooltipOn="Show disorders adjacent to all currently displayed drugs ON." - tooltipOff="Show disorders adjacent to all currently displayed drugs OFF." - [smallStyle]="smallStyle" - [value]="adjacentDisordersDrug" - [disabled]="!hasDrugsLoaded()" - (valueChange)="updateAdjacentDrugDisorders($event)" - ></app-toggle> - <app-toggle - class="footer-buttons network-footer-toolbar-element" - textOn="Animation" - textOff="Off" - tooltipOn="Enable the network animation." - tooltipOff="Disable the network animation and freeze nodes." - [smallStyle]="smallStyle" - [value]="physicsEnabled" - (valueChange)="updatePhysicsEnabled($event)" - ></app-toggle> + <div + class="row is-full m-1" + *ngIf=" + drugstoneConfig.config.showNetworkMenuButtonAdjacentDrugs + " + > + <app-toggle + class="network-footer-toolbar-element" + textOn="Drugs" + textOff="Off" + icon="fas fa-capsules" + tooltipOn="Display adjacent drugs ON." + tooltipOff="Display adjacent drugs OFF." + [value]="adjacentDrugs" + (valueChange)="updateAdjacentDrugs($event)" + ></app-toggle> + </div> + <div + class="row is-full m-1" + *ngIf=" + drugstoneConfig.config + .showNetworkMenuButtonAdjacentDisordersProteins + " + > + <app-toggle + class="network-footer-toolbar-element" + textOn="Disorders (protein)" + textOff="Off" + tooltipOn="Show disorders adjacent to all currently displayed proteins/genes ON." + tooltipOff="Show disorders adjacent to all currently displayed proteins/genes OFF." + [value]="adjacentDisordersProtein" + (valueChange)="updateAdjacentProteinDisorders($event)" + icon="fas fa-head-side-mask" + ></app-toggle> + </div> + <div + class="row is-full m-1" + *ngIf=" + drugstoneConfig.config + .showNetworkMenuButtonAdjacentDisordersDrugs + " + > + <app-toggle + class="network-footer-toolbar-element" + textOn="Disorders (drug)" + textOff="Off" + tooltipOn="Show disorders adjacent to all currently displayed drugs ON." + tooltipOff="Show disorders adjacent to all currently displayed drugs OFF." + [value]="adjacentDisordersDrug" + [disabled]="!hasDrugsLoaded()" + (valueChange)="updateAdjacentDrugDisorders($event)" + icon="fas fa-biohazard" + ></app-toggle> + </div> + <div + class="row is-full m-1" + *ngIf=" + drugstoneConfig.config.showNetworkMenuButtonAnimation + " + > + <app-toggle + class="network-footer-toolbar-element" + textOn="Animation" + textOff="Off" + tooltipOn="Enable the network animation." + tooltipOff="Disable the network animation and freeze nodes." + [value]="drugstoneConfig.config.physicsOn" + (valueChange)="updatePhysicsEnabled($event)" + icon="fas fa-bullseye" + ></app-toggle> + </div> + </div> </div> - </footer> + </div> </div> </div> </div> @@ -875,8 +936,8 @@ <div class="is-hidden-tablet mobile-fallback"> Sorry, drugstone is not available for mobile phones. To find information - about drugstone, please check the <a routerLink="/about">About</a> page or - visit this page with another device with a larger screen. + about drugstone, please check the <a routerLink="/about">About</a> page + or visit this page with another device with a larger screen. </div> </div> </div> diff --git a/src/app/pages/explorer-page/explorer-page.component.scss b/src/app/pages/explorer-page/explorer-page.component.scss index 31cdbe977374d392e785bf88997b278d28b1bc80..bc84f49f7c2572a9dfbc65aef71fbbb0d05bc017 100644 --- a/src/app/pages/explorer-page/explorer-page.component.scss +++ b/src/app/pages/explorer-page/explorer-page.component.scss @@ -118,5 +118,17 @@ padding: 0.5rem !important; } +.network-toolbar-toggle { + position: relative; + top: calc(50% - 10px); + display: inline-block; + margin: 0px; + left: -20px; + &.rotated { + -ms-transform: rotate(180deg); /* IE 9 */ + transform: rotate(180deg); + } +} + diff --git a/src/app/pages/explorer-page/explorer-page.component.ts b/src/app/pages/explorer-page/explorer-page.component.ts index 014884dd06af70b5be1ed3087488db5441c59ccf..c8cbb1fb52bd0d8af6cd920e17b11c88fbb30117 100644 --- a/src/app/pages/explorer-page/explorer-page.component.ts +++ b/src/app/pages/explorer-page/explorer-page.component.ts @@ -30,6 +30,7 @@ import {pieChartContextRenderer, removeDuplicateObjectsFromList} from '../../uti import * as merge from 'lodash/fp/merge'; import {AnalysisPanelComponent} from 'src/app/components/analysis-panel/analysis-panel.component'; import * as JSON5 from 'json5'; +import { DrugstoneConfigService } from 'src/app/services/drugstone-config/drugstone-config.service'; declare var vis: any; @@ -44,9 +45,6 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { private networkJSON = '{"nodes": [], "edges": []}'; private networkPositions = undefined; - // set default config on init - public myConfig: IConfig = JSON.parse(JSON.stringify(defaultConfig)); - @Input() public onload: undefined | string; @@ -65,7 +63,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { // add settings to config const configObj = typeof config === 'string' ? config.length === 0 ? {}: JSON5.parse(config) : config; - this.myConfig = merge(this.myConfig, configObj); + this.drugstoneConfig.config = merge(this.drugstoneConfig.config, configObj); // update Drugst.One according to the settings // check if config updates affect network @@ -82,7 +80,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { } } // trigger updates on config e.g. in legend - this.myConfig = {...this.myConfig}; + this.drugstoneConfig.config = {...this.drugstoneConfig.config}; if (updateNetworkFlag && typeof this.networkJSON !== 'undefined') { // update network if network config has changed and networkJSON exists if (this.networkInternal !== undefined) { @@ -90,7 +88,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { this.networkPositions = this.networkInternal.getPositions(); } this.createNetwork().then(() => { - if(this.myConfig.physicsOn) { + if(this.drugstoneConfig.config.physicsOn) { this.updatePhysicsEnabled(true); } }); @@ -115,7 +113,6 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { } public windowWidth = 0; - public smallStyle = false; public showDetails = false; public selectedWrapper: Wrapper | null = null; @@ -135,12 +132,13 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { public proteins: Node[]; public edges: NodeInteraction[]; + public networkSidebarOpen = true; + private networkInternal: any; // this will store the vis Dataset public nodeData: { nodes: any, edges: any } = {nodes: null, edges: null}; private dumpPositions = false; - public physicsEnabled = false; public adjacentDrugs = false; public adjacentDrugList: Node[] = []; @@ -196,6 +194,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { constructor( public omnipath: OmnipathControllerService, public analysis: AnalysisService, + public drugstoneConfig: DrugstoneConfigService, public netex: NetexControllerService) { this.showDetails = false; this.analysis.subscribeList(async (items, selected) => { @@ -220,7 +219,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { node.y = pos[wrapper.id].y; const nodeStyled = NetworkSettings.getNodeStyle( node, - this.myConfig, + this.drugstoneConfig.config, false, selected, 1.0 @@ -235,11 +234,11 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { this.nodeData.nodes.forEach((node) => { // const nodeSelected = this.analysis.idInSelection(node.id); // if (node.group == 'default') { - // Object.assign(node, this.myConfig.nodeGroups.default); + // Object.assign(node, this.drugstoneConfig.config.nodeGroups.default); // } else { - // Object.assign(node, this.myConfig.nodeGroups[node.group]); + // Object.assign(node, this.drugstoneConfig.config.nodeGroups[node.group]); // }; - Object.assign(node, this.myConfig.nodeGroups[node.group]); + Object.assign(node, this.drugstoneConfig.config.nodeGroups[node.group]); }); this.nodeData.nodes.update(updatedNodes); @@ -264,6 +263,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { // tslint:disable-next-line:no-eval eval(this.onload); } + } async getInteractions(key: InteractionDatabase) { @@ -272,7 +272,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { const names = this.nodeData.nodes.map((node) => node.label); const nameToNetworkId = {}; this.nodeData.nodes.map((node) => nameToNetworkId[node.label] = node.id); - edges = await this.omnipath.getInteractions(names, this.myConfig.identifier, nameToNetworkId); + edges = await this.omnipath.getInteractions(names, this.drugstoneConfig.config.identifier, nameToNetworkId); } this.nodeData.edges.update(edges); } @@ -280,7 +280,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { private async getNetwork() { const network = JSON.parse(this.networkJSON); - if (this.myConfig.identifier === 'ensg') { + if (this.drugstoneConfig.config.identifier === 'ensg') { // @ts-ignore network.nodes.forEach(node => { node.id = this.removeEnsemblVersion(node.id); @@ -295,10 +295,10 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { // map data to nodes in backend if (network.nodes != null && network.nodes.length) { - network.nodes = await this.netex.mapNodes(network.nodes, this.myConfig.identifier); + network.nodes = await this.netex.mapNodes(network.nodes, this.drugstoneConfig.config.identifier); } - if (this.myConfig.identifier === 'ensg') { + if (this.drugstoneConfig.config.identifier === 'ensg') { // remove possible duplicate IDs network.nodes = removeDuplicateObjectsFromList(network.nodes, 'netexId'); } @@ -334,10 +334,9 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { private setWindowWidth(width: number) { this.windowWidth = width; - this.smallStyle = this.windowWidth < 1250; + this.drugstoneConfig.smallStyle = this.windowWidth < 1250; } - private zoomToNode(id: string) { // get network object, depending on whether analysis is open or not const network = this.selectedAnalysisToken ? this.analysisPanel.network : this.networkInternal; @@ -394,18 +393,18 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { // TODO do we still need this? // this.proteinData.linkNodes(); - const {nodes, edges} = this.proteinData.mapDataToNetworkInput(this.myConfig); + const {nodes, edges} = this.proteinData.mapDataToNetworkInput(this.drugstoneConfig.config); - if (this.myConfig.autofillEdges && nodes.length) { - const netexEdges = await this.netex.fetchEdges(nodes, this.myConfig.interactionProteinProtein); - edges.push(...netexEdges.map(netexEdge => mapNetexEdge(netexEdge, this.myConfig))) + if (this.drugstoneConfig.config.autofillEdges && nodes.length) { + const netexEdges = await this.netex.fetchEdges(nodes, this.drugstoneConfig.config.interactionProteinProtein); + edges.push(...netexEdges.map(netexEdge => mapNetexEdge(netexEdge, this.drugstoneConfig.config))) } this.nodeData.nodes = new vis.DataSet(nodes); this.nodeData.edges = new vis.DataSet(edges); const container = this.networkEl.nativeElement; - const options = NetworkSettings.getOptions('main',this.myConfig.physicsOn); + const options = NetworkSettings.getOptions('main',this.drugstoneConfig.config.physicsOn); this.networkInternal = new vis.Network(container, this.nodeData, options); @@ -481,10 +480,10 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { } public updatePhysicsEnabled(bool: boolean) { - this.physicsEnabled = bool; + this.drugstoneConfig.config.physicsOn = bool; this.networkInternal.setOptions({ physics: { - enabled: this.physicsEnabled, + enabled: this.drugstoneConfig.config.physicsOn, stabilization: { enabled: false, }, @@ -498,12 +497,12 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { this.netex.adjacentDisorders(this.nodeData.nodes, 'proteins').subscribe(response => { for (const interaction of response.edges) { const edge = {from: interaction.protein, to: interaction.disorder}; - this.adjacentProteinDisorderEdgesList.push(mapCustomEdge(edge, this.myConfig)); + this.adjacentProteinDisorderEdgesList.push(mapCustomEdge(edge, this.drugstoneConfig.config)); } for (const disorder of response.disorders) { disorder.group = 'defaultDisorder'; disorder.id = disorder.netexId; - this.adjacentProteinDisorderList.push(mapCustomNode(disorder, this.myConfig)) + this.adjacentProteinDisorderList.push(mapCustomNode(disorder, this.drugstoneConfig.config)) } this.saveAddNodes(this.adjacentProteinDisorderList); this.nodeData.edges.add(this.adjacentProteinDisorderEdgesList); @@ -526,12 +525,12 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { this.netex.adjacentDisorders(this.nodeData.nodes, 'drugs').subscribe(response => { for (const interaction of response.edges) { const edge = {from: interaction.drug, to: interaction.disorder}; - this.adjacentDrugDisorderEdgesList.push(mapCustomEdge(edge, this.myConfig)); + this.adjacentDrugDisorderEdgesList.push(mapCustomEdge(edge, this.drugstoneConfig.config)); } for (const disorder of response.disorders) { disorder.group = 'defaultDisorder'; disorder.id = disorder.netexId; - this.adjacentDrugDisorderList.push(mapCustomNode(disorder, this.myConfig)); + this.adjacentDrugDisorderList.push(mapCustomNode(disorder, this.drugstoneConfig.config)); } this.saveAddNodes(this.adjacentDrugDisorderList); this.nodeData.edges.add(this.adjacentDrugDisorderEdgesList); @@ -568,15 +567,15 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { public updateAdjacentDrugs(bool: boolean) { this.adjacentDrugs = bool; if (this.adjacentDrugs) { - this.netex.adjacentDrugs(this.myConfig.interactionDrugProtein, this.nodeData.nodes).subscribe(response => { + this.netex.adjacentDrugs(this.drugstoneConfig.config.interactionDrugProtein, this.nodeData.nodes).subscribe(response => { for (const interaction of response.pdis) { const edge = {from: interaction.protein, to: interaction.drug}; - this.adjacentDrugEdgesList.push(mapCustomEdge(edge, this.myConfig)); + this.adjacentDrugEdgesList.push(mapCustomEdge(edge, this.drugstoneConfig.config)); } for (const drug of response.drugs) { drug.group = 'foundDrug'; drug.id = getDrugNodeId(drug) - this.adjacentDrugList.push(mapCustomNode(drug, this.myConfig)) + this.adjacentDrugList.push(mapCustomNode(drug, this.drugstoneConfig.config)) } this.nodeData.nodes.add(this.adjacentDrugList); this.nodeData.edges.add(this.adjacentDrugEdgesList); @@ -645,10 +644,10 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { group.shape = 'image'; } // implement nodeShadow option, it needs to be set for all nodes or none - group.shadow = this.myConfig.nodeShadow; + group.shadow = this.drugstoneConfig.config.nodeShadow; }); - this.myConfig[key] = nodeGroups; + this.drugstoneConfig.config[key] = nodeGroups; } /** @@ -673,9 +672,9 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { } // implement edgeShadow option, it needs to be set for all nodes or none - value.shadow = this.myConfig.edgeShadow; + value.shadow = this.drugstoneConfig.config.edgeShadow; }); - this.myConfig[key] = edgeGroups; + this.drugstoneConfig.config[key] = edgeGroups; } public toImage() { @@ -758,7 +757,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { node, NetworkSettings.getNodeStyle( node, - this.myConfig, + this.drugstoneConfig.config, false, this.analysis.inSelection(getWrapperFromNode(item)), 1.0 @@ -802,7 +801,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { Object.assign(node, NetworkSettings.getNodeStyle( node, - this.myConfig, + this.drugstoneConfig.config, node.isSeed, this.analysis.inSelection(wrapper), gradient)); @@ -836,4 +835,8 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { else this.inputNetwork = network; } + + toggleNetworkSidebar() { + this.networkSidebarOpen = !this.networkSidebarOpen; + } } diff --git a/src/index.html b/src/index.html index e201022ef700840f72fbab4265e1a0a318ba2bab..929432859c1069c609ff0615a13c5ff10f9bd5db 100644 --- a/src/index.html +++ b/src/index.html @@ -18,10 +18,10 @@ <input type="checkbox" onclick=changeConfigStr('{"showAdvAnalysis":'+this.checked+'}') checked /> Show Advanced Analysis<br> <input type="checkbox" onclick=changeConfigStr('{"showTasks":'+this.checked+'}') checked /> Show Tasks<br> <input type="checkbox" onclick=changeConfigStr('{"showSelection":'+this.checked+'}') checked /> Show Selection<br> -<input type="checkbox" onclick=changeConfigStr('{"showFooter":'+this.checked+'}') checked /> Show Footer<br> +<input type="checkbox" onclick=changeConfigStr('{"showNetworkMenu":'+this.checked+'}') checked /> Show Footer<br> <input type="checkbox" onclick=changeConfigStr('{"showLegend":'+this.checked+'}') checked /> Show Legend<br> -<input type="checkbox" onclick=changeConfigStr('{"showFooterButtonScreenshot":'+this.checked+'}') checked /> Show Screenshot button<br> -<input type="checkbox" onclick=changeConfigStr('{"showFooterButtonExportGraphml":'+this.checked+'}') checked /> Show Export As Graphml Button<br> +<input type="checkbox" onclick=changeConfigStr('{"showNetworkMenuButtonScreenshot":'+this.checked+'}') checked /> Show Screenshot button<br> +<input type="checkbox" onclick=changeConfigStr('{"showNetworkMenuButtonExportGraphml":'+this.checked+'}') checked /> Show Export As Graphml Button<br> <input id="new_color" type="text" /> <button onclick=changeColor(document.getElementById("new_color").value) >Set Color </button> <br> diff --git a/src/stylesheets/styles.scss b/src/stylesheets/styles.scss index aa5e9f9a1f17d77e3bf76af1fdd1821e89bb197b..2fd036edebc79d7e0019376106ffe6791c6d88ee 100644 --- a/src/stylesheets/styles.scss +++ b/src/stylesheets/styles.scss @@ -12,6 +12,9 @@ max-height: 150px !important; } + .drgstn-box-shadow { + box-shadow: 0 .125em .25em hsla(0,0%,4%,.1); + } .fullheight { height: 100%; @@ -26,33 +29,52 @@ z-index: $explorer-network-z; } + @keyframes hideSidebar { + from {right: 0;} + to {right: $network-footer-right-closed} + } + + @keyframes showSidebar { + from {right: $network-footer-right-closed} + to {right: 0;} + } + // general network settings, some will be overwritten in analysis .network-footer-toolbar { position: absolute; - width: 100%; - bottom: 0; - height: $network-footer-height; + height: calc(100% - #{$network-header-height}); + width: $network-footer-width; + top: $network-header-height; + background-color: var(--drgstn-panel-secondary); + z-index: $network-footer-container-z; + + &.opened { + right: 0; + animation-name: showSidebar; + animation-duration: 1s; + } + &.closed { + right: $network-footer-right-closed; + animation-name: hideSidebar; + animation-duration: 1s; + } &-inner-container { width: 100%; - display: inline-flex; - overflow-x: auto; - overflow-y: hidden; height: $network-footer-inner-container-height; position: absolute; - bottom: 0; } &-element { position: relative; - margin-top: calc(#{$network-footer-inner-container-height} - #{$network-footer-height} + #{$network-footer-space-button-to-border}); + margin-left: 10px; } .dropdown-menu { z-index: $explorer-network-toolbar-dropdown-z; .scroll-area { - height: calc(#{$network-footer-inner-container-height} - #{$network-footer-height}); + height: 15rem; } } } @@ -172,9 +194,10 @@ div.drugstone.explorer { - height: #{$height}; + height: $height; margin-left: 10px; margin-right: 10px; + overflow: hidden; } .analysis-view { @@ -193,25 +216,6 @@ margin-top: 20px; } - - .footer-buttons { - margin-left: 10px; - margin-right: 10px; - } - - .toolbar { - border-top: 2px solid #d0d0d0; - - .field { - margin-bottom: 0 !important; - - .control { - margin-bottom: 0 !important; - } - } - } - - // classes for different screen sizes .text-small { font-size: $text-small-font-size; diff --git a/src/stylesheets/variables.scss b/src/stylesheets/variables.scss index 906ac7c99d02db6321b5c75e1d5b18aad81a02c4..16a831781f6101953e2b75ce2a19fa40319eee24 100644 --- a/src/stylesheets/variables.scss +++ b/src/stylesheets/variables.scss @@ -3,7 +3,11 @@ $screen-lg: 1400px; $row-data-selector-height: auto; $network-header-height: 3rem; -$network-footer-height: 4rem; +$network-footer-height: 0rem; +$network-footer-width: 15rem; +$network-footer-right-closed: -12rem; +$network-footer-container-z: 20; + $network-footer-inner-container-height: 25rem; $network-footer-space-button-to-border: 0.5rem;