Skip to content

Commit 8c6d8ca

Browse files
authored
[charts] Apply axis colorMap to radial bar fill (mui#22800)
1 parent 691a8d1 commit 8c6d8ca

4 files changed

Lines changed: 139 additions & 1 deletion

File tree

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import * as React from 'react';
2+
import { RadialBarChart } from '@mui/x-charts-premium/RadialBarChart';
3+
4+
const healthData = [
5+
{ metric: 'Water', value: 5, goal: 8, color: '#00bcd4' },
6+
{ metric: 'Sleep', value: 6.5, goal: 8, color: '#3f51b5' },
7+
{ metric: 'Calories', value: 540, goal: 700, color: '#ff9800' },
8+
{ metric: 'Activity', value: 42, goal: 60, color: '#4caf50' },
9+
{ metric: 'Steps', value: 8200, goal: 10000, color: '#e91e63' },
10+
];
11+
12+
const dataset = healthData.map((d) => ({
13+
metric: d.metric,
14+
progress: Math.round((d.value / d.goal) * 100),
15+
}));
16+
17+
const highlightScope = { highlight: 'none', fade: 'none' };
18+
19+
export default function HealthRadialBarChart() {
20+
return (
21+
<RadialBarChart
22+
height={400}
23+
dataset={dataset}
24+
series={[
25+
{
26+
dataKey: 'progress',
27+
layout: 'horizontal',
28+
label: 'Progress',
29+
highlightScope,
30+
valueFormatter: (value) => `${value}%`,
31+
},
32+
]}
33+
radiusAxis={[
34+
{
35+
scaleType: 'band',
36+
dataKey: 'metric',
37+
categoryGapRatio: 0.3,
38+
disableLine: true,
39+
disableTicks: true,
40+
colorMap: {
41+
type: 'ordinal',
42+
values: healthData.map((d) => d.metric),
43+
colors: healthData.map((d) => d.color),
44+
},
45+
},
46+
]}
47+
rotationAxis={[
48+
{
49+
scaleType: 'linear',
50+
disableTickLabel: true,
51+
disableLine: true,
52+
disableTicks: true,
53+
min: 0,
54+
max: 100,
55+
valueFormatter: (value) => `${value}%`,
56+
},
57+
]}
58+
axisHighlight={{ rotation: 'none', radius: 'none' }}
59+
hideLegend
60+
slotProps={{ tooltip: { trigger: 'none' } }}
61+
/>
62+
);
63+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import * as React from 'react';
2+
import { RadialBarChart } from '@mui/x-charts-premium/RadialBarChart';
3+
4+
const healthData = [
5+
{ metric: 'Water', value: 5, goal: 8, color: '#00bcd4' },
6+
{ metric: 'Sleep', value: 6.5, goal: 8, color: '#3f51b5' },
7+
{ metric: 'Calories', value: 540, goal: 700, color: '#ff9800' },
8+
{ metric: 'Activity', value: 42, goal: 60, color: '#4caf50' },
9+
{ metric: 'Steps', value: 8200, goal: 10000, color: '#e91e63' },
10+
];
11+
12+
const dataset = healthData.map((d) => ({
13+
metric: d.metric,
14+
progress: Math.round((d.value / d.goal) * 100),
15+
}));
16+
17+
const highlightScope = { highlight: 'none', fade: 'none' } as const;
18+
19+
export default function HealthRadialBarChart() {
20+
return (
21+
<RadialBarChart
22+
height={400}
23+
dataset={dataset}
24+
series={[
25+
{
26+
dataKey: 'progress',
27+
layout: 'horizontal',
28+
label: 'Progress',
29+
highlightScope,
30+
valueFormatter: (value) => `${value}%`,
31+
},
32+
]}
33+
radiusAxis={[
34+
{
35+
scaleType: 'band',
36+
dataKey: 'metric',
37+
categoryGapRatio: 0.3,
38+
disableLine: true,
39+
disableTicks: true,
40+
colorMap: {
41+
type: 'ordinal',
42+
values: healthData.map((d) => d.metric),
43+
colors: healthData.map((d) => d.color),
44+
},
45+
},
46+
]}
47+
rotationAxis={[
48+
{
49+
scaleType: 'linear',
50+
disableTickLabel: true,
51+
disableLine: true,
52+
disableTicks: true,
53+
min: 0,
54+
max: 100,
55+
valueFormatter: (value) => `${value}%`,
56+
},
57+
]}
58+
axisHighlight={{ rotation: 'none', radius: 'none' }}
59+
hideLegend
60+
slotProps={{ tooltip: { trigger: 'none' } }}
61+
/>
62+
);
63+
}

docs/data/charts/radial-bars/radial-bars.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ The demo below demonstrates those options.
3636

3737
{{"demo": "RadialBarConfig.js", "hideToolbar": true, "bg": "playground"}}
3838

39+
## Coloring each bar
40+
41+
Radial bars support the same [color scale](/x/react-charts/bars/#color-scale) as the bar chart.
42+
The only difference is that the cartesian `x` and `y` axes are replaced by the `rotationAxis` and `radiusAxis`, so you can set a `colorMap` on either of them.
43+
44+
The demo below sets an `'ordinal'` color map on the `radiusAxis` to build a health dashboard where every metric ring tracks progress toward its goal.
45+
46+
{{"demo": "HealthRadialBarChart.js", "bg": "outline"}}
47+
3948
## Click events
4049

4150
The `RadialBarChart` provides an `onAxisClick` handler that fires when the user clicks anywhere in the chart area.

packages/x-charts-premium/src/RadialBarChart/useRadialBarPlotData.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
type ChartsRadialAxisProps,
1616
} from '@mui/x-charts/internals';
1717
import { type SeriesId } from '@mui/x-charts/models';
18+
import getColor from './seriesConfig/getColor';
1819

1920
interface ProcessedRadialBarData {
2021
seriesId: SeriesId;
@@ -102,6 +103,8 @@ function processRadialBarDataForPlot(
102103
const rotationOrigin = rotationAxisConfig.scale(0) ?? 0;
103104
const radiusOrigin = radiusAxisConfig.scale(0) ?? 0;
104105

106+
const colorGetter = getColor(seriesItem, rotationAxisConfig, radiusAxisConfig);
107+
105108
const { barWidth: bandSlice, offset } = getBandSize(
106109
baseScale.bandwidth(),
107110
stackingGroups.length,
@@ -138,7 +141,7 @@ function processRadialBarDataForPlot(
138141
seriesId,
139142
dataIndex,
140143
hidden: seriesItem.hidden,
141-
color: seriesItem.color,
144+
color: colorGetter(dataIndex),
142145
value: seriesValue,
143146
startAngle: verticalLayout ? baseStart : valueStart,
144147
endAngle: verticalLayout ? baseEnd : valueEnd,

0 commit comments

Comments
 (0)