about summary refs log tree commit diff
diff options
context:
space:
mode:
-rwxr-xr-xwqflask/runserver.py3
-rwxr-xr-xwqflask/wqflask/static/new/css/bar_chart.css4
-rwxr-xr-xwqflask/wqflask/static/new/javascript/bar_chart.coffee214
-rwxr-xr-xwqflask/wqflask/static/new/javascript/bar_chart.js957
-rwxr-xr-xwqflask/wqflask/static/new/javascript/show_trait.coffee109
-rwxr-xr-xwqflask/wqflask/static/new/javascript/show_trait.js106
-rwxr-xr-xwqflask/wqflask/templates/show_trait_statistics_new.html17
7 files changed, 767 insertions, 643 deletions
diff --git a/wqflask/runserver.py b/wqflask/runserver.py
index 5a76d1e2..59ebf0d4 100755
--- a/wqflask/runserver.py
+++ b/wqflask/runserver.py
@@ -30,6 +30,7 @@ logging_tree.printout()
 
 app.run(host='0.0.0.0',
         port=app.config['SERVER_PORT'],
-        use_debugger=False,
+        debug=True,
+        use_debugger=True,
         threaded=True,
         use_reloader=True)
diff --git a/wqflask/wqflask/static/new/css/bar_chart.css b/wqflask/wqflask/static/new/css/bar_chart.css
index 78d31eee..0dda47c4 100755
--- a/wqflask/wqflask/static/new/css/bar_chart.css
+++ b/wqflask/wqflask/static/new/css/bar_chart.css
@@ -9,6 +9,10 @@
   fill: steelblue;

   shape-rendering: crispEdges;

 }

+

+#legend-left, #legend-right {

+  font-size: 20px;

