UNPKG

recharts

Version:
308 lines (297 loc) 13.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.filterSvgElements = exports.filterProps = exports.TOOLTIP_TYPES = exports.SCALE_TYPES = exports.LEGEND_TYPES = void 0; exports.findAllByType = findAllByType; exports.findChildByType = findChildByType; exports.withoutType = exports.validateWidthHeight = exports.toArray = exports.renderByOrder = exports.parseChildIndex = exports.isValidSpreadableProp = exports.isSingleChildEqual = exports.isDotProps = exports.isChildrenEqual = exports.getReactEventByType = exports.getDisplayName = void 0; var _get = _interopRequireDefault(require("lodash/get")); var _isNil = _interopRequireDefault(require("lodash/isNil")); var _isString = _interopRequireDefault(require("lodash/isString")); var _isFunction = _interopRequireDefault(require("lodash/isFunction")); var _isObject = _interopRequireDefault(require("lodash/isObject")); var _react = require("react"); var _reactIs = require("react-is"); var _DataUtils = require("./DataUtils"); var _ShallowEqual = require("./ShallowEqual"); var _types = require("./types"); var _excluded = ["children"], _excluded2 = ["children"]; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 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; } function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 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' }; var SCALE_TYPES = exports.SCALE_TYPES = ['auto', 'linear', 'pow', 'sqrt', 'log', 'identity', 'time', 'band', 'point', 'ordinal', 'quantile', 'quantize', 'utc', 'sequential', 'threshold']; var LEGEND_TYPES = exports.LEGEND_TYPES = ['plainline', 'line', 'square', 'rect', 'circle', 'cross', 'diamond', 'star', 'triangle', 'wye', 'none']; var TOOLTIP_TYPES = exports.TOOLTIP_TYPES = ['none']; /** * Get the display name of a component * @param {Object} Comp Specified Component * @return {String} Display name of Component */ var getDisplayName = exports.getDisplayName = function getDisplayName(Comp) { if (typeof Comp === 'string') { return Comp; } if (!Comp) { return ''; } return Comp.displayName || Comp.name || 'Component'; }; // `toArray` gets called multiple times during the render // so we can memoize last invocation (since reference to `children` is the same) var lastChildren = null; var lastResult = null; var toArray = exports.toArray = function toArray(children) { if (children === lastChildren && Array.isArray(lastResult)) { return lastResult; } var result = []; _react.Children.forEach(children, function (child) { if ((0, _isNil["default"])(child)) return; if ((0, _reactIs.isFragment)(child)) { result = result.concat(toArray(child.props.children)); } else { result.push(child); } }); lastResult = result; lastChildren = children; return result; }; /* * Find and return all matched children by type. * `type` must be a React.ComponentType */ function findAllByType(children, type) { var result = []; var types = []; if (Array.isArray(type)) { types = type.map(function (t) { return getDisplayName(t); }); } else { types = [getDisplayName(type)]; } toArray(children).forEach(function (child) { var childType = (0, _get["default"])(child, 'type.displayName') || (0, _get["default"])(child, 'type.name'); if (types.indexOf(childType) !== -1) { result.push(child); } }); return result; } /* * Return the first matched child by type, return null otherwise. * `type` must be a React.ComponentType */ 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 */ var withoutType = exports.withoutType = function withoutType(children, type) { var newChildren = []; var types; if (Array.isArray(type)) { types = type.map(function (t) { return getDisplayName(t); }); } else { types = [getDisplayName(type)]; } toArray(children).forEach(function (child) { var displayName = (0, _get["default"])(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 */ var validateWidthHeight = exports.validateWidthHeight = function validateWidthHeight(el) { if (!el || !el.props) { return false; } var _el$props = el.props, width = _el$props.width, height = _el$props.height; if (!(0, _DataUtils.isNumber)(width) || width <= 0 || !(0, _DataUtils.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 && (0, _isString["default"])(child.type) && SVG_TAGS.indexOf(child.type) >= 0; }; var isDotProps = exports.isDotProps = function isDotProps(dot) { return dot && _typeof(dot) === 'object' && 'cx' in dot && 'cy' in dot && 'r' in dot; }; /** * Checks if the property is valid to spread onto an SVG element or onto a specific component * @param {unknown} property property value currently being compared * @param {string} key property key currently being compared * @param {boolean} includeEvents if events are included in spreadable props * @param {boolean} svgElementType checks against map of SVG element types to attributes * @returns {boolean} is prop valid */ var isValidSpreadableProp = exports.isValidSpreadableProp = function isValidSpreadableProp(property, key, includeEvents, svgElementType) { var _FilteredElementKeyMa; /** * If the svg element type is explicitly included, check against the filtered element key map * to determine if there are attributes that should only exist on that element type. * @todo Add an internal cjs version of https://github.com/wooorm/svg-element-attributes for full coverage. */ var matchingElementTypeKeys = (_FilteredElementKeyMa = _types.FilteredElementKeyMap === null || _types.FilteredElementKeyMap === void 0 ? void 0 : _types.FilteredElementKeyMap[svgElementType]) !== null && _FilteredElementKeyMa !== void 0 ? _FilteredElementKeyMa : []; return !(0, _isFunction["default"])(property) && (svgElementType && matchingElementTypeKeys.includes(key) || _types.SVGElementPropKeys.includes(key)) || includeEvents && _types.EventKeys.includes(key); }; /** * Filter all the svg elements of children * @param {Array} children The children of a react element * @return {Array} All the svg elements */ var filterSvgElements = exports.filterSvgElements = function filterSvgElements(children) { var svgElements = []; toArray(children).forEach(function (entry) { if (isSvgElement(entry)) { svgElements.push(entry); } }); return svgElements; }; var filterProps = exports.filterProps = function filterProps(props, includeEvents, svgElementType) { if (!props || typeof props === 'function' || typeof props === 'boolean') { return null; } var inputProps = props; if ( /*#__PURE__*/(0, _react.isValidElement)(props)) { inputProps = props.props; } if (!(0, _isObject["default"])(inputProps)) { return null; } var out = {}; /** * Props are blindly spread onto SVG elements. This loop filters out properties that we don't want to spread. * Items filtered out are as follows: * - functions in properties that are SVG attributes (functions are included when includeEvents is true) * - props that are SVG attributes but don't matched the passed svgElementType * - any prop that is not in SVGElementPropKeys (or in EventKeys if includeEvents is true) */ Object.keys(inputProps).forEach(function (key) { var _inputProps; if (isValidSpreadableProp((_inputProps = inputProps) === null || _inputProps === void 0 ? void 0 : _inputProps[key], key, includeEvents, svgElementType)) { out[key] = inputProps[key]; } }); return out; }; /** * Wether props of children changed * @param {Object} nextChildren The latest children * @param {Object} prevChildren The prev children * @return {Boolean} equal or not */ var isChildrenEqual = exports.isChildrenEqual = function isChildrenEqual(nextChildren, prevChildren) { if (nextChildren === prevChildren) { return true; } var count = _react.Children.count(nextChildren); if (count !== _react.Children.count(prevChildren)) { return false; } if (count === 0) { return true; } if (count === 1) { // eslint-disable-next-line @typescript-eslint/no-use-before-define return isSingleChildEqual(Array.isArray(nextChildren) ? nextChildren[0] : nextChildren, Array.isArray(prevChildren) ? prevChildren[0] : prevChildren); } for (var i = 0; i < count; i++) { var nextChild = nextChildren[i]; var prevChild = prevChildren[i]; if (Array.isArray(nextChild) || Array.isArray(prevChild)) { if (!isChildrenEqual(nextChild, prevChild)) { return false; } // eslint-disable-next-line @typescript-eslint/no-use-before-define } else if (!isSingleChildEqual(nextChild, prevChild)) { return false; } } return true; }; var isSingleChildEqual = exports.isSingleChildEqual = function isSingleChildEqual(nextChild, prevChild) { if ((0, _isNil["default"])(nextChild) && (0, _isNil["default"])(prevChild)) { return true; } if (!(0, _isNil["default"])(nextChild) && !(0, _isNil["default"])(prevChild)) { var _ref = nextChild.props || {}, nextChildren = _ref.children, nextProps = _objectWithoutProperties(_ref, _excluded); var _ref2 = prevChild.props || {}, prevChildren = _ref2.children, prevProps = _objectWithoutProperties(_ref2, _excluded2); if (nextChildren && prevChildren) { return (0, _ShallowEqual.shallowEqual)(nextProps, prevProps) && isChildrenEqual(nextChildren, prevChildren); } if (!nextChildren && !prevChildren) { return (0, _ShallowEqual.shallowEqual)(nextProps, prevProps); } return false; } return false; }; var renderByOrder = exports.renderByOrder = function renderByOrder(children, renderMap) { var elements = []; var record = {}; toArray(children).forEach(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 elements; }; var getReactEventByType = exports.getReactEventByType = function getReactEventByType(e) { var type = e && e.type; if (type && REACT_BROWSER_EVENT_MAP[type]) { return REACT_BROWSER_EVENT_MAP[type]; } return null; }; var parseChildIndex = exports.parseChildIndex = function parseChildIndex(child, children) { return toArray(children).indexOf(child); };