UNPKG

recharts

Version:
264 lines (222 loc) 8.91 kB
import _flatten from "lodash/flatten"; import _isNil from "lodash/isNil"; import _isString from "lodash/isString"; import _get from "lodash/get"; import _isArray from "lodash/isArray"; function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } import React, { Children } from 'react'; import { isNumber } from './DataUtils'; import { shallowEqual } from './ShallowEqual'; var REACT_BROWSER_EVENT_MAP = { click: 'onClick', mousedown: 'onMouseDown', mouseup: 'onMouseUp', mouseover: 'onMouseOver', mousemove: 'onMouseMove', mouseout: 'onMouseOut', mouseenter: 'onMouseEnter', mouseleave: 'onMouseLeave', touchcancel: 'onTouchCancel', touchend: 'onTouchEnd', touchmove: 'onTouchMove', touchstart: 'onTouchStart' }; export var SCALE_TYPES = ['auto', 'linear', 'pow', 'sqrt', 'log', 'identity', 'time', 'band', 'point', 'ordinal', 'quantile', 'quantize', 'utc', 'sequential', 'threshold']; export var LEGEND_TYPES = ['plainline', 'line', 'square', 'rect', 'circle', 'cross', 'diamond', 'star', 'triangle', 'wye', 'none']; export var TOOLTIP_TYPES = ['none']; /** * Get the display name of a component * @param {Object} Comp Specified Component * @return {String} Display name of Component */ export var getDisplayName = function getDisplayName(Comp) { if (typeof Comp === 'string') { return Comp; } if (!Comp) { return ''; } return Comp.displayName || Comp.name || 'Component'; }; /* * Find and return all matched children by type. `type` can be a React element class or * string */ export var findAllByType = function findAllByType(children, type) { var result = []; var types = []; if (_isArray(type)) { types = type.map(function (t) { return getDisplayName(t); }); } else { types = [getDisplayName(type)]; } React.Children.forEach(children, function (child) { var childType = _get(child, 'type.displayName') || _get(child, 'type.name'); if (types.indexOf(childType) !== -1) { result.push(child); } }); return result; }; /* * Return the first matched child by type, return null otherwise. * `type` can be a React element class or string. */ export var findChildByType = function findChildByType(children, type) { var result = findAllByType(children, type); return result && result[0]; }; /* * Create a new array of children excluding the ones matched the type */ export var withoutType = function withoutType(children, type) { var newChildren = []; var types; if (_isArray(type)) { types = type.map(function (t) { return getDisplayName(t); }); } else { types = [getDisplayName(type)]; } React.Children.forEach(children, function (child) { var displayName = _get(child, 'type.displayName'); if (displayName && types.indexOf(displayName) !== -1) { return; } newChildren.push(child); }); return newChildren; }; /** * validate the width and height props of a chart element * @param {Object} el A chart element * @return {Boolean} true If the props width and height are number, and greater than 0 */ export var validateWidthHeight = function validateWidthHeight(el) { if (!el || !el.props) { return false; } var _el$props = el.props, width = _el$props.width, height = _el$props.height; if (!isNumber(width) || width <= 0 || !isNumber(height) || height <= 0) { return false; } return true; }; var SVG_TAGS = ['a', 'altGlyph', 'altGlyphDef', 'altGlyphItem', 'animate', 'animateColor', 'animateMotion', 'animateTransform', 'circle', 'clipPath', 'color-profile', 'cursor', 'defs', 'desc', 'ellipse', 'feBlend', 'feColormatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence', 'filter', 'font', 'font-face', 'font-face-format', 'font-face-name', 'font-face-url', 'foreignObject', 'g', 'glyph', 'glyphRef', 'hkern', 'image', 'line', 'lineGradient', 'marker', 'mask', 'metadata', 'missing-glyph', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'script', 'set', 'stop', 'style', 'svg', 'switch', 'symbol', 'text', 'textPath', 'title', 'tref', 'tspan', 'use', 'view', 'vkern']; var isSvgElement = function isSvgElement(child) { return child && child.type && _isString(child.type) && SVG_TAGS.indexOf(child.type) >= 0; }; /** * Filter all the svg elements of children * @param {Array} children The children of a react element * @return {Array} All the svg elements */ export var filterSvgElements = function filterSvgElements(children) { var svgElements = []; React.Children.forEach(children, function (entry) { if (isSvgElement(entry)) { svgElements.push(entry); } }); return svgElements; }; /** * Wether props of children changed * @param {Object} nextChildren The latest children * @param {Object} prevChildren The prev children * @return {Boolean} equal or not */ export var isChildrenEqual = function isChildrenEqual(nextChildren, prevChildren) { if (nextChildren === prevChildren) { return true; } if (Children.count(nextChildren) !== Children.count(prevChildren)) { return false; } var count = Children.count(nextChildren); if (count === 0) { return true; } if (count === 1) { // eslint-disable-next-line no-use-before-define,@typescript-eslint/no-use-before-define return isSingleChildEqual(_isArray(nextChildren) ? nextChildren[0] : nextChildren, _isArray(prevChildren) ? prevChildren[0] : prevChildren); } for (var i = 0; i < count; i++) { var nextChild = nextChildren[i]; var prevChild = prevChildren[i]; if (_isArray(nextChild) || _isArray(prevChild)) { if (!isChildrenEqual(nextChild, prevChild)) { return false; } // eslint-disable-next-line no-use-before-define,@typescript-eslint/no-use-before-define } else if (!isSingleChildEqual(nextChild, prevChild)) { return false; } } return true; }; export var isSingleChildEqual = function isSingleChildEqual(nextChild, prevChild) { if (_isNil(nextChild) && _isNil(prevChild)) { return true; } if (!_isNil(nextChild) && !_isNil(prevChild)) { var _ref = nextChild.props || {}, nextChildren = _ref.children, nextProps = _objectWithoutProperties(_ref, ["children"]); var _ref2 = prevChild.props || {}, prevChildren = _ref2.children, prevProps = _objectWithoutProperties(_ref2, ["children"]); if (nextChildren && prevChildren) { // eslint-disable-next-line no-use-before-define return shallowEqual(nextProps, prevProps) && isChildrenEqual(nextChildren, prevChildren); } if (!nextChildren && !prevChildren) { return shallowEqual(nextProps, prevProps); } return false; } return false; }; export var renderByOrder = function renderByOrder(children, renderMap) { var elements = []; var record = {}; Children.forEach(children, function (child, index) { if (isSvgElement(child)) { elements.push(child); } else if (child) { var displayName = getDisplayName(child.type); var _ref3 = renderMap[displayName] || {}, handler = _ref3.handler, once = _ref3.once; if (handler && (!once || !record[displayName])) { var results = handler(child, displayName, index); elements.push(results); record[displayName] = true; } } }); return _flatten(elements).filter(function (element) { return !_isNil(element); }); }; export var getReactEventByType = function getReactEventByType(e) { var type = e && e.type; if (type && REACT_BROWSER_EVENT_MAP[type]) { return REACT_BROWSER_EVENT_MAP[type]; } return null; }; export var parseChildIndex = function parseChildIndex(child, children) { var result = -1; Children.forEach(children, function (entry, index) { if (entry === child) { result = index; } }); return result; };