diff --git a/display/graph.js b/display/graph.js
index e54a14fe2a058a6bba0f85a87414caf5e048d6d1..e24ce446274231b7828c6eabe3c0286888181cc4 100644
--- a/display/graph.js
+++ b/display/graph.js
@@ -2,7 +2,7 @@ import * as Config from "../config";
 import * as Helpers from "./helpers";
 import { loadGraphJson } from "../datasets/datasets";
 import { NodeInfoOverlay } from "./overlays/nodeinfo";
-import { LinkSelectionOverlay } from "./overlays/linkselection";
+import { FilterOverlay } from "./overlays/filteroverlay";
 
 import * as THREE from "three";
 import ForceGraph3D from "3d-force-graph";
@@ -33,9 +33,10 @@ class Graph {
         this.idToNode = {};
 
         this.firstTick = true;
-        this.infooverlay = null;
+        this.infoOverlay = null;
 
         this.edgeTypeVisibility = {};
+        this.nodeTypeVisibility = {};
 
         this.loadGraph(spaceId);
     }
@@ -59,7 +60,7 @@ class Graph {
             .linkWidth((link) => this.getLinkWidth(link))
             .onNodeClick((node) => {
                 this.focusOnNode(node);
-                this.infooverlay.updateInfoOverlay(node);
+                this.infoOverlay.updateInfoOverlay(node);
             })
             .onNodeHover((node) => {
                 this.onNodeHover(node);
@@ -101,9 +102,13 @@ class Graph {
             document.addEventListener("fullscreenchange", () => this.resize());
             window.addEventListener("resize", () => this.resize());
 
+            // Initialize visibility states
             this.getLinkClasses().forEach(
                 (item) => (this.edgeTypeVisibility[item] = true)
             );
+            this.getNodeClasses().forEach(
+                (item) => (this.nodeTypeVisibility[item] = true)
+            );
             this.firstTick = false;
         }
     }
@@ -150,7 +155,7 @@ class Graph {
         this.graph
             .graphData()
             .nodes.forEach((node) => nodeClasses.push(node.type));
-        return [...new Set(nodeClasses)];
+        return [...new Set(nodeClasses)].map((c) => String(c));
     }
 
     onNodeHover(node) {
@@ -215,18 +220,39 @@ class Graph {
         }
     }
 
-    hideLinkType(type) {
-        this.edgeTypeVisibility[type] = false;
+    toggleNodeVisibility(type) {
+        if (this.nodeTypeVisibility[type]) {
+            this.hideNodeType(type);
+        } else {
+            this.showNodeType(type);
+        }
+    }
+
+    updateVisibility() {
         this.updateGraphData();
+        this.removeFloatingLinks();
         this.updateNodeData();
         this.removeFloatingNodes();
     }
 
+    hideLinkType(type) {
+        this.edgeTypeVisibility[type] = false;
+        this.updateVisibility();
+    }
+
     showLinkType(type) {
         this.edgeTypeVisibility[type] = true;
-        this.updateGraphData();
-        this.updateNodeData();
-        this.removeFloatingNodes();
+        this.updateVisibility();
+    }
+
+    hideNodeType(type) {
+        this.nodeTypeVisibility[type] = false;
+        this.updateVisibility();
+    }
+
+    showNodeType(type) {
+        this.nodeTypeVisibility[type] = true;
+        this.updateVisibility();
     }
 
     removeFloatingNodes() {
@@ -239,9 +265,25 @@ class Graph {
         this.graph.graphData(data);
     }
 
+    removeFloatingLinks() {
+        const gData = this.graph.graphData();
+        const links = gData.links.filter(
+            (link) =>
+                this.nodeTypeVisibility[link.target.type] &
+                this.nodeTypeVisibility[link.source.type]
+        );
+        const data = {
+            nodes: gData.nodes,
+            links: links,
+        };
+        this.graph.graphData(data);
+    }
+
     updateGraphData() {
         const data = {
-            nodes: this.gData.nodes,
+            nodes: this.gData.nodes.filter(
+                (l) => this.nodeTypeVisibility[l.type]
+            ),
             links: this.gData.links.filter(
                 (l) => this.edgeTypeVisibility[l.type]
             ),
@@ -450,8 +492,10 @@ class Graph {
 }
 
 function loadComponents() {
-    linkoverlay.create();
-    infooverlay.create();
+    filterOverlay.create();
+    infoOverlay.create();
+    filterOverlay.filterChangedCallback = (cls) =>
+        infoOverlay.bottomMenu.toggleTabVisibility(cls);
     createFullScreenButton();
 }
 
@@ -471,14 +515,14 @@ function createFullScreenButton() {
     sceneNode.appendChild(overlayNode);
 }
 
-var G;
-var linkoverlay;
-var infooverlay;
+let G = null;
+let filterOverlay = null;
+let infoOverlay = null;
 
 // Only execute, if corresponding dom is present
 if (document.getElementById("3d-graph") !== null) {
     G = new Graph(space_id); // space_id defined globaly through knowledge-space.php
-    linkoverlay = new LinkSelectionOverlay(G);
-    infooverlay = new NodeInfoOverlay(G);
-    G.infooverlay = infooverlay;
+    filterOverlay = new FilterOverlay(G, "node");
+    infoOverlay = new NodeInfoOverlay(G);
+    G.infoOverlay = infoOverlay;
 }
diff --git a/display/overlays/linkselection.js b/display/overlays/filteroverlay.js
similarity index 57%
rename from display/overlays/linkselection.js
rename to display/overlays/filteroverlay.js
index fb43bc926aac6c5ff15b311d33dbe8cc716742ea..76db39e8c433dc237899646036cdabf79ba57aba 100644
--- a/display/overlays/linkselection.js
+++ b/display/overlays/filteroverlay.js
@@ -1,19 +1,22 @@
 import * as Helpers from "../helpers";
 import jQuery from "jquery";
 
-export { LinkSelectionOverlay };
+export { FilterOverlay };
 
 /**
- * Represents an overlay showing the meaning of different edge colors.
- * Offers the ability to toggle certain edge types.
+ * Represents an overlay showing the meaning of different link/node colors.
+ * Offers the ability to toggle certain types.
  */
-class LinkSelectionOverlay {
+class FilterOverlay {
     /**
-     * Creates the link overlay for a given graph object.
+     * Creates the overlay for a given graph object.
      * @param {Graph} graph The graph object.
+     * @param {String} type The selection type. Can be "link" or "node".
      */
-    constructor(graph) {
+    constructor(graph, type = "link") {
         this.graph = graph;
+        this.type = type;
+        this.filterChangedCallback = (type) => void type;
     }
 
     /**
@@ -26,20 +29,23 @@ class LinkSelectionOverlay {
         overlayNode.className = "link-overlay";
         sceneNode.insertBefore(overlayNode, sceneNode.childNodes[2]);
 
-        const linkClasses = this.graph.getLinkClasses();
+        const classes =
+            this.type === "link"
+                ? this.graph.getLinkClasses()
+                : this.graph.getNodeClasses();
         const chars = Math.max.apply(
             Math,
-            linkClasses.map(function (c) {
+            classes.map(function (c) {
                 return c.length;
             })
         );
 
-        for (const link of linkClasses) {
+        for (const link of classes) {
             const relation = Helpers.createDiv("relation", overlayNode, {
-                edgeType: link, // Attach the link type to the relation div object
+                type: link, // Attach the link type to the relation div object
                 innerHTML: "<p>" + link + "</p>",
             });
-            jQuery(relation).click((event) => this.toggleLinkVisibility(event));
+            jQuery(relation).click((event) => this.toggleVisibility(event));
 
             const colorStrip = Helpers.createDiv("rel-container", relation);
             colorStrip.style.backgroundColor = this.graph.edgeColors[link];
@@ -52,9 +58,14 @@ class LinkSelectionOverlay {
      * Toggles the visibility of certain edge types.
      * @param {MouseEvent} event
      */
-    toggleLinkVisibility(event) {
+    toggleVisibility(event) {
         const target = event.currentTarget;
-        this.graph.toggleLinkVisibility(target.edgeType);
+        if (this.type === "link") {
+            this.graph.toggleLinkVisibility(target.type);
+        } else {
+            this.graph.toggleNodeVisibility(target.type);
+        }
+        this.filterChangedCallback(target.type);
         if (getComputedStyle(target).opacity == 1.0) {
             target.style.opacity = 0.4;
         } else {
diff --git a/display/overlays/neighbors.js b/display/overlays/neighbors.js
index d7b253f971ffd0e6c3aa48f2b1acc08f9b710d37..7e641b8d31b4cd06b938ee590d1cca88ea92234f 100644
--- a/display/overlays/neighbors.js
+++ b/display/overlays/neighbors.js
@@ -9,15 +9,17 @@ export { NodeNeighborOverlay };
  * that connects them.
  */
 class NodeNeighborOverlay {
-    constructor(graph, parentNode, infoOverlay) {
+    constructor(graph, parentNode, infoOverlay, type = "link") {
         this.graph = graph;
         this.parentNode = parentNode;
         this.infoOverlay = infoOverlay;
+        this.type = type;
 
         this.activeTabNav = null; // The currently selected tab handle
         this.activeTabContent = null; // The currently selected tab content
 
         this.tabContentPages = {};
+        this.tabNavHandles = {};
     }
 
     /**
@@ -38,15 +40,20 @@ class NodeNeighborOverlay {
             bottomContainerDiv
         );
 
-        for (const [cls, color] of Object.entries(this.graph.edgeColors)) {
+        const colors =
+            this.type === "link"
+                ? this.graph.edgeColors
+                : this.graph.nodeColors;
+        for (const [cls, color] of Object.entries(colors)) {
             const navTab = Helpers.createDiv(
                 "bottom-container-nav-tab",
                 bottomContainerNavDiv
             );
             navTab.innerText = cls.slice(0, 3);
             navTab.style.backgroundColor = color;
-            navTab.edgeType = cls; // Attach the edge type to the DOM object to retrieve it during click events
-            jQuery(navTab).click((event) => this.openTab(event));
+            navTab.type = cls; // Attach the edge type to the DOM object to retrieve it during click events
+            jQuery(navTab).click((event) => this.openTabFromEvent(event));
+            this.tabNavHandles[cls] = navTab;
 
             const tabContent = Helpers.createDiv(
                 "bottom-container-tab-content",
@@ -69,29 +76,58 @@ class NodeNeighborOverlay {
 
         this.activeTabContent.classList.add("active-tab-content");
         this.activeTabNav.classList.add("active-tab-nav");
-        this.activeTabNav.innerText = this.activeTabNav.edgeType;
+        this.activeTabNav.innerText = this.activeTabNav.type;
     }
 
     /**
      * Click event handler for the tab headers of the bottom menu.
      * @param event
      */
-    openTab(event) {
+    openTabFromEvent(event) {
         const navTab = event.target;
-        const cls = navTab.edgeType;
+        const cls = navTab.type;
+        this.openTab(cls);
+    }
 
+    openTab(cls) {
         this.activeTabNav.classList.remove("active-tab-nav");
         this.activeTabNav.innerText = this.activeTabNav.innerText.slice(0, 3);
-        navTab.classList.add("active-tab-nav");
-        navTab.innerText = cls;
+        this.tabNavHandles[cls].classList.add("active-tab-nav");
+        this.tabNavHandles[cls].innerText = cls;
 
         this.activeTabContent.classList.remove("active-tab-content");
         this.tabContentPages[cls].classList.add("active-tab-content");
 
-        this.activeTabNav = navTab;
+        this.activeTabNav = this.tabNavHandles[cls];
         this.activeTabContent = this.tabContentPages[cls];
     }
 
+    toggleTabVisibility(cls) {
+        this.tabNavHandles[cls].classList.toggle("bottom-container-nav-tab");
+        this.tabNavHandles[cls].classList.toggle("hidden-tab");
+        this.tabContentPages[cls].classList.toggle(
+            "bottom-container-tab-content"
+        );
+        this.tabContentPages[cls].classList.toggle("hidden-tab");
+
+        // If the tab gets hidden and is the active tab, search for an alternative nav tab to become the new active tab.
+        if (this.tabContentPages[cls].classList.contains("hidden-tab")) {
+            if (this.tabNavHandles[cls].classList.contains("active-tab-nav")) {
+                for (const tab of Object.values(this.tabNavHandles)) {
+                    if (!tab.classList.contains("hidden-tab")) {
+                        this.openTab(tab.type);
+                        break;
+                    }
+                }
+            }
+        } else {
+            // If all tabs are hidden, the new tab should become the active tab.
+            if (this.activeTabNav.classList.contains("hidden-tab")) {
+                this.openTab(cls);
+            }
+        }
+    }
+
     /**
      * Clears the images from all tab content pages.
      */
@@ -134,7 +170,11 @@ class NodeNeighborOverlay {
         for (const link of node.links) {
             const target = link.source == node ? link.target : link.source;
             const reference = this.createReference(target);
-            this.tabContentPages[link.type].appendChild(reference);
+            if (this.type === "link") {
+                this.tabContentPages[link.type].appendChild(reference);
+            } else {
+                this.tabContentPages[target.type].appendChild(reference);
+            }
         }
     }
 }
diff --git a/display/overlays/nodeinfo.js b/display/overlays/nodeinfo.js
index 1c97533f8a7dc0b00501c903028df3b276bff40c..e94bba4aeca0096a7906aae460eb4eaadda1bf13 100644
--- a/display/overlays/nodeinfo.js
+++ b/display/overlays/nodeinfo.js
@@ -26,7 +26,12 @@ class NodeInfoOverlay {
     create() {
         const overlayDiv = this.createOverlayMainDiv();
         this.createOverlayElements(overlayDiv);
-        this.bottomMenu = new NodeNeighborOverlay(this.graph, overlayDiv, this);
+        this.bottomMenu = new NodeNeighborOverlay(
+            this.graph,
+            overlayDiv,
+            this,
+            "node"
+        );
         this.bottomMenu.create();
 
         jQuery("#infoOverlayCloseButton").click(function () {
diff --git a/kg-style.css b/kg-style.css
index 58f0b450ed1cdad72c543cdd46c3be100514c207..6ed2ff89d37aa75b165acc15efa63004795fc34f 100644
--- a/kg-style.css
+++ b/kg-style.css
@@ -169,6 +169,10 @@
     align-items: center;
 }
 
+.hidden-tab {
+    display: none;
+}
+
 .bottom-container {
     position: absolute;
     bottom: 0;