Skip to content

Commit

Permalink
Inline /contigs and /spec calls
Browse files Browse the repository at this point in the history
  • Loading branch information
danvk committed Dec 3, 2014
1 parent c058b1c commit 81e6325
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 68 deletions.
51 changes: 17 additions & 34 deletions cycledash/static/js/examine/RecordStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ var ENTIRE_GENOME = {start: null, end: null, contig: types.ALL_CHROMOSOMES};

// opt_testDataSource is provided for testing.
// Its type is function(url, done_callback).
function createRecordStore(vcfId, dispatcher, opt_testDataSource) {
function createRecordStore(run, dispatcher, opt_testDataSource) {
// Initial state of the store. This is mutable. There be monsters.
var hasLoaded = false,
var vcfId = run.id,
hasLoaded = false,
loadError = null,

records = [],
Expand All @@ -41,8 +42,8 @@ function createRecordStore(vcfId, dispatcher, opt_testDataSource) {
sortBys = DEFAULT_SORT_BYS,
range = ENTIRE_GENOME,

contigs = [],
columns = {};
contigs = run.contigs,
columns = run.spec;

// State for paging the server for records. Page should be reset to 0 on most
// operations.
Expand Down Expand Up @@ -120,6 +121,7 @@ function createRecordStore(vcfId, dispatcher, opt_testDataSource) {

$.when(deferredGenotypes(vcfId, query))
.done(response => {
hasLoaded = true;
if (append) {
// TODO: BUG: This can result in a out-of-order records, if a later
// XHR returns before an earlier XHR.
Expand Down Expand Up @@ -219,42 +221,23 @@ function createRecordStore(vcfId, dispatcher, opt_testDataSource) {
range = query.range || ENTIRE_GENOME;
}

// Initialize the RecordStore with basic information (columns, the contigs
// in the VCF), and request first records to display.
$.when(deferredSpec(vcfId), deferredContigs(vcfId))
.done((columnsResponse, contigsResponse) => {
hasLoaded = true;
columns = columnsResponse.spec;
contigs = contigsResponse.contigs;

var existingQuery = getQueryStringValue('query');
if (existingQuery) {
try {
var jsonQuery = JSON.parse(existingQuery);
setQuery(jsonQuery);
} catch (e) {
// query is invalid
}
}
var existingQuery = getQueryStringValue('query');
if (existingQuery) {
try {
var jsonQuery = JSON.parse(existingQuery);
setQuery(jsonQuery);
} catch (e) {
// query is invalid
}
}

// no need to debounce this update -- make it so now!
_updateGenotypes({append: false});
});
// no need to debounce this update -- make it so now!

This comment has been minimized.

Copy link
@ihodes

ihodes Dec 3, 2014

Member

nit: should be capitalized

This comment has been minimized.

Copy link
@danvk

danvk Dec 3, 2014

Author Contributor

I usually only capitalize complete sentences. I'm not sure if this is google style guide compatible or just me.

Either way, I made this a complete sentence and capitalized the first letter.

This comment has been minimized.

Copy link
@ihodes

ihodes Dec 3, 2014

Member

I was just peaking at the lab's style guide today, and it notes that comments should be grammatical. I don't think it's a big deal either way.

_updateGenotypes({append: false});

function notifyChange() {
_.each(listenerCallbacks, cb => { cb(); });
}

// Return deferred GET for the column spec for a given VCF.
function deferredSpec(vcfId) {
return callbackToPromise(dataSource, '/runs/' + vcfId + '/spec');
}

// Return deferred GET for the contigs in a given VCF.
function deferredContigs(vcfId) {
return callbackToPromise(dataSource, '/runs/' + vcfId + '/contigs');
}

// Return a deferred GET returning genotypes and stats.
function deferredGenotypes(vcfId, query) {
var queryString = encodeURIComponent(JSON.stringify(query));
Expand Down
8 changes: 3 additions & 5 deletions cycledash/static/js/examine/components/QueryBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,10 @@ var QueryBox = React.createClass({
this.props.handleQueryChange(parsedQuery);
}
},
componentDidMount: function(prevProps, prevState) {
this.initQueryBox();
},
componentDidUpdate: function(prevProps, prevState) {
// Watch for the first update with a populated set of columns.
if (_.isEmpty(prevProps.columns) && !_.isEmpty(this.props.columns)) {
this.initQueryBox();
}

if (prevProps.query != this.props.query) {
this.setQueryBoxToQuery();
}
Expand Down
2 changes: 1 addition & 1 deletion cycledash/static/js/examine/examine.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ var React = require('react'),
window.renderExaminePage = function(el, run, igvHttpfsUrl) {
var dispatcher = new Dispatcher();
var recordActions = getRecordActions(dispatcher);
var recordStore = createRecordStore(run.id, dispatcher);
var recordStore = createRecordStore(run, dispatcher);
React.render(<ExaminePage recordStore={recordStore}
recordActions={recordActions}
run={run}
Expand Down
15 changes: 4 additions & 11 deletions cycledash/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,15 @@ def genotypes(run_id):
return jsonify(gt.get(run_id, json.loads(request.args.get('q'))))


@app.route('/runs/<run_id>/spec')
def examine_spec(run_id):
return jsonify({'spec': gt.spec(run_id)})


@app.route('/runs/<run_id>/contigs')
def contigs(run_id):
return jsonify({'contigs': gt.contigs(run_id)})


@app.route('/runs/<run_id>/examine')
def examine(run_id):
with db.engine.connect() as con:
select_vcf_sql = 'select * from vcfs where id = {};'.format(run_id)
vcf = dict(con.execute(select_vcf_sql).fetchall()[0])
return render_template('examine.html', run=dict(vcf))
run = dict(vcf)
run['spec'] = gt.spec(run_id)
run['contigs'] = gt.contigs(run_id)
return render_template('examine.html', run=run)


@app.route('/runs/<run_ids_key>/concordance', methods=['GET', 'PUT'])
Expand Down
4 changes: 2 additions & 2 deletions tests/js/DataUtils-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ var dataUtils = require('./DataUtils'),
vcf = require('vcf.js'),
_ = require('underscore');

describe('test data', function() {
describe('DataUtils', function() {
var vcfData;
before(function() {
var parseVcf = vcf.parser(); // Note: the real deal, not a fake!
Expand All @@ -19,7 +19,7 @@ describe('test data', function() {
});

it('should generate a column spec', function() {
var spec = dataUtils.getSpec(vcfData).spec;
var spec = dataUtils.getSpec(vcfData);
assert.deepEqual(['INFO', 'SAMPLE'], _.keys(spec));
assert.deepEqual(['DP','SOMATIC','SS','SSC','GPV','SPV'], _.keys(spec.INFO));
assert.deepEqual(['GT','GQ','DP','RD','AD','FREQ','DP4'], _.keys(spec.SAMPLE));
Expand Down
12 changes: 4 additions & 8 deletions tests/js/DataUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ function getSpec(vcfData) {

// TODO: add sample_name

return {spec: cols};
return cols;
}

function getContigs(vcfData) {
return _.uniq(vcfData.records.map(rec => rec.CHROM));
}

function getRecords(vcfData) {
var spec = getSpec(vcfData).spec;
var spec = getSpec(vcfData);
return _.flatten(vcfData.records.map((record) => {
var baseProps = {
contig: record.CHROM,
Expand Down Expand Up @@ -81,11 +81,7 @@ function makeFakeServer(vcfPath) {

var genotypesUrl = '/runs/1/genotypes';
var get = function(path, callback) {
if (path == '/runs/1/spec') {
callback(spec);
} else if (path == '/runs/1/contigs') {
callback({contigs: contigs});
} else if (path.slice(0, genotypesUrl.length) == genotypesUrl) {
if (path.slice(0, genotypesUrl.length) == genotypesUrl) {
callback({
records: records,
stats: {
Expand All @@ -94,7 +90,7 @@ function makeFakeServer(vcfPath) {
}
});
} else {
throw new Error('Unexpected request');
throw new Error('Unexpected request for ' + path);
}
};

Expand Down
9 changes: 6 additions & 3 deletions tests/js/ExaminePage-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,19 @@ describe('ExaminePage', function() {
});

it('should display and select records', function() {
var dispatcher = new Dispatcher();
var recordActions = RecordActions.getRecordActions(dispatcher);
var recordStore = createRecordStore(1, dispatcher, fakeServer);
var run = {
id: 1,
spec: fakeServer.spec,
contigs: fakeServer.contigs,
caller_name: 'test',
dataset_name: 'test',
created_at: '',
uri: '/tests/js/data/snv.vcf'
};

var dispatcher = new Dispatcher();
var recordActions = RecordActions.getRecordActions(dispatcher);
var recordStore = createRecordStore(run, dispatcher, fakeServer);
var examine = TestUtils.renderIntoDocument(
<ExaminePage recordStore={recordStore}
recordActions={recordActions}
Expand Down
6 changes: 2 additions & 4 deletions tests/js/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,13 @@ function findInComponent(selector, component) {
return _.toArray(component.getDOMNode().querySelectorAll(selector));
}


/**
* Stub out a React class method using Sinon.
* Stub out a React class method with the given function using Sinon.
* Returns the Sinon stub. Don't forget to call .restore() on it!
*/
function stubReactMethod(ReactClass, method, fn) {
return sinon.stub(ReactClass.type.prototype.__reactAutoBindMap, method, fn);
};

}

function makeObj(list, keyValFn) {
return _.object(list.map(keyValFn));
Expand Down

0 comments on commit 81e6325

Please sign in to comment.