diff --git a/Source/AccessClass.cpp b/Source/AccessClass.cpp
index 063765e9369003f8557d8b2acc67adbdf3e830bf..281f9fde8c1e1a68243af86c0680817157ad1eda 100644
--- a/Source/AccessClass.cpp
+++ b/Source/AccessClass.cpp
@@ -24,14 +24,14 @@
 #include "AccessClass.h"
 
 #include "UI/UIComponent.h"
-#include "UI/EditorViewport.h"
-#include "UI/ProcessorList.h"
-#include "UI/DataViewport.h"
-#include "UI/ControlPanel.h"
-#include "UI/MessageCenter.h"
-#include "UI/GraphViewer.h"
-#include "Audio/AudioComponent.h"
-#include "Processors/ProcessorGraph.h"
+// #include "UI/EditorViewport.h"
+// #include "UI/ProcessorList.h"
+// #include "UI/DataViewport.h"
+// #include "UI/ControlPanel.h"
+// #include "UI/MessageCenter.h"
+// #include "UI/GraphViewer.h"
+// #include "Audio/AudioComponent.h"
+// #include "Processors/ProcessorGraph.h"
 
 void AccessClass::setUIComponent(UIComponent* ui_)
 {
diff --git a/Source/Processors/Editors/GenericEditor.h b/Source/Processors/Editors/GenericEditor.h
index 953edfd48e4cfad272def3fb7cf8c80206cacc1b..105436eb89cf1974938881e2ae8a3011a5c28637 100755
--- a/Source/Processors/Editors/GenericEditor.h
+++ b/Source/Processors/Editors/GenericEditor.h
@@ -260,6 +260,9 @@ public:
     
     /** Returns the editor of this processor's destination */
     GenericEditor* getDestEditor();
+
+    /** Returns the editors a splitter or merger is connected to */
+    virtual Array<GenericEditor*> getConnectedEditors() { }
     
 protected:
 
diff --git a/Source/Processors/Editors/SplitterEditor.cpp b/Source/Processors/Editors/SplitterEditor.cpp
index d65b4befec396a7e8ecaef4b087b79aab8b85dfc..1e360b7b8fcbb88c83ec158286ec5ad8ca3202a9 100755
--- a/Source/Processors/Editors/SplitterEditor.cpp
+++ b/Source/Processors/Editors/SplitterEditor.cpp
@@ -161,6 +161,27 @@ int SplitterEditor::getPathForEditor(GenericEditor* editor)
 }
 
 
