From 2ea0be00f04f73e72f0008f3ecd5f2d281731180 Mon Sep 17 00:00:00 2001
From: "Hartung, Michael" <michael.hartung@uni-hamburg.de>
Date: Fri, 5 May 2023 16:00:52 +0200
Subject: [PATCH] hide connector nodes in legend if none in network

---
 .../analysis-panel.component.ts               | 682 +++++++++++-------
 .../network-legend.component.ts               |  65 +-
 .../legend-service/legend-service.service.ts  |   7 +
 src/index.html                                |   2 +-
 4 files changed, 481 insertions(+), 275 deletions(-)

diff --git a/src/app/components/analysis-panel/analysis-panel.component.ts b/src/app/components/analysis-panel/analysis-panel.component.ts
index 26c8b639..a616c00f 100644
--- a/src/app/components/analysis-panel/analysis-panel.component.ts
+++ b/src/app/components/analysis-panel/analysis-panel.component.ts
@@ -9,9 +9,12 @@ import {
   Output,
   SimpleChanges,
   ViewChild,
-} from '@angular/core';
-import {HttpClient} from '@angular/common/http';
-import {algorithmNames, AnalysisService} from '../../services/analysis/analysis.service';
+} from "@angular/core";
+import { HttpClient } from "@angular/common/http";
+import {
+  algorithmNames,
+  AnalysisService,
+} from "../../services/analysis/analysis.service";
 import {
   Drug,
   NodeAttributeMap,
@@ -23,22 +26,26 @@ import {
   Tissue,
   Wrapper,
   NodeInteraction,
-} from '../../interfaces';
-import {NetworkSettings} from '../../network-settings';
-import {NetexControllerService} from 'src/app/services/netex-controller/netex-controller.service';
-import {mapCustomEdge, mapNetexEdge, ProteinNetwork} from 'src/app/main-network';
-import {DrugstoneConfigService} from 'src/app/services/drugstone-config/drugstone-config.service';
-import {NetworkHandlerService} from 'src/app/services/network-handler/network-handler.service';
-import {LegendService} from 'src/app/services/legend-service/legend-service.service';
-import {LoadingScreenService} from 'src/app/services/loading-screen/loading-screen.service';
-import {version} from '../../../version';
-import {downloadCSV} from 'src/app/utils';
+} from "../../interfaces";
+import { NetworkSettings } from "../../network-settings";
+import { NetexControllerService } from "src/app/services/netex-controller/netex-controller.service";
+import {
+  mapCustomEdge,
+  mapNetexEdge,
+  ProteinNetwork,
+} from "src/app/main-network";
+import { DrugstoneConfigService } from "src/app/services/drugstone-config/drugstone-config.service";
+import { NetworkHandlerService } from "src/app/services/network-handler/network-handler.service";
+import { LegendService } from "src/app/services/legend-service/legend-service.service";
+import { LoadingScreenService } from "src/app/services/loading-screen/loading-screen.service";
+import { version } from "../../../version";
+import { downloadCSV } from "src/app/utils";
 
 declare var vis: any;
 
 interface Scored {
-  score: number;  // Normalized or unnormalized (whichever user selects, will be displayed in the table)
-  rawScore: number;  // Unnormalized (kept to restore unnormalized value)
+  score: number; // Normalized or unnormalized (whichever user selects, will be displayed in the table)
+  rawScore: number; // Unnormalized (kept to restore unnormalized value)
   rank: number;
 }
 
@@ -46,23 +53,25 @@ interface Seeded {
   isSeed: boolean;
 }
 
-
 @Component({
-  selector: 'app-analysis-panel',
-  templateUrl: './analysis-panel.component.html',
-  styleUrls: ['./analysis-panel.component.scss'],
+  selector: "app-analysis-panel",
+  templateUrl: "./analysis-panel.component.html",
+  styleUrls: ["./analysis-panel.component.scss"],
 })
