UNPKG

@patternfly/react-charts

Version:

This library provides a set of React chart components for use with the PatternFly reference implementation.

255 lines • 16.1 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { cloneElement, Fragment, useEffect } from 'react'; import hoistNonReactStatics from 'hoist-non-react-statics'; import { VictoryChart } from 'victory-chart'; import { getComparativeMeasureErrorWidth, getComparativeMeasureWidth, getComparativeMeasureWarningWidth, getPrimaryDotMeasureSize, getPrimarySegmentedMeasureWidth, getQualitativeRangeBarWidth } from './utils/chart-bullet-size'; import { ChartAxis } from '../ChartAxis/ChartAxis'; import { ChartBulletTitle } from './ChartBulletTitle'; import { ChartContainer } from '../ChartContainer/ChartContainer'; import { ChartLegend } from '../ChartLegend/ChartLegend'; import { ChartTooltip } from '../ChartTooltip/ChartTooltip'; import { ChartBulletStyles } from '../ChartTheme/ChartStyles'; import { getComputedLegend, getLegendItemsExtraHeight, getLegendMaxTextWidth } from '../ChartUtils/chart-legend'; import { ChartBulletComparativeErrorMeasure } from './ChartBulletComparativeErrorMeasure'; import { ChartBulletComparativeMeasure } from './ChartBulletComparativeMeasure'; import { ChartBulletComparativeWarningMeasure } from './ChartBulletComparativeWarningMeasure'; import { ChartBulletGroupTitle } from './ChartBulletGroupTitle'; import { ChartBulletPrimaryDotMeasure } from './ChartBulletPrimaryDotMeasure'; import { ChartBulletPrimarySegmentedMeasure } from './ChartBulletPrimarySegmentedMeasure'; import { ChartBulletQualitativeRange } from './ChartBulletQualitativeRange'; import { getBulletDomain } from './utils/chart-bullet-domain'; import { getBulletThemeWithLegendColorScale } from './utils/chart-bullet-theme'; import { getPaddingForSide } from '../ChartUtils/chart-padding'; import { ChartPoint } from '../ChartPoint/ChartPoint'; import { ChartLabel } from '../ChartLabel/ChartLabel'; export const ChartBullet = ({ allowTooltip = true, ariaDesc, ariaTitle, axisComponent = _jsx(ChartAxis, {}), comparativeErrorMeasureComponent = _jsx(ChartBulletComparativeErrorMeasure, {}), comparativeErrorMeasureData, comparativeErrorMeasureDataY, comparativeErrorMeasureLegendData, comparativeWarningMeasureComponent = _jsx(ChartBulletComparativeWarningMeasure, {}), comparativeWarningMeasureData, comparativeWarningMeasureDataY, comparativeWarningMeasureLegendData, comparativeZeroMeasureComponent = _jsx(ChartBulletComparativeMeasure, {}), constrainToVisibleArea = false, groupTitleComponent = _jsx(ChartBulletGroupTitle, {}), groupSubTitle, groupTitle, horizontal = true, invert = false, labels, legendAllowWrap = false, legendComponent = _jsx(ChartLegend, {}), legendItemsPerRow, legendPosition = 'bottom', legendDirection = 'ltr', maxDomain, minDomain, name, padding, primaryDotMeasureComponent = _jsx(ChartBulletPrimaryDotMeasure, {}), primaryDotMeasureData, primaryDotMeasureDataY, primaryDotMeasureLegendData, primarySegmentedMeasureComponent = _jsx(ChartBulletPrimarySegmentedMeasure, {}), primarySegmentedMeasureData, primarySegmentedMeasureDataY, primarySegmentedMeasureLegendData, qualitativeRangeComponent = _jsx(ChartBulletQualitativeRange, {}), qualitativeRangeData, qualitativeRangeDataY, qualitativeRangeDataY0, qualitativeRangeLegendData, standalone = true, subTitle, themeColor, title, titleComponent = _jsx(ChartBulletTitle, {}), titlePosition, // destructure last theme = getBulletThemeWithLegendColorScale({ comparativeErrorMeasureData, comparativeErrorMeasureLegendData, comparativeWarningMeasureData, comparativeWarningMeasureLegendData, invert, primaryDotMeasureData, primaryDotMeasureLegendData, primarySegmentedMeasureData, primarySegmentedMeasureLegendData, qualitativeRangeData, qualitativeRangeLegendData, themeColor }), domain = getBulletDomain({ comparativeErrorMeasureComponent, comparativeErrorMeasureData, comparativeWarningMeasureComponent, comparativeWarningMeasureData, maxDomain, minDomain, primaryDotMeasureComponent, primaryDotMeasureData, primarySegmentedMeasureComponent, primarySegmentedMeasureData, qualitativeRangeComponent, qualitativeRangeData }), legendOrientation = theme.legend.orientation, height = horizontal ? theme.chart.height : theme.chart.width, width = horizontal ? theme.chart.width : theme.chart.height, bulletSize = theme.chart.height }) => { // Note that we're using a fixed bullet height width to align components. const chartSize = { height: horizontal ? bulletSize : height, width: horizontal ? width : bulletSize }; const defaultPadding = { bottom: getPaddingForSide('bottom', padding, theme.chart.padding), left: getPaddingForSide('left', padding, theme.chart.padding), right: getPaddingForSide('right', padding, theme.chart.padding), top: getPaddingForSide('top', padding, theme.chart.padding) }; // Bullet group title const bulletGroupTitle = cloneElement(groupTitleComponent, Object.assign(Object.assign(Object.assign({ height }, (name && { name: `${name}-${groupTitleComponent.type.displayName}` })), { standalone: false, subTitle: groupSubTitle, title: groupTitle, themeColor, width }), groupTitleComponent.props)); // Bullet title const bulletTitle = cloneElement(titleComponent, Object.assign(Object.assign(Object.assign({ height, horizontal, legendPosition }, (name && { name: `${name}-${titleComponent.type.displayName}` })), { padding, standalone: false, subTitle, theme, themeColor, title, titlePosition, width }), titleComponent.props)); // Comparative error measure const comparativeErrorMeasure = cloneElement(comparativeErrorMeasureComponent, Object.assign({ allowTooltip, barWidth: getComparativeMeasureErrorWidth({ height: chartSize.height, horizontal, themeColor, width: chartSize.width }), constrainToVisibleArea, data: comparativeErrorMeasureData, domain, height: chartSize.height, horizontal, labelComponent: allowTooltip ? _jsx(ChartTooltip, { height: height, theme: theme, width: width }) : undefined, labels, padding, standalone: false, themeColor, width: chartSize.width, y: comparativeErrorMeasureDataY }, comparativeErrorMeasureComponent.props)); // Comparative warning measure const comparativeWarningMeasure = cloneElement(comparativeWarningMeasureComponent, Object.assign({ allowTooltip, barWidth: getComparativeMeasureWarningWidth({ height: chartSize.height, horizontal, themeColor, width: chartSize.width }), constrainToVisibleArea, data: comparativeWarningMeasureData, domain, height: chartSize.height, horizontal, labelComponent: allowTooltip ? _jsx(ChartTooltip, { height: height, theme: theme, width: width }) : undefined, labels, padding, standalone: false, themeColor, width: chartSize.width, y: comparativeWarningMeasureDataY }, comparativeWarningMeasureComponent.props)); // Comparative zero measure const comparativeZeroMeasure = cloneElement(comparativeZeroMeasureComponent, Object.assign({ barWidth: getComparativeMeasureWidth({ height: chartSize.height, horizontal, themeColor, width: chartSize.width }), data: [{ y: 0 }], domain, height: chartSize.height, horizontal, padding, standalone: false, themeColor, width: chartSize.width }, comparativeZeroMeasureComponent.props)); let legendXOffset = 0; if (legendDirection === 'rtl') { legendXOffset = getLegendMaxTextWidth([ ...(primaryDotMeasureLegendData ? primaryDotMeasureLegendData : []), ...(primarySegmentedMeasureLegendData ? primarySegmentedMeasureLegendData : []), ...(comparativeWarningMeasureLegendData ? comparativeWarningMeasureLegendData : []), ...(comparativeErrorMeasureLegendData ? comparativeErrorMeasureLegendData : []), ...(qualitativeRangeLegendData ? qualitativeRangeLegendData : []) ], theme); } // Legend const legend = cloneElement(legendComponent, Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ data: [ ...(primaryDotMeasureLegendData ? primaryDotMeasureLegendData : []), ...(primarySegmentedMeasureLegendData ? primarySegmentedMeasureLegendData : []), ...(comparativeWarningMeasureLegendData ? comparativeWarningMeasureLegendData : []), ...(comparativeErrorMeasureLegendData ? comparativeErrorMeasureLegendData : []), ...(qualitativeRangeLegendData ? qualitativeRangeLegendData : []) ] }, (name && { name: `${name}-${legendComponent.type.displayName}` })), { itemsPerRow: legendItemsPerRow, orientation: legendOrientation, position: legendPosition, theme, themeColor }), (legendDirection === 'rtl' && { dataComponent: legendComponent.props.dataComponent ? (cloneElement(legendComponent.props.dataComponent, { transform: `translate(${legendXOffset})` })) : (_jsx(ChartPoint, { transform: `translate(${legendXOffset})` })) })), (legendDirection === 'rtl' && { labelComponent: legendComponent.props.labelComponent ? (cloneElement(legendComponent.props.labelComponent, { direction: 'rtl', dx: legendXOffset - 30 })) : (_jsx(ChartLabel, { direction: "rtl", dx: legendXOffset - 30 })) })), legendComponent.props)); // Primary dot measure const primaryDotMeasure = cloneElement(primaryDotMeasureComponent, Object.assign({ allowTooltip, constrainToVisibleArea, data: primaryDotMeasureData, domain, height: chartSize.height, horizontal, invert, labelComponent: allowTooltip ? _jsx(ChartTooltip, { height: height, theme: theme, width: width }) : undefined, labels, padding, size: getPrimaryDotMeasureSize({ height: chartSize.height, horizontal, themeColor, width: chartSize.width }), standalone: false, themeColor, width: chartSize.width, y: primaryDotMeasureDataY }, primaryDotMeasureComponent.props)); // Primary segmented measure const primarySegmentedMeasure = cloneElement(primarySegmentedMeasureComponent, Object.assign({ allowTooltip, constrainToVisibleArea, barWidth: getPrimarySegmentedMeasureWidth({ height: chartSize.height, horizontal, themeColor, width: chartSize.width }), data: primarySegmentedMeasureData, domain, height: chartSize.height, horizontal, invert, labelComponent: allowTooltip ? _jsx(ChartTooltip, { height: height, theme: theme, width: width }) : undefined, labels, padding, standalone: false, themeColor, width: chartSize.width, y: primarySegmentedMeasureDataY }, primarySegmentedMeasureComponent.props)); // Qualitative range const qualitativeRange = cloneElement(qualitativeRangeComponent, Object.assign({ allowTooltip, constrainToVisibleArea, barWidth: getQualitativeRangeBarWidth({ height: chartSize.height, horizontal, themeColor, width: chartSize.width }), data: qualitativeRangeData, domain, height: chartSize.height, horizontal, invert, labelComponent: allowTooltip ? _jsx(ChartTooltip, { height: height, theme: theme, width: width }) : undefined, labels, padding, standalone: false, themeColor, width: chartSize.width, y: qualitativeRangeDataY, y0: qualitativeRangeDataY0 }, qualitativeRangeComponent.props)); // Returns tick values -- Victory doesn't include min/max domain const getTickValues = (minVal, maxVal) => { const tickValues = [minVal, maxVal]; let range = 0; if (minVal < 0 && maxVal < 0) { range = Math.abs(minVal - maxVal); } else if (minVal < 0) { range = Math.abs(minVal) + maxVal; } else { range = maxVal - minVal; } const tickInterval = range / (ChartBulletStyles.axisTickCount - 1); for (let i = minVal; i < maxVal;) { i += tickInterval; tickValues.push(Math.ceil(i)); } return tickValues; }; // Returns a computed legend const getLegend = () => { if (!legend.props.data) { return null; } let dx = 0; let dy = 0; // Adjust for padding if (legendPosition === 'bottom') { if (horizontal) { dy = defaultPadding.top * 0.5 + (defaultPadding.bottom * 0.5 - defaultPadding.bottom) - 25; } else if (title) { dy = -defaultPadding.bottom + 60; } else { dy = -defaultPadding.bottom; } } else if (legendPosition === 'bottom-left') { if (horizontal) { dy = defaultPadding.top * 0.5 + (defaultPadding.bottom * 0.5 - defaultPadding.bottom) - 25; } else if (title) { dy = -defaultPadding.bottom + 60; } else { dy = -defaultPadding.bottom; } dx = -10; } return getComputedLegend({ allowWrap: legendAllowWrap === true || typeof legendAllowWrap === 'function', chartType: 'bullet', dx, dy, height: chartSize.height, legendComponent: legend, padding: defaultPadding, position: legendPosition, theme, width: chartSize.width }); }; // Returns comparative zero measure const getComparativeZeroMeasure = () => { const _domain = domain; let low = 0; if (Array.isArray(_domain)) { low = _domain[0]; } else if (_domain.y && Array.isArray(_domain.y)) { low = _domain.y[0]; } let high = 0; if (Array.isArray(_domain)) { high = _domain[_domain.length - 1]; } else if (_domain.y && Array.isArray(_domain.y)) { high = _domain.y[_domain.y.length - 1]; } if (low < 0 && high > 0) { return comparativeZeroMeasure; } return null; }; // Axis component for custom tick values const axis = cloneElement(axisComponent, Object.assign(Object.assign(Object.assign({ dependentAxis: horizontal ? false : true, domain: !horizontal ? domain : { x: domain.y, y: domain.x }, height: chartSize.height }, (name && { name: `${name}-${axisComponent.type.displayName}` })), { // Adjust for padding offsetX: !horizontal ? defaultPadding.left * 0.5 + (defaultPadding.right * 0.5 - (defaultPadding.right - 55)) : 0, offsetY: horizontal ? 80 - defaultPadding.top * 0.5 + (defaultPadding.bottom * 0.5 - 25) : 0, padding, standalone: false, themeColor, tickCount: ChartBulletStyles.axisTickCount, tickValues: getTickValues(domain.y[0], domain.y[1]), width: chartSize.width }), axisComponent.props)); const computedLegend = getLegend(); const bulletChart = (_jsxs(Fragment, { children: [axis, bulletGroupTitle, bulletTitle, qualitativeRange, primarySegmentedMeasure, primaryDotMeasure, comparativeErrorMeasure, comparativeWarningMeasure, getComparativeZeroMeasure(), computedLegend] })); // Callback to compliment legendAllowWrap useEffect(() => { if (typeof legendAllowWrap === 'function') { const extraHeight = getLegendItemsExtraHeight({ legendData: computedLegend.props.data, legendOrientation: computedLegend.props.orientation, legendProps: computedLegend.props, theme }); legendAllowWrap(extraHeight); } }, [computedLegend, legendAllowWrap, theme, width]); return standalone ? (_jsx(ChartContainer, { desc: ariaDesc, height: height, title: ariaTitle, theme: theme, width: width, children: bulletChart })) : (_jsx(Fragment, { children: bulletChart })); }; ChartBullet.displayName = 'ChartBullet'; hoistNonReactStatics(ChartBullet, VictoryChart); //# sourceMappingURL=ChartBullet.js.map