diff --git a/package-lock.json b/package-lock.json
index 97c3e70bc3842ffdf9cb366fd9e788651ee9ded9..5d701b8d239b2d9db1d84a5aed8d5597a2e375f4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2191,6 +2191,302 @@
       "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=",
       "dev": true
     },
+    "d3": {
+      "version": "5.9.2",
+      "resolved": "https://registry.npmjs.org/d3/-/d3-5.9.2.tgz",
+      "integrity": "sha512-ydrPot6Lm3nTWH+gJ/Cxf3FcwuvesYQ5uk+j/kXEH/xbuYWYWTMAHTJQkyeuG8Y5WM5RSEYB41EctUrXQQytRQ==",
+      "dev": true,
+      "requires": {
+        "d3-array": "1",
+        "d3-axis": "1",
+        "d3-brush": "1",
+        "d3-chord": "1",
+        "d3-collection": "1",
+        "d3-color": "1",
+        "d3-contour": "1",
+        "d3-dispatch": "1",
+        "d3-drag": "1",
+        "d3-dsv": "1",
+        "d3-ease": "1",
+        "d3-fetch": "1",
+        "d3-force": "1",
+        "d3-format": "1",
+        "d3-geo": "1",
+        "d3-hierarchy": "1",
+        "d3-interpolate": "1",
+        "d3-path": "1",
+        "d3-polygon": "1",
+        "d3-quadtree": "1",
+        "d3-random": "1",
+        "d3-scale": "2",
+        "d3-scale-chromatic": "1",
+        "d3-selection": "1",
+        "d3-shape": "1",
+        "d3-time": "1",
+        "d3-time-format": "2",
+        "d3-timer": "1",
+        "d3-transition": "1",
+        "d3-voronoi": "1",
+        "d3-zoom": "1"
+      }
+    },
+    "d3-array": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz",
+      "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==",
+      "dev": true
+    },
+    "d3-axis": {
+      "version": "1.0.12",
+      "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.12.tgz",
+      "integrity": "sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ==",
+      "dev": true
+    },
+    "d3-brush": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.0.6.tgz",
+      "integrity": "sha512-lGSiF5SoSqO5/mYGD5FAeGKKS62JdA1EV7HPrU2b5rTX4qEJJtpjaGLJngjnkewQy7UnGstnFd3168wpf5z76w==",
+      "dev": true,
+      "requires": {
+        "d3-dispatch": "1",
+        "d3-drag": "1",
+        "d3-interpolate": "1",
+        "d3-selection": "1",
+        "d3-transition": "1"
+      }
+    },
+    "d3-chord": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.6.tgz",
+      "integrity": "sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA==",
+      "dev": true,
+      "requires": {
+        "d3-array": "1",
+        "d3-path": "1"
+      }
+    },
+    "d3-collection": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.7.tgz",
+      "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==",
+      "dev": true
+    },
+    "d3-color": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.2.3.tgz",
+      "integrity": "sha512-x37qq3ChOTLd26hnps36lexMRhNXEtVxZ4B25rL0DVdDsGQIJGB18S7y9XDwlDD6MD/ZBzITCf4JjGMM10TZkw==",
+      "dev": true
+    },
+    "d3-contour": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-1.3.2.tgz",
+      "integrity": "sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg==",
+      "dev": true,
+      "requires": {
+        "d3-array": "^1.1.1"
+      }
+    },
+    "d3-dispatch": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.5.tgz",
+      "integrity": "sha512-vwKx+lAqB1UuCeklr6Jh1bvC4SZgbSqbkGBLClItFBIYH4vqDJCA7qfoy14lXmJdnBOdxndAMxjCbImJYW7e6g==",
+      "dev": true
+    },
+    "d3-drag": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.3.tgz",
+      "integrity": "sha512-8S3HWCAg+ilzjJsNtWW1Mutl74Nmzhb9yU6igspilaJzeZVFktmY6oO9xOh5TDk+BM2KrNFjttZNoJJmDnkjkg==",
+      "dev": true,
+      "requires": {
+        "d3-dispatch": "1",
+        "d3-selection": "1"
+      }
+    },
+    "d3-dsv": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.1.1.tgz",
+      "integrity": "sha512-1EH1oRGSkeDUlDRbhsFytAXU6cAmXFzc52YUe6MRlPClmWb85MP1J5x+YJRzya4ynZWnbELdSAvATFW/MbxaXw==",
+      "dev": true,
+      "requires": {
+        "commander": "2",
+        "iconv-lite": "0.4",
+        "rw": "1"
+      }
+    },
+    "d3-ease": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.5.tgz",
+      "integrity": "sha512-Ct1O//ly5y5lFM9YTdu+ygq7LleSgSE4oj7vUt9tPLHUi8VCV7QoizGpdWRWAwCO9LdYzIrQDg97+hGVdsSGPQ==",
+      "dev": true
+    },
+    "d3-fetch": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-1.1.2.tgz",
+      "integrity": "sha512-S2loaQCV/ZeyTyIF2oP8D1K9Z4QizUzW7cWeAOAS4U88qOt3Ucf6GsmgthuYSdyB2HyEm4CeGvkQxWsmInsIVA==",
+      "dev": true,
+      "requires": {
+        "d3-dsv": "1"
+      }
+    },
+    "d3-force": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.2.1.tgz",
+      "integrity": "sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg==",
+      "dev": true,
+      "requires": {
+        "d3-collection": "1",
+        "d3-dispatch": "1",
+        "d3-quadtree": "1",
+        "d3-timer": "1"
+      }
+    },
+    "d3-format": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.3.2.tgz",
+      "integrity": "sha512-Z18Dprj96ExragQ0DeGi+SYPQ7pPfRMtUXtsg/ChVIKNBCzjO8XYJvRTC1usblx52lqge56V5ect+frYTQc8WQ==",
+      "dev": true
+    },
+    "d3-geo": {
+      "version": "1.11.3",
+      "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.11.3.tgz",
+      "integrity": "sha512-n30yN9qSKREvV2fxcrhmHUdXP9TNH7ZZj3C/qnaoU0cVf/Ea85+yT7HY7i8ySPwkwjCNYtmKqQFTvLFngfkItQ==",
+      "dev": true,
+      "requires": {
+        "d3-array": "1"
+      }
+    },
+    "d3-hierarchy": {
+      "version": "1.1.8",
+      "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.8.tgz",
+      "integrity": "sha512-L+GHMSZNwTpiq4rt9GEsNcpLa4M96lXMR8M/nMG9p5hBE0jy6C+3hWtyZMenPQdwla249iJy7Nx0uKt3n+u9+w==",
+      "dev": true
+    },
+    "d3-interpolate": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.3.2.tgz",
+      "integrity": "sha512-NlNKGopqaz9qM1PXh9gBF1KSCVh+jSFErrSlD/4hybwoNX/gt1d8CDbDW+3i+5UOHhjC6s6nMvRxcuoMVNgL2w==",
+      "dev": true,
+      "requires": {
+        "d3-color": "1"
+      }
+    },
+    "d3-path": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.7.tgz",
+      "integrity": "sha512-q0cW1RpvA5c5ma2rch62mX8AYaiLX0+bdaSM2wxSU9tXjU4DNvkx9qiUvjkuWCj3p22UO/hlPivujqMiR9PDzA==",
+      "dev": true
+    },
+    "d3-polygon": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.5.tgz",
+      "integrity": "sha512-RHhh1ZUJZfhgoqzWWuRhzQJvO7LavchhitSTHGu9oj6uuLFzYZVeBzaWTQ2qSO6bz2w55RMoOCf0MsLCDB6e0w==",
+      "dev": true
+    },
+    "d3-quadtree": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.6.tgz",
+      "integrity": "sha512-NUgeo9G+ENQCQ1LsRr2qJg3MQ4DJvxcDNCiohdJGHt5gRhBW6orIB5m5FJ9kK3HNL8g9F4ERVoBzcEwQBfXWVA==",
+      "dev": true
+    },
+    "d3-random": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.2.tgz",
+      "integrity": "sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ==",
+      "dev": true
+    },
+    "d3-scale": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.2.2.tgz",
+      "integrity": "sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw==",
+      "dev": true,
+      "requires": {
+        "d3-array": "^1.2.0",
+        "d3-collection": "1",
+        "d3-format": "1",
+        "d3-interpolate": "1",
+        "d3-time": "1",
+        "d3-time-format": "2"
+      }
+    },
+    "d3-scale-chromatic": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.3.3.tgz",
+      "integrity": "sha512-BWTipif1CimXcYfT02LKjAyItX5gKiwxuPRgr4xM58JwlLocWbjPLI7aMEjkcoOQXMkYsmNsvv3d2yl/OKuHHw==",
+      "dev": true,
+      "requires": {
+        "d3-color": "1",
+        "d3-interpolate": "1"
+      }
+    },
+    "d3-selection": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.0.tgz",
+      "integrity": "sha512-EYVwBxQGEjLCKF2pJ4+yrErskDnz5v403qvAid96cNdCMr8rmCYfY5RGzWz24mdIbxmDf6/4EAH+K9xperD5jg==",
+      "dev": true
+    },
+    "d3-shape": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.5.tgz",
+      "integrity": "sha512-VKazVR3phgD+MUCldapHD7P9kcrvPcexeX/PkMJmkUov4JM8IxsSg1DvbYoYich9AtdTsa5nNk2++ImPiDiSxg==",
+      "dev": true,
+      "requires": {
+        "d3-path": "1"
+      }
+    },
+    "d3-time": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.0.11.tgz",
+      "integrity": "sha512-Z3wpvhPLW4vEScGeIMUckDW7+3hWKOQfAWg/U7PlWBnQmeKQ00gCUsTtWSYulrKNA7ta8hJ+xXc6MHrMuITwEw==",
+      "dev": true
+    },
+    "d3-time-format": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.1.3.tgz",
+      "integrity": "sha512-6k0a2rZryzGm5Ihx+aFMuO1GgelgIz+7HhB4PH4OEndD5q2zGn1mDfRdNrulspOfR6JXkb2sThhDK41CSK85QA==",
+      "dev": true,
+      "requires": {
+        "d3-time": "1"
+      }
+    },
+    "d3-timer": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.9.tgz",
+      "integrity": "sha512-rT34J5HnQUHhcLvhSB9GjCkN0Ddd5Y8nCwDBG2u6wQEeYxT/Lf51fTFFkldeib/sE/J0clIe0pnCfs6g/lRbyg==",
+      "dev": true
+    },
+    "d3-transition": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.2.0.tgz",
+      "integrity": "sha512-VJ7cmX/FPIPJYuaL2r1o1EMHLttvoIuZhhuAlRoOxDzogV8iQS6jYulDm3xEU3TqL80IZIhI551/ebmCMrkvhw==",
+      "dev": true,
+      "requires": {
+        "d3-color": "1",
+        "d3-dispatch": "1",
+        "d3-ease": "1",
+        "d3-interpolate": "1",
+        "d3-selection": "^1.1.0",
+        "d3-timer": "1"
+      }
+    },
+    "d3-voronoi": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.4.tgz",
+      "integrity": "sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg==",
+      "dev": true
+    },
+    "d3-zoom": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.7.3.tgz",
+      "integrity": "sha512-xEBSwFx5Z9T3/VrwDkMt+mr0HCzv7XjpGURJ8lWmIC8wxe32L39eWHIasEe/e7Ox8MPU4p1hvH8PKN2olLzIBg==",
+      "dev": true,
+      "requires": {
+        "d3-dispatch": "1",
+        "d3-drag": "1",
+        "d3-interpolate": "1",
+        "d3-selection": "1",
+        "d3-transition": "1"
+      }
+    },
     "dashdash": {
       "version": "1.14.1",
       "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
@@ -6520,6 +6816,12 @@
         "aproba": "^1.1.1"
       }
     },
