         .nodes(data)
       @
 
-    breadcrumbs: () ->
-      breadcrumbData = @_allData.map((prevData, idx) -> { name: prevData.name, value: idx })
-      breadcrumbs = d3.select('.breadcrumb')
-        .selectAll('li')
-        .data(breadcrumbData)
-
-      breadcrumbs.enter()
-        .append('li')
-          .append('a')
-          .text((d) -> getLastTwoTokens(d.name))
-          .on 'click', (breadcrumb) =>
-            idx = breadcrumb.value
-            displayed = @_allData[idx]
-            @_allData = @_allData.slice(0, idx)
-            @data(displayed).render()
-
-      breadcrumbs.exit().remove()
-      @
-
-    getLabelText: (label, dx) ->
-      return "" if not label
-      shortLabel = getLastTwoTokens(label)
-      maxLength = Math.round(@x(dx) / 4)
-      return shortLabel.substr(0, maxLength)
+    label: (d) ->
+      return "" if not d.name
+      label = getClassAndMethodName(d.name)
+      label.substr(0, Math.round(@x(d.dx) / 4))
 
     color: (d) -> @colorScheme()[Math.floor(Math.random() * @colorScheme().length)]
 
     render: () ->
-      # compute height dynamically so the fixed unit is the height of a cell
-      console.time('rendering')
+      console.time('render')
 
-      d3.select(@containerId())
-        .select('svg').remove()
+      # refresh container
+      @container(@containerSelector())
+        .attr('width', @width())
+        .attr('height', @height())
 
-      @container = d3.select(@containerId())
-        .append('svg')
-          .attr('width', @width())
-          .attr('height', @height())
+      @maxCells = Math.floor(@height() / @cellHeight())
+      @maxDepth = maxDepth(@data()[0])
 
-      @maxCells    = Math.floor(@height() / @cellHeight())
-
-      depth = maxDepth(@data()[0])
       @x = d3.scale.linear()
         .domain([0, d3.max(@data(), (d) -> d.x + d.dx)])
         .range([0, @width()])
       @y = d3.scale.quantize()
         .domain([d3.max(@data(), (d) -> d.y), 0])
-        .range(d3.range(depth)
-          .map((cell) =>  (cell  - depth + @maxCells) * @cellHeight()))
+        .range(d3.range(@maxDepth)
+          .map((cell) =>  (cell - @maxDepth + @maxCells) * @cellHeight()))
 
-      @container
+      @container()
         .selectAll('.node')
         .data(@data().filter((d) =>
           @x(d.dx) > 0.1 and @y(d.y) >= 0))

            .attr('dy', '.25em')
            .attr('x', (d) => @x(d.x) + @x(d.dx) / 2)
            .attr('y', (d) => @y(d.y) + @cellHeight() / 2)
            .text((d) => @getLabelText(d.name, d.dx))

      console.timeEnd('rendering')
      console.log("Rendered #{@container.selectAll('.node')[0].length} elements")
      return @breadcrumbs().interactivity()

    interactivity: () ->
      console.time('interactivity')
      clickHandler = (d) => @data(d).render()

      @container
        .selectAll('.node')
        .on 'click', clickHandler

      @container
        .selectAll('.label')
        .on 'click', clickHandler
      console.timeEnd('interactivity')
      @

    _generateAccessors: (accessors) ->

d3.json "data/profile-large.json", (err, data) ->
  window.flameGraph = d3.flameGraph()
  flameGraph
    .containerSelector('#d3-flame-graph')
    .width(1200).height(600).cellHeight(10)
    .data(convert(data.profile))
    .colorScheme(["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#bd0026"])
