UNPKG

recharts

Version:
162 lines (154 loc) 7.26 kB
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); } import React, { createContext, useContext } from 'react'; import invariant from 'tiny-invariant'; import find from 'lodash/find'; import every from 'lodash/every'; import { calculateViewBox } from '../util/calculateViewBox'; import { getAnyElementOfObject } from '../util/DataUtils'; export var XAxisContext = /*#__PURE__*/createContext(undefined); export var YAxisContext = /*#__PURE__*/createContext(undefined); export var ViewBoxContext = /*#__PURE__*/createContext(undefined); export var OffsetContext = /*#__PURE__*/createContext({}); export var ClipPathIdContext = /*#__PURE__*/createContext(undefined); export var ChartHeightContext = /*#__PURE__*/createContext(0); export var ChartWidthContext = /*#__PURE__*/createContext(0); /** * Will add all the properties required to render all individual Recharts components into a React Context. * * If you want to read these properties, see the collection of hooks exported from this file. * * @param {object} props CategoricalChartState, plus children * @returns {ReactElement} React Context Provider */ export var ChartLayoutContextProvider = function ChartLayoutContextProvider(props) { var _props$state = props.state, xAxisMap = _props$state.xAxisMap, yAxisMap = _props$state.yAxisMap, offset = _props$state.offset, clipPathId = props.clipPathId, children = props.children, width = props.width, height = props.height; /** * Perhaps we should compute this property when reading? Let's see what is more often used */ var viewBox = calculateViewBox(offset); /* * This pretends to be a single context but actually is split into multiple smaller ones. * Why? * Because one React Context only allows to set one value. * But we need to set multiple values. * If we do that with one context, then we force re-render on components that might not even be interested * in the part of the state that has changed. * * By splitting into smaller contexts, we allow each components to be optimized and only re-render when its dependencies change. * * To actually achieve the optimal re-render, it is necessary to use React.memo(). * See the test file for details. */ return /*#__PURE__*/React.createElement(XAxisContext.Provider, { value: xAxisMap }, /*#__PURE__*/React.createElement(YAxisContext.Provider, { value: yAxisMap }, /*#__PURE__*/React.createElement(OffsetContext.Provider, { value: offset }, /*#__PURE__*/React.createElement(ViewBoxContext.Provider, { value: viewBox }, /*#__PURE__*/React.createElement(ClipPathIdContext.Provider, { value: clipPathId }, /*#__PURE__*/React.createElement(ChartHeightContext.Provider, { value: height }, /*#__PURE__*/React.createElement(ChartWidthContext.Provider, { value: width }, children))))))); }; export var useClipPathId = function useClipPathId() { return useContext(ClipPathIdContext); }; function getKeysForDebug(object) { var keys = Object.keys(object); if (keys.length === 0) { return 'There are no available ids.'; } return "Available ids are: ".concat(keys, "."); } /** * This either finds and returns Axis by the specified ID, or throws an exception if an axis with this ID does not exist. * * @param xAxisId identifier of the axis - it's either autogenerated ('0'), or passed via `id` prop as <XAxis id='foo' /> * @returns axis configuration object * @throws Error if no axis with this ID exists */ export var useXAxisOrThrow = function useXAxisOrThrow(xAxisId) { var xAxisMap = useContext(XAxisContext); !(xAxisMap != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Could not find Recharts context; are you sure this is rendered inside a Recharts wrapper component?') : invariant(false) : void 0; var xAxis = xAxisMap[xAxisId]; !(xAxis != null) ? process.env.NODE_ENV !== "production" ? invariant(false, "Could not find xAxis by id \"".concat(xAxisId, "\" [").concat(_typeof(xAxisId), "]. ").concat(getKeysForDebug(xAxisMap))) : invariant(false) : void 0; return xAxis; }; /** * This will find an arbitrary first XAxis. If there's exactly one it always returns that one * - but if there are multiple then it can return any of those. * * If you want specific XAxis out of multiple then prefer using useXAxisOrThrow * * @returns X axisOptions, or undefined - if there are no X axes */ export var useArbitraryXAxis = function useArbitraryXAxis() { var xAxisMap = useContext(XAxisContext); return getAnyElementOfObject(xAxisMap); }; /** * This will find an arbitrary first YAxis. If there's exactly one it always returns that one * - but if there are multiple then it can return any of those. * * If you want specific YAxis out of multiple then prefer using useXAxisOrThrow * * @returns Y axisOptions, or undefined - if there are no Y axes */ export var useArbitraryYAxis = function useArbitraryYAxis() { var yAxisMap = useContext(YAxisContext); return getAnyElementOfObject(yAxisMap); }; /** * This hooks will: * 1st attempt to find an YAxis that has all elements in its domain finite * If no such axis exists, it will return an arbitrary YAxis * if there are no Y axes then it returns undefined * * @returns Either Y axisOptions, or undefined if there are no Y axes */ export var useYAxisWithFiniteDomainOrRandom = function useYAxisWithFiniteDomainOrRandom() { var yAxisMap = useContext(YAxisContext); var yAxisWithFiniteDomain = find(yAxisMap, function (axis) { return every(axis.domain, Number.isFinite); }); return yAxisWithFiniteDomain || getAnyElementOfObject(yAxisMap); }; /** * This either finds and returns Axis by the specified ID, or throws an exception if an axis with this ID does not exist. * * @param yAxisId identifier of the axis - it's either autogenerated ('0'), or passed via `id` prop as <YAxis id='foo' /> * @returns axis configuration object * @throws Error if no axis with this ID exists */ export var useYAxisOrThrow = function useYAxisOrThrow(yAxisId) { var yAxisMap = useContext(YAxisContext); !(yAxisMap != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Could not find Recharts context; are you sure this is rendered inside a Recharts wrapper component?') : invariant(false) : void 0; var yAxis = yAxisMap[yAxisId]; !(yAxis != null) ? process.env.NODE_ENV !== "production" ? invariant(false, "Could not find yAxis by id \"".concat(yAxisId, "\" [").concat(_typeof(yAxisId), "]. ").concat(getKeysForDebug(yAxisMap))) : invariant(false) : void 0; return yAxis; }; export var useViewBox = function useViewBox() { var viewBox = useContext(ViewBoxContext); return viewBox; }; export var useOffset = function useOffset() { return useContext(OffsetContext); }; export var useChartWidth = function useChartWidth() { return useContext(ChartWidthContext); }; export var useChartHeight = function useChartHeight() { return useContext(ChartHeightContext); };