+    "rw": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
+      "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=",
+      "dev": true
+    },
     "safe-buffer": {
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
diff --git a/package.json b/package.json
index e4da75a48b6fc5f482ac32991b85652e4b9196fc..d20274be287f44bac542b41955d6dce8b2d0d231 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
     "@babel/preset-env": "^7.4.5",
     "babel-loader": "^8.0.6",
     "css-loader": "^2.1.1",
+    "d3": "^5.9.2",
     "file-loader": "^3.0.1",
     "html-loader": "^0.5.5",
     "html-webpack-plugin": "^3.2.0",
diff --git a/src/app.js b/src/app.js
index cddfe220d4574e359546f2c324a7f5220c52a9d5..49f6a7740b0a2c866dade27b57fe2798e3bc23e6 100644
--- a/src/app.js
+++ b/src/app.js
@@ -1,12 +1,3 @@
-import {Graph} from "./js/graph/graph";
-import {Edge} from "./js/graph/edge";
-import {Node} from "./js/graph/node";
-import {Neo4JAdapter} from "./js/neo4j/neo"
+import {Visualizer} from './js/visualizer/visualizer'
 
-var graph = new Graph();
-
-var neo = new Neo4JAdapter('neo4j', 'W7uFSy$ywR3M3ck');
-
-graph = neo.getGraph();
-
-console.log(graph);
\ No newline at end of file
+new Visualizer().plotGraph('match (a:Issue{id:4})<-[r*..]-(b) return *');
\ No newline at end of file
diff --git a/src/index.html b/src/index.html
index 8231315c293c3e412900d4166cb2a67921e15d67..6d3a0bbd7052430dddd2d1ac6cd1fbde799d87b6 100644
--- a/src/index.html
+++ b/src/index.html
@@ -1,9 +1,14 @@
 <!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <title>Foo</title>
-</head>
-<body>
-</body>
-</html>
\ No newline at end of file
+<meta charset="utf-8">
+<style>
+    body {
+        font-family: "Inconsolata";
+    }
+    circle {
+        fill: aquamarine;
+    }
+    line {
+        stroke: blueviolet;
+    }
+</style>
+<svg width="960" height="600"></svg>
\ No newline at end of file
diff --git a/src/js/graph/edge.js b/src/js/graph/edge.js
deleted file mode 100644
index c6911f0ae24acd03482077d80c61abd992dee397..0000000000000000000000000000000000000000
--- a/src/js/graph/edge.js
+++ /dev/null
@@ -1,10 +0,0 @@
-export class Edge {
-
-    constructor(id, properties, type, start, end) {
-        this.id = id;
-        this.properties = properties;
-        this.type = type;
-        this.start = start;
-        this.end = end;
-    }
-}
\ No newline at end of file
diff --git a/src/js/graph/graph.js b/src/js/graph/graph.js
index af8dde920a28e139fb9b2401b6f9176fc3ac8cae..7c174e220d46f7ab32e75b2399d7240f5e02cdf3 100644
--- a/src/js/graph/graph.js
+++ b/src/js/graph/graph.js
@@ -1,42 +1,27 @@
-import {Edge} from './edge'
-
 export class Graph {
 
-    constructor() {
-        this.edges = {};
-        this.nodes = {};
+    constructor(){
+        this.nodes = new Array();
+        this.edges = new Array();
     }
 
-    addEdge(edge) {
-        if (!(edge.id in this.edges)) {
-            this.edges[edge.id] = edge;
-            console.log("Added: " + JSON.stringify(edge) + " to edges.");
-        }
-    };
-
-    addNode(node) {
-        if (!(node.id in this.nodes)) {
-            this.nodes[node.id] = node;
-            console.log("Added: " + JSON.stringify(node) + " to nodes.");
-        }
-    };
-
-    _asList(dict) {
-        var list = [];
-        for (var key in dict) {
-            if (dict.hasOwnProperty(key)) {
-                list.push(dict[key]);
-            }
-        }
-        return list;
+    addNode(newNode){
+        this.nodes.push(newNode);
+        this.nodes = this.getUnique(this.nodes, "id");
     }
 
-    get edgesAsList() {
-        return this._asList(this.edges);
+    addEdge(newEdge){
+        this.edges.push(newEdge);
     }
 
-    get nodesAsList() {
-        return this._asList(this.nodes);
+    getUnique(arr, comp) {
+        const unique = arr
+            .map(e => e[comp])
+            // store the keys of the unique objects
+            .map((e, i, final) => final.indexOf(e) === i && i)
+            // eliminate the dead keys & store unique objects
+            .filter(e => arr[e]).map(e => arr[e]);
+        return unique;
     }
 
 }
\ No newline at end of file
diff --git a/src/js/graph/graphCreator.js b/src/js/graph/graphCreator.js
new file mode 100644
index 0000000000000000000000000000000000000000..d673a3338388f327c51aa203947207d950a2879c
--- /dev/null
+++ b/src/js/graph/graphCreator.js
@@ -0,0 +1,27 @@
+import {Neo4JAdapter} from '../neo4j/neo'
+import {v1 as neo4j} from 'neo4j-driver'
+export class GraphCreator{
+
+    async fill(graph, withQuery){
+        const queryResult = await new Neo4JAdapter('neo4j', 'W7uFSy$ywR3M3ck').ask(withQuery);
+        var records = queryResult.records;
+        records.forEach(function (record) {
+            record.forEach(function (element) {
+                if (element instanceof neo4j.types.Node) {
+                    var id = element.identity.toInt();
+                    var newNode = {"id": id};
+                    graph.addNode(newNode);
+                } else if (element instanceof neo4j.types.Relationship) {
+                    var newEdge = {"source": element.start.toInt(), "target": element.end.toInt()};
+                    graph.addEdge(newEdge);
+                } else if (element instanceof Array) {
+                    element.forEach(function (relation) {
+                        var newEdge = {"source": relation.start.toInt(), "target": relation.end.toInt()};
+                        graph.addEdge(newEdge);
+                    })
+                }
+            });
+        });
+        return graph;
+    }
+}
\ No newline at end of file
diff --git a/src/js/graph/node.js b/src/js/graph/node.js
deleted file mode 100644
index 30f0ed5b1911c0bd2a19b085f156c845c05834fc..0000000000000000000000000000000000000000
--- a/src/js/graph/node.js
+++ /dev/null
@@ -1,8 +0,0 @@
-export class Node {
-
-    constructor(id, properties, labels) {
-        this.id = id;
-        this.properties = properties;
-        this.labels = labels
-    }
-}
\ No newline at end of file
diff --git a/src/js/neo4j/neo.js b/src/js/neo4j/neo.js
index 995c7d9af0dcf6d811fe749581ee5b892c359412..bce85427e25f526b9c5651011be4565a8154756b 100644
--- a/src/js/neo4j/neo.js
+++ b/src/js/neo4j/neo.js
@@ -1,7 +1,4 @@
 import {v1 as neo4j} from 'neo4j-driver'
-import {Edge} from '../graph/edge'
-import {Node} from '../graph/node'
-import {Graph} from '../graph/graph'
 
 export class Neo4JAdapter {
     constructor(username, password) {
@@ -10,33 +7,12 @@ export class Neo4JAdapter {
         this.authToken = neo4j.auth.basic(this.username, this.password);
     }
 
-    getGraph(graph) {
-
-        const driver = neo4j.driver('bolt://localhost:7687', this.authToken, {
-            encrypted: false
-        });
-
+    async ask(query){
+        const driver = neo4j.driver('bolt://localhost:7687', this.authToken);
         const session = driver.session();
-
-
-        const resultPromise = session.run(
-            'match (a:User)<-[r]-() return *'
-        );
-
-        var graph = new Graph();
-        resultPromise.then(result => {
-            session.close();
-            result.records.forEach(function (element) {
-                element.forEach(function (subelement) {
-                    if (subelement instanceof neo4j.types.Node) {
-                        graph.addNode(new Node(subelement.identity.toInt(), subelement.properties, subelement.labels));
-                    } else if (subelement instanceof neo4j.types.Relationship) {
-                        graph.addEdge(new Edge(subelement.identity.toInt(), subelement.properties, subelement.type, subelement.start.toInt(), subelement.end.toInt()));
-                    }
-                });
-            });
-            driver.close();
-        });
-        return graph
+        const result = await session.run(query);
+        session.close();
+        driver.close();
+        return result;
     }
 }
diff --git a/src/js/visualizer/visualizer.js b/src/js/visualizer/visualizer.js
new file mode 100644
index 0000000000000000000000000000000000000000..f39a73ec28f58929f3b1853da2056743e65a17d6
--- /dev/null
+++ b/src/js/visualizer/visualizer.js
@@ -0,0 +1,126 @@
+import * as d3 from 'd3'
+import {Neo4JAdapter} from '../neo4j/neo'
+import {Graph} from '../graph/graph'
+import {GraphCreator} from '../graph/graphCreator'
+import {v1 as neo4j} from 'neo4j-driver'
+
+export class Visualizer {
+
+    async plotGraph(query) {
+        const graph = await new GraphCreator().fill(new Graph(), query);
+
+        var svg = d3.select("svg");
+        var width = +svg.attr("width");
+        var height = +svg.attr("height");
+
+        var simulation = d3.forceSimulation()
+            .force("link", d3.forceLink().id(function (d) {
+                return d.id;
+            }))
+            .force('charge', d3.forceManyBody()
+                .strength(0)
+                .theta(1)
+                .distanceMax(10)
+            )
+            .force('collide', d3.forceCollide().radius(d => 40)
+                .iterations(2)
+            )
+            .force("center", d3.forceCenter(width / 2, height / 2));
+
+
+        this.run(svg, simulation, graph);
+    }
+
+
+    async run(svg, simulation, graph) {
+
+        function dragstarted(d) {
+            if (!d3.event.active) simulation.alphaTarget(0.2).restart()
+            d.fx = d.x;
+            d.fy = d.y;
+        }
+
+        function dragged(d) {
+            d.fx = d3.event.x;
+            d.fy = d3.event.y;
+        }
+
+        function dragended(d) {
+            if (!d3.event.active) simulation.alphaTarget(0);
+            d.fx = null;
+            d.fy = null;
+        }
+
+        var link = svg.append("g")
+            .selectAll("line")
+            .data(graph.edges)
+            .enter()
+            .append("line");
+
+        var node = svg.append("g")
+            .attr("class", "nodes")
+            .selectAll("circle")
+            .data(graph.nodes)
+            .enter()
+            .append("circle")
+            .call(d3.drag()
+                .on("start", dragstarted)
+                .on("drag", dragged)
+                .on("end", dragended));
+
+        var label = svg.append("g")
+            .attr("class", "labels")
+            .selectAll("text")
+            .data(graph.nodes)
+            .enter()
+            .append("text")
+            .attr("class", "label")
+            .text(function (d) {
+                return d.id;
+            });
+
+        simulation
+            .nodes(graph.nodes)
+            .on("tick", ticked);
+
+        simulation.force("link")
+            .links(graph.edges);
+
+        function ticked() {
+            link
+                .attr("x1", function (d) {
+                    return d.source.x;
+                })
+                .attr("y1", function (d) {
+                    return d.source.y;
+                })
+                .attr("x2", function (d) {
+                    return d.target.x;
+                })
+                .attr("y2", function (d) {
+                    return d.target.y;
+                });
+
+            node
+                .attr("r", 10)
+                .style("stroke", "#424242")
+                .style("stroke-width", "2px")
+                .attr("cx", function (d) {
+                    return d.x + 3;
+                })
+                .attr("cy", function (d) {
+                    return d.y - 3;
+                });
+
+            label
+                .attr("x", function (d) {
+                    return d.x;
+                })
+                .attr("y", function (d) {
+                    return d.y;
+                })
+                .style("font-size", "10px").style("fill", "#333");
+        }
+    }
+
+}
\ No newline at end of file