-export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit {
-
-  @ViewChild('networkWithLegend', {static: false}) networkWithLegendEl: ElementRef;
+export class AnalysisPanelComponent
+  implements OnInit, OnChanges, AfterViewInit
+{
+  @ViewChild("networkWithLegend", { static: false })
+  networkWithLegendEl: ElementRef;
   @Input() token: string | null = null;
   @Input() tokenType: string | null = null;
 
-
   @Output() tokenChange = new EventEmitter<string | null>();
   @Output() showDetailsChange = new EventEmitter<Wrapper>();
   @Output() setInputNetwork = new EventEmitter<any>();
-  @Output() visibleItems = new EventEmitter<[any[], [Node[], Tissue], NodeInteraction[]]>();
+  @Output() visibleItems = new EventEmitter<
+    [any[], [Node[], Tissue], NodeInteraction[]]
+  >();
   public task: Task | null = null;
   public result: any = null;
 
@@ -71,10 +80,10 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
   public algorithmDefault = undefined;
 
   public network: any;
-  public nodeData: { nodes: any, edges: any } = {nodes: null, edges: null};
+  public nodeData: { nodes: any; edges: any } = { nodes: null, edges: null };
   // private drugNodes: any[] = [];
   // private drugEdges: any[] = [];
-  public tab: 'meta' | 'network' | 'table' = 'network';
+  public tab: "meta" | "network" | "table" = "network";
 
   private proteins: any;
   public effects: any;
@@ -85,15 +94,15 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
   public tableNormalize = false;
   public tableHasScores = false;
 
-  public LegendContext: LegendContext = 'drugTarget';
+  public LegendContext: LegendContext = "drugTarget";
 
   public expressionExpanded = false;
   public selectedTissue: Tissue | null = null;
 
   public algorithmNames = algorithmNames;
 
-  public tableDrugScoreTooltip = '';
-  public tableProteinScoreTooltip = '';
+  public tableDrugScoreTooltip = "";
+  public tableProteinScoreTooltip = "";
 
   public versionString = undefined;
 
@@ -101,18 +110,24 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
 
   public loading = false;
 
-  constructor(public legendService: LegendService, public networkHandler: NetworkHandlerService, public drugstoneConfig: DrugstoneConfigService, private http: HttpClient, public analysis: AnalysisService, public netex: NetexControllerService, public loadingScreen: LoadingScreenService) {
+  constructor(
+    public legendService: LegendService,
+    public networkHandler: NetworkHandlerService,
+    public drugstoneConfig: DrugstoneConfigService,
+    private http: HttpClient,
+    public analysis: AnalysisService,
+    public netex: NetexControllerService,
+    public loadingScreen: LoadingScreenService
+  ) {
     try {
       this.versionString = version;
-    } catch (e) {
-    }
+    } catch (e) {}
   }
 
-  async ngOnInit() {
-  }
+  async ngOnInit() {}
 
   ngAfterViewInit() {
-    this.networkHandler.setActiveNetwork('analysis');
+    this.networkHandler.setActiveNetwork("analysis");
   }
 
   async ngOnChanges(changes: SimpleChanges) {
@@ -127,53 +142,70 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
     this.resetEmitter.emit(true);
   }
 
-  private setNetworkListeners(){
-    this.networkHandler.activeNetwork.networkInternal.on('dragEnd', (properties) => {
-      const node_ids = this.networkHandler.activeNetwork.networkInternal.getSelectedNodes();
-      if (node_ids.length === 0 || !this.networkHandler.shiftDown) {
-        return;
-      }
-      this.analysis.addNodesByIdsToSelection(node_ids);
-      this.networkHandler.activeNetwork.networkInternal.unselectAll();
-    });
-    this.networkHandler.activeNetwork.networkInternal.on('deselectNode', (properties) => {
-      this.showDetailsChange.emit(null);
-    });
-    this.networkHandler.activeNetwork.networkInternal.on('doubleClick', (properties) => {
-      const nodeIds: Array<string> = properties.nodes;
-      if (nodeIds.length > 0) {
-        const nodeId = nodeIds[0];
-        const node = this.nodeData.nodes.get(nodeId);
-        if (node.drugstoneId === undefined || node.nodeType === 'drug' || node.drugstoneType !== 'protein') {
-          this.analysis.unmappedNodeToast();
+  private setNetworkListeners() {
+    this.networkHandler.activeNetwork.networkInternal.on(
+      "dragEnd",
+      (properties) => {
+        const node_ids =
+          this.networkHandler.activeNetwork.networkInternal.getSelectedNodes();
+        if (node_ids.length === 0 || !this.networkHandler.shiftDown) {
           return;
         }
-        const wrapper = getWrapperFromNode(node);
-        if (this.analysis.inSelection(wrapper)) {
-          this.analysis.removeItems([wrapper]);
-          this.analysis.getCount();
-        } else {
-          this.analysis.addItems([wrapper]);
-          this.analysis.getCount();
+        this.analysis.addNodesByIdsToSelection(node_ids);
+        this.networkHandler.activeNetwork.networkInternal.unselectAll();
+      }
+    );
+    this.networkHandler.activeNetwork.networkInternal.on(
+      "deselectNode",
+      (properties) => {
+        this.showDetailsChange.emit(null);
+      }
+    );
+    this.networkHandler.activeNetwork.networkInternal.on(
+      "doubleClick",
+      (properties) => {
+        const nodeIds: Array<string> = properties.nodes;
+        if (nodeIds.length > 0) {
+          const nodeId = nodeIds[0];
+          const node = this.nodeData.nodes.get(nodeId);
+          if (
+            node.drugstoneId === undefined ||
+            node.nodeType === "drug" ||
+            node.drugstoneType !== "protein"
+          ) {
+            this.analysis.unmappedNodeToast();
+            return;
+          }
+          const wrapper = getWrapperFromNode(node);
+          if (this.analysis.inSelection(wrapper)) {
+            this.analysis.removeItems([wrapper]);
+            this.analysis.getCount();
+          } else {
+            this.analysis.addItems([wrapper]);
+            this.analysis.getCount();
+          }
         }
       }
-    });
-
-    this.networkHandler.activeNetwork.networkInternal.on('click', (properties) => {
-      if (properties.nodes.length === 0 && properties.edges.length === 1) {
-        // clicked on one edge
-        const edgeId = properties.edges[0];
-        this.networkHandler.activeNetwork.openEdgeSummary(edgeId);
-      } else {
-        this.networkHandler.activeNetwork.activeEdge = null;
-        const selectedNodes = this.nodeData.nodes.get(properties.nodes);
-        if (selectedNodes.length > 0) {
-          this.showDetailsChange.emit(getWrapperFromNode(selectedNodes[0]));
+    );
+
+    this.networkHandler.activeNetwork.networkInternal.on(
+      "click",
+      (properties) => {
+        if (properties.nodes.length === 0 && properties.edges.length === 1) {
+          // clicked on one edge
+          const edgeId = properties.edges[0];
+          this.networkHandler.activeNetwork.openEdgeSummary(edgeId);
         } else {
-          this.showDetailsChange.emit(null);
+          this.networkHandler.activeNetwork.activeEdge = null;
+          const selectedNodes = this.nodeData.nodes.get(properties.nodes);
+          if (selectedNodes.length > 0) {
+            this.showDetailsChange.emit(getWrapperFromNode(selectedNodes[0]));
+          } else {
+            this.showDetailsChange.emit(null);
+          }
         }
       }
-    });
+    );
     this.analysis.subscribeList((items, selected) => {
       // return if analysis panel is closed or no nodes are loaded
       if (!this.token) {
@@ -187,10 +219,15 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
           if (!node) {
             continue;
           }
-          const pos = this.networkHandler.activeNetwork.networkInternal.getPositions([item.id]);
+          const pos =
+            this.networkHandler.activeNetwork.networkInternal.getPositions([
+              item.id,
+            ]);
           node.x = pos[item.id].x;
           node.y = pos[item.id].y;
-          const isSeed = this.networkHandler.activeNetwork.highlightSeeds ? this.networkHandler.activeNetwork.seedMap[node.id] : false;
+          const isSeed = this.networkHandler.activeNetwork.highlightSeeds
+            ? this.networkHandler.activeNetwork.seedMap[node.id]
+            : false;
           const nodeStyled = NetworkSettings.getNodeStyle(
             node,
             this.drugstoneConfig.currentConfig(),
@@ -206,8 +243,12 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
         const proteinSelection = this.tableSelectedProteins;
         for (const item of items) {
           // TODO: Refactor!
-          const found = proteinSelection.findIndex((i) => getProteinNodeId(i) === item.id);
-          const tableItem = this.tableProteins.find((i) => getProteinNodeId(i) === item.id);
+          const found = proteinSelection.findIndex(
+            (i) => getProteinNodeId(i) === item.id
+          );
+          const tableItem = this.tableProteins.find(
+            (i) => getProteinNodeId(i) === item.id
+          );
           if (selected && found === -1 && tableItem) {
             proteinSelection.push(tableItem);
           }
@@ -220,7 +261,9 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
         // else: selected is null
         const updatedNodes = [];
         this.nodeData.nodes.forEach((node) => {
-          const isSeed = this.networkHandler.activeNetwork.highlightSeeds ? this.networkHandler.activeNetwork.seedMap[node.id] : false;
+          const isSeed = this.networkHandler.activeNetwork.highlightSeeds
+            ? this.networkHandler.activeNetwork.seedMap[node.id]
+            : false;
           if (!isSeed) {
             return;
           }
@@ -238,7 +281,9 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
 
         const proteinSelection = [];
         for (const item of items) {
-          const tableItem = this.tableProteins.find((i) => getProteinNodeId(i) === item.id);
+          const tableItem = this.tableProteins.find(
+            (i) => getProteinNodeId(i) === item.id
+          );
           if (tableItem) {
             proteinSelection.push(tableItem);
           }
@@ -248,7 +293,9 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
     });
   }
 
-  private rankTable(table: Array<Drug & Scored> | Array<Node & Scored & Seeded>) {
+  private rankTable(
+    table: Array<Drug & Scored> | Array<Node & Scored & Seeded>
+  ) {
     let lastRank = 1;
     for (let idx = 0; idx < table.length; idx++) {
       if (idx === 0) {
@@ -265,16 +312,15 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
   private async refreshView() {
     this.loading = true;
     this.loadingScreen.stateUpdate(true);
-    this.getView(this.token).then(async view => {
+    this.getView(this.token).then(async (view) => {
       this.task = view;
       this.result = view;
       this.drugstoneConfig.set_analysisConfig(view.config);
       this.analysis.switchSelection(this.token);
       this.loadingScreen.stateUpdate(false);
 
-
       // Reset
-      this.nodeData = {nodes: null, edges: null};
+      this.nodeData = { nodes: null, edges: null };
       // this.networkHandler.activeNetwork.networkEl.nativeElement.innerHTML = '';
       // this.networkHandler.activeNetwork.networkInternal = null;
       // Create+
@@ -284,34 +330,56 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
 
         if (this.drugstoneConfig.config.autofillEdges && nodes.length) {
           const node_map = {};
-          nodes.filter(n => n.drugstoneType === 'protein').forEach(node => {
-            if (typeof node.drugstoneId === 'string') {
-              if (node_map[node.drugstoneId]) {
-                node_map[node.drugstoneId].push(node.id);
-              } else {
-                node_map[node.drugstoneId] = [node.id];
-              }
-            } else {
-              node.drugstoneId.forEach(n => {
-                if (node_map[n]) {
-                  node_map[n].push(node.id);
+          nodes
+            .filter((n) => n.drugstoneType === "protein")
+            .forEach((node) => {
+              if (typeof node.drugstoneId === "string") {
+                if (node_map[node.drugstoneId]) {
+                  node_map[node.drugstoneId].push(node.id);
                 } else {
-                  node_map[n] = [node.id];
+                  node_map[node.drugstoneId] = [node.id];
                 }
-              });
-            }
-          });
-          const netexEdges = await this.netex.fetchEdges(nodes, this.drugstoneConfig.config.interactionProteinProtein, this.drugstoneConfig.config.licensedDatasets);
-          edges.push(...netexEdges.map(netexEdge => mapNetexEdge(netexEdge, this.drugstoneConfig.currentConfig(), node_map)).flatMap(e => e));
+              } else {
+                node.drugstoneId.forEach((n) => {
+                  if (node_map[n]) {
+                    node_map[n].push(node.id);
+                  } else {
+                    node_map[n] = [node.id];
+                  }
+                });
+              }
+            });
+          const netexEdges = await this.netex.fetchEdges(
+            nodes,
+            this.drugstoneConfig.config.interactionProteinProtein,
+            this.drugstoneConfig.config.licensedDatasets
+          );
+          edges.push(
+            ...netexEdges
+              .map((netexEdge) =>
+                mapNetexEdge(
+                  netexEdge,
+                  this.drugstoneConfig.currentConfig(),
+                  node_map
+                )
+              )
+              .flatMap((e) => e)
+          );
         }
 
         const edge_map = {};
 
-        edges = edges.filter(edge => {
-          if (edge_map[edge.to] && edge_map[edge.to].indexOf(edge.from) !== -1) {
+        edges = edges.filter((edge) => {
+          if (
+            edge_map[edge.to] &&
+            edge_map[edge.to].indexOf(edge.from) !== -1
+          ) {
             return false;
           }
-          if (edge_map[edge.from] && edge_map[edge.from].indexOf(edge.to) !== -1) {
+          if (
+            edge_map[edge.from] &&
+            edge_map[edge.from].indexOf(edge.to) !== -1
+          ) {
             return false;
           }
           if (!edge_map[edge.from]) {
@@ -324,15 +392,22 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
 
         // @ts-ignore
         if (!this.drugstoneConfig.selfReferences) {
-          edges = edges.filter(el => el.from !== el.to);
+          edges = edges.filter((el) => el.from !== el.to);
         }
 
-        this.networkHandler.activeNetwork.inputNetwork = {nodes: nodes, edges: edges};
+        this.networkHandler.activeNetwork.inputNetwork = {
+          nodes: nodes,
+          edges: edges,
+        };
         this.nodeData.nodes = new vis.DataSet(nodes);
         this.nodeData.edges = new vis.DataSet(edges);
-        const container = this.networkHandler.activeNetwork.networkEl.nativeElement;
+        const container =
+          this.networkHandler.activeNetwork.networkEl.nativeElement;
         const isBig = nodes.length > 100 || edges.length > 100;
-        const options = NetworkSettings.getOptions(isBig ? 'analysis-big' : 'analysis', this.drugstoneConfig.currentConfig());
+        const options = NetworkSettings.getOptions(
+          isBig ? "analysis-big" : "analysis",
+          this.drugstoneConfig.currentConfig()
+        );
         // @ts-ignore
         options.groups = this.drugstoneConfig.currentConfig().nodeGroups;
         // @ts-ignore
@@ -343,19 +418,31 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
         if (this.drugstoneConfig.config.physicsOn) {
           this.drugstoneConfig.config.physicsOn = !isBig;
         }
-        this.networkHandler.activeNetwork.networkInternal = new vis.Network(container, this.nodeData, options);
+        this.networkHandler.activeNetwork.networkInternal = new vis.Network(
+          container,
+          this.nodeData,
+          options
+        );
 
         if (isBig) {
           resolve(nodes);
         }
-        this.networkHandler.activeNetwork.networkInternal.once('stabilizationIterationsDone', async () => {
-          if (!this.drugstoneConfig.config.physicsOn || this.networkHandler.activeNetwork.isBig()) {
-            this.networkHandler.activeNetwork.updatePhysicsEnabled(false);
+        this.networkHandler.activeNetwork.networkInternal.once(
+          "stabilizationIterationsDone",
+          async () => {
+            if (
+              !this.drugstoneConfig.config.physicsOn ||
+              this.networkHandler.activeNetwork.isBig()
+            ) {
+              this.networkHandler.activeNetwork.updatePhysicsEnabled(false);
+            }
+            this.networkHandler
+              .updateAdjacentNodes(this.networkHandler.activeNetwork.isBig())
+              .then(() => {
+                resolve(nodes);
+              });
           }
-          this.networkHandler.updateAdjacentNodes(this.networkHandler.activeNetwork.isBig()).then(() => {
-            resolve(nodes);
-          });
-        });
+        );
       }).then(() => {
         this.setNetworkListeners();
         this.emitVisibleItems(true);
@@ -363,79 +450,84 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
     });
   }
 
-
   private async refreshTask() {
     this.loadingScreen.stateUpdate(true);
     this.task = await this.getTask(this.token);
     this.analysis.switchSelection(this.token);
 
-    if (this.task.info.algorithm === 'degree') {
+    if (this.task.info.algorithm === "degree") {
       this.tableDrugScoreTooltip =
-        'Normalized number of direct interactions of the drug with the seeds. ' +
-        'The higher the score, the more relevant the drug.';
+        "Normalized number of direct interactions of the drug with the seeds. " +
+        "The higher the score, the more relevant the drug.";
       this.tableProteinScoreTooltip =
-        'Normalized number of direct interactions of the protein with the seeds. ' +
-        'The higher the score, the more relevant the protein.';
-    } else if (this.task.info.algorithm === 'closeness' || this.task.info.algorithm === 'quick' || this.task.info.algorithm === 'super') {
+        "Normalized number of direct interactions of the protein with the seeds. " +
+        "The higher the score, the more relevant the protein.";
+    } else if (
+      this.task.info.algorithm === "closeness" ||
+      this.task.info.algorithm === "quick" ||
+      this.task.info.algorithm === "super"
+    ) {
       this.tableDrugScoreTooltip =
-        'Normalized inverse mean distance of the drug to the seeds. ' +
-        'The higher the score, the more relevant the drug.';
+        "Normalized inverse mean distance of the drug to the seeds. " +
+        "The higher the score, the more relevant the drug.";
       this.tableProteinScoreTooltip =
-        'Normalized inverse mean distance of the protein to the seeds. ' +
-        'The higher the score, the more relevant the protein.';
-    } else if (this.task.info.algorithm === 'trustrank') {
+        "Normalized inverse mean distance of the protein to the seeds. " +
+        "The higher the score, the more relevant the protein.";
+    } else if (this.task.info.algorithm === "trustrank") {
       this.tableDrugScoreTooltip =
-        'Amount of ‘trust’ on the drug at termination of the algorithm. ' +
-        'The higher the score, the more relevant the drug.';
+        "Amount of ‘trust’ on the drug at termination of the algorithm. " +
+        "The higher the score, the more relevant the drug.";
       this.tableProteinScoreTooltip =
-        'Amount of ‘trust’ on the protein at termination of the algorithm. ' +
-        'The higher the score, the more relevant the protein.';
-    } else if (this.task.info.algorithm === 'proximity') {
+        "Amount of ‘trust’ on the protein at termination of the algorithm. " +
+        "The higher the score, the more relevant the protein.";
+    } else if (this.task.info.algorithm === "proximity") {
       this.tableDrugScoreTooltip =
-        'Empirical z-score of mean minimum distance between the drug’s targets and the seeds. ' +
-        'The lower the score, the more relevant the drug.';
+        "Empirical z-score of mean minimum distance between the drug’s targets and the seeds. " +
+        "The lower the score, the more relevant the drug.";
       this.tableProteinScoreTooltip =
-        'Empirical z-score of mean minimum distance between the drug’s targets and the seeds. ' +
-        'The lower the score, the more relevant the drug.';
+        "Empirical z-score of mean minimum distance between the drug’s targets and the seeds. " +
+        "The lower the score, the more relevant the drug.";
     }
 
     if (this.task && this.task.info && this.task.info.done) {
-
       this.loading = true;
-      this.netex.getTaskResult(this.token).then(async result => {
-        if (this.networkHandler.activeNetwork.networkType !== 'analysis') {
+      this.netex.getTaskResult(this.token).then(async (result) => {
+        if (this.networkHandler.activeNetwork.networkType !== "analysis") {
           return;
         }
         this.drugstoneConfig.set_analysisConfig(result.parameters.config);
         this.analysis.switchSelection(this.token);
         this.result = result;
-        if (this.result.parameters.target === 'drug') {
-          this.legendService.add_to_context('drug');
+        if (this.result.parameters.target === "drug") {
+          this.legendService.add_to_context("drug");
         } else {
-          this.legendService.add_to_context('drugTarget');
+          this.legendService.add_to_context("drugTarget");
         }
         const nodeAttributes = this.result.nodeAttributes || {};
-        const analysisNetwork = this.networkHandler.networks['analysis'];
+        const analysisNetwork = this.networkHandler.networks["analysis"];
         analysisNetwork.seedMap = nodeAttributes.isSeed || {};
 
         // Reset
-        this.nodeData = {nodes: null, edges: null};
-        analysisNetwork.networkEl.nativeElement.innerHTML = '';
+        this.nodeData = { nodes: null, edges: null };
+        analysisNetwork.networkEl.nativeElement.innerHTML = "";
         analysisNetwork.networkInternal = null;
         // Create
-        await this.createNetwork(this.result).then(nw => {
+        await this.createNetwork(this.result).then((nw) => {
           return new Promise<any>((resolve, reject) => {
-            if (this.networkHandler.activeNetwork.networkType !== 'analysis') {
+            if (this.networkHandler.activeNetwork.networkType !== "analysis") {
               return;
             }
             const nodes = nw.nodes;
             const edges = nw.edges;
-            analysisNetwork.inputNetwork = {nodes: nodes, edges: edges};
+            analysisNetwork.inputNetwork = { nodes: nodes, edges: edges };
             this.nodeData.nodes = new vis.DataSet(nodes);
             this.nodeData.edges = new vis.DataSet(edges);
             const container = analysisNetwork.networkEl.nativeElement;
             const isBig = nodes.length > 100 || edges.length > 100;
-            const options = NetworkSettings.getOptions(isBig ? 'analysis-big' : 'analysis', this.drugstoneConfig.currentConfig());
+            const options = NetworkSettings.getOptions(
+              isBig ? "analysis-big" : "analysis",
+              this.drugstoneConfig.currentConfig()
+            );
             // @ts-ignore
             options.groups = this.drugstoneConfig.currentConfig().nodeGroups;
             // @ts-ignore
@@ -446,60 +538,94 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
             if (this.drugstoneConfig.config.physicsOn) {
               this.drugstoneConfig.config.physicsOn = !isBig;
             }
-            analysisNetwork.networkInternal = new vis.Network(container, this.nodeData, options);
+            analysisNetwork.networkInternal = new vis.Network(
+              container,
+              this.nodeData,
+              options
+            );
 
             if (isBig) {
               resolve(nodes);
             }
-            analysisNetwork.networkInternal.once('stabilizationIterationsDone', async () => {
-              if (!this.drugstoneConfig.config.physicsOn || analysisNetwork.isBig()) {
-                analysisNetwork.updatePhysicsEnabled(false);
+            analysisNetwork.networkInternal.once(
+              "stabilizationIterationsDone",
+              async () => {
+                if (
+                  !this.drugstoneConfig.config.physicsOn ||
+                  analysisNetwork.isBig()
+                ) {
+                  analysisNetwork.updatePhysicsEnabled(false);
+                }
+                this.networkHandler
+                  .updateAdjacentNodes(analysisNetwork.isBig())
+                  .then(() => {
+                    resolve(nodes);
+                  });
               }
-              this.networkHandler.updateAdjacentNodes(analysisNetwork.isBig()).then(() => {
-                resolve(nodes);
+            );
+          })
+            .then((nodes) => {
+              this.tableDrugs = nodes.filter(
+                (e) => e.drugstoneId && e.drugstoneType === "drug"
+              );
+              this.tableDrugs.forEach((r) => {
+                r.rawScore = r.score;
               });
-            });
-          }).then(nodes => {
-
-            this.tableDrugs = nodes.filter(e => e.drugstoneId && e.drugstoneType === 'drug');
-            this.tableDrugs.forEach((r) => {
-              r.rawScore = r.score;
-            });
-            // @ts-ignore
-            this.tableDrugs.sort((a, b) => b.score - a.score);
-            this.rankTable(this.tableDrugs);
-            this.tableProteins = nodes.filter(e => e.drugstoneId && e.drugstoneType === 'protein');
-            this.tableSelectedProteins = [];
-            this.tableProteins.forEach((r) => {
-              r.rawScore = r.score;
-              r.isSeed = analysisNetwork.seedMap[r.id];
-              const wrapper = getWrapperFromNode(r);
-              if (this.analysis.inSelection(wrapper)) {
-                this.tableSelectedProteins.push(r);
+              // @ts-ignore
+              this.tableDrugs.sort((a, b) => b.score - a.score);
+              this.rankTable(this.tableDrugs);
+              this.tableProteins = nodes.filter(
+                (e) => e.drugstoneId && e.drugstoneType === "protein"
+              );
+              this.tableSelectedProteins = [];
+              this.tableProteins.forEach((r) => {
+                r.rawScore = r.score;
+                r.isSeed = analysisNetwork.seedMap[r.id];
+                const wrapper = getWrapperFromNode(r);
+                if (this.analysis.inSelection(wrapper)) {
+                  this.tableSelectedProteins.push(r);
+                }
+              });
+              this.tableProteins.sort((a, b) => b.score - a.score);
+              this.rankTable(this.tableProteins);
+
+              this.tableHasScores =
+                [
+                  "trustrank",
+                  "closeness",
+                  "degree",
+                  "betweenness",
+                  "quick",
+                  "super",
+                ].indexOf(this.task.info.algorithm) !== -1;
+              if (this.tableHasScores) {
+                this.toggleNormalization(true);
               }
-            });
-            this.tableProteins.sort((a, b) => b.score - a.score);
-            this.rankTable(this.tableProteins);
-
-            this.tableHasScores = ['trustrank', 'closeness', 'degree', 'betweenness', 'quick', 'super']
-              .indexOf(this.task.info.algorithm) !== -1;
-            if (this.tableHasScores) {
-              this.toggleNormalization(true);
-            }
-            analysisNetwork.networkInternal.setData({nodes: undefined, edge: undefined});
-            setTimeout(() => {
-              analysisNetwork.networkInternal.setData(this.nodeData);
-            }, 1000);
-            this.setNetworkListeners();
-            this.emitVisibleItems(true);
-          }).then(() => {
-            if (!['quick', 'super', 'connect', 'connectSelected'].includes(this.task.info.algorithm)) {
-              return;
-            }
-            this.netex.getAlgorithmDefaults(this.task.info.algorithm).then(response => {
-              this.algorithmDefault = response;
-            });
-          }).catch(console.error);
+              analysisNetwork.networkInternal.setData({
+                nodes: undefined,
+                edge: undefined,
+              });
+              setTimeout(() => {
+                analysisNetwork.networkInternal.setData(this.nodeData);
+              }, 1000);
+              this.setNetworkListeners();
+              this.emitVisibleItems(true);
+            })
+            .then(() => {
+              if (
+                !["quick", "super", "connect", "connectSelected"].includes(
+                  this.task.info.algorithm
+                )
+              ) {
+                return;
+              }
+              this.netex
+                .getAlgorithmDefaults(this.task.info.algorithm)
+                .then((response) => {
+                  this.algorithmDefault = response;
+                });
+            })
+            .catch(console.error);
         });
         this.loadingScreen.stateUpdate(false);
       });
@@ -508,7 +634,7 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
 
   private async refresh() {
     if (this.token) {
-      if (this.tokenType === 'view') {
+      if (this.tokenType === "view") {
         this.networkHandler.showSeedsButton = false;
         await this.refreshView();
       } else {
@@ -516,39 +642,47 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
         await this.refreshTask();
       }
     }
-
   }
 
   public emitVisibleItems(on: boolean) {
     if (on) {
-      this.visibleItems.emit([this.nodeData.nodes, [this.proteins, this.selectedTissue], this.nodeData.edges]);
+      this.visibleItems.emit([
+        this.nodeData.nodes,
+        [this.proteins, this.selectedTissue],
+        this.nodeData.edges,
+      ]);
     } else {
       this.visibleItems.emit(null);
     }
   }
 
   private async getView(token: string): Promise<any> {
-    return await this.http.get(`${this.netex.getBackend()}view/?token=${token}`).toPromise();
+    return await this.http
+      .get(`${this.netex.getBackend()}view/?token=${token}`)
+      .toPromise();
   }
 
   private async getTask(token: string): Promise<any> {
-    return await this.http.get(`${this.netex.getBackend()}task/?token=${token}`).toPromise();
+    return await this.http
+      .get(`${this.netex.getBackend()}task/?token=${token}`)
+      .toPromise();
   }
 
   close() {
-    const analysisNetwork = this.networkHandler.networks['analysis'];
+    const analysisNetwork = this.networkHandler.networks["analysis"];
     analysisNetwork.gradientMap = {};
     this.drugstoneConfig.remove_analysisConfig();
     this.expressionExpanded = false;
     this.expressionMap = undefined;
     analysisNetwork.seedMap = {};
     analysisNetwork.highlightSeeds = false;
-    this.analysis.switchSelection('main');
+    this.legendService.networkHasConnector = false;
+    this.analysis.switchSelection("main");
     // this.analysis.resetSelection();
     this.token = null;
     this.tokenChange.emit(this.token);
-    this.legendService.remove_from_context('drug');
-    this.legendService.remove_from_context('drugTarget');
+    this.legendService.remove_from_context("drug");
+    this.legendService.remove_from_context("drugTarget");
     this.emitVisibleItems(false);
   }
 
@@ -557,30 +691,30 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
 
     const normalizeFn = (table) => {
       let max = 0;
-      table.forEach(i => {
+      table.forEach((i) => {
         if (i.rawScore > max) {
           max = i.rawScore;
         }
       });
-      table.forEach(i => {
+      table.forEach((i) => {
         i.score = i.rawScore / max;
       });
     };
 
     const unnormalizeFn = (table) => {
-      table.forEach(i => {
+      table.forEach((i) => {
         i.score = i.rawScore;
       });
     };
 
     if (normalize) {
       normalizeFn(this.tableProteins);
-      if (this.task.info.target === 'drug') {
+      if (this.task.info.target === "drug") {
         normalizeFn(this.tableDrugs);
       }
     } else {
       unnormalizeFn(this.tableProteins);
-      if (this.task.info.target === 'drug') {
+      if (this.task.info.target === "drug") {
         unnormalizeFn(this.tableDrugs);
       }
     }
@@ -595,11 +729,22 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
       }
     });
 
-    if ('score' in data[0]) {
-      data = data.sort((a, b) => b['score'] - a['score']);
+    if ("score" in data[0]) {
+      data = data.sort((a, b) => b["score"] - a["score"]);
     }
 
-    const columns = ['label', 'symbol', 'uniprot', 'ensg', 'entrez', 'proteinName', 'isSeed', 'score', 'rank', 'status'];
+    const columns = [
+      "label",
+      "symbol",
+      "uniprot",
+      "ensg",
+      "entrez",
+      "proteinName",
+      "isSeed",
+      "score",
+      "rank",
+      "status",
+    ];
     downloadCSV(data, columns, `drugstone_${view}`);
   }
 
@@ -609,7 +754,9 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
    * @param result
    * @returns
    */
-  public async createNetwork(result: any): Promise<{ edges: any[]; nodes: any[]; }> {
+  public async createNetwork(
+    result: any
+  ): Promise<{ edges: any[]; nodes: any[] }> {
     const identifier = this.drugstoneConfig.currentConfig().identifier;
 
     // add drugGroup and foundNodesGroup for added nodes
@@ -625,47 +772,84 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
     network.nodes = [...new Set<string>(network.nodes)];
     const details = attributes.details || {};
     const nodeIdMap = {};
+    Object.entries(details)
     // @ts-ignore
-    Object.entries(details).filter(e => e[1].drugstoneType === 'protein').forEach(e => {
-      // @ts-ignore
-      e[1].drugstoneId.forEach(id => {
-        nodeIdMap[id] = e[1][identifier][0];
+      .filter((e) => e[1].drugstoneType === "protein")
+      .forEach((e) => {
+        // @ts-ignore
+        e[1].drugstoneId.forEach((id) => {
+          nodeIdMap[id] = e[1][identifier][0];
+        });
       });
-    });
     for (const nodeId of network.nodes) {
       if (details[nodeId]) {
         const nodeDetails = details[nodeId];
-        nodeDetails.id = nodeDetails.id ? nodeDetails.id : (typeof nodeDetails.drugstoneId === 'string' ? nodeDetails.drugstoneId : nodeDetails.drugstoneId[0]);
-        if (nodeDetails.drugstoneId && nodeDetails.drugstoneType === 'protein') {
+        nodeDetails.id = nodeDetails.id
+          ? nodeDetails.id
+          : typeof nodeDetails.drugstoneId === "string"
+          ? nodeDetails.drugstoneId
+          : nodeDetails.drugstoneId[0];
+        if (
+          nodeDetails.drugstoneId &&
+          nodeDetails.drugstoneType === "protein"
+        ) {
           // node is protein from database, has been mapped on init to backend protein from backend
           // or was found during analysis
           // FIXME connectorNodes are not visualized correctly
-          nodeDetails.group = result.targetNodes && result.targetNodes.indexOf(nodeId) !== -1 ? 'foundNode' : (nodeDetails.group ? nodeDetails.group : 'connectorNode');
-          nodeDetails.label = nodeDetails.label ? nodeDetails.label : nodeDetails[identifier];
-          nodeDetails.id = nodeDetails[identifier][0] ? nodeDetails[identifier][0] : nodeDetails.id;
+          nodeDetails.group =
+            result.targetNodes && result.targetNodes.indexOf(nodeId) !== -1
+              ? "foundNode"
+              : nodeDetails.group
+              ? nodeDetails.group
+              : "connectorNode";
+          nodeDetails.label = nodeDetails.label
+            ? nodeDetails.label
+            : nodeDetails[identifier];
+          nodeDetails.id = nodeDetails[identifier][0]
+            ? nodeDetails[identifier][0]
+            : nodeDetails.id;
           this.proteins.push(nodeDetails);
-        } else if (nodeDetails.drugstoneId && nodeDetails.drugstoneType === 'drug') {
+        } else if (
+          nodeDetails.drugstoneId &&
+          nodeDetails.drugstoneType === "drug"
+        ) {
           // node is drug, was found during analysis
-          nodeDetails.type = 'Drug';
-          nodeDetails.group = 'foundDrug';
+          nodeDetails.type = "Drug";
+          nodeDetails.group = "foundDrug";
         } else {
           // node is custom input from user, could not be mapped to backend protein
-          nodeDetails.group = nodeDetails.group ? nodeDetails.group : 'default';
-          nodeDetails.label = nodeDetails.label ? nodeDetails.label : nodeDetails[identifier];
+          nodeDetails.group = nodeDetails.group ? nodeDetails.group : "default";
+          nodeDetails.label = nodeDetails.label
+            ? nodeDetails.label
+            : nodeDetails[identifier];
         }
         // further analysis and the button function can be used to highlight seeds
         // option to use scores[node] as gradient, but sccores are very small
-        nodes.push(NetworkSettings.getNodeStyle(nodeDetails as Node, this.drugstoneConfig.currentConfig(), false, false, 1, this.networkHandler.activeNetwork.nodeRenderer));
+        nodes.push(
+          NetworkSettings.getNodeStyle(
+            nodeDetails as Node,
+            this.drugstoneConfig.currentConfig(),
+            false,
+            false,
+            1,
+            this.networkHandler.activeNetwork.nodeRenderer
+          )
+        );
       } else {
-        console.log('Missing details for ' + nodeId);
+        console.log("Missing details for " + nodeId);
       }
     }
     const uniqEdges = [];
     for (const edge of network.edges) {
-      const e = mapCustomEdge(edge, this.drugstoneConfig.currentConfig(), this.drugstoneConfig);
-      e.from = e.from[0] === 'p' && nodeIdMap[e.from] ? nodeIdMap[e.from] : e.from;
-      e.to = e.to[0] === 'p' && nodeIdMap[e.to] ? nodeIdMap[e.to] : e.to;
-      const hash = e.from + '_' + e.to;
+      const e = mapCustomEdge(
+        edge,
+        this.drugstoneConfig.currentConfig(),
+        this.drugstoneConfig
+      );
+      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);
         edges.push(e);
@@ -673,24 +857,35 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
     }
     // remove self-edges/loops
     if (!this.drugstoneConfig.currentConfig().selfReferences) {
-      edges = edges.filter(el => el.from !== el.to);
+      edges = edges.filter((el) => el.from !== el.to);
     }
-    return {
+
+    this.legendService.networkHasConnector =
+      nodes.filter((node) => node.group === "connectorNode").length > 0;
+
+      return {
       nodes,
       edges,
     };
   }
 
   getResultNodes() {
-    if (this.nodeData && this.nodeData['nodes']) {
-      return this.nodeData['nodes'].get();
+    if (this.nodeData && this.nodeData["nodes"]) {
+      return this.nodeData["nodes"].get();
     }
     return [];
   }
 
   getResultEdges() {
-    if (this.nodeData && this.nodeData['edges']) {
-      return this.nodeData['edges'].get().filter(e => !e.id || !e.groupName || (typeof e.from === 'string' && typeof e.to === 'string'));
+    if (this.nodeData && this.nodeData["edges"]) {
+      return this.nodeData["edges"]
+        .get()
+        .filter(
+          (e) =>
+            !e.id ||
+            !e.groupName ||
+            (typeof e.from === "string" && typeof e.to === "string")
+        );
     }
     return [];
   }
@@ -728,5 +923,4 @@ export class AnalysisPanelComponent implements OnInit, OnChanges, AfterViewInit
   public openBugreport() {
     this.drugstoneConfig.showBugreport = true;
   }
-
 }
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 7db97954..8dbafa89 100644
--- a/src/app/components/network/network-legend/network-legend.component.ts
+++ b/src/app/components/network/network-legend/network-legend.component.ts
@@ -1,38 +1,37 @@
-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";
-import { NetworkHandlerService } from 'src/app/services/network-handler/network-handler.service';
+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";
+import { NetworkHandlerService } from "src/app/services/network-handler/network-handler.service";
 
 @Component({
-  selector: 'app-network-legend',
-  templateUrl: './network-legend.component.html',
-  styleUrls: ['./network-legend.component.scss']
+  selector: "app-network-legend",
+  templateUrl: "./network-legend.component.html",
+  styleUrls: ["./network-legend.component.scss"],
 })
 export class NetworkLegendComponent implements OnInit {
-
-  _context = 'explorer';
+  _context = "explorer";
   _emptyEdgeConfig = false;
-  @Input() set context (value: LegendContext) {
-    this._context = value
+  @Input() set context(value: LegendContext) {
+    this._context = value;
     this._emptyEdgeConfig = this.checkIfEdgeConfigEmpty();
-  };
+  }
   @Input() config: IConfig;
 
   private contextEdgeGroupsToDelete = {
-    'explorer': ['default'],
-    'adjacentDrugs': ['default'],
-    'adjacentDisorders': ['default'],
-    'adjacentDrugsAndDisorders' :['default'],
-    'drugTarget': ['default'],
-    'drug': ['default'],
-    'drugTargetAndSeeds': ['default'],
-    'drugAndSeeds': ['default']
-  }
+    explorer: ["default"],
+    adjacentDrugs: ["default"],
+    adjacentDisorders: ["default"],
+    adjacentDrugsAndDisorders: ["default"],
+    drugTarget: ["default"],
+    drug: ["default"],
+    drugTargetAndSeeds: ["default"],
+    drugAndSeeds: ["default"],
+  };
 
   public checkNodeGroupContext(nodeGroupKey) {
-    if (nodeGroupKey === 'selectedNode') {
+    if (nodeGroupKey === "selectedNode") {
       // selected node is not supposed to appear in legend
       return false;
     }
@@ -40,16 +39,22 @@ export class NetworkLegendComponent implements OnInit {
   }
 
   public checkEdgeGroupContext(edgeGroupKey) {
-    return !this.contextEdgeGroupsToDelete[this._context].includes(edgeGroupKey);
+    return !this.contextEdgeGroupsToDelete[this._context].includes(
+      edgeGroupKey
+    );
   }
 
   public checkIfEdgeConfigEmpty() {
-    return Object.keys(this.config.edgeGroups).some(key => this.checkEdgeGroupContext(key));
+    return Object.keys(this.config.edgeGroups).some((key) =>
+      this.checkEdgeGroupContext(key)
+    );
   }
 
-  constructor(public drugstoneConfig: DrugstoneConfigService, public legendService: LegendService, public networkHandler: NetworkHandlerService) { }
-
-  ngOnInit(): void {
-  }
+  constructor(
+    public drugstoneConfig: DrugstoneConfigService,
+    public legendService: LegendService,
+    public networkHandler: NetworkHandlerService
+  ) {}
 
+  ngOnInit(): void {}
 }
diff --git a/src/app/services/legend-service/legend-service.service.ts b/src/app/services/legend-service/legend-service.service.ts
index a883f0dd..cd651ba9 100644
--- a/src/app/services/legend-service/legend-service.service.ts
+++ b/src/app/services/legend-service/legend-service.service.ts
@@ -11,6 +11,7 @@ export class LegendService {
 
   private default_delete = ['foundNode', 'foundDrug', 'seedNode', 'default', 'defaultDisorder', 'connectorNode'];
   private context = [];
+  public networkHasConnector = false;
 
   private contextNodeGroupsToDelete = {
     adjacentDrugs: ['foundNode', 'seedNode', 'default', 'defaultDisorder', 'connectorNode'],
@@ -41,6 +42,12 @@ export class LegendService {
     const out = [].concat(this.default_delete);
     for (const node of this.default_delete) {
       let keep = false;
+      
+      // delete connectorNodes if network does not contain any 
+      if (node === 'connectorNode' && !this.networkHasConnector) {
+        break;
+      }
+
       for (const c of this.context) {
         if (this.contextNodeGroupsToDelete[c].indexOf(node) === -1) {
           keep = true;
diff --git a/src/index.html b/src/index.html
index c25ff979..f21e306c 100644
--- a/src/index.html
+++ b/src/index.html
@@ -115,7 +115,7 @@ menu<br>
    <!-- task-id="ks38WxeCSdbXk2cajKACinnUnCHWbf4I" -->
   <drugst-one id="netexp1"
               groups='{"nodeGroups":{"important":{"type":"gene","color":"#ff881f","font":{"color":"#000000"},"groupName":"Seed","shape":"star"},"gene":{"type":"gene","color":"#4da300","font":{"color":"#f0f0f0"},"groupName":"Discovered target","shape":"circle"},"foundDrug":{"type":"drug","color":"#F12590","font":{"color":"#000000"},"groupName":"Drug","shape":"diamond"}},"edgeGroups":{"default":{"color":"#000000","groupName":"default edge"}}}'
-              config='{"customEdges":{"default":true, "selectable":false}, "showAdvAnalysisContent":["drug-search", "enrichment-gprofiler", "enrichment-digest", "search-ndex"],"identifier":"symbol","title":"ROBUST output network", "taskDrugName": "Drug Search", "showLegendNodes": true, "showLegendEdges": true, "showSidebar": "left", "showOverview": true, "legendPos": "left", "legendClass": "legend", "showQuery": true, "showItemSelector": true,"showSimpleAnalysis": false,"showAdvAnalysis": true,"showSelection": true,"showTasks": true,"showNetworkMenu": "right","showLegend": true,"showNetworkMenuButtonExpression": true, "showNetworkMenuButtonScreenshot": true,"showNetworkMenuButtonExportGraphml": true,"showNetworkMenuButtonAdjacentDrugs": true,"showNetworkMenuButtonCenter": true,"showConnectGenes": false,"networkMenuButtonAdjacentDrugsLabel": "Drugs","showNetworkMenuButtonAdjacentDisordersProteins": true,"networkMenuButtonAdjacentDisordersProteinsLabel": "Disorders (protein)","showNetworkMenuButtonAdjacentDisordersDrugs": true,"networkMenuButtonAdjacentDisordersDrugsLabel": "Disorders (drug)","showNetworkMenuButtonAnimation": true,"networkMenuButtonAnimationLabel": "Animation", "autofillEdges": false, "physicsOn": false,"useNedrexLicenced": true,"selfReferences": false, "interactionDrugProtein": "NeDRex", "indicationDrugDisorder": "NeDRex","nodeShadow": true,"edgeShadow": true, "algorithms": {"drug": ["trustrank", "closeness", "degree", "proximity"], "drug-target": ["trustrank", "multisteiner", "keypathwayminer", "degree", "closeness", "betweenness"]}, "associatedProteinDisorder": "NeDRex",                                "nodeGroups":{"important":{"type":"gene","color":"#ff881f","font":{"color":"#000000"},"groupName":"Seed","shape":"star"},"gene":{"type":"gene","color":"#4da300","font":{"color":"#f0f0f0"},"groupName":"Discovered target","shape":"circle"},"foundDrug":{"type":"drug","color":"#F12590","font":{"color":"#000000"},"groupName":"Drug","shape":"diamond"}},"edgeGroups":{"default":{"color":"#000000","groupName":"default edge"}}}'
+              config='{"customEdges":{"default":true, "selectable":false}, "showAdvAnalysisContent":["drug-search", "drug-target-search", "enrichment-gprofiler", "enrichment-digest", "search-ndex"],"identifier":"symbol","title":"ROBUST output network", "taskDrugName": "Drug Search", "showLegendNodes": true, "showLegendEdges": true, "showSidebar": "left", "showOverview": true, "legendPos": "left", "legendClass": "legend", "showQuery": true, "showItemSelector": true,"showSimpleAnalysis": false,"showAdvAnalysis": true,"showSelection": true,"showTasks": true,"showNetworkMenu": "right","showLegend": true,"showNetworkMenuButtonExpression": true, "showNetworkMenuButtonScreenshot": true,"showNetworkMenuButtonExportGraphml": true,"showNetworkMenuButtonAdjacentDrugs": true,"showNetworkMenuButtonCenter": true,"showConnectGenes": false,"networkMenuButtonAdjacentDrugsLabel": "Drugs","showNetworkMenuButtonAdjacentDisordersProteins": true,"networkMenuButtonAdjacentDisordersProteinsLabel": "Disorders (protein)","showNetworkMenuButtonAdjacentDisordersDrugs": true,"networkMenuButtonAdjacentDisordersDrugsLabel": "Disorders (drug)","showNetworkMenuButtonAnimation": true,"networkMenuButtonAnimationLabel": "Animation", "autofillEdges": false, "physicsOn": false,"useNedrexLicenced": true,"selfReferences": false, "interactionDrugProtein": "NeDRex", "indicationDrugDisorder": "NeDRex","nodeShadow": true,"edgeShadow": true, "algorithms": {"drug": ["trustrank", "closeness", "degree", "proximity"], "drug-target": ["trustrank", "multisteiner", "keypathwayminer", "degree", "closeness", "betweenness"]}, "associatedProteinDisorder": "NeDRex",                                "nodeGroups":{"important":{"type":"gene","color":"#ff881f","font":{"color":"#000000"},"groupName":"Seed","shape":"star"},"gene":{"type":"gene","color":"#4da300","font":{"color":"#f0f0f0"},"groupName":"Discovered target","shape":"circle"},"foundDrug":{"type":"drug","color":"#F12590","font":{"color":"#000000"},"groupName":"Drug","shape":"diamond"}},"edgeGroups":{"default":{"color":"#000000","groupName":"default edge"}}}'
               network='{"nodes": [{"id": "DEFA1", "group": "gene"},{"id": "DEFA1", "group": "gene"}, {"id": "CST6", "group": "gene"}, {"id": "IGFBP2", "group": "gene"}, {"id": "TNFSF8", "group": "gene"}, {"id": "COPRS", "group": "gene"}, {"id": "AGT", "group": "important"}, {"id": "IL6", "group": "important"}, {"id": "A2M", "group": "gene"}, {"id": "NLRP3", "group": "important"}, {"id": "TLR4", "group": "important"}, {"id": "TNFSF9", "group": "gene"}, {"id": "RPL18", "group": "gene"}, {"id": "F5", "group": "gene"}, {"id": "IVL", "group": "gene"}, {"id": "IL6R", "group": "gene"}, {"id": "CPB2", "group": "gene"}, {"id": "CCDC8", "group": "gene"}, {"id": "SERPINB6", "group": "gene"}, {"id": "MBL2", "group": "important"}, {"id": "IL1B", "group": "important"}, {"id": "HIST1H3E", "group": "gene"}, {"id": "IL24", "group": "gene"}, {"id": "GSDMB", "group": "gene"}, {"id": "NOTCH2", "group": "gene"}, {"id": "F2", "group": "important"}, {"id": "CCR5", "group": "important"}, {"id": "SERPINB8", "group": "gene"}, {"id": "KRT1", "group": "gene"}, {"id": "IL1RN", "group": "important"}, {"id": "PLAT", "group": "gene"}, {"id": "URB1", "group": "gene"}, {"id": "FCF1", "group": "gene"}, {"id": "ACE", "group": "important"}, {"id": "THBS3", "group": "gene"}, {"id": "CALML3", "group": "gene"}, {"id": "PSMA5", "group": "gene"}, {"id": "NDUFA3", "group": "gene"}, {"id": "PARK2", "group": "gene"}, {"id": "FANCB", "group": "gene"}, {"id": "SERPINB2", "group": "gene"}, {"id": "KLRG2", "group": "gene"}, {"id": "FAM19A3", "group": "gene"}, {"id": "CRYZL1", "group": "gene"}, {"id": "HEATR1", "group": "gene"}, {"id": "IGHG2", "group": "gene"}, {"id": "C17orf70", "group": "gene"}, {"id": "TINAG", "group": "gene"}, {"id": "RSPRY1", "group": "gene"}, {"id": "TMPRSS11A", "group": "gene"}, {"id": "SLC18A1", "group": "gene"}, {"id": "PSMD1", "group": "gene"}, {"id": "PCDHB15", "group": "gene"}, {"id": "TSR3", "group": "gene"}, {"id": "FGL1", "group": "gene"}, {"id": "C7orf60", "group": "gene"}, {"id": "SSR3", "group": "gene"}, {"id": "REN", "group": "gene"}, {"id": "MYH14", "group": "gene"}, {"id": "TBCK", "group": "gene"}, {"id": "DARS", "group": "gene"}, {"id": "C16orf70", "group": "gene"}, {"id": "DQX1", "group": "gene"}, {"id": "RPL30", "group": "gene"}, {"id": "FBXO30", "group": "gene"}, {"id": "EPPK1", "group": "gene"}, {"id": "LAMA1", "group": "gene"}, {"id": "AP4E1", "group": "gene"}, {"id": "AP4S1", "group": "gene"}, {"id": "HIST1H1B", "group": "gene"}, {"id": "AFP", "group": "gene"}], "edges": [{"from": "DEFA1", "to": "PLAT", "group": "default"}, {"from": "DEFA1", "to": "IGFBP2", "group": "default"}, {"from": "CST6", "to": "FCF1", "group": "default"}, {"from": "CST6", "to": "NOTCH2", "group": "default"}, {"from": "IGFBP2", "to": "GSDMB", "group": "default"}, {"from": "TNFSF8", "to": "F5", "group": "default"}, {"from": "TNFSF8", "to": "TNFSF9", "group": "default"}, {"from": "COPRS", "to": "HIST1H3E", "group": "default"}, {"from": "COPRS", "to": "IL6R", "group": "default"}, {"from": "AGT", "to": "ACE", "group": "default"}, {"from": "AGT", "to": "GSDMB", "group": "default"}, {"from": "AGT", "to": "NDUFA3", "group": "default"}, {"from": "AGT", "to": "REN", "group": "default"}, {"from": "IL6", "to": "IL6R", "group": "default"}, {"from": "A2M", "to": "IL1B", "group": "default"}, {"from": "A2M", "to": "CPB2", "group": "default"}, {"from": "NLRP3", "to": "URB1", "group": "default"}, {"from": "NLRP3", "to": "HIST1H1B", "group": "default"}, {"from": "TLR4", "to": "TNFSF9", "group": "default"}, {"from": "TNFSF9", "to": "KLRG2", "group": "default"}, {"from": "RPL18", "to": "FCF1", "group": "default"}, {"from": "RPL18", "to": "URB1", "group": "default"}, {"from": "F5", "to": "F2", "group": "default"}, {"from": "F5", "to": "CCDC8", "group": "default"}, {"from": "F5", "to": "KLRG2", "group": "default"}, {"from": "IVL", "to": "FCF1", "group": "default"}, {"from": "IVL", "to": "KRT1", "group": "default"}, {"from": "IL6R", "to": "FANCB", "group": "default"}, {"from": "IL6R", "to": "CRYZL1", "group": "default"}, {"from": "IL6R", "to": "C17orf70", "group": "default"}, {"from": "IL6R", "to": "TBCK", "group": "default"}, {"from": "CPB2", "to": "F2", "group": "default"}, {"from": "CPB2", "to": "TINAG", "group": "default"}, {"from": "CCDC8", "to": "HEATR1", "group": "default"}, {"from": "CCDC8", "to": "PSMD1", "group": "default"}, {"from": "CCDC8", "to": "DARS", "group": "default"}, {"from": "SERPINB6", "to": "F2", "group": "default"}, {"from": "SERPINB6", "to": "SERPINB8", "group": "default"}, {"from": "SERPINB6", "to": "TMPRSS11A", "group": "default"}, {"from": "SERPINB6", "to": "C16orf70", "group": "default"}, {"from": "MBL2", "to": "KRT1", "group": "default"}, {"from": "IL24", "to": "NOTCH2", "group": "default"}, {"from": "IL24", "to": "CCR5", "group": "default"}, {"from": "F2", "to": "PLAT", "group": "default"}, {"from": "CCR5", "to": "PSMA5", "group": "default"}, {"from": "CCR5", "to": "AFP", "group": "default"}, {"from": "SERPINB8", "to": "FCF1", "group": "default"}, {"from": "IL1RN", "to": "FCF1", "group": "default"}, {"from": "PLAT", "to": "SERPINB2", "group": "default"}, {"from": "PLAT", "to": "FGL1", "group": "default"}, {"from": "PLAT", "to": "LAMA1", "group": "default"}, {"from": "FCF1", "to": "CALML3", "group": "default"}, {"from": "FCF1", "to": "SERPINB2", "group": "default"}, {"from": "FCF1", "to": "IGHG2", "group": "default"}, {"from": "FCF1", "to": "MYH14", "group": "default"}, {"from": "FCF1", "to": "RPL30", "group": "default"}, {"from": "FCF1", "to": "EPPK1", "group": "default"}, {"from": "THBS3", "to": "NDUFA3", "group": "default"}, {"from": "THBS3", "to": "FANCB", "group": "default"}, {"from": "CALML3", "to": "PARK2", "group": "default"}, {"from": "PSMA5", "to": "PARK2", "group": "default"}, {"from": "PSMA5", "to": "HEATR1", "group": "default"}, {"from": "PSMA5", "to": "PSMD1", "group": "default"}, {"from": "PSMA5", "to": "DARS", "group": "default"}, {"from": "NDUFA3", "to": "SLC18A1", "group": "default"}, {"from": "NDUFA3", "to": "DQX1", "group": "default"}, {"from": "FAM19A3", "to": "CRYZL1", "group": "default"}, {"from": "RSPRY1", "to": "TMPRSS11A", "group": "default"}, {"from": "RSPRY1", "to": "SLC18A1", "group": "default"}, {"from": "PCDHB15", "to": "SSR3", "group": "default"}, {"from": "PCDHB15", "to": "TBCK", "group": "default"}, {"from": "TSR3", "to": "FGL1", "group": "default"}, {"from": "TSR3", "to": "C7orf60", "group": "default"}, {"from": "C7orf60", "to": "REN", "group": "default"}, {"from": "SSR3", "to": "MYH14", "group": "default"}, {"from": "C16orf70", "to": "FBXO30", "group": "default"}, {"from": "DQX1", "to": "FBXO30", "group": "default"}, {"from": "LAMA1", "to": "AP4E1", "group": "default"}, {"from": "AP4E1", "to": "AP4S1", "group": "default"}, {"from": "AP4S1", "to": "AFP", "group": "default"}]}'>
   </drugst-one>
 
-- 
GitLab