diff --git a/libs/shared/lib/graph-layout/graphology-layouts.ts b/libs/shared/lib/graph-layout/graphology-layouts.ts
index 46960915b48f8579aef6e6306c6ead6e2a35d036..4074a90cc0a40e01791ea638e3dfd34799182bab 100644
--- a/libs/shared/lib/graph-layout/graphology-layouts.ts
+++ b/libs/shared/lib/graph-layout/graphology-layouts.ts
@@ -70,7 +70,7 @@ export class GraphologyCircular extends GraphologyLayout {
 
   public override async layout(
     graph: Graph<Attributes, Attributes, Attributes>,
-    boundingBox?: { x1: number; x2: number; y1: number; y2: number }
+    boundingBox?: { x1: number; x2: number; y1: number; y2: number },
   ): Promise<void> {
     super.layout(graph, boundingBox);
     // To directly assign the positions to the nodes:
@@ -91,15 +91,16 @@ export class GraphologyRandom extends GraphologyLayout {
 
   public override async layout(
     graph: Graph<Attributes, Attributes, Attributes>,
-    boundingBox?: { x1: number; x2: number; y1: number; y2: number }
+    boundingBox?: { x1: number; x2: number; y1: number; y2: number },
   ): Promise<void> {
     super.layout(graph, boundingBox);
     // const positions = random(graph);
 
     // To directly assign the positions to the nodes:
     random.assign(graph, {
-      scale: graph.order * 10,
+      scale: graph.order * 1.5,
       ...this.defaultLayoutSettings,
+      center: 0,
     });
   }
 }
@@ -126,7 +127,7 @@ export class GraphologyNoverlap extends GraphologyLayout {
 
   public override async layout(
     graph: Graph<Attributes, Attributes, Attributes>,
-    boundingBox?: { x1: number; x2: number; y1: number; y2: number }
+    boundingBox?: { x1: number; x2: number; y1: number; y2: number },
   ): Promise<void> {
     super.layout(graph, boundingBox);
     // To directly assign the positions to the nodes:
@@ -168,7 +169,7 @@ export class GraphologyForceAtlas2 extends GraphologyLayout {
 
   public override async layout(
     graph: Graph<Attributes, Attributes, Attributes>,
-    boundingBox?: { x1: number; x2: number; y1: number; y2: number }
+    boundingBox?: { x1: number; x2: number; y1: number; y2: number },
   ): Promise<void> {
     super.layout(graph, boundingBox);
 
@@ -189,17 +190,20 @@ export class GraphologyForceAtlas2Webworker extends GraphologyLayout {
     super('Graphology_forceAtlas2_webworker');
   }
 
-  public override layout(
+  public override async layout(
     graph: Graph<Attributes, Attributes, Attributes>,
-    boundingBox?: { x1: number; x2: number; y1: number; y2: number }
-  ): void {
+    boundingBox?: { x1: number; x2: number; y1: number; y2: number },
+  ): Promise<void> {
     super.layout(graph, boundingBox);
 
     const sensibleSettings = forceAtlas2.inferSettings(graph);
+    console.log(sensibleSettings);
+
     const layout = new FA2Layout(graph, {
       settings: {
         ...this.defaultLayoutSettings,
         ...sensibleSettings,
+        adjustSizes: graph.order < 300 ? true : false,
       },
     });
     layout.start();
@@ -207,6 +211,6 @@ export class GraphologyForceAtlas2Webworker extends GraphologyLayout {
     // stop the layout after 5 seconds
     setTimeout(() => {
       layout.stop();
-    }, 10000);
+    }, 20000);
   }
 }
diff --git a/libs/shared/lib/vis/visualizationManager.tsx b/libs/shared/lib/vis/visualizationManager.tsx
index 1167e74a4b0c370458bb0517234ed9458b5c94f5..12b474b332630d2895e6fbb691ac878c06199d20 100644
--- a/libs/shared/lib/vis/visualizationManager.tsx
+++ b/libs/shared/lib/vis/visualizationManager.tsx
@@ -85,18 +85,16 @@ export const VisualizationManager = () => {
   try {
     return (
       vis.activeVisualization && (
-        <div className="w-full h-full">
-          <visualizationComponent.VIS
-            data={graphQueryResult}
-            schema={schema}
-            ml={ml}
-            dispatch={dispatch}
-            globalConfig={globalConfig}
-            settings={visSettings}
-            encodings={visEncodings}
-            interactions={visInteractions}
-          />
-        </div>
+        <visualizationComponent.VIS
+          data={graphQueryResult}
+          schema={schema}
+          ml={ml}
+          dispatch={dispatch}
+          globalConfig={globalConfig}
+          settings={visSettings}
+          encodings={visEncodings}
+          interactions={visInteractions}
+        />
       )
     );
   } catch (error) {
diff --git a/libs/shared/lib/vis/visualizationPanel.tsx b/libs/shared/lib/vis/visualizationPanel.tsx
index ab722fc2c3c9fadaa52e4bb66ce61fe440aed42b..7a42403afc916cd67b8b4397baf40fa90a549d8e 100644
--- a/libs/shared/lib/vis/visualizationPanel.tsx
+++ b/libs/shared/lib/vis/visualizationPanel.tsx
@@ -103,9 +103,7 @@ export const VisualizationPanel = () => {
           {query.nodes.length > 0 ? <p>Query resulted in empty dataset</p> : <p>Query for data to visualize</p>}
         </div>
       ) : (
-        <div className="w-full h-full">
-          <VisualizationManager />
-        </div>
+        <VisualizationManager />
       )}
     </div>
   );
diff --git a/libs/shared/lib/vis/visualizations/nodelinkvis/components/NLPixi.tsx b/libs/shared/lib/vis/visualizations/nodelinkvis/components/NLPixi.tsx
index b8d90ed2d7cdfcfee8f52d3842a58c5677ab5202..df4e62737add52f85da8fc97737f6196e4f4dc47 100644
--- a/libs/shared/lib/vis/visualizations/nodelinkvis/components/NLPixi.tsx
+++ b/libs/shared/lib/vis/visualizations/nodelinkvis/components/NLPixi.tsx
@@ -1,12 +1,14 @@
 import { GraphType, LinkType, NodeType } from '../types';
-import { tailwindColors } from 'config';
+import { dataColors, tailwindColors } from 'config';
 import { ReactEventHandler, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
-import { Application, Circle, Container, FederatedPointerEvent, Graphics, IPointData } from 'pixi.js';
-import { binaryColor, nodeColor as nodeColor } from './utils';
+import { Application, Circle, Color, Container, FederatedPointerEvent, Graphics, IPointData, Point } from 'pixi.js';
 import * as force from './NLForce';
 import { Viewport } from 'pixi-viewport';
 import { useAppDispatch, useML, useSearchResultData } from '../../../../data-access';
 import { NLPopup } from './NLPopup';
+import { hslStringToHex, nodeColor } from './utils';
+import { CytoscapeLayout, GraphologyLayout, LayoutFactory, Layouts } from '../../../../graph-layout';
+import { MultiGraph } from 'graphology';
 
 type Props = {
   onClick: (node: NodeType, pos: IPointData) => void;
@@ -16,11 +18,20 @@ type Props = {
   currentShortestPathEdges?: LinkType[];
   highlightedLinks?: LinkType[];
   graph?: GraphType;
+  layoutAlgorithm: string;
 };
 
-const app = new Application({ background: 0xffffff, antialias: true, autoDensity: true, eventMode: 'auto' });
-const nodes = new Container();
-const links = new Container();
+const app = new Application({
+  background: 0xffffff,
+  antialias: true,
+  autoDensity: true,
+  eventMode: 'auto',
+  resolution: window.devicePixelRatio || 1,
+});
+const nodeLayer = new Container();
+const linkLayer = new Container();
+
+type LayoutState = 'reset' | 'running' | 'paused';
 
 //////////////////
 // MAIN COMPONENT
@@ -33,6 +44,8 @@ export const NLPixi = (props: Props) => {
   const nodeMap = useRef(new Map<string, Graphics>());
   const linkMap = useRef(new Map<string, Graphics>());
   const viewport = useRef<Viewport>();
+  const layoutState = useRef<LayoutState>('reset');
+  const layoutStoppedCount = useRef(0);
   const ref = useRef<HTMLDivElement>(null);
   const mouseInCanvas = useRef<boolean>(false);
   const isSetup = useRef(false);
@@ -42,10 +55,45 @@ export const NLPixi = (props: Props) => {
   const dispatch = useAppDispatch();
   const searchResults = useSearchResultData();
 
+  const layoutAlgorithm = useRef<CytoscapeLayout | GraphologyLayout>(new LayoutFactory().createLayout(Layouts.DAGRE));
+
+  // const cull = new Cull();
+  // let cullDirty = useRef(true);
+
+  const [config, setConfig] = useState({
+    width: 1000,
+    height: 1000,
+
+    LAYOUT_ALGORITHM: Layouts.FORCEATLAS2WEBWORKER,
+
+    NODE_RADIUS: 5,
+    NODE_BORDER_LINE_WIDTH: 1.0,
+    NODE_BORDER_LINE_WIDTH_SELECTED: 1.0, // if selected and normal width are different the thicker line will be still in the gfx
+    NODE_BORDER_COLOR_DEFAULT: dataColors.black,
+    NODE_BORDER_COLOR_SELECTED: dataColors.orange[60],
+
+    LINE_COLOR_DEFAULT: dataColors.neutral[20],
+    LINE_COLOR_SELECTED: tailwindColors.entity[400],
+    LINE_COLOR_ML: dataColors.blue[60],
+    LINE_WIDTH_DEFAULT: 0.8,
+  });
+
+  useEffect(() => {
+    setConfig((lastConfig) => {
+      return {
+        ...lastConfig,
+        LAYOUT_ALGORITHM: (props.layoutAlgorithm as Layouts) || lastConfig.LAYOUT_ALGORITHM,
+      };
+    });
+  }, [props.layoutAlgorithm]);
+
   const imperative = useRef<any>(null);
 
   useImperativeHandle(imperative, () => ({
     onDragStart(node: NodeType, gfx: Graphics) {
+      // todo: graphology does not support fixed nodes
+      // todo: after vis-settings panel is there, we should to also support the original d3 force to allow interactivity if needed
+      if (props.layoutAlgorithm === Layouts.FORCEATLAS2WEBWORKER) return;
       if (viewport.current) viewport.current.pause = true;
       dragging.current = { node, gfx };
       onlyClicked.current = true;
@@ -69,7 +117,7 @@ export const NLPixi = (props: Props) => {
         if (!dragging.current.node.fy) dragging.current.node.fy = dragging.current.node.y || 0;
         dragging.current.node.fx += movementX / (viewport.current?.scaled || 1);
         dragging.current.node.fy += movementY / (viewport.current?.scaled || 1);
-        force.simulation.alpha(0.1).restart();
+        // force.simulation.alpha(0.1).restart();
       }
     },
 
@@ -181,10 +229,10 @@ export const NLPixi = (props: Props) => {
       : node.isShortestPathTarget
         ? tailwindColors.relation[950]
         : node.selected
-          ? tailwindColors.entity[400]
-          : '#000000';
-    const lineWidth = node.selected ? 3 : 1.5;
-    gfx.lineStyle(lineWidth, binaryColor(lineColor));
+          ? config.NODE_BORDER_COLOR_SELECTED
+          : config.NODE_BORDER_COLOR_DEFAULT;
+    const lineWidth = node.selected ? config.NODE_BORDER_LINE_WIDTH_SELECTED : config.NODE_BORDER_LINE_WIDTH;
+    gfx.lineStyle(lineWidth, new Color(hslStringToHex(lineColor)));
 
     if (node?.cluster) {
       gfx.beginFill(node.cluster >= 0 ? nodeColor(node.cluster) : 0x000000);
@@ -234,7 +282,7 @@ export const NLPixi = (props: Props) => {
     if (node.x === undefined || node.y === undefined) return;
     const gfx = new Graphics();
     nodeMap.current.set(node.id, gfx);
-    nodes.addChild(gfx);
+    nodeLayer.addChild(gfx);
     node.selected = selected;
 
     updateNode(node);
@@ -285,11 +333,12 @@ export const NLPixi = (props: Props) => {
     }
 
     if (gfx) {
-      let color = link.color || 0x000000;
-      let style = 0.2;
+      // let color = link.color || 0x000000;
+      let color = config.LINE_COLOR_DEFAULT;
+      let style = config.LINE_WIDTH_DEFAULT;
       let alpha = link.alpha || 1;
       if (link.mlEdge) {
-        color = 0x0000ff;
+        color = config.LINE_COLOR_ML;
         if (link.value > ml.communityDetection.jaccard_threshold) {
           style = link.value * 1.8;
         } else {
@@ -299,22 +348,25 @@ export const NLPixi = (props: Props) => {
       } else if (props.highlightedLinks && props.highlightedLinks.includes(link)) {
         if (link.mlEdge && ml.communityDetection.jaccard_threshold) {
           if (link.value > ml.communityDetection.jaccard_threshold) {
-            color = 0xaa00ff;
+            color = dataColors.magenta[50];
+            // 0xaa00ff;
             style = link.value * 1.8;
           }
         } else {
-          color = 0xff0000;
+          color = dataColors.red[70];
+          // color = 0xff0000;
           style = 1.0;
         }
       } else if (props.currentShortestPathEdges && props.currentShortestPathEdges.includes(link)) {
-        color = 0x00ff00;
+        color = dataColors.green[50];
+        // color = 0x00ff00;
         style = 3.0;
       }
 
       gfx.clear();
       gfx.beginFill();
       gfx
-        .lineStyle(style, color, alpha)
+        .lineStyle(style, hslStringToHex(color), alpha)
         .moveTo(source.x || 0, source.y || 0)
         .lineTo(target.x || 0, target.y || 0);
       gfx.endFill();
@@ -331,17 +383,26 @@ export const NLPixi = (props: Props) => {
     gfx.name = 'link_' + link.id;
     linkMap.current.set(link.id, gfx);
     updateLink(link, gfx);
-    links.addChild(gfx);
+    linkLayer.addChild(gfx);
     return gfx;
   };
 
+  useEffect(() => {
+    return () => {
+      nodeMap.current.clear();
+      linkMap.current.clear();
+      nodeLayer.removeChildren();
+      linkLayer.removeChildren();
+    };
+  }, []);
+
   useEffect(() => {
     if (props.graph && ref.current && ref.current.children.length > 0 && imperative.current) {
-      if (!isSetup.current) setup();
-      else update();
-      // setup();
+      console.log(props.graph);
+      if (isSetup.current === false) setup();
+      else update(false);
     }
-  }, [props.graph]);
+  }, [props.graph, config]);
 
   useEffect(() => {
     if (props.graph) {
@@ -362,16 +423,61 @@ export const NLPixi = (props: Props) => {
   }, [searchResults]);
 
   const tick = (delta: number) => {
+    if (layoutState.current === 'paused') return;
+    if (layoutState.current === 'reset') layoutStoppedCount.current = 0;
+
     if (props.graph) {
-      props.graph.nodes.forEach((node: NodeType) => {
+      if (!layoutAlgorithm.current) return;
+
+      let stopped = 0;
+      props.graph.nodes.forEach((node: NodeType, i) => {
+        if (!layoutAlgorithm.current) return;
         const gfx = nodeMap.current.get(node.id);
         if (!gfx || node.x === undefined || node.y === undefined) return;
-        gfx.position.copyFrom(node as IPointData);
+
+        const position = layoutAlgorithm.current.getNodePosition(node.id);
+
+        if (Math.abs(node.x - position.x - app.renderer.width / 2) + Math.abs(node.y - position.y - app.renderer.height / 2) < 1) {
+          stopped += 1;
+          return;
+        }
+        if (layoutAlgorithm.current.provider === 'Graphology') {
+          // this is a dirty hack to fix the graphology layout being out of bounds
+          node.x = position.x + app.renderer.width / 2;
+          node.y = position.y + app.renderer.height / 2;
+        } else {
+          node.x = position.x;
+          node.y = position.y;
+        }
+
+        if (layoutState.current === 'running') {
+          gfx.position.copyFrom({
+            x: node.fx || gfx.position.x + ((node.x || 0) - gfx.position.x) * 0.1 * delta,
+            y: node.fy || gfx.position.y + ((node.y || 0) - gfx.position.y) * 0.1 * delta,
+          });
+        } else {
+          gfx.position.copyFrom(node as IPointData);
+        }
       });
 
+      if (stopped === props.graph.nodes.length) {
+        layoutStoppedCount.current = layoutStoppedCount.current + 1;
+        if (layoutStoppedCount.current > 1000) {
+          layoutState.current = 'paused';
+          console.debug('NL layout paused');
+        }
+      } else {
+        layoutStoppedCount.current = 0;
+      }
+      if (layoutState.current === 'reset') {
+        layoutState.current = 'running';
+      }
+
       // Update forces of the links
       props.graph.links.forEach((link: any) => {
-        if (linkMap.current && !!linkMap.current.has(link.id)) updateLink(link, linkMap.current.get(link.id) as Graphics);
+        if (linkMap.current && !!linkMap.current.has(link.id)) {
+          updateLink(link, linkMap.current.get(link.id) as Graphics);
+        }
       });
     }
   };
@@ -384,13 +490,13 @@ export const NLPixi = (props: Props) => {
       if (forceClear) {
         nodeMap.current.clear();
         linkMap.current.clear();
-        nodes.removeChildren();
-        links.removeChildren();
+        nodeLayer.removeChildren();
+        linkLayer.removeChildren();
       }
 
       nodeMap.current.forEach((gfx, id) => {
         if (!props.graph?.nodes?.find((node) => node.id === id)) {
-          nodes.removeChild(gfx);
+          nodeLayer.removeChild(gfx);
           gfx.destroy();
           nodeMap.current.delete(id);
         }
@@ -398,7 +504,7 @@ export const NLPixi = (props: Props) => {
 
       linkMap.current.forEach((gfx, id) => {
         if (!props.graph?.links?.find((link) => link.id === id)) {
-          links.removeChild(gfx);
+          linkLayer.removeChild(gfx);
           gfx.destroy();
           linkMap.current.delete(id);
         }
@@ -434,9 +540,11 @@ export const NLPixi = (props: Props) => {
       //   });
       // console.log(nodes.children);
 
-      force.startSimulation(props.graph, ref.current.getBoundingClientRect());
-      force.simulation.on('tick', () => {});
+      // force.startSimulation(props.graph, ref.current.getBoundingClientRect());
+      // force.simulation.on('tick', () => {});
       app.ticker.add(tick);
+      layoutState.current = 'reset';
+      if (forceClear) setupLayout(forceClear);
     }
   };
 
@@ -446,8 +554,8 @@ export const NLPixi = (props: Props) => {
    * @param graph The graph returned from the database and that is parsed into a nodelist and edgelist.
    */
   const setup = () => {
-    nodes.removeChildren();
-    links.removeChildren();
+    nodeLayer.removeChildren();
+    linkLayer.removeChildren();
     app.stage.removeChildren();
 
     if (!props.graph) throw Error('Graph is undefined');
@@ -463,30 +571,49 @@ export const NLPixi = (props: Props) => {
     });
     app.stage.addChild(viewport.current);
     // activate plugins
-    viewport.current.drag().pinch().wheel().animate({}).decelerate({ friction: 0.75 });
+    viewport.current.drag().pinch().wheel({ smooth: 2 }).animate({}).decelerate({ friction: 0.75 });
 
-    viewport.current.addChild(links);
-    viewport.current.addChild(nodes);
+    viewport.current.addChild(linkLayer);
+    viewport.current.addChild(nodeLayer);
     viewport.current.on('drag-start', (event) => {
       imperative.current.onPan();
     });
 
-    // app.stage.addChild(links);
-    // app.stage.addChild(nodes);
     app.stage.eventMode = 'dynamic';
     app.stage.on('mouseup', onDragEnd);
     app.stage.on('pointerup', onDragEnd);
     app.stage.on('mousemove', onDragMove);
     app.stage.on('mouseup', onDragEnd);
 
-    app.ticker.add(tick);
-
     nodeMap.current.clear();
     linkMap.current.clear();
-    update();
+    update(true);
     isSetup.current = true;
   };
 
+  const setupLayout = (forceClear: boolean) => {
+    const layoutFactory = new LayoutFactory();
+    layoutAlgorithm.current = layoutFactory.createLayout(config.LAYOUT_ALGORITHM);
+
+    if (!layoutAlgorithm) throw Error('LayoutAlgorithm is undefined');
+
+    const graphologyGraph = new MultiGraph();
+    props.graph?.nodes.forEach((node) => {
+      if (forceClear) graphologyGraph.addNode(node.id, { size: node.radius || 5 });
+      else graphologyGraph.addNode(node.id, { size: node.radius || 5, x: node.x || 0, y: node.y || 0 });
+    });
+
+    props.graph?.links.forEach((link) => {
+      graphologyGraph.addEdge(link.source, link.target);
+    });
+    const boundingBox = { x1: 0, x2: app.renderer.screen.width, y1: 0, y2: app.renderer.screen.height };
+
+    if (forceClear) {
+      const startingLayout = layoutFactory.createLayout('Graphology_random');
+      startingLayout.layout(graphologyGraph, boundingBox);
+    }
+    layoutAlgorithm.current.layout(graphologyGraph, boundingBox);
+  };
   return (
     <>
       {mouseInCanvas.current && popups.map((popup) => <NLPopup onClose={() => {}} data={popup} key={popup.node.id} />)}
diff --git a/libs/shared/lib/vis/visualizations/nodelinkvis/nodelinkvis.stories.tsx b/libs/shared/lib/vis/visualizations/nodelinkvis/nodelinkvis.stories.tsx
index bcbc513fdbfd7ddd681bed356a37a993425dc004..72719dc5aed97c5a7b4e1bb1e96b187f6db97dc7 100644
--- a/libs/shared/lib/vis/visualizations/nodelinkvis/nodelinkvis.stories.tsx
+++ b/libs/shared/lib/vis/visualizations/nodelinkvis/nodelinkvis.stories.tsx
@@ -10,7 +10,13 @@ import {
 } from '../../../data-access/store';
 import { configureStore } from '@reduxjs/toolkit';
 import { Provider } from 'react-redux';
-import { big2ndChamberQueryResult, smallFlightsQueryResults, mockLargeQueryResults } from '../../../mock-data';
+import {
+  big2ndChamberQueryResult,
+  smallFlightsQueryResults,
+  mockLargeQueryResults,
+  recommendationPersonActedInMovieQueryResultPayload,
+  slackReactionToThreadedMessageQueryResultPayload,
+} from '../../../mock-data';
 import { setActiveVisualization } from '@graphpolaris/shared/lib/data-access/store/visualizationSlice';
 
 const Component: Meta<typeof VisualizationPanel> = {
@@ -65,6 +71,33 @@ export const TestWithData = {
   },
 };
 
+export const TestWithDoubleArchData = {
+  layout: 'fullscreen',
+  play: async () => {
+    const dispatch = Mockstore.dispatch;
+
+    dispatch(
+      setNewGraphQueryResult({
+        queryID: '1',
+        result: {
+          type: 'nodelink',
+          payload: {
+            nodes: [
+              { id: 'agent/007', attributes: { name: 'Daniel Craig' } },
+              { id: 'villain', attributes: { name: 'Le Chiffre' } },
+            ],
+            edges: [
+              { id: 'escape/escape', from: 'agent/007', to: 'villain', attributes: { name: 'Escape' } },
+              { id: 'escape/escape', to: 'agent/007', from: 'villain', attributes: { name: 'Escape' } },
+            ],
+          },
+        },
+      }),
+    );
+    dispatch(setActiveVisualization(Visualizations.NodeLink));
+  },
+};
+
 export const TestWithNoData = {
   args: { loading: false },
   play: async () => {
@@ -111,4 +144,22 @@ export const TestWithLargeQueryResult = {
   },
 };
 
+export const TestWithRecommendationPersonActedInMovieQueryResult = {
+  args: { loading: false },
+  play: async () => {
+    const dispatch = Mockstore.dispatch;
+    dispatch(setNewGraphQueryResult(recommendationPersonActedInMovieQueryResultPayload));
+    dispatch(setActiveVisualization(Visualizations.NodeLink));
+  },
+};
+
+export const TestWithSlackReactionToThreadedMessageQueryResult = {
+  args: { loading: false },
+  play: async () => {
+    const dispatch = Mockstore.dispatch;
+    dispatch(setNewGraphQueryResult(slackReactionToThreadedMessageQueryResultPayload));
+    dispatch(setActiveVisualization(Visualizations.NodeLink));
+  },
+};
+
 export default Component;
diff --git a/libs/shared/lib/vis/visualizations/nodelinkvis/nodelinkvis.tsx b/libs/shared/lib/vis/visualizations/nodelinkvis/nodelinkvis.tsx
index 6c86c681c506e798f44afe892a62be241c18a40d..f9a42c5d51cc9f3e34dbc256cad9987624fe6efc 100644
--- a/libs/shared/lib/vis/visualizations/nodelinkvis/nodelinkvis.tsx
+++ b/libs/shared/lib/vis/visualizations/nodelinkvis/nodelinkvis.tsx
@@ -5,8 +5,9 @@ import { parseQueryResult } from './components/query2NL';
 import { useImmer } from 'use-immer';
 import { ML, setShortestPathSource, setShortestPathTarget } from '../../../data-access/store/mlSlice';
 import { VisualizationPropTypes, VISComponentType } from '../../types';
+import { Layouts } from '../../../graph-layout/types';
 
-export const NodeLinkVis = React.memo(({ data, ml, dispatch }: VisualizationPropTypes) => {
+export const NodeLinkVis = React.memo(({ data, ml, dispatch, settings }: VisualizationPropTypes) => {
   const ref = useRef<HTMLDivElement>(null);
   const [graph, setGraph] = useImmer<GraphType | undefined>(undefined);
   const [highlightNodes, setHighlightNodes] = useState<NodeType[]>([]);
@@ -18,7 +19,7 @@ export const NodeLinkVis = React.memo(({ data, ml, dispatch }: VisualizationProp
         parseQueryResult(data, ml, {
           defaultX: (ref.current?.clientWidth || 1000) / 2,
           defaultY: (ref.current?.clientHeight || 1000) / 2,
-        })
+        }),
       );
     }
   }, [data, ml]);
@@ -55,18 +56,15 @@ export const NodeLinkVis = React.memo(({ data, ml, dispatch }: VisualizationProp
   };
 
   return (
-    <>
-      <div className="h-full w-full overflow-hidden" ref={ref}>
-        <NLPixi
-          graph={graph}
-          highlightNodes={highlightNodes}
-          highlightedLinks={highlightedLinks}
-          onClick={(node, pos) => {
-            onClickedNode(node, ml);
-          }}
-        />
-      </div>
-    </>
+    <NLPixi
+      graph={graph}
+      highlightNodes={highlightNodes}
+      highlightedLinks={highlightedLinks}
+      onClick={(node, pos) => {
+        onClickedNode(node, ml);
+      }}
+      layoutAlgorithm={settings.layout}
+    />
   );
 });
 
@@ -75,10 +73,10 @@ export const NodeLinkComponent: VISComponentType = {
   VIS: NodeLinkVis,
   settings: {
     layout: {
-      value: 'Force directed',
+      value: Layouts.FORCEATLAS2WEBWORKER as string,
       type: 'dropdown',
       label: 'Layout',
-      options: ['Force directed'],
+      options: Object.values(Layouts) as string[],
       description: 'Select a layout that is used for the visualization',
     },
   },
diff --git a/libs/shared/lib/vis/visualizations/paohvis/paohvis.stories.tsx b/libs/shared/lib/vis/visualizations/paohvis/paohvis.stories.tsx
index bb1042048bae3f715ed0138b264a39d51fbfc898..6b20d52456c9f16f179ccd066bd9a70a4690106e 100644
--- a/libs/shared/lib/vis/visualizations/paohvis/paohvis.stories.tsx
+++ b/libs/shared/lib/vis/visualizations/paohvis/paohvis.stories.tsx
@@ -104,7 +104,7 @@ export const TestWithMarieBoucherSample = {
     const schema = SchemaUtils.schemaBackend2Graphology(marieBoucherSampleSchemaRaw);
 
     dispatch(setSchema(schema.export()));
-    dispatch(assignNewGraphQueryResult({ queryID: '1', result: { type: 'nodelink', payload: marieBoucherSample } }));
+    dispatch(setNewGraphQueryResult({ queryID: '1', result: { type: 'nodelink', payload: marieBoucherSample } }));
     dispatch(setActiveVisualization('PaohVis'));
   },
 };
@@ -135,7 +135,7 @@ export const TestWithRecommendationsActorMovie = {
     const dispatch = Mockstore.dispatch;
     const schema = SchemaUtils.schemaBackend2Graphology(marieBoucherSampleSchemaRaw);
     dispatch(setSchema(schema.export()));
-    dispatch(assignNewGraphQueryResult({ queryID: '1', result: { type: 'nodelink', payload: mockRecommendationsActorMovie } }));
+    dispatch(setNewGraphQueryResult({ queryID: '1', result: { type: 'nodelink', payload: mockRecommendationsActorMovie } }));
     dispatch(setActiveVisualization('PaohVis'));
   },
 };
diff --git a/libs/shared/lib/vis/visualizations/semanticsubstratesvis/semanticsubstratesvis.stories.tsx b/libs/shared/lib/vis/visualizations/semanticsubstratesvis/semanticsubstratesvis.stories.tsx
index a618ef2ae003ae9fa013255d4920889f137abcb2..752304cb0663f7cf8a7f7d920580d4bf0f29d498 100644
--- a/libs/shared/lib/vis/visualizations/semanticsubstratesvis/semanticsubstratesvis.stories.tsx
+++ b/libs/shared/lib/vis/visualizations/semanticsubstratesvis/semanticsubstratesvis.stories.tsx
@@ -4,7 +4,7 @@ import { VisualizationPanel } from '../../visualizationPanel';
 import { SchemaUtils } from '../../../schema/schema-utils';
 
 import {
-  assignNewGraphQueryResult,
+  setNewGraphQueryResult,
   graphQueryResultSlice,
   querybuilderSlice,
   schemaSlice,
@@ -59,7 +59,7 @@ export const TestWithBig2ndChamber = {
     const dispatch = Mockstore.dispatch;
     const schema = SchemaUtils.schemaBackend2Graphology(big2ndChamberSchemaRaw);
     dispatch(setSchema(schema.export()));
-    dispatch(assignNewGraphQueryResult({ queryID: '1', result: { type: 'nodelink', payload: big2ndChamberQueryResult } }));
+    dispatch(setNewGraphQueryResult({ queryID: '1', result: { type: 'nodelink', payload: big2ndChamberQueryResult } }));
     dispatch(setActiveVisualization('SemSubstrVis'));
   },
 };
@@ -69,7 +69,7 @@ export const TestWithRecommendationsActorMovie = {
     const dispatch = Mockstore.dispatch;
     const schema = SchemaUtils.schemaBackend2Graphology(marieBoucherSampleSchemaRaw);
     dispatch(setSchema(schema.export()));
-    dispatch(assignNewGraphQueryResult({ queryID: '1', result: { type: 'nodelink', payload: mockRecommendationsActorMovie } }));
+    dispatch(setNewGraphQueryResult({ queryID: '1', result: { type: 'nodelink', payload: mockRecommendationsActorMovie } }));
     dispatch(setActiveVisualization('SemSubstrVis'));
   },
 };
@@ -79,7 +79,7 @@ export const TestWithGOTcharacter2character = {
     const dispatch = Mockstore.dispatch;
     const schema = SchemaUtils.schemaBackend2Graphology(marieBoucherSampleSchemaRaw);
     dispatch(setSchema(schema.export()));
-    dispatch(assignNewGraphQueryResult({ queryID: '1', result: { type: 'nodelink', payload: gotCharacter2Character } }));
+    dispatch(setNewGraphQueryResult({ queryID: '1', result: { type: 'nodelink', payload: gotCharacter2Character } }));
     dispatch(setActiveVisualization('SemSubstrVis'));
   },
 };