Skip to content

Commit bafb011

Browse files
authored
Fix labelBackgroundColor to apply to background instead of text (#44990)
* Add labelTextColor property to ChartTheme interface * Add labelTextColor to all theme configurations * Fix pie chart labels to use labelTextColor instead of labelBackgroundColor * Add Storybook controls and documentation for label color properties * Remove non-functional labelBackgroundColor control from Storybook * Implement functional labelBackgroundColor with visual backgrounds * Set labelBackgroundColor default to transparent to preserve original appearance * changelog * Set default label text color to white - Update labelTextColor from #333 to #FFFFFF in all themes (default, jetpack, woo) - Maintains original chart appearance with white text on segments - Ensures consistent behavior across all theme variations * Fix TypeScript error in Storybook stories - Remove direct theme prop from PieChart component - Wrap PieChart in ThemeProvider when theme is provided - Handle all theme variations (default, jetpack, woo, object) - Convert nested ternaries to if-else statements for linter compliance - Resolves TS2322 error about theme prop not existing
1 parent 710c54f commit bafb011

File tree

6 files changed

+198
-15
lines changed

6 files changed

+198
-15
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: minor
2+
Type: fixed
3+
4+
Charts: fix label background colour and text colour

projects/js-packages/charts/src/components/pie-chart/pie-chart.tsx

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -245,21 +245,42 @@ const PieChartInternal = ( {
245245
pathProps.onMouseLeave = onMouseLeave;
246246
}
247247

248+
// Estimate text width more accurately for background sizing
249+
const fontSize = 12;
250+
const estimatedTextWidth = arc.data.label.length * fontSize * 0.6; // Rough estimate
251+
const labelPadding = 6;
252+
const backgroundWidth = estimatedTextWidth + labelPadding * 2;
253+
const backgroundHeight = fontSize + labelPadding * 2;
254+
248255
return (
249256
<g key={ `arc-${ index }` }>
250257
<path { ...pathProps } />
251258
{ hasSpaceForLabel && (
252-
<text
253-
x={ centroidX }
254-
y={ centroidY }
255-
dy=".33em"
256-
fill={ providerTheme.labelBackgroundColor || '#333' }
257-
fontSize={ 12 }
258-
textAnchor="middle"
259-
pointerEvents="none"
260-
>
261-
{ arc.data.label }
262-
</text>
259+
<g>
260+
{ providerTheme.labelBackgroundColor && (
261+
<rect
262+
x={ centroidX - backgroundWidth / 2 }
263+
y={ centroidY - backgroundHeight / 2 }
264+
width={ backgroundWidth }
265+
height={ backgroundHeight }
266+
fill={ providerTheme.labelBackgroundColor }
267+
rx={ 4 }
268+
ry={ 4 }
269+
pointerEvents="none"
270+
/>
271+
) }
272+
<text
273+
x={ centroidX }
274+
y={ centroidY }
275+
dy=".33em"
276+
fill={ providerTheme.labelTextColor || '#333' }
277+
fontSize={ fontSize }
278+
textAnchor="middle"
279+
pointerEvents="none"
280+
>
281+
{ arc.data.label }
282+
</text>
283+
</g>
263284
) }
264285
</g>
265286
);

projects/js-packages/charts/src/components/pie-chart/stories/index.docs.mdx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,39 @@ Override theme colors by providing color values in data:
239239

240240
/>
241241

242+
### Label Colors and Styling
243+
244+
<Canvas of={ PieChartStories.CustomLabelColors } />
245+
246+
The Pie Chart supports customizable label colors through the theme system:
247+
248+
<Source
249+
language="jsx"
250+
code={ `import { ThemeProvider } from '@automattic/charts';
251+
252+
const customTheme = {
253+
...defaultTheme,
254+
labelTextColor: '#FFFFFF', // White text for labels
255+
labelBackgroundColor: 'rgba(0, 0, 0, 0.8)', // Enable dark background (transparent by default)
256+
};
257+
258+
<ThemeProvider theme={ customTheme }>
259+
<PieChart data={ data } />
260+
</ThemeProvider>` }
261+
/>
262+
263+
**Label Color Properties:**
264+
265+
- **`labelTextColor`** - Controls the color of text displayed on pie chart segments. Defaults to `#FFFFFF` (white) to match original behavior.
266+
- **`labelBackgroundColor`** - Controls the background color of labels. Defaults to `transparent` (no background). When set to any color value, creates a rounded rectangle behind each label for enhanced readability. Supports any CSS color including transparency (e.g., `rgba(0, 0, 0, 0.7)`).
267+
268+
**Best Practices:**
269+
- Use high contrast between `labelTextColor` and `labelBackgroundColor` for optimal readability
270+
- Consider semi-transparent backgrounds (`rgba()`) to maintain visual connection to segment colors
271+
- Test with different segment colors to ensure labels remain visible
272+
- Use `labelBackgroundColor` when segment colors are too varied or bright for consistent text visibility
273+
- Consider accessibility guidelines when choosing color combinations
274+
242275
### Theme Integration
243276

244277
Pie Charts automatically integrate with the chart theme system, inheriting colors, typography, and styling from the active theme. Custom themes can be applied using the `ThemeProvider`:
@@ -282,6 +315,15 @@ Main component for rendering pie and donut charts.
282315
| `aspectRatio` | `number` | `1` | Aspect ratio for responsive charts |
283316
| `resizeDebounceTime` | `number` | `100` | Debounce time for resize events (ms) |
284317

318+
### Theme Properties
319+
320+
The following properties can be customized via the theme system:
321+
322+
| Prop | Type | Default | Description |
323+
| --------------------------- | ------------------------------- | -------------- | --------------------------------------------------------------------------------- |
324+
| `labelTextColor` | `string` | `'#FFFFFF'` | Color of text displayed on pie chart segments |
325+
| `labelBackgroundColor` | `string` | `'transparent'` | Background color for labels. Set to any color value to enable label backgrounds |
326+
285327
### Compound Components
286328

287329
#### PieChart.SVG

projects/js-packages/charts/src/components/pie-chart/stories/index.stories.tsx

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
import { jetpackTheme, wooTheme } from '../../../providers/theme';
1+
import { jetpackTheme, wooTheme, ThemeProvider } from '../../../providers/theme';
22
import { sharedDecorator } from '../../../stories/decorator-config';
33
import { legendArgTypes } from '../../../stories/legend-config';
44
import { osUsageData as data } from '../../../stories/sample-data';
55
import { PieChart } from '../index';
66
import { PieChartUnresponsive } from '../pie-chart';
7+
import type { ChartTheme } from '../../../types';
78
import type { Meta, StoryObj } from '@storybook/react';
89

910
type StoryArgs = React.ComponentProps< typeof PieChart > & {
1011
theme?: string | object;
1112
resize?: string;
1213
containerWidth?: string;
1314
containerHeight?: string;
15+
labelTextColor?: string;
16+
labelBackgroundColor?: string;
1417
};
1518

1619
const meta: Meta< StoryArgs > = {
@@ -94,6 +97,66 @@ const meta: Meta< StoryArgs > = {
9497
max: 10000,
9598
},
9699
},
100+
labelTextColor: {
101+
control: { type: 'color' },
102+
description: 'Color of the label text displayed on pie chart segments',
103+
},
104+
labelBackgroundColor: {
105+
control: { type: 'color' },
106+
description: 'Background color for labels displayed on pie chart segments',
107+
},
108+
},
109+
render: ( { labelTextColor, labelBackgroundColor, theme, ...args } ) => {
110+
// Create custom theme if label colors are provided
111+
let customTheme: ChartTheme | undefined;
112+
if ( labelTextColor || labelBackgroundColor ) {
113+
let baseTheme: ChartTheme | undefined;
114+
115+
if ( typeof theme === 'object' ) {
116+
baseTheme = theme as ChartTheme;
117+
} else if ( theme === 'jetpack' ) {
118+
baseTheme = jetpackTheme;
119+
} else if ( theme === 'woo' ) {
120+
baseTheme = wooTheme;
121+
}
122+
123+
customTheme = {
124+
...baseTheme,
125+
labelTextColor: labelTextColor || baseTheme?.labelTextColor,
126+
labelBackgroundColor: labelBackgroundColor || baseTheme?.labelBackgroundColor,
127+
} as ChartTheme;
128+
}
129+
130+
let ChartComponent;
131+
if ( customTheme ) {
132+
ChartComponent = (
133+
<ThemeProvider theme={ customTheme }>
134+
<PieChart { ...args } />
135+
</ThemeProvider>
136+
);
137+
} else if ( typeof theme === 'object' ) {
138+
ChartComponent = (
139+
<ThemeProvider theme={ theme as ChartTheme }>
140+
<PieChart { ...args } />
141+
</ThemeProvider>
142+
);
143+
} else if ( theme === 'jetpack' ) {
144+
ChartComponent = (
145+
<ThemeProvider theme={ jetpackTheme }>
146+
<PieChart { ...args } />
147+
</ThemeProvider>
148+
);
149+
} else if ( theme === 'woo' ) {
150+
ChartComponent = (
151+
<ThemeProvider theme={ wooTheme }>
152+
<PieChart { ...args } />
153+
</ThemeProvider>
154+
);
155+
} else {
156+
ChartComponent = <PieChart { ...args } />;
157+
}
158+
159+
return ChartComponent;
97160
},
98161
} satisfies Meta< StoryArgs >;
99162

