@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
JavaScript
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