ucsc-xena-client
Version:
UCSC Xena Client. Functional genomics visualizations.
1,187 lines (1,002 loc) • 36.7 kB
JavaScript
'use strict';
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 _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _link = require('react-toolbox/lib/link');
var _link2 = _interopRequireDefault(_link);
var _checkbox = require('react-toolbox/lib/checkbox');
var _button = require('react-toolbox/lib/button');
var _dialog = require('react-toolbox/lib/dialog');
var _dialog2 = _interopRequireDefault(_dialog);
var _reactCssThemr = require('react-css-themr');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
require('./base');
var React = require('react');
var _require = require('./underscore_ext'),
uniq = _require.uniq,
flatten = _require.flatten,
sortBy = _require.sortBy,
groupBy = _require.groupBy,
map = _require.map,
flatmap = _require.flatmap,
partitionN = _require.partitionN,
mapObject = _require.mapObject,
pluck = _require.pluck,
concat = _require.concat,
where = _require.where,
contains = _require.contains,
get = _require.get,
updateIn = _require.updateIn,
range = _require.range,
Let = _require.Let,
zip = _require.zip,
identity = _require.identity,
getIn = _require.getIn,
sum = _require.sum,
keys = _require.keys,
values = _require.values,
mmap = _require.mmap;
var _require2 = require('./rx'),
from = _require2.Observable.from,
animationFrame = _require2.Scheduler.animationFrame;
var _require3 = require('./xenaQuery'),
parseDsID = _require3.parseDsID;
var styles = require('./Datapages.module.css');
var nav = require('./nav');
var showdown = require('showdown');
var _require4 = require('./dom_helper'),
stripHTML = _require4.stripHTML;
var treehouseImg = require('../images/Treehouse.jpg');
var _require5 = require('./react-utils'),
rxEvents = _require5.rxEvents;
var _require6 = require('./defaultServers'),
localHub = _require6.servers.localHub,
serverNames = _require6.serverNames;
var _require7 = require('./util'),
encodeObject = _require7.encodeObject,
urlParams = _require7.urlParams;
var appTheme = require('./appTheme');
var _require8 = require('./hubParams'),
getHubParams = _require8.getHubParams;
var getHubName = function getHubName(host) {
return get(serverNames, host, host);
};
var pluralize = function pluralize(str, count) {
return count === 1 ? '1 ' + str : count + ' ' + str + 's';
};
// Get params from the anchor href. With RT Link, the anchor is parentElement.
var paramFromHref = function paramFromHref(ev) {
return mapObject(urlParams(ev.target.parentElement.href), function (a) {
return a[0];
});
};
//
// event handler for navigating within datapages. Prevents page load, and
// sets url params.
//
function navHandler(ev) {
ev.preventDefault();
this.props.callback(['navigate', 'datapages', paramFromHref(ev, this.props.state)]);
}
var getUserServers = function getUserServers(servers) {
return keys(servers).filter(function (k) {
return servers[k].user;
});
};
//
// Data hubs sidebar
//
var hubLink = function hubLink(host, onClick, hubParams) {
return React.createElement(_link2.default, {
className: styles.link,
href: '?' + encodeObject(_extends({ host: host }, hubParams)),
label: getHubName(host),
onClick: onClick });
};
var DataHubs = function (_React$Component) {
_inherits(DataHubs, _React$Component);
function DataHubs() {
var _ref;
var _temp, _this, _ret;
_classCallCheck(this, DataHubs);
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = DataHubs.__proto__ || Object.getPrototypeOf(DataHubs)).call.apply(_ref, [this].concat(args))), _this), _this.onHub = function (ev) {
navHandler.call(_this, ev);
}, _this.onSelect = function (isOn, ev) {
var checked = ev.target.checked,
host = ev.target.getAttribute('data-host');
_this.props.callback([checked ? 'enable-host' : 'disable-host', host, 'user']);
}, _temp), _possibleConstructorReturn(_this, _ret);
}
_createClass(DataHubs, [{
key: 'render',
value: function render() {
var _this2 = this;
var _props = this.props,
hubParams = _props.hubParams,
servers = _props.state.spreadsheet.servers;
return React.createElement(
'div',
{ className: styles.dataHubs },
React.createElement(
'h2',
null,
'Active Data Hubs'
),
React.createElement(
'ul',
null,
map(servers, function (_ref2, host) {
var user = _ref2.user;
return React.createElement(
'li',
{ key: host },
React.createElement(_checkbox.Checkbox, {
label: hubLink(host, _this2.onHub, hubParams),
onChange: _this2.onSelect,
checked: user,
'data-host': host })
);
})
)
);
}
}]);
return DataHubs;
}(React.Component);
//
// Cohort Summary Page
//
var treehouse = function treehouse(cohort) {
return cohort.search(/^Treehouse/gi) === -1 ? null : React.createElement('img', { src: treehouseImg, height: '40px' });
};
var cohortLink = function cohortLink(cohort, onClick, hubParams) {
return React.createElement(_link2.default, {
className: styles.link,
href: '?' + encodeObject(_extends({ cohort: cohort }, hubParams)),
label: cohort,
onClick: onClick });
};
var collateCohorts = function collateCohorts(hubCohorts) {
return concat.apply(undefined, _toConsumableArray(pluck(hubCohorts, 'cohorts'))).reduce(function (acc, cohort) {
return updateIn(acc, [cohort.cohort], function () {
var v = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
return cohort.count + v;
});
}, {});
};
var CohortSummary = function CohortSummary(_ref3) {
var cohorts = _ref3.cohorts,
onCohort = _ref3.onCohort,
hubParams = _ref3.hubParams;
var names = sortBy(keys(cohorts), function (c) {
return c.toLowerCase();
}),
nCohorts = names.length,
nDatasets = sum(values(cohorts));
return React.createElement(
'div',
null,
React.createElement(
'h2',
null,
pluralize('Cohort', nCohorts),
', ',
pluralize('Dataset', nDatasets)
),
React.createElement(
'ul',
{ className: styles.list },
map(names, function (name) {
return React.createElement(
'li',
{ key: name },
treehouse(name),
cohortLink(name, onCohort, hubParams),
' (' + pluralize('dataset', cohorts[name]) + ')'
);
})
)
);
};
var CohortSummaryPage = function (_React$Component2) {
_inherits(CohortSummaryPage, _React$Component2);
function CohortSummaryPage() {
var _ref4;
var _temp2, _this3, _ret2;
_classCallCheck(this, CohortSummaryPage);
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return _ret2 = (_temp2 = (_this3 = _possibleConstructorReturn(this, (_ref4 = CohortSummaryPage.__proto__ || Object.getPrototypeOf(CohortSummaryPage)).call.apply(_ref4, [this].concat(args))), _this3), _this3.onCohort = function (ev) {
navHandler.call(_this3, ev);
}, _temp2), _possibleConstructorReturn(_this3, _ret2);
}
_createClass(CohortSummaryPage, [{
key: 'render',
value: function render() {
var _props2 = this.props,
hubParams = _props2.hubParams,
state = _props2.state,
servers = state.spreadsheet.servers,
userServers = getUserServers(servers),
cohorts = getIn(this.props.state, ['datapages', 'cohorts'], []),
activeCohorts = cohorts.filter(function (c) {
return contains(userServers, c.server);
}),
combined = collateCohorts(activeCohorts);
return React.createElement(
'div',
{ className: styles.datapages },
React.createElement(DataHubs, this.props),
React.createElement(CohortSummary, { hubParams: hubParams, cohorts: combined, onCohort: this.onCohort })
);
}
}]);
return CohortSummaryPage;
}(React.Component);
//
// Dataset delete button
//
var DeleteButton = function (_React$Component3) {
_inherits(DeleteButton, _React$Component3);
function DeleteButton() {
var _ref5;
var _temp3, _this4, _ret3;
_classCallCheck(this, DeleteButton);
for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
return _ret3 = (_temp3 = (_this4 = _possibleConstructorReturn(this, (_ref5 = DeleteButton.__proto__ || Object.getPrototypeOf(DeleteButton)).call.apply(_ref5, [this].concat(args))), _this4), _this4.state = { active: false }, _this4.onDelete = function () {
_this4.setState({ active: !_this4.state.active });
}, _this4.onReally = function () {
var name = _this4.props.name;
_this4.props.callback(['navigate', 'datapages', { host: localHub }]);
_this4.props.callback(['delete-dataset', localHub, name]);
}, _this4.actions = function () {
return [{ label: 'Cancel', onClick: _this4.onDelete }, { label: 'Really Delete', onClick: _this4.onReally }];
}, _temp3), _possibleConstructorReturn(_this4, _ret3);
}
_createClass(DeleteButton, [{
key: 'render',
value: function render() {
var active = this.state.active,
label = this.props.label;
return React.createElement(
'div',
{ className: styles.deleteButton },
React.createElement(
_dialog2.default,
{ actions: this.actions(), active: active,
onEscKeyDown: this.onDelete, onOverlayClick: this.onDelete,
title: 'Delete dataset' },
label
),
React.createElement(
_button.Button,
{ onClick: this.onDelete, accent: true },
'Delete'
)
);
}
}]);
return DeleteButton;
}(React.Component);
var canDelete = function canDelete(_ref6, host) {
var status = _ref6.status;
return host === localHub && contains(['loaded', 'error'], status);
};
var markdownValue = function markdownValue(value) {
if (value) {
var converter = new showdown.Converter();
return React.createElement('div', { className: styles.header,
dangerouslySetInnerHTML: { __html: converter.makeHtml(value) } });
}
};
//
// Cohort Datasets Page
//
var datasetLink = function datasetLink(callback, preferred, onClick, hubParams) {
return function (ds) {
var _parseDsID = parseDsID(ds.dsID),
_parseDsID2 = _slicedToArray(_parseDsID, 1),
host = _parseDsID2[0];
return React.createElement(
'li',
{ key: ds.name },
React.createElement(_link2.default, {
className: styles.link,
href: '?' + encodeObject(_extends({ dataset: ds.name, host: host }, hubParams)),
label: ds.label,
onClick: onClick }),
preferred.has(ds.dsID) ? React.createElement(
'span',
{ className: styles.star },
'*'
) : null,
ds.status !== 'loaded' ? React.createElement(
'span',
{ className: styles.count },
' [',
ds.status,
']'
) : null,
ds.status === 'loaded' ? React.createElement(
'span',
{ className: styles.count },
' (n=',
(ds.count || 0).toLocaleString(),
')'
) : null,
React.createElement(
'span',
null,
' ',
getHubName(host)
),
canDelete(ds, host) ? React.createElement(DeleteButton, { callback: callback, name: ds.name, label: ds.label || ds.name }) : null,
React.createElement(
'div',
{ className: styles.lineClamp },
React.createElement(
'span',
{ className: styles.description },
stripHTML(ds.description)
)
)
);
};
};
var drawGroup = function drawGroup(callback, groups, preferred, onClick, hubParams) {
return function (dataSubType) {
var list = sortBy(groups[dataSubType], function (g) {
return g.label.toLowerCase();
});
return React.createElement(
'div',
{ key: dataSubType },
React.createElement(
'h3',
null,
dataSubType
),
React.createElement(
'ul',
{ className: styles.groupList },
map(list, datasetLink(callback, preferred, onClick, hubParams))
)
);
};
};
var COHORT_NULL = '(unassigned)';
var getPreferred = function getPreferred(wizard, cohort) {
return new Set(values(getIn(wizard, ['cohortPreferred', cohort], {})));
};
var CohortPage = function (_React$Component4) {
_inherits(CohortPage, _React$Component4);
function CohortPage() {
var _ref7;
var _temp4, _this5, _ret4;
_classCallCheck(this, CohortPage);
for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
args[_key4] = arguments[_key4];
}
return _ret4 = (_temp4 = (_this5 = _possibleConstructorReturn(this, (_ref7 = CohortPage.__proto__ || Object.getPrototypeOf(CohortPage)).call.apply(_ref7, [this].concat(args))), _this5), _this5.onViz = function () {
var _this5$props$state = _this5.props.state,
datapages = _this5$props$state.datapages,
currentCohort = _this5$props$state.spreadsheet.cohort,
cohort = getIn(datapages, ['cohort', 'cohort'], COHORT_NULL);
if (cohort !== get(currentCohort, 'name')) {
_this5.props.callback(['cohort', cohort]);
}
_this5.props.callback(['navigate', 'heatmap']);
}, _this5.onDataset = function (ev) {
navHandler.call(_this5, ev);
}, _temp4), _possibleConstructorReturn(_this5, _ret4);
}
_createClass(CohortPage, [{
key: 'render',
value: function render() {
var _props3 = this.props,
hubParams = _props3.hubParams,
_props3$state = _props3.state,
datapages = _props3$state.datapages,
params = _props3$state.params,
wizard = _props3$state.wizard,
cohort = getIn(datapages, ['cohort', 'cohort']) === params.cohort ? datapages.cohort : { cohort: '...', datasets: [] },
callback = this.props.callback,
dsGroups = groupBy(values(cohort.datasets), 'dataSubType'),
dataSubTypes = sortBy(keys(dsGroups), function (g) {
return g.toLowerCase();
}),
preferred = getPreferred(wizard, params.cohort);
return React.createElement(
'div',
{ className: styles.datapages },
markdownValue(cohort.meta),
React.createElement(
'div',
{ className: styles.sidebar },
React.createElement(
_button.Button,
{ onClick: this.onViz, accent: true },
'Visualize'
)
),
React.createElement(
'h2',
null,
'cohort: ',
treehouse(cohort.cohort),
cohort.cohort
),
dataSubTypes.map(drawGroup(callback, dsGroups, preferred, this.onDataset, hubParams)),
preferred.size === 0 ? null : React.createElement(
'span',
null,
React.createElement(
'span',
{ className: styles.star },
'*'
),
React.createElement(
'span',
null,
'default dataset in visualization'
)
)
);
}
}]);
return CohortPage;
}(React.Component);
//
// Dataset Page
//
var TYPE_NULL = 'genomicMatrix',
FORMAT_MAPPING = {
'clinicalMatrix': "ROWs (samples) x COLUMNs (identifiers) (i.e. clinicalMatrix)",
'genomicMatrix': "ROWs (identifiers) x COLUMNs (samples) (i.e. genomicMatrix)",
'mutationVector': "Variant by Position (i.e. mutationVector)",
'genomicSegment': 'Genomic Segment (i.e. genomicSegment)',
'unknown': "unknown"
};
var dataPair = function dataPair(key, value) {
var method = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : identity;
return value == null ? [] : [React.createElement(
'span',
{ className: styles.key },
key
), React.createElement(
'span',
{ className: styles.value },
method(value)
), React.createElement('br', null)];
};
var toLink = function toLink(value) {
return React.createElement(
'a',
{ href: value },
value
);
};
var toCohortLink = function toCohortLink(onClick, hubParams) {
return function (cohort) {
return React.createElement(_link2.default, {
href: '?' + encodeObject(_extends({ cohort: cohort }, hubParams)),
onClick: onClick,
label: cohort });
};
};
var toPMIDLink = function toPMIDLink(value) {
return React.createElement(
'a',
{ href: 'http://www.ncbi.nlm.nih.gov/pubmed/?term=' + value.toString() },
value
);
};
var jsonLink = function jsonLink(link) {
return link.replace(/(.gz)?$/, '.json');
};
var toDownloadLink = function toDownloadLink(value) {
return React.createElement(
'span',
null,
React.createElement(
'a',
{ href: value },
value
),
'; ',
React.createElement(
'a',
{ href: jsonLink(value) },
'Full metadata'
)
);
};
var toHTML = function toHTML(value) {
return React.createElement('span', { dangerouslySetInnerHTML: { __html: value } });
};
var headerValue = function headerValue(value) {
return value && React.createElement(
'p',
{ className: styles.header },
value
);
};
var htmlValue = function htmlValue(value) {
return value && React.createElement('p', { className: styles.header, dangerouslySetInnerHTML: { __html: value } });
};
// XXX Does not display load warning in pop-up
// XXX Does not use red/blue coloring for error vs. other load status (e.g. 'loading')
var getStatus = function getStatus(status, loaderWarning) {
return status === 'loaded' && !loaderWarning ? [] : status === 'loaded' ? dataPair('status', 'loaded with warning') : dataPair('status', status);
};
// split, handling falsey values
var split = function split(str, pat) {
return str ? str.split(pat) : [];
};
var resolveCodes = function resolveCodes(probes, codes, data) {
return mmap(probes, data, function (probe, row) {
return codes[probe] ? map(row, function (v) {
return isNaN(v) ? v : codes[probe][v];
}) : row;
});
};
// not the most efficient algorithm :-/
var addHeaders = function addHeaders(fields, samples, data) {
return mmap([''].concat(_toConsumableArray(fields)), [samples].concat(_toConsumableArray(data)), function (header, row) {
return [header].concat(_toConsumableArray(row));
});
};
var transpose = function transpose(data) {
return zip.apply(null, data);
};
// Transpose matrix if it's clinical
var transposeClinical = function transposeClinical(meta, data) {
return get(meta, 'type') === 'clinicalMatrix' ? transpose(data) : data;
};
var table = function table(data) {
return React.createElement(
'table',
{ className: styles.dataSnippetTable },
React.createElement(
'tbody',
null,
map(data, function (row, i) {
return React.createElement(
'tr',
{ key: i },
map(row, function (c, j) {
return React.createElement(
'td',
{ key: j },
c
);
})
);
})
)
);
};
var matrixTable = function matrixTable(meta, _ref8) {
var fields = _ref8.fields,
samples = _ref8.samples,
codes = _ref8.codes,
data = _ref8.data;
return table(transposeClinical(meta, addHeaders(fields, samples, resolveCodes(fields, codes, data))));
};
// swap chromend & chromstart when sorting fields
var cmpSparseFields = function cmpSparseFields(a, b) {
return a === 'chromend' && b === 'chromstart' ? 1 : a === 'chromstart' && b === 'chromend' ? -1 : a.localeCompare(b);
};
var sparseTable = function sparseTable(meta, data) {
var fields = keys(data).sort(cmpSparseFields),
rows = fields.map(function (field) {
return data[field];
}),
samples = data.sampleID;
return table(transpose(addHeaders(fields, samples, rows)));
};
var noTable = function noTable() {
return null;
};
var dataMethod = function dataMethod() {
var _ref9 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref9$type = _ref9.type,
type = _ref9$type === undefined ? 'genomicMatrix' : _ref9$type,
status = _ref9.status;
return status !== 'loaded' ? noTable : type === 'genomicMatrix' ? matrixTable : type === 'clinicalMatrix' ? matrixTable : type === 'mutationVector' ? sparseTable : type === 'genomicSegment' ? sparseTable : noTable;
};
var setKey = function setKey(arr) {
return arr.map(function (el, i) {
return React.cloneElement(el, { key: i });
});
};
var DatasetPage = function (_React$Component5) {
_inherits(DatasetPage, _React$Component5);
function DatasetPage() {
var _ref10;
var _temp5, _this6, _ret5;
_classCallCheck(this, DatasetPage);
for (var _len5 = arguments.length, args = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
args[_key5] = arguments[_key5];
}
return _ret5 = (_temp5 = (_this6 = _possibleConstructorReturn(this, (_ref10 = DatasetPage.__proto__ || Object.getPrototypeOf(DatasetPage)).call.apply(_ref10, [this].concat(args))), _this6), _this6.onCohort = function (ev) {
navHandler.call(_this6, ev);
}, _this6.onViz = function () {
var _this6$props$state = _this6.props.state,
datapages = _this6$props$state.datapages,
currentCohort = _this6$props$state.spreadsheet.cohort,
cohort = getIn(datapages, ['dataset', 'meta', 'cohort'], COHORT_NULL);
if (cohort !== get(currentCohort, 'name')) {
_this6.props.callback(['cohort', cohort]);
}
_this6.props.callback(['navigate', 'heatmap']);
}, _this6.onIdentifiers = function (ev) {
navHandler.call(_this6, ev);
}, _this6.onSamples = function (ev) {
navHandler.call(_this6, ev);
}, _temp5), _possibleConstructorReturn(_this6, _ret5);
}
_createClass(DatasetPage, [{
key: 'render',
value: function render() {
var _props4 = this.props,
callback = _props4.callback,
state = _props4.state,
hubParams = _props4.hubParams,
_state$params = state.params,
host = _state$params.host,
dataset = _state$params.dataset,
datapages = state.datapages,
_get = get(datapages, 'dataset', {}),
meta = _get.meta,
_get$probeCount = _get.probeCount,
probeCount = _get$probeCount === undefined ? 0 : _get$probeCount,
data = _get.data,
downloadLink = _get.downloadLink,
probemapLink = _get.probemapLink,
currentDataset = _get.dataset,
currentHost = _get.host;
if (!meta || currentHost !== host || currentDataset !== dataset) {
return React.createElement(
'div',
{ className: styles.datapages },
React.createElement(
'h2',
null,
'dataset: ...'
)
);
}
var name = meta.name,
_meta$label = meta.label,
label = _meta$label === undefined ? name : _meta$label,
description = meta.description,
longTitle = meta.longTitle,
_meta$cohort = meta.cohort,
cohort = _meta$cohort === undefined ? COHORT_NULL : _meta$cohort,
dataSubType = meta.dataSubType,
platform = meta.platform,
unit = meta.unit,
assembly = meta.assembly,
version = meta.version,
url = meta.url,
articletitle = meta.articletitle,
citation = meta.citation,
pmid = meta.pmid,
dataproducer = meta.dataproducer,
_meta$author = meta.author,
author = _meta$author === undefined ? dataproducer : _meta$author,
wranglingProcedure = meta['wrangling_procedure'],
_meta$type = meta.type,
type = _meta$type === undefined ? TYPE_NULL : _meta$type,
status = meta.status,
loader = meta.loader,
count = meta.count;
return React.createElement(
'div',
{ className: styles.datapages },
React.createElement(
'div',
{ className: styles.sidebar },
React.createElement(
_button.Button,
{ onClick: this.onViz, accent: true },
'Visualize'
),
canDelete(meta, host) ? React.createElement(DeleteButton, { callback: callback, name: name, label: label }) : null
),
React.createElement(
'h2',
null,
'dataset: ',
(dataSubType ? dataSubType + ' - ' : '') + label
),
headerValue(longTitle),
htmlValue(description),
setKey(flatten([dataPair('cohort', cohort, toCohortLink(this.onCohort, hubParams)), dataPair('dataset ID', name), getStatus(status, loader), dataPair('download', downloadLink, toDownloadLink), dataPair('samples', count), dataPair('version', version), dataPair('hub', host), dataPair('type of data', dataSubType), dataPair('assembly', assembly), dataPair('unit', unit), dataPair('platform', platform), dataPair('ID/Gene Mapping', probemapLink, toDownloadLink), dataPair('publication', articletitle), dataPair('citation', citation), dataPair('author', author), dataPair('PMID', pmid, toPMIDLink), flatmap(uniq(split(url, /,/)), function (url) {
return dataPair('raw data', url, toLink);
}), dataPair('wrangling', wranglingProcedure, toHTML), dataPair('input data format', FORMAT_MAPPING[type])])),
status === 'loaded' ? React.createElement(
'span',
{ className: styles.tableControls },
type === 'genomicMatrix' ? probeCount.toLocaleString() + ' identifiers X ' + count + ' samples' : null,
type === 'clinicalMatrix' ? count + ' samples X ' + probeCount.toLocaleString() + ' identifiers' : null,
React.createElement(_link2.default, {
href: '?' + encodeObject(_extends({ host: host, dataset: dataset, allIdentifiers: true }, hubParams)),
onClick: this.onIdentifiers, label: 'All Identifiers' }),
React.createElement(_link2.default, {
href: '?' + encodeObject(_extends({ host: host, dataset: dataset, allSamples: true }, hubParams)),
onClick: this.onSamples, label: 'All Samples' })
) : null,
dataMethod(meta)(meta, data)
);
}
}]);
return DatasetPage;
}(React.Component);
// Our handling of parameters 'hub' and 'host', is somewhat confusing. 'host'
// means "show the hub page for this url". 'hub' means "add this url to the
// active hub list, and, if in /datapages/ show the hub page for this url".
// The 'hub' parameter can be repeated, which adds each hub to the active hub
// list. Only the first one will be displayed when linking to /datapages/.
// Needs refactor.
var defaultHost = function defaultHost(params) {
return Let(function () {
var _ref11 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : params,
host = _ref11.host,
hubs = _ref11.hubs;
return !host && hubs ? _extends({}, params, { host: hubs[0] }) : params;
});
};
//
// Hub page
//
var HubPage = function (_React$Component6) {
_inherits(HubPage, _React$Component6);
function HubPage() {
var _ref12;
var _temp6, _this7, _ret6;
_classCallCheck(this, HubPage);
for (var _len6 = arguments.length, args = Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
args[_key6] = arguments[_key6];
}
return _ret6 = (_temp6 = (_this7 = _possibleConstructorReturn(this, (_ref12 = HubPage.__proto__ || Object.getPrototypeOf(HubPage)).call.apply(_ref12, [this].concat(args))), _this7), _this7.onCohort = function (ev) {
navHandler.call(_this7, ev);
}, _temp6), _possibleConstructorReturn(_this7, _ret6);
}
_createClass(HubPage, [{
key: 'render',
value: function render() {
var _props5 = this.props,
state = _props5.state,
hubParams = _props5.hubParams,
servers = state.spreadsheet.servers,
userServers = getUserServers(servers),
_defaultHost = defaultHost(state.params),
host = _defaultHost.host,
cohorts = getIn(state, ['datapages', 'cohorts'], []),
hubCohorts = where(cohorts, { server: host }),
coll = collateCohorts(hubCohorts),
inHubs = contains(userServers, host) ? '' : ' (not in my data hubs)';
return React.createElement(
'div',
{ className: styles.datapages },
markdownValue(getIn(hubCohorts, [0, 'meta'])),
React.createElement(
'h2',
null,
getHubName(host),
inHubs
),
React.createElement(
'p',
null,
'Hub address: ',
host
),
React.createElement(CohortSummary, { hubParams: hubParams, cohorts: coll, onCohort: this.onCohort })
);
}
}]);
return HubPage;
}(React.Component);
//
// Samples / Identifiers page
//
var binSize = 1000;
// The point of ListPage is to render a potentially very long list
// incrementally, so we get a fast first render, and don't lock up the UI.
// We do that by rendering binSize rows at a time, on a requestAnimationFrame
// timeout.
var ListPage = function (_React$Component7) {
_inherits(ListPage, _React$Component7);
function ListPage() {
var _ref13;
var _temp7, _this8, _ret7;
_classCallCheck(this, ListPage);
for (var _len7 = arguments.length, args = Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
args[_key7] = arguments[_key7];
}
return _ret7 = (_temp7 = (_this8 = _possibleConstructorReturn(this, (_ref13 = ListPage.__proto__ || Object.getPrototypeOf(ListPage)).call.apply(_ref13, [this].concat(args))), _this8), _this8.state = {}, _temp7), _possibleConstructorReturn(_this8, _ret7);
}
_createClass(ListPage, [{
key: 'componentWillMount',
value: function componentWillMount() {
var _this9 = this;
var _props6 = this.props,
state = _props6.state,
path = _props6.path,
list = getIn(state, ['datapages', path, 'list']);
var events = rxEvents(this, 'list');
var chunks = events.list.startWith(list).distinctUntilChanged().filter(identity).switchMap(function (ids) {
var chunks = partitionN(ids, binSize).map(function (a) {
return a.join('\n');
});
return from(range(chunks.length), animationFrame).map(function (i) {
return { chunks: chunks.slice(0, i + 1), total: chunks.length };
});
});
this.sub = chunks.subscribe(function (chunks) {
_this9.setState(chunks);
});
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this.sub.unsubscribe();
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(props) {
var state = props.state,
path = props.path,
list = getIn(state, ['datapages', path, 'list']);
this.on.list(list);
}
}, {
key: 'render',
value: function render() {
var _props7 = this.props,
state = _props7.state,
path = _props7.path,
title = _props7.title,
_state$params2 = state.params,
host = _state$params2.host,
dataset = _state$params2.dataset,
datapages = state.datapages,
_getIn = getIn(datapages, [path], {}),
currentDataset = _getIn.dataset,
currentHost = _getIn.host,
_ref14 = currentHost !== host || currentDataset !== dataset ? {} : this.state,
chunks = _ref14.chunks,
total = _ref14.total,
percent = !chunks ? ' 0%' : chunks.length === total ? '' : ' ' + Math.floor(chunks.length / total * 100) + '%';
return React.createElement(
'div',
{ className: styles.datapages },
React.createElement(
'h3',
null,
'dataset: ',
dataset
),
React.createElement(
'h4',
null,
title,
percent
),
chunks ? chunks.map(function (c, i) {
return React.createElement(
'pre',
{ key: i, className: styles.list },
c
);
}) : 'Loading...'
);
}
}]);
return ListPage;
}(React.Component);
var markdownPage = function (_React$Component8) {
_inherits(markdownPage, _React$Component8);
function markdownPage() {
_classCallCheck(this, markdownPage);
return _possibleConstructorReturn(this, (markdownPage.__proto__ || Object.getPrototypeOf(markdownPage)).apply(this, arguments));
}
_createClass(markdownPage, [{
key: 'render',
value: function render() {
var state = this.props.state,
content = getIn(state, ['datapages', 'markdownContent']);
return React.createElement(
'div',
{ className: styles.datapages },
markdownValue(content)
);
}
}]);
return markdownPage;
}(React.Component);
var IdentifiersPage = function IdentifiersPage(props) {
return React.createElement(ListPage, _extends({ title: 'Identifiers', path: 'identifiers' }, props));
};
var SamplesPage = function SamplesPage(props) {
return React.createElement(ListPage, _extends({ title: 'Samples', path: 'samples' }, props));
};
//
// Top-level dispatch to sub-pages
//
var getPage = function getPage(_ref15) {
var dataset = _ref15.dataset,
host = _ref15.host,
cohort = _ref15.cohort,
allIdentifiers = _ref15.allIdentifiers,
allSamples = _ref15.allSamples,
markdown = _ref15.markdown;
return markdown ? markdownPage : allSamples ? SamplesPage : allIdentifiers ? IdentifiersPage : dataset && host ? DatasetPage : host ? HubPage : cohort ? CohortPage : CohortSummaryPage;
};
var Datapages = function (_React$Component9) {
_inherits(Datapages, _React$Component9);
function Datapages() {
var _ref16;
var _temp8, _this11, _ret8;
_classCallCheck(this, Datapages);
for (var _len8 = arguments.length, args = Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
args[_key8] = arguments[_key8];
}
return _ret8 = (_temp8 = (_this11 = _possibleConstructorReturn(this, (_ref16 = Datapages.__proto__ || Object.getPrototypeOf(Datapages)).call.apply(_ref16, [this].concat(args))), _this11), _this11.onNavigate = function (page) {
_this11.props.callback(['navigate', page]);
}, _temp8), _possibleConstructorReturn(_this11, _ret8);
}
_createClass(Datapages, [{
key: 'componentDidMount',
value: function componentDidMount() {
nav({ activeLink: 'datapages', onNavigate: this.onNavigate });
}
}, {
key: 'render',
value: function render() {
var state = this.props.state,
params = state.params,
hubParams = getHubParams(state),
Page = getPage(defaultHost(params));
return React.createElement(Page, _extends({}, this.props, { hubParams: hubParams }));
}
}]);
return Datapages;
}(React.Component);
var ThemedDatapages = function (_React$Component10) {
_inherits(ThemedDatapages, _React$Component10);
function ThemedDatapages() {
_classCallCheck(this, ThemedDatapages);
return _possibleConstructorReturn(this, (ThemedDatapages.__proto__ || Object.getPrototypeOf(ThemedDatapages)).apply(this, arguments));
}
_createClass(ThemedDatapages, [{
key: 'render',
value: function render() {
return React.createElement(
_reactCssThemr.ThemeProvider,
{ theme: appTheme },
React.createElement(Datapages, this.props)
);
}
}]);
return ThemedDatapages;
}(React.Component);
var selector = function selector(state) {
return state;
};
module.exports = function (props) {
return React.createElement(ThemedDatapages, _extends({}, props, { selector: selector }));
};