+}

 /*

 .x.axis path {

   display: none;

diff --git a/wqflask/wqflask/static/new/javascript/bar_chart.coffee b/wqflask/wqflask/static/new/javascript/bar_chart.coffee
index c83de64e..7a2b38f3 100755
--- a/wqflask/wqflask/static/new/javascript/bar_chart.coffee
+++ b/wqflask/wqflask/static/new/javascript/bar_chart.coffee
@@ -10,11 +10,10 @@ class Bar_Chart
             @get_attr_color_dict(@distinct_attr_vals)
         
         #Used to calculate the bottom margin so sample names aren't cut off
-        longest_sample_name = d3.max(sample.length for sample in @sample_names)
+        longest_sample_name = d3.max(sample.name.length for sample in @sample_list)
         
         @margin = {top: 20, right: 20, bottom: longest_sample_name * 7, left: 40}
-        @plot_width = @sample_vals.length * 20 - @margin.left - @margin.right
-        @range = @sample_vals.length * 20
+        @plot_width = @sample_vals.length * 20
         @plot_height = 500 - @margin.top - @margin.bottom
 
         @x_buffer = @plot_width/20
@@ -26,41 +25,36 @@ class Bar_Chart
         @svg = @create_svg()
 
         @plot_height -= @y_buffer
-        @create_scales()
+        @create_scales(@sample_names)
         @create_graph()
 
         d3.select("#color_attribute").on("change", =>
             @attribute = $("#color_attribute").val()
+
             console.log("attr_color_dict:", @attr_color_dict)
-            #if $("#update_bar_chart").html() == 'Sort By Name'
-            if @sort_by = "name" 
-                @svg.selectAll(".bar")
-                    .data(@sorted_samples())
-                    .transition()
-                    .duration(1000)
-                    .style("fill", (d) =>
-                        if @attribute == "None"
-                            return "steelblue"
-                        else
-                            return @attr_color_dict[@attribute][d[2][@attribute]]
-                    )
-                    .select("title")
-                    .text((d) =>
-                        return d[1]
-                    )
+
+            @svg.selectAll(".bar")
+                .data(if @sort_by == "name" then @samples else @sorted_samples())
+                .transition()
+                .duration(1000)
+                .style("fill", (d) =>
+                    if @attribute == "None"
+                        return "steelblue"
+                    else
+                        return @attr_color_dict[@attribute][d[2][@attribute]]
+                )
+                .select("title")
+                .text((d) =>
+                    return d[1]
+                )
+
+            $(".legend").remove()
+            if @attribute == "None" or @is_discrete[@attribute]
+                $("#legend-left,#legend-right,#legend-colors").empty()
+                if @attribute != "None"
+                    @add_legend(@attribute, @distinct_attr_vals[@attribute])
             else
-                @svg.selectAll(".bar")
-                    .data(@samples)
-                    .transition()
-                    .duration(1000)
-                    .style("fill", (d) =>
-                        if @attribute == "None"
-                            return "steelblue"
-                        else
-                            return @attr_color_dict[@attribute][d[2][@attribute]]
-                    )
-            @draw_legend()
-            @add_legend(@attribute, @distinct_attr_vals[@attribute])
+                @draw_legend()
         )
 
         $(".sort_by_value").on("click", =>
@@ -136,11 +130,45 @@ class Bar_Chart
             @open_trait_selection()
         )
 
+    extra: (sample) ->
+        attr_vals = {}
+        for attribute in @attributes
+            attr_vals[attribute] = sample["extra_attributes"][attribute]
+        attr_vals
+
+    # takes a dict: name -> value and rebuilds the graph
+    redraw: (samples_dict) ->
+        curr = (x for x in @sample_list when\
+                x.name of samples_dict and samples_dict[x.name] != null)
+        @sample_names = (x.name for x in curr)
+        @sample_vals = (samples_dict[x.name] for x in curr)
+        @sample_attr_vals = (@extra(x) for x in curr)
+        @samples = _.zip(@sample_names, @sample_vals, @sample_attr_vals)
+
+        @rebuild_bar_graph(if @sort_by == 'name' then @samples else @sorted_samples())
+
     rebuild_bar_graph: (samples) ->
         console.log("samples:", samples)
-        @svg.selectAll(".bar")
-            .data(samples)
-            .transition()
+        @attribute = $("#color_attribute").val()
+
+        # recompute sizes
+        vals = (x[1] for x in samples)
+        @y_min = d3.min(vals)
+        @y_max = d3.max(vals) * 1.1
+        @plot_width = samples.length * 20
+
+        $("svg.bar_chart").attr("width", @plot_width + @margin.left + @margin.right)
+
+        names = (x[0] for x in samples)
+        @create_scales(names)
+        $('.bar_chart').find('.x.axis').remove()
+        $('.bar_chart').find('.y.axis').remove()
+        @add_x_axis()
+        @add_y_axis()
+
+        bars = @update_bars(samples)
+
+        bars.transition()
             .duration(1000)
             .style("fill", (d) =>
                 if @attributes.length == 0 and @trait_color_dict?
@@ -156,6 +184,7 @@ class Bar_Chart
                 else
                     return "steelblue"
             )
+            .attr("x", (d) => return @x_scale(d[0]))
             .attr("y", (d) =>
                 return @y_scale(d[1])
             )
@@ -170,22 +199,19 @@ class Bar_Chart
             #    return @trait_color_dict[d[0]]
             #    #return @attr_color_dict["collection_trait"][trimmed_samples[d[0]]]
             #)
-        sample_names = (sample[0] for sample in samples)
-        console.log("sample_names2:", sample_names)
-        x_scale = d3.scale.ordinal()
-            .domain(sample_names)
-            .rangeRoundBands([0, @range], 0.1, 0)
-        $('.bar_chart').find('.x.axis').remove()
-        @add_x_axis(x_scale)
 
     get_attr_color_dict: (vals) ->
         @attr_color_dict = {}
+        @is_discrete = {}
+        @minimum_values = {}
+        @maximum_values = {}
         console.log("vals:", vals)
         for own key, distinct_vals of vals
             @min_val = d3.min(distinct_vals)
             @max_val = d3.max(distinct_vals)
             this_color_dict = {}
-            if distinct_vals.length < 10
+            discrete = distinct_vals.length < 10
+            if discrete
                 color = d3.scale.category10()
                 for value, i in distinct_vals
                     this_color_dict[value] = color(i)
@@ -200,8 +226,7 @@ class Bar_Chart
                         return true
                 )
                     color_range = d3.scale.linear()
-                                    .domain([min_val,
-                                            max_val])
+                                    .domain([@min_val, @max_val])
                                     .range([0,255])
                     for value, i in distinct_vals
                         console.log("color_range(value):", parseInt(color_range(value)))
@@ -209,19 +234,22 @@ class Bar_Chart
                         #this_color_dict[value] = d3.rgb("lightblue").darker(color_range(parseInt(value)))
                         #this_color_dict[value] = "rgb(0, 0, " + color_range(parseInt(value)) + ")"
             @attr_color_dict[key] = this_color_dict
+            @is_discrete[key] = discrete
+            @minimum_values[key] = @min_val
+            @maximum_values[key] = @max_val
        
 
 
     draw_legend: () ->
-        $('#legend-left').html(@min_val)
-        $('#legend-right').html(@max_val)
-        svg_html = '<svg height="10" width="90"> \
-                        <rect x="0" width="15" height="10" style="fill: rgb(0, 0, 0);"></rect> \
-                        <rect x="15" width="15" height="10" style="fill: rgb(50, 0, 0);"></rect> \
-                        <rect x="30" width="15" height="10" style="fill: rgb(100, 0, 0);"></rect> \
-                        <rect x="45" width="15" height="10" style="fill: rgb(150, 0, 0);"></rect> \
-                        <rect x="60" width="15" height="10" style="fill: rgb(200, 0, 0);"></rect> \
-                        <rect x="75" width="15" height="10" style="fill: rgb(255, 0, 0);"></rect> \
+        $('#legend-left').html(@minimum_values[@attribute])
+        $('#legend-right').html(@maximum_values[@attribute])
+        svg_html = '<svg height="15" width="120"> \
+                        <rect x="0" width="20" height="15" style="fill: rgb(0, 0, 0);"></rect> \
+                        <rect x="20" width="20" height="15" style="fill: rgb(50, 0, 0);"></rect> \
+                        <rect x="40" width="20" height="15" style="fill: rgb(100, 0, 0);"></rect> \
+                        <rect x="60" width="20" height="15" style="fill: rgb(150, 0, 0);"></rect> \
+                        <rect x="80" width="20" height="15" style="fill: rgb(200, 0, 0);"></rect> \
+                        <rect x="100" width="20" height="15" style="fill: rgb(255, 0, 0);"></rect> \
                     </svg>'
         console.log("svg_html:", svg_html)
         $('#legend-colors').html(svg_html)
@@ -272,16 +300,11 @@ class Bar_Chart
         @sample_vals = (sample.value for sample in @sample_list when sample.value != null)
         @attributes = (key for key of @sample_list[0]["extra_attributes"])
         console.log("attributes:", @attributes)
-        @sample_attr_vals = []
-        if @attributes.length > 0
-            for sample in @sample_list
-                attr_vals = {}
-                for attribute in @attributes
-                    attr_vals[attribute] = sample["extra_attributes"][attribute]
-                @sample_attr_vals.push(attr_vals)
+        @sample_attr_vals = (@extra(sample) for sample in @sample_list when sample.value != null)
         @samples = _.zip(@sample_names, @sample_vals, @sample_attr_vals)
 
     get_distinct_attr_vals: () ->
+        # FIXME: this has quadratic behaviour, may cause issues with many samples and continuous attributes
         @distinct_attr_vals = {}
         for sample in @sample_attr_vals
             for attribute of sample
@@ -302,10 +325,10 @@ class Bar_Chart
             
         return svg
         
-    create_scales: () ->
+    create_scales: (sample_names) ->
         @x_scale = d3.scale.ordinal()
-            .domain(@sample_names)
-            .rangeRoundBands([0, @range], 0.1, 0)
+            .domain(sample_names)
+            .rangeRoundBands([0, @plot_width], 0.1, 0)
 
         @y_scale = d3.scale.linear()
             .domain([@y_min * 0.75, @y_max])
@@ -314,14 +337,14 @@ class Bar_Chart
     create_graph: () ->
         
         #@add_border()
-        @add_x_axis(@x_scale)
+        @add_x_axis()
         @add_y_axis() 
         
-        @add_bars()
+        @update_bars(@samples)
         
     add_x_axis: (scale) ->
         xAxis = d3.svg.axis()
-            .scale(scale)
+            .scale(@x_scale)
             .orient("bottom");
         
         @svg.append("g")
@@ -352,10 +375,9 @@ class Bar_Chart
             .attr("dy", ".71em")
             .style("text-anchor", "end")
 
-    add_bars: () ->
-        @svg.selectAll(".bar")
-            .data(@samples)
-          .enter().append("rect")
+    update_bars: (samples) ->
+        bars = @svg.selectAll(".bar").data(samples, (d) => return d[0])
+        bars.enter().append("rect")
             .style("fill", "steelblue")
             .attr("class", "bar")
             .attr("x", (d) =>
@@ -372,7 +394,8 @@ class Bar_Chart
             .text((d) =>
                 return d[1]
             )
-            
+        bars.exit().remove()
+        return bars
 
     sorted_samples: () ->
         #if @sample_attr_vals.length > 0
@@ -386,38 +409,19 @@ class Bar_Chart
         return sorted
 
     add_legend: (attribute, distinct_vals) ->
-        legend = @svg.append("g")
-            .attr("class", "legend")
-            .attr("height", 100)
-            .attr("width", 100)
-            .attr('transform', 'translate(-20,50)')
-
-        legend_rect = legend.selectAll('rect')
-                        .data(distinct_vals)
-                        .enter()
-                        .append("rect")
-                        .attr("x", @plot_width - 65)
-                        .attr("width", 10)
-                        .attr("height", 10)
-                        .attr("y", (d, i) =>
-                            return i * 20
-                        )
-                        .style("fill", (d) =>
-                            console.log("TEST:", @attr_color_dict[attribute][d])
-                            return @attr_color_dict[attribute][d]
-                        )
-
-        legend_text = legend.selectAll('text')
-                        .data(distinct_vals)
-                        .enter()
-                        .append("text")
-                        .attr("x", @plot_width - 52)
-                        .attr("y", (d, i) =>
-                            return i*20 + 9    
-                        )
-                        .text((d) =>
-                            return d
-                        )
+        legend_span = d3.select('#bar_chart_legend')
+            .append('div').style('word-wrap', 'break-word')
+            .attr('class', 'legend').selectAll('span')
+            .data(distinct_vals)
+          .enter().append('span').style({'word-wrap': 'normal', 'display': 'inline-block'})
+
+        legend_span.append('span')
+            .style("background-color", (d) =>
+                return @attr_color_dict[attribute][d]
+            )
+            .style({'display': 'inline-block', 'width': '15px', 'height': '15px',\
+                    'margin': '0px 5px 0px 15px'})
+        legend_span.append('span').text((d) => return d).style('font-size', '20px')
 
     open_trait_selection: () ->
         $('#collections_holder').load('/collections/list?color_by_trait #collections_list', =>
@@ -488,4 +492,4 @@ class Bar_Chart
         #for sample in samples
         #    if samples[sample] in distinct_values
 
-root.Bar_Chart = Bar_Chart
\ No newline at end of file
+root.Bar_Chart = Bar_Chart
diff --git a/wqflask/wqflask/static/new/javascript/bar_chart.js b/wqflask/wqflask/static/new/javascript/bar_chart.js
index f5ed544b..cc21550e 100755
--- a/wqflask/wqflask/static/new/javascript/bar_chart.js
+++ b/wqflask/wqflask/static/new/javascript/bar_chart.js
@@ -1,54 +1,53 @@
-// Generated by CoffeeScript 1.8.0
-var Bar_Chart, root,
-  __hasProp = {}.hasOwnProperty,
-  __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+// Generated by CoffeeScript 1.9.2
+(function() {
+  var Bar_Chart, root,
+    hasProp = {}.hasOwnProperty,
+    indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
 
-root = typeof exports !== "undefined" && exports !== null ? exports : this;
+  root = typeof exports !== "undefined" && exports !== null ? exports : this;
 
-Bar_Chart = (function() {
-  function Bar_Chart(sample_list) {
-    var longest_sample_name, sample;
-    this.sample_list = sample_list;
-    this.sort_by = "name";
-    this.get_samples();
-    console.log("sample names:", this.sample_names);
-    if (this.sample_attr_vals.length > 0) {
-      this.get_distinct_attr_vals();
-      this.get_attr_color_dict(this.distinct_attr_vals);
-    }
-    longest_sample_name = d3.max((function() {
-      var _i, _len, _ref, _results;
-      _ref = this.sample_names;
-      _results = [];
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        sample = _ref[_i];
-        _results.push(sample.length);
+  Bar_Chart = (function() {
+    function Bar_Chart(sample_list1) {
+      var longest_sample_name, sample;
+      this.sample_list = sample_list1;
+      this.sort_by = "name";
+      this.get_samples();
+      console.log("sample names:", this.sample_names);
+      if (this.sample_attr_vals.length > 0) {
+        this.get_distinct_attr_vals();
+        this.get_attr_color_dict(this.distinct_attr_vals);
       }
-      return _results;
-    }).call(this));
-    this.margin = {
-      top: 20,
-      right: 20,
-      bottom: longest_sample_name * 7,
-      left: 40
-    };
-    this.plot_width = this.sample_vals.length * 20 - this.margin.left - this.margin.right;
-    this.range = this.sample_vals.length * 20;
-    this.plot_height = 500 - this.margin.top - this.margin.bottom;
-    this.x_buffer = this.plot_width / 20;
-    this.y_buffer = this.plot_height / 20;
-    this.y_min = d3.min(this.sample_vals);
-    this.y_max = d3.max(this.sample_vals) * 1.1;
-    this.svg = this.create_svg();
-    this.plot_height -= this.y_buffer;
-    this.create_scales();
-    this.create_graph();
-    d3.select("#color_attribute").on("change", (function(_this) {
-      return function() {
-        _this.attribute = $("#color_attribute").val();
-        console.log("attr_color_dict:", _this.attr_color_dict);
-        if (_this.sort_by = "name") {
-          _this.svg.selectAll(".bar").data(_this.sorted_samples()).transition().duration(1000).style("fill", function(d) {
+      longest_sample_name = d3.max((function() {
+        var j, len, ref, results;
+        ref = this.sample_list;
+        results = [];
+        for (j = 0, len = ref.length; j < len; j++) {
+          sample = ref[j];
+          results.push(sample.name.length);
+        }
+        return results;
+      }).call(this));
+      this.margin = {
+        top: 20,
+        right: 20,
+        bottom: longest_sample_name * 7,
+        left: 40
+      };
+      this.plot_width = this.sample_vals.length * 20;
+      this.plot_height = 500 - this.margin.top - this.margin.bottom;
+      this.x_buffer = this.plot_width / 20;
+      this.y_buffer = this.plot_height / 20;
+      this.y_min = d3.min(this.sample_vals);
+      this.y_max = d3.max(this.sample_vals) * 1.1;
+      this.svg = this.create_svg();
+      this.plot_height -= this.y_buffer;
+      this.create_scales(this.sample_names);
+      this.create_graph();
+      d3.select("#color_attribute").on("change", (function(_this) {
+        return function() {
+          _this.attribute = $("#color_attribute").val();
+          console.log("attr_color_dict:", _this.attr_color_dict);
+          _this.svg.selectAll(".bar").data(_this.sort_by === "name" ? _this.samples : _this.sorted_samples()).transition().duration(1000).style("fill", function(d) {
             if (_this.attribute === "None") {
               return "steelblue";
             } else {
@@ -57,438 +56,526 @@ Bar_Chart = (function() {
           }).select("title").text(function(d) {
             return d[1];
           });
-        } else {
-          _this.svg.selectAll(".bar").data(_this.samples).transition().duration(1000).style("fill", function(d) {
-            if (_this.attribute === "None") {
-              return "steelblue";
-            } else {
-              return _this.attr_color_dict[_this.attribute][d[2][_this.attribute]];
+          $(".legend").remove();
+          if (_this.attribute === "None" || _this.is_discrete[_this.attribute]) {
+            $("#legend-left,#legend-right,#legend-colors").empty();
+            if (_this.attribute !== "None") {
+              return _this.add_legend(_this.attribute, _this.distinct_attr_vals[_this.attribute]);
             }
-          });
+          } else {
+            return _this.draw_legend();
+          }
+        };
+      })(this));
+      $(".sort_by_value").on("click", (function(_this) {
+        return function() {
+          console.log("sorting by value");
+          _this.sort_by = "value";
+          if (_this.attributes.length > 0) {
+            _this.attribute = $("#color_attribute").val();
+          }
+          return _this.rebuild_bar_graph(_this.sorted_samples());
+        };
+      })(this));
+      $(".sort_by_name").on("click", (function(_this) {
+        return function() {
+          console.log("sorting by name");
+          _this.sort_by = "name";
+          if (_this.attributes.length > 0) {
+            _this.attribute = $("#color_attribute").val();
+          }
+          return _this.rebuild_bar_graph(_this.samples);
+        };
+      })(this));
+      d3.select("#color_by_trait").on("click", (function(_this) {
+        return function() {
+          return _this.open_trait_selection();
+        };
+      })(this));
+    }
+
+    Bar_Chart.prototype.extra = function(sample) {
+      var attr_vals, attribute, j, len, ref;
+      attr_vals = {};
+      ref = this.attributes;
+      for (j = 0, len = ref.length; j < len; j++) {
+        attribute = ref[j];
+        attr_vals[attribute] = sample["extra_attributes"][attribute];
+      }
+      return attr_vals;
+    };
+
+    Bar_Chart.prototype.redraw = function(samples_dict) {
+      var curr, x;
+      curr = (function() {
+        var j, len, ref, results;
+        ref = this.sample_list;
+        results = [];
+        for (j = 0, len = ref.length; j < len; j++) {
+          x = ref[j];
+          if (x.name in samples_dict && samples_dict[x.name] !== null) {
+            results.push(x);
+          }
         }
-        _this.draw_legend();
-        return _this.add_legend(_this.attribute, _this.distinct_attr_vals[_this.attribute]);
-      };
-    })(this));
-    $(".sort_by_value").on("click", (function(_this) {
-      return function() {
-        console.log("sorting by value");
-        _this.sort_by = "value";
-        if (_this.attributes.length > 0) {
-          _this.attribute = $("#color_attribute").val();
+        return results;
+      }).call(this);
+      this.sample_names = (function() {
+        var j, len, results;
+        results = [];
+        for (j = 0, len = curr.length; j < len; j++) {
+          x = curr[j];
+          results.push(x.name);
         }
-        return _this.rebuild_bar_graph(_this.sorted_samples());
-      };
-    })(this));
-    $(".sort_by_name").on("click", (function(_this) {
-      return function() {
-        console.log("sorting by name");
-        _this.sort_by = "name";
-        if (_this.attributes.length > 0) {
-          _this.attribute = $("#color_attribute").val();
+        return results;
+      })();
+      this.sample_vals = (function() {
+        var j, len, results;
+        results = [];
+        for (j = 0, len = curr.length; j < len; j++) {
+          x = curr[j];
+          results.push(samples_dict[x.name]);
         }
-        return _this.rebuild_bar_graph(_this.samples);
-      };
-    })(this));
-    d3.select("#color_by_trait").on("click", (function(_this) {
-      return function() {
-        return _this.open_trait_selection();
-      };
-    })(this));
-  }
-
-  Bar_Chart.prototype.rebuild_bar_graph = function(samples) {
-    var sample, sample_names, x_scale;
-    console.log("samples:", samples);
-    this.svg.selectAll(".bar").data(samples).transition().duration(1000).style("fill", (function(_this) {
-      return function(d) {
-        if (_this.attributes.length === 0 && (_this.trait_color_dict != null)) {
-          console.log("SAMPLE:", d[0]);
-          console.log("CHECKING:", _this.trait_color_dict[d[0]]);
-          return _this.trait_color_dict[d[0]];
-        } else if (_this.attributes.length > 0 && _this.attribute !== "None") {
-          console.log("@attribute:", _this.attribute);
-          console.log("d[2]", d[2]);
-          console.log("the_color:", _this.attr_color_dict[_this.attribute][d[2][_this.attribute]]);
-          return _this.attr_color_dict[_this.attribute][d[2][_this.attribute]];
-        } else {
-          return "steelblue";
+        return results;
+      })();
+      this.sample_attr_vals = (function() {
+        var j, len, results;
+        results = [];
+        for (j = 0, len = curr.length; j < len; j++) {
+          x = curr[j];
+          results.push(this.extra(x));
         }
-      };
-    })(this)).attr("y", (function(_this) {
-      return function(d) {
-        return _this.y_scale(d[1]);
-      };
-    })(this)).attr("height", (function(_this) {
-      return function(d) {
-        return _this.plot_height - _this.y_scale(d[1]);
-      };
-    })(this)).select("title").text((function(_this) {
-      return function(d) {
-        return d[1];
-      };
-    })(this));
-    sample_names = (function() {
-      var _i, _len, _results;
-      _results = [];
-      for (_i = 0, _len = samples.length; _i < _len; _i++) {
-        sample = samples[_i];
-        _results.push(sample[0]);
-      }
-      return _results;
-    })();
-    console.log("sample_names2:", sample_names);
-    x_scale = d3.scale.ordinal().domain(sample_names).rangeRoundBands([0, this.range], 0.1, 0);
-    $('.bar_chart').find('.x.axis').remove();
-    return this.add_x_axis(x_scale);
-  };
+        return results;
+      }).call(this);
+      this.samples = _.zip(this.sample_names, this.sample_vals, this.sample_attr_vals);
+      return this.rebuild_bar_graph(this.sort_by === 'name' ? this.samples : this.sorted_samples());
+    };
 
-  Bar_Chart.prototype.get_attr_color_dict = function(vals) {
-    var color, color_range, distinct_vals, i, key, this_color_dict, value, _i, _j, _len, _len1, _results;
-    this.attr_color_dict = {};
-    console.log("vals:", vals);
-    _results = [];
-    for (key in vals) {
-      if (!__hasProp.call(vals, key)) continue;
-      distinct_vals = vals[key];
-      this.min_val = d3.min(distinct_vals);
-      this.max_val = d3.max(distinct_vals);
-      this_color_dict = {};
-      if (distinct_vals.length < 10) {
-        color = d3.scale.category10();
-        for (i = _i = 0, _len = distinct_vals.length; _i < _len; i = ++_i) {
-          value = distinct_vals[i];
-          this_color_dict[value] = color(i);
+    Bar_Chart.prototype.rebuild_bar_graph = function(samples) {
+      var bars, names, vals, x;
+      console.log("samples:", samples);
+      this.attribute = $("#color_attribute").val();
+      vals = (function() {
+        var j, len, results;
+        results = [];
+        for (j = 0, len = samples.length; j < len; j++) {
+          x = samples[j];
+          results.push(x[1]);
         }
-      } else {
-        console.log("distinct_values:", distinct_vals);
-        if (_.every(distinct_vals, (function(_this) {
-          return function(d) {
-            if (isNaN(d)) {
-              return false;
-            } else {
-              return true;
-            }
-          };
-        })(this))) {
-          color_range = d3.scale.linear().domain([min_val, max_val]).range([0, 255]);
-          for (i = _j = 0, _len1 = distinct_vals.length; _j < _len1; i = ++_j) {
+        return results;
+      })();
+      this.y_min = d3.min(vals);
+      this.y_max = d3.max(vals) * 1.1;
+      this.plot_width = samples.length * 20;
+      $("svg.bar_chart").attr("width", this.plot_width + this.margin.left + this.margin.right);
+      names = (function() {
+        var j, len, results;
+        results = [];
+        for (j = 0, len = samples.length; j < len; j++) {
+          x = samples[j];
+          results.push(x[0]);
+        }
+        return results;
+      })();
+      this.create_scales(names);
+      $('.bar_chart').find('.x.axis').remove();
+      $('.bar_chart').find('.y.axis').remove();
+      this.add_x_axis();
+      this.add_y_axis();
+      bars = this.update_bars(samples);
+      return bars.transition().duration(1000).style("fill", (function(_this) {
+        return function(d) {
+          if (_this.attributes.length === 0 && (_this.trait_color_dict != null)) {
+            console.log("SAMPLE:", d[0]);
+            console.log("CHECKING:", _this.trait_color_dict[d[0]]);
+            return _this.trait_color_dict[d[0]];
+          } else if (_this.attributes.length > 0 && _this.attribute !== "None") {
+            console.log("@attribute:", _this.attribute);
+            console.log("d[2]", d[2]);
+            console.log("the_color:", _this.attr_color_dict[_this.attribute][d[2][_this.attribute]]);
+            return _this.attr_color_dict[_this.attribute][d[2][_this.attribute]];
+          } else {
+            return "steelblue";
+          }
+        };
+      })(this)).attr("x", (function(_this) {
+        return function(d) {
+          return _this.x_scale(d[0]);
+        };
+      })(this)).attr("y", (function(_this) {
+        return function(d) {
+          return _this.y_scale(d[1]);
+        };
+      })(this)).attr("height", (function(_this) {
+        return function(d) {
+          return _this.plot_height - _this.y_scale(d[1]);
+        };
+      })(this)).select("title").text((function(_this) {
+        return function(d) {
+          return d[1];
+        };
+      })(this));
+    };
+
+    Bar_Chart.prototype.get_attr_color_dict = function(vals) {
+      var color, color_range, discrete, distinct_vals, i, j, k, key, len, len1, results, this_color_dict, value;
+      this.attr_color_dict = {};
+      this.is_discrete = {};
+      this.minimum_values = {};
+      this.maximum_values = {};
+      console.log("vals:", vals);
+      results = [];
+      for (key in vals) {
+        if (!hasProp.call(vals, key)) continue;
+        distinct_vals = vals[key];
+        this.min_val = d3.min(distinct_vals);
+        this.max_val = d3.max(distinct_vals);
+        this_color_dict = {};
+        discrete = distinct_vals.length < 10;
+        if (discrete) {
+          color = d3.scale.category10();
+          for (i = j = 0, len = distinct_vals.length; j < len; i = ++j) {
             value = distinct_vals[i];
-            console.log("color_range(value):", parseInt(color_range(value)));
-            this_color_dict[value] = d3.rgb(parseInt(color_range(value)), 0, 0);
+            this_color_dict[value] = color(i);
+          }
+        } else {
+          console.log("distinct_values:", distinct_vals);
+          if (_.every(distinct_vals, (function(_this) {
+            return function(d) {
+              if (isNaN(d)) {
+                return false;
+              } else {
+                return true;
+              }
+            };
+          })(this))) {
+            color_range = d3.scale.linear().domain([this.min_val, this.max_val]).range([0, 255]);
+            for (i = k = 0, len1 = distinct_vals.length; k < len1; i = ++k) {
+              value = distinct_vals[i];
+              console.log("color_range(value):", parseInt(color_range(value)));
+              this_color_dict[value] = d3.rgb(parseInt(color_range(value)), 0, 0);
+            }
           }
         }
+        this.attr_color_dict[key] = this_color_dict;
+        this.is_discrete[key] = discrete;
+        this.minimum_values[key] = this.min_val;
+        results.push(this.maximum_values[key] = this.max_val);
       }
-      _results.push(this.attr_color_dict[key] = this_color_dict);
-    }
-    return _results;
-  };
+      return results;
+    };
 
-  Bar_Chart.prototype.draw_legend = function() {
-    var svg_html;
-    $('#legend-left').html(this.min_val);
-    $('#legend-right').html(this.max_val);
-    svg_html = '<svg height="10" width="90"> <rect x="0" width="15" height="10" style="fill: rgb(0, 0, 0);"></rect> <rect x="15" width="15" height="10" style="fill: rgb(50, 0, 0);"></rect> <rect x="30" width="15" height="10" style="fill: rgb(100, 0, 0);"></rect> <rect x="45" width="15" height="10" style="fill: rgb(150, 0, 0);"></rect> <rect x="60" width="15" height="10" style="fill: rgb(200, 0, 0);"></rect> <rect x="75" width="15" height="10" style="fill: rgb(255, 0, 0);"></rect> </svg>';
-    console.log("svg_html:", svg_html);
-    return $('#legend-colors').html(svg_html);
-  };
+    Bar_Chart.prototype.draw_legend = function() {
+      var svg_html;
+      $('#legend-left').html(this.minimum_values[this.attribute]);
+      $('#legend-right').html(this.maximum_values[this.attribute]);
+      svg_html = '<svg height="15" width="120"> <rect x="0" width="20" height="15" style="fill: rgb(0, 0, 0);"></rect> <rect x="20" width="20" height="15" style="fill: rgb(50, 0, 0);"></rect> <rect x="40" width="20" height="15" style="fill: rgb(100, 0, 0);"></rect> <rect x="60" width="20" height="15" style="fill: rgb(150, 0, 0);"></rect> <rect x="80" width="20" height="15" style="fill: rgb(200, 0, 0);"></rect> <rect x="100" width="20" height="15" style="fill: rgb(255, 0, 0);"></rect> </svg>';
+      console.log("svg_html:", svg_html);
+      return $('#legend-colors').html(svg_html);
+    };
 
-  Bar_Chart.prototype.get_trait_color_dict = function(samples, vals) {
-    var color, color_range, distinct_vals, i, key, sample, this_color_dict, value, _i, _j, _len, _len1, _results;
-    this.trait_color_dict = {};
-    console.log("vals:", vals);
-    for (key in vals) {
-      if (!__hasProp.call(vals, key)) continue;
-      distinct_vals = vals[key];
-      this_color_dict = {};
-      this.min_val = d3.min(distinct_vals);
-      this.max_val = d3.max(distinct_vals);
-      if (distinct_vals.length < 10) {
-        color = d3.scale.category10();
-        for (i = _i = 0, _len = distinct_vals.length; _i < _len; i = ++_i) {
-          value = distinct_vals[i];
-          this_color_dict[value] = color(i);
-        }
-      } else {
-        console.log("distinct_values:", distinct_vals);
-        if (_.every(distinct_vals, (function(_this) {
-          return function(d) {
-            if (isNaN(d)) {
-              return false;
-            } else {
-              return true;
-            }
-          };
-        })(this))) {
-          color_range = d3.scale.linear().domain([d3.min(distinct_vals), d3.max(distinct_vals)]).range([0, 255]);
-          for (i = _j = 0, _len1 = distinct_vals.length; _j < _len1; i = ++_j) {
+    Bar_Chart.prototype.get_trait_color_dict = function(samples, vals) {
+      var color, color_range, distinct_vals, i, j, k, key, len, len1, results, sample, this_color_dict, value;
+      this.trait_color_dict = {};
+      console.log("vals:", vals);
+      for (key in vals) {
+        if (!hasProp.call(vals, key)) continue;
+        distinct_vals = vals[key];
+        this_color_dict = {};
+        this.min_val = d3.min(distinct_vals);
+        this.max_val = d3.max(distinct_vals);
+        if (distinct_vals.length < 10) {
+          color = d3.scale.category10();
+          for (i = j = 0, len = distinct_vals.length; j < len; i = ++j) {
             value = distinct_vals[i];
-            console.log("color_range(value):", parseInt(color_range(value)));
-            this_color_dict[value] = d3.rgb(parseInt(color_range(value)), 0, 0);
+            this_color_dict[value] = color(i);
+          }
+        } else {
+          console.log("distinct_values:", distinct_vals);
+          if (_.every(distinct_vals, (function(_this) {
+            return function(d) {
+              if (isNaN(d)) {
+                return false;
+              } else {
+                return true;
+              }
+            };
+          })(this))) {
+            color_range = d3.scale.linear().domain([d3.min(distinct_vals), d3.max(distinct_vals)]).range([0, 255]);
+            for (i = k = 0, len1 = distinct_vals.length; k < len1; i = ++k) {
+              value = distinct_vals[i];
+              console.log("color_range(value):", parseInt(color_range(value)));
+              this_color_dict[value] = d3.rgb(parseInt(color_range(value)), 0, 0);
+            }
           }
         }
       }
-    }
-    _results = [];
-    for (sample in samples) {
-      if (!__hasProp.call(samples, sample)) continue;
-      value = samples[sample];
-      _results.push(this.trait_color_dict[sample] = this_color_dict[value]);
-    }
-    return _results;
-  };
+      results = [];
+      for (sample in samples) {
+        if (!hasProp.call(samples, sample)) continue;
+        value = samples[sample];
+        results.push(this.trait_color_dict[sample] = this_color_dict[value]);
+      }
+      return results;
+    };
 
-  Bar_Chart.prototype.convert_into_colors = function(values) {
-    var color_range, i, value, _i, _len, _results;
-    color_range = d3.scale.linear().domain([d3.min(values), d3.max(values)]).range([0, 255]);
-    _results = [];
-    for (i = _i = 0, _len = values.length; _i < _len; i = ++_i) {
-      value = values[i];
-      console.log("color_range(value):", color_range(parseInt(value)));
-      _results.push(this_color_dict[value] = d3.rgb(color_range(parseInt(value)), 0, 0));
-    }
-    return _results;
-  };
+    Bar_Chart.prototype.convert_into_colors = function(values) {
+      var color_range, i, j, len, results, value;
+      color_range = d3.scale.linear().domain([d3.min(values), d3.max(values)]).range([0, 255]);
+      results = [];
+      for (i = j = 0, len = values.length; j < len; i = ++j) {
+        value = values[i];
+        console.log("color_range(value):", color_range(parseInt(value)));
+        results.push(this_color_dict[value] = d3.rgb(color_range(parseInt(value)), 0, 0));
+      }
+      return results;
+    };
 
-  Bar_Chart.prototype.get_samples = function() {
-    var attr_vals, attribute, key, sample, _i, _j, _len, _len1, _ref, _ref1;
-    this.sample_names = (function() {
-      var _i, _len, _ref, _results;
-      _ref = this.sample_list;
-      _results = [];
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        sample = _ref[_i];
-        if (sample.value !== null) {
-          _results.push(sample.name);
+    Bar_Chart.prototype.get_samples = function() {
+      var key, sample;
+      this.sample_names = (function() {
+        var j, len, ref, results;
+        ref = this.sample_list;
+        results = [];
+        for (j = 0, len = ref.length; j < len; j++) {
+          sample = ref[j];
+          if (sample.value !== null) {
+            results.push(sample.name);
+          }
         }
-      }
-      return _results;
-    }).call(this);
-    this.sample_vals = (function() {
-      var _i, _len, _ref, _results;
-      _ref = this.sample_list;
-      _results = [];
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        sample = _ref[_i];
-        if (sample.value !== null) {
-          _results.push(sample.value);
+        return results;
+      }).call(this);
+      this.sample_vals = (function() {
+        var j, len, ref, results;
+        ref = this.sample_list;
+        results = [];
+        for (j = 0, len = ref.length; j < len; j++) {
+          sample = ref[j];
+          if (sample.value !== null) {
+            results.push(sample.value);
+          }
         }
-      }
-      return _results;
-    }).call(this);
-    this.attributes = (function() {
-      var _results;
-      _results = [];
-      for (key in this.sample_list[0]["extra_attributes"]) {
-        _results.push(key);
-      }
-      return _results;
-    }).call(this);
-    console.log("attributes:", this.attributes);
-    this.sample_attr_vals = [];
-    if (this.attributes.length > 0) {
-      _ref = this.sample_list;
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        sample = _ref[_i];
-        attr_vals = {};
-        _ref1 = this.attributes;
-        for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
-          attribute = _ref1[_j];
-          attr_vals[attribute] = sample["extra_attributes"][attribute];
+        return results;
+      }).call(this);
+      this.attributes = (function() {
+        var results;
+        results = [];
+        for (key in this.sample_list[0]["extra_attributes"]) {
+          results.push(key);
         }
-        this.sample_attr_vals.push(attr_vals);
-      }
-    }
-    return this.samples = _.zip(this.sample_names, this.sample_vals, this.sample_attr_vals);
-  };
-
-  Bar_Chart.prototype.get_distinct_attr_vals = function() {
-    var attribute, sample, _i, _len, _ref, _results;
-    this.distinct_attr_vals = {};
-    _ref = this.sample_attr_vals;
-    _results = [];
-    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-      sample = _ref[_i];
-      _results.push((function() {
-        var _ref1, _results1;
-        _results1 = [];
-        for (attribute in sample) {
-          if (!this.distinct_attr_vals[attribute]) {
-            this.distinct_attr_vals[attribute] = [];
-          }
-          if (_ref1 = sample[attribute], __indexOf.call(this.distinct_attr_vals[attribute], _ref1) < 0) {
-            _results1.push(this.distinct_attr_vals[attribute].push(sample[attribute]));
-          } else {
-            _results1.push(void 0);
+        return results;
+      }).call(this);
+      console.log("attributes:", this.attributes);
+      this.sample_attr_vals = (function() {
+        var j, len, ref, results;
+        ref = this.sample_list;
+        results = [];
+        for (j = 0, len = ref.length; j < len; j++) {
+          sample = ref[j];
+          if (sample.value !== null) {
+            results.push(this.extra(sample));
           }
         }
-        return _results1;
-      }).call(this));
-    }
-    return _results;
-  };
-
-  Bar_Chart.prototype.create_svg = function() {
-    var svg;
-    svg = d3.select("#bar_chart").append("svg").attr("class", "bar_chart").attr("width", this.plot_width + this.margin.left + this.margin.right).attr("height", this.plot_height + this.margin.top + this.margin.bottom).append("g").attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")");
-    return svg;
-  };
-
-  Bar_Chart.prototype.create_scales = function() {
-    this.x_scale = d3.scale.ordinal().domain(this.sample_names).rangeRoundBands([0, this.range], 0.1, 0);
-    return this.y_scale = d3.scale.linear().domain([this.y_min * 0.75, this.y_max]).range([this.plot_height, this.y_buffer]);
-  };
-
-  Bar_Chart.prototype.create_graph = function() {
-    this.add_x_axis(this.x_scale);
-    this.add_y_axis();
-    return this.add_bars();
-  };
+        return results;
+      }).call(this);
+      return this.samples = _.zip(this.sample_names, this.sample_vals, this.sample_attr_vals);
+    };
 
-  Bar_Chart.prototype.add_x_axis = function(scale) {
-    var xAxis;
-    xAxis = d3.svg.axis().scale(scale).orient("bottom");
-    return this.svg.append("g").attr("class", "x axis").attr("transform", "translate(0," + this.plot_height + ")").call(xAxis).selectAll("text").style("text-anchor", "end").style("font-size", "12px").attr("dx", "-.8em").attr("dy", "-.3em").attr("transform", (function(_this) {
-      return function(d) {
-        return "rotate(-90)";
-      };
-    })(this));
-  };
+    Bar_Chart.prototype.get_distinct_attr_vals = function() {
+      var attribute, j, len, ref, results, sample;
+      this.distinct_attr_vals = {};
+      ref = this.sample_attr_vals;
+      results = [];
+      for (j = 0, len = ref.length; j < len; j++) {
+        sample = ref[j];
+        results.push((function() {
+          var ref1, results1;
+          results1 = [];
+          for (attribute in sample) {
+            if (!this.distinct_attr_vals[attribute]) {
+              this.distinct_attr_vals[attribute] = [];
+            }
+            if (ref1 = sample[attribute], indexOf.call(this.distinct_attr_vals[attribute], ref1) < 0) {
+              results1.push(this.distinct_attr_vals[attribute].push(sample[attribute]));
+            } else {
+              results1.push(void 0);
+            }
+          }
+          return results1;
+        }).call(this));
+      }
+      return results;
+    };
 
-  Bar_Chart.prototype.add_y_axis = function() {
-    var yAxis;
-    yAxis = d3.svg.axis().scale(this.y_scale).orient("left").ticks(5);
-    return this.svg.append("g").attr("class", "y axis").call(yAxis).append("text").attr("transform", "rotate(-90)").attr("y", 6).attr("dy", ".71em").style("text-anchor", "end");
-  };
+    Bar_Chart.prototype.create_svg = function() {
+      var svg;
+      svg = d3.select("#bar_chart").append("svg").attr("class", "bar_chart").attr("width", this.plot_width + this.margin.left + this.margin.right).attr("height", this.plot_height + this.margin.top + this.margin.bottom).append("g").attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")");
+      return svg;
+    };
 
-  Bar_Chart.prototype.add_bars = function() {
-    return this.svg.selectAll(".bar").data(this.samples).enter().append("rect").style("fill", "steelblue").attr("class", "bar").attr("x", (function(_this) {
-      return function(d) {
-        return _this.x_scale(d[0]);
-      };
-    })(this)).attr("width", this.x_scale.rangeBand()).attr("y", (function(_this) {
-      return function(d) {
-        return _this.y_scale(d[1]);
-      };
-    })(this)).attr("height", (function(_this) {
-      return function(d) {
-        return _this.plot_height - _this.y_scale(d[1]);
-      };
-    })(this)).append("svg:title").text((function(_this) {
-      return function(d) {
-        return d[1];
-      };
-    })(this));
-  };
+    Bar_Chart.prototype.create_scales = function(sample_names) {
+      this.x_scale = d3.scale.ordinal().domain(sample_names).rangeRoundBands([0, this.plot_width], 0.1, 0);
+      return this.y_scale = d3.scale.linear().domain([this.y_min * 0.75, this.y_max]).range([this.plot_height, this.y_buffer]);
+    };
 
-  Bar_Chart.prototype.sorted_samples = function() {
-    var sample_list, sorted;
-    sample_list = _.zip(this.sample_names, this.sample_vals, this.sample_attr_vals);
-    sorted = _.sortBy(sample_list, (function(_this) {
-      return function(sample) {
-        return sample[1];
-      };
-    })(this));
-    console.log("sorted:", sorted);
-    return sorted;
-  };
+    Bar_Chart.prototype.create_graph = function() {
+      this.add_x_axis();
+      this.add_y_axis();
+      return this.update_bars(this.samples);
+    };
 
-  Bar_Chart.prototype.add_legend = function(attribute, distinct_vals) {
-    var legend, legend_rect, legend_text;
-    legend = this.svg.append("g").attr("class", "legend").attr("height", 100).attr("width", 100).attr('transform', 'translate(-20,50)');
-    legend_rect = legend.selectAll('rect').data(distinct_vals).enter().append("rect").attr("x", this.plot_width - 65).attr("width", 10).attr("height", 10).attr("y", (function(_this) {
-      return function(d, i) {
-        return i * 20;
-      };
-    })(this)).style("fill", (function(_this) {
-      return function(d) {
-        console.log("TEST:", _this.attr_color_dict[attribute][d]);
-        return _this.attr_color_dict[attribute][d];
-      };
-    })(this));
-    return legend_text = legend.selectAll('text').data(distinct_vals).enter().append("text").attr("x", this.plot_width - 52).attr("y", (function(_this) {
-      return function(d, i) {
-        return i * 20 + 9;
-      };
-    })(this)).text((function(_this) {
-      return function(d) {
-        return d;
-      };
-    })(this));
-  };
+    Bar_Chart.prototype.add_x_axis = function(scale) {
+      var xAxis;
+      xAxis = d3.svg.axis().scale(this.x_scale).orient("bottom");
+      return this.svg.append("g").attr("class", "x axis").attr("transform", "translate(0," + this.plot_height + ")").call(xAxis).selectAll("text").style("text-anchor", "end").style("font-size", "12px").attr("dx", "-.8em").attr("dy", "-.3em").attr("transform", (function(_this) {
+        return function(d) {
+          return "rotate(-90)";
+        };
+      })(this));
+    };
 
-  Bar_Chart.prototype.open_trait_selection = function() {
-    return $('#collections_holder').load('/collections/list?color_by_trait #collections_list', (function(_this) {
-      return function() {
-        $.colorbox({
-          inline: true,
-          href: "#collections_holder"
-        });
-        return $('a.collection_name').attr('onClick', 'return false');
-      };
-    })(this));
-  };
+    Bar_Chart.prototype.add_y_axis = function() {
+      var yAxis;
+      yAxis = d3.svg.axis().scale(this.y_scale).orient("left").ticks(5);
+      return this.svg.append("g").attr("class", "y axis").call(yAxis).append("text").attr("transform", "rotate(-90)").attr("y", 6).attr("dy", ".71em").style("text-anchor", "end");
+    };
 
-  Bar_Chart.prototype.color_by_trait = function(trait_sample_data) {
-    var distinct_values, trimmed_samples;
-    console.log("BXD1:", trait_sample_data["BXD1"]);
-    console.log("trait_sample_data:", trait_sample_data);
-    trimmed_samples = this.trim_values(trait_sample_data);
-    distinct_values = {};
-    distinct_values["collection_trait"] = this.get_distinct_values(trimmed_samples);
-    this.get_trait_color_dict(trimmed_samples, distinct_values);
-    console.log("TRAIT_COLOR_DICT:", this.trait_color_dict);
-    console.log("SAMPLES:", this.samples);
-    if (this.sort_by = "value") {
-      this.svg.selectAll(".bar").data(this.samples).transition().duration(1000).style("fill", (function(_this) {
+    Bar_Chart.prototype.update_bars = function(samples) {
+      var bars;
+      bars = this.svg.selectAll(".bar").data(samples, (function(_this) {
         return function(d) {
-          console.log("this color:", _this.trait_color_dict[d[0]]);
-          return _this.trait_color_dict[d[0]];
+          return d[0];
         };
-      })(this)).select("title").text((function(_this) {
+      })(this));
+      bars.enter().append("rect").style("fill", "steelblue").attr("class", "bar").attr("x", (function(_this) {
+        return function(d) {
+          return _this.x_scale(d[0]);
+        };
+      })(this)).attr("width", this.x_scale.rangeBand()).attr("y", (function(_this) {
+        return function(d) {
+          return _this.y_scale(d[1]);
+        };
+      })(this)).attr("height", (function(_this) {
+        return function(d) {
+          return _this.plot_height - _this.y_scale(d[1]);
+        };
+      })(this)).append("svg:title").text((function(_this) {
         return function(d) {
           return d[1];
         };
       })(this));
-      return this.draw_legend();
-    } else {
-      this.svg.selectAll(".bar").data(this.sorted_samples()).transition().duration(1000).style("fill", (function(_this) {
+      bars.exit().remove();
+      return bars;
+    };
+
+    Bar_Chart.prototype.sorted_samples = function() {
+      var sample_list, sorted;
+      sample_list = _.zip(this.sample_names, this.sample_vals, this.sample_attr_vals);
+      sorted = _.sortBy(sample_list, (function(_this) {
+        return function(sample) {
+          return sample[1];
+        };
+      })(this));
+      console.log("sorted:", sorted);
+      return sorted;
+    };
+
+    Bar_Chart.prototype.add_legend = function(attribute, distinct_vals) {
+      var legend_span;
+      legend_span = d3.select('#bar_chart_legend').append('div').style('word-wrap', 'break-word').attr('class', 'legend').selectAll('span').data(distinct_vals).enter().append('span').style({
+        'word-wrap': 'normal',
+        'display': 'inline-block'
+      });
+      legend_span.append('span').style("background-color", (function(_this) {
         return function(d) {
-          console.log("this color:", _this.trait_color_dict[d[0]]);
-          return _this.trait_color_dict[d[0]];
+          return _this.attr_color_dict[attribute][d];
         };
-      })(this)).select("title").text((function(_this) {
+      })(this)).style({
+        'display': 'inline-block',
+        'width': '15px',
+        'height': '15px',
+        'margin': '0px 5px 0px 15px'
+      });
+      return legend_span.append('span').text((function(_this) {
         return function(d) {
-          return d[1];
+          return d;
+        };
+      })(this)).style('font-size', '20px');
+    };
+
+    Bar_Chart.prototype.open_trait_selection = function() {
+      return $('#collections_holder').load('/collections/list?color_by_trait #collections_list', (function(_this) {
+        return function() {
+          $.colorbox({
+            inline: true,
+            href: "#collections_holder"
+          });
+          return $('a.collection_name').attr('onClick', 'return false');
         };
       })(this));
-      return this.draw_legend();
-    }
-  };
+    };
 
-  Bar_Chart.prototype.trim_values = function(trait_sample_data) {
-    var sample, trimmed_samples, _i, _len, _ref;
-    trimmed_samples = {};
-    _ref = this.sample_names;
-    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-      sample = _ref[_i];
-      if (sample in trait_sample_data) {
-        trimmed_samples[sample] = trait_sample_data[sample];
+    Bar_Chart.prototype.color_by_trait = function(trait_sample_data) {
+      var distinct_values, trimmed_samples;
+      console.log("BXD1:", trait_sample_data["BXD1"]);
+      console.log("trait_sample_data:", trait_sample_data);
+      trimmed_samples = this.trim_values(trait_sample_data);
+      distinct_values = {};
+      distinct_values["collection_trait"] = this.get_distinct_values(trimmed_samples);
+      this.get_trait_color_dict(trimmed_samples, distinct_values);
+      console.log("TRAIT_COLOR_DICT:", this.trait_color_dict);
+      console.log("SAMPLES:", this.samples);
+      if (this.sort_by = "value") {
+        this.svg.selectAll(".bar").data(this.samples).transition().duration(1000).style("fill", (function(_this) {
+          return function(d) {
+            console.log("this color:", _this.trait_color_dict[d[0]]);
+            return _this.trait_color_dict[d[0]];
+          };
+        })(this)).select("title").text((function(_this) {
+          return function(d) {
+            return d[1];
+          };
+        })(this));
+        return this.draw_legend();
+      } else {
+        this.svg.selectAll(".bar").data(this.sorted_samples()).transition().duration(1000).style("fill", (function(_this) {
+          return function(d) {
+            console.log("this color:", _this.trait_color_dict[d[0]]);
+            return _this.trait_color_dict[d[0]];
+          };
+        })(this)).select("title").text((function(_this) {
+          return function(d) {
+            return d[1];
+          };
+        })(this));
+        return this.draw_legend();
       }
-    }
-    console.log("trimmed_samples:", trimmed_samples);
-    return trimmed_samples;
-  };
+    };
+
+    Bar_Chart.prototype.trim_values = function(trait_sample_data) {
+      var j, len, ref, sample, trimmed_samples;
+      trimmed_samples = {};
+      ref = this.sample_names;
+      for (j = 0, len = ref.length; j < len; j++) {
+        sample = ref[j];
+        if (sample in trait_sample_data) {
+          trimmed_samples[sample] = trait_sample_data[sample];
+        }
+      }
+      console.log("trimmed_samples:", trimmed_samples);
+      return trimmed_samples;
+    };
+
+    Bar_Chart.prototype.get_distinct_values = function(samples) {
+      var distinct_values;
+      distinct_values = _.uniq(_.values(samples));
+      console.log("distinct_values:", distinct_values);
+      return distinct_values;
+    };
 
-  Bar_Chart.prototype.get_distinct_values = function(samples) {
-    var distinct_values;
-    distinct_values = _.uniq(_.values(samples));
-    console.log("distinct_values:", distinct_values);
-    return distinct_values;
-  };
+    return Bar_Chart;
 
-  return Bar_Chart;
+  })();
 
-})();
+  root.Bar_Chart = Bar_Chart;
 
-root.Bar_Chart = Bar_Chart;
+}).call(this);
diff --git a/wqflask/wqflask/static/new/javascript/show_trait.coffee b/wqflask/wqflask/static/new/javascript/show_trait.coffee
index 1d3123ba..d548b253 100755
--- a/wqflask/wqflask/static/new/javascript/show_trait.coffee
+++ b/wqflask/wqflask/static/new/javascript/show_trait.coffee
@@ -64,36 +64,6 @@ $ ->
     sample_lists = js_data.sample_lists
     sample_group_types = js_data.sample_group_types
 
-    #if $("#update_bar_chart").length
-    #    $("#update_bar_chart.btn-group").button()
-    root.bar_chart = new Bar_Chart(sample_lists[0])
-    root.histogram = new Histogram(sample_lists[0])
-    new Box_Plot(sample_lists[0])
-
-    $('.bar_chart_samples_group').change ->
-        $('#bar_chart').remove()
-        $('#bar_chart_container').append('<div id="bar_chart"></div>')
-        group = $(this).val()
-        if group == "samples_primary"
-            root.bar_chart = new Bar_Chart(sample_lists[0])
-        else if group == "samples_other"
-            root.bar_chart = new Bar_Chart(sample_lists[1])
-        else if group == "samples_all"
-            all_samples = sample_lists[0].concat sample_lists[1]
-            root.bar_chart = new Bar_Chart(all_samples)
-
-    $('.box_plot_samples_group').change ->
-        $('#box_plot').remove()
-        $('#box_plot_container').append('<div id="box_plot"></div>')
-        group = $(this).val()
-        if group == "samples_primary"
-            new Box_Plot(sample_lists[0])
-        else if group == "samples_other"
-            new Box_Plot(sample_lists[1])
-        else if group == "samples_all"
-            all_samples = sample_lists[0].concat sample_lists[1]
-            new Box_Plot(all_samples)
-
     d3.select("#select_compare_trait").on("click", =>
         $('.scatter-matrix-container').remove()
         open_trait_selection()
@@ -126,7 +96,7 @@ $ ->
         $("#stats_tabs" + selected).show()
 
 
-    change_stats_value = (sample_sets, category, value_type, decimal_places)->
+    change_stats_value = (sample_sets, category, value_type, decimal_places, effects) ->
         id = "#" + process_id(category, value_type)
         console.log("the_id:", id)
         in_box = $(id).html
@@ -145,7 +115,10 @@ $ ->
         console.log("*-* current_value:", current_value)
         if the_value != current_value
             console.log("object:", $(id).html(the_value))
-            $(id).html(the_value).effect("highlight")
+            if effects
+                $(id).html(the_value).effect("highlight")
+            else
+                $(id).html(the_value)
 
         # We go ahead and always change the title value if we have it
         if title_value
@@ -153,11 +126,17 @@ $ ->
 
 
     update_stat_values = (sample_sets)->
+        show_effects = $(".tab-pane.active").attr("id") == "stats_tab"
         for category in ['samples_primary', 'samples_other', 'samples_all']
             for row in Stat_Table_Rows
                 console.log("Calling change_stats_value")
-                change_stats_value(sample_sets, category, row.vn, row.digits)
+                change_stats_value(sample_sets, category, row.vn, row.digits, show_effects)
+
+    redraw_histogram = ->
+        root.histogram.redraw(_.values(root.selected_samples[root.histogram_group]))
 
+    redraw_bar_chart = ->
+        root.bar_chart.redraw(root.selected_samples[root.bar_chart_group])
 
     make_table = ->
         header = "<thead><tr><th>&nbsp;</th>"
@@ -213,6 +192,11 @@ $ ->
             samples_other: new Stats([])
             samples_all: new Stats([])
 
+        root.selected_samples = # maps: sample name -> value
+            samples_primary: {}
+            samples_other: {}
+            samples_all: {}
+
         console.log("at beginning:", sample_sets)
 
         tables = ['samples_primary', 'samples_other']
@@ -222,25 +206,32 @@ $ ->
                 name = $(row).find('.edit_sample_sample_name').html()
                 name = $.trim(name)
                 real_value = $(row).find('.edit_sample_value').val()
-                console.log("real_value:", real_value)
+                #console.log("real_value:", real_value)
                 
                 checkbox = $(row).find(".edit_sample_checkbox")
-                checked = $(checkbox).attr('checked')
+                checked = $(checkbox).prop('checked')
 
                 if checked and is_number(real_value) and real_value != ""
-                    console.log("in the iffy if")
+                    #console.log("in the iffy if")
                     real_value = parseFloat(real_value)
 
                     sample_sets[table].add_value(real_value)
-                    console.log("checking name of:", name)
+                    root.selected_samples[table][name] = real_value
+                    #console.log("checking name of:", name)
                     if not (name of already_seen)
-                        console.log("haven't seen")
+                        #console.log("haven't seen")
                         sample_sets['samples_all'].add_value(real_value)
+                        root.selected_samples['samples_all'][name] = real_value
                         already_seen[name] = true
         console.log("towards end:", sample_sets)
-        root.histogram.redraw(sample_sets['samples_primary'].the_values)
         update_stat_values(sample_sets)
 
+        console.log("redrawing histogram")
+        redraw_histogram()
+
+        console.log("redrawing bar chart")
+        redraw_bar_chart()
+
     show_hide_outliers = ->
         console.log("FOOBAR in beginning of show_hide_outliers")
         label = $('#show_hide_outliers').val()
@@ -427,11 +418,43 @@ $ ->
     console.log("after registering block_outliers")
 
     _.mixin(_.str.exports());  # Add string fuctions directly to underscore
-    $('#edit_sample_lists').change(edit_data_change)
-    console.log("loaded")
-    #console.log("basic_table is:", basic_table)
-    # Add back following two lines later
+
+    root.histogram_group = 'samples_primary'
+    root.histogram = new Histogram(sample_lists[0])
+    $('.histogram_samples_group').change ->
+        root.histogram_group = $(this).val()
+        redraw_histogram()
+
+    root.bar_chart_group = 'samples_primary'
+    root.bar_chart = new Bar_Chart(sample_lists[0])
+    $('.bar_chart_samples_group').change ->
+        root.bar_chart_group = $(this).val()
+        redraw_bar_chart()
+
+    new Box_Plot(sample_lists[0])
+        
+    $('.box_plot_samples_group').change ->
+        $('#box_plot').remove()
+        $('#box_plot_container').append('<div id="box_plot"></div>')
+        group = $(this).val()
+        if group == "samples_primary"
+            new Box_Plot(sample_lists[0])
+        else if group == "samples_other"
+            new Box_Plot(sample_lists[1])
+        else if group == "samples_all"
+            all_samples = sample_lists[0].concat sample_lists[1]
+            new Box_Plot(all_samples)
+
     make_table()
     edit_data_change()   # Set the values at the beginning
+
+    $('#edit_sample_lists').change(edit_data_change)
+
+    # bind additional handlers for pushing data updates
+    $('#block_by_index').click(edit_data_change)
+    $('#exclude_group').click(edit_data_change)
+    $('#block_outliers').click(edit_data_change)
+    $('#reset').click(edit_data_change)
+
     #$("#all-mean").html('foobar8')
     console.log("end")
diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js
index 9323862a..d1b43677 100755
--- a/wqflask/wqflask/static/new/javascript/show_trait.js
+++ b/wqflask/wqflask/static/new/javascript/show_trait.js
@@ -56,40 +56,9 @@
   ];
 
   $(function() {
-    var block_by_attribute_value, block_by_index, block_outliers, change_stats_value, create_value_dropdown, edit_data_change, export_sample_table_data, get_sample_table_data, hide_no_value, hide_tabs, make_table, on_corr_method_change, open_trait_selection, populate_sample_attributes_values_dropdown, process_id, reset_samples_table, sample_group_types, sample_lists, show_hide_outliers, stats_mdp_change, update_stat_values;
+    var block_by_attribute_value, block_by_index, block_outliers, change_stats_value, create_value_dropdown, edit_data_change, export_sample_table_data, get_sample_table_data, hide_no_value, hide_tabs, make_table, on_corr_method_change, open_trait_selection, populate_sample_attributes_values_dropdown, process_id, redraw_bar_chart, redraw_histogram, reset_samples_table, sample_group_types, sample_lists, show_hide_outliers, stats_mdp_change, update_stat_values;
     sample_lists = js_data.sample_lists;
     sample_group_types = js_data.sample_group_types;
-    root.bar_chart = new Bar_Chart(sample_lists[0]);
-    root.histogram = new Histogram(sample_lists[0]);
-    new Box_Plot(sample_lists[0]);
-    $('.bar_chart_samples_group').change(function() {
-      var all_samples, group;
-      $('#bar_chart').remove();
-      $('#bar_chart_container').append('<div id="bar_chart"></div>');
-      group = $(this).val();
-      if (group === "samples_primary") {
-        return root.bar_chart = new Bar_Chart(sample_lists[0]);
-      } else if (group === "samples_other") {
-        return root.bar_chart = new Bar_Chart(sample_lists[1]);
-      } else if (group === "samples_all") {
-        all_samples = sample_lists[0].concat(sample_lists[1]);
-        return root.bar_chart = new Bar_Chart(all_samples);
-      }
-    });
-    $('.box_plot_samples_group').change(function() {
-      var all_samples, group;
-      $('#box_plot').remove();
-      $('#box_plot_container').append('<div id="box_plot"></div>');
-      group = $(this).val();
-      if (group === "samples_primary") {
-        return new Box_Plot(sample_lists[0]);
-      } else if (group === "samples_other") {
-        return new Box_Plot(sample_lists[1]);
-      } else if (group === "samples_all") {
-        all_samples = sample_lists[0].concat(sample_lists[1]);
-        return new Box_Plot(all_samples);
-      }
-    });
     d3.select("#select_compare_trait").on("click", (function(_this) {
       return function() {
         $('.scatter-matrix-container').remove();
@@ -126,7 +95,7 @@
       hide_tabs(0);
       return $("#stats_tabs" + selected).show();
     };
-    change_stats_value = function(sample_sets, category, value_type, decimal_places) {
+    change_stats_value = function(sample_sets, category, value_type, decimal_places, effects) {
       var current_value, id, in_box, the_value, title_value;
       id = "#" + process_id(category, value_type);
       console.log("the_id:", id);
@@ -144,14 +113,19 @@
       console.log("*-* current_value:", current_value);
       if (the_value !== current_value) {
         console.log("object:", $(id).html(the_value));
-        $(id).html(the_value).effect("highlight");
+        if (effects) {
+          $(id).html(the_value).effect("highlight");
+        } else {
+          $(id).html(the_value);
+        }
       }
       if (title_value) {
         return $(id).attr('title', title_value);
       }
     };
     update_stat_values = function(sample_sets) {
-      var category, i, len, ref, results, row;
+      var category, i, len, ref, results, row, show_effects;
+      show_effects = $(".tab-pane.active").attr("id") === "stats_tab";
       ref = ['samples_primary', 'samples_other', 'samples_all'];
       results = [];
       for (i = 0, len = ref.length; i < len; i++) {
@@ -162,13 +136,19 @@
           for (j = 0, len1 = Stat_Table_Rows.length; j < len1; j++) {
             row = Stat_Table_Rows[j];
             console.log("Calling change_stats_value");
-            results1.push(change_stats_value(sample_sets, category, row.vn, row.digits));
+            results1.push(change_stats_value(sample_sets, category, row.vn, row.digits, show_effects));
           }
           return results1;
         })());
       }
       return results;
     };
+    redraw_histogram = function() {
+      return root.histogram.redraw(_.values(root.selected_samples[root.histogram_group]));
+    };
+    redraw_bar_chart = function() {
+      return root.bar_chart.redraw(root.selected_samples[root.bar_chart_group]);
+    };
     make_table = function() {
       var header, i, key, len, ref, ref1, row, row_line, table, the_id, the_rows, value;
       header = "<thead><tr><th>&nbsp;</th>";
@@ -238,6 +218,11 @@
         samples_other: new Stats([]),
         samples_all: new Stats([])
       };
+      root.selected_samples = {
+        samples_primary: {},
+        samples_other: {},
+        samples_all: {}
+      };
       console.log("at beginning:", sample_sets);
       tables = ['samples_primary', 'samples_other'];
       for (i = 0, len = tables.length; i < len; i++) {
@@ -248,25 +233,26 @@
           name = $(row).find('.edit_sample_sample_name').html();
           name = $.trim(name);
           real_value = $(row).find('.edit_sample_value').val();
-          console.log("real_value:", real_value);
           checkbox = $(row).find(".edit_sample_checkbox");
-          checked = $(checkbox).attr('checked');
+          checked = $(checkbox).prop('checked');
           if (checked && is_number(real_value) && real_value !== "") {
-            console.log("in the iffy if");
             real_value = parseFloat(real_value);
             sample_sets[table].add_value(real_value);
-            console.log("checking name of:", name);
+            root.selected_samples[table][name] = real_value;
             if (!(name in already_seen)) {
-              console.log("haven't seen");
               sample_sets['samples_all'].add_value(real_value);
+              root.selected_samples['samples_all'][name] = real_value;
               already_seen[name] = true;
             }
           }
         }
       }
       console.log("towards end:", sample_sets);
-      root.histogram.redraw(sample_sets['samples_primary'].the_values);
-      return update_stat_values(sample_sets);
+      update_stat_values(sample_sets);
+      console.log("redrawing histogram");
+      redraw_histogram();
+      console.log("redrawing bar chart");
+      return redraw_bar_chart();
     };
     show_hide_outliers = function() {
       var label;
@@ -460,10 +446,40 @@
     $('#block_outliers').click(block_outliers);
     console.log("after registering block_outliers");
     _.mixin(_.str.exports());
-    $('#edit_sample_lists').change(edit_data_change);
-    console.log("loaded");
+    root.histogram_group = 'samples_primary';
+    root.histogram = new Histogram(sample_lists[0]);
+    $('.histogram_samples_group').change(function() {
+      root.histogram_group = $(this).val();
+      return redraw_histogram();
+    });
+    root.bar_chart_group = 'samples_primary';
+    root.bar_chart = new Bar_Chart(sample_lists[0]);
+    $('.bar_chart_samples_group').change(function() {
+      root.bar_chart_group = $(this).val();
+      return redraw_bar_chart();
+    });
+    new Box_Plot(sample_lists[0]);
+    $('.box_plot_samples_group').change(function() {
+      var all_samples, group;
+      $('#box_plot').remove();
+      $('#box_plot_container').append('<div id="box_plot"></div>');
+      group = $(this).val();
+      if (group === "samples_primary") {
+        return new Box_Plot(sample_lists[0]);
+      } else if (group === "samples_other") {
+        return new Box_Plot(sample_lists[1]);
+      } else if (group === "samples_all") {
+        all_samples = sample_lists[0].concat(sample_lists[1]);
+        return new Box_Plot(all_samples);
+      }
+    });
     make_table();
     edit_data_change();
+    $('#edit_sample_lists').change(edit_data_change);
+    $('#block_by_index').click(edit_data_change);
+    $('#exclude_group').click(edit_data_change);
+    $('#block_outliers').click(edit_data_change);
+    $('#reset').click(edit_data_change);
     return console.log("end");
   });
 
diff --git a/wqflask/wqflask/templates/show_trait_statistics_new.html b/wqflask/wqflask/templates/show_trait_statistics_new.html
index f2ebbbef..54bd79f2 100755
--- a/wqflask/wqflask/templates/show_trait_statistics_new.html
+++ b/wqflask/wqflask/templates/show_trait_statistics_new.html
@@ -80,20 +80,9 @@
                         </div>
                     </div>
                         <div class="row" style="height: 0px">
-                          <div id="bar_chart_legend" style="margin-left: 900px; margin-top:50px; positive: relative;">
+                          <div id="bar_chart_legend" style="margin-left: 150px; margin-top:50px; positive: relative;">
                             <span id="legend-left"></span>
-                            <span id="legend-colors">
-                            <!--
-                              <svg height="10" width="90">
-                                <rect x="0" width="15" height="10" style="fill: rgb(0, 0, 0);"></rect>
-                                <rect x="15" width="15" height="10" style="fill: rgb(50, 0, 0);"></rect>
-                                <rect x="30" width="15" height="10" style="fill: rgb(100, 0, 0);"></rect>
-                                <rect x="45" width="15" height="10" style="fill: rgb(150, 0, 0);"></rect>
-                                <rect x="60" width="15" height="10" style="fill: rgb(200, 0, 0);"></rect>
-                                <rect x="75" width="15" height="10" style="fill: rgb(255, 0, 0);"></rect>
-                              </svg>
-                            -->
-                            </span>
+                            <span id="legend-colors"></span>
                             <span id="legend-right"></span>
                           </div>
                         </div>
@@ -140,4 +129,4 @@
         <div id="collections_holder"></div>
     </div>
    
-</div>
\ No newline at end of file
+</div>