+Array<GenericEditor*> SplitterEditor::getConnectedEditors()
+{
+
+    Array<GenericEditor*> editors;
+
+    Splitter* processor = (Splitter*) getProcessor();
+    
+    for (int pathNum = 0; pathNum < 2; pathNum++)
+    {
+        processor->switchIO();
+
+        if (processor->getDestNode() != nullptr)
+            editors.add(processor->getDestNode()->getEditor());
+        else
+            editors.add(nullptr);
+    }
+    
+    return editors;
+    
+}
+
 void SplitterEditor::switchDest()
 {
     Splitter* processor = (Splitter*) getProcessor();
diff --git a/Source/Processors/Editors/SplitterEditor.h b/Source/Processors/Editors/SplitterEditor.h
index db7b6896f813f7350617a263af5ed9c47474046f..ddcd447616c9a6a21bb40cc9097beb31a20caff1 100755
--- a/Source/Processors/Editors/SplitterEditor.h
+++ b/Source/Processors/Editors/SplitterEditor.h
@@ -50,6 +50,7 @@ public:
     void switchIO(int i);
     
     int getPathForEditor(GenericEditor* editor);
+    Array<GenericEditor*> getConnectedEditors();
 
 
 private:
diff --git a/Source/Processors/Utilities/Merger.cpp b/Source/Processors/Utilities/Merger.cpp
index e972bf473869f46ca522e9bef9041748f5fd9b4e..b51b8fb2d663c8773cb0923620a5c95de0887033 100755
--- a/Source/Processors/Utilities/Merger.cpp
+++ b/Source/Processors/Utilities/Merger.cpp
@@ -104,7 +104,7 @@ bool Merger::stillHasSource()
 void Merger::switchIO()
 {
 
-    std::cout << "Merger switching source." << std::endl;
+    //std::cout << "Merger switching source." << std::endl;
 
     if (activePath == 0)
     {
diff --git a/Source/Processors/Utilities/Splitter.cpp b/Source/Processors/Utilities/Splitter.cpp
index 4756f2d3d3b321f05b949b5896b9783ab14796d5..d1854748d8ed5717909bab07587f133058316626 100755
--- a/Source/Processors/Utilities/Splitter.cpp
+++ b/Source/Processors/Utilities/Splitter.cpp
@@ -105,7 +105,7 @@ void Splitter::switchIO(int destNum)
 void Splitter::switchIO()
 {
 
-    std::cout << "Splitter switching source." << std::endl;
+    //std::cout << "Splitter switching source." << std::endl;
 
     if (activePath == 0)
     {
diff --git a/Source/UI/GraphViewer.cpp b/Source/UI/GraphViewer.cpp
index debf13c757599833b46457f745cdd2061d961ed9..aaa9b3afc1be4da9aa6f9e5b98aef6d436ae6fe6 100644
--- a/Source/UI/GraphViewer.cpp
+++ b/Source/UI/GraphViewer.cpp
@@ -38,7 +38,7 @@ GraphViewer::~GraphViewer()
 void GraphViewer::addNode(GenericEditor* editor)
 {
     
-    GraphNode* gn = new GraphNode(editor);
+    GraphNode* gn = new GraphNode(editor, this);
     addAndMakeVisible(gn);
     availableNodes.add(gn);
     
@@ -56,6 +56,14 @@ void GraphViewer::removeNode(GenericEditor* editor)
 
 }
 
+void GraphViewer::removeAllNodes()
+{
+    availableNodes.clear();
+
+    updateNodeLocations();
+    
+}
+
 void GraphViewer::updateNodeLocations()
 {
     for (int i = 0; i < availableNodes.size(); i++)
@@ -66,12 +74,6 @@ void GraphViewer::updateNodeLocations()
     repaint();
 }
 
-void GraphViewer::removeAllNodes()
-{
-    availableNodes.clear();
-    
-}
-
 int GraphViewer::indexOfEditor(GenericEditor* editor)
 {
     int index = -1;
@@ -87,6 +89,45 @@ int GraphViewer::indexOfEditor(GenericEditor* editor)
     return index;
 }
 
+int GraphViewer::nodesAtLevel(int level)
+{
+
+    int numNodes;
+
+    for (int i = 0; i < availableNodes.size(); i++)
+    {
+        if (availableNodes[i]->getLevel() == numNodes)
+        {
+            numNodes++;
+        }
+    }
+
+    return numNodes;
+
+}
+
+int GraphViewer::getHorizontalShift(GraphNode* gn)
+{
+    int shift = 0;
+
+    for (int i = 0; i < availableNodes.size(); i++)
+    {
+        if (availableNodes[i] == gn)
+        {
+            break;
+        } else
+        {
+            if (availableNodes[i]->getLevel() == gn->getLevel())
+            {
+                shift++;
+            }
+        }
+    }
+
+    return shift;
+
+}
+
 
 void GraphViewer::paint(Graphics& g)
 {
@@ -98,25 +139,88 @@ void GraphViewer::paint(Graphics& g)
     
     g.drawFittedText("open ephys", 40, 40, getWidth()-50, getHeight()-50, Justification::bottomRight, 100);
     
-//    for (int i = 0; i < availableNodes.size(); i++)
-//    {
-//        g.drawText(availableNodes[i]->getName(), 20, 20*i, getWidth()-20, 40, Justification::left, true);
-//    }
+    // draw connections
+
+    for (int i = 0; i < availableNodes.size(); i++)
+    {
+
+        if (!availableNodes[i]->isSplitter())
+        {
+            if (availableNodes[i]->getDest() != nullptr)
+            {
+                int indexOfDest = indexOfEditor(availableNodes[i]->getDest());
+                
+                if (indexOfDest > -1)
+                    connectNodes(i, indexOfDest, g);
+            }
+        } else {
+
+            Array<GenericEditor*> editors = availableNodes[i]->getConnectedEditors();
+
+            for (int path = 0; path < 2; path++)
+            {
+                int indexOfDest = indexOfEditor(editors[path]);
+                    
+                if (indexOfDest > -1)    
+                    connectNodes(i, indexOfDest, g);
+            }
+            
+
+        }
+
+    }
+}
+
+void GraphViewer::connectNodes(int node1, int node2, Graphics& g)
+{
+
+    Point<float> start = availableNodes[node1]->getCenterPoint();
+    Point<float> end = availableNodes[node2]->getCenterPoint();
+
+    Path linePath;
+    float x1 = start.getX();
+    float y1 = start.getY();
+    float x2 = end.getX();
+    float y2 = end.getY();
+    linePath.startNewSubPath (x1, y1);
+    linePath.cubicTo (x1, y1 + (y2 - y1) * 0.9f,
+                      x2, y1 + (y2 - y1) * 0.1f,
+                      x2, y2);
+    
+    PathStrokeType stroke (2.0f);
+    g.strokePath(linePath, stroke);
 }
 
 /// ------------------------------------------------------
 
-GraphNode::GraphNode(GenericEditor* ed)
+GraphNode::GraphNode(GenericEditor* ed, GraphViewer* g)
 {
     editor = ed;
     mouseOver = false;
     labelFont = Font("Paragraph", 14, Font::plain);
+
+    gv = g;
 }
 
 GraphNode::~GraphNode()
 {
     
 }
+
+int GraphNode::getLevel()
+{
+    int level = -1;
+
+    GenericEditor* ed = editor;
+
+    while (ed != nullptr)
+    {
+        level += 1;
+        ed = ed->getSourceEditor();
+    }
+
+    return level;
+}
     
 void GraphNode::mouseEnter(const MouseEvent& m)
 {
@@ -141,65 +245,107 @@ bool GraphNode::hasEditor(GenericEditor* ed)
         return false;
 }
 
+bool GraphNode::isSplitter()
+{
+    return editor->isSplitter();
+}
+
+bool GraphNode::isMerger()
+{
+    return editor->isMerger();
+}
+
+
+GenericEditor* GraphNode::getDest()
+{
+    return editor->getDestEditor();
+}
+
+Array<GenericEditor*> GraphNode::getConnectedEditors()
+{
+    return editor->getConnectedEditors();
+}
+
 const String GraphNode::getName()
 {
     return editor->getName();
 }
 
+Point<float> GraphNode::getCenterPoint()
+{
+    Point<float> center = Point<float>(getX()+10, getY()+10);
+
+    return center;
+}
+
+void GraphNode::switchIO(int path)
+{
+
+}
+
 void GraphNode::updateBoundaries()
 {
-    int level = -1;
-    int chain = 0;
+    // float vertShift = -1;
+    // float horzShift = 0;
     
-    GenericEditor* ed = editor;
+    // GenericEditor* ed = editor;
     
-    while (ed != nullptr)
-    {
-        level++;
+    // while (ed != nullptr)
+    // {
+    //     vertShift += 1;
 
-        GenericEditor* sourceEditor = ed->getSourceEditor();
+    //     GenericEditor* sourceEditor = ed->getSourceEditor();
         
-        if (sourceEditor != nullptr)
-        {
-            if (sourceEditor->isSplitter())
-            {
-                if (sourceEditor->getPathForEditor(ed) == 1)
-                    chain++;
-            }
-        }
-        ed = sourceEditor;
+    //     if (sourceEditor != nullptr)
+    //     {
+    //         if (sourceEditor->isSplitter())
+    //         {
+    //             if (sourceEditor->getPathForEditor(ed) == 1)
+    //                 horzShift += 1;
+    //             //else
+    //             //    horzShift -= 0.5;
+    //         }
+    //     }
+    //     ed = sourceEditor;
     
-    }
+    // }
+
+    // ed = editor;
+
+    // if (ed->isSplitter())
+    // {
+    //     horzShift += 0.5;
+    // }
     
-    setBounds(20+chain*140, 20+level*40, 150, 50);
+    // while (ed != nullptr)
+    // {
+
+    //     GenericEditor* destEditor = ed->getDestEditor();
+        
+    //     if (destEditor != nullptr)
+    //     {
+    //         if (destEditor->isSplitter())
+    //         {
+    //             horzShift += 0.5;
+    //         } else if (destEditor->isMerger())
+    //         {
+    //             if (destEditor->getPathForEditor(ed) == 1)
+    //                 horzShift += 1;
+    //         }
+    //     }
+    //     ed = destEditor;
+    
+    // }
+
+    int level = getLevel();
+
+    int horzShift = gv->getHorizontalShift(this);
+    
+    setBounds(20+horzShift*140, 20+getLevel()*40, 150, 50);
 }
 
 void GraphNode::paint(Graphics& g)
 {
-    if (editor->getDestEditor() != nullptr)
-    {
-        Line<float> line = Line<float>(10,10,10,50);
-        
-        g.setColour(Colours::grey);
-        g.drawLine(line, 2.0f);
-        
-        if (editor->isSplitter())
-        {
-            Path linePath;
-            float x1 = 10;
-            float y1 = 19;
-            float x2 = 150;
-            float y2 = 45;
-            linePath.startNewSubPath (x1, y1);
-            linePath.cubicTo (x1, y1 + (y2 - y1) * 0.33f,
-                              x2, y1 + (y2 - y1) * 0.66f,
-                              x2, y2);
-            
-            PathStrokeType stroke (2.0f);
-            g.strokePath(linePath, stroke);
-
-        }
-    }
 
     if (mouseOver)
     {
@@ -213,6 +359,4 @@ void GraphNode::paint(Graphics& g)
     
     g.drawText(getName(), 25, 0, getWidth()-25, 20, Justification::left, true);
     
-  
-    
 }
\ No newline at end of file
diff --git a/Source/UI/GraphViewer.h b/Source/UI/GraphViewer.h
index bc34a942cba76a99732ade7cc2f0594961541ce4..9b0273130f97dba3cc91da697bf0928007b0cf66 100644
--- a/Source/UI/GraphViewer.h
+++ b/Source/UI/GraphViewer.h
@@ -43,7 +43,7 @@
 class GraphNode : public Component
 {
 public:
-    GraphNode(GenericEditor* editor);
+    GraphNode(GenericEditor* editor, GraphViewer* g);
     ~GraphNode();
     
     void mouseEnter(const MouseEvent& m);
@@ -55,19 +55,32 @@ public:
     void paint(Graphics& g);
     
     void updateBoundaries();
-    
+
+    Point<float> getCenterPoint();
+    GenericEditor* getDest();
+    Array<GenericEditor*> getConnectedEditors();
+    void switchIO(int path);
+
+    bool isSplitter();
+    bool isMerger();
+
     const String getName();
+
+    int getLevel();
     
 private:
+
     GenericEditor* editor;
     
     Font labelFont;
     
     bool mouseOver;
+
+    GraphViewer* gv;
 };
 
 
-class GraphViewer : public Component, public AccessClass
+class GraphViewer : public Component
 
 {
 public:
@@ -81,8 +94,12 @@ public:
     void removeNode(GenericEditor* editor);
     void removeAllNodes();
 
-    
+    int nodesAtLevel(int lvl);
+    int getHorizontalShift(GraphNode*);
+
 private:
+
+    void connectNodes(int, int, Graphics&);
     
     void updateNodeLocations();
     int indexOfEditor(GenericEditor* editor);
diff --git a/Source/UI/UIComponent.cpp b/Source/UI/UIComponent.cpp
index 9b81847cc53ad9ce88940081270cbe792730d11c..47b4c282ed9bf226365654ffd8b4b087fceb5579 100755
--- a/Source/UI/UIComponent.cpp
+++ b/Source/UI/UIComponent.cpp
@@ -83,7 +83,6 @@ UIComponent::UIComponent(MainWindow* mainWindow_, ProcessorGraph* pgraph, AudioC
     dataViewport->setUIComponent(this);
     controlPanel->getAudioEditor()->setUIComponent(this);
     controlPanel->setUIComponent(this);
-    graphViewer->setUIComponent(this);
     
     processorGraph->updatePointers(); // needs to happen after processorGraph gets the right pointers