UNPKG

@mui/x-charts

Version:

The community edition of MUI X Charts components.

381 lines (377 loc) 14.2 kB
"use strict"; 'use client'; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChartsYAxis = ChartsYAxis; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); var React = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _useSlotProps = _interopRequireDefault(require("@mui/utils/useSlotProps")); var _composeClasses = _interopRequireDefault(require("@mui/utils/composeClasses")); var _styles = require("@mui/material/styles"); var _RtlProvider = require("@mui/system/RtlProvider"); var _useIsHydrated = require("../hooks/useIsHydrated"); var _defaultTextPlacement = require("../ChartsText/defaultTextPlacement"); var _ellipsize = require("../internals/ellipsize"); var _domUtils = require("../internals/domUtils"); var _useTicks = require("../hooks/useTicks"); var _useDrawingArea = require("../hooks/useDrawingArea"); var _AxisSharedComponents = require("../internals/components/AxisSharedComponents"); var _ChartsText = require("../ChartsText"); var _axisClasses = require("../ChartsAxis/axisClasses"); var _isInfinity = require("../internals/isInfinity"); var _isBandScale = require("../internals/isBandScale"); var _ChartProvider = require("../context/ChartProvider"); var _hooks = require("../hooks"); var _clampAngle = require("../internals/clampAngle"); var _invertTextAnchor = require("../internals/invertTextAnchor"); var _jsxRuntime = require("react/jsx-runtime"); const _excluded = ["scale", "tickNumber"]; const useUtilityClasses = ownerState => { const { classes, position, id } = ownerState; const slots = { root: ['root', 'directionY', position, `id-${id}`], line: ['line'], tickContainer: ['tickContainer'], tick: ['tick'], tickLabel: ['tickLabel'], label: ['label'] }; return (0, _composeClasses.default)(slots, _axisClasses.getAxisUtilityClass, classes); }; /* Gap between a tick and its label. */ const TICK_LABEL_GAP = 2; /* Gap between the axis label and tick labels. */ const AXIS_LABEL_TICK_LABEL_GAP = 2; function shortenLabels(visibleLabels, drawingArea, maxWidth, isRtl, tickLabelStyle) { const shortenedLabels = new Map(); const angle = (0, _clampAngle.clampAngle)(tickLabelStyle?.angle ?? 0); let topBoundFactor = 1; let bottomBoundFactor = 1; if (tickLabelStyle?.textAnchor === 'start') { topBoundFactor = Infinity; bottomBoundFactor = 1; } else if (tickLabelStyle?.textAnchor === 'end') { topBoundFactor = 1; bottomBoundFactor = Infinity; } else { topBoundFactor = 2; bottomBoundFactor = 2; } if (angle > 180) { [topBoundFactor, bottomBoundFactor] = [bottomBoundFactor, topBoundFactor]; } if (isRtl) { [topBoundFactor, bottomBoundFactor] = [bottomBoundFactor, topBoundFactor]; } for (const item of visibleLabels) { if (item.formattedValue) { // That maximum height of the tick depends on its proximity to the axis bounds. const height = Math.min((item.offset + item.labelOffset) * topBoundFactor, (drawingArea.top + drawingArea.height + drawingArea.bottom - item.offset - item.labelOffset) * bottomBoundFactor); const doesTextFit = text => (0, _ellipsize.doesTextFitInRect)(text, { width: maxWidth, height, angle, measureText: string => (0, _domUtils.getStringSize)(string, tickLabelStyle) }); shortenedLabels.set(item, (0, _ellipsize.ellipsize)(item.formattedValue.toString(), doesTextFit)); } } return shortenedLabels; } const YAxisRoot = (0, _styles.styled)(_AxisSharedComponents.AxisRoot, { name: 'MuiChartsYAxis', slot: 'Root' })({}); const defaultProps = { disableLine: false, disableTicks: false, tickSize: 6 }; /** * Demos: * * - [Axis](https://mui.com/x/react-charts/axis/) * * API: * * - [ChartsYAxis API](https://mui.com/x/api/charts/charts-y-axis/) */ function ChartsYAxis(inProps) { const { yAxisIds, yAxis } = (0, _hooks.useYAxes)(); const _yAxis = yAxis[inProps.axisId ?? yAxisIds[0]], { scale: yScale, tickNumber } = _yAxis, settings = (0, _objectWithoutPropertiesLoose2.default)(_yAxis, _excluded); const themedProps = (0, _styles.useThemeProps)({ props: (0, _extends2.default)({}, settings, inProps), name: 'MuiChartsYAxis' }); const defaultizedProps = (0, _extends2.default)({}, defaultProps, themedProps); const { position, disableLine, disableTicks, label, labelStyle, tickLabelStyle, tickSize: tickSizeProp, valueFormatter, slots, slotProps, tickPlacement, tickLabelPlacement, tickInterval, tickLabelInterval, sx, offset, width: axisWidth } = defaultizedProps; const theme = (0, _styles.useTheme)(); const isRtl = (0, _RtlProvider.useRtl)(); const isHydrated = (0, _useIsHydrated.useIsHydrated)(); const classes = useUtilityClasses(defaultizedProps); const { instance } = (0, _ChartProvider.useChartContext)(); const drawingArea = (0, _useDrawingArea.useDrawingArea)(); const { left, top, width, height } = drawingArea; const tickSize = disableTicks ? 4 : tickSizeProp; const yTicks = (0, _useTicks.useTicks)({ scale: yScale, tickNumber, valueFormatter, tickPlacement, tickLabelPlacement, tickInterval, direction: 'y' }); const positionSign = position === 'right' ? 1 : -1; const tickFontSize = typeof tickLabelStyle?.fontSize === 'number' ? tickLabelStyle.fontSize : 12; const Line = slots?.axisLine ?? 'line'; const Tick = slots?.axisTick ?? 'line'; const TickLabel = slots?.axisTickLabel ?? _ChartsText.ChartsText; const Label = slots?.axisLabel ?? _ChartsText.ChartsText; const defaultTextAnchor = (0, _defaultTextPlacement.getDefaultTextAnchor)((position === 'right' ? -90 : 90) - (tickLabelStyle?.angle ?? 0)); const defaultDominantBaseline = (0, _defaultTextPlacement.getDefaultBaseline)((position === 'right' ? -90 : 90) - (tickLabelStyle?.angle ?? 0)); const axisTickLabelProps = (0, _useSlotProps.default)({ elementType: TickLabel, externalSlotProps: slotProps?.axisTickLabel, additionalProps: { style: (0, _extends2.default)({}, theme.typography.caption, { fontSize: tickFontSize, textAnchor: isRtl ? (0, _invertTextAnchor.invertTextAnchor)(defaultTextAnchor) : defaultTextAnchor, dominantBaseline: defaultDominantBaseline }, tickLabelStyle) }, className: classes.tickLabel, ownerState: {} }); const axisLabelProps = (0, _useSlotProps.default)({ elementType: Label, externalSlotProps: slotProps?.axisLabel, additionalProps: { style: (0, _extends2.default)({}, theme.typography.body1, { lineHeight: 1, fontSize: 14, angle: positionSign * 90, textAnchor: 'middle', dominantBaseline: 'text-before-edge' }, labelStyle) }, ownerState: {} }); const lineSlotProps = (0, _useSlotProps.default)({ elementType: Line, externalSlotProps: slotProps?.axisLine, additionalProps: { strokeLinecap: 'square' }, ownerState: {} }); const domain = yScale.domain(); const ordinalAxis = (0, _isBandScale.isBandScale)(yScale); // Skip axis rendering if no data is available // - The domain is an empty array for band/point scales. // - The domains contains Infinity for continuous scales. // - The position is 'none'. if (ordinalAxis && domain.length === 0 || !ordinalAxis && domain.some(_isInfinity.isInfinity) || position === 'none') { return null; } const labelRefPoint = { x: positionSign * axisWidth, y: top + height / 2 }; /* If there's an axis title, the tick labels have less space to render */ const tickLabelsMaxWidth = Math.max(0, axisWidth - (label ? (0, _domUtils.getStringSize)(label, axisLabelProps.style).height + AXIS_LABEL_TICK_LABEL_GAP : 0) - tickSize - TICK_LABEL_GAP); const tickLabels = isHydrated ? shortenLabels(yTicks, drawingArea, tickLabelsMaxWidth, isRtl, axisTickLabelProps.style) : new Map(Array.from(yTicks).map(item => [item, item.formattedValue])); return /*#__PURE__*/(0, _jsxRuntime.jsxs)(YAxisRoot, { transform: `translate(${position === 'right' ? left + width + offset : left - offset}, 0)`, className: classes.root, sx: sx, children: [!disableLine && /*#__PURE__*/(0, _jsxRuntime.jsx)(Line, (0, _extends2.default)({ y1: top, y2: top + height, className: classes.line }, lineSlotProps)), yTicks.map((item, index) => { const { offset: tickOffset, labelOffset, value } = item; const xTickLabel = positionSign * (tickSize + TICK_LABEL_GAP); const yTickLabel = labelOffset; const skipLabel = typeof tickLabelInterval === 'function' && !tickLabelInterval?.(value, index); const showLabel = instance.isYInside(tickOffset); const tickLabel = tickLabels.get(item); if (!showLabel) { return null; } return /*#__PURE__*/(0, _jsxRuntime.jsxs)("g", { transform: `translate(0, ${tickOffset})`, className: classes.tickContainer, children: [!disableTicks && /*#__PURE__*/(0, _jsxRuntime.jsx)(Tick, (0, _extends2.default)({ x2: positionSign * tickSize, className: classes.tick }, slotProps?.axisTick)), tickLabel !== undefined && !skipLabel && /*#__PURE__*/(0, _jsxRuntime.jsx)(TickLabel, (0, _extends2.default)({ x: xTickLabel, y: yTickLabel, text: tickLabel }, axisTickLabelProps))] }, index); }), label && isHydrated && /*#__PURE__*/(0, _jsxRuntime.jsx)("g", { className: classes.label, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Label, (0, _extends2.default)({}, labelRefPoint, axisLabelProps, { text: label })) })] }); } process.env.NODE_ENV !== "production" ? ChartsYAxis.propTypes = { // ----------------------------- Warning -------------------------------- // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit the TypeScript types and run "pnpm proptypes" | // ---------------------------------------------------------------------- axis: _propTypes.default.oneOf(['y']), /** * The id of the axis to render. * If undefined, it will be the first defined axis. */ axisId: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]), /** * Override or extend the styles applied to the component. */ classes: _propTypes.default.object, /** * If true, the axis line is disabled. * @default false */ disableLine: _propTypes.default.bool, /** * If true, the ticks are disabled. * @default false */ disableTicks: _propTypes.default.bool, /** * The fill color of the axis text. * @default 'currentColor' */ fill: _propTypes.default.string, /** * The label of the axis. */ label: _propTypes.default.string, /** * The style applied to the axis label. */ labelStyle: _propTypes.default.object, /** * The props used for each component slot. * @default {} */ slotProps: _propTypes.default.object, /** * Overridable component slots. * @default {} */ slots: _propTypes.default.object, /** * The stroke color of the axis line. * @default 'currentColor' */ stroke: _propTypes.default.string, sx: _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object, _propTypes.default.bool])), _propTypes.default.func, _propTypes.default.object]), /** * Defines which ticks are displayed. * Its value can be: * - 'auto' In such case the ticks are computed based on axis scale and other parameters. * - a filtering function of the form `(value, index) => boolean` which is available only if the axis has "point" scale. * - an array containing the values where ticks should be displayed. * @see See {@link https://mui.com/x/react-charts/axis/#fixed-tick-positions} * @default 'auto' */ tickInterval: _propTypes.default.oneOfType([_propTypes.default.oneOf(['auto']), _propTypes.default.array, _propTypes.default.func]), /** * Defines which ticks get its label displayed. Its value can be: * - 'auto' In such case, labels are displayed if they do not overlap with the previous one. * - a filtering function of the form (value, index) => boolean. Warning: the index is tick index, not data ones. * @default 'auto' */ tickLabelInterval: _propTypes.default.oneOfType([_propTypes.default.oneOf(['auto']), _propTypes.default.func]), /** * The placement of ticks label. Can be the middle of the band, or the tick position. * Only used if scale is 'band'. * @default 'middle' */ tickLabelPlacement: _propTypes.default.oneOf(['middle', 'tick']), /** * The style applied to ticks text. */ tickLabelStyle: _propTypes.default.object, /** * Maximal step between two ticks. * When using time data, the value is assumed to be in ms. * Not supported by categorical axis (band, points). */ tickMaxStep: _propTypes.default.number, /** * Minimal step between two ticks. * When using time data, the value is assumed to be in ms. * Not supported by categorical axis (band, points). */ tickMinStep: _propTypes.default.number, /** * The number of ticks. This number is not guaranteed. * Not supported by categorical axis (band, points). */ tickNumber: _propTypes.default.number, /** * The placement of ticks in regard to the band interval. * Only used if scale is 'band'. * @default 'extremities' */ tickPlacement: _propTypes.default.oneOf(['end', 'extremities', 'middle', 'start']), /** * The size of the ticks. * @default 6 */ tickSize: _propTypes.default.number } : void 0;