Skip to content

Commit

Permalink
feat(charts): skeletons
Browse files Browse the repository at this point in the history
  • Loading branch information
dlabrecq committed Apr 28, 2024
1 parent 58139cd commit 750b5c8
Show file tree
Hide file tree
Showing 22 changed files with 1,199 additions and 54 deletions.
12 changes: 9 additions & 3 deletions packages/react-charts/src/components/Chart/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { getChartTheme } from '../ChartUtils/chart-theme-types';
import { useEffect } from 'react';
import { ChartLabel } from '../ChartLabel/ChartLabel';
import { ChartPoint } from '../ChartPoint/ChartPoint';
import { ChartThemeColor } from '../ChartTheme/ChartThemeColor';

/**
* Chart is a wrapper component that reconciles the domain for all its children, controls the layout of the chart,
Expand Down Expand Up @@ -473,7 +474,7 @@ export const Chart: React.FunctionComponent<ChartProps> = ({
children,
colorScale,
hasPatterns,
legendAllowWrap = false,
legendAllowWrap,
legendComponent = <ChartLegend />,
legendData,
legendPosition = ChartCommonStyles.legend.position,
Expand Down Expand Up @@ -526,7 +527,8 @@ export const Chart: React.FunctionComponent<ChartProps> = ({
theme,
...containerComponent.props,
className: getClassName({ className: containerComponent.props.className }), // Override VictoryContainer class name
...(labelComponent && { labelComponent }) // Override label component props
...(labelComponent && { labelComponent }), // Override label component props
...(themeColor === ChartThemeColor.skeleton && { labelComponent: <ChartLabel /> }) // Omit cursor and tooltips
});

let legendXOffset = 0;
Expand All @@ -550,7 +552,11 @@ export const Chart: React.FunctionComponent<ChartProps> = ({
labelComponent: legendComponent.props.labelComponent ? (
React.cloneElement(legendComponent.props.labelComponent, { direction: 'rtl', dx: legendXOffset - 30 })
) : (
<ChartLabel direction="rtl" dx={legendXOffset - 30} />
<ChartLabel
direction="rtl"
dx={legendXOffset - 30}
backgroundStyle={theme.skeleton ? theme.skeleton.backgroundStyle : undefined} // override backgroundStyle
/>
)
}),
...legendComponent.props
Expand Down
6 changes: 4 additions & 2 deletions packages/react-charts/src/components/ChartAxis/ChartAxis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -462,15 +462,17 @@ export const ChartAxis: React.FunctionComponent<ChartAxisProps> = ({
...(name && {
id: () => `${name}-${(axisLabelComponent as any).type.displayName}`
}),
...axisLabelComponent.props
...axisLabelComponent.props,
...(theme.skeleton && theme.skeleton) // override backgroundStyle
});

const getTickLabelComponent = () =>
React.cloneElement(tickLabelComponent, {
...(name && {
id: (props: any) => `${name}-${(tickLabelComponent as any).type.displayName}-${props.index}`
}),
...tickLabelComponent.props
...tickLabelComponent.props,
...(theme.skeleton && theme.skeleton) // override backgroundStyle
});

// Note: containerComponent is required for theme
Expand Down
48 changes: 40 additions & 8 deletions packages/react-charts/src/components/ChartBullet/ChartBullet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,8 @@ export const ChartBullet: React.FunctionComponent<ChartBulletProps> = ({
standalone: false,
subTitle: groupSubTitle,
title: groupTitle,
theme,
themeColor,
width,
...groupTitleComponent.props
});
Expand All @@ -608,6 +610,7 @@ export const ChartBullet: React.FunctionComponent<ChartBulletProps> = ({
standalone: false,
subTitle,
theme,
themeColor,
title,
titlePosition,
width,
Expand All @@ -617,7 +620,12 @@ export const ChartBullet: React.FunctionComponent<ChartBulletProps> = ({
// Comparative error measure
const comparativeErrorMeasure = React.cloneElement(comparativeErrorMeasureComponent, {
allowTooltip,
barWidth: getComparativeMeasureErrorWidth({ height: chartSize.height, horizontal, width: chartSize.width }),
barWidth: getComparativeMeasureErrorWidth({
height: chartSize.height,
horizontal,
themeColor,
width: chartSize.width
}),
constrainToVisibleArea,
data: comparativeErrorMeasureData,
domain,
Expand All @@ -627,6 +635,7 @@ export const ChartBullet: React.FunctionComponent<ChartBulletProps> = ({
labels,
padding,
standalone: false,
themeColor,
width: chartSize.width,
y: comparativeErrorMeasureDataY,
...comparativeErrorMeasureComponent.props
Expand All @@ -635,7 +644,12 @@ export const ChartBullet: React.FunctionComponent<ChartBulletProps> = ({
// Comparative warning measure
const comparativeWarningMeasure = React.cloneElement(comparativeWarningMeasureComponent, {
allowTooltip,
barWidth: getComparativeMeasureWarningWidth({ height: chartSize.height, horizontal, width: chartSize.width }),
barWidth: getComparativeMeasureWarningWidth({
height: chartSize.height,
horizontal,
themeColor,
width: chartSize.width
}),
constrainToVisibleArea,
data: comparativeWarningMeasureData,
domain,
Expand All @@ -645,20 +659,22 @@ export const ChartBullet: React.FunctionComponent<ChartBulletProps> = ({
labels,
padding,
standalone: false,
themeColor,
width: chartSize.width,
y: comparativeWarningMeasureDataY,
...comparativeWarningMeasureComponent.props
});

// Comparative zero measure
const comparativeZeroMeasure = React.cloneElement(comparativeZeroMeasureComponent, {
barWidth: getComparativeMeasureWidth({ height: chartSize.height, horizontal, width: chartSize.width }),
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
});
Expand Down Expand Up @@ -691,6 +707,7 @@ export const ChartBullet: React.FunctionComponent<ChartBulletProps> = ({
orientation: legendOrientation,
position: legendPosition,
theme,
themeColor,
...(legendDirection === 'rtl' && {
dataComponent: legendComponent.props.dataComponent ? (
React.cloneElement(legendComponent.props.dataComponent, { transform: `translate(${legendXOffset})` })
Expand All @@ -700,9 +717,17 @@ export const ChartBullet: React.FunctionComponent<ChartBulletProps> = ({
}),
...(legendDirection === 'rtl' && {
labelComponent: legendComponent.props.labelComponent ? (
React.cloneElement(legendComponent.props.labelComponent, { direction: 'rtl', dx: legendXOffset - 30 })
React.cloneElement(legendComponent.props.labelComponent, {
direction: 'rtl',
dx: legendXOffset - 30,
...(theme.skeleton && theme.skeleton) // override backgroundStyle
})
) : (
<ChartLabel direction="rtl" dx={legendXOffset - 30} />
<ChartLabel
direction="rtl"
dx={legendXOffset - 30}
{...(theme.skeleton && theme.skeleton)} // override backgroundStyle
/>
)
}),
...legendComponent.props
Expand All @@ -720,7 +745,7 @@ export const ChartBullet: React.FunctionComponent<ChartBulletProps> = ({
labelComponent: allowTooltip ? <ChartTooltip height={height} theme={theme} width={width} /> : undefined,
labels,
padding,
size: getPrimaryDotMeasureSize({ height: chartSize.height, horizontal, width: chartSize.width }),
size: getPrimaryDotMeasureSize({ height: chartSize.height, horizontal, themeColor, width: chartSize.width }),
standalone: false,
themeColor,
width: chartSize.width,
Expand All @@ -732,7 +757,12 @@ export const ChartBullet: React.FunctionComponent<ChartBulletProps> = ({
const primarySegmentedMeasure = React.cloneElement(primarySegmentedMeasureComponent, {
allowTooltip,
constrainToVisibleArea,
barWidth: getPrimarySegmentedMeasureWidth({ height: chartSize.height, horizontal, width: chartSize.width }),
barWidth: getPrimarySegmentedMeasureWidth({
height: chartSize.height,
horizontal,
themeColor,
width: chartSize.width
}),
data: primarySegmentedMeasureData,
domain,
height: chartSize.height,
Expand All @@ -752,7 +782,7 @@ export const ChartBullet: React.FunctionComponent<ChartBulletProps> = ({
const qualitativeRange = React.cloneElement(qualitativeRangeComponent, {
allowTooltip,
constrainToVisibleArea,
barWidth: getQualitativeRangeBarWidth({ height: chartSize.height, horizontal, width: chartSize.width }),
barWidth: getQualitativeRangeBarWidth({ height: chartSize.height, horizontal, themeColor, width: chartSize.width }),
data: qualitativeRangeData,
domain,
height: chartSize.height,
Expand All @@ -762,6 +792,7 @@ export const ChartBullet: React.FunctionComponent<ChartBulletProps> = ({
labels,
padding,
standalone: false,
themeColor,
width: chartSize.width,
y: qualitativeRangeDataY,
y0: qualitativeRangeDataY0,
Expand Down Expand Up @@ -868,6 +899,7 @@ export const ChartBullet: React.FunctionComponent<ChartBulletProps> = ({
offsetY: horizontal ? 80 - defaultPadding.top * 0.5 + (defaultPadding.bottom * 0.5 - 25) : 0,
padding,
standalone: false,
themeColor,
tickCount: ChartBulletStyles.axisTickCount,
tickValues: getTickValues((domain as any).y[0], (domain as any).y[1]),
width: chartSize.width,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ export const ChartBulletComparativeMeasure: React.FunctionComponent<ChartBulletC
padding,
standalone: false,
theme,
themeColor,
width,
...measureComponent.props
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ export const ChartBulletComparativeWarningMeasure: React.FunctionComponent<
padding,
standalone: false,
theme,
themeColor,
width,
y,
...measureComponent.props
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ export const ChartBulletGroupTitle: React.FunctionComponent<ChartBulletGroupTitl
dy: defaultPadding.top,
labelPosition: 'top'
}),
...titleProps
...titleProps,
...(theme.skeleton && theme.skeleton) // override backgroundStyle
});
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,8 @@ export const ChartBulletTitle: React.FunctionComponent<ChartBulletTitleProps> =
dy,
labelPosition
}),
...titleComponent.props
...titleComponent.props,
...(theme.skeleton && theme.skeleton) // override backgroundStyle
});
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
} from './chart-bullet-data';
import { ChartThemeDefinition } from '../../ChartTheme/ChartTheme';
import { getBulletTheme } from '../../ChartUtils/chart-theme-types';
import { ChartThemeColor } from '../../ChartTheme/ChartThemeColor';
import { SkeletonColorTheme } from '../../ChartTheme/themes/colors/skeleton-theme';

interface ChartBulletThemeInterface {
comparativeErrorMeasureData?: any[];
Expand Down Expand Up @@ -134,5 +136,8 @@ export const getBulletThemeWithLegendColorScale = ({

const theme = getBulletTheme(themeColor);
theme.legend.colorScale = [...colorScale];
if (themeColor === ChartThemeColor.skeleton) {
theme.legend.colorScale = SkeletonColorTheme.legend.colorScale;
}
return theme;
};
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,8 @@ export const ChartCursorContainer: React.FunctionComponent<ChartCursorContainerP
const chartClassName = getClassName({ className });
const chartCursorLabelComponent = React.cloneElement(cursorLabelComponent, {
theme,
...cursorLabelComponent.props
...cursorLabelComponent.props,
...(theme.skeleton && theme.skeleton) // override backgroundStyle
});

// Clone so users can override cursor container props
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,8 @@ export const ChartDonut: React.FunctionComponent<ChartDonutProps> = ({
padding: defaultPadding,
width
}),
...subTitleProps
...subTitleProps,
...(theme.skeleton && theme.skeleton) // override backgroundStyle
});
};

Expand Down Expand Up @@ -692,7 +693,8 @@ export const ChartDonut: React.FunctionComponent<ChartDonutProps> = ({
padding: defaultPadding,
width
}),
...titleProps
...titleProps,
...(theme.skeleton && theme.skeleton) // override backgroundStyle
});
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,14 +350,16 @@ export const ChartLegend: React.FunctionComponent<ChartLegendProps> = ({
const getLabelComponent = () =>
React.cloneElement(labelComponent, {
...(name && { id: (props: any) => `${name}-${(labelComponent as any).type.displayName}-${props.index}` }),
...labelComponent.props
...labelComponent.props,
...(theme.skeleton && theme.skeleton) // override backgroundStyle
});

const getTitleComponent = () =>
React.cloneElement(titleComponent, {
// Victory doesn't appear to call the id function here, but it's valid for label components
...(name && { id: () => `${name}-${(titleComponent as any).type.displayName}` }),
...titleComponent.props
...titleComponent.props,
...(theme.skeleton && theme.skeleton) // override backgroundStyle
});

// Note: containerComponent is required for theme
Expand Down
12 changes: 11 additions & 1 deletion packages/react-charts/src/components/ChartTheme/ChartTheme.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import { VictoryThemeDefinition } from 'victory-core';

// Note: Victory incorrectly typed ThemeBaseProps.padding as number instead of PaddingProps
export interface ChartThemeDefinitionInterface extends VictoryThemeDefinition {}
export interface ChartThemeDefinitionInterface extends VictoryThemeDefinition {
skeleton?: {
backgroundStyle?: {
fill?: string;
};
style?: {
fill?: string;
stroke?: string;
};
};
}

/**
* Chart theme definition
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ interface ChartThemeColorInterface {
multiUnordered: string;
orange: string;
purple: string;
skeleton: string;
}

/**
Expand Down Expand Up @@ -49,5 +50,6 @@ export const ChartThemeColor: ChartThemeColorInterface = {
multiOrdered: 'multi-ordered',
multiUnordered: 'multi-unordered',
orange: 'orange',
purple: 'purple'
purple: 'purple',
skeleton: 'skeleton'
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ChartThemeDefinition } from './ChartTheme';
import { AxisTheme } from './themes/components/axis-theme';
import { BaseTheme } from './themes/base-theme';
import { SkeletonTheme } from './themes/skeleton-theme';
import {
BulletTheme,
BulletComparativeErrorMeasureTheme,
Expand Down Expand Up @@ -108,13 +109,19 @@ export const ChartDonutTheme: ChartThemeDefinition = DonutTheme;
export const ChartDonutThresholdDynamicTheme: ChartThemeDefinition = DonutThresholdDynamicTheme;

/**
* ChartDonutThresholdStatic theme
* Donut threshold static theme
* @private
*/
export const ChartDonutThresholdStaticTheme: ChartThemeDefinition = DonutThresholdStaticTheme;

/**
* Donut threshold static theme
* Skeleton theme
* @private
*/
export const ChartSkeletonTheme: ChartThemeDefinition = SkeletonTheme;

/**
* Threshold static theme
* @private
*/
export const ChartThresholdTheme: ChartThemeDefinition = ThresholdTheme;
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ export const BaseTheme = {
},
grid: {
fill: chart_axis_grid_Fill.var,
stroke: 'none',
stroke: 'transparent',
pointerEvents: chart_axis_grid_PointerEvents.value,
strokeLinecap: STROKE_LINE_CAP,
strokeLinejoin: STROKE_LINE_JOIN
Expand Down
Loading

0 comments on commit 750b5c8

Please sign in to comment.