title: Different states in D3/Coffee Bubble chart
body: <p>I want to use this (<a href="http://vallandingham.me/vis/gates/" rel="nofollow noreferrer" title="Bubble Chart">http://vallandingham.me/vis/gates/</a>) Bubble Chart (made in D3):</p>
  
  <p><img src="https://i.stack.imgur.com/Mk6ZX.gif" alt="enter image description here"></p>
  
  <p>...to walk through some different scenarios. In short, I want to visualize election data. How many votes did parties get, and what scenario's are possible to form a government?</p>
  
  <p>At the data level, it's quite obvious: Name, number of seats in parliament, state1, state2, state3, etc. State1 is a 1 or 2. 1 is a place in government, 2 is opposition. Pretty straightforward.</p>
  
  <p>But the example only shows two states: All Grants and Grants By year. What I want, is more states like Grants By Year. But me being not a very good programmer can't figure out how to make this work. The visualisation doesn't work when I add a new state.</p>
  
  <p>Here's the code (Coffee) which controls states.</p>
  
  <pre class="lang-coffeescript prettyprint-override"><code>class BubbleChart
    constructor: (data) -&gt;
      @data = data
      @width = 940
      @height = 600
  
      @tooltip = CustomTooltip("gates_tooltip", 240)
  
      # locations the nodes will move towards
      # depending on which view is currently being
      # used
      @center = {x: @width / 2, y: @height / 2}
      @year_centers = {
        "2008": {x: @width / 3, y: @height / 2},
        "2009": {x: @width / 2, y: @height / 2},
        "2010": {x: 2 * @width / 3, y: @height / 2}
      }
  
      # used when setting up force and
      # moving around nodes
      @layout_gravity = -0.01
      @damper = 0.1
  
      # these will be set in create_nodes and create_vis
      @vis = null
      @nodes = []
      @force = null
      @circles = null
  
      # nice looking colors - no reason to buck the trend
      @fill_color = d3.scale.ordinal()
        .domain(["low", "medium", "high"])
        .range(["#d84b2a", "#beccae", "#7aa25c"])
  
      # use the max total_amount in the data as the max in the scale's domain
      max_amount = d3.max(@data, (d) -&gt; parseInt(d.total_amount))
      @radius_scale = d3.scale.pow().exponent(0.5).domain([0, max_amount]).range([2, 85])
  
      this.create_nodes()
      this.create_vis()
  
    # create node objects from original data
    # that will serve as the data behind each
    # bubble in the vis, then add each node
    # to @nodes to be used later
    create_nodes: () =&gt;
      @data.forEach (d) =&gt;
        node = {
          id: d.id
          radius: @radius_scale(parseInt(d.total_amount))
          value: d.total_amount
          name: d.grant_title
          org: d.organization
          group: d.group
          year: d.start_year
          x: Math.random() * 900
          y: Math.random() * 800
        }
        @nodes.push node
  
      @nodes.sort (a,b) -&gt; b.value - a.value
  
  
    # create svg at #vis and then 
    # create circle representation for each node
    create_vis: () =&gt;
      @vis = d3.select("#vis").append("svg")
        .attr("width", @width)
        .attr("height", @height)
        .attr("id", "svg_vis")
  
      @circles = @vis.selectAll("circle")
        .data(@nodes, (d) -&gt; d.id)
  
      # used because we need 'this' in the 
      # mouse callbacks
      that = this
  
      # radius will be set to 0 initially.
      # see transition below
      @circles.enter().append("circle")
        .attr("r", 0)
        .attr("fill", (d) =&gt; @fill_color(d.group))
        .attr("stroke-width", 2)
        .attr("stroke", (d) =&gt; d3.rgb(@fill_color(d.group)).darker())
        .attr("id", (d) -&gt; "bubble_#{d.id}")
        .on("mouseover", (d,i) -&gt; that.show_details(d,i,this))
        .on("mouseout", (d,i) -&gt; that.hide_details(d,i,this))
  
      # Fancy transition to make bubbles appear, ending with the
      # correct radius
      @circles.transition().duration(2000).attr("r", (d) -&gt; d.radius)
  
  
    # Charge function that is called for each node.
    # Charge is proportional to the diameter of the
    # circle (which is stored in the radius attribute
    # of the circle's associated data.
    # This is done to allow for accurate collision 
    # detection with nodes of different sizes.
    # Charge is negative because we want nodes to 
    # repel.
    # Dividing by 8 scales down the charge to be
    # appropriate for the visualization dimensions.
    charge: (d) -&gt;
      -Math.pow(d.radius, 2.0) / 8
  
    # Starts up the force layout with
    # the default values
    start: () =&gt;
      @force = d3.layout.force()
        .nodes(@nodes)
        .size([@width, @height])
  
    # Sets up force layout to display
    # all nodes in one circle.
    display_group_all: () =&gt;
      @force.gravity(@layout_gravity)
        .charge(this.charge)
        .friction(0.9)
        .on "tick", (e) =&gt;
          @circles.each(this.move_towards_center(e.alpha))
            .attr("cx", (d) -&gt; d.x)
            .attr("cy", (d) -&gt; d.y)
      @force.start()
  
      this.hide_years()
  
    # Moves all circles towards the @center
    # of the visualization
    move_towards_center: (alpha) =&gt;
      (d) =&gt;
        d.x = d.x + (@center.x - d.x) * (@damper + 0.02) * alpha
        d.y = d.y + (@center.y - d.y) * (@damper + 0.02) * alpha
  
    # sets the display of bubbles to be separated
    # into each year. Does this by calling move_towards_year
    display_by_year: () =&gt;
      @force.gravity(@layout_gravity)
        .charge(this.charge)
        .friction(0.9)
        .on "tick", (e) =&gt;
          @circles.each(this.move_towards_year(e.alpha))
            .attr("cx", (d) -&gt; d.x)
            .attr("cy", (d) -&gt; d.y)
      @force.start()
  
      this.display_years()
  
    # move all circles to their associated @year_centers 
    move_towards_year: (alpha) =&gt;
      (d) =&gt;
        target = @year_centers[d.year]
        d.x = d.x + (target.x - d.x) * (@damper + 0.02) * alpha * 1.1
        d.y = d.y + (target.y - d.y) * (@damper + 0.02) * alpha * 1.1
  
    # Method to display year titles
    display_years: () =&gt;
      years_x = {"2008": 160, "2009": @width / 2, "2010": @width - 160}
      years_data = d3.keys(years_x)
      years = @vis.selectAll(".years")
        .data(years_data)
  
      years.enter().append("text")
        .attr("class", "years")
        .attr("x", (d) =&gt; years_x[d] )
        .attr("y", 40)
        .attr("text-anchor", "middle")
        .text((d) -&gt; d)
  
    # Method to hide year titiles
    hide_years: () =&gt;
      years = @vis.selectAll(".years").remove()
  
    show_details: (data, i, element) =&gt;
      d3.select(element).attr("stroke", "black")
      content = "&lt;span class=\"name\"&gt;Title:&lt;/span&gt;&lt;span class=\"value\"&gt; #{data.name}&lt;/span&gt;&lt;br/&gt;"
      content +="&lt;span class=\"name\"&gt;Amount:&lt;/span&gt;&lt;span class=\"value\"&gt; $#{addCommas(data.value)}&lt;/span&gt;&lt;br/&gt;"
      content +="&lt;span class=\"name\"&gt;Year:&lt;/span&gt;&lt;span class=\"value\"&gt; #{data.year}&lt;/span&gt;"
      @tooltip.showTooltip(content,d3.event)
  
  
    hide_details: (data, i, element) =&gt;
      d3.select(element).attr("stroke", (d) =&gt; d3.rgb(@fill_color(d.group)).darker())
      @tooltip.hideTooltip()
  
  
  root = exports ? this
  
  $ -&gt;
    chart = null
  
    render_vis = (csv) -&gt;
      chart = new BubbleChart csv
      chart.start()
      root.display_all()
    root.display_all = () =&gt;
      chart.display_group_all()
    root.display_year = () =&gt;
      chart.display_by_year()
    root.toggle_view = (view_type) =&gt;
      if view_type == 'year'
        root.display_year()
      else
        root.display_all()
  
    d3.csv "data/gates_money.csv", render_vis
  </code></pre>