UNPKG

ucsc-xena-client

Version:

UCSC Xena Client. Functional genomics visualizations.

178 lines (138 loc) 6.08 kB
'use strict'; 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 _PureComponent2 = require('./PureComponent'); var _PureComponent3 = _interopRequireDefault(_PureComponent2); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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; } var _ = require('./underscore_ext'); var Rx = require('./rx'); var widgets = require('./columnWidgets'); var util = require('./util'); var React = require('react'); var CanvasDrawing = require('./CanvasDrawing'); var _require = require('./react-utils'), rxEvents = _require.rxEvents; var _require2 = require('./drawSamples'), drawSamples = _require2.drawSamples; // Since we don't set module.exports, but instead register ourselves // with columWidgets, react-hot-loader can't handle the updates automatically. // Accept hot loading here. if (module.hot) { module.hot.accept(); } // Since there are multiple components in the file we have to use makeHot // explicitly. function hotOrNot(component) { return module.makeHot ? module.makeHot(component) : component; } // // Tooltip // // We're getting events with coords < 0. Not sure if this // is a side-effect of the react event system. This will // restrict values to the given range. function bounded(min, max, x) { return x < min ? min : x > max ? max : x; } function tooltip(heatmap, sampleFormat, codes, width, zoom, samples, ev) { var coord = util.eventOffset(ev), sampleIndex = bounded(0, samples.length, Math.floor(coord.y * zoom.count / zoom.height + zoom.index)), sampleID = samples[sampleIndex]; var val = _.getIn(heatmap, [0, sampleIndex]), code = _.get(codes, val, 'NA'); return { sampleID: sampleFormat(sampleID), rows: [[['labelValue', 'sample', code]]] }; } // // plot rendering // var SamplesColumn = hotOrNot( // // plot rendering // function (_PureComponent) { _inherits(_class2, _PureComponent); function _class2() { var _ref; var _temp, _this, _ret; _classCallCheck(this, _class2); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = _class2.__proto__ || Object.getPrototypeOf(_class2)).call.apply(_ref, [this].concat(args))), _this), _this.tooltip = function (ev) { var _this$props = _this.props, samples = _this$props.samples, data = _this$props.data, column = _this$props.column, zoom = _this$props.zoom, sampleFormat = _this$props.sampleFormat, codes = _.get(data, 'codes'), heatmap = column.heatmap, width = column.width; return tooltip(heatmap, sampleFormat, codes, width, zoom, samples, ev); }, _temp), _possibleConstructorReturn(_this, _ret); } _createClass(_class2, [{ key: 'componentWillMount', value: function componentWillMount() { var _this2 = this; var events = rxEvents(this, 'mouseout', 'mousemove', 'mouseover'); // Compute tooltip events from mouse events. this.ttevents = events.mouseover.filter(function (ev) { return util.hasClass(ev.currentTarget, 'Tooltip-target'); }).flatMap(function () { return events.mousemove.takeUntil(events.mouseout).map(function (ev) { return { data: _this2.tooltip(ev), open: true }; }) // look up current data .concat(Rx.Observable.of({ open: false })); }).subscribe(this.props.tooltip); } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { this.ttevents.unsubscribe(); } }, { key: 'render', // To reduce this set of properties, we could // - Drop data & move codes into the 'display' obj, outside of data // Might also want to copy fields into 'display', so we can drop req probes value: function render() { var _props = this.props, data = _props.data, column = _props.column, zoom = _props.zoom, heatmap = column.heatmap, codes = _.get(data, 'codes'); return React.createElement(CanvasDrawing, { ref: 'plot', draw: drawSamples, wrapperProps: { className: 'Tooltip-target', onMouseMove: this.on.mousemove, onMouseOut: this.on.mouseout, onMouseOver: this.on.mouseover, onClick: this.props.onClick }, codes: codes, width: _.get(column, 'width'), zoom: zoom, heatmapData: heatmap }); } }]); return _class2; }(_PureComponent3.default)); var getColumn = function getColumn(props) { return React.createElement(SamplesColumn, props); }; widgets.column.add("samples", getColumn); var getLegend = function getLegend() { return null; }; widgets.legend.add('samples', getLegend);