Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 31 additions & 7 deletions packages/react-charts/src/components/Chart/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ import {
getPaddingForSide,
getPatternDefs,
getDefaultData,
useDefaultPatternProps
} from '../ChartUtils';
getLegendItemsExtraHeight,
useDefaultPatternProps,
} from "../ChartUtils";
import { useEffect } from "react";

/**
* Chart is a wrapper component that reconciles the domain for all its children, controls the layout of the chart,
Expand Down Expand Up @@ -235,12 +237,20 @@ export interface ChartProps extends VictoryChartProps {
*/
innerRadius?: number;
/**
* Allows legend items to wrap. A value of true allows the legend to wrap onto the next line
* if its container is not wide enough.
* @beta Allows legend items to wrap onto the next line if the chart is not wide enough.
*
* Note that the chart's SVG height and width are 100% by default, so it can be responsive itself. However, if you
* define the height and width of the chart's parent container, you must accommodate for extra legend height due to
* legend items wrapping onto the next line. When the height of the chart's parent container is too small, some legend
* items may not be visible.
*
* Alternatively, a callback function may be provided, which will be called after the legend's itemsPerRow property
* has been calculated. The value provided can be used to increase the chart's parent container height as legend
* items wrap onto the next line. If no adjustment is necessary, the value will be zero.
*
* Note: This is overridden by the legendItemsPerRow property
*/
legendAllowWrap?: boolean;
legendAllowWrap?: boolean | ((extraHeight: number) => void);
/**
* The legend component to render with chart.
*
Expand Down Expand Up @@ -557,7 +567,7 @@ export const Chart: React.FunctionComponent<ChartProps> = ({
}

return getComputedLegend({
allowWrap: legendAllowWrap,
allowWrap: legendAllowWrap === true || typeof legendAllowWrap === 'function',
chartType: 'chart',
colorScale,
dx,
Expand Down Expand Up @@ -594,6 +604,20 @@ export const Chart: React.FunctionComponent<ChartProps> = ({
return child;
});

// Callback to compliment legendAllowWrap
const computedLegend = getLegend();
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]);

// Note: containerComponent is required for theme
return (
<VictoryChart
Expand All @@ -606,7 +630,7 @@ export const Chart: React.FunctionComponent<ChartProps> = ({
{...rest}
>
{renderChildren()}
{getLegend()}
{computedLegend}
{isPatternDefs && getPatternDefs({ patternId, colorScale: defaultColorScale })}
</VictoryChart>
);
Expand Down
36 changes: 30 additions & 6 deletions packages/react-charts/src/components/ChartBullet/ChartBullet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import { ChartContainer } from '../ChartContainer';
import { ChartLegend, ChartLegendOrientation, ChartLegendPosition } from '../ChartLegend';
import { ChartBulletStyles, ChartThemeDefinition } from '../ChartTheme';
import { ChartTooltip } from '../ChartTooltip';
import { getComputedLegend, getPaddingForSide } from '../ChartUtils';
import { getComputedLegend, getLegendItemsExtraHeight, getPaddingForSide } from "../ChartUtils";
import { useEffect } from "react";

/**
* ChartBullet renders a dataset as a bullet chart.
Expand Down Expand Up @@ -207,12 +208,20 @@ export interface ChartBulletProps {
*/
labels?: string[] | number[] | ((data: any) => string | number | null);
/**
* Allows legend items to wrap. A value of true allows the legend to wrap onto the next line
* if its container is not wide enough.
* @beta Allows legend items to wrap onto the next line if the chart is not wide enough.
*
* Note that the chart's SVG height and width are 100% by default, so it can be responsive itself. However, if you
* define the height and width of the chart's parent container, you must accommodate for extra legend height due to
* legend items wrapping onto the next line. When the height of the chart's parent container is too small, some legend
* items may not be visible.
*
* Alternatively, a callback function may be provided, which will be called after the legend's itemsPerRow property
* has been calculated. The value provided can be used to increase the chart's parent container height as legend
* items wrap onto the next line. If no adjustment is necessary, the value will be zero.
*
* Note: This is overridden by the legendItemsPerRow property
*/
legendAllowWrap?: boolean;
legendAllowWrap?: boolean | ((extraHeight: number) => void);
/**
* The legend component to render with chart.
*/
Expand Down Expand Up @@ -766,8 +775,9 @@ export const ChartBullet: React.FunctionComponent<ChartBulletProps> = ({
}
dx = -10;
}

