diff --git a/app/models/hivtrace.js b/app/models/hivtrace.js
index ad850121..74170628 100644
--- a/app/models/hivtrace.js
+++ b/app/models/hivtrace.js
@@ -107,6 +107,7 @@ var HivTrace = new Schema({
validate: [notEmptyValidator, "Ambiguity Handling field is empty"]
},
sequence_length: Number,
+ job_started : { type: Boolean, default:false },
status_stack: Array,
status: {
type: String
@@ -274,6 +275,7 @@ HivTrace.virtual("url").get(function() {
});
HivTrace.methods.saveAttributes = function(cb) {
+
var self = this;
// Once annotations are configured, save the mapped attributes so that we
@@ -288,16 +290,19 @@ HivTrace.methods.saveAttributes = function(cb) {
});
var patient_attributes = _.map(headers, function(d) {
+
var attrs = d.split(delimiter);
var key_val = _.object(annotations, attrs);
key_val["header"] = d;
return key_val;
+
});
// save attributes for each patient
self.patient_attributes = patient_attributes;
cb(null, self);
+
};
HivTrace.methods.addAttributesToResults = function(cb) {
@@ -306,6 +311,12 @@ HivTrace.methods.addAttributesToResults = function(cb) {
var attributes = self.patient_attributes;
var attr_keys = _.keys(attributes[0]);
+ var category_map = {
+ "categorical" : "String",
+ "individual" : "String",
+ "temporal" : "Date"
+ };
+
// transform attributes to be a dictionary
var attrs_by_id = _.object(
_.map(attributes, function(item) {
@@ -319,7 +330,7 @@ HivTrace.methods.addAttributesToResults = function(cb) {
return d.annotation;
}),
_.map(self.attributes, function(val, key) {
- new_dict = { type: val.category, label: val.annotation };
+ new_dict = { type: category_map[val.category], label: val.annotation };
return new_dict;
})
);
diff --git a/app/routes/hivtrace.js b/app/routes/hivtrace.js
index f6268258..31f6f60a 100644
--- a/app/routes/hivtrace.js
+++ b/app/routes/hivtrace.js
@@ -228,7 +228,9 @@ exports.jobPage = function(req, res) {
if (err || !hivtrace) {
res.json(500, error.errorResponse("hivtrace : " + id + " : missing id"));
} else {
- if (hivtrace.status === undefined) {
+
+ if (!hivtrace.job_started) {
+
var callback = function(err) {
if (err) {
logger.error(err);
@@ -237,7 +239,12 @@ exports.jobPage = function(req, res) {
}
};
- HivTrace.submitJob(hivtrace, callback);
+ hivtrace.job_started=true;
+
+ hivtrace.save((err, hivtrace) => {
+ HivTrace.submitJob(hivtrace, callback);
+ });
+
}
res.format({
@@ -442,6 +449,7 @@ exports.mapAttributes = function(req, res) {
};
exports.saveAttributes = function(req, res) {
+
var id = req.params.id;
var postdata = req.body;
diff --git a/app/templates/hivtrace/jobpage.ejs b/app/templates/hivtrace/jobpage.ejs
index b7c72b4d..8f26cb38 100644
--- a/app/templates/hivtrace/jobpage.ejs
+++ b/app/templates/hivtrace/jobpage.ejs
@@ -6,7 +6,7 @@
-
+
<% if (hivtrace.status == 'aborted') { %>
diff --git a/app/templates/hivtrace/results.ejs b/app/templates/hivtrace/results.ejs
index c384c14d..8ae233fd 100644
--- a/app/templates/hivtrace/results.ejs
+++ b/app/templates/hivtrace/results.ejs
@@ -58,6 +58,12 @@
+
+ Hide others
+
+
+ Show small clusters
+
@@ -68,9 +74,8 @@
-
-
-
+
+
Clusters are shown as circles with thick rims
@@ -88,7 +114,7 @@
+ aria-valuemin="0" aria-valuemax="100" style="width: 100%; height: 50px">
Loading the network
@@ -96,14 +122,6 @@
-
-
-
-
@@ -123,10 +141,6 @@
@@ -212,7 +226,6 @@
- Clusters
@@ -261,6 +274,10 @@
diff --git a/public/assets/css/datamonkey.css b/public/assets/css/datamonkey.css
index e1039fb8..c060b12c 100644
--- a/public/assets/css/datamonkey.css
+++ b/public/assets/css/datamonkey.css
@@ -669,3 +669,6 @@ a.hyphy-anchor {
display:none;
}
+#cluster_table td:first-child {
+ min-width:200px;
+}
diff --git a/src/entry.js b/src/entry.js
index 1fcf7426..f68b9878 100644
--- a/src/entry.js
+++ b/src/entry.js
@@ -24,6 +24,7 @@ var branch_selection = require('jsx/branch-selection.jsx');
var stats = require('jsx/stats.jsx');
var analysis_tree = require('jsx/analysis_tree.jsx');
var jobqueue = require('jsx/jobqueue.jsx');
+var render_attribute_modal = require('jsx/attribute_table.jsx');
window.gard_form = gard_form;
window.slac_form = slac_form;
@@ -34,3 +35,4 @@ window.hyphyVision = hyphyVision;
window.datamonkey_stats = stats;
window.datamonkey_analysis_tree = analysis_tree;
window.datamonkey_jobqueue = jobqueue;
+window.render_attribute_modal = render_attribute_modal;
diff --git a/src/jsx/attribute_table.jsx b/src/jsx/attribute_table.jsx
new file mode 100644
index 00000000..18ff4abb
--- /dev/null
+++ b/src/jsx/attribute_table.jsx
@@ -0,0 +1,106 @@
+var React = require("react"),
+ ReactDOM = require("react-dom");
+
+/*
+
+ Displays a modal on the HIV-TRACE results page when the user clicks "View" under the Attributes column
+ The modal displays a table of attributes associated with the node
+
+ In order to update the modal, a custom event, "view-attributes", needs to be triggered on the shiv-attribute-modal div.
+ The object associated with it will be a dictionary with keys and its respective values.
+
+*/
+var AttributeModal = React.createClass({
+
+ getInitialState: function() {
+ return { attr : {} };
+ },
+
+ displayModal : function(attributes) {
+ this.setState( { attr : attributes } );
+ $('#shiv-attribute-modal').modal();
+ },
+
+ componentDidMount: function() {
+
+ var self = this;
+
+ // append to passed container
+ $( "#shiv-attribute-modal" ).on( "view-attributes", function( event, attributes ) {
+ self.displayModal(attributes);
+ });
+
+ },
+
+ attributeRow : function(val) {
+ return (
+
+ {val[0]} |
+ {val[1]} |
+
+ );
+ },
+
+ attributeTable : function() {
+
+ var self = this;
+
+ // filter out _id from attributes
+ var attr = _.omit(self.state.attr, '_id');
+
+ // transform to tuples and sort by key
+ var attr_tuple = _.sortBy(_.map(attr, function(v,k) { return [k,v]}), function(d) { return d[0] });
+
+ var attributeRows = _.map(attr_tuple, self.attributeRow);
+
+ return (
+
+
+ Name |
+ Value |
+
+ {attributeRows}
+
+ )
+
+ },
+
+ render : function() {
+
+ var self = this;
+ var attributeTable = self.attributeTable();
+
+ return (
+
+
+
+
+
+
Patient Attributes
+
+
+
+ {attributeTable}
+
+
+
+
+
+
+
+
+
+ )
+
+ }
+
+});
+
+function render_attribute_modal() {
+ ReactDOM.render(
+ , document.getElementById("shiv-node-tab-attribute-modal")
+ );
+}
+
+
+module.exports = render_attribute_modal;