diff --git a/src/common/graph/graph.ts b/src/common/graph/graph.ts
index 80715515d0b428e1784b30565e4348ac9e9b5a73..9b9a61515a8077e4480afd9dec7346f84af04476 100644
--- a/src/common/graph/graph.ts
+++ b/src/common/graph/graph.ts
@@ -77,7 +77,6 @@ export class Graph
             this.idToLink.set(link.id, link);
         });
 
-        this.connectElementsToGraph();
         this.updateNodeData();
         this.initializeIdGeneration();
     }
@@ -92,24 +91,19 @@ export class Graph
     }
 
     private initializeIdGeneration() {
-        this.nextNodeId = Math.max(...this.nodes.map((node) => node.id)) + 1;
+        const ids = this.nodes
+            .map((node) => node.id)
+            .filter((id) => typeof id == "number");
+
+        // TODO: Prevent ids from being -Infinity if ids is empty
+        //this.nextNodeId = Math.max(...this.nodes.map((node) => node.id)) + 1;
+        this.nextNodeId = Math.max(...ids) + 1; // TODO: Remove non-numeric ids from dataset and disable check
         this.nextLinkId = Math.max(...this.links.map((link) => link.id)) + 1;
         this.nextObjectGroupId = Math.max(
             ...this.objectGroups.map((group) => group.id)
         );
     }
 
-    /**
-     * Sets the correct graph object for all the graph elements in data.
-     */
-    private connectElementsToGraph() {
-        this.nodes.forEach((n) => (n.graph = this));
-        this.links.forEach((l) => {
-            l.graph = this;
-        });
-        this.objectGroups.forEach((t) => (t.graph = this));
-    }
-
     public toJSONSerializableObject(): GraphData {
         return {
             nodes: this.nodes.map((node) => node.toJSONSerializableObject()),
@@ -146,6 +140,7 @@ export class Graph
         data.links.forEach((link) => this.createLink(link.source, link.target));
 
         this.updateNodeData();
+        this.initializeIdGeneration();
 
         return this;
     }
@@ -209,7 +204,7 @@ export class Graph
     }
 
     public createNode(data?: NodeData | SimNodeData): Node {
-        const node = new Node(this);
+        const node = new Node();
         node.fromSerializedObject(data);
         node.type = this.nameToObjectGroup.get(data.type);
         node.neighbors = [];
@@ -234,7 +229,7 @@ export class Graph
             return;
         }
 
-        const link = new Link(sourceNode, targetNode, this);
+        const link = new Link(sourceNode, targetNode);
         sourceNode.links.push(link);
         targetNode.links.push(link);
         this.addLink(link);
@@ -242,7 +237,7 @@ export class Graph
     }
 
     public createObjectGroup(name?: string, color?: string): NodeType {
-        const group = new NodeType(name, color, this);
+        const group = new NodeType(name, color);
         this.addObjectGroup(group);
         return group;
     }