@@ -318,6 +381,54 @@ This pattern provides:
318381
},
319382
};
320383

384+
export const CustomLabelColors: Story = {
385+
args: {
386+
...Default.args,
387+
thickness: 0.85, // Slightly thinner for better label visibility
388+
data: [
389+
{
390+
label: 'Desktop',
391+
value: 45000,
392+
valueDisplay: '45K',
393+
percentage: 45,
394+
color: '#FF6B6B', // Light red segment
395+
},
396+
{
397+
label: 'Mobile',
398+
value: 35000,
399+
valueDisplay: '35K',
400+
percentage: 35,
401+
color: '#4ECDC4', // Light teal segment
402+
},
403+
{
404+
label: 'Tablet',
405+
value: 20000,
406+
valueDisplay: '20K',
407+
percentage: 20,
408+
color: '#45B7D1', // Light blue segment
409+
},
410+
],
411+
labelTextColor: '#FFFFFF', // White text for contrast against dark background
412+
labelBackgroundColor: 'rgba(0, 0, 0, 0.75)', // Dark semi-transparent background
413+
size: 400,
414+
},
415+
parameters: {
416+
docs: {
417+
description: {
418+
story: `This example demonstrates how to enable label backgrounds for enhanced readability. By default, labels have no background (transparent) to preserve the original chart appearance, but you can add backgrounds when needed.
419+
420+
**Key Features:**
421+
- **labelTextColor**: White text (\`#FFFFFF\`) for contrast against dark background
422+
- **labelBackgroundColor**: Dark semi-transparent background (\`rgba(0, 0, 0, 0.75)\`) - disabled by default
423+
- **Custom segment colors**: Bright colors that would make default dark text hard to read
424+
- **Opt-in enhancement**: Backgrounds only appear when explicitly set
425+
426+
Use the Storybook controls to experiment with different combinations. Try setting labelBackgroundColor to \`transparent\` to see the default behavior.`,
427+
},
428+
},
429+
},
430+
};
431+
321432
export const ErrorStates: Story = {
322433
render: () => (
323434
<div style={ { display: 'grid', gap: '2rem', gridTemplateColumns: 'repeat(2, 1fr)' } }>

projects/js-packages/charts/src/providers/theme/themes.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import type { ChartTheme } from '../../types';
55
*/
66
const defaultTheme: ChartTheme = {
77
backgroundColor: '#FFFFFF', // chart background color
8-
labelBackgroundColor: '#FFFFFF', // label background color
8+
labelBackgroundColor: 'transparent', // label background color (transparent by default)
9+
labelTextColor: '#FFFFFF', // label text color (white to match original behavior)
910
colors: [ '#98C8DF', '#006DAB', '#A6DC80', '#1F9828', '#FF8C8F' ],
1011
gridStyles: {
1112
stroke: '#DCDCDE',
@@ -62,7 +63,8 @@ const defaultTheme: ChartTheme = {
6263
*/
6364
const jetpackTheme: ChartTheme = {
6465
backgroundColor: '#FFFFFF', // chart background color
65-
labelBackgroundColor: '#FFFFFF', // label background color
66+
labelBackgroundColor: 'transparent', // label background color (transparent by default)
67+
labelTextColor: '#FFFFFF', // label text color (white to match original behavior)
6668
colors: [ '#98C8DF', '#006DAB', '#A6DC80', '#1F9828', '#FF8C8F' ],
6769
gridStyles: {
6870
stroke: '#DCDCDE',
@@ -119,7 +121,8 @@ const jetpackTheme: ChartTheme = {
119121
*/
120122
const wooTheme: ChartTheme = {
121123
backgroundColor: '#FFFFFF', // chart background color
122-
labelBackgroundColor: '#FFFFFF', // label background color
124+
labelBackgroundColor: 'transparent', // label background color (transparent by default)
125+
labelTextColor: '#FFFFFF', // label text color (white to match original behavior)
123126
colors: [ '#80C8FF', '#B999FF', '#3858E9' ],
124127
gridStyles: {
125128
stroke: '#787C82',

projects/js-packages/charts/src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ export type ChartTheme = {
8989
backgroundColor: string;
9090
/** Background color for labels */
9191
labelBackgroundColor?: string;
92+
/** Text color for labels */
93+
labelTextColor?: string;
9294
/** Array of colors used for data visualization */
9395
colors: string[];
9496
/** Optional CSS styles for grid lines */

0 commit comments

Comments
 (0)