diff --git a/tools/turbolizer/graph-view.js b/tools/turbolizer/graph-view.js
new file mode 100644
index 0000000..41d35d8
--- /dev/null
+++ b/tools/turbolizer/graph-view.js
@@ -0,0 +1,987 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+"use strict";
+
+class GraphView extends View {
+  constructor (d3, id, nodes, edges, broker) {
+    super(id, broker);
+    var graph = this;
+
+    var svg = this.divElement.append("svg").attr('version','1.1').attr("width", "100%");
+    graph.svg = svg;
+
+    graph.nodes = nodes || [];
+    graph.edges = edges || [];
+
+    graph.minGraphX = 0;
+    graph.maxGraphX = 1;
+    graph.minGraphY = 0;
+    graph.maxGraphY = 1;
+
+    graph.state = {
+      selection: null,
+      mouseDownNode: null,
+      justDragged: false,
+      justScaleTransGraph: false,
+      lastKeyDown: -1,
+      showTypes: false
+    };
+
+    var selectionHandler = {
+      clear: function() {
+        broker.clear(selectionHandler);
+      },
+      select: function(items, selected) {
+        var ranges = [];
+        for (var d of items) {
+          if (selected) {
+            d.classList.add("selected");
+          } else {
+            d.classList.remove("selected");
+          }
+          var data = d.__data__;
+          ranges.push([data.pos, data.pos + 1, data.id]);
+        }
+        broker.select(selectionHandler, ranges, selected);
+      },
+      selectionDifference: function(span1, inclusive1, span2, inclusive2) {
+        // Should not be called
+      },
+      brokeredSelect: function(ranges, selected) {
+        var test = [].entries().next();
+        var selection = graph.nodes
+          .filter(function(n) {
+            var pos = n.pos;
+            for (var range of ranges) {
+              var start = range[0];
+              var end = range[1];
+              var id = range[2];
+              if (end != undefined) {
+                if (pos >= start && pos < end) {
+                  return true;
+                }
+              } else if (start != undefined) {
+                if (pos === start) {
+                  return true;
+                }
+              } else {
+                if (n.id === id) {
+                  return true;
+                }
+              }
+            }
+            return false;
+          });
+        var newlySelected = new Set();
+        selection.forEach(function(n) {
+          newlySelected.add(n);
+          if (!n.visible) {
+            n.visible = true;
+          }
+        });
+        graph.updateGraphVisibility();
+        graph.visibleNodes.each(function(n) {
+          if (newlySelected.has(n)) {
+            graph.state.selection.select(this, selected);
+          }
+        });
+        graph.updateGraphVisibility();
+        graph.viewSelection();
+      },
+      brokeredClear: function() {
+        graph.state.selection.clear();
+      }
+    };
+    broker.addSelectionHandler(selectionHandler);
+
+    graph.state.selection = new Selection(selectionHandler);
+
+    var defs = svg.append('svg:defs');
+    defs.append('svg:marker')
+      .attr('id', 'end-arrow')
+      .attr('viewBox', '0 -4 8 8')
+      .attr('refX', 2)
+      .attr('markerWidth', 2.5)
+      .attr('markerHeight', 2.5)
+      .attr('orient', 'auto')
+      .append('svg:path')
+      .attr('d', 'M0,-4L8,0L0,4');
+
+    this.graphElement = svg.append("g");
+    graph.visibleEdges = this.graphElement.append("g").selectAll("g");
+    graph.visibleNodes = this.graphElement.append("g").selectAll("g");
+
+    graph.drag = d3.behavior.drag()
+      .origin(function(d){
+        return {x: d.x, y: d.y};
+      })
+      .on("drag", function(args){
+        graph.state.justDragged = true;
+        graph.dragmove.call(graph, args);
+      })
+
+    d3.select("#upload").on("click", function(){
+      document.getElementById("hidden-file-upload").click();
+    });
+
+    d3.select("#layout").on("click", function(){
+      graph.updateGraphVisibility();
+      graph.layoutGraph();
+      graph.updateGraphVisibility();
+      graph.viewWholeGraph();
+    });
+
+    d3.select("#show-all").on("click", function(){
+      graph.nodes.filter(function(n) { n.visible = true; })
+      graph.edges.filter(function(e) { e.visible = true; })
+      graph.updateGraphVisibility();
+      graph.viewWholeGraph();
+    });
+
+    d3.select("#hide-unselected").on("click", function() {
+      var unselected = graph.visibleNodes.filter(function(n) {
+        return !this.classList.contains("selected");
+      });
+      unselected.each(function(n) {
+        n.visible = false;
+      });
+      graph.updateGraphVisibility();
+    });
+
+    d3.select("#hide-selected").on("click", function() {
+      var selected = graph.visibleNodes.filter(function(n) {
+        return this.classList.contains("selected");
+      });
+      selected.each(function(n) {
+        n.visible = false;
+      });
+      graph.state.selection.clear();
+      graph.updateGraphVisibility();
+    });
+
+    d3.select("#zoom-selection").on("click", function() {
+      graph.viewSelection();
+    });
+
+    d3.select("#toggle-types").on("click", function() {
+      graph.toggleTypes();
+    });
+
+    d3.select("#search-input").on("keydown", function() {
+      if (d3.event.keyCode == 13) {
+        graph.state.selection.clear();
+        var reg = new RegExp(this.value);
+        var filterFunction = function(n) {
+          return (reg.exec(n.getDisplayLabel()) != null ||
+                  (graph.state.showTypes && reg.exec(n.getDisplayType())) ||
+                  reg.exec(n.opcode) != null);
+        };
+        if (d3.event.ctrlKey) {
+          graph.nodes.forEach(function(n, i) {
+            if (filterFunction(n)) {
+              n.visible = true;
+            }
+          });
+          graph.updateGraphVisibility();
+        }
+        var selected = graph.visibleNodes.each(function(n) {
+          if (filterFunction(n)) {
+            graph.state.selection.select(this, true);
+          }
+        });
+        graph.connectVisibleSelectedNodes();
+        graph.updateGraphVisibility();
+        this.blur();
+        graph.viewSelection();
+      }
+      d3.event.stopPropagation();
+    });
+
+    // listen for key events
+    d3.select(window).on("keydown", function(e){
+      graph.svgKeyDown.call(graph);
+    })
+      .on("keyup", function(){
+        graph.svgKeyUp.call(graph);
+      });
+    svg.on("mousedown", function(d){graph.svgMouseDown.call(graph, d);});
+    svg.on("mouseup", function(d){graph.svgMouseUp.call(graph, d);});
+
+    graph.dragSvg = d3.behavior.zoom()
+      .on("zoom", function(){
+        if (d3.event.sourceEvent.shiftKey){
+          return false;
+        } else{
+          graph.zoomed.call(graph);
+        }
+        return true;
+      })
+      .on("zoomstart", function(){
+        if (!d3.event.sourceEvent.shiftKey) d3.select('body').style("cursor", "move");
+      })
+      .on("zoomend", function(){
+        d3.select('body').style("cursor", "auto");
+      });
+
+    svg.call(graph.dragSvg).on("dblclick.zoom", null);
+  }
+
+  static get selectedClass() {
+    return "selected";
+  }
+  static get rectClass() {
+    return "nodeStyle";
+  }
+  static get activeEditId() {
+    return "active-editing";
+  }
+  static get nodeRadius() {
+    return 50;
+  }
+
+  getNodeHeight(graph) {
+    if (this.state.showTypes) {
+      return DEFAULT_NODE_HEIGHT + TYPE_HEIGHT;
+    } else {
+      return DEFAULT_NODE_HEIGHT;
+    }
+  }
+
+  getEdgeFrontier(nodes, inEdges, edgeFilter) {
+    let frontier = new Set();
+    nodes.forEach(function(element) {
+      var edges = inEdges ? element.__data__.inputs : element.__data__.outputs;
+      var edgeNumber = 0;
+      edges.forEach(function(edge) {
+        if (edgeFilter == undefined || edgeFilter(edge, edgeNumber)) {
+          frontier.add(edge);
+        }
+        ++edgeNumber;
+      });
+    });
+    return frontier;
+  }
+
+  getNodeFrontier(nodes, inEdges, edgeFilter) {
+    let graph = this;
+    var frontier = new Set();
+    var newState = true;
+    var edgeFrontier = graph.getEdgeFrontier(nodes, inEdges, edgeFilter);
+    // Control key toggles edges rather than just turning them on
+    if (d3.event.ctrlKey) {
+      edgeFrontier.forEach(function(edge) {
+        if (edge.visible) {
+          newState = false;
+        }
+      });
+    }
+    edgeFrontier.forEach(function(edge) {
+      edge.visible = newState;
+      if (newState) {
+        var node = inEdges ? edge.source : edge.target;
+        node.visible = true;
+        frontier.add(node);
+      }
+    });
+    graph.updateGraphVisibility();
+    if (newState) {
+      return graph.visibleNodes.filter(function(n) {
+        return frontier.has(n);
+      });
+    } else {
+      return undefined;
+    }
+  }
+
+  dragmove(d) {
+    var graph = this;
+    d.x += d3.event.dx;
+    d.y += d3.event.dy;
+    graph.updateGraphVisibility();
+  }
+
+  initializeContent(data, rememberedSelection) {
+    this.createGraph(data, rememberedSelection);
+    if (rememberedSelection != null) {
+      this.attachSelection(rememberedSelection);
+      this.connectVisibleSelectedNodes();
+    }
+    this.updateGraphVisibility();
+  }
+
+  deleteContent() {
+    if (this.visibleNodes) {
+      this.nodes = [];
+      this.edges = [];
+      this.nodeMap = [];
+      this.updateGraphVisibility();
+    }
+  };
+
+  createGraph(data, initiallyVisibileIds) {
+    var g = this;
+    g.nodes = data.nodes;
+    g.nodeMap = [];
+    var textMeasure = document.getElementById('text-measure');
+    g.nodes.forEach(function(n, i){
+      n.__proto__ = Node;
+      n.visible = false;
+      n.x = 0;
+      n.y = 0;
+      n.rank = MAX_RANK_SENTINEL;
+      n.inputs = [];
+      n.outputs = [];
+      n.rpo = -1;
+      n.outputApproach = MINIMUM_NODE_OUTPUT_APPROACH;
+      n.cfg = n.control;
+      g.nodeMap[n.id] = n;
+      n.displayLabel = n.getDisplayLabel();
+      textMeasure.textContent = n.getDisplayLabel();
+      var width = textMeasure.getComputedTextLength();
+      textMeasure.textContent = n.getDisplayType();
+      width = Math.max(width, textMeasure.getComputedTextLength());
+      n.width = Math.alignUp(width + NODE_INPUT_WIDTH * 2,
+                             NODE_INPUT_WIDTH);
+    });
+    g.edges = [];
+    data.edges.forEach(function(e, i){
+      var t = g.nodeMap[e.target];
+      var s = g.nodeMap[e.source];
+      var newEdge = new Edge(t, e.index, s, e.type);
+      t.inputs.push(newEdge);
+      s.outputs.push(newEdge);
+      g.edges.push(newEdge);
+      if (e.type == 'control') {
+        s.cfg = true;
+      }
+    });
+    g.nodes.forEach(function(n, i) {
+      n.visible = isNodeInitiallyVisible(n);
+      if (initiallyVisibileIds != undefined) {
+        if (initiallyVisibileIds.has(n.id)) {
+          n.visible = true;
+        }
+      }
+    });
+    g.fitGraphViewToWindow();
+    g.updateGraphVisibility();
+    g.layoutGraph();
+    g.updateGraphVisibility();
+    g.viewWholeGraph();
+  }
+
+  connectVisibleSelectedNodes() {
+    var graph = this;
+    graph.state.selection.selection.forEach(function(element) {
+      var edgeNumber = 0;
+      element.__data__.inputs.forEach(function(edge) {
+        if (edge.source.visible && edge.target.visible) {
+          edge.visible = true;
+        }
+      });
+      element.__data__.outputs.forEach(function(edge) {
+        if (edge.source.visible && edge.target.visible) {
+          edge.visible = true;
+        }
+      });
+    });
+  }
+
+  updateInputAndOutputBubbles() {
+    var g = this;
+    var s = g.visibleBubbles;
+    s.classed("filledBubbleStyle", function(c) {
+      var components = this.id.split(',');
+      if (components[0] == "ib") {
+        var edge = g.nodeMap[components[3]].inputs[components[2]];
+        return edge.isVisible();
+      } else {
+        return g.nodeMap[components[1]].areAnyOutputsVisible() == 2;
+      }
+    }).classed("halfFilledBubbleStyle", function(c) {
+      var components = this.id.split(',');
+      if (components[0] == "ib") {
+        var edge = g.nodeMap[components[3]].inputs[components[2]];
+        return false;
+      } else {
+        return g.nodeMap[components[1]].areAnyOutputsVisible() == 1;
+      }
+    }).classed("bubbleStyle", function(c) {
+      var components = this.id.split(',');
+      if (components[0] == "ib") {
+        var edge = g.nodeMap[components[3]].inputs[components[2]];
+        return !edge.isVisible();
+      } else {
+        return g.nodeMap[components[1]].areAnyOutputsVisible() == 0;
+      }
+    });
+    s.each(function(c) {
+      var components = this.id.split(',');
+      if (components[0] == "ob") {
+        var from = g.nodeMap[components[1]];
+        var x = from.getOutputX();
+        var y = g.getNodeHeight() + DEFAULT_NODE_BUBBLE_RADIUS / 2 + 4;
+        var transform = "translate(" + x + "," + y + ")";
+        this.setAttribute('transform', transform);
+      }
+    });
+  }
+
+  attachSelection(s) {
+    var graph = this;
+    if (s.size != 0) {
+      this.visibleNodes.each(function(n) {
+        if (s.has(this.__data__.id)) {
+          graph.state.selection.select(this, true);
+        }
+      });
+    }
+  }
+
+  detachSelection() {
+    var selection = this.state.selection.detachSelection();
+    var s = new Set();
+    for (var i of selection) {
+      s.add(i.__data__.id);
+    };
+    return s;
+  }
+
+  pathMouseDown(path, d) {
+    d3.event.stopPropagation();
+    this.state.selection.clear();
+    this.state.selection.add(path);
+  };
+
+  nodeMouseDown(node, d) {
+    d3.event.stopPropagation();
+    this.state.mouseDownNode = d;
+  }
+
+  nodeMouseUp(d3node, d) {
+    var graph = this,
+    state = graph.state,
+    consts = graph.consts;
+
+    var mouseDownNode = state.mouseDownNode;
+
+    if (!mouseDownNode) return;
+
+    if (mouseDownNode !== d){
+      // we're in a different node: create new edge for mousedown edge and add to graph
+      var newEdge = {source: mouseDownNode, target: d};
+      var filtRes = graph.visibleEdges.filter(function(d){
+        if (d.source === newEdge.target && d.target === newEdge.source){
+          graph.edges.splice(graph.edges.indexOf(d), 1);
+        }
+        return d.source === newEdge.source && d.target === newEdge.target;
+      });
+      if (!filtRes[0].length){
+        graph.edges.push(newEdge);
+        graph.updateGraphVisibility();
+      }
+    } else{
+      // we're in the same node
+      if (state.justDragged) {
+        // dragged, not clicked
+        state.justDragged = false;
+      } else{
+        // clicked, not dragged
+        var extend = d3.event.shiftKey;
+        var selection = graph.state.selection;
+        if (!extend) {
+          selection.clear();
+        }
+        selection.select(d3node[0][0], true);
+      }
+    }
+  }
+
+  selectSourcePositions(start, end, selected) {
+    var graph = this;
+    var map = [];
+    var sel = graph.nodes.filter(function(n) {
+      var pos = (n.pos === undefined)
+        ? -1
+        : n.getFunctionRelativeSourcePosition(graph);
+      if (pos >= start && pos < end) {
+        map[n.id] = true;
+        n.visible = true;
+      }
+    });
+    graph.updateGraphVisibility();
+    graph.visibleNodes.filter(function(n) { return map[n.id]; })
+      .each(function(n) {
+        var selection = graph.state.selection;
+        selection.select(d3.select(this), selected);
+      });
+  }
+
+  selectAllNodes(inEdges, filter) {
+    var graph = this;
+    if (!d3.event.shiftKey) {
+      graph.state.selection.clear();
+    }
+    graph.state.selection.select(graph.visibleNodes[0], true);
+    graph.updateGraphVisibility();
+  }
+
+  svgMouseDown() {
+    this.state.graphMouseDown = true;
+  }
+
+  svgMouseUp() {
+    var graph = this,
+    state = graph.state;
+    if (state.justScaleTransGraph) {
+      // Dragged
+      state.justScaleTransGraph = false;
+    } else {
+      // Clicked
+      if (state.mouseDownNode == null) {
+        graph.state.selection.clear();
+      }
+    }
+    state.mouseDownNode = null;
+    state.graphMouseDown = false;
+  }
+
+  svgKeyDown() {
+    var state = this.state;
+    var graph = this;
+
+    // Don't handle key press repetition
+    if(state.lastKeyDown !== -1) return;
+
+    var showSelectionFrontierNodes = function(inEdges, filter, select) {
+      var frontier = graph.getNodeFrontier(state.selection.selection, inEdges, filter);
+      if (frontier != undefined) {
+        if (select) {
+          if (!d3.event.shiftKey) {
+            state.selection.clear();
+          }
+          state.selection.select(frontier[0], true);
+        }
+        graph.updateGraphVisibility();
+      }
+      allowRepetition = false;
+    }
+
+    var allowRepetition = true;
+    var eventHandled = true; // unless the below switch defaults
+    switch(d3.event.keyCode) {
+    case 49:
+    case 50:
+    case 51:
+    case 52:
+    case 53:
+    case 54:
+    case 55:
+    case 56:
+    case 57:
+      // '1'-'9'
+      showSelectionFrontierNodes(true,
+          (edge, index) => { return index == (d3.event.keyCode - 49); },
+          false);
+      break;
+    case 67:
+      // 'c'
+      showSelectionFrontierNodes(true,
+          (edge, index) => { return edge.type == 'control'; },
+          false);
+      break;
+    case 69:
+      // 'e'
+      showSelectionFrontierNodes(true,
+          (edge, index) => { return edge.type == 'effect'; },
+          false);
+      break;
+    case 79:
+      // 'o'
+      showSelectionFrontierNodes(false, undefined, false);
+      break;
+    case 73:
+      // 'i'
+      showSelectionFrontierNodes(true, undefined, false);
+      break;
+    case 65:
+      // 'a'
+      graph.selectAllNodes();
+      allowRepetition = false;
+      break;
+    case 38:
+    case 40: {
+      showSelectionFrontierNodes(d3.event.keyCode == 38, undefined, true);
+      break;
+    }
+    default:
+      eventHandled = false;
+      break;
+    }
+    if (eventHandled) {
+      d3.event.preventDefault();
+    }
+    if (!allowRepetition) {
+      state.lastKeyDown = d3.event.keyCode;
+    }
+  }
+
+  svgKeyUp() {
+    this.state.lastKeyDown = -1
+  };
+
+  layoutEdges() {
+    var graph = this;
+    graph.maxGraphX = graph.maxGraphNodeX;
+    this.visibleEdges.attr("d", function(edge){
+      return edge.generatePath(graph);
+    });
+  }
+
+  layoutGraph() {
+    layoutNodeGraph(this);
+  }
+
+  // call to propagate changes to graph
+  updateGraphVisibility() {
+
+    var graph = this,
+    state = graph.state;
+
+    var filteredEdges = graph.edges.filter(function(e) { return e.isVisible(); });
+    var visibleEdges = graph.visibleEdges.data(filteredEdges, function(edge) {
+      return edge.stringID();
+    });
+
+    // add new paths
+    visibleEdges.enter()
+      .append('path')
+      .style('marker-end','url(#end-arrow)')
+      .classed('hidden', function(e) {
+        return !e.isVisible();
+      })
+      .attr("id", function(edge){ return "e," + edge.stringID(); })
+      .on("mousedown", function(d){
+        graph.pathMouseDown.call(graph, d3.select(this), d);
+      })
+
+    // Set the correct styles on all of the paths
+    visibleEdges.classed('value', function(e) {
+      return e.type == 'value' || e.type == 'context';
+    }).classed('control', function(e) {
+      return e.type == 'control';
+    }).classed('effect', function(e) {
+      return e.type == 'effect';
+    }).classed('frame-state', function(e) {
+      return e.type == 'frame-state';
+    }).attr('stroke-dasharray', function(e) {
+      if (e.type == 'frame-state') return "10,10";
+      return (e.type == 'effect') ? "5,5" : "";
+    });
+
+    // remove old links
+    visibleEdges.exit().remove();
+
+    graph.visibleEdges = visibleEdges;
+
+    // update existing nodes
+    var filteredNodes = graph.nodes.filter(function(n) { return n.visible; });
+    graph.visibleNodes = graph.visibleNodes.data(filteredNodes, function(d) {
+      return d.id;
+    });
+    graph.visibleNodes.attr("transform", function(n){
+      return "translate(" + n.x + "," + n.y + ")";
+    }).select('rect').
+      attr(HEIGHT, function(d) { return graph.getNodeHeight(); });
+
+    // add new nodes
+    var newGs = graph.visibleNodes.enter()
+      .append("g");
+
+    newGs.classed("control", function(n) { return n.isControl(); })
+      .classed("javascript", function(n) { return n.isJavaScript(); })
+      .classed("input", function(n) { return n.isInput(); })
+      .classed("simplified", function(n) { return n.isSimplified(); })
+      .classed("machine", function(n) { return n.isMachine(); })
+      .attr("transform", function(d){ return "translate(" + d.x + "," + d.y + ")";})
+      .on("mousedown", function(d){
+        graph.nodeMouseDown.call(graph, d3.select(this), d);
+      })
+      .on("mouseup", function(d){
+        graph.nodeMouseUp.call(graph, d3.select(this), d);
+      })
+      .call(graph.drag);
+
+    newGs.append("rect")
+      .attr("rx", 10)
+      .attr("ry", 10)
+      .attr(WIDTH, function(d) { return d.getTotalNodeWidth(); })
+      .attr(HEIGHT, function(d) { return graph.getNodeHeight(); })
+
+    function appendInputAndOutputBubbles(g, d) {
+      for (var i = 0; i < d.inputs.length; ++i) {
+        var x = d.getInputX(i);
+        var y = -DEFAULT_NODE_BUBBLE_RADIUS / 2 - 4;
+        var s = g.append('circle')
+          .classed("filledBubbleStyle", function(c) {
+            return d.inputs[i].isVisible();
+          } )
+          .classed("bubbleStyle", function(c) {
+            return !d.inputs[i].isVisible();
+          } )
+          .attr("id", "ib," + d.inputs[i].stringID())
+          .attr("r", DEFAULT_NODE_BUBBLE_RADIUS)
+          .attr("transform", function(d) {
+            return "translate(" + x + "," + y + ")";
+          })
+          .on("mousedown", function(d){
+            var components = this.id.split(',');
+            var node = graph.nodeMap[components[3]];
+            var edge = node.inputs[components[2]];
+            var visible = !edge.isVisible();
+            node.setInputVisibility(components[2], visible);
+            d3.event.stopPropagation();
+            graph.updateGraphVisibility();
+          });
+      }
+      if (d.outputs.length != 0) {
+        var x = d.getOutputX();
+        var y = graph.getNodeHeight() + DEFAULT_NODE_BUBBLE_RADIUS / 2 + 4;
+        var s = g.append('circle')
+          .classed("filledBubbleStyle", function(c) {
+            return d.areAnyOutputsVisible() == 2;
+          } )
+          .classed("halFilledBubbleStyle", function(c) {
+            return d.areAnyOutputsVisible() == 1;
+          } )
+          .classed("bubbleStyle", function(c) {
+            return d.areAnyOutputsVisible() == 0;
+          } )
+          .attr("id", "ob," + d.id)
+          .attr("r", DEFAULT_NODE_BUBBLE_RADIUS)
+          .attr("transform", function(d) {
+            return "translate(" + x + "," + y + ")";
+          })
+          .on("mousedown", function(d) {
+            d.setOutputVisibility(d.areAnyOutputsVisible() == 0);
+            d3.event.stopPropagation();
+            graph.updateGraphVisibility();
+          });
+      }
+    }
+
+    newGs.each(function(d){
+      appendInputAndOutputBubbles(d3.select(this), d);
+    });
+
+    newGs.each(function(d){
+      d3.select(this).append("text")
+        .classed("label", true)
+        .attr("text-anchor","right")
+        .attr("dx", "5")
+        .attr("dy", DEFAULT_NODE_HEIGHT / 2 + 5)
+        .append('tspan')
+        .text(function(l) {
+          return d.getDisplayLabel();
+        })
+        .append("title")
+        .text(function(l) {
+          return d.getLabel();
+        })
+      if (d.type != undefined) {
+        d3.select(this).append("text")
+          .classed("label", true)
+          .classed("type", true)
+          .attr("text-anchor","right")
+          .attr("dx", "5")
+          .attr("dy", DEFAULT_NODE_HEIGHT / 2 + TYPE_HEIGHT + 5)
+          .append('tspan')
+          .text(function(l) {
+            return d.getDisplayType();
+          })
+          .append("title")
+          .text(function(l) {
+            return d.getType();
+          })
+      }
+    });
+
+    graph.visibleNodes.select('.type').each(function (d) {
+      this.setAttribute('visibility', graph.state.showTypes ? 'visible' : 'hidden');
+    });
+
+    // remove old nodes
+    graph.visibleNodes.exit().remove();
+
+    graph.visibleBubbles = d3.selectAll('circle');
+
+    graph.updateInputAndOutputBubbles();
+
+    graph.layoutEdges();
+
+    graph.svg.style.height = '100%';
+  }
+
+  getVisibleTranslation(translate, scale) {
+    var graph = this;
+    var height = (graph.maxGraphY - graph.minGraphY + 2 * GRAPH_MARGIN) * scale;
+    var width = (graph.maxGraphX - graph.minGraphX + 2 * GRAPH_MARGIN) * scale;
+
+    var dimensions = this.getSvgViewDimensions();
+
+    var baseY = translate[1];
+    var minY = (graph.minGraphY - GRAPH_MARGIN) * scale;
+    var maxY = (graph.maxGraphY + GRAPH_MARGIN) * scale;
+
+    var adjustY = 0;
+    var adjustYCandidate = 0;
+    if ((maxY + baseY) < dimensions[1]) {
+      adjustYCandidate = dimensions[1] - (maxY + baseY);
+      if ((minY + baseY + adjustYCandidate) > 0) {
+        adjustY = (dimensions[1] / 2) - (maxY - (height / 2)) - baseY;
+      } else {
+        adjustY = adjustYCandidate;
+      }
+    } else if (-baseY < minY) {
+      adjustYCandidate = -(baseY + minY);
+      if ((maxY + baseY + adjustYCandidate) < dimensions[1]) {
+        adjustY = (dimensions[1] / 2) - (maxY - (height / 2)) - baseY;
+      } else {
+        adjustY = adjustYCandidate;
+      }
+    }
+    translate[1] += adjustY;
+
+    var baseX = translate[0];
+    var minX = (graph.minGraphX - GRAPH_MARGIN) * scale;
+    var maxX = (graph.maxGraphX + GRAPH_MARGIN) * scale;
+
+    var adjustX = 0;
+    var adjustXCandidate = 0;
+    if ((maxX + baseX) < dimensions[0]) {
+      adjustXCandidate = dimensions[0] - (maxX + baseX);
+      if ((minX + baseX + adjustXCandidate) > 0) {
+        adjustX = (dimensions[0] / 2) - (maxX - (width / 2)) - baseX;
+      } else {
+        adjustX = adjustXCandidate;
+      }
+    } else if (-baseX < minX) {
+      adjustXCandidate = -(baseX + minX);
+      if ((maxX + baseX + adjustXCandidate) < dimensions[0]) {
+        adjustX = (dimensions[0] / 2) - (maxX - (width / 2)) - baseX;
+      } else {
+        adjustX = adjustXCandidate;
+      }
+    }
+    translate[0] += adjustX;
+    return translate;
+  }
+
+  translateClipped(translate, scale, transition) {
+    var graph = this;
+    var graphNode = this.graphElement[0][0];
+    var translate = this.getVisibleTranslation(translate, scale);
+    if (transition) {
+      graphNode.classList.add('visible-transition');
+      clearTimeout(graph.transitionTimout);
+      graph.transitionTimout = setTimeout(function(){
+        graphNode.classList.remove('visible-transition');
+      }, 1000);
+    }
+    var translateString = "translate(" + translate[0] + "px," + translate[1] + "px) scale(" + scale + ")";
+    graphNode.style.transform = translateString;
+    graph.dragSvg.translate(translate);
+    graph.dragSvg.scale(scale);
+  }
+
+  zoomed(){
+    this.state.justScaleTransGraph = true;
+    var scale =  this.dragSvg.scale();
+    this.translateClipped(d3.event.translate, scale);
+  }
+
+
+  getSvgViewDimensions() {
+    var canvasWidth = this.parentNode.clientWidth;
+    var documentElement = document.documentElement;
+    var canvasHeight = documentElement.clientHeight;
+    return [canvasWidth, canvasHeight];
+  }
+
+
+  minScale() {
+    var graph = this;
+    var dimensions = this.getSvgViewDimensions();
+    var width = graph.maxGraphX - graph.minGraphX;
+    var height = graph.maxGraphY - graph.minGraphY;
+    var minScale = dimensions[0] / (width + GRAPH_MARGIN * 2);
+    var minScaleYCandidate = dimensions[1] / (height + GRAPH_MARGIN * 2);
+    if (minScaleYCandidate < minScale) {
+      minScale = minScaleYCandidate;
+    }
+    this.dragSvg.scaleExtent([minScale, 1.5]);
+    return minScale;
+  }
+
+  fitGraphViewToWindow() {
+    this.svg.attr("height", document.documentElement.clientHeight + "px");
+    this.translateClipped(this.dragSvg.translate(), this.dragSvg.scale());
+  }
+
+  toggleTypes() {
+    var graph = this;
+    graph.state.showTypes = !graph.state.showTypes;
+    var element = document.getElementById('toggle-types');
+    if (graph.state.showTypes) {
+      element.classList.add('button-input-toggled');
+    } else {
+      element.classList.remove('button-input-toggled');
+    }
+    graph.updateGraphVisibility();
+  }
+
+  viewSelection() {
+    var graph = this;
+    var minX, maxX, minY, maxY;
+    var hasSelection = false;
+    graph.visibleNodes.each(function(n) {
+      if (this.classList.contains("selected")) {
+        hasSelection = true;
+        minX = minX ? Math.min(minX, n.x) : n.x;
+        maxX = maxX ? Math.max(maxX, n.x + n.getTotalNodeWidth()) :
+          n.x + n.getTotalNodeWidth();
+        minY = minY ? Math.min(minY, n.y) : n.y;
+        maxY = maxY ? Math.max(maxY, n.y + DEFAULT_NODE_HEIGHT) :
+          n.y + DEFAULT_NODE_HEIGHT;
+      }
+    });
+    if (hasSelection) {
+      graph.viewGraphRegion(minX - NODE_INPUT_WIDTH, minY - 60,
+                            maxX + NODE_INPUT_WIDTH, maxY + 60,
+                            true);
+    }
+  }
+
+  viewGraphRegion(minX, minY, maxX, maxY, transition) {
+    var graph = this;
+    var dimensions = this.getSvgViewDimensions();
+    var width = maxX - minX;
+    var height = maxY - minY;
+    var scale = Math.min(dimensions[0] / width, dimensions[1] / height);
+    scale = Math.min(1.5, scale);
+    scale = Math.max(graph.minScale(), scale);
+    var translation = [-minX*scale, -minY*scale];
+    translation = graph.getVisibleTranslation(translation, scale);
+    graph.translateClipped(translation, scale, transition);
+  }
+
+  viewWholeGraph() {
+    var graph = this;
+    var minScale = graph.minScale();
+    var translation = [0, 0];
+    translation = graph.getVisibleTranslation(translation, minScale);
+    graph.translateClipped(translation, minScale);
+  }
+}
