diff --git a/ivette/src/dome/renderer/graph/diagram.tsx b/ivette/src/dome/renderer/graph/diagram.tsx
index ac817f4459a8527eeaec84c4e165fb398dc9085f..d726c9ab7ef5497b74f8c4b8e7e6c13d3d883a99 100644
--- a/ivette/src/dome/renderer/graph/diagram.tsx
+++ b/ivette/src/dome/renderer/graph/diagram.tsx
@@ -69,30 +69,70 @@ export interface DiagramProps {
   /** Styling the Graph main div element. */
   className?: string;
 
-  /** Prints the DOT specification instead of the graph (only in DEV) */
-  debug?: boolean;
+  /** Debug the generated DotModel */
+  onModelChanged?: (model: string) => void;
+
 }
 
 /* -------------------------------------------------------------------------- */
 /* --- Dot Model                                                          --- */
 /* -------------------------------------------------------------------------- */
 
-type edgeSpec = { source : string, target : string };
-const edgeKey = (e: edgeSpec):string => `${e.source} -> ${e.target}`;
+type edgeSpec = { source: string, target: string };
+const edgeKey = (e: edgeSpec): string => `${e.source} -> ${e.target}`;
 
 class DotModel {
-  private spec = 'digraph {';
-  print(...text: string []): DotModel {
+
+  // --- Basics
+  private spec = 'digraph {\n';
+  print(...text: string[]): DotModel {
     this.spec = this.spec.concat(...text);
     return this;
   }
-  println(...text: string []): DotModel {
+  println(...text: string[]): DotModel {
     this.spec = this.spec.concat(...text).concat('\n');
     return this;
   }
   flush(): string { return this.spec.concat('}'); }
+
+  // --- Graph
+  rankdir(d: Direction): DotModel {
+    return this.println('  rankdir="', d, '";');
+  }
+
+  // --- Special
+  quoted(a: string): DotModel { return this.print('"', a, '"'); }
+
+  // --- Node
+  node(n: Node): void {
+    this
+      .print('  ')
+      .quoted(n.id)
+      .print(' [')
+      .println('];');
+  }
+
+  // --- Edge
+  edge(e: Edge): void {
+    this
+      .print('  ')
+      .quoted(e.source)
+      .print(' -> ')
+      .quoted(e.target)
+      .print(' [')
+      .println('];');
+  }
 }
 
+const byStr = (a: string, b: string): number => {
+  if (a < b) return -1;
+  if (a > b) return +1;
+  return 0;
+}
+
+const byNode = (a: Node, b: Node): number => byStr(a.id, b.id);
+const byEdge = (a: Edge, b: Edge): number => byStr(edgeKey(a), edgeKey(b));
+
 /* -------------------------------------------------------------------------- */
 /* --- d3-Graphviz Component                                              --- */
 /* -------------------------------------------------------------------------- */
@@ -100,17 +140,27 @@ class DotModel {
 interface GraphvizProps extends DiagramProps { size: Size }
 
 function Graphviz(props: GraphvizProps): JSX.Element {
-  const { nodes, edges, size } = props;
+  // --- Model Generation
+  const { direction = 'LR', nodes, edges } = props;
   const model = React.useMemo(() => {
     const dot = new DotModel();
+    dot.rankdir(direction);
+    nodes.concat().sort(byNode).forEach(n => dot.node(n));
+    edges.concat().sort(byEdge).forEach(e => dot.edge(e));
     return dot.flush();
   }, [nodes, edges]);
+  // --- Model Update Callback
+  const { onModelChanged } = props;
+  React.useEffect(() => {
+    if (onModelChanged) onModelChanged(model);
+  }, [model, onModelChanged]);
+  // --- Rendering
   return (
-    <Scroll style={size}>
-      <pre>
+    <div style={props.size}>
+      <pre style={{background: 'red'}}>
         {model}
       </pre>
-    </Scroll>
+    </div>
   );
 }
 
diff --git a/ivette/src/sandbox/diagram.tsx b/ivette/src/sandbox/diagram.tsx
index ab56f3d2d4a2e01f17ba797d7a724b8797c51f86..ca602a70a164f78c44805b796b9863a447244987 100644
--- a/ivette/src/sandbox/diagram.tsx
+++ b/ivette/src/sandbox/diagram.tsx
@@ -25,15 +25,40 @@
 /* -------------------------------------------------------------------------- */
 
 import React from 'react';
-import { Diagram } from 'dome/graph/diagram';
+import { Scroll } from 'dome/layout/boxes';
+import { HSplit } from 'dome/layout/splitters';
+import { Diagram, Node, Edge } from 'dome/graph/diagram';
 import { registerSandbox } from 'ivette';
 
 // --------------------------------------------------------------------------
 // --- Init functions for nodes and edges
 // --------------------------------------------------------------------------
 
+const nodes : Node[] = [
+  { id: 'A' },
+  { id: 'B' },
+];
+
+const edges : Edge[] = [
+  { source: 'A', target: 'B' }
+];
+
 function DiagramSample(): JSX.Element {
-  return <Diagram nodes={[]} edges={[]} />;
+  const [model, setModel] = React.useState('');
+  return (
+    <HSplit settings='sandbox.diagram.split'>
+      <Scroll>
+        <pre>
+          {model}
+        </pre>
+      </Scroll>
+      <Diagram
+        nodes={nodes}
+        edges={edges}
+        onModelChanged={setModel}
+      />
+    </HSplit >
+  );
 }
 
 /* -------------------------------------------------------------------------- */