aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xwqflask/base/data_set.py4
-rwxr-xr-xwqflask/cfg/default_settings.py2
-rwxr-xr-xwqflask/wqflask/search_results.py5
-rw-r--r--wqflask/wqflask/static/new/css/show_trait.css8
-rwxr-xr-xwqflask/wqflask/static/new/javascript/bar_chart.coffee34
-rwxr-xr-xwqflask/wqflask/static/new/javascript/bar_chart.js22
-rwxr-xr-xwqflask/wqflask/static/new/javascript/get_traits_from_collection.coffee44
-rwxr-xr-xwqflask/wqflask/static/new/javascript/get_traits_from_collection.js50
-rw-r--r--wqflask/wqflask/static/new/javascript/scatter-matrix.js549
-rwxr-xr-xwqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee119
-rwxr-xr-xwqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js13
-rwxr-xr-xwqflask/wqflask/static/packages/bootstrap/css/bootstrap.css71
-rwxr-xr-xwqflask/wqflask/templates/collections/view.html15
-rwxr-xr-xwqflask/wqflask/templates/index_page.html10
-rwxr-xr-xwqflask/wqflask/templates/interval_mapping.html234
-rwxr-xr-xwqflask/wqflask/templates/new_security/login_user.html23
-rwxr-xr-xwqflask/wqflask/templates/search_result_page.html24
-rwxr-xr-xwqflask/wqflask/templates/show_trait.html20
-rwxr-xr-xwqflask/wqflask/templates/show_trait_mapping_tools.html55
-rwxr-xr-xwqflask/wqflask/templates/show_trait_statistics_new.html22
20 files changed, 979 insertions, 345 deletions
diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py
index 15a8c7cc..8965e1d1 100755
--- a/wqflask/base/data_set.py
+++ b/wqflask/base/data_set.py
@@ -640,7 +640,7 @@ class PhenotypeDataSet(DataSet):
'Year',
'Max LRS',
'Max LRS Location',
- 'Add. Effect']
+ 'Add. Effect<a href="http://genenetwork.org//glossary.html#A" target="_blank"><sup style="color:#f00"> ?</sup></a>']
self.type = 'Publish'
@@ -901,7 +901,7 @@ class MrnaAssayDataSet(DataSet):
'Mean Expr',
'Max LRS',
'Max LRS Location',
- 'Add. Effect']
+ 'Add. Effect<a href="http://genenetwork.org//glossary.html#A" target="_blank"><sup style="color:#f00"> ?</sup></a>']
# Todo: Obsolete or rename this field
self.type = 'ProbeSet'
diff --git a/wqflask/cfg/default_settings.py b/wqflask/cfg/default_settings.py
index 8fca3d77..8b5d1313 100755
--- a/wqflask/cfg/default_settings.py
+++ b/wqflask/cfg/default_settings.py
@@ -13,3 +13,5 @@ SECURITY_RECOVERABLE = True
SECURITY_EMAIL_SENDER = "no-reply@genenetwork.org"
SECURITY_POST_LOGIN_VIEW = "/thank_you"
+
+SQLALCHEMY_POOL_RECYCLE = 3600 \ No newline at end of file
diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py
index 5444d1bc..9d2d0b88 100755
--- a/wqflask/wqflask/search_results.py
+++ b/wqflask/wqflask/search_results.py
@@ -233,11 +233,6 @@ class SearchResultPage(object):
print("search_type is:", pf(search_type))
- # This is throwing an error when a_search['key'] is None, so I changed above
- #search_type = string.upper(a_search['key'])
- #if not search_type:
- # search_type = self.dataset.type
-
search_ob = do_search.DoSearch.get_search(search_type)
search_class = getattr(do_search, search_ob)
print("search_class is: ", pf(search_class))
diff --git a/wqflask/wqflask/static/new/css/show_trait.css b/wqflask/wqflask/static/new/css/show_trait.css
index 9dcbfce9..9fc82a85 100644
--- a/wqflask/wqflask/static/new/css/show_trait.css
+++ b/wqflask/wqflask/static/new/css/show_trait.css
@@ -1,3 +1,7 @@
-tr .outlier {
- background-color: #ffff99;
+tr .outlier {
+ background-color: #ffff99;
+}
+
+#bar_chart_container {
+ overflow-x:scroll;
} \ No newline at end of file
diff --git a/wqflask/wqflask/static/new/javascript/bar_chart.coffee b/wqflask/wqflask/static/new/javascript/bar_chart.coffee
index a48718de..c83de64e 100755
--- a/wqflask/wqflask/static/new/javascript/bar_chart.coffee
+++ b/wqflask/wqflask/static/new/javascript/bar_chart.coffee
@@ -28,7 +28,7 @@ class Bar_Chart
@plot_height -= @y_buffer
@create_scales()
@create_graph()
-
+
d3.select("#color_attribute").on("change", =>
@attribute = $("#color_attribute").val()
console.log("attr_color_dict:", @attr_color_dict)
@@ -59,6 +59,7 @@ class Bar_Chart
else
return @attr_color_dict[@attribute][d[2][@attribute]]
)
+ @draw_legend()
@add_legend(@attribute, @distinct_attr_vals[@attribute])
)
@@ -181,6 +182,8 @@ class Bar_Chart
@attr_color_dict = {}
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
color = d3.scale.category10()
@@ -197,8 +200,8 @@ class Bar_Chart
return true
)
color_range = d3.scale.linear()
- .domain([d3.min(distinct_vals),
- d3.max(distinct_vals)])
+ .domain([min_val,
+ max_val])
.range([0,255])
for value, i in distinct_vals
console.log("color_range(value):", parseInt(color_range(value)))
@@ -206,12 +209,30 @@ 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
+
+
+
+ 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> \
+ </svg>'
+ console.log("svg_html:", svg_html)
+ $('#legend-colors').html(svg_html)
get_trait_color_dict: (samples, vals) ->
@trait_color_dict = {}
console.log("vals:", vals)
for own key, distinct_vals of vals
this_color_dict = {}
+ @min_val = d3.min(distinct_vals)
+ @max_val = d3.max(distinct_vals)
if distinct_vals.length < 10
color = d3.scale.category10()
for value, i in distinct_vals
@@ -434,8 +455,8 @@ class Bar_Chart
.select("title")
.text((d) =>
return d[1]
- )
-
+ )
+ @draw_legend()
else
@svg.selectAll(".bar")
.data(@sorted_samples())
@@ -448,7 +469,8 @@ class Bar_Chart
.select("title")
.text((d) =>
return d[1]
- )
+ )
+ @draw_legend()
trim_values: (trait_sample_data) ->
trimmed_samples = {}
diff --git a/wqflask/wqflask/static/new/javascript/bar_chart.js b/wqflask/wqflask/static/new/javascript/bar_chart.js
index 07761ba7..f5ed544b 100755
--- a/wqflask/wqflask/static/new/javascript/bar_chart.js
+++ b/wqflask/wqflask/static/new/javascript/bar_chart.js
@@ -66,6 +66,7 @@ Bar_Chart = (function() {
}
});
}
+ _this.draw_legend();
return _this.add_legend(_this.attribute, _this.distinct_attr_vals[_this.attribute]);
};
})(this));
@@ -150,6 +151,8 @@ Bar_Chart = (function() {
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();
@@ -168,7 +171,7 @@ Bar_Chart = (function() {
}
};
})(this))) {
- color_range = d3.scale.linear().domain([d3.min(distinct_vals), d3.max(distinct_vals)]).range([0, 255]);
+ 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) {
value = distinct_vals[i];
console.log("color_range(value):", parseInt(color_range(value)));
@@ -181,6 +184,15 @@ Bar_Chart = (function() {
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.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 = {};
@@ -189,6 +201,8 @@ Bar_Chart = (function() {
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) {
@@ -426,7 +440,7 @@ Bar_Chart = (function() {
console.log("TRAIT_COLOR_DICT:", this.trait_color_dict);
console.log("SAMPLES:", this.samples);
if (this.sort_by = "value") {
- return this.svg.selectAll(".bar").data(this.samples).transition().duration(1000).style("fill", (function(_this) {
+ 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]];
@@ -436,8 +450,9 @@ Bar_Chart = (function() {
return d[1];
};
})(this));
+ return this.draw_legend();
} else {
- return this.svg.selectAll(".bar").data(this.sorted_samples()).transition().duration(1000).style("fill", (function(_this) {
+ 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]];
@@ -447,6 +462,7 @@ Bar_Chart = (function() {
return d[1];
};
})(this));
+ return this.draw_legend();
}
};
diff --git a/wqflask/wqflask/static/new/javascript/get_traits_from_collection.coffee b/wqflask/wqflask/static/new/javascript/get_traits_from_collection.coffee
index ff7c041c..07be824f 100755
--- a/wqflask/wqflask/static/new/javascript/get_traits_from_collection.coffee
+++ b/wqflask/wqflask/static/new/javascript/get_traits_from_collection.coffee
@@ -57,10 +57,52 @@ submit_click = () ->
this_trait_vals.push(null)
all_vals.push(this_trait_vals)
- create_scatterplots(trait_names, samples, all_vals)
+ trait_vals_csv = create_trait_data_csv(selected_traits)
+ scatter_matrix = new ScatterMatrix(trait_vals_csv)
+ scatter_matrix.render()
+
+
+ #create_scatterplots(trait_names, samples, all_vals)
$.colorbox.close()
+create_trait_data_csv = (selected_traits) ->
+ trait_names = []
+ trait_names.push($('input[name=trait_id]').val())
+ samples = $('input[name=allsamples]').val().split(" ")
+ all_vals = []
+ this_trait_vals = get_this_trait_vals(samples)
+ all_vals.push(this_trait_vals)
+
+ for trait in Object.keys(selected_traits)
+ trait_names.push(trait)
+
+ this_trait_vals = []
+ for sample in samples
+ if sample in Object.keys(selected_traits[trait])
+ this_trait_vals.push(parseFloat(selected_traits[trait][sample]))
+ else
+ this_trait_vals.push(null)
+ all_vals.push(this_trait_vals)
+
+ console.log("all_vals:", all_vals)
+
+ trait_vals_csv = trait_names.join(",")
+ trait_vals_csv += "\n"
+
+ for sample, index in samples
+ if all_vals[0][index] == null
+ continue
+ sample_vals = []
+ for trait in all_vals
+ sample_vals.push(trait[index])
+ trait_vals_csv += sample_vals.join(",")
+ trait_vals_csv += "\n"
+
+ #console.log("trait_vals_csv:", trait_vals_csv)
+
+ return trait_vals_csv
+
trait_click = () ->
console.log("Clicking on:", $(this))
trait = $(this).parent().find('.trait').text()
diff --git a/wqflask/wqflask/static/new/javascript/get_traits_from_collection.js b/wqflask/wqflask/static/new/javascript/get_traits_from_collection.js
index af3f5135..a73eafe4 100755
--- a/wqflask/wqflask/static/new/javascript/get_traits_from_collection.js
+++ b/wqflask/wqflask/static/new/javascript/get_traits_from_collection.js
@@ -1,5 +1,5 @@
// Generated by CoffeeScript 1.8.0
-var add_trait_data, assemble_into_json, back_to_collections, collection_click, collection_list, color_by_trait, get_this_trait_vals, get_trait_data, process_traits, selected_traits, submit_click, this_trait_data, trait_click,
+var add_trait_data, assemble_into_json, back_to_collections, collection_click, collection_list, color_by_trait, create_trait_data_csv, get_this_trait_vals, get_trait_data, process_traits, selected_traits, submit_click, this_trait_data, trait_click,
__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; };
console.log("before get_traits_from_collection");
@@ -25,7 +25,7 @@ collection_click = function() {
};
submit_click = function() {
- var all_vals, sample, samples, this_trait_vals, trait, trait_names, traits, _i, _j, _len, _len1, _ref;
+ var all_vals, sample, samples, scatter_matrix, this_trait_vals, trait, trait_names, trait_vals_csv, traits, _i, _j, _len, _len1, _ref;
selected_traits = {};
traits = [];
$('#collections_holder').find('input[type=checkbox]:checked').each(function() {
@@ -63,10 +63,54 @@ submit_click = function() {
}
all_vals.push(this_trait_vals);
}
- create_scatterplots(trait_names, samples, all_vals);
+ trait_vals_csv = create_trait_data_csv(selected_traits);
+ scatter_matrix = new ScatterMatrix(trait_vals_csv);
+ scatter_matrix.render();
return $.colorbox.close();
};
+create_trait_data_csv = function(selected_traits) {
+ var all_vals, index, sample, sample_vals, samples, this_trait_vals, trait, trait_names, trait_vals_csv, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref;
+ trait_names = [];
+ trait_names.push($('input[name=trait_id]').val());
+ samples = $('input[name=allsamples]').val().split(" ");
+ all_vals = [];
+ this_trait_vals = get_this_trait_vals(samples);
+ all_vals.push(this_trait_vals);
+ _ref = Object.keys(selected_traits);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ trait = _ref[_i];
+ trait_names.push(trait);
+ this_trait_vals = [];
+ for (_j = 0, _len1 = samples.length; _j < _len1; _j++) {
+ sample = samples[_j];
+ if (__indexOf.call(Object.keys(selected_traits[trait]), sample) >= 0) {
+ this_trait_vals.push(parseFloat(selected_traits[trait][sample]));
+ } else {
+ this_trait_vals.push(null);
+ }
+ }
+ all_vals.push(this_trait_vals);
+ }
+ console.log("all_vals:", all_vals);
+ trait_vals_csv = trait_names.join(",");
+ trait_vals_csv += "\n";
+ for (index = _k = 0, _len2 = samples.length; _k < _len2; index = ++_k) {
+ sample = samples[index];
+ if (all_vals[0][index] === null) {
+ continue;
+ }
+ sample_vals = [];
+ for (_l = 0, _len3 = all_vals.length; _l < _len3; _l++) {
+ trait = all_vals[_l];
+ sample_vals.push(trait[index]);
+ }
+ trait_vals_csv += sample_vals.join(",");
+ trait_vals_csv += "\n";
+ }
+ return trait_vals_csv;
+};
+
trait_click = function() {
var dataset, this_trait_url, trait;
console.log("Clicking on:", $(this));
diff --git a/wqflask/wqflask/static/new/javascript/scatter-matrix.js b/wqflask/wqflask/static/new/javascript/scatter-matrix.js
new file mode 100644
index 00000000..38fd276e
--- /dev/null
+++ b/wqflask/wqflask/static/new/javascript/scatter-matrix.js
@@ -0,0 +1,549 @@
+// Heavily influenced by Mike Bostock's Scatter Matrix example
+// http://mbostock.github.io/d3/talk/20111116/iris-splom.html
+//
+
+/*
+ScatterMatrix = function(url) {
+ this.__url = url;
+ this.__data = undefined;
+ this.__cell_size = 140;
+};
+*/
+
+ScatterMatrix = function(csv_string) {
+ this.__csv_string = csv_string;
+ this.__data = undefined;
+ this.__cell_size = 140;
+};
+
+ScatterMatrix.prototype.cellSize = function(n) {
+ this.__cell_size = n;
+ return this;
+};
+
+/*
+ScatterMatrix.prototype.onData = function(cb) {
+ if (this.__data) { cb(); return; }
+ var self = this;
+ d3.csv(self.__url, function(data) {
+ self.__data = data;
+ cb();
+ });
+};
+*/
+
+ScatterMatrix.prototype.onData = function(cb) {
+ if (this.__data) { cb(); return; }
+ var self = this;
+ console.log("self.csv_string:", self.__csv_string)
+
+ data = d3.csv.parse(self.__csv_string);
+ self.__data = data;
+ cb();
+
+/*
+ d3.csv.parseRows(self.__csv_string, function(data) {
+ self.__data = data;
+ cb();
+ });
+*/
+
+};
+
+ScatterMatrix.prototype.render = function () {
+ var self = this;
+
+ var container = d3.select('#scatterplot_container').append('div')
+ .attr('class', 'scatter-matrix-container');
+ var control = container.append('div')
+ .attr('class', 'scatter-matrix-control');
+ var svg = container.append('div')
+ .attr('class', 'scatter-matrix-svg')
+ .html('<em>Loading data...</em>');
+
+ this.onData(function() {
+ var data = self.__data;
+
+ // Fetch data and get all string variables
+ var string_variables = [undefined];
+ var numeric_variables = [];
+ var numeric_variable_values = {};
+
+ for (k in data[0]) {
+ if (isNaN(+data[0][k])) { string_variables.push(k); }
+ else { numeric_variables.push(k); numeric_variable_values[k] = []; }
+ }
+
+ console.log("data:", data)
+
+ data.forEach(function(d) {
+ for (var j in numeric_variables) {
+ var k = numeric_variables[j];
+ var value = d[k];
+ if (numeric_variable_values[k].indexOf(value) < 0) {
+ numeric_variable_values[k].push(value);
+ }
+ }
+ });
+
+ var size_control = control.append('div').attr('class', 'scatter-matrix-size-control');
+ var color_control = control.append('div').attr('class', 'scatter-matrix-color-control');
+ var filter_control = control.append('div').attr('class', 'scatter-matrix-filter-control');
+ var variable_control = control.append('div').attr('class', 'scatter-matrix-variable-control');
+ var drill_control = control.append('div').attr('class', 'scatter-matrix-drill-control');
+
+ // shared control states
+ var to_include = [];
+ var color_variable = undefined;
+ var selected_colors = undefined;
+ for (var j in numeric_variables) {
+ var v = numeric_variables[j];
+ to_include.push(v);
+ }
+ var drill_variables = [];
+
+ function set_filter(variable) {
+ filter_control.selectAll('*').remove();
+ if (variable) {
+ // Get unique values for this variable
+ var values = [];
+ data.forEach(function(d) {
+ var v = d[variable];
+ if (values.indexOf(v) < 0) { values.push(v); }
+ });
+
+ selected_colors = [];
+ for (var j in values) {
+ var v = values[j];
+ selected_colors.push(v);
+ }
+
+ var filter_li =
+ filter_control
+ .append('p').text('Filter by '+variable+': ')
+ .append('ul')
+ .selectAll('li')
+ .data(values)
+ .enter().append('li');
+
+ filter_li.append('input')
+ .attr('type', 'checkbox')
+ .attr('checked', 'checked')
+ .on('click', function(d, i) {
+ var new_selected_colors = [];
+ for (var j in selected_colors) {
+ var v = selected_colors[j];
+ if (v !== d || this.checked) { new_selected_colors.push(v); }
+ }
+ if (this.checked) { new_selected_colors.push(d); }
+ selected_colors = new_selected_colors;
+ self.__draw(self.__cell_size, svg, color_variable, selected_colors, to_include, drill_variables);
+ });
+ filter_li.append('label')
+ .html(function(d) { return d; });
+ }
+ }
+
+ size_a = size_control.append('p').text('Change cell size: ');
+ size_a.append('a')
+ .attr('href', '#')
+ .html('-')
+ .on('click', function() {
+ self.__cell_size *= 0.75;
+ self.__draw(self.__cell_size, svg, color_variable, selected_colors, to_include, drill_variables);
+ });
+ size_a.append('span').html('&nbsp;');
+ size_a.append('a')
+ .attr('href', '#')
+ .html('+')
+ .on('click', function() {
+ self.__cell_size *= 1.25;
+ self.__draw(self.__cell_size, svg, color_variable, selected_colors, to_include, drill_variables);
+ });
+
+ color_control.append('p').text('Select a variable to color:')
+ color_control
+ .append('ul')
+ .selectAll('li')
+ .data(string_variables)
+ .enter().append('li')
+ .append('a')
+ .attr('href', '#')
+ .text(function(d) { return d ? d : 'None'; })
+ .on('click', function(d, i) {
+ color_variable = d;
+ selected_colors = undefined;
+ self.__draw(self.__cell_size, svg, color_variable, selected_colors, to_include, drill_variables);
+ set_filter(d);
+ });
+
+ var variable_li =
+ variable_control
+ .append('p').text('Include variables: ')
+ .append('ul')
+ .selectAll('li')
+ .data(numeric_variables)
+ .enter().append('li');
+
+ variable_li.append('input')
+ .attr('type', 'checkbox')
+ .attr('checked', 'checked')
+ .on('click', function(d, i) {
+ var new_to_include = [];
+ for (var j in to_include) {
+ var v = to_include[j];
+ if (v !== d || this.checked) { new_to_include.push(v); }
+ }
+ if (this.checked) { new_to_include.push(d); }
+ to_include = new_to_include;
+ self.__draw(self.__cell_size, svg, color_variable, selected_colors, to_include, drill_variables);
+ });
+ variable_li.append('label')
+ .html(function(d) { return d; });
+
+ drill_li =
+ drill_control
+ .append('p').text('Drill and Expand: ')
+ .append('ul')
+ .selectAll('li')
+ .data(numeric_variables)
+ .enter().append('li');
+
+ drill_li.append('input')
+ .attr('type', 'checkbox')
+ .on('click', function(d, i) {
+ var new_drill_variables = [];
+ for (var j in drill_variables) {
+ var v = drill_variables[j];
+ if (v !== d || this.checked) { new_drill_variables.push(v); }
+ }
+ if (this.checked) { new_drill_variables.push(d); }
+ drill_variables = new_drill_variables;
+ self.__draw(self.__cell_size, svg, color_variable, selected_colors, to_include, drill_variables);
+ });
+ drill_li.append('label')
+ .html(function(d) { return d+' ('+numeric_variable_values[d].length+')'; });
+
+ self.__draw(self.__cell_size, svg, color_variable, selected_colors, to_include, drill_variables);
+ });
+};
+
+ScatterMatrix.prototype.__draw =
+ function(cell_size, container_el, color_variable, selected_colors, to_include, drill_variables) {
+ var self = this;
+ this.onData(function() {
+ var data = self.__data;
+
+ if (color_variable && selected_colors) {
+ data = [];
+ self.__data.forEach(function(d) {
+ if (selected_colors.indexOf(d[color_variable]) >= 0) { data.push(d); }
+ });
+ }
+
+ container_el.selectAll('*').remove();
+
+ // If no data, don't do anything
+ if (data.length == 0) { return; }
+
+ // Parse headers from first row of data
+ var numeric_variables = [];
+ for (k in data[0]) {
+ if (!isNaN(+data[0][k]) && to_include.indexOf(k) >= 0) { numeric_variables.push(k); }
+ }
+ numeric_variables.sort();
+
+ // Get values of the string variable
+ var colors = [];
+ if (color_variable) {
+ // Using self.__data, instead of data, so our css classes are consistent when
+ // we filter by value.
+ self.__data.forEach(function(d) {
+ var s = d[color_variable];
+ if (colors.indexOf(s) < 0) { colors.push(s); }
+ });
+ }
+
+ function color_class(d) {
+ var c = d;
+ if (color_variable && d[color_variable]) { c = d[color_variable]; }
+ return colors.length > 0 ? 'color-'+colors.indexOf(c) : 'color-2';
+ }
+
+ // Size parameters
+ var size = cell_size, padding = 10,
+ axis_width = 20, axis_height = 15, legend_width = 200, label_height = 15;
+
+ // Get x and y scales for each numeric variable
+ var x = {}, y = {};
+ numeric_variables.forEach(function(trait) {
+ // Coerce values to numbers.
+ data.forEach(function(d) { d[trait] = +d[trait]; });
+
+ var value = function(d) { return d[trait]; },
+ domain = [d3.min(data, value), d3.max(data, value)],
+ range_x = [padding / 2, size - padding / 2],
+ range_y = [padding / 2, size - padding / 2];
+
+ x[trait] = d3.scale.linear().domain(domain).range(range_x);
+ y[trait] = d3.scale.linear().domain(domain).range(range_y.reverse());
+ });
+
+ // When drilling, user select one or more variables. The first drilled
+ // variable becomes the x-axis variable for all columns, and each column
+ // contains only data points that match specific values for each of the
+ // drilled variables other than the first.
+
+ var drill_values = [];
+ var drill_degrees = []
+ drill_variables.forEach(function(variable) {
+ // Skip first one, since that's just the x axis
+ if (drill_values.length == 0) {
+ drill_values.push([]);
+ drill_degrees.push(1);
+ }
+ else {
+ var values = [];
+ data.forEach(function(d) {
+ var v = d[variable];
+ if (v !== undefined && values.indexOf(v) < 0) { values.push(v); }
+ });
+ values.sort();
+ drill_values.push(values);
+ drill_degrees.push(values.length);
+ }
+ });
+ var total_columns = 1;
+ drill_degrees.forEach(function(d) { total_columns *= d; });
+
+ // Pick out stuff to draw on horizontal and vertical dimensions
+
+ if (drill_variables.length > 0) {
+ // First drill is now the x-axis variable for all columns
+ x_variables = [];
+ for (var i=0; i<total_columns; i++) {
+ x_variables.push(drill_variables[0]);
+ }
+ }
+ else {
+ x_variables = numeric_variables.slice(0);
+ }
+
+ if (drill_variables.length > 0) {
+ // Don't draw any of the "drilled" variables in vertical dimension
+ y_variables = [];
+ numeric_variables.forEach(function(variable) {
+ if (drill_variables.indexOf(variable) < 0) { y_variables.push(variable); }
+ });
+ }
+ else {
+ y_variables = numeric_variables.slice(0);
+ }
+
+ var filter_descriptions = 0;
+ if (drill_variables.length > 1) {
+ filter_descriptions = drill_variables.length-1;
+ }
+
+ // Axes
+ var x_axis = d3.svg.axis();
+ var y_axis = d3.svg.axis();
+ var intf = d3.format('d');
+ var fltf = d3.format('.f');
+ var scif = d3.format('e');
+
+ x_axis.ticks(5)
+ .tickSize(size * y_variables.length)
+ .tickFormat(function(d) {
+ if (Math.abs(+d) > 10000 || (Math.abs(d) < 0.001 && Math.abs(d) != 0)) { return scif(d); }
+ if (parseInt(d) == +d) { return intf(d); }
+ return fltf(d);
+ });
+
+ y_axis.ticks(5)
+ .tickSize(size * x_variables.length)
+ .tickFormat(function(d) {
+ if (Math.abs(+d) > 10000 || (Math.abs(d) < 0.001 && Math.abs(d) != 0)) { return scif(d); }
+ if (parseInt(d) == +d) { return intf(d); }
+ return fltf(d);
+ });
+
+ // Brush - for highlighting regions of data
+ var brush = d3.svg.brush()
+ .on("brushstart", brushstart)
+ .on("brush", brush)
+ .on("brushend", brushend);
+
+ // Root panel
+ var svg = container_el.append("svg:svg")
+ .attr("width", label_height + size * x_variables.length + axis_width + padding + legend_width)
+ .attr("height", size * y_variables.length + axis_height + label_height + label_height*filter_descriptions)
+ .append("svg:g")
+ .attr("transform", "translate("+label_height+",0)");
+
+ // Push legend to the side
+ var legend = svg.selectAll("g.legend")
+ .data(colors)
+ .enter().append("svg:g")
+ .attr("class", "legend")
+ .attr("transform", function(d, i) {
+ return "translate(" + (label_height + size * x_variables.length + padding) + "," + (i*20+10) + ")";
+ });
+
+ legend.append("svg:circle")
+ .attr("class", function(d, i) { return color_class(d); })
+ .attr("r", 3);
+
+ legend.append("svg:text")
+ .attr("x", 12)
+ .attr("dy", ".31em")
+ .text(function(d) { return d; });
+
+ // Draw X-axis
+ svg.selectAll("g.x.axis")
+ .data(x_variables)
+ .enter().append("svg:g")
+ .attr("class", "x axis")
+ .attr("transform", function(d, i) { return "translate(" + i * size + ",0)"; })
+ .each(function(d) { d3.select(this).call(x_axis.scale(x[d]).orient("bottom")); });
+
+ // Draw Y-axis
+ svg.selectAll("g.y.axis")
+ .data(y_variables)
+ .enter().append("svg:g")
+ .attr("class", "y axis")
+ .attr("transform", function(d, i) { return "translate(0," + i * size + ")"; })
+ .each(function(d) { d3.select(this).call(y_axis.scale(y[d]).orient("right")); });
+
+ // Draw scatter plot
+ var cell = svg.selectAll("g.cell")
+ .data(cross(x_variables, y_variables))
+ .enter().append("svg:g")
+ .attr("class", "cell")
+ .attr("transform", function(d) { return "translate(" + d.i * size + "," + d.j * size + ")"; })
+ .each(plot);
+
+ // Add titles for y variables
+ cell.filter(function(d) { return d.i == 0; }).append("svg:text")
+ .attr("x", padding-size)
+ .attr("y", -label_height)
+ .attr("dy", ".71em")
+ .attr("transform", function(d) { return "rotate(-90)"; })
+ .text(function(d) { return d.y; });
+
+ function plot(p) {
+ // console.log(p);
+
+ var data_to_draw = data;
+
+ // If drilling, compute what values of the drill variables correspond to
+ // this column.
+ //
+ var filter = {};
+ if (drill_variables.length > 1) {
+ var column = p.i;
+
+ var cap = 1;
+ for (var i=drill_variables.length-1; i > 0; i--) {
+ var var_name = drill_variables[i];
+ var var_value = undefined;
+
+ if (i == drill_variables.length-1) {
+ // for the last drill variable, we index by %
+ var_value = drill_values[i][column % drill_degrees[i]];
+ }
+ else {
+ // otherwise divide by capacity of subsequent variables to get value array index
+ var_value = drill_values[i][parseInt(column/cap)];
+ }
+
+ filter[var_name] = var_value;
+ cap *= drill_degrees[i];
+ }
+
+ data_to_draw = [];
+ data.forEach(function(d) {
+ var pass = true;
+ for (k in filter) { if (d[k] != filter[k]) { pass = false; break; } }
+ if (pass === true) { data_to_draw.push(d); }
+ });
+ }
+
+ var cell = d3.select(this);
+
+ // Frame
+ cell.append("svg:rect")
+ .attr("class", "frame")
+ .attr("x", padding / 2)
+ .attr("y", padding / 2)
+ .attr("width", size - padding)
+ .attr("height", size - padding);
+
+ // Scatter plot dots
+ cell.selectAll("circle")
+ .data(data_to_draw)
+ .enter().append("svg:circle")
+ .attr("class", function(d) { return color_class(d); })
+ .attr("cx", function(d) { return x[p.x](d[p.x]); })
+ .attr("cy", function(d) { return y[p.y](d[p.y]); })
+ .attr("r", 5);
+
+ // Add titles for x variables and drill variable values
+ if (p.j == y_variables.length-1) {
+ cell.append("svg:text")
+ .attr("x", padding)
+ .attr("y", size+axis_height)
+ .attr("dy", ".71em")
+ .text(function(d) { return d.x; });
+
+ if (drill_variables.length > 1) {
+ var i = 0;
+ for (k in filter) {
+ i += 1;
+ cell.append("svg:text")
+ .attr("x", padding)
+ .attr("y", size+axis_height+label_height*i)
+ .attr("dy", ".71em")
+ .text(function(d) { return filter[k]+': '+k; });
+ }
+ }
+ }
+
+ // Brush
+ cell.call(brush.x(x[p.x]).y(y[p.y]));
+ }
+
+ // Clear the previously-active brush, if any
+ function brushstart(p) {
+ if (brush.data !== p) {
+ cell.call(brush.clear());
+ brush.x(x[p.x]).y(y[p.y]).data = p;
+ }
+ }
+
+ // Highlight selected circles
+ function brush(p) {
+ var e = brush.extent();
+ svg.selectAll(".cell circle").attr("class", function(d) {
+ return e[0][0] <= d[p.x] && d[p.x] <= e[1][0]
+ && e[0][1] <= d[p.y] && d[p.y] <= e[1][1]
+ ? color_class(d) : null;
+ });
+ }
+
+ // If brush is empty, select all circles
+ function brushend() {
+ if (brush.empty()) svg.selectAll(".cell circle").attr("class", function(d) {
+ return color_class(d);
+ });
+ }
+
+ function cross(a, b) {
+ var c = [], n = a.length, m = b.length, i, j;
+ for (i = -1; ++i < n;) for (j = -1; ++j < m;) c.push({x: a[i], i: i, y: b[j], j: j});
+ return c;
+ }
+ });
+
+};
+
diff --git a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee
index 8b73b85d..fdec0ee4 100755
--- a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee
+++ b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee
@@ -67,15 +67,24 @@ do_ajax_post = (url, form_data) ->
success: (data) =>
clearInterval(this.my_timer)
$('#progress_bar_container').modal('hide')
- $("body").html(data)
+ open_mapping_results(data)
+ #$("body").html(data)
)
console.log("settingInterval")
this.my_timer = setInterval(get_progress, 1000)
return false
+open_mapping_results = (data) ->
+ $.colorbox(
+ html: data
+ href: "#mapping_results_holder"
+ height: "80%"
+ width: "80%"
+ )
+
showalert = (message,alerttype) ->
- $('#alert_placeholder').append('<div id="alertdiv" class="alert ' + alerttype + '"><a class="close" data-dismiss="alert">×</a><span>'+message+'</span></div>')
+ $('#alert_placeholder').append('<div id="alertdiv" class="alert ' + alerttype + '"><a class="close" data-dismiss="alert">×</a><span>'+message+'</span></div>')
$("#interval_mapping_compute").click(() =>
@@ -95,32 +104,6 @@ $("#interval_mapping_compute").click(() =>
console.log("form_data is:", form_data)
do_ajax_post(url, form_data)
-
- #remove_outliers = confirm("Remove outliers?")
- #if use_outliers == true
- # block_outliers()
- # do_ajax_post(url, form_data)
- #else
- # do_ajax_post(url, form_data)
- #$.ajax(
- # type: "POST"
- # url: url
- # data: form_data
- # error: (xhr, ajaxOptions, thrownError) =>
- # alert("Sorry, an error occurred")
- # console.log(xhr)
- # clearInterval(this.my_timer)
- # $('#progress_bar_container').modal('hide')
- # $("body").html("We got an error.")
- # success: (data) =>
- # clearInterval(this.my_timer)
- # $('#progress_bar_container').modal('hide')
- # $("body").html(data)
- #)
- #console.log("settingInterval")
- #
- #this.my_timer = setInterval(get_progress, 1000)
- #return false
)
$('#suggestive').hide()
@@ -146,26 +129,6 @@ $("#pylmm_compute").click(() =>
#if use_outliers == true
# block_outliers()
do_ajax_post(url, form_data)
-
- #$.ajax(
- # type: "POST"
- # url: url
- # data: form_data
- # error: (xhr, ajaxOptions, thrownError) =>
- # alert("Sorry, an error occurred")
- # console.log(xhr)
- # clearInterval(this.my_timer)
- # $('#progress_bar_container').modal('hide')
- # $("body").html("We got an error.")
- # success: (data) =>
- # clearInterval(this.my_timer)
- # $('#progress_bar_container').modal('hide')
- # $("body").html(data)
- #)
- #console.log("settingInterval")
- #
- #this.my_timer = setInterval(get_progress, 1000)
- #return false
)
@@ -184,26 +147,6 @@ $("#rqtl_geno_compute").click(() =>
#if use_outliers == true
# block_outliers()
do_ajax_post(url, form_data)
-
- #$.ajax(
- # type: "POST"
- # url: url
- # data: form_data
- # error: (xhr, ajaxOptions, thrownError) =>
- # alert("Sorry, an error occurred")
- # console.log(xhr)
- # clearInterval(this.my_timer)
- # $('#progress_bar_container').modal('hide')
- # $("body").html("We got an error.")
- # success: (data) =>
- # clearInterval(this.my_timer)
- # $('#progress_bar_container').modal('hide')
- # $("body").html(data)
- #)
- #console.log("settingInterval")
- #
- #this.my_timer = setInterval(get_progress, 1000)
- #return false
)
@@ -218,26 +161,6 @@ $("#plink_compute").click(() =>
console.log("form_data is:", form_data)
do_ajax_post(url, form_data)
-
- #$.ajax(
- # type: "POST"
- # url: url
- # data: form_data
- # error: (xhr, ajaxOptions, thrownError) =>
- # alert("Sorry, an error occurred")
- # console.log(xhr)
- # clearInterval(this.my_timer)
- # $('#static_progress_bar_container').modal('hide')
- # $("body").html("We got an error.")
- # success: (data) =>
- # clearInterval(this.my_timer)
- # $('#static_progress_bar_container').modal('hide')
- # $("body").html(data)
- #)
- #console.log("settingInterval")
- #
- #this.my_timer = setInterval(get_progress, 1000)
- #return false
)
$("#gemma_compute").click(() =>
@@ -251,26 +174,6 @@ $("#gemma_compute").click(() =>
console.log("form_data is:", form_data)
do_ajax_post(url, form_data)
-
- #$.ajax(
- # type: "POST"
- # url: url
- # data: form_data
- # error: (xhr, ajaxOptions, thrownError) =>
- # alert("Sorry, an error occurred")
- # console.log(xhr)
- # clearInterval(this.my_timer)
- # $('#static_progress_bar_container').modal('hide')
- # $("body").html("We got an error.")
- # success: (data) =>
- # clearInterval(this.my_timer)
- # $('#static_progress_bar_container').modal('hide')
- # $("body").html(data)
- #)
- #console.log("settingInterval")
- #
- #this.my_timer = setInterval(get_progress, 1000)
- #return false
)
#$(".submit_special").click(submit_special)
diff --git a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js
index 92d3183a..c8988cdc 100755
--- a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js
+++ b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js
@@ -1,5 +1,5 @@
// Generated by CoffeeScript 1.8.0
-var block_outliers, composite_mapping_fields, do_ajax_post, get_progress, mapping_method_fields, showalert, submit_special, toggle_enable_disable, update_time_remaining;
+var block_outliers, composite_mapping_fields, do_ajax_post, get_progress, mapping_method_fields, open_mapping_results, showalert, submit_special, toggle_enable_disable, update_time_remaining;
submit_special = function() {
var url;
@@ -86,7 +86,7 @@ do_ajax_post = function(url, form_data) {
return function(data) {
clearInterval(_this.my_timer);
$('#progress_bar_container').modal('hide');
- return $("body").html(data);
+ return open_mapping_results(data);
};
})(this)
});
@@ -95,6 +95,15 @@ do_ajax_post = function(url, form_data) {
return false;
};
+open_mapping_results = function(data) {
+ return $.colorbox({
+ html: data,
+ href: "#mapping_results_holder",
+ height: "80%",
+ width: "80%"
+ });
+};
+
showalert = function(message, alerttype) {
return $('#alert_placeholder').append('<div id="alertdiv" class="alert ' + alerttype + '"><a class="close" data-dismiss="alert">�</a><span>' + message + '</span></div>');
};
diff --git a/wqflask/wqflask/static/packages/bootstrap/css/bootstrap.css b/wqflask/wqflask/static/packages/bootstrap/css/bootstrap.css
index 3dc73a7a..8326e83f 100755
--- a/wqflask/wqflask/static/packages/bootstrap/css/bootstrap.css
+++ b/wqflask/wqflask/static/packages/bootstrap/css/bootstrap.css
@@ -1414,6 +1414,7 @@ pre code {
margin-right: auto;
margin-left: auto;
}
+
.row {
margin-right: -15px;
margin-left: -15px;
@@ -2763,13 +2764,13 @@ select[multiple].form-group-lg .form-control {
margin-right: -15px;
margin-left: -15px;
}
-@media (min-width: 768px) {
- .form-horizontal .control-label {
- padding-top: 7px;
- margin-bottom: 0;
- text-align: right;
- }
+
+.form-horizontal .control-label {
+ padding-top: 7px;
+ margin-bottom: 0;
+ text-align: right;
}
+
.form-horizontal .has-feedback .form-control-feedback {
right: 15px;
}
@@ -3760,7 +3761,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
top: auto;
left: auto;
}
-@media (min-width: 768px) {
+
.nav-tabs.nav-justified > li {
display: table-cell;
width: 1%;
@@ -3768,7 +3769,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.nav-tabs.nav-justified > li > a {
margin-bottom: 0;
}
-}
+
.nav-tabs.nav-justified > li > a {
margin-right: 0;
border-radius: 4px;
@@ -3778,7 +3779,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.nav-tabs.nav-justified > .active > a:focus {
border: 1px solid #ddd;
}
-@media (min-width: 768px) {
+
.nav-tabs.nav-justified > li > a {
border-bottom: 1px solid #ddd;
border-radius: 4px 4px 0 0;
@@ -3788,7 +3789,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.nav-tabs.nav-justified > .active > a:focus {
border-bottom-color: #fff;
}
-}
+
.nav-pills > li {
float: left;
}
@@ -3825,7 +3826,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
top: auto;
left: auto;
}
-@media (min-width: 768px) {
+
.nav-justified > li {
display: table-cell;
width: 1%;
@@ -3833,7 +3834,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.nav-justified > li > a {
margin-bottom: 0;
}
-}
+
.nav-tabs-justified {
border-bottom: 0;
}
@@ -3846,7 +3847,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.nav-tabs-justified > .active > a:focus {
border: 1px solid #ddd;
}
-@media (min-width: 768px) {
+
.nav-tabs-justified > li > a {
border-bottom: 1px solid #ddd;
border-radius: 4px 4px 0 0;
@@ -3856,7 +3857,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.nav-tabs-justified > .active > a:focus {
border-bottom-color: #fff;
}
-}
+
.tab-content > .tab-pane {
display: none;
visibility: hidden;
@@ -4079,7 +4080,7 @@ float: right!important;
background-image: none;
}
}
-@media (min-width: 768px) {
+
.navbar-nav {
float: left;
margin: 0;
@@ -4091,7 +4092,7 @@ float: right!important;
padding-top: 15px;
padding-bottom: 15px;
}
-}
+
.navbar-form {
padding: 10px 15px;
margin-top: 8px;
@@ -4200,25 +4201,25 @@ float: right!important;
margin-top: 15px;
margin-bottom: 15px;
}
-@media (min-width: 768px) {
- .navbar-text {
- float: left;
- margin-right: 15px;
- margin-left: 15px;
- }
+
+.navbar-text {
+ float: left;
+ margin-right: 15px;
+ margin-left: 15px;
}
-@media (min-width: 768px) {
- .navbar-left {
- float: left !important;
- }
- .navbar-right {
- float: right !important;
- margin-right: -15px;
- }
- .navbar-right ~ .navbar-right {
- margin-right: 0;
- }
+
+
+.navbar-left {
+ float: left !important;
+}
+.navbar-right {
+ float: right !important;
+ margin-right: -15px;
}
+.navbar-right ~ .navbar-right {
+ margin-right: 0;
+}
+
.navbar-default {
background-color: #f8f8f8;
border-color: #e7e7e7;
@@ -6061,6 +6062,7 @@ button.close {
.carousel-caption .btn {
text-shadow: none;
}
+/*
@media screen and (min-width: 768px) {
.carousel-control .glyphicon-chevron-left,
.carousel-control .glyphicon-chevron-right,
@@ -6088,6 +6090,7 @@ button.close {
bottom: 20px;
}
}
+*/
.clearfix:before,
.clearfix:after,
.dl-horizontal dd:before,
@@ -6195,6 +6198,7 @@ button.close {
.visible-lg-inline-block {
display: none !important;
}
+/*
@media (max-width: 767px) {
.visible-xs {
display: block !important;
@@ -6353,6 +6357,7 @@ button.close {
display: table-cell !important;
}
}
+*/
.visible-print-block {
display: none !important;
}
diff --git a/wqflask/wqflask/templates/collections/view.html b/wqflask/wqflask/templates/collections/view.html
index 3d777866..fc1edf2a 100755
--- a/wqflask/wqflask/templates/collections/view.html
+++ b/wqflask/wqflask/templates/collections/view.html
@@ -69,9 +69,9 @@
<th>Description</th>
<th>Location</th>
<th>Mean</th>
- <th>Max LRS</th>
+ <th>Max LRS<a href="http://genenetwork.org//glossary.html#L" target="_blank"><sup style="color:#f00"> ?</sup></a></th>
<th>Max LRS Location</th>
- <th>Additive Effect</th>
+ <th>Additive Effect<a href="http://genenetwork.org//glossary.html#A" target="_blank"><sup style="color:#f00"> ?</sup></a></th>
</tr>
</thead>
@@ -119,6 +119,13 @@
<script language="javascript" type="text/javascript" src="/static/packages/TableTools/media/js/TableTools.min.js"></script>
<script language="javascript" type="text/javascript">
$(document).ready( function () {
+
+ $('#trait_table tr').click(function(event) {
+ if (event.target.type !== 'checkbox') {
+ $(':checkbox', this).trigger('click');
+ }
+ });
+
console.time("Creating table");
$('#trait_table').dataTable( {
"aoColumns": [
@@ -130,7 +137,7 @@
"sWidth": "15%" },
{ "sType": "cust-txt" },
{ "sType": "natural",
- "sWidth": "10%" },
+ "sWidth": "12%" },
{ "sType": "natural",
"sWidth": "15%" },
{ "sType": "cust-txt" }
@@ -143,7 +150,7 @@
null,
null
],
- "sDom": "ftir",
+ "sDom": "tir",
"iDisplayLength": -1,
"autoWidth": true,
"bLengthChange": true,
diff --git a/wqflask/wqflask/templates/index_page.html b/wqflask/wqflask/templates/index_page.html
index adc004a5..eb4f883c 100755
--- a/wqflask/wqflask/templates/index_page.html
+++ b/wqflask/wqflask/templates/index_page.html
@@ -65,7 +65,7 @@
<!-- GET ANY SEARCH -->
<div class="form-group">
- <label for="tfor" class="col-xs-1 control-label" style="width: 65px !important;">Search:</label>
+ <label for="tfor" class="col-xs-1 control-label" style="width: 65px !important;">Search for:</label>
<div class="col-xs-10 controls">
<textarea name="search_terms" rows="2" class="form-control search-query" style="width: 450px !important;" id="tfor"></textarea>
</div>
@@ -93,7 +93,7 @@
<input id="btsearch" type="submit" class="btn btn-primary form-control" value="Search">
</div>
<div class="col-xs-4 controls" style="width: 150px !important;">
- <input id="make_default" type="submit" class="btn btn-default form-control" value="Make Default">
+ <input id="make_default" class="btn btn-default form-control" value="Make Default">
</div>
</div>
@@ -103,11 +103,9 @@
</fieldset>
</form>
</section>
- </div>
- <div style="padding-left:120px" class="col-xs-6" style="width: 600px !important;">
<section id="advanced">
<div class="page-header">
- <h1>Advanced commands</h1>
+ <h2>Advanced commands</h2>
</div>
<p>GeneNetwork supports a variety of advanced searches.</p>
@@ -148,6 +146,8 @@
scores between 9 and 999.</li>-->
</ul>
</section>
+ </div>
+ <div style="padding-left:120px" class="col-xs-6" style="width: 600px !important;">
<!--
<section id="tour-info">
<div class="page-header">
diff --git a/wqflask/wqflask/templates/interval_mapping.html b/wqflask/wqflask/templates/interval_mapping.html
index 7a03ce34..82a96ba1 100755
--- a/wqflask/wqflask/templates/interval_mapping.html
+++ b/wqflask/wqflask/templates/interval_mapping.html
@@ -1,120 +1,116 @@
-{% extends "base.html" %}
-{% block title %}Interval Mapping{% endblock %}
-{% block css %}
-<!-- <link rel="stylesheet" type="text/css" href="/static/new/css/interval_mapping.css" />-->
- <link rel="stylesheet" type="text/css" href="/static/new/packages/DataTables/css/jquery.dataTables.css" />
- <link rel="stylesheet" type="text/css" href="/static/packages/DT_bootstrap/DT_bootstrap.css" />
- <link rel="stylesheet" type="text/css" href="/static/packages/TableTools/media/css/TableTools.css" />
- <link rel="stylesheet" type="text/css" href="/static/new/css/d3-tip.min.css" />
- <link rel="stylesheet" type="text/css" href="/static/new/css/panelutil.css" />
-{% endblock %}
-{% block content %} <!-- Start of body -->
-
- {{ header("Mapping",
- '{}: {}'.format(this_trait.name, this_trait.description_fmt)) }}
-
- <div class="container">
- <div>
- <h2>
- Whole Genome Mapping
- </h2>
- <form style ='float: left; padding: 5px;' id="exportform" action="export" method="post">
- <input type="hidden" id="data" name="data" value="">
- <input type="hidden" id="filename" name="filename" value="">
- <input type="submit" id="export" value="Download SVG">
- </form>
- <form style ='float: left; padding: 5px;' id="exportpdfform" action="export_pdf" method="post">
- <input type="hidden" id="data" name="data" value="">
- <input type="hidden" id="filename" name="filename" value="">
- <input type="submit" id="export_pdf" value="Download PDF">
- </form>
- </div>
- <div id="chart_container">
- <div class="qtlcharts" id="topchart">
-
- </div>
- </div>
- <div>
- <h2>
- Results
- </h2>
- </div>
- <table cellpadding="0" cellspacing="0" border="0" id="qtl_results" class="table table-hover table-striped table-bordered">
- <thead>
- <tr>
- <td>Index</td>
- <td>LRS Score</td>
- <td>Chr</td>
- <td>Mb</td>
- <td>Locus</td>
- <td>Additive Effect</td>
- </tr>
- </thead>
- <tbody>
- {% for marker in qtl_results %}
- <tr>
- <td>{{ loop.index }}</td>
- <td>{{ marker.lrs_value|float }}</td>
- <td>{{ marker.chr|int }}</td>
- <td>{{ marker.Mb|float }}</td>
- <td>{{ marker.name }}</td>
- <td>{{ marker.additive|float }}</td>
- </tr>
- {% endfor %}
- </tbody>
- </table>
-
- </div>
-
- <!-- End of body -->
-
-{% endblock %}
-
-{% block js %}
- <script>
- js_data = {{ js_data | safe }}
- </script>
-
- <!--[if lt IE 9]>
-<!-- <script language="javascript" type="text/javascript" src="/static/packages/jqplot/excanvas.js"></script>-->
- <![endif]-->
- <script language="javascript" type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
- <script language="javascript" type="text/javascript" src="/static/new/js_external/d3-tip.min.js"></script>
- <script language="javascript" type="text/javascript" src="/static/new/javascript/panelutil.js"></script>
- <script language="javascript" type="text/javascript" src="/static/new/javascript/chr_interval_map.js"></script>
- <script language="javascript" type="text/javascript" src="/static/new/javascript/lod_chart.js"></script>
- <script language="javascript" type="text/javascript" src="/static/new/javascript/create_lodchart.js"></script>
- <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/jquery.js"></script>
- <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/jquery.dataTables.min.js"></script>
- <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/dataTables.scientific.js"></script>
- <script language="javascript" type="text/javascript" src="/static/packages/DT_bootstrap/DT_bootstrap.js"></script>
- <script language="javascript" type="text/javascript" src="/static/packages/TableTools/media/js/TableTools.min.js"></script>
- <script language="javascript" type="text/javascript" src="/static/packages/underscore/underscore-min.js"></script>
-
- <script type="text/javascript" charset="utf-8">
- $(document).ready( function () {
- console.time("Creating table");
- $('#qtl_results').dataTable( {
- //"sDom": "<<'span3'l><'span3'T><'span4'f>'row-fluid'r>t<'row-fluid'<'span6'i><'span6'p>>",
- "sDom": "lTftipr",
- "oTableTools": {
- "aButtons": [
- "copy",
- "print",
- {
- "sExtends": "collection",
- "sButtonText": 'Save <span class="caret" />',
- "aButtons": [ "csv", "xls", "pdf" ]
- }
- ],
- "sSwfPath": "/static/packages/TableTools/media/swf/copy_csv_xls_pdf.swf"
- },
- "iDisplayLength": 50,
- "bLengthChange": true,
- "bDeferRender": true,
- "bSortClasses": false
- } );
- console.timeEnd("Creating table");
- });
- </script>
+{% block css %}
+<!-- <link rel="stylesheet" type="text/css" href="/static/new/css/interval_mapping.css" />-->
+ <link rel="stylesheet" type="text/css" href="/static/new/packages/DataTables/css/jquery.dataTables.css" />
+ <link rel="stylesheet" type="text/css" href="/static/packages/DT_bootstrap/DT_bootstrap.css" />
+ <link rel="stylesheet" type="text/css" href="/static/packages/TableTools/media/css/TableTools.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/d3-tip.min.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/panelutil.css" />
+{% endblock %}
+{% block content %} <!-- Start of body -->
+
+
+ <div id="mapping_results" class="container">
+ <div>
+ <h2>
+ Whole Genome Mapping
+ </h2>
+ <form style ='float: left; padding: 5px;' id="exportform" action="export" method="post">
+ <input type="hidden" id="data" name="data" value="">
+ <input type="hidden" id="filename" name="filename" value="">
+ <input type="submit" id="export" value="Download SVG">
+ </form>
+ <form style ='float: left; padding: 5px;' id="exportpdfform" action="export_pdf" method="post">
+ <input type="hidden" id="data" name="data" value="">
+ <input type="hidden" id="filename" name="filename" value="">
+ <input type="submit" id="export_pdf" value="Download PDF">
+ </form>
+ </div>
+ <div id="chart_container">
+ <div class="qtlcharts" id="topchart">
+
+ </div>
+ </div>
+ <div>
+ <h2>
+ Results
+ </h2>
+ </div>
+ <table cellpadding="0" cellspacing="0" border="0" id="qtl_results" class="table table-hover table-striped table-bordered">
+ <thead>
+ <tr>
+ <td>Index</td>
+ <td>LRS Score</td>
+ <td>Chr</td>
+ <td>Mb</td>
+ <td>Locus</td>
+ <td>Additive Effect</td>
+ </tr>
+ </thead>
+ <tbody>
+ {% for marker in qtl_results %}
+ <tr>
+ <td>{{ loop.index }}</td>
+ <td>{{ marker.lrs_value|float }}</td>
+ <td>{{ marker.chr|int }}</td>
+ <td>{{ marker.Mb|float }}</td>
+ <td>{{ marker.name }}</td>
+ <td>{{ marker.additive|float }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+
+ </div>
+
+ <!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+ <script>
+ js_data = {{ js_data | safe }}
+ </script>
+
+ <!--[if lt IE 9]>
+<!-- <script language="javascript" type="text/javascript" src="/static/packages/jqplot/excanvas.js"></script>-->
+ <![endif]-->
+ <script language="javascript" type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/js_external/d3-tip.min.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/panelutil.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/chr_interval_map.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/lod_chart.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/javascript/create_lodchart.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/jquery.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/jquery.dataTables.min.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/dataTables.scientific.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/packages/DT_bootstrap/DT_bootstrap.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/packages/TableTools/media/js/TableTools.min.js"></script>
+ <script language="javascript" type="text/javascript" src="/static/packages/underscore/underscore-min.js"></script>
+
+ <script type="text/javascript" charset="utf-8">
+ $(document).ready( function () {
+ console.time("Creating table");
+ $('#qtl_results').dataTable( {
+ //"sDom": "<<'span3'l><'span3'T><'span4'f>'row-fluid'r>t<'row-fluid'<'span6'i><'span6'p>>",
+ "sDom": "lTftipr",
+ "oTableTools": {
+ "aButtons": [
+ "copy",
+ "print",
+ {
+ "sExtends": "collection",
+ "sButtonText": 'Save <span class="caret" />',
+ "aButtons": [ "csv", "xls", "pdf" ]
+ }
+ ],
+ "sSwfPath": "/static/packages/TableTools/media/swf/copy_csv_xls_pdf.swf"
+ },
+ "iDisplayLength": 50,
+ "bLengthChange": true,
+ "bDeferRender": true,
+ "bSortClasses": false
+ } );
+ console.timeEnd("Creating table");
+ });
+ </script>
{% endblock %} \ No newline at end of file
diff --git a/wqflask/wqflask/templates/new_security/login_user.html b/wqflask/wqflask/templates/new_security/login_user.html
index ecf8278c..8ad0c79e 100755
--- a/wqflask/wqflask/templates/new_security/login_user.html
+++ b/wqflask/wqflask/templates/new_security/login_user.html
@@ -3,6 +3,9 @@
{% block content %}
<div class="container">
+
+ {{ flash_me() }}
+
<div class="page-header">
<h1>Login</h1>
</div>
@@ -24,15 +27,15 @@
<form class="form-horizontal" action="/n/login" method="POST" name="login_user_form">
<fieldset>
<div class="form-group">
- <label class="col-xs-2 control-label" for="email_address">Email&nbsp;Address</label>
- <div class="col-xs-10">
+ <label style="text-align:left;" class="col-xs-1 control-label" for="email_address">Email&nbsp;Address</label>
+ <div style="margin-left:20px;" class="col-xs-10">
<input id="email_address" class="focused" name="email_address" type="text" value="">
</div>
</div>
<div class="form-group">
- <label class="col-xs-2 control-label" for="password">Password</label>
- <div class="col-xs-3 controls">
+ <label style="text-align:left;" class="col-xs-1 control-label" for="password">Password</label>
+ <div style="margin-left:20px;" class="col-xs-3 controls">
<input id="password" name="password" type="password" value="">
<br />
<a href="/n/forgot_password">Forgot your password?</a><br/>
@@ -41,17 +44,15 @@
<div class="form-group">
- <label class="col-xs-2 control-label" for="remember"></label>
- <div class="col-xs-3 controls">
- <label class="checkbox">
- <input id="remember" name="remember" type="checkbox" value="y"> Remember me
- </label>
+ <label class="col-xs-1 control-label" for="remember"></label>
+ <div style="margin-left:20px;" class="col-xs-3 controls">
+ <input id="remember" name="remember" type="checkbox" value="y"> <b>Remember me</b>
</div>
</div>
<div class="form-group">
- <label class="col-xs-2 control-label" for="submit"></label>
- <div class="col-xs-3 controls">
+ <label class="col-xs-1 control-label" for="submit"></label>
+ <div style="margin-left:20px;" class="col-xs-3 controls">
<input id="next" name="next" type="hidden" value="">
<input class="btn btn-primary" id="submit" name="submit" type="submit" value="Sign in">
</div>
diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html
index 055ab979..731f6fbd 100755
--- a/wqflask/wqflask/templates/search_result_page.html
+++ b/wqflask/wqflask/templates/search_result_page.html
@@ -49,7 +49,13 @@
<thead>
<tr>
{% for header in header_fields %}
+ {% if header == 'Max LRS' %}
+ <th>{{header}}<a href="http://genenetwork.org//glossary.html#L" target="_blank"><sup style="color:#f00"> ?</sup></a></th>
+ {% elif header == 'Additive Effect' %}
+ <th>{{header}}<a href="http://genenetwork.org//glossary.html#A" target="_blank"><sup style="color:#f00"> ?</sup></a></th>
+ {% else %}
<th>{{header}}</th>
+ {% endif %}
{% endfor %}
</tr>
</thead>
@@ -140,17 +146,11 @@
$(document).ready( function () {
- /*num_columns = $('#trait_table').find('tr:first th').length;
-
- nul_cols = []
- for (i=0; i<num_columns - 1, i++) {
- $('#trait_table > tbody > tr').each(function() {
- if ($(this).find('td:eq(i)').html()){
- continue;
- }
- });
- nul_cols.push(i)
- }*/
+ $('#trait_table tr').click(function(event) {
+ if (event.target.type !== 'checkbox') {
+ $(':checkbox', this).trigger('click');
+ }
+ });
console.time("Creating table");
{% if dataset.type == 'ProbeSet' %}
@@ -166,7 +166,7 @@
"sWidth": "15%" },
{ "sType": "cust-txt" },
{ "sType": "natural",
- "sWidth": "10%" },
+ "sWidth": "12%" },
{ "sType": "natural",
"sWidth": "15%" },
{ "sType": "cust-txt" }
diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html
index 5d0437df..a1723ef8 100755
--- a/wqflask/wqflask/templates/show_trait.html
+++ b/wqflask/wqflask/templates/show_trait.html
@@ -6,6 +6,7 @@
<link rel="stylesheet" type="text/css" href="/static/new/css/bar_chart.css" />
<link rel="stylesheet" type="text/css" href="/static/new/css/box_plot.css" />
<link rel="stylesheet" type="text/css" href="/static/new/css/panelutil.css" />
+ <link rel="stylesheet" type="text/css" href="/static/new/css/scatter-matrix.css" />
<link rel="stylesheet" type="text/css" href="/static/new/css/d3-tip.min.css" />
<link rel="stylesheet" type="text/css" href="/static/new/packages/DataTables/css/jquery.dataTables.css" />
<link rel="stylesheet" type="text/css" href="/static/packages/DT_bootstrap/DT_bootstrap.css" />
@@ -40,7 +41,7 @@
<div class="panel-heading">
<h3 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseOne">
- Statistics
+ <span class="glyphicon glyphicon-chevron-down"></span> Statistics
</a>
</h3>
</div>
@@ -54,7 +55,7 @@
<div class="panel-heading">
<h3 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseTwo">
- Calculate Correlations
+ <span class="glyphicon glyphicon-chevron-down"></span> Calculate Correlations
</a>
</h3>
</div>
@@ -68,7 +69,7 @@
<div class="panel-heading">
<h3 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseThree">
- Mapping Tools
+ <span class="glyphicon glyphicon-chevron-down"></span> Mapping Tools
</a>
</h3>
</div>
@@ -82,7 +83,7 @@
<div class="panel-heading">
<h3 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseFour" aria-expanded="true">
- Review and Edit Data
+ <span class="glyphicon glyphicon-chevron-up"></span> Review and Edit Data
</a>
</h3>
</div>
@@ -122,6 +123,7 @@
<script type="text/javascript" src="/static/new/javascript/histogram.js"></script>
<script type="text/javascript" src="/static/new/javascript/box_plot.js"></script>
<script type="text/javascript" src="/static/new/javascript/scatterplot.js"></script>
+ <script type="text/javascript" src="/static/new/javascript/scatter-matrix.js"></script>
<script type="text/javascript" src="/static/new/javascript/draw_probability_plot.js"></script>
<script type="text/javascript" src="/static/new/javascript/compare_traits_scatterplot.js"></script>
@@ -162,6 +164,16 @@
};
$(document).ready( function () {
+
+ $('.panel-heading').find('a').click(function () {
+ if ($(this).hasClass('collapsed')){
+ $(this).find('.glyphicon-chevron-down').removeClass('glyphicon-chevron-down').addClass('glyphicon-chevron-up');
+ }
+ else {
+ $(this).find('.glyphicon-chevron-up').removeClass('glyphicon-chevron-up').addClass('glyphicon-chevron-down');
+ }
+ });
+
console.time("Creating table");
{% if sample_groups[0].se_exists() %}
diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html
index 84ddfd53..6f5fe237 100755
--- a/wqflask/wqflask/templates/show_trait_mapping_tools.html
+++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html
@@ -1,5 +1,7 @@
<div>
+ <div class="col-xs-6">
<div class="tabbable"> <!-- Only required for left/right tabs -->
+
<ul class="nav nav-pills">
<li class="active">
<a href="#interval_mapping" data-toggle="tab">Interval Mapping</a>
@@ -27,22 +29,22 @@
<div class="tab-pane active" id="interval_mapping">
<div style="padding: 20px" class="form-horizontal">
<div class="mapping_method_fields form-group">
- <label for="mapping_permutations" class="col-xs-1 control-label">Permutations</label>
- <div style="margin-left: 20px;" class="col-xs-2 controls">
+ <label for="mapping_permutations" class="col-xs-2 control-label">Permutations</label>
+ <div style="margin-left: 20px;" class="col-xs-4 controls">
<input name="num_perm_reaper" value="2000" type="text" class="form-control">
</div>
</div>
<div class="mapping_method_fields form-group">
- <label for="mapping_bootstraps" class="col-xs-1 control-label" title="Bootstrapping Resamples">Bootstrap</label>
- <div style="margin-left: 20px;" class="col-xs-2 controls">
+ <label for="mapping_bootstraps" class="col-xs-2 control-label" title="Bootstrapping Resamples">Bootstrap</label>
+ <div style="margin-left: 20px;" class="col-xs-4 controls">
<input name="mapping_bootstraps" value="2000" type="text" class="form-control">
</div>
</div>
<div class="mapping_method_fields form-group">
- <label class="col-xs-2 control-label">Display Additive Effect</label>
- <div class="col-xs-4 controls" id="display_additive_effect">
+ <label style="text-align:left;" class="col-xs-12 control-label">Display Additive Effect</label>
+ <div class="col-xs-12 controls" id="display_additive_effect">
<label class="radio-inline">
<input type="radio" name="display_additive" id="display_additive" value="yes" checked="">
Yes
@@ -55,8 +57,8 @@
</div>
<div class="mapping_method_fields form-group">
- <label class="col-xs-2 control-label">Manhattan Plot</label>
- <div class="col-xs-4 controls">
+ <label style="text-align:left;" class="col-xs-12 control-label">Manhattan Plot</label>
+ <div class="col-xs-12 controls">
<label class="radio-inline">
<input type="radio" name="manhattan_plot_reaper" value="true">
Yes
@@ -67,16 +69,14 @@
</label>
</div>
</div>
- </div>
- <div class="form-group">
- <label for="interval_mapping_submit" class="col-xs-1 control-label"></label>
- <div style="margin-left:35px;" class="col-xs-4 controls">
- <button id="interval_mapping_compute" class="btn submit_special btn-primary" data-url="/interval_mapping" title="Compute Interval Mapping">
- <i class="icon-ok-circle icon-white"></i> Compute
- </button>
+ <div class="form-group">
+ <div style="padding-left:15px;" class="controls">
+ <button id="interval_mapping_compute" class="btn submit_special btn-primary" data-url="/interval_mapping" title="Compute Interval Mapping">
+ <i class="icon-ok-circle icon-white"></i> Open Mapping Tool
+ </button>
+ </div>
</div>
</div>
- <div id="alert_placeholder"></div>
</div>
<div class="tab-pane" id="pylmm">
@@ -119,8 +119,7 @@
</button>
</div>
</div>
- <div id="alert_placeholder"></div>
-
+
</div>
<div class="tab-pane" id="rqtl_geno">
@@ -167,7 +166,6 @@
</button>
</div>
</div>
- <div id="alert_placeholder"></div>
</div>
@@ -190,8 +188,6 @@
</button>
</div>
</div>
- <div id="alert_placeholder"></div>
-
</div>
<div class="tab-pane" id="gemma">
@@ -212,10 +208,23 @@
</button>
</div>
</div>
- <div id="alert_placeholder"></div>
-
</div>
{% endif %}
</div>
</div>
+ </div>
+ <div class="col-xs-6">
+ <dl>
+ <dt>Interval Mapping</dt>
+ <dd>Interval mapping is a process in which the statistical significance of a hypothetical QTL is evaluated at regular points across a chromosome, even in the absence of explicit genotype data at those points.</dd>
+ <dt>pyLMM</dt>
+ <dd>pyLMM is a fast and lightweight linear mixed-model (LMM) solver for use in genome-wide association studies (GWAS).</dd>
+ <dt>R/qtl</dt>
+ <dd>R/qtl is an extensible, interactive environment for mapping quantitative trait loci (QTL) in experimental crosses.</dd>
+ </dl>
+ </div>
+ <div id="alert_placeholder"></div>
+ <div id="mapping_result_holder_wrapper" style="display:none;">
+ <div id="mapping_result_holder"></div>
+ </div>
</div> \ No newline at end of file
diff --git a/wqflask/wqflask/templates/show_trait_statistics_new.html b/wqflask/wqflask/templates/show_trait_statistics_new.html
index 11f5ba68..9ce60c0b 100755
--- a/wqflask/wqflask/templates/show_trait_statistics_new.html
+++ b/wqflask/wqflask/templates/show_trait_statistics_new.html
@@ -78,10 +78,28 @@
<i class="icon-tint"></i> Color by Trait
</button>
</div>
- <div id="bar_chart_container">
+ </div>
+ <div class="row" style="height: 0px">
+ <div id="bar_chart_legend" style="margin-left: 900px; 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-right"></span>
+ </div>
+ </div>
+ <div style="margin-left: 20px; margin-right: 20px;" class="row" id="bar_chart_container">
<div id="bar_chart" class="barchart"></div>
</div>
- </div>
</div>
<div class="tab-pane" id="probability_plot">
<div id="probability_plot_container">