UNPKG

@mui/x-charts

Version:

The community edition of the charts components (MUI X).

300 lines (296 loc) 13.7 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.CartesianContext = void 0; exports.CartesianContextProvider = CartesianContextProvider; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _d3Scale = require("d3-scale"); var _propTypes = _interopRequireDefault(require("prop-types")); var _extremums = require("../BarChart/extremums"); var _extremums2 = require("../ScatterChart/extremums"); var _extremums3 = require("../LineChart/extremums"); var _axis = require("../models/axis"); var _getScale = require("../internals/getScale"); var _DrawingProvider = require("./DrawingProvider"); var _SeriesContextProvider = require("./SeriesContextProvider"); var _constants = require("../constants"); var _useTicks = require("../hooks/useTicks"); var _jsxRuntime = require("react/jsx-runtime"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } const DEFAULT_CATEGORY_GAP_RATIO = 0.2; const DEFAULT_BAR_GAP_RATIO = 0.1; // TODO: those might be better placed in a distinct file const xExtremumGetters = { bar: _extremums.getExtremumX, scatter: _extremums2.getExtremumX, line: _extremums3.getExtremumX }; const yExtremumGetters = { bar: _extremums.getExtremumY, scatter: _extremums2.getExtremumY, line: _extremums3.getExtremumY }; const CartesianContext = exports.CartesianContext = /*#__PURE__*/React.createContext({ xAxis: {}, yAxis: {}, xAxisIds: [], yAxisIds: [] }); /** * API: * * - [CartesianContextProvider API](https://mui.com/x/api/charts/cartesian-context-provider/) */ function CartesianContextProvider({ xAxis: inXAxis, yAxis: inYAxis, dataset, children }) { const formattedSeries = React.useContext(_SeriesContextProvider.SeriesContext); const drawingArea = React.useContext(_DrawingProvider.DrawingContext); const xAxis = React.useMemo(() => inXAxis?.map(axisConfig => { const dataKey = axisConfig.dataKey; if (dataKey === undefined || axisConfig.data !== undefined) { return axisConfig; } if (dataset === undefined) { throw Error('MUI-X-Charts: x-axis uses `dataKey` but no `dataset` is provided.'); } return (0, _extends2.default)({}, axisConfig, { data: dataset.map(d => d[dataKey]) }); }), [inXAxis, dataset]); const yAxis = React.useMemo(() => inYAxis?.map(axisConfig => { const dataKey = axisConfig.dataKey; if (dataKey === undefined || axisConfig.data !== undefined) { return axisConfig; } if (dataset === undefined) { throw Error('MUI-X-Charts: y-axis uses `dataKey` but no `dataset` is provided.'); } return (0, _extends2.default)({}, axisConfig, { data: dataset.map(d => d[dataKey]) }); }), [inYAxis, dataset]); const value = React.useMemo(() => { const axisExtremumCallback = (acc, chartType, axis, getters, isDefaultAxis) => { const getter = getters[chartType]; const series = formattedSeries[chartType]?.series ?? {}; const [minChartTypeData, maxChartTypeData] = getter({ series, axis, isDefaultAxis }); const [minData, maxData] = acc; if (minData === null || maxData === null) { return [minChartTypeData, maxChartTypeData]; } if (minChartTypeData === null || maxChartTypeData === null) { return [minData, maxData]; } return [Math.min(minChartTypeData, minData), Math.max(maxChartTypeData, maxData)]; }; const getAxisExtremum = (axis, getters, isDefaultAxis) => { const charTypes = Object.keys(getters); return charTypes.reduce((acc, charType) => axisExtremumCallback(acc, charType, axis, getters, isDefaultAxis), [null, null]); }; const allXAxis = [...(xAxis?.map((axis, index) => (0, _extends2.default)({ id: `deaultized-x-axis-${index}` }, axis)) ?? []), // Allows to specify an axis with id=DEFAULT_X_AXIS_KEY ...(xAxis === undefined || xAxis.findIndex(({ id }) => id === _constants.DEFAULT_X_AXIS_KEY) === -1 ? [{ id: _constants.DEFAULT_X_AXIS_KEY, scaleType: 'linear' }] : [])]; const completedXAxis = {}; allXAxis.forEach((axis, axisIndex) => { const isDefaultAxis = axisIndex === 0; const [minData, maxData] = getAxisExtremum(axis, xExtremumGetters, isDefaultAxis); const range = [drawingArea.left, drawingArea.left + drawingArea.width]; if ((0, _axis.isBandScaleConfig)(axis)) { const categoryGapRatio = axis.categoryGapRatio ?? DEFAULT_CATEGORY_GAP_RATIO; const barGapRatio = axis.barGapRatio ?? DEFAULT_BAR_GAP_RATIO; completedXAxis[axis.id] = (0, _extends2.default)({ categoryGapRatio, barGapRatio }, axis, { scale: (0, _d3Scale.scaleBand)(axis.data, range).paddingInner(categoryGapRatio).paddingOuter(categoryGapRatio / 2), tickNumber: axis.data.length }); } if ((0, _axis.isPointScaleConfig)(axis)) { completedXAxis[axis.id] = (0, _extends2.default)({}, axis, { scale: (0, _d3Scale.scalePoint)(axis.data, range), tickNumber: axis.data.length }); } if (axis.scaleType === 'band' || axis.scaleType === 'point') { // Could be merged with the two previous "if conditions" but then TS does not get that `axis.scaleType` can't be `band` or `point`. return; } const scaleType = axis.scaleType ?? 'linear'; const extremums = [axis.min ?? minData, axis.max ?? maxData]; const tickNumber = (0, _useTicks.getTickNumber)((0, _extends2.default)({}, axis, { range, domain: extremums })); const niceScale = (0, _getScale.getScale)(scaleType, extremums, range).nice(tickNumber); const niceDomain = niceScale.domain(); const domain = [axis.min ?? niceDomain[0], axis.max ?? niceDomain[1]]; completedXAxis[axis.id] = (0, _extends2.default)({}, axis, { scaleType, scale: niceScale.domain(domain), tickNumber }); }); const allYAxis = [...(yAxis?.map((axis, index) => (0, _extends2.default)({ id: `deaultized-y-axis-${index}` }, axis)) ?? []), ...(yAxis === undefined || yAxis.findIndex(({ id }) => id === _constants.DEFAULT_Y_AXIS_KEY) === -1 ? [{ id: _constants.DEFAULT_Y_AXIS_KEY, scaleType: 'linear' }] : [])]; const completedYAxis = {}; allYAxis.forEach((axis, axisIndex) => { const isDefaultAxis = axisIndex === 0; const [minData, maxData] = getAxisExtremum(axis, yExtremumGetters, isDefaultAxis); const range = [drawingArea.top + drawingArea.height, drawingArea.top]; if ((0, _axis.isBandScaleConfig)(axis)) { const categoryGapRatio = axis.categoryGapRatio ?? DEFAULT_CATEGORY_GAP_RATIO; completedYAxis[axis.id] = (0, _extends2.default)({ categoryGapRatio, barGapRatio: 0 }, axis, { scale: (0, _d3Scale.scaleBand)(axis.data, [range[1], range[0]]).paddingInner(categoryGapRatio).paddingOuter(categoryGapRatio / 2), tickNumber: axis.data.length }); } if ((0, _axis.isPointScaleConfig)(axis)) { completedYAxis[axis.id] = (0, _extends2.default)({}, axis, { scale: (0, _d3Scale.scalePoint)(axis.data, [range[1], range[0]]), tickNumber: axis.data.length }); } if (axis.scaleType === 'band' || axis.scaleType === 'point') { // Could be merged with the two previous "if conditions" but then TS does not get that `axis.scaleType` can't be `band` or `point`. return; } const scaleType = axis.scaleType ?? 'linear'; const extremums = [axis.min ?? minData, axis.max ?? maxData]; const tickNumber = (0, _useTicks.getTickNumber)((0, _extends2.default)({}, axis, { range, domain: extremums })); const niceScale = (0, _getScale.getScale)(scaleType, extremums, range).nice(tickNumber); const niceDomain = niceScale.domain(); const domain = [axis.min ?? niceDomain[0], axis.max ?? niceDomain[1]]; completedYAxis[axis.id] = (0, _extends2.default)({}, axis, { scaleType, scale: niceScale.domain(domain), tickNumber }); }); return { xAxis: completedXAxis, yAxis: completedYAxis, xAxisIds: allXAxis.map(({ id }) => id), yAxisIds: allYAxis.map(({ id }) => id) }; }, [drawingArea.height, drawingArea.left, drawingArea.top, drawingArea.width, formattedSeries, xAxis, yAxis]); // @ts-ignore return /*#__PURE__*/(0, _jsxRuntime.jsx)(CartesianContext.Provider, { value: value, children: children }); } process.env.NODE_ENV !== "production" ? CartesianContextProvider.propTypes = { // ----------------------------- Warning -------------------------------- // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit the TypeScript types and run "yarn proptypes" | // ---------------------------------------------------------------------- children: _propTypes.default.node, /** * An array of objects that can be used to populate series and axes data using their `dataKey` property. */ dataset: _propTypes.default.arrayOf(_propTypes.default.object), /** * The configuration of the x-axes. * If not provided, a default axis config is used with id set to `DEFAULT_X_AXIS_KEY`. */ xAxis: _propTypes.default.arrayOf(_propTypes.default.shape({ axisId: _propTypes.default.string, classes: _propTypes.default.object, data: _propTypes.default.array, dataKey: _propTypes.default.string, disableLine: _propTypes.default.bool, disableTicks: _propTypes.default.bool, fill: _propTypes.default.string, hideTooltip: _propTypes.default.bool, id: _propTypes.default.string, label: _propTypes.default.string, labelFontSize: _propTypes.default.number, labelStyle: _propTypes.default.object, max: _propTypes.default.oneOfType([_propTypes.default.instanceOf(Date), _propTypes.default.number]), min: _propTypes.default.oneOfType([_propTypes.default.instanceOf(Date), _propTypes.default.number]), position: _propTypes.default.oneOf(['bottom', 'left', 'right', 'top']), scaleType: _propTypes.default.oneOf(['band', 'linear', 'log', 'point', 'pow', 'sqrt', 'time', 'utc']), slotProps: _propTypes.default.object, slots: _propTypes.default.object, stroke: _propTypes.default.string, tickFontSize: _propTypes.default.number, tickInterval: _propTypes.default.oneOfType([_propTypes.default.oneOf(['auto']), _propTypes.default.array, _propTypes.default.func]), tickLabelInterval: _propTypes.default.oneOfType([_propTypes.default.oneOf(['auto']), _propTypes.default.func]), tickLabelStyle: _propTypes.default.object, tickMaxStep: _propTypes.default.number, tickMinStep: _propTypes.default.number, tickNumber: _propTypes.default.number, tickSize: _propTypes.default.number, valueFormatter: _propTypes.default.func })), /** * The configuration of the y-axes. * If not provided, a default axis config is used with id set to `DEFAULT_Y_AXIS_KEY`. */ yAxis: _propTypes.default.arrayOf(_propTypes.default.shape({ axisId: _propTypes.default.string, classes: _propTypes.default.object, data: _propTypes.default.array, dataKey: _propTypes.default.string, disableLine: _propTypes.default.bool, disableTicks: _propTypes.default.bool, fill: _propTypes.default.string, hideTooltip: _propTypes.default.bool, id: _propTypes.default.string, label: _propTypes.default.string, labelFontSize: _propTypes.default.number, labelStyle: _propTypes.default.object, max: _propTypes.default.oneOfType([_propTypes.default.instanceOf(Date), _propTypes.default.number]), min: _propTypes.default.oneOfType([_propTypes.default.instanceOf(Date), _propTypes.default.number]), position: _propTypes.default.oneOf(['bottom', 'left', 'right', 'top']), scaleType: _propTypes.default.oneOf(['band', 'linear', 'log', 'point', 'pow', 'sqrt', 'time', 'utc']), slotProps: _propTypes.default.object, slots: _propTypes.default.object, stroke: _propTypes.default.string, tickFontSize: _propTypes.default.number, tickInterval: _propTypes.default.oneOfType([_propTypes.default.oneOf(['auto']), _propTypes.default.array, _propTypes.default.func]), tickLabelInterval: _propTypes.default.oneOfType([_propTypes.default.oneOf(['auto']), _propTypes.default.func]), tickLabelStyle: _propTypes.default.object, tickMaxStep: _propTypes.default.number, tickMinStep: _propTypes.default.number, tickNumber: _propTypes.default.number, tickSize: _propTypes.default.number, valueFormatter: _propTypes.default.func })) } : void 0;