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
73 changes: 56 additions & 17 deletions src/lib/components/charts/barchart/Barchart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@ const CHART_CONSTANTS = {

/* ---------------------------------- TYPE ---------------------------------- */

type BarchartDisplayOptions = {
noBackground?: boolean;
showHorizontalGridLines?: boolean;
noYAxisLine?: boolean;
noTickLine?: boolean;
noHeader?: boolean;
};

type ResolvedBarchartDisplayOptions = Required<BarchartDisplayOptions>;

const BARCHART_PRESETS: Record<'default' | 'modern', ResolvedBarchartDisplayOptions> = {
default: { noBackground: false, showHorizontalGridLines: false, noYAxisLine: false, noTickLine: false, noHeader: false },
modern: { noBackground: true, showHorizontalGridLines: true, noYAxisLine: true, noTickLine: true, noHeader: true },
};

export type Point = {
key: string | number;
values: { label: string; value: number }[];
Expand Down Expand Up @@ -84,6 +99,21 @@ export type BarchartProps<T extends BarchartBars> = {
height?: number;
isLoading?: boolean;
isError?: boolean;
/**
* Named display preset that sets a group of visual defaults at once.
*
* - `'default'` — opaque background, no grid lines, Y-axis line visible, tick marks visible.
* - `'modern'` — transparent background, horizontal grid lines, no Y-axis line, no tick marks.
*
* Individual values can be overridden with `displayOptions`.
* Defaults to `'default'` when omitted.
*/
displayPreset?: 'default' | 'modern';
/**
* Fine-grained overrides applied on top of the active `displayPreset`.
* Only the properties you specify are overridden; the rest come from the preset.
*/
displayOptions?: BarchartDisplayOptions;
};

/* ---------------------------------- MAIN COMPONENT ---------------------------------- */
Expand All @@ -109,8 +139,17 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
rightTitle,
isLoading,
isError,
displayPreset = 'default',
displayOptions,
} = props;

const presetOptions = BARCHART_PRESETS[displayPreset];
const resolvedNoBackground = displayOptions?.noBackground ?? presetOptions.noBackground;
const resolvedShowHorizontalGridLines = displayOptions?.showHorizontalGridLines ?? presetOptions.showHorizontalGridLines;
const resolvedNoYAxisLine = displayOptions?.noYAxisLine ?? presetOptions.noYAxisLine;
const resolvedNoTickLine = displayOptions?.noTickLine ?? presetOptions.noTickLine;
const resolvedNoHeader = displayOptions?.noHeader ?? presetOptions.noHeader;

// Create colorSet from ChartLegendWrapper
const colorSet = useMemo(
() =>
Expand Down Expand Up @@ -174,12 +213,13 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
barCategoryGap={type.type === 'category' ? type.gap : undefined}
>
<CartesianGrid
vertical={true}
vertical={resolvedShowHorizontalGridLines ? false : true}
horizontal={true}
verticalPoints={[0]}
horizontalPoints={[0]}
{...(!resolvedShowHorizontalGridLines ? { verticalPoints: [0], horizontalPoints: [0] } : {})}
stroke={theme.border}
fill={theme.backgroundLevel4}
strokeOpacity={resolvedShowHorizontalGridLines ? 0.4 : 1}
syncWithTicks={resolvedShowHorizontalGridLines}
fill={resolvedNoBackground ? 'transparent' : theme.backgroundLevel4}
strokeWidth={1}
/>
{rechartsBars.map((bar) => {
Expand All @@ -203,7 +243,8 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
domain={[0, topDomain]}
ticks={getTicks(roundReferenceValue, false)}
tickFormatter={tickFormatter}
axisLine={{ stroke: theme.border }}
axisLine={resolvedNoYAxisLine ? false : { stroke: theme.border }}
tickLine={resolvedNoTickLine ? false : { stroke: theme.border }}
tick={{
fill: theme.textSecondary,
fontSize: fontSize.smaller,
Expand All @@ -223,12 +264,8 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
type="category"
interval={0}
allowDataOverflow={true}
tickLine={{
stroke: theme.border,
}}
axisLine={{
stroke: theme.border,
}}
tickLine={resolvedNoTickLine ? false : { stroke: theme.border }}
axisLine={{ stroke: theme.border }}
/>

<Tooltip
Expand All @@ -252,12 +289,14 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {

return (
<Stack direction="vertical" style={{ gap: '0' }}>
<ChartHeader
title={titleWithUnit}
secondaryTitle={secondaryTitle}
helpTooltip={helpTooltip}
rightTitle={rightTitle}
/>
{!resolvedNoHeader && (
<ChartHeader
title={titleWithUnit}
secondaryTitle={secondaryTitle}
helpTooltip={helpTooltip}
rightTitle={rightTitle}
/>
)}
{renderChartContent()}
</Stack>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export function LineTimeSerieChart({
const resolvedShowHorizontalGridLines = displayOptions?.showHorizontalGridLines ?? presetOptions.showHorizontalGridLines;
const resolvedNoHeader = displayOptions?.noHeader ?? presetOptions.noHeader;
const resolvedNoYAxisLine = displayOptions?.noYAxisLine ?? presetOptions.noYAxisLine;
const resolvedNoTickLine = displayOptions?.noTickLine ?? presetOptions.noTickLine;

const theme = useTheme();
const chartRef = useRef(null);
Expand Down Expand Up @@ -178,6 +179,7 @@ export function LineTimeSerieChart({
}
allowDataOverflow={true}
axisLine={resolvedNoYAxisLine ? false : { stroke: theme.border }}
tickLine={resolvedNoTickLine ? false : { stroke: theme.border }}
tick={{
fill: theme.textSecondary,
fontSize: fontSize.smaller,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export type LineChartProps = (
* - `showHorizontalGridLines` — draws horizontal grid lines across the plot area.
* - `noHeader` — hides the title/help-text/right-title header row.
* - `noYAxisLine` — hides the vertical Y-axis line.
* - `noTickLine` — hides the tick marks on the Y-axis.
*
* @example
* // Add grid lines to the default preset
Expand All @@ -98,6 +99,7 @@ export type LineChartProps = (
showHorizontalGridLines?: boolean;
noHeader?: boolean;
noYAxisLine?: boolean;
noTickLine?: boolean;
};
/** Custom tooltip renderer */
renderTooltip?: (
Expand All @@ -110,8 +112,8 @@ export type LineChartProps = (
type DisplayOptions = Required<NonNullable<LineChartProps['displayOptions']>>;

export const CHART_PRESETS: Record<'default' | 'modern', DisplayOptions> = {
default: { noBackground: false, showHorizontalGridLines: false, noHeader: false, noYAxisLine: false },
modern: { noBackground: true, showHorizontalGridLines: true, noHeader: true, noYAxisLine: true },
default: { noBackground: false, showHorizontalGridLines: false, noHeader: false, noYAxisLine: false, noTickLine: false },
modern: { noBackground: true, showHorizontalGridLines: true, noHeader: true, noYAxisLine: true, noTickLine: true },
};

export type LineTimeSerieChartTooltipProps = {
Expand Down
85 changes: 85 additions & 0 deletions stories/BarChart/barchart.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -986,6 +986,91 @@ export const Histogram: Story = {
},
};

export const ModernPreset: Story = {
render: () => {
const theme = useTheme() as CoreUITheme;
const data = [
{
label: 'Success',
data: [
['category1', 25],
['category2', 40],
['category3', 35],
['category4', 28],
['category5', 47],
],
},
{
label: 'Failed',
data: [
['category1', 8],
['category2', 12],
['category3', 6],
['category4', 15],
['category5', 9],
],
},
] as const;
return (
<Stack direction="vertical" gap="r24" style={{ width: '600px' }}>
<div
style={{
padding: spacing.r16,
borderRadius: spacing.r8,
backgroundColor: theme.backgroundLevel2,
}}
>
<Text variant="Large">Default preset</Text>
<ChartLegendWrapper
colorSet={{
Success: theme.statusHealthy,
Failed: theme.statusCritical,
}}
sortOrder="status"
>
<Stack direction="vertical" gap="r16">
<Barchart
type={{ type: 'category' }}
bars={data}
title="Operations"
displayPreset="default"
/>
<ChartLegend shape="rectangle" direction="horizontal" />
</Stack>
</ChartLegendWrapper>
</div>

<div
style={{
padding: spacing.r16,
borderRadius: spacing.r8,
backgroundColor: theme.backgroundLevel2,
}}
>
<Text variant="Large">Modern preset</Text>
<ChartLegendWrapper
colorSet={{
Success: theme.statusHealthy,
Failed: theme.statusCritical,
}}
sortOrder="status"
>
<Stack direction="vertical" gap="r16">
<Barchart
type={{ type: 'category' }}
bars={data}
title="Operations"
displayPreset="modern"
/>
<ChartLegend shape="rectangle" direction="horizontal" />
</Stack>
</ChartLegendWrapper>
</div>
</Stack>
);
},
};

export const StackedHistogram: Story = {
render: () => {
const histogramData = [
Expand Down
Loading