       return "" if not d?.name
       label = getClassAndMethodName(d.name)
       label.substr(0, Math.round(@x(d.dx) / 4))
-
-    color: (d) -> @colors()[Math.floor(Math.random() * @colors().length)]
-
-    getClassAndMethodName = (fqdn) ->
-      tokens = fqdn.split(".")
-      tokens.slice(tokens.length - 2).join(".")
 
     render: (selector) ->
       console.time('render')

            .attr('height', (d) => @cellHeight())
            .attr('x', (d) => @x(d.x))
            .attr('y', (d) => @y(d.y))
            .attr('stroke', @colors()[@colors().length - 1])
            .attr('fill', (d) => @color(d))
            .attr('fill-opacity', '0.8')

      @container

throw new Error("d3.js needs to be loaded") if not d3

d3.flameGraph = ->

  getClassAndMethodName = (fqdn) ->
    tokens = fqdn.split(".")
    tokens.slice(tokens.length - 2).join(".")

  # Return a vector (0.0->1.0) that is a hash of the input string.
  # The hash is computed to favor early characters over later ones, so
  # that strings with similar starts have similar vectors. Only the first
  # 6 characters are considered.
  hash = (name) ->
    [result, maxHash, weight, mod] = [0, 0, 1, 10]
    name = getClassAndMethodName(name).slice(0, 6)
    for i in [0..(name.length-1)]
      result += weight * (name.charCodeAt(i) % mod)
      maxHash += weight * (mod - 1)
      weight *= 0.7
    if maxHash > 0 then result / maxHash else result

  class FlameGraph
    constructor: () ->
