From 734602c883db9f22efc2557ac2d3e83931e142e1 Mon Sep 17 00:00:00 2001
From: Matthias Konitzny <konitzny@ibr.cs.tu-bs.de>
Date: Tue, 19 Jul 2022 16:20:45 +0200
Subject: [PATCH] Fixed node filtering and design. Nodes may still change color
 during filter operations. This should be resolved when colors are hard-mapped
 to node types.

---
 src/display/components/nodefilter/classlabel.css |  4 ++--
 src/display/components/nodefilter/filtermenu.css |  2 +-
 src/display/components/nodefilter/filtermenu.tsx |  7 +++++--
 src/display/display.tsx                          |  2 +-
 src/display/graph.ts                             | 16 +++++++++++++++-
 5 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/src/display/components/nodefilter/classlabel.css b/src/display/components/nodefilter/classlabel.css
index 8d4ff55..17d3d00 100644
--- a/src/display/components/nodefilter/classlabel.css
+++ b/src/display/components/nodefilter/classlabel.css
@@ -1,12 +1,12 @@
 .filter-class-label {
     display: inline-block;
-    padding-right: 5px;
+    padding-right: 10px;
     color: #fff;
     font-size: 13px;
     line-height: 20px;
     font-family: CuratorRegular, Helvetica Neue, Helvetica, Arial, sans-serif;
     text-transform: uppercase;
-    margin-bottom: 6px;
+    margin-bottom: 8px;
     height: 17px;
     z-index: 100;
     cursor: pointer;
diff --git a/src/display/components/nodefilter/filtermenu.css b/src/display/components/nodefilter/filtermenu.css
index 015e6b4..4823e2b 100644
--- a/src/display/components/nodefilter/filtermenu.css
+++ b/src/display/components/nodefilter/filtermenu.css
@@ -3,7 +3,7 @@
     bottom: 0;
     pointer-events: none;
     width: 350px;
-    max-width: 400px;
+    height: 105px;
     padding: 10px;
     left: 0;
     display: block;
diff --git a/src/display/components/nodefilter/filtermenu.tsx b/src/display/components/nodefilter/filtermenu.tsx
index bbd2549..8065543 100644
--- a/src/display/components/nodefilter/filtermenu.tsx
+++ b/src/display/components/nodefilter/filtermenu.tsx
@@ -32,14 +32,17 @@ function FilterMenu({ classes, onVisibilityChange }: FilterMenuProps) {
         }
     };
 
+    const labelWidth = 10 * chars;
+    const width = Math.ceil(classList.length / 3) * (labelWidth + 20);
+
     return (
-        <div className={"filter-menu"}>
+        <div className={"filter-menu"} style={{ width }}>
             {classList.map((cls: string, idx) => (
                 <ClassLabel
                     key={cls}
                     type={cls}
                     color={classes.get(cls)}
-                    width={10 * chars}
+                    width={labelWidth}
                     visible={visibility[idx]}
                     onClick={() => handleClick(idx)}
                 />
diff --git a/src/display/display.tsx b/src/display/display.tsx
index d802622..d5bd1fd 100644
--- a/src/display/display.tsx
+++ b/src/display/display.tsx
@@ -131,7 +131,7 @@ class Display extends React.Component<
 
                 {this.state.graph && (
                     <FilterMenu
-                        classes={this.state.graph.nodeColors}
+                        classes={this.graph.nodeColors}
                         onVisibilityChange={this.handleNodeFilter}
                     />
                 )}
diff --git a/src/display/graph.ts b/src/display/graph.ts
index 934305d..262a47e 100644
--- a/src/display/graph.ts
+++ b/src/display/graph.ts
@@ -58,6 +58,7 @@ export default class Graph {
 
         this.resetNodeData();
         this.updateNodeData();
+        this.removeFloatingNodes();
         this.mapNodeColors();
         this.mapLinkColors();
     }
@@ -69,6 +70,10 @@ export default class Graph {
         }
     }
 
+    private removeFloatingNodes() {
+        this.nodes = this.nodes.filter((node) => node.neighbors.length > 0);
+    }
+
     /**
      * Updates the graph data structure to contain additional values.
      * Creates a 'neighbors' and 'links' array for each node object.
@@ -137,6 +142,10 @@ export default class Graph {
         nodeTypes: Map<string, boolean>,
         linkTypes?: Map<string, boolean>
     ): Graph {
+        // Filter nodes depending on type
+        const nodes = this.nodes.filter((l) => nodeTypes.get(l.type));
+
+        // Filter links depending on type
         let links;
         if (linkTypes === undefined) {
             links = this.links;
@@ -144,8 +153,13 @@ export default class Graph {
             links = this.links.filter((l) => linkTypes.get(l.type));
         }
 
+        // Filter links which are connected to an invisible node
+        links = links.filter(
+            (l) => nodeTypes.get(l.source.type) && nodeTypes.get(l.target.type)
+        );
+
         return new Graph(
-            this.nodes.filter((l) => nodeTypes.get(l.type)),
+            nodes,
             links.map((link) => {
                 return {
                     source: link.source.id,
-- 
GitLab