diff --git a/package-lock.json b/package-lock.json
index 4adaa3400e0235b5616c42f4ce640da9bcd340e5..590d8325c0e7b0f6a8a4d12cda535b7cfc9be314 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3130,6 +3130,16 @@
       "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
       "dev": true
     },
+    "bindings": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "file-uri-to-path": "1.0.0"
+      }
+    },
     "bl": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
@@ -5498,6 +5508,13 @@
         "escape-string-regexp": "^1.0.5"
       }
     },
+    "file-uri-to-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+      "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+      "dev": true,
+      "optional": true
+    },
     "fill-range": {
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@@ -8277,6 +8294,13 @@
       "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
       "dev": true
     },
+    "nan": {
+      "version": "2.14.2",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
+      "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
+      "dev": true,
+      "optional": true
+    },
     "nanoid": {
       "version": "3.1.23",
       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
@@ -14048,7 +14072,11 @@
           "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
           "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
           "dev": true,
-          "optional": true
+          "optional": true,
+          "requires": {
+            "bindings": "^1.5.0",
+            "nan": "^2.12.1"
+          }
         },
         "glob-parent": {
           "version": "3.1.0",
diff --git a/src/app/components/analysis-panel/analysis-panel.component.html b/src/app/components/analysis-panel/analysis-panel.component.html
index a38369d2e87f3782d3b74fa86c91cacbc81a60d8..313c541f169ca8fb298780bebc838cdba634d034 100644
--- a/src/app/components/analysis-panel/analysis-panel.component.html
+++ b/src/app/components/analysis-panel/analysis-panel.component.html
@@ -127,7 +127,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" [analysis]="false"></app-network-legend>
+            <app-network-legend [config]="myConfig" [analysis]="true"></app-network-legend>
           </div>
           <div class="fullheight center image1" #network>
             <button class="button is-loading center">Loading</button>
@@ -180,7 +180,9 @@
             <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':smallStyle}"
+                      pTooltip="Tissue expression data is provided by the GTEx project." tooltipPosition="top"
+                      >
                 <div [ngClass]="{'text-small':smallStyle}">
                   <span *ngIf="!selectedTissue">Tissue</span>
                   <span *ngIf="selectedTissue">{{selectedTissue.name}}</span>
@@ -212,9 +214,10 @@
           </div>
 
           <app-toggle *ngIf="task.info.target === 'drug-target'" class="footer-buttons" textOn="Drugs On" textOff="Off"
-                      tooltipOn="Display drugs in the network" tooltipOff="Hide drugs in the network"
-                      [smallStyle]="smallStyle"
-                      [value]="showDrugs" (valueChange)="toggleDrugs($event)"></app-toggle>
+                tooltipOn="Display adjacent drugs ON."
+                tooltipOff="Display adjacent drugs OFF."
+                [smallStyle]="smallStyle"
+                [value]="adjacentDrugs" (valueChange)="updateAdjacentDrugs($event)"></app-toggle>
 
           <app-toggle class="footer-buttons" textOn="Animation On" textOff="Off"
                       tooltipOn="Enable the network animation."
diff --git a/src/app/components/analysis-panel/analysis-panel.component.ts b/src/app/components/analysis-panel/analysis-panel.component.ts
index a62795cf7d3e57e15190c91e9ed8ca3ac94afb96..c51e633d78e148bef4b3d65ee3eb86c6e60850ed 100644
--- a/src/app/components/analysis-panel/analysis-panel.component.ts
+++ b/src/app/components/analysis-panel/analysis-panel.component.ts
@@ -9,18 +9,15 @@ import {
   SimpleChanges,
   ViewChild,
 } from '@angular/core';
-import {HttpClient, HttpErrorResponse} from '@angular/common/http';
+import {HttpClient} from '@angular/common/http';
 import {environment} from '../../../environments/environment';
 import {algorithmNames, AnalysisService} from '../../services/analysis/analysis.service';
 import {
   Drug,
   EdgeType,
-  getNodeIdsFromPDI,
-  getNodeIdsFromPPI,
+  getDrugNodeId,
   getProteinNodeId,
-  getWrapperFromDrug,
   getWrapperFromNode,
-  getWrapperFromProtein,
   Node,
   Task,
   Tissue,
@@ -31,6 +28,7 @@ import {toast} from 'bulma-toast';
 import {NetworkSettings} from '../../network-settings';
 import {NetexControllerService} from 'src/app/services/netex-controller/netex-controller.service';
 import {defaultConfig, IConfig} from 'src/app/config';
+import { mapCustomEdge, mapCustomNode } from 'src/app/main-network';
 
 
 declare var vis: any;
@@ -85,6 +83,10 @@ export class AnalysisPanelComponent implements OnInit, OnChanges {
   public tab: 'meta' | 'network' | 'table' = 'table';
   public physicsEnabled = true;
 
+  public adjacentDrugs = false;
+  public adjacentDrugList: Node[] = [];
+  public adjacentDrugEdgesList: Node[] = [];
+
   private proteins: any;
   public effects: any;
 
@@ -427,6 +429,12 @@ export class AnalysisPanelComponent implements OnInit, OnChanges {
    */
   public createNetwork(result: any): { edges: any[], nodes: any[] } {
     const config = result.parameters.config;
+    this.myConfig = config;
+
+    console.log(config)
+    console.log('config')
+
+    const identifier = this.myConfig.identifier;
 
     // add drugGroup and foundNodesGroup for added nodes
     // these groups can be overwritten by the user
@@ -443,30 +451,36 @@ export class AnalysisPanelComponent implements OnInit, OnChanges {
     const isSeed = attributes.isSeed || {};
     const scores = attributes.scores || {};
     const details = attributes.details || {};
-    const wrappers: { [key: string]: Wrapper } = {};
 
     for (const node of network.nodes) {
       // convert id to netex Id if exists
       const nodeDetails = details[node];
+
+      nodeDetails.id = nodeDetails.id ? nodeDetails.id : nodeDetails.netexId;
       if (nodeDetails.netexId && nodeDetails.netexId.startsWith('p')) {
         // node is protein from database, has been mapped on init to backend protein from backend
         // or was found during analysis
+        nodeDetails.group = nodeDetails.group ? nodeDetails.group : 'foundNode';
+        nodeDetails.label = nodeDetails.label ? nodeDetails.label : nodeDetails[identifier];
         this.proteins.push(nodeDetails);
-        wrappers[node] = getWrapperFromProtein(nodeDetails as Node);
       } else if (nodeDetails.netexId && nodeDetails.netexId.startsWith('d')) {
         // node is drug, was found during analysis
-        wrappers[node] = getWrapperFromDrug(nodeDetails as Drug);
+        nodeDetails.type = 'Drug';
+        nodeDetails.group = 'foundDrug';
       } else {
         // node is custom input from user, could not be mapped to backend protein
-        wrappers[node] = getWrapperFromNode(nodeDetails as Node);
+        nodeDetails.group = nodeDetails.group ? nodeDetails.group : 'default';
+        nodeDetails.label = nodeDetails.label ? nodeDetails.label : nodeDetails[identifier]
       }
       // IMPORTANT we set seeds to "selected" and not to seeds. The user should be inspired to run 
       // 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(wrappers[node].data as Node, config, false, isSeed[node], 1))
+      nodes.push(NetworkSettings.getNodeStyle(nodeDetails as Node, config, false, isSeed[node], 1))
     }
+    console.log('nodes')
+    console.log(nodes)
     for (const edge of network.edges) {
-      edges.push(this.mapEdge(edge, this.inferEdgeGroup(edge), wrappers));
+      edges.push(mapCustomEdge(edge, this.myConfig));
     }
     return {
       nodes,
@@ -474,80 +488,28 @@ export class AnalysisPanelComponent implements OnInit, OnChanges {
     };
   }
 
-  private mapEdge(edge: any, type: 'protein-protein' | 'protein-drug', wrappers?: { [key: string]: Wrapper }): any {
-    let edgeColor;
-    if (type === 'protein-protein') {
-      edgeColor = {
-        color: NetworkSettings.getColor('edgeGeneGene'),
-        highlight: NetworkSettings.getColor('edgeGeneGeneHighlight'),
-      };
-      const {from, to} = getNodeIdsFromPPI(edge, wrappers);
-      return {
-        from, to,
-        color: edgeColor,
-      };
-    } else if (type === 'protein-drug') {
-      edgeColor = {
-        color: NetworkSettings.getColor('edgeHostDrug'),
-        highlight: NetworkSettings.getColor('edgeHostDrugHighlight'),
-      };
-      const {from, to} = getNodeIdsFromPDI(edge);
-      return {
-        from, to,
-        color: edgeColor,
-      };
-    }
-  }
-
-  public async toggleDrugs(bool: boolean) {
-    this.showDrugs = bool;
-    this.nodeData.nodes.remove(this.drugNodes);
-    this.nodeData.edges.remove(this.drugEdges);
-    this.drugNodes = [];
-    this.drugEdges = [];
-    if (this.showDrugs) {
-      const result = await this.http.get<any>(
-        `${environment.backend}drug_interactions/?token=${this.token}`).toPromise().catch(
-        (err: HttpErrorResponse) => {
-          // simple logging, but you can do a lot more, see below
-          toast({
-            message: 'An error occured while fetching the drugs.',
-            duration: 5000,
-            dismissible: true,
-            pauseOnHover: true,
-            type: 'is-danger',
-            position: 'top-center',
-            animate: {in: 'fadeIn', out: 'fadeOut'}
-          });
-          this.showDrugs = false;
-          return;
-        });
-
-      const drugs = result.drugs;
-      const edges = result.edges;
-
-      if (drugs.length === 0) {
-        toast({
-          message: 'No drugs found.',
-          duration: 5000,
-          dismissible: true,
-          pauseOnHover: true,
-          type: 'is-warning',
-          position: 'top-center',
-          animate: {in: 'fadeIn', out: 'fadeOut'}
-        });
-      } else {
-        // for (const drug of drugs) {
-        //   this.drugNodes.push(this.mapNode(config, 'drug', drug, false, null));
-        // }
 
-        for (const interaction of edges) {
-          const edge = {from: interaction.uniprotAc, to: interaction.drugId};
-          this.drugEdges.push(this.mapEdge(edge, 'protein-drug'));
-        }
-        this.nodeData.nodes.add(Array.from(this.drugNodes.values()));
-        this.nodeData.edges.add(Array.from(this.drugEdges.values()));
-      }
+  public updateAdjacentDrugs(bool: boolean) {
+    this.adjacentDrugs = bool;
+    if (this.adjacentDrugs) {
+        this.netex.adjacentDrugs(this.myConfig.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));
+          }
+          for (const drug of response.drugs) {
+            drug.group = 'foundDrug';
+            drug.id = getDrugNodeId(drug)
+            this.adjacentDrugList.push(mapCustomNode(drug, this.myConfig))
+          }
+          this.nodeData.nodes.add(this.adjacentDrugList);
+          this.nodeData.edges.add(this.adjacentDrugEdgesList);
+      })
+    } else {
+      this.nodeData.nodes.remove(this.adjacentDrugList);
+      this.nodeData.edges.remove(this.adjacentDrugEdgesList);
+      this.adjacentDrugList = [];
+      this.adjacentDrugEdgesList = [];
     }
   }
 
diff --git a/src/app/components/network-legend/network-legend.component.ts b/src/app/components/network-legend/network-legend.component.ts
index 64984b1ab62a0315250b000c8864ffee875ab5fa..10bdb07d08babfc97da52b6c2fff39075b855361 100644
--- a/src/app/components/network-legend/network-legend.component.ts
+++ b/src/app/components/network-legend/network-legend.component.ts
@@ -13,6 +13,7 @@ export class NetworkLegendComponent implements OnInit {
   @Input() set config(value: IConfig) {
     // copy to not override user config
     value = JSON.parse(JSON.stringify(value));
+    // remove selected node group since it is just a border
     delete value.nodeGroups.selectedNode;
     if (!this.analysis) {
       // do not show the analysis-groups in the explorer network
diff --git a/src/app/interfaces.ts b/src/app/interfaces.ts
index 69fcc9a373d69b04f97b68e66d272138615f66c2..f7c46aa3bea2f9580438db58eb4e7ef9995c9fec 100644
--- a/src/app/interfaces.ts
+++ b/src/app/interfaces.ts
@@ -110,10 +110,6 @@ export function getDrugNodeId(drug: Drug) {
   return drug.netexId
 }
 
-export function getDrugBackendId(drug: Drug) {
-  return drug.netexId;
-}
-
 export function getNodeId(node: Node) {
   /**
    * Returns backend_id of Gene object
@@ -130,7 +126,7 @@ export function getNetworkId(node: Node) {
   /**
    * Returns ID of a network node
    */
-  return node.id
+  return node.netexId
 }
 
 export function getId(gene: Node) {
@@ -140,19 +136,6 @@ export function getId(gene: Node) {
   return `${gene.id}`;
 }
 
-export function getWrapperFromProtein(gene: Node): Wrapper {
-  /**
-   * Constructs wrapper interface for gene
-   */
-  // if node does not have property group, it was found by the analysis
-  gene.group = gene.group ? gene.group : 'foundNode';
-  gene.label = gene.label ? gene.label : gene.id
-  return {
-    id: getNetworkId(gene),
-    data: gene,
-  };
-}
-
 export function getWrapperFromNode(gene: Node): Wrapper {
   /**
    * Constructs wrapper interface for gene
@@ -161,22 +144,11 @@ export function getWrapperFromNode(gene: Node): Wrapper {
   gene.group = gene.group ? gene.group : 'default';
   gene.label = gene.label ? gene.label : gene.id
   return {
-    id: getNetworkId(gene),
+    id: gene.id,
     data: gene,
   };
 }
 
-
-export function getWrapperFromDrug(drug: Drug): Wrapper {
-  // set type and group
-  drug.type = 'Drug';
-  drug.group = 'foundDrug';
-  return {
-    id: getDrugNodeId(drug),
-    data: drug,
-  };
-}
-
 export type EdgeType = 'protein-protein' | 'protein-drug';
 
 export interface Wrapper {
diff --git a/src/app/main-network.ts b/src/app/main-network.ts
index 052d040b9cb9ab8089cf53f12e4527b0d2799837..c66def70730a5c648b338f6f9faecbf1906d1581 100644
--- a/src/app/main-network.ts
+++ b/src/app/main-network.ts
@@ -43,71 +43,16 @@ export class ProteinNetwork {
     });
   }
 
-  /** Maps user input node to network node object
-   * If user input node has no group, fall back to default
-   * If user input node has group that is not defined, throw error
-   * 
-   * @param customNode 
-   * @param config 
-   * @returns 
-   */
-  public mapCustomNode(customNode: any, config: IConfig): Node {
-    let node;
-    if (customNode.group === undefined) {
-      // fallback to default node
-      node = JSON.parse(JSON.stringify(defaultConfig.nodeGroups.default));
-      node.group = 'default'
-    } else {
-      if (config.nodeGroups[customNode.group] === undefined) {
-        throw `Node with id ${customNode.id} has undefined node group ${customNode.group}.`
-      }
-      // copy
-      node = JSON.parse(JSON.stringify(config.nodeGroups[customNode.group]));
-    }
-    // update the node with custom node properties, including values fetched from backend
-    node = merge(node, customNode)
-    // label is only used for network visualization
-    node.label = customNode.label ? customNode.label : customNode.id;
-    return node;
-  }
-
-  /** Maps user input edge to network edge object
-   * If user input edge has no group, fall back to default
-   * If user input edge has group that is not defined, throw error
-   * 
-   * @param customEdge 
-   * @param config 
-   * @returns 
-   */
-  public mapCustomEdge(customEdge: NodeInteraction, config: IConfig): any {
-    let edge;
-    if (customEdge.group === undefined) {
-      // fallback to default node
-      edge = JSON.parse(JSON.stringify(defaultConfig.edgeGroups.default));
-    } else {
-      if (config.edgeGroups[customEdge.group] === undefined) {
-        throw `Edge "from ${customEdge.from}" - "to ${customEdge.to}" has undefined edge group ${customEdge.group}.`
-      }
-      // copy
-      edge = JSON.parse(JSON.stringify(config.edgeGroups[customEdge.group]));
-    }
-    edge = {
-      ...edge,
-      ...customEdge
-    }
-    return edge;
-  }
-
   public mapDataToNetworkInput(config: IConfig): { nodes: Node[], edges: any[]; } {
     const nodes = [];
     const edges = [];
 
     for (const protein of this.proteins) {
-      nodes.push(this.mapCustomNode(protein, config));
+      nodes.push(mapCustomNode(protein, config));
     }
 
     for (const edge of this.edges) {
-      edges.push(this.mapCustomEdge(edge, config));
+      edges.push(mapCustomEdge(edge, config));
     }
 
     return {
@@ -117,3 +62,60 @@ export class ProteinNetwork {
   }
 
 }
+
+/** Maps user input node to network node object
+   * If user input node has no group, fall back to default
+   * If user input node has group that is not defined, throw error
+   * 
+   * @param customNode 
+   * @param config 
+   * @returns 
+   */
+ export function mapCustomNode(customNode: any, config: IConfig): Node {
+  let node;
+  if (customNode.group === undefined) {
+    // fallback to default node
+    node = JSON.parse(JSON.stringify(defaultConfig.nodeGroups.default));
+    node.group = 'default';
+  } else {
+    if (config.nodeGroups[customNode.group] === undefined) {
+      throw `Node with id ${customNode.id} has undefined node group ${customNode.group}.`
+    }
+    // copy
+    node = JSON.parse(JSON.stringify(config.nodeGroups[customNode.group]));
+  }
+  // update the node with custom node properties, including values fetched from backend
+  node = merge(node, customNode)
+  // label is only used for network visualization
+  node.label = customNode.label ? customNode.label : customNode.id;
+  return node;
+}
+
+/** Maps user input edge to network edge object
+ * If user input edge has no group, fall back to default
+ * If user input edge has group that is not defined, throw error
+ * 
+ * @param customEdge 
+ * @param config 
+ * @returns 
+ */
+export function mapCustomEdge(customEdge: NodeInteraction, config: IConfig): any {
+  let edge;
+  if (customEdge.group === undefined) {
+    // fallback to default node
+    edge = JSON.parse(JSON.stringify(defaultConfig.edgeGroups.default));
+  } else {
+    if (config.edgeGroups[customEdge.group] === undefined) {
+      throw `Edge "from ${customEdge.from}" - "to ${customEdge.to}" has undefined edge group ${customEdge.group}.`
+    }
+    // copy
+    edge = JSON.parse(JSON.stringify(config.edgeGroups[customEdge.group]));
+  }
+  edge = {
+    ...edge,
+    ...customEdge
+  }
+  console.log('edge')
+  console.log(edge)
+  return edge;
+}
diff --git a/src/app/pages/explorer-page/explorer-page.component.html b/src/app/pages/explorer-page/explorer-page.component.html
index 9ec8e526d8f2722681430f6ba6c0ebd50181f048..87baa8c76dfc39dbe226d0dfbded0d09ed322239 100644
--- a/src/app/pages/explorer-page/explorer-page.component.html
+++ b/src/app/pages/explorer-page/explorer-page.component.html
@@ -146,6 +146,7 @@
 
             <ng-container *ngIf="myConfig.showFooterButtonExpression">
               <div class="footer-buttons dropdown is-up explorer-footer-element" [class.is-active]="expressionExpanded">
+
                 <div class="dropdown-trigger">
                   <button (click)="expressionExpanded=!expressionExpanded"
                           class="button is-rounded is-primary" [class.is-outlined]="!selectedTissue"
@@ -182,17 +183,17 @@
               </div>
             </ng-container>
 
-        <app-toggle class="footer-buttons" textOn="Drugs On" 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 explorer-footer-element" textOn="Animation On" textOff="Off"
-                    tooltipOn="Enable the network animation."
-                    tooltipOff="Disable the network animation and freeze nodes."
-                    [smallStyle]="smallStyle"
-                    [value]="physicsEnabled" (valueChange)="updatePhysicsEnabled($event)"></app-toggle>
+            <app-toggle class="footer-buttons" textOn="Drugs On" 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 explorer-footer-element" textOn="Animation On" textOff="Off"
+                        tooltipOn="Enable the network animation."
+                        tooltipOff="Disable the network animation and freeze nodes."
+                        [smallStyle]="smallStyle"
+                        [value]="physicsEnabled" (valueChange)="updatePhysicsEnabled($event)"></app-toggle>
 
         </footer>
       </div>
diff --git a/src/app/pages/explorer-page/explorer-page.component.ts b/src/app/pages/explorer-page/explorer-page.component.ts
index cd2a64d4700fb27753550516e67d24f3871e2230..c5d09b1a9830814a6bdc3d470353336d7b617434 100644
--- a/src/app/pages/explorer-page/explorer-page.component.ts
+++ b/src/app/pages/explorer-page/explorer-page.component.ts
@@ -15,7 +15,7 @@ import {
   getDrugNodeId,
   Drug
 } from '../../interfaces';
-import {ProteinNetwork} from '../../main-network';
+import {mapCustomEdge, mapCustomNode, ProteinNetwork} from '../../main-network';
 import {AnalysisService} from '../../services/analysis/analysis.service';
 import {OmnipathControllerService} from '../../services/omnipath-controller/omnipath-controller.service';
 import domtoimage from 'dom-to-image';
@@ -269,10 +269,20 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
     if (network.nodes.length) {
       network.nodes = await this.netex.mapNodes(network.nodes, this.myConfig.identifier);
     }
-    // use netexIds where posssible
+    // at this point, we have nodes synched with the backend
+    // use netexIds where posssible, but use original id as node name if no label given
     const nodeIdMap = {};
-    network.nodes.forEach(node => {
-      nodeIdMap[node.id] = node.netexId ? node.netexId : node.id
+    const seenNodeIds = new Set();
+    network.nodes.forEach((node, index, object) => {
+      if (seenNodeIds.has(node.id)) {
+        // remove duplicate ensg nodes, TODO is there a better way to do this?
+        object.splice(index, 1);
+        return;
+      } else {
+        seenNodeIds.add(node.id);
+      }
+      nodeIdMap[node.id] = node.netexId ? node.netexId : node.id;
+      node.label = node.label ? node.label : node.id;
       node.id = nodeIdMap[node.id];
     });
     // adjust edge labels accordingly
@@ -425,12 +435,12 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
         this.netex.adjacentDrugs(this.myConfig.interactionDrugProtein, this.nodeData.nodes).subscribe(response => {
           for (const interaction of response.pdis) {
             const edge = {from: interaction.protein, to: interaction.drug};
-            this.adjacentDrugEdgesList.push(this.proteinData.mapCustomEdge(edge, this.myConfig));
+            this.adjacentDrugEdgesList.push(mapCustomEdge(edge, this.myConfig));
           }
           for (const drug of response.drugs) {
             drug.group = 'foundDrug';
             drug.id = getDrugNodeId(drug)
-            this.adjacentDrugList.push(this.proteinData.mapCustomNode(drug, this.myConfig))
+            this.adjacentDrugList.push(mapCustomNode(drug, this.myConfig))
           }
           this.nodeData.nodes.add(this.adjacentDrugList);
           this.nodeData.edges.add(this.adjacentDrugEdgesList);