UNPKG

virool-pivot

Version:

A web-based exploratory visualization UI for Druid.io

422 lines (387 loc) 19.5 kB
webpackJsonp([5],{ /***/ 479: /***/ function(module, exports, __webpack_require__) { "use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; __webpack_require__(480); var React = __webpack_require__(5); var ReactDOM = __webpack_require__(42); var plywood_1 = __webpack_require__(190); var index_1 = __webpack_require__(194); var general_1 = __webpack_require__(199); var download_1 = __webpack_require__(257); var formatter_1 = __webpack_require__(332); var dom_1 = __webpack_require__(245); var sizing_1 = __webpack_require__(482); var constants_1 = __webpack_require__(227); var modal_1 = __webpack_require__(483); var button_1 = __webpack_require__(346); var scroller_1 = __webpack_require__(437); var loader_1 = __webpack_require__(173); var query_error_1 = __webpack_require__(343); var SPACE_RIGHT = 10; var SPACE_LEFT = 10; var BODY_PADDING_BOTTOM = 90; var HEADER_HEIGHT = 30; var ROW_HEIGHT = 30; var LIMIT = 100; var TIME_COL_WIDTH = 180; var BOOLEAN_COL_WIDTH = 100; var NUMBER_COL_WIDTH = 100; var DEFAULT_COL_WIDTH = 200; function getColumnWidth(attribute) { switch (attribute.type) { case 'BOOLEAN': return BOOLEAN_COL_WIDTH; case 'NUMBER': return NUMBER_COL_WIDTH; case 'TIME': return TIME_COL_WIDTH; default: return DEFAULT_COL_WIDTH; } } function classFromAttribute(attribute) { return dom_1.classNames(String(attribute.type).toLowerCase().replace(/\//g, '-'), { unsplitable: attribute.unsplitable }); } var RawDataModal = (function (_super) { __extends(RawDataModal, _super); function RawDataModal() { _super.call(this); this.state = { loading: false, dataset: null, scrollLeft: 0, scrollTop: 0, error: null, stage: null }; this.globalResizeListener = this.globalResizeListener.bind(this); } RawDataModal.prototype.componentDidMount = function () { this.mounted = true; var essence = this.props.essence; this.fetchData(essence); this.globalResizeListener(); }; RawDataModal.prototype.componentWillUnmount = function () { this.mounted = false; }; RawDataModal.prototype.fetchData = function (essence) { var _this = this; var dataSource = essence.dataSource; var $main = plywood_1.$('main'); var query = $main.filter(essence.getEffectiveFilter().toExpression()).limit(LIMIT); this.setState({ loading: true }); dataSource.executor(query, { timezone: essence.timezone }) .then(function (dataset) { if (!_this.mounted) return; _this.setState({ dataset: dataset, loading: false }); }, function (error) { if (!_this.mounted) return; _this.setState({ error: error, loading: false }); }); }; RawDataModal.prototype.globalResizeListener = function () { var table = this.refs.table; var tableDOM = ReactDOM.findDOMNode(table); if (!tableDOM) return; this.setState({ stage: index_1.Stage.fromClientRect(tableDOM.getBoundingClientRect()) }); }; RawDataModal.prototype.onScroll = function (scrollTop, scrollLeft) { this.setState({ scrollLeft: scrollLeft, scrollTop: scrollTop }); }; RawDataModal.prototype.getStringifiedFilters = function () { var essence = this.props.essence; var dataSource = essence.dataSource; return essence.getEffectiveFilter().clauses.map(function (clause, i) { var dimension = dataSource.getDimensionByExpression(clause.expression); if (!dimension) return null; return formatter_1.formatFilterClause({ dimension: dimension, clause: clause, essence: essence, verbose: true }); }).toList(); }; RawDataModal.prototype.getSortedAttributes = function (dataSource) { var timeAttributeName = dataSource.timeAttribute ? dataSource.timeAttribute.name : null; var attributeRank = function (attribute) { var name = attribute.name; if (name === timeAttributeName) { return 1; } else if (attribute.unsplitable) { return 3; } else { return 2; } }; return dataSource.attributes.sort(function (a1, a2) { var score1 = attributeRank(a1); var score2 = attributeRank(a2); if (score1 === score2) { return a1.name.toLowerCase().localeCompare(a2.name.toLowerCase()); } return score1 - score2; }); }; RawDataModal.prototype.renderFilters = function () { var filters = this.getStringifiedFilters().map(function (filter, i) { return React.createElement("li", {className: "filter", key: i}, filter); }).toList(); var limit = React.createElement("li", {className: "limit", key: "limit"}, "First ", LIMIT, " events matching "); return filters.unshift(limit); }; RawDataModal.prototype.renderHeader = function () { var essence = this.props.essence; var dataset = this.state.dataset; if (!dataset) return null; var dataSource = essence.dataSource; var attributes = this.getSortedAttributes(dataSource); return attributes.map(function (attribute, i) { var name = attribute.name; var width = getColumnWidth(attribute); var style = { width: width }; var key = name; return (React.createElement("div", {className: dom_1.classNames("header-cell", classFromAttribute(attribute)), style: style, key: i}, React.createElement("div", {className: "title-wrap"}, general_1.makeTitle(key)))); }); }; RawDataModal.prototype.getVisibleIndices = function (rowCount, height) { var scrollTop = this.state.scrollTop; return [ Math.max(0, Math.floor(scrollTop / ROW_HEIGHT)), Math.min(rowCount, Math.ceil((scrollTop + height) / ROW_HEIGHT)) ]; }; RawDataModal.prototype.renderRows = function () { var essence = this.props.essence; var _a = this.state, dataset = _a.dataset, scrollLeft = _a.scrollLeft, stage = _a.stage; if (!dataset) return null; var dataSource = essence.dataSource; var rawData = dataset.data; var _b = this.getVisibleIndices(rawData.length, stage.height), firstRowToShow = _b[0], lastRowToShow = _b[1]; var rows = rawData.slice(firstRowToShow, lastRowToShow); var attributes = this.getSortedAttributes(dataSource); var attributeWidths = attributes.map(getColumnWidth); var _c = sizing_1.getVisibleSegments(attributeWidths, scrollLeft, stage.width), startIndex = _c.startIndex, shownColumns = _c.shownColumns; var leftOffset = general_1.arraySum(attributeWidths.slice(0, startIndex)); attributes = attributes.slice(startIndex, startIndex + shownColumns); var rowY = firstRowToShow * ROW_HEIGHT; return rows.map(function (datum, i) { var cols = []; attributes.forEach(function (attribute) { var name = attribute.name; var value = datum[name]; var colStyle = { width: getColumnWidth(attribute) }; var displayValue = value; if (plywood_1.isDate(datum[name])) { displayValue = datum[name].toISOString(); } cols.push(React.createElement("div", {className: dom_1.classNames('cell', classFromAttribute(attribute)), key: name, style: colStyle}, React.createElement("span", {className: "cell-value"}, String(displayValue)))); }); var rowStyle = { top: rowY, left: leftOffset }; rowY += ROW_HEIGHT; return React.createElement("div", {className: "row", style: rowStyle, key: i}, cols); }); }; RawDataModal.prototype.render = function () { var _a = this.props, essence = _a.essence, onClose = _a.onClose; var _b = this.state, dataset = _b.dataset, loading = _b.loading, error = _b.error; var dataSource = essence.dataSource; var title = general_1.makeTitle(constants_1.STRINGS.segment) + " " + constants_1.STRINGS.rawData; var filtersString = essence.getEffectiveFilter().getFileString(dataSource.timeAttribute); var scrollerLayout = { // Inner dimensions bodyWidth: general_1.arraySum(dataSource.attributes.map(getColumnWidth)), bodyHeight: (dataset ? dataset.data.length : 0) * ROW_HEIGHT, // Gutters top: HEADER_HEIGHT, right: 0, bottom: 0, left: 0 }; return React.createElement(modal_1.Modal, {className: "raw-data-modal", title: title, onClose: onClose}, React.createElement("div", {className: "content"}, React.createElement("ul", {className: "filters"}, this.renderFilters()), React.createElement(scroller_1.Scroller, {ref: "table", layout: scrollerLayout, topGutter: this.renderHeader(), body: this.renderRows(), onScroll: this.onScroll.bind(this)}), error ? React.createElement(query_error_1.QueryError, {error: error}) : null, loading ? React.createElement(loader_1.Loader, null) : null, React.createElement("div", {className: "button-bar"}, React.createElement(button_1.Button, {type: "primary", className: "close", onClick: onClose, title: constants_1.STRINGS.close}), React.createElement(button_1.Button, {type: "secondary", className: "download", onClick: download_1.download.bind(this, dataset, download_1.makeFileName(dataSource.name, filtersString, 'raw'), 'csv'), title: constants_1.STRINGS.download, disabled: Boolean(loading || error)})))); }; return RawDataModal; }(React.Component)); exports.RawDataModal = RawDataModal; /***/ }, /***/ 480: /***/ function(module, exports, __webpack_require__) { // style-loader: Adds some css to the DOM by adding a <style> tag // load the styles var content = __webpack_require__(481); if(typeof content === 'string') content = [[module.id, content, '']]; // add the styles to the DOM var update = __webpack_require__(4)(content, {}); if(content.locals) module.exports = content.locals; // Hot Module Replacement if(false) { // When the styles change, update the <style> tags if(!content.locals) { module.hot.accept("!!./../../../../node_modules/css-loader/index.js!./raw-data-modal.css", function() { var newContent = require("!!./../../../../node_modules/css-loader/index.js!./raw-data-modal.css"); if(typeof newContent === 'string') newContent = [[module.id, newContent, '']]; update(newContent); }); } // When the module is disposed, remove the <style> tags module.hot.dispose(function() { update(); }); } /***/ }, /***/ 481: /***/ function(module, exports, __webpack_require__) { exports = module.exports = __webpack_require__(3)(); // imports // module exports.push([module.id, ".raw-data-modal .content{position:absolute;top:60px;bottom:0;left:0;right:0;left:18px;right:18px;overflow:hidden}.raw-data-modal .content .filters{position:absolute;top:0;bottom:0;left:0;right:0;white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis;height:30px;color:#999}.raw-data-modal .content .filters .limit,.raw-data-modal .content .filters .filter{font-size:13px;height:30px;display:inline}.raw-data-modal .content .filters .filter:not(:last-child):after{content:'; '}.raw-data-modal .content .scroller{position:absolute;top:30px;bottom:66px;left:0;right:0;border:1px solid #dedede;cursor:auto}.raw-data-modal .content .scroller .row{height:30px;position:absolute;border-bottom:1px solid #dedede}.raw-data-modal .content .scroller .header-cell,.raw-data-modal .content .scroller .cell{white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis;display:inline-block;height:100%;border-right:1px solid #dedede;padding-left:6px;padding-right:6px;padding-top:8px}.raw-data-modal .content .scroller .header-cell.unsplitable,.raw-data-modal .content .scroller .cell.unsplitable{background:#f5f5f5}.raw-data-modal .content .scroller .header-cell{background:#f5f5f5;height:30px;border-bottom:1px solid #dedede}.raw-data-modal .content .scroller .header-cell .title-wrap{white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis;display:inline-block;width:100%;height:100%}.raw-data-modal .content .loader,.raw-data-modal .content .query-error{position:absolute;top:0;bottom:0;left:0;right:0}.raw-data-modal .content .button-bar{position:absolute;left:0;right:0;bottom:18px}.raw-data-modal .content .button-bar .close{margin-right:8px}\n", ""]); // exports /***/ }, /***/ 482: /***/ function(module, exports) { "use strict"; function getVisibleSegments(segmentWidths, offset, visibleSize) { var startIndex = 0; var shownColumns = 0; var curWidth = 0; for (var i = 0; i < segmentWidths.length; i++) { var segmentWidth = segmentWidths[i]; var afterWidth = curWidth + segmentWidth; if (afterWidth < offset) { startIndex++; } else if (curWidth < offset + visibleSize) { shownColumns++; } curWidth = afterWidth; } return { startIndex: startIndex, shownColumns: shownColumns }; } exports.getVisibleSegments = getVisibleSegments; /***/ }, /***/ 483: /***/ function(module, exports, __webpack_require__) { "use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; __webpack_require__(484); var React = __webpack_require__(5); var dom_1 = __webpack_require__(245); var body_portal_1 = __webpack_require__(264); var svg_icon_1 = __webpack_require__(176); var golden_center_1 = __webpack_require__(235); var Modal = (function (_super) { __extends(Modal, _super); function Modal() { _super.call(this); this.state = { id: null }; this.globalMouseDownListener = this.globalMouseDownListener.bind(this); this.globalKeyDownListener = this.globalKeyDownListener.bind(this); } Modal.prototype.componentWillMount = function () { var id = this.props.id; this.setState({ id: id || dom_1.uniqueId('modal-') }); }; Modal.prototype.componentDidMount = function () { window.addEventListener('mousedown', this.globalMouseDownListener); window.addEventListener('keydown', this.globalKeyDownListener); }; Modal.prototype.componentWillUnmount = function () { window.removeEventListener('mousedown', this.globalMouseDownListener); window.removeEventListener('keydown', this.globalKeyDownListener); }; Modal.prototype.globalMouseDownListener = function (e) { var _a = this.props, onClose = _a.onClose, mandatory = _a.mandatory; if (mandatory) return; var id = this.state.id; // can not use ReactDOM.findDOMNode(this) because portal? var myElement = document.getElementById(id); if (!myElement) return; var target = e.target; if (dom_1.isInside(target, myElement)) return; onClose(); }; Modal.prototype.globalKeyDownListener = function (e) { if (!dom_1.escapeKey(e)) return; var _a = this.props, onClose = _a.onClose, mandatory = _a.mandatory; if (mandatory) return; onClose(); }; Modal.prototype.render = function () { var _a = this.props, className = _a.className, title = _a.title, children = _a.children, onClose = _a.onClose; var id = this.state.id; var titleElement = null; if (typeof title === 'string') { titleElement = React.createElement("div", {className: "modal-title"}, React.createElement("div", {className: "text"}, title), React.createElement("div", {className: "close", onClick: onClose}, React.createElement(svg_icon_1.SvgIcon, {svg: __webpack_require__(415)}))); } return React.createElement(body_portal_1.BodyPortal, {fullSize: true}, React.createElement("div", {className: dom_1.classNames('modal', className)}, React.createElement("div", {className: "backdrop"}), React.createElement(golden_center_1.GoldenCenter, null, React.createElement("div", {className: "modal-window", id: id}, titleElement, children)))); }; return Modal; }(React.Component)); exports.Modal = Modal; /***/ }, /***/ 484: /***/ function(module, exports, __webpack_require__) { // style-loader: Adds some css to the DOM by adding a <style> tag // load the styles var content = __webpack_require__(485); if(typeof content === 'string') content = [[module.id, content, '']]; // add the styles to the DOM var update = __webpack_require__(4)(content, {}); if(content.locals) module.exports = content.locals; // Hot Module Replacement if(false) { // When the styles change, update the <style> tags if(!content.locals) { module.hot.accept("!!./../../../../node_modules/css-loader/index.js!./modal.css", function() { var newContent = require("!!./../../../../node_modules/css-loader/index.js!./modal.css"); if(typeof newContent === 'string') newContent = [[module.id, newContent, '']]; update(newContent); }); } // When the module is disposed, remove the <style> tags module.hot.dispose(function() { update(); }); } /***/ }, /***/ 485: /***/ function(module, exports, __webpack_require__) { exports = module.exports = __webpack_require__(3)(); // imports // module exports.push([module.id, ".modal .modal-window{background:#fff;border-radius:2px;box-shadow:0 5px 9px 0 rgba(0,0,0,0.3),0 0 5px 0 rgba(0,0,0,0.2)}.modal{position:absolute;top:0;bottom:0;left:0;right:0}.modal .backdrop{position:absolute;top:0;bottom:0;left:0;right:0;background:#000;opacity:0.2}.modal .golden-center{position:absolute;top:0;bottom:0;left:0;right:0}.modal .modal-window{width:420px;padding:18px;background:#fff}.modal .modal-window .modal-title{line-height:30px;font-size:17px;margin-bottom:16px}.modal .modal-window .modal-title .close{top:0;right:0;position:absolute;padding:5px;cursor:pointer}.modal .modal-window .modal-title:hover svg path{fill:#888}.modal .modal-window .modal-title svg{width:19px}.modal .modal-window .modal-title svg path{fill:#bbb}.modal.raw-data-modal .modal-window{width:70%;height:85%;min-height:200px}\n", ""]); // exports /***/ } });