return getComputedLegend({
allowWrap: legendAllowWrap,
allowWrap: legendAllowWrap === true || typeof legendAllowWrap === 'function',
chartType: 'bullet',
dx,
dy,
Expand Down Expand Up @@ -825,6 +835,7 @@ export const ChartBullet: React.FunctionComponent<ChartBulletProps> = ({
...axisComponent.props
});

const computedLegend = getLegend();
const bulletChart = (
<React.Fragment>
{axis}
Expand All @@ -836,10 +847,23 @@ export const ChartBullet: React.FunctionComponent<ChartBulletProps> = ({
{comparativeErrorMeasure}
{comparativeWarningMeasure}
{getComparativeZeroMeasure()}
{getLegend()}
{computedLegend}
</React.Fragment>
);

// 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 ? (
<ChartContainer desc={ariaDesc} height={height} title={ariaTitle} theme={theme} width={width}>
{bulletChart}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,23 @@ class BulletChart extends React.Component {
this.containerRef = React.createRef();
this.observer = () => {};
this.state = {
extraHeight: 0,
width: 0
};
this.handleResize = () => {
if (this.containerRef.current && this.containerRef.current.clientWidth) {
this.setState({ width: this.containerRef.current.clientWidth });
}
};
this.handleLegendAllowWrap = (extraHeight) => {
if (extraHeight !== this.state.extraHeight) {
this.setState({ extraHeight });
}
}
this.getHeight = (baseHeight) => {
const { extraHeight } = this.state;
return baseHeight + extraHeight;
};
}

componentDidMount() {
Expand All @@ -112,17 +122,18 @@ class BulletChart extends React.Component {

render() {
const { width } = this.state;
const height = this.getHeight(200);
return (
<div ref={this.containerRef} style={{ height: '250px' }}>
<div ref={this.containerRef} style={{ height: height + "px" }}>
<ChartBullet
ariaDesc="Storage capacity"
ariaTitle="Bullet chart example"
comparativeWarningMeasureData={[{name: 'Warning', y: 88}]}
comparativeWarningMeasureLegendData={[{ name: 'Warning' }]}
constrainToVisibleArea
height={250}
height={height}
labels={({ datum }) => `${datum.name}: ${datum.y}`}
legendAllowWrap
legendAllowWrap={this.handleLegendAllowWrap}
legendPosition="bottom-left"
maxDomain={{y: 100}}
name="chart3"
Expand Down
16 changes: 11 additions & 5 deletions packages/react-charts/src/components/ChartDonut/ChartDonut.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -308,12 +308,20 @@ export interface ChartDonutProps extends ChartPieProps {
*/
labels?: string[] | number[] | ((data: any) => string | number | null);
/**
* Allows legend items to wrap. A value of true allows the legend to wrap onto the next line
* if its container is not wide enough.
* @beta Allows legend items to wrap onto the next line if the chart is not wide enough.
*
* Note that the chart's SVG height and width are 100% by default, so it can be responsive itself. However, if you
* define the height and width of the chart's parent container, you must accommodate for extra legend height due to
* legend items wrapping onto the next line. When the height of the chart's parent container is too small, some legend
* items may not be visible.
*
* Alternatively, a callback function may be provided, which will be called after the legend's itemsPerRow property
* has been calculated. The value provided can be used to increase the chart's parent container height as legend
* items wrap onto the next line. If no adjustment is necessary, the value will be zero.
*
* Note: This is overridden by the legendItemsPerRow property
*/
legendAllowWrap?: boolean;
legendAllowWrap?: boolean | ((extraHeight: number) => void);
/**
* The legend component to render with chart.
*
Expand Down Expand Up @@ -580,7 +588,6 @@ export const ChartDonut: React.FunctionComponent<ChartDonutProps> = ({
capHeight = 1.1,
containerComponent = <ChartContainer />,
innerRadius,
legendAllowWrap,
legendPosition = ChartCommonStyles.legend.position as ChartPieLegendPosition,
name,
padAngle,
Expand Down Expand Up @@ -706,7 +713,6 @@ export const ChartDonut: React.FunctionComponent<ChartDonutProps> = ({
height={height}
innerRadius={chartInnerRadius > 0 ? chartInnerRadius : 0}
key="pf-chart-donut-pie"
legendAllowWrap={legendAllowWrap}
legendPosition={legendPosition}
name={name}
padAngle={padAngle !== undefined ? padAngle : getPadAngle}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,12 +292,20 @@ export interface ChartDonutUtilizationProps extends ChartDonutProps {
*/
isStatic?: boolean;
/**
* Allows legend items to wrap. A value of true allows the legend to wrap onto the next line
* if its container is not wide enough.
* @beta Allows legend items to wrap onto the next line if the chart is not wide enough.
*
* Note that the chart's SVG height and width are 100% by default, so it can be responsive itself. However, if you
* define the height and width of the chart's parent container, you must accommodate for extra legend height due to
* legend items wrapping onto the next line. When the height of the chart's parent container is too small, some legend
* items may not be visible.
*
* Alternatively, a callback function may be provided, which will be called after the legend's itemsPerRow property
* has been calculated. The value provided can be used to increase the chart's parent container height as legend
* items wrap onto the next line. If no adjustment is necessary, the value will be zero.
*
* Note: This is overridden by the legendItemsPerRow property
*/
legendAllowWrap?: boolean;
legendAllowWrap?: boolean | ((extraHeight: number) => void);
/**
* The labelComponent prop takes in an entire label component which will be used
* to create a label for the area. The new element created from the passed labelComponent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,23 @@ class BulletChart extends React.Component {
this.containerRef = React.createRef();
this.observer = () => {};
this.state = {
extraHeight: 0,
width: 0
};
this.handleResize = () => {
if(this.containerRef.current && this.containerRef.current.clientWidth){
if (this.containerRef.current && this.containerRef.current.clientWidth) {
this.setState({ width: this.containerRef.current.clientWidth });
}
};
this.handleLegendAllowWrap = (extraHeight) => {
if (extraHeight !== this.state.extraHeight) {
this.setState({ extraHeight });
}
}
this.getHeight = (baseHeight) => {
const { extraHeight } = this.state;
return baseHeight + extraHeight;
};
}

componentDidMount() {
Expand All @@ -151,37 +161,36 @@ class BulletChart extends React.Component {

render() {
const { width } = this.state;
const height = this.getHeight(200);
return (
<div ref={this.containerRef}>
<div style={{ height: '250px' }}>
<ChartBullet
ariaDesc="Storage capacity"
ariaTitle="Bullet chart example"
comparativeWarningMeasureData={[{name: 'Warning', y: 88}]}
comparativeWarningMeasureLegendData={[{ name: 'Warning' }]}
constrainToVisibleArea
height={250}
labels={({ datum }) => `${datum.name}: ${datum.y}`}
legendAllowWrap
legendPosition="bottom-left"
maxDomain={{y: 100}}
name="chart3"
padding={{
bottom: 50,
left: 50,
right: 50,
top: 100 // Adjusted to accommodate labels
}}
primarySegmentedMeasureData={[{ name: 'Measure', y: 25 }, { name: 'Measure', y: 60 }]}
primarySegmentedMeasureLegendData={[{ name: 'Measure 1' }, { name: 'Measure 2' }]}
qualitativeRangeData={[{ name: 'Range', y: 50 }, { name: 'Range', y: 75 }]}
qualitativeRangeLegendData={[{ name: 'Range 1' }, { name: 'Range 2' }]}
subTitle="Measure details"
title="Text label"
titlePosition="top-left"
width={width}
/>
</div>
<div ref={this.containerRef} style={{ height: height + "px" }}>
<ChartBullet
ariaDesc="Storage capacity"
ariaTitle="Bullet chart example"
comparativeWarningMeasureData={[{name: 'Warning', y: 88}]}
comparativeWarningMeasureLegendData={[{ name: 'Warning' }]}
constrainToVisibleArea
height={height}
labels={({ datum }) => `${datum.name}: ${datum.y}`}
legendAllowWrap={this.handleLegendAllowWrap}
legendPosition="bottom-left"
maxDomain={{y: 100}}
name="chart3"
padding={{
bottom: 50,
left: 50,
right: 50,
top: 100 // Adjusted to accommodate labels
}}
primarySegmentedMeasureData={[{ name: 'Measure', y: 25 }, { name: 'Measure', y: 60 }]}
primarySegmentedMeasureLegendData={[{ name: 'Measure 1' }, { name: 'Measure 2' }]}
qualitativeRangeData={[{ name: 'Range', y: 50 }, { name: 'Range', y: 75 }]}
qualitativeRangeLegendData={[{ name: 'Range 1' }, { name: 'Range 2' }]}
subTitle="Measure details"
title="Text label"
titlePosition="top-left"
width={width}
/>
</div>
);
}
Expand Down
Loading