       return nodes
 
     # formats the value shown in the link labels
-    #
     format_value: (x) -> "#{x.toFixed(2)} PJ"
 
     # callbacks

  model: D3.sankey.Node

  # returns the height of the tallest column
  #
  max_column_value: =>
    sums = {}
    @each (n) ->

    link_mouseover: ->
      current_id = $(this).parent().attr("data-cid")
      d3.selectAll(".link").
        each (d) ->
          item = d3.select(this)
          if d.cid == current_id
            item.selectAll(".link_label").transition().style("opacity", 1)
          else
            item.transition().duration(200).style("opacity", 0.2)

    # this method is called every time we're updating the chart
    refresh: =>
      max_height = @node_list.max_column_value()

      # update the scaling function
      @y = d3.scale.linear().
        domain([0, max_height * 1.25]).
        range([0, @height * .90])

      # refresh the axis
      @svg.selectAll(".y").transition().duration(500).call(@y_axis.scale(@y))

      # move the rectangles
      @nodes.data(@node_list.models, (d) -> d.get('id')).
        selectAll("rect").
        transition().duration(500).
        attr("height", (d) => @y d.value()).
        attr("y", (d) => @y(d.y_offset()))

      # then move the node label
      @nodes.data(@node_list.models, (d) -> d.get('id')).
        selectAll("text.label").
        transition().duration(500).
        attr("y", (d) => @y(d.y_offset() + d.value() / 2) )

      # then transform the links
      @links.data(@link_list.models, (d) -> d.cid).
        transition().duration(500).
        selectAll("path").
        attr("d", (link) => @link_line link.path_points()).
        style("stroke-width", (link) => @y(link.value()))

      # then move the link labels and update their value
      @links.data(@link_list.models, (d) -> d.cid).
        transition().duration(500).
        selectAll("text.link_label").
        attr("y", (link) => @y link.right_y()).