diff --git a/src/common/graph/graphelement.ts b/src/common/graph/graphelement.ts
index 6e0fe1ef4e4d4580915e2deeec12caca3b34ef31..432905d96c7e0a223e8c6ac1b9e97a51cd738963 100644
--- a/src/common/graph/graphelement.ts
+++ b/src/common/graph/graphelement.ts
@@ -1,25 +1,12 @@
-import { Graph } from "./graph";
 import { SerializableItem } from "../serializableitem";
 
 export class GraphElement<JSONType, HistoryType> extends SerializableItem<
     JSONType,
     HistoryType
 > {
-    public graph: Graph;
-
-    constructor(id = -1, graph: Graph = undefined) {
+    constructor(id = -1) {
         super(id);
         this.equals = this.equals.bind(this);
-
-        this.graph = graph;
-    }
-
-    /**
-     * Removes element from its parent graph.
-     * @returns True, if successful.
-     */
-    public delete() {
-        throw new Error('Function "delete()" has not been implemented.');
     }
 
     public isInitialized(): boolean {
diff --git a/src/common/graph/link.ts b/src/common/graph/link.ts
index a69469f09963e573df66a864c461edab5c7e743f..0aaa37e0397f784ed38c944d4c6d3370403b3585 100644
--- a/src/common/graph/link.ts
+++ b/src/common/graph/link.ts
@@ -1,7 +1,6 @@
 import { GraphElement } from "./graphelement";
 import { Node } from "./node";
 import { NodeType } from "./nodetype";
-import { Graph } from "./graph";
 
 export interface LinkData {
     source: number;
@@ -35,8 +34,8 @@ export class Link
     // These parameters will be added by the force graph implementation
     public index?: number;
 
-    constructor(source?: Node, target?: Node, graph?: Graph) {
-        super(0, graph);
+    constructor(source?: Node, target?: Node) {
+        super(0);
 
         this.equals = this.equals.bind(this);
 
@@ -60,10 +59,6 @@ export class Link
         return this.target.id;
     }
 
-    public delete() {
-        return this.graph.deleteLink(this.id);
-    }
-
     /**
      * Determines if the given node is part of the link structure.
      * @param node Node to check for.
diff --git a/src/common/graph/node.ts b/src/common/graph/node.ts
index 78de57b1040d1b7e9fc3567ab572b307fdcb3ab5..b0c553b99678a74f87b33c712217038712b165c7 100644
--- a/src/common/graph/node.ts
+++ b/src/common/graph/node.ts
@@ -88,40 +88,12 @@ export class Node
     public fy?: number;
     public fz?: number;
 
-    constructor(graph?: Graph) {
-        super(0, graph);
+    constructor() {
+        super(0);
         this.neighbors = [];
         this.links = [];
     }
 
-    public setType(typeId: number) {
-        const newType = this.graph.nameToObjectGroup.get(String(typeId)); // TODO
-
-        // Exists?
-        if (newType === undefined) {
-            return;
-        }
-
-        this.type = newType;
-    }
-
-    public delete() {
-        return this.graph.deleteNode(this.id);
-    }
-
-    /**
-     * Connects this node to a given node. Only works if they are in the same graph.
-     * @param node Other node to connect.
-     * @returns The created link, if successful, otherwise undefined.
-     */
-    public connect(node: Node): Link {
-        if (this.graph !== node.graph) {
-            throw new Error("The connected nodes are not on the same graph!");
-        }
-
-        return this.graph.createLink(this.id, node.id);
-    }
-
     public toJSONSerializableObject(): NodeData {
         return {
             id: this.id,
diff --git a/src/common/graph/nodetype.ts b/src/common/graph/nodetype.ts
index 39862e69c939a4e2d5e35f8b0341ae1d148780ee..45a5353f7036f5cc164d8029ba94c7081fbffd96 100644
--- a/src/common/graph/nodetype.ts
+++ b/src/common/graph/nodetype.ts
@@ -1,5 +1,4 @@
 import { GraphElement } from "./graphelement";
-import { Graph } from "./graph";
 
 export interface NodeTypeData {
     id: number;
@@ -15,8 +14,8 @@ export class NodeType
     public name: string;
     public color: string;
 
-    constructor(name?: string, color?: string, graph?: Graph) {
-        super(0, graph);
+    constructor(name?: string, color?: string) {
+        super(0);
         this.name = name;
         this.color = color;
     }
@@ -34,10 +33,6 @@ export class NodeType
         return this;
     }
 
-    public delete() {
-        return this.graph.deleteNodeType(this.name); // TODO: Change to id
-    }
-
     public toString(): string {
         return this.name;
     }
diff --git a/src/editor/components/instructions.tsx b/src/editor/components/instructions.tsx
index 4b3c3d92bc3b91a3e20b358bb9c8995f528662f1..be8e78d4ed27a715c21ccec649cada60db4dc168 100644
--- a/src/editor/components/instructions.tsx
+++ b/src/editor/components/instructions.tsx
@@ -8,11 +8,11 @@ interface InstructionsProps {
 function Instructions({ connectOnDragEnabled }: InstructionsProps) {
     return (
         <ul className={"instructions"}>
-            <li>Click background to create node</li>
+            <li>Click background to deselect all node</li>
             <li>
                 SHIFT+Click and drag on background to add nodes to selection
             </li>
-            <li>CTRL+Click background to clear selection</li>
+            <li>CTRL+Click background to create a new node</li>
             <li>Click node to select and edit</li>
             <li>SHIFT+Click node to add or remove from selection</li>
             <li>CTRL+Click another node to connect</li>
diff --git a/src/editor/editor.tsx b/src/editor/editor.tsx
index e38f72a3b0ca886286f8582a3909d445de83fce0..35bb633ac2fb089510e2612189d71d53275f81a4 100644
--- a/src/editor/editor.tsx
+++ b/src/editor/editor.tsx
@@ -8,11 +8,12 @@ import { Node, NodeProperties } from "../common/graph/node";
 
 import { SpaceManager } from "./components/spacemanager";
 import SelectLayer from "./components/selectlayer";
-import { GraphData } from "../common/graph/graph";
+import { Coordinate2D, GraphData } from "../common/graph/graph";
 import { NodeType } from "../common/graph/nodetype";
 import { GraphRenderer2D } from "./renderer";
 import * as Config from "../config";
 import Sidepanel from "./components/sidepanel";
+import { Link } from "../common/graph/link";
 
 export interface NodeDataChangeRequest extends NodeProperties {
     id: number;
@@ -76,6 +77,10 @@ export class Editor extends React.PureComponent<any, stateTypes> {
         this.handleBoxSelect = this.handleBoxSelect.bind(this);
         this.selectNodes = this.selectNodes.bind(this);
         this.handleNodeDataChange = this.handleNodeDataChange.bind(this);
+        this.handleNodeCreation = this.handleNodeCreation.bind(this);
+        this.handleNodeDeletion = this.handleNodeDeletion.bind(this);
+        this.handleLinkCreation = this.handleLinkCreation.bind(this);
+        this.handleLinkDeletion = this.handleLinkDeletion.bind(this);
 
         document.addEventListener("keydown", (e) => {
             this.keyPressed(e.key);
@@ -217,6 +222,38 @@ export class Editor extends React.PureComponent<any, stateTypes> {
         this.setState({ graph: graph });
     }
 
+    private handleNodeCreation(position?: Coordinate2D): Node {
+        const graph = Object.assign(new DynamicGraph(), this.state.graph);
+        const node = graph.createNode(undefined, position.x, position.y, 0, 0);
+
+        this.setState({
+            graph: graph,
+            selectedNodes: [node],
+        });
+        return node;
+    }
+
+    private handleNodeDeletion(id: number) {
+        const graph = Object.assign(new DynamicGraph(), this.state.graph);
+        graph.deleteNode(id);
+        this.setState({ graph: graph });
+    }
+
+    private handleLinkCreation(source: number, target: number): Link {
+        const graph = Object.assign(new DynamicGraph(), this.state.graph);
+        const link = graph.createLink(source, target);
+        this.setState({ graph: graph });
+
+        return link;
+    }
+
+    private handleLinkDeletion(id: number) {
+        const graph = Object.assign(new DynamicGraph(), this.state.graph);
+        graph.deleteLink(id);
+
+        this.setState({ graph: graph });
+    }
+
     render(): React.ReactNode {
         return (
             <div id="ks-editor">
@@ -246,6 +283,10 @@ export class Editor extends React.PureComponent<any, stateTypes> {
                                     graph={this.state.graph}
                                     width={this.state.graphWidth}
                                     onNodeSelectionChanged={this.selectNodes}
+                                    onNodeCreation={this.handleNodeCreation}
+                                    onNodeDeletion={this.handleNodeDeletion}
+                                    onLinkCreation={this.handleLinkCreation}
+                                    onLinkDeletion={this.handleLinkDeletion}
                                     selectedNodes={this.state.selectedNodes}
                                     settings={this.state.settings}
                                 />
diff --git a/src/editor/graph.ts b/src/editor/graph.ts
index d55cbd38f58abf67677221365700edde456c77e2..5ef66529fd0053b2fd0b04fb5131cc415d465898 100644
--- a/src/editor/graph.ts
+++ b/src/editor/graph.ts
@@ -8,16 +8,8 @@ import { GraphContent, GraphData, SimGraphData } from "../common/graph/graph";
 export class DynamicGraph extends Common.Graph {
     public history: History<SimGraphData>;
 
-    // Callbacks
-    public onChangeCallbacks: { (data: DynamicGraph): void }[];
-
     constructor(data?: GraphContent) {
         super(data);
-        this.onChangeCallbacks = [];
-
-        super.deleteNode = super.deleteNode.bind(this);
-        super.deleteLink = super.deleteLink.bind(this);
-        super.deleteNodeType = super.deleteNodeType.bind(this);
 
         if (data != undefined) {
             this.history = new History<SimGraphData>(
@@ -39,36 +31,6 @@ export class DynamicGraph extends Common.Graph {
         return this;
     }
 
-    /**
-     * Calls all registered callbacks for the onChange event.
-     * @private
-     */
-    private triggerOnChange() {
-        this.onChangeCallbacks.forEach((fn) => fn(this));
-    }
-
-    /**
-     * Triggers change event on data-redo.
-     */
-    protected onRedo() {
-        if (this.history.hasRedoCheckpoints()) {
-            const checkpoint = this.history.redo();
-            this.fromSerializedObject(checkpoint.data);
-            this.triggerOnChange();
-        }
-    }
-
-    /**
-     * Triggers change event on data-undo.
-     */
-    protected onUndo() {
-        if (this.history.hasUndoCheckpoints()) {
-            const checkpoint = this.history.undo();
-            this.fromSerializedObject(checkpoint.data);
-            this.triggerOnChange();
-        }
-    }
-
     public createObjectGroup(name?: string, color?: string): NodeType {
         if (name == undefined) {
             name = "Unnamed";
@@ -77,7 +39,6 @@ export class DynamicGraph extends Common.Graph {
             color = "#000000";
         }
         const objectGroup = super.createObjectGroup(name, color);
-        this.triggerOnChange();
 
         return objectGroup;
     }
@@ -103,26 +64,6 @@ export class DynamicGraph extends Common.Graph {
         return super.createNode(data);
     }
 
-    private delete(id: string | number, fn: (id: string | number) => boolean) {
-        if (fn(id)) {
-            this.triggerOnChange();
-            return true;
-        }
-        return false;
-    }
-
-    public deleteNodeType(id: string): boolean {
-        return this.delete(id, super.deleteNodeType);
-    }
-
-    public deleteNode(id: number): boolean {
-        return this.delete(id, super.deleteNode);
-    }
-
-    public deleteLink(id: number): boolean {
-        return this.delete(id, super.deleteLink);
-    }
-
     getLink(
         sourceId: number,
         targetId: number,
diff --git a/src/editor/renderer.tsx b/src/editor/renderer.tsx
index b7795d9806a46d5cddbdf30152fd328878b64218..c6c6ae7b890d233696e39f45e05d21ce3b843af9 100644
--- a/src/editor/renderer.tsx
+++ b/src/editor/renderer.tsx
@@ -4,7 +4,6 @@ import { DynamicGraph } from "./graph";
 import { Node } from "../common/graph/node";
 import { ForceGraph2D } from "react-force-graph";
 import { Link } from "../common/graph/link";
-import { GraphElement } from "../common/graph/graphelement";
 import { Coordinate2D } from "../common/graph/graph";
 
 export class GraphRenderer2D extends React.PureComponent<
@@ -19,7 +18,7 @@ export class GraphRenderer2D extends React.PureComponent<
     /**
      * True, if the graph was the target of the most recent click event.
      */
-    private graphInFocus = false; // TODO: Remove?
+    private graphInFocus = false;
     /**
      * True for each key, that is currently considered pressed. If key has not been pressed yet, it will not exist as dict-key.
      */
@@ -30,6 +29,10 @@ export class GraphRenderer2D extends React.PureComponent<
         width: PropTypes.number.isRequired,
         onNodeClicked: PropTypes.func,
         onNodeSelectionChanged: PropTypes.func,
+        onNodeCreation: PropTypes.func,
+        onNodeDeletion: PropTypes.func,
+        onLinkCreation: PropTypes.func,
+        onLinkDeletion: PropTypes.func,
         /**
          * Collection of all currently selected nodes. Can also be undefined or empty.
          */
@@ -45,7 +48,6 @@ export class GraphRenderer2D extends React.PureComponent<
         this.handleNodeClick = this.handleNodeClick.bind(this);
         this.handleEngineStop = this.handleEngineStop.bind(this);
         this.handleNodeDrag = this.handleNodeDrag.bind(this);
-        this.handleElementRightClick = this.handleElementRightClick.bind(this);
         this.screen2GraphCoords = this.screen2GraphCoords.bind(this);
         this.handleNodeCanvasObject = this.handleNodeCanvasObject.bind(this);
         this.handleLinkCanvasObject = this.handleLinkCanvasObject.bind(this);
@@ -59,10 +61,6 @@ export class GraphRenderer2D extends React.PureComponent<
             this.keys[e.key] = false;
             this.handleShortcutEvents(e.key);
         });
-        document.addEventListener(
-            "mousedown",
-            (e) => (this.graphInFocus = false)
-        );
 
         this.state = {
             selectedNodes: [], // TODO: Why was undefined allowed here?
@@ -76,22 +74,6 @@ export class GraphRenderer2D extends React.PureComponent<
         this.warmupTicks = this.defaultWarmupTicks;
     }
 
-    /**
-     * Deletes all nodes currently selected. Handles store points accordingly of the number of deleted nodes.
-     */
-    private deleteSelectedNodes() {
-        const selectedNodes = this.state.selectedNodes;
-
-        if (selectedNodes.length == 1) {
-            selectedNodes[0].delete();
-            selectedNodes.pop();
-            this.props.onNodeSelectionChanged(selectedNodes);
-        } else {
-            selectedNodes.forEach((node: Node) => node.delete());
-            this.props.onNodeSelectionChanged([]);
-        }
-    }
-
     /**
      * Triggers actions that correspond with certain shortcuts.
      *
@@ -104,13 +86,14 @@ export class GraphRenderer2D extends React.PureComponent<
             key === "Delete" &&
             this.graphInFocus // Only delete if 2d-graph is the focused element
         ) {
-            this.deleteSelectedNodes();
+            this.props.selectedNodes.forEach((node: Node) =>
+                this.props.onNodeDeletion(node.id)
+            );
+            this.props.onNodeSelectionChanged([]);
         }
     }
 
     private handleNodeClick(node: Node) {
-        this.graphInFocus = true;
-
         if (this.keys["Control"]) {
             // Connect to clicked node as parent while control is pressed
             if (this.props.selectedNodes.length == 0) {
@@ -136,8 +119,6 @@ export class GraphRenderer2D extends React.PureComponent<
         event: MouseEvent,
         position: { graph: Coordinate2D; window: Coordinate2D }
     ) {
-        this.graphInFocus = true;
-
         // Is there really no node there? Trying to prevent small error, where this event is triggered, even if there is a node.
         const nearestNode = this.props.graph.getClosestNode(
             position.graph.x,
@@ -148,41 +129,18 @@ export class GraphRenderer2D extends React.PureComponent<
             return;
         }
 
-        // Just deselect if control key is pressed
         if (this.keys["Control"]) {
-            this.props.onNodeSelectionChanged([]);
-            return;
-        }
-
-        // Add new node
-        const node = this.state.graph.createNode(
-            undefined,
-            position.graph.x,
-            position.graph.y,
-            0,
-            0
-        );
-        this.forceUpdate(); // TODO: Remove?
-
-        // Select newly created node
-        if (this.keys["Shift"]) {
-            // Simply add to current selection of shift is pressed
-            this.toggleNodeSelection(node);
+            // Request new node
+            this.props.onNodeCreation({
+                x: position.graph.x,
+                y: position.graph.y,
+            });
         } else {
-            this.props.onNodeSelectionChanged([node]);
+            // Just deselect
+            this.props.onNodeSelectionChanged([]);
         }
     }
 
-    /**
-     * Processes right-click event on graph elements by deleting them.
-     */
-    private handleElementRightClick(element: GraphElement<unknown, unknown>) {
-        this.graphInFocus = true;
-
-        element.delete();
-        this.forceUpdate(); // TODO: Necessary?
-    }
-
     /**
      * Propagates the changed state of the graph.
      */
@@ -200,10 +158,10 @@ export class GraphRenderer2D extends React.PureComponent<
         }
 
         if (this.props.selectedNodes.length == 1) {
-            node.connect(this.state.selectedNodes[0]);
+            this.props.onLinkCreation(node.id, this.props.selectedNodes[0].id);
         } else {
             this.props.selectedNodes.forEach((selectedNode: Node) =>
-                node.connect(selectedNode)
+                this.props.onLinkCreation(node.id, selectedNode.id)
             );
         }
     }
@@ -233,8 +191,6 @@ export class GraphRenderer2D extends React.PureComponent<
     }
 
     private handleNodeDrag(node: Node) {
-        this.graphInFocus = true;
-
         // if (!this.props.selectedNodes.includes(node)) {
         //     this.props.onNodeSelectionChanged([...this.props.selectedNodes, node]);
         // }
@@ -257,8 +213,7 @@ export class GraphRenderer2D extends React.PureComponent<
         }
 
         // Add link
-        node.connect(closest.node); // TODO: Change must propagate
-        // this.forceUpdate(); TODO: Remove?
+        this.props.onLinkCreation(node.id, closest.id);
     }
 
     private handleNodeCanvasObject(
@@ -419,30 +374,40 @@ export class GraphRenderer2D extends React.PureComponent<
 
     render() {
         return (
-            <ForceGraph2D
-                ref={this.forceGraph}
-                width={this.props.width}
-                graphData={this.props.graph}
-                onNodeClick={this.handleNodeClick}
-                autoPauseRedraw={false}
-                cooldownTicks={0}
-                warmupTicks={this.warmupTicks}
-                onEngineStop={this.handleEngineStop}
-                nodeCanvasObject={this.handleNodeCanvasObject}
-                nodeCanvasObjectMode={() => "after"}
-                linkCanvasObject={this.handleLinkCanvasObject}
-                linkCanvasObjectMode={() => "replace"}
-                nodeColor={(node: Node) => node.type.color}
-                onNodeDrag={this.handleNodeDrag}
-                onLinkRightClick={this.handleElementRightClick}
-                onNodeRightClick={this.handleElementRightClick}
-                onBackgroundClick={(event: any) =>
-                    this.handleBackgroundClick(
-                        event,
-                        this.extractPositions(event)
-                    )
-                }
-            />
+            <div
+                tabIndex={0} // This is needed to receive focus events
+                onFocus={() => (this.graphInFocus = true)}
+                onBlur={() => (this.graphInFocus = false)}
+            >
+                <ForceGraph2D
+                    ref={this.forceGraph}
+                    width={this.props.width}
+                    graphData={this.props.graph}
+                    onNodeClick={this.handleNodeClick}
+                    autoPauseRedraw={false}
+                    cooldownTicks={0}
+                    warmupTicks={this.warmupTicks}
+                    onEngineStop={this.handleEngineStop}
+                    nodeCanvasObject={this.handleNodeCanvasObject}
+                    nodeCanvasObjectMode={() => "after"}
+                    linkCanvasObject={this.handleLinkCanvasObject}
+                    linkCanvasObjectMode={() => "replace"}
+                    nodeColor={(node: Node) => node.type.color}
+                    onNodeDrag={this.handleNodeDrag}
+                    onLinkRightClick={(link: Link) =>
+                        this.props.onLinkDeletion(link.id)
+                    }
+                    onNodeRightClick={(node: Node) =>
+                        this.props.onNodeDeletion(node.id)
+                    }
+                    onBackgroundClick={(event: any) =>
+                        this.handleBackgroundClick(
+                            event,
+                            this.extractPositions(event)
+                        )
+                    }
+                />
+            </div>
         );
     }
 }