UNPKG

grommet

Version:

The most advanced UX framework for enterprise applications.

388 lines (309 loc) 14.2 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.Range = exports.HotSpots = exports.MarkerLabel = exports.Marker = exports.Bar = exports.Line = exports.Area = exports.Grid = exports.Base = exports.Layers = exports.Axis = undefined; 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 _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 _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _classnames2 = require('classnames'); var _classnames3 = _interopRequireDefault(_classnames2); var _CSSClassnames = require('../../utils/CSSClassnames'); var _CSSClassnames2 = _interopRequireDefault(_CSSClassnames); var _Intl = require('../../utils/Intl'); var _Intl2 = _interopRequireDefault(_Intl); var _utils = require('./utils'); var _Meter = require('../Meter'); var _Meter2 = _interopRequireDefault(_Meter); var _Axis = require('./Axis'); var _Axis2 = _interopRequireDefault(_Axis); var _Layers = require('./Layers'); var _Layers2 = _interopRequireDefault(_Layers); var _Base = require('./Base'); var _Base2 = _interopRequireDefault(_Base); var _Grid = require('./Grid'); var _Grid2 = _interopRequireDefault(_Grid); var _Area = require('./Area'); var _Area2 = _interopRequireDefault(_Area); var _Line = require('./Line'); var _Line2 = _interopRequireDefault(_Line); var _Bar = require('./Bar'); var _Bar2 = _interopRequireDefault(_Bar); var _Marker = require('./Marker'); var _Marker2 = _interopRequireDefault(_Marker); var _MarkerLabel = require('./MarkerLabel'); var _MarkerLabel2 = _interopRequireDefault(_MarkerLabel); var _HotSpots = require('./HotSpots'); var _HotSpots2 = _interopRequireDefault(_HotSpots); var _Range = require('./Range'); var _Range2 = _interopRequireDefault(_Range); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } 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; } // (C) Copyright 2016 Hewlett Packard Enterprise Development LP var CLASS_ROOT = _CSSClassnames2.default.CHART; var CHART_BASE = _CSSClassnames2.default.CHART_BASE; function traverseAndUpdateChildren(children) { return _react.Children.map(children, function (child) { if (!child || !child.type) { return child; } // remove tabIndex from child elements to avoid // multiple tabs inside a chart if (child.type === _Meter2.default || child.type.name === 'Meter' || child.type === Chart || child.type.name === 'Chart') { return _react2.default.cloneElement(child, { tabIndex: '-1' }); } if (child.props.children) { var childrenNoTabIndex = traverseAndUpdateChildren(child.props.children); return _react2.default.cloneElement(child, { children: childrenNoTabIndex }); } return child; }); } var Chart = function (_Component) { _inherits(Chart, _Component); function Chart(props, context) { _classCallCheck(this, Chart); var _this = _possibleConstructorReturn(this, (Chart.__proto__ || Object.getPrototypeOf(Chart)).call(this, props, context)); _this._onResize = _this._onResize.bind(_this); _this._layout = _this._layout.bind(_this); _this.state = { alignTop: 0, alignLeft: 0, alignHeight: 0, alignWidth: 0 }; return _this; } _createClass(Chart, [{ key: 'componentDidMount', value: function componentDidMount() { window.addEventListener('resize', this._onResize); // Give sometime for the ui to render. Why is this needed though? setTimeout(this._layout, 150); } }, { key: 'componentWillReceiveProps', value: function componentWillReceiveProps(nextProps) { // Always layout when new props come. This takes care of a contained // Base having children that change. this.setState({ layoutNeeded: true }); } }, { key: 'componentDidUpdate', value: function componentDidUpdate() { if (this.state.layoutNeeded) { this._layout(); this.setState({ layoutNeeded: false }); } } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { window.removeEventListener('resize', this._onResize); } }, { key: '_onResize', value: function _onResize() { // debounce clearTimeout(this._resizeTimer); this._resizeTimer = setTimeout(this._layout, _utils.debounceDelay); } }, { key: '_layout', value: function _layout() { var _props = this.props, horizontalAlignWith = _props.horizontalAlignWith, verticalAlignWith = _props.verticalAlignWith, vertical = _props.vertical, onMaxCount = _props.onMaxCount; var chart = this.chartRef; if (chart) { var chartRect = chart.getBoundingClientRect(); var base = this.chartRef.querySelector('.' + CHART_BASE); var alignWidth = void 0, alignLeft = void 0, alignRight = void 0, alignHeight = void 0, alignTop = void 0, alignBottom = void 0; var padAlign = true; if (horizontalAlignWith) { var elem = document.getElementById(horizontalAlignWith); if (elem) { var rect = elem.getBoundingClientRect(); alignWidth = rect.width; alignLeft = rect.left - chartRect.left; alignRight = chartRect.right - rect.right; padAlign = false; } } else if (base) { var _rect = base.getBoundingClientRect(); alignWidth = _rect.width; alignLeft = _rect.left - chartRect.left; alignRight = chartRect.right - _rect.right; } if (verticalAlignWith) { var _elem = document.getElementById(verticalAlignWith); if (_elem) { var _rect2 = _elem.getBoundingClientRect(); alignHeight = _rect2.height; alignTop = _rect2.top - chartRect.top; alignBottom = chartRect.bottom - _rect2.bottom; padAlign = false; } } else if (base) { var _rect3 = base.getBoundingClientRect(); alignHeight = _rect3.height; alignTop = _rect3.top - chartRect.top; alignBottom = chartRect.bottom - _rect3.bottom; } this.setState({ alignWidth: alignWidth, alignLeft: alignLeft, alignRight: alignRight, alignHeight: alignHeight, alignTop: alignTop, alignBottom: alignBottom, padAlign: padAlign }); if (onMaxCount) { var maxCount = void 0; if (vertical) { maxCount = Math.floor(alignWidth / (4 * _utils.padding)); } else { maxCount = Math.floor(alignHeight / (4 * _utils.padding)); } if (maxCount !== this.state.maxCount) { this.setState({ maxCount: maxCount }, function () { onMaxCount(maxCount); }); } } } } }, { key: 'render', value: function render() { var _classnames, _this2 = this; var _props2 = this.props, a11yTitle = _props2.a11yTitle, className = _props2.className, full = _props2.full, loading = _props2.loading, vertical = _props2.vertical, props = _objectWithoutProperties(_props2, ['a11yTitle', 'className', 'full', 'loading', 'vertical']); delete props.horizontalAlignWith; delete props.onMaxCount; delete props.verticalAlignWith; var _state = this.state, alignBottom = _state.alignBottom, alignHeight = _state.alignHeight, alignLeft = _state.alignLeft, alignRight = _state.alignRight, alignTop = _state.alignTop, alignWidth = _state.alignWidth, padAlign = _state.padAlign; var intl = this.context.intl; var classes = (0, _classnames3.default)(CLASS_ROOT, (_classnames = {}, _defineProperty(_classnames, CLASS_ROOT + '--full', full), _defineProperty(_classnames, CLASS_ROOT + '--loading', loading), _defineProperty(_classnames, CLASS_ROOT + '--vertical', vertical), _classnames), className); // Align Axis children towards the Base|Layers|Chart var axisAlign = 'end'; var children = _react.Children.map(this.props.children, function (child) { // name comparison is to work around webpack alias issues in development if (child && (child.type === _Axis2.default || child.type.name === 'Axis' || child.type === _MarkerLabel2.default || child.type.name === 'MarkerLabel')) { if (vertical) { child = _react2.default.cloneElement(child, { style: { marginLeft: padAlign ? alignLeft + _utils.padding : alignLeft, marginRight: padAlign ? alignRight + _utils.padding : alignRight }, align: axisAlign }); } else { child = _react2.default.cloneElement(child, { style: { // We set the height just for Safari due to: // http://stackoverflow.com/questions/35532987/ // heights-rendering-differently-in-chrome-and-firefox/ // 35537510#35537510 // Chrome seems to have addressed this already. height: padAlign ? alignHeight - 2 * _utils.padding : alignHeight, marginTop: padAlign ? alignTop + _utils.padding : alignTop, marginBottom: padAlign ? alignBottom + _utils.padding : alignBottom }, align: axisAlign }); } } else if (child && (child.type === _Layers2.default || child.type.name === 'Layers')) { child = _react2.default.cloneElement(child, { height: alignHeight, width: alignWidth, style: { left: alignLeft, top: alignTop } }); axisAlign = 'start'; } else if (child && (child.type === Chart || child.type.name === 'Chart' || child.type === _Base2.default || child.type.name === 'Base')) { if (child.type === _Base2.default) { var updatedChildren = traverseAndUpdateChildren(child.props.children); child = _react2.default.cloneElement(child, { children: updatedChildren }); } else { child = _react2.default.cloneElement(child, { tabIndex: '-1' }); } axisAlign = 'start'; } return child; }); if (loading) { children.push(_react2.default.createElement( 'svg', { key: 'loading', className: classes, viewBox: '0 0 ' + alignWidth + ' ' + alignHeight }, _react2.default.createElement('path', { d: 'M0,' + alignHeight / 2 + ' L' + alignWidth + ',' + alignHeight / 2 }) )); } var ariaLabel = a11yTitle || _Intl2.default.getMessage(intl, 'Chart'); return _react2.default.createElement( 'div', _extends({ ref: function ref(_ref) { return _this2.chartRef = _ref; } }, props, { className: classes, 'aria-label': ariaLabel, role: 'group' }), children ); } }]); return Chart; }(_react.Component); Chart.displayName = 'Chart'; exports.default = Chart; Chart.contextTypes = { intl: _propTypes2.default.object }; Chart.propTypes = { a11yTitle: _propTypes2.default.string, full: _propTypes2.default.bool, horizontalAlignWith: _propTypes2.default.string, loading: _propTypes2.default.bool, onMaxCount: _propTypes2.default.func, vertical: _propTypes2.default.bool, verticalAlignWith: _propTypes2.default.string }; exports.Axis = _Axis2.default; exports.Layers = _Layers2.default; exports.Base = _Base2.default; exports.Grid = _Grid2.default; exports.Area = _Area2.default; exports.Line = _Line2.default; exports.Bar = _Bar2.default; exports.Marker = _Marker2.default; exports.MarkerLabel = _MarkerLabel2.default; exports.HotSpots = _HotSpots2.default; exports.Range = _Range2.default;