ucsc-xena-client
Version:
UCSC Xena Client. Functional genomics visualizations.
189 lines (170 loc) • 7.51 kB
JavaScript
;
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _ = require('../underscore_ext');
var Rx = require('../rx');
var _require = require('./errors'),
reifyErrors = _require.reifyErrors,
collectResults = _require.collectResults;
var _require2 = require('./common'),
resetZoom = _require2.resetZoom,
fetchColumnData = _require2.fetchColumnData,
fetchCohortData = _require2.fetchCohortData,
setCohort = _require2.setCohort,
fetchColumnData = _require2.fetchColumnData,
updateWizard = _require2.updateWizard,
clearWizardCohort = _require2.clearWizardCohort;
var xenaQuery = require('../xenaQuery');
var allFieldMetadata = xenaQuery.allFieldMetadata;
var _require3 = require('./utils'),
compose = _require3.compose,
make = _require3.make,
mount = _require3.mount;
var phenoPat = /^phenotypes?$/i;
function featuresQuery(datasets) {
var clinicalMatrices = _.filter(datasets, function (ds) {
return ds.type === 'clinicalMatrix' && (!ds.dataSubType || ds.dataSubType.match(phenoPat));
}),
dsIDs = _.pluck(clinicalMatrices, 'dsID');
// XXX note that datasetFeatures takes optional args, so don't pass it directly
// to map.
return Rx.Observable.zipArray(_.map(dsIDs, function (dsID) {
return reifyErrors(allFieldMetadata(dsID), { dsID: dsID });
})).flatMap(function (resps) {
return collectResults(resps, function (features) {
return _.object(dsIDs, features);
});
});
}
function fetchFeatures(serverBus, datasets) {
serverBus.next(['features', featuresQuery(datasets)]);
}
var columnOpen = function columnOpen(state, id) {
return _.has(_.get(state, 'columns'), id);
};
var resetLoadPending = function resetLoadPending(state) {
return _.dissoc(state, 'loadPending');
};
// Cohort metadata looks like
// {[cohort]: [tag, tag, ...], [cohort]: [tag, tag, ...], ...}
// We want data like
// {[tag]: [cohort, cohort, ...], [tag]: [cohort, cohort, ...], ...}
function invertCohortMeta(meta) {
return _.fmap(_.groupBy(_.flatmap(meta, function (tags, cohort) {
return tags.map(function (tag) {
return [cohort, tag];
});
}), function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
tag = _ref2[1];
return tag;
}), function (cohortTags) {
return cohortTags.map(function (_ref3) {
var _ref4 = _slicedToArray(_ref3, 1),
cohort = _ref4[0];
return cohort;
});
});
}
var wizardControls = {
cohorts: function cohorts(state, _cohorts) {
return _.assoc(state, "cohorts", _cohorts);
},
datasets: function datasets(state, _datasets) {
return _.assoc(state, 'datasets', _datasets);
},
'datasets-post!': function datasetsPost(serverBus, state, newState, datasets) {
return fetchFeatures(serverBus, datasets);
},
features: function features(state, _features) {
return _.assoc(state, 'features', _features);
},
cohortMeta: function cohortMeta(state, meta) {
return _.assoc(state, 'cohortMeta', invertCohortMeta(meta));
},
cohortPreferred: function cohortPreferred(state, _cohortPreferred) {
return _.assoc(state, 'cohortPreferred', _.fmap(_cohortPreferred, function (preferred) {
return _.fmap(preferred, function (_ref5) {
var host = _ref5.host,
dataset = _ref5.dataset;
return JSON.stringify({ host: host, name: dataset });
});
}));
},
cohortPhenotype: function cohortPhenotype(state, _cohortPhenotype) {
return _.assoc(state, 'cohortPhenotype', _.fmap(_cohortPhenotype, function (preferred) {
return _.map(preferred, function (_ref6) {
var host = _ref6.host,
dataset = _ref6.dataset,
feature = _ref6.feature;
return { dsID: JSON.stringify({ host: host, name: dataset }), name: feature };
});
}));
}
};
var controls = {
bookmark: function bookmark(state, _bookmark) {
return clearWizardCohort(resetLoadPending(_.merge(state, _bookmark)));
},
'bookmark-error': function bookmarkError(state) {
return resetLoadPending(_.assoc(state, 'stateError', 'bookmark'));
},
// Here we need to load cohort data if servers or cohort has changed,
// *or* if we never loaded cohort data (e.g. due to waiting on bookmark).
'bookmark-post!': function bookmarkPost(serverBus, state, newState) {
updateWizard(serverBus, state.spreadsheet, newState.spreadsheet, { force: !_.getIn(newState, ['wizard', 'cohorts']) });
},
'manifest': function manifest(state, _ref7) {
var cohort = _ref7.cohort,
samples = _ref7.samples;
return clearWizardCohort(_.updateIn(state, ['spreadsheet'], setCohort({ name: cohort, sampleFilter: samples }, null)));
},
'manifest-post!': function manifestPost(serverBus, state, newState) {
return fetchCohortData(serverBus, newState.spreadsheet);
},
inlineState: function inlineState(state, newState) {
return resetLoadPending(newState);
},
'inlineState-post!': function inlineStatePost(serverBus, state, newState) {
updateWizard(serverBus, state.spreadsheet, newState.spreadsheet, { force: !_.getIn(newState, ['wizard', 'cohorts']) });
}
};
var spreadsheetControls = {
samples: function samples(state, _ref8) {
var _samples = _ref8.samples,
over = _ref8.over,
hasPrivateSamples = _ref8.hasPrivateSamples;
var newState = resetZoom(_.assoc(state, 'cohortSamples', _samples, 'samplesOver', over, 'hasPrivateSamples', hasPrivateSamples)),
columnOrder = newState.columnOrder;
return _.reduce(columnOrder, function (acc, id) {
return _.assocIn(acc, ['data', id, 'status'], 'loading');
}, newState);
},
'samples-post!': function samplesPost(serverBus, state, newState, _ref9) {
var samples = _ref9.samples;
return _.mapObject(_.get(newState, 'columns', {}), function (settings, id) {
return fetchColumnData(serverBus, samples, id, settings);
});
},
// XXX Here we drop the update if the column is no longer open.
'widget-data': function widgetData(state, id, data) {
return columnOpen(state, id) ? _.assocIn(state, ["data", id], _.assoc(data, 'status', 'loaded')) : state;
},
'widget-data-error': function widgetDataError(state, id) {
return columnOpen(state, id) ? _.assocIn(state, ["data", id, 'status'], 'error') : state;
},
'columnEdit-features': function columnEditFeatures(state, list) {
return _.assocIn(state, ["columnEdit", 'features'], list);
},
'columnEdit-examples': function columnEditExamples(state, list) {
return _.assocIn(state, ["columnEdit", 'examples'], list);
},
'km-survival-data': function kmSurvivalData(state, survival) {
return _.assoc(state, 'survival', survival);
},
// XXX Here we should be updating application state. Instead we invoke a callback, because
// chart.js can't handle passed-in state updates.
'chart-average-data-post!': function chartAverageDataPost(serverBus, state, newState, offsets, thunk) {
return thunk(offsets);
}
};
module.exports = compose(make(controls), mount(make(wizardControls), ['wizard']), mount(make(spreadsheetControls), ['spreadsheet']));