UNPKG

recharts

Version:
390 lines (384 loc) 14.5 kB
var _excluded = ["x1", "y1", "x2", "y2", "key"], _excluded2 = ["offset"], _excluded3 = ["xAxisId", "yAxisId"], _excluded4 = ["xAxisId", "yAxisId"]; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; } function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; } /** * @fileOverview Cartesian Grid */ import * as React from 'react'; import { warn } from '../util/LogUtils'; import { isNumber } from '../util/DataUtils'; import { filterProps } from '../util/ReactUtils'; import { getCoordinatesOfGrid, getTicksOfAxis } from '../util/ChartUtils'; import { getTicks } from './getTicks'; import { CartesianAxis } from './CartesianAxis'; import { useChartHeight, useChartWidth, useOffsetInternal } from '../context/chartLayoutContext'; import { selectAxisPropsNeededForCartesianGridTicksGenerator } from '../state/selectors/axisSelectors'; import { useAppSelector } from '../state/hooks'; import { useIsPanorama } from '../context/PanoramaContext'; import { resolveDefaultProps } from '../util/resolveDefaultProps'; /** * The <CartesianGrid horizontal */ var Background = props => { var { fill } = props; if (!fill || fill === 'none') { return null; } var { fillOpacity, x, y, width, height, ry } = props; return /*#__PURE__*/React.createElement("rect", { x: x, y: y, ry: ry, width: width, height: height, stroke: "none", fill: fill, fillOpacity: fillOpacity, className: "recharts-cartesian-grid-bg" }); }; function renderLineItem(option, props) { var lineItem; if (/*#__PURE__*/React.isValidElement(option)) { // @ts-expect-error typescript does not see the props type when cloning an element lineItem = /*#__PURE__*/React.cloneElement(option, props); } else if (typeof option === 'function') { lineItem = option(props); } else { var { x1, y1, x2, y2, key } = props, others = _objectWithoutProperties(props, _excluded); var _filterProps = filterProps(others, false), { offset: __ } = _filterProps, restOfFilteredProps = _objectWithoutProperties(_filterProps, _excluded2); lineItem = /*#__PURE__*/React.createElement("line", _extends({}, restOfFilteredProps, { x1: x1, y1: y1, x2: x2, y2: y2, fill: "none", key: key })); } return lineItem; } function HorizontalGridLines(props) { var { x, width, horizontal = true, horizontalPoints } = props; if (!horizontal || !horizontalPoints || !horizontalPoints.length) { return null; } var { xAxisId, yAxisId } = props, otherLineItemProps = _objectWithoutProperties(props, _excluded3); var items = horizontalPoints.map((entry, i) => { var lineItemProps = _objectSpread(_objectSpread({}, otherLineItemProps), {}, { x1: x, y1: entry, x2: x + width, y2: entry, key: "line-".concat(i), index: i }); return renderLineItem(horizontal, lineItemProps); }); return /*#__PURE__*/React.createElement("g", { className: "recharts-cartesian-grid-horizontal" }, items); } function VerticalGridLines(props) { var { y, height, vertical = true, verticalPoints } = props; if (!vertical || !verticalPoints || !verticalPoints.length) { return null; } var { xAxisId, yAxisId } = props, otherLineItemProps = _objectWithoutProperties(props, _excluded4); var items = verticalPoints.map((entry, i) => { var lineItemProps = _objectSpread(_objectSpread({}, otherLineItemProps), {}, { x1: entry, y1: y, x2: entry, y2: y + height, key: "line-".concat(i), index: i }); return renderLineItem(vertical, lineItemProps); }); return /*#__PURE__*/React.createElement("g", { className: "recharts-cartesian-grid-vertical" }, items); } function HorizontalStripes(props) { var { horizontalFill, fillOpacity, x, y, width, height, horizontalPoints, horizontal = true } = props; if (!horizontal || !horizontalFill || !horizontalFill.length) { return null; } // Why =y -y? I was trying to find any difference that this makes, with floating point numbers and edge cases but ... nothing. var roundedSortedHorizontalPoints = horizontalPoints.map(e => Math.round(e + y - y)).sort((a, b) => a - b); // Why is this condition `!==` instead of `<=` ? if (y !== roundedSortedHorizontalPoints[0]) { roundedSortedHorizontalPoints.unshift(0); } var items = roundedSortedHorizontalPoints.map((entry, i) => { // Why do we strip only the last stripe if it is invisible, and not all invisible stripes? var lastStripe = !roundedSortedHorizontalPoints[i + 1]; var lineHeight = lastStripe ? y + height - entry : roundedSortedHorizontalPoints[i + 1] - entry; if (lineHeight <= 0) { return null; } var colorIndex = i % horizontalFill.length; return /*#__PURE__*/React.createElement("rect", { key: "react-".concat(i) // eslint-disable-line react/no-array-index-key , y: entry, x: x, height: lineHeight, width: width, stroke: "none", fill: horizontalFill[colorIndex], fillOpacity: fillOpacity, className: "recharts-cartesian-grid-bg" }); }); return /*#__PURE__*/React.createElement("g", { className: "recharts-cartesian-gridstripes-horizontal" }, items); } function VerticalStripes(props) { var { vertical = true, verticalFill, fillOpacity, x, y, width, height, verticalPoints } = props; if (!vertical || !verticalFill || !verticalFill.length) { return null; } var roundedSortedVerticalPoints = verticalPoints.map(e => Math.round(e + x - x)).sort((a, b) => a - b); if (x !== roundedSortedVerticalPoints[0]) { roundedSortedVerticalPoints.unshift(0); } var items = roundedSortedVerticalPoints.map((entry, i) => { var lastStripe = !roundedSortedVerticalPoints[i + 1]; var lineWidth = lastStripe ? x + width - entry : roundedSortedVerticalPoints[i + 1] - entry; if (lineWidth <= 0) { return null; } var colorIndex = i % verticalFill.length; return /*#__PURE__*/React.createElement("rect", { key: "react-".concat(i) // eslint-disable-line react/no-array-index-key , x: entry, y: y, width: lineWidth, height: height, stroke: "none", fill: verticalFill[colorIndex], fillOpacity: fillOpacity, className: "recharts-cartesian-grid-bg" }); }); return /*#__PURE__*/React.createElement("g", { className: "recharts-cartesian-gridstripes-vertical" }, items); } var defaultVerticalCoordinatesGenerator = (_ref, syncWithTicks) => { var { xAxis, width, height, offset } = _ref; return getCoordinatesOfGrid(getTicks(_objectSpread(_objectSpread(_objectSpread({}, CartesianAxis.defaultProps), xAxis), {}, { ticks: getTicksOfAxis(xAxis, true), viewBox: { x: 0, y: 0, width, height } })), offset.left, offset.left + offset.width, syncWithTicks); }; var defaultHorizontalCoordinatesGenerator = (_ref2, syncWithTicks) => { var { yAxis, width, height, offset } = _ref2; return getCoordinatesOfGrid(getTicks(_objectSpread(_objectSpread(_objectSpread({}, CartesianAxis.defaultProps), yAxis), {}, { ticks: getTicksOfAxis(yAxis, true), viewBox: { x: 0, y: 0, width, height } })), offset.top, offset.top + offset.height, syncWithTicks); }; var defaultProps = { horizontal: true, vertical: true, // The ordinates of horizontal grid lines horizontalPoints: [], // The abscissas of vertical grid lines verticalPoints: [], stroke: '#ccc', fill: 'none', // The fill of colors of grid lines verticalFill: [], horizontalFill: [], xAxisId: 0, yAxisId: 0 }; export function CartesianGrid(props) { var chartWidth = useChartWidth(); var chartHeight = useChartHeight(); var offset = useOffsetInternal(); var propsIncludingDefaults = _objectSpread(_objectSpread({}, resolveDefaultProps(props, defaultProps)), {}, { x: isNumber(props.x) ? props.x : offset.left, y: isNumber(props.y) ? props.y : offset.top, width: isNumber(props.width) ? props.width : offset.width, height: isNumber(props.height) ? props.height : offset.height }); var { xAxisId, yAxisId, x, y, width, height, syncWithTicks, horizontalValues, verticalValues } = propsIncludingDefaults; var isPanorama = useIsPanorama(); var xAxis = useAppSelector(state => selectAxisPropsNeededForCartesianGridTicksGenerator(state, 'xAxis', xAxisId, isPanorama)); var yAxis = useAppSelector(state => selectAxisPropsNeededForCartesianGridTicksGenerator(state, 'yAxis', yAxisId, isPanorama)); if (!isNumber(width) || width <= 0 || !isNumber(height) || height <= 0 || !isNumber(x) || x !== +x || !isNumber(y) || y !== +y) { return null; } /* * verticalCoordinatesGenerator and horizontalCoordinatesGenerator are defined * outside the propsIncludingDefaults because they were never part of the original props * and they were never passed as a prop down to horizontal/vertical custom elements. * If we add these two to propsIncludingDefaults then we are changing public API. * Not a bad thing per se but also not necessary. */ var verticalCoordinatesGenerator = propsIncludingDefaults.verticalCoordinatesGenerator || defaultVerticalCoordinatesGenerator; var horizontalCoordinatesGenerator = propsIncludingDefaults.horizontalCoordinatesGenerator || defaultHorizontalCoordinatesGenerator; var { horizontalPoints, verticalPoints } = propsIncludingDefaults; // No horizontal points are specified if ((!horizontalPoints || !horizontalPoints.length) && typeof horizontalCoordinatesGenerator === 'function') { var isHorizontalValues = horizontalValues && horizontalValues.length; var generatorResult = horizontalCoordinatesGenerator({ yAxis: yAxis ? _objectSpread(_objectSpread({}, yAxis), {}, { ticks: isHorizontalValues ? horizontalValues : yAxis.ticks }) : undefined, width: chartWidth, height: chartHeight, offset }, isHorizontalValues ? true : syncWithTicks); warn(Array.isArray(generatorResult), "horizontalCoordinatesGenerator should return Array but instead it returned [".concat(typeof generatorResult, "]")); if (Array.isArray(generatorResult)) { horizontalPoints = generatorResult; } } // No vertical points are specified if ((!verticalPoints || !verticalPoints.length) && typeof verticalCoordinatesGenerator === 'function') { var isVerticalValues = verticalValues && verticalValues.length; var _generatorResult = verticalCoordinatesGenerator({ xAxis: xAxis ? _objectSpread(_objectSpread({}, xAxis), {}, { ticks: isVerticalValues ? verticalValues : xAxis.ticks }) : undefined, width: chartWidth, height: chartHeight, offset }, isVerticalValues ? true : syncWithTicks); warn(Array.isArray(_generatorResult), "verticalCoordinatesGenerator should return Array but instead it returned [".concat(typeof _generatorResult, "]")); if (Array.isArray(_generatorResult)) { verticalPoints = _generatorResult; } } return /*#__PURE__*/React.createElement("g", { className: "recharts-cartesian-grid" }, /*#__PURE__*/React.createElement(Background, { fill: propsIncludingDefaults.fill, fillOpacity: propsIncludingDefaults.fillOpacity, x: propsIncludingDefaults.x, y: propsIncludingDefaults.y, width: propsIncludingDefaults.width, height: propsIncludingDefaults.height, ry: propsIncludingDefaults.ry }), /*#__PURE__*/React.createElement(HorizontalStripes, _extends({}, propsIncludingDefaults, { horizontalPoints: horizontalPoints })), /*#__PURE__*/React.createElement(VerticalStripes, _extends({}, propsIncludingDefaults, { verticalPoints: verticalPoints })), /*#__PURE__*/React.createElement(HorizontalGridLines, _extends({}, propsIncludingDefaults, { offset: offset, horizontalPoints: horizontalPoints, xAxis: xAxis, yAxis: yAxis })), /*#__PURE__*/React.createElement(VerticalGridLines, _extends({}, propsIncludingDefaults, { offset: offset, verticalPoints: verticalPoints, xAxis: xAxis, yAxis: yAxis }))); } CartesianGrid.displayName = 'CartesianGrid';