Skip to content

Commit eb6baad

Browse files
authored
[charts-pro] Add data-series to elements of funnel chart (#18067)
Signed-off-by: Jose C Quintas Jr <juniorquintas@gmail.com>
1 parent 8a94fa6 commit eb6baad

File tree

6 files changed

+155
-27
lines changed

6 files changed

+155
-27
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import * as React from 'react';
2+
import Box from '@mui/material/Box';
3+
import {
4+
Unstable_FunnelChart as FunnelChart,
5+
funnelSectionClasses,
6+
} from '@mui/x-charts-pro/FunnelChart';
7+
8+
export default function FunnelDataAttributes() {
9+
return (
10+
<Box sx={{ width: '100%', maxWidth: 400 }}>
11+
<FunnelChart
12+
{...funnelProps}
13+
sx={{
14+
[`[data-series="main"] .${funnelSectionClasses.root}:nth-of-type(1)`]: {
15+
fill: 'url(#pattern)',
16+
},
17+
}}
18+
>
19+
<defs>
20+
<pattern id="pattern" width="50" height="50" patternUnits="userSpaceOnUse">
21+
<rect width="100%" height="100%" fill="hotpink" />
22+
<circle fill="slateblue" cx="15" cy="15" r="10" />
23+
<circle fill="slateblue" cx="40" cy="40" r="10" />
24+
</pattern>
25+
</defs>
26+
</FunnelChart>
27+
</Box>
28+
);
29+
}
30+
31+
const funnelProps = {
32+
height: 300,
33+
hideLegend: true,
34+
series: [
35+
{
36+
id: 'main',
37+
data: [{ value: 200 }, { value: 180 }, { value: 90 }, { value: 50 }],
38+
},
39+
],
40+
};
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import * as React from 'react';
2+
import Box from '@mui/material/Box';
3+
import {
4+
Unstable_FunnelChart as FunnelChart,
5+
funnelSectionClasses,
6+
} from '@mui/x-charts-pro/FunnelChart';
7+
8+
export default function FunnelDataAttributes() {
9+
return (
10+
<Box sx={{ width: '100%', maxWidth: 400 }}>
11+
<FunnelChart
12+
{...funnelProps}
13+
sx={{
14+
[`[data-series="main"] .${funnelSectionClasses.root}:nth-of-type(1)`]: {
15+
fill: 'url(#pattern)',
16+
},
17+
}}
18+
>
19+
<defs>
20+
<pattern id="pattern" width="50" height="50" patternUnits="userSpaceOnUse">
21+
<rect width="100%" height="100%" fill="hotpink" />
22+
<circle fill="slateblue" cx="15" cy="15" r="10" />
23+
<circle fill="slateblue" cx="40" cy="40" r="10" />
24+
</pattern>
25+
</defs>
26+
</FunnelChart>
27+
</Box>
28+
);
29+
}
30+
31+
const funnelProps = {
32+
height: 300,
33+
hideLegend: true,
34+
series: [
35+
{
36+
id: 'main',
37+
data: [{ value: 200 }, { value: 180 }, { value: 90 }, { value: 50 }],
38+
},
39+
],
40+
} as const;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<FunnelChart
2+
{...funnelProps}
3+
sx={{
4+
[`[data-series="main"] .${funnelSectionClasses.root}:nth-of-type(1)`]: {
5+
fill: 'url(#pattern)',
6+
},
7+
}}
8+
>
9+
<defs>
10+
<pattern id="pattern" width="50" height="50" patternUnits="userSpaceOnUse">
11+
<rect width="100%" height="100%" fill="hotpink" />
12+
<circle fill="slateblue" cx="15" cy="15" r="10" />
13+
<circle fill="slateblue" cx="40" cy="40" r="10" />
14+
</pattern>
15+
</defs>
16+
</FunnelChart>

docs/data/charts/funnel/funnel.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,16 @@ The funnel colors can be customized in two ways.
123123

124124
{{"demo": "FunnelColor.js"}}
125125

126+
### CSS
127+
128+
The funnel chart can be styled using CSS.
129+
130+
Each section group has a `data-series` attribute that can be used to target specific series sections.
131+
132+
In order to target specific sections, you can use the `:nth-child` or `:nth-child-of-type` selectors as shown in the example below.
133+
134+
{{"demo": "FunnelDataAttributes.js"}}
135+
126136
## Multiple funnels
127137

128138
By default, multiple series are displayed on top of each other.

packages/x-charts-pro/src/FunnelChart/FunnelPlot.tsx

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ const useAggregatedData = () => {
209209
});
210210
});
211211

212-
return result.flat();
212+
return result;
213213
}, [seriesData, xAxis, xAxisIds, yAxis, yAxisIds, gap]);
214214

215215
return allData;
@@ -222,36 +222,56 @@ function FunnelPlot(props: FunnelPlotProps) {
222222

223223
return (
224224
<React.Fragment>
225-
{data.map(({ d, color, id, seriesId, dataIndex, variant }) => (
226-
<FunnelSection
227-
{...other}
228-
d={d}
229-
color={color}
230-
key={id}
231-
dataIndex={dataIndex}
232-
seriesId={seriesId}
233-
variant={variant}
234-
onClick={
235-
onItemClick &&
236-
((event) => {
237-
onItemClick(event, { type: 'funnel', seriesId, dataIndex });
238-
})
239-
}
240-
/>
241-
))}
242-
{data.map(({ id, label, seriesId, dataIndex }) => {
243-
if (!label || !label.value) {
225+
{data.map((series) => {
226+
if (series.length === 0) {
244227
return null;
245228
}
246229

247230
return (
248-
<FunnelSectionLabel
249-
key={id}
250-
label={label}
251-
dataIndex={dataIndex}
252-
seriesId={seriesId}
253-
{...other}
254-
/>
231+
<g data-series={series[0].seriesId} key={series[0].seriesId}>
232+
{series.map(({ d, color, id, seriesId, dataIndex, variant }) => (
233+
<FunnelSection
234+
{...other}
235+
d={d}
236+
color={color}
237+
key={id}
238+
dataIndex={dataIndex}
239+
seriesId={seriesId}
240+
variant={variant}
241+
onClick={
242+
onItemClick &&
243+
((event) => {
244+
onItemClick(event, { type: 'funnel', seriesId, dataIndex });
245+
})
246+
}
247+
/>
248+
))}
249+
</g>
250+
);
251+
})}
252+
{data.map((series) => {
253+
if (series.length === 0) {
254+
return null;
255+
}
256+
257+
return (
258+
<g data-series={series[0].seriesId} key={series[0].seriesId}>
259+
{series.map(({ id, label, seriesId, dataIndex }) => {
260+
if (!label || !label.value) {
261+
return null;
262+
}
263+
264+
return (
265+
<FunnelSectionLabel
266+
key={id}
267+
label={label}
268+
dataIndex={dataIndex}
269+
seriesId={seriesId}
270+
{...other}
271+
/>
272+
);
273+
})}
274+
</g>
255275
);
256276
})}
257277
</React.Fragment>

packages/x-charts-pro/src/FunnelChart/FunnelSection.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ const FunnelSection = consumeSlots(
6262
strokeWidth={isOutlined ? 1.5 : 0}
6363
cursor={onClick ? 'pointer' : 'unset'}
6464
onClick={onClick}
65+
data-highlighted={isHighlighted || undefined}
66+
data-faded={isFaded || undefined}
6567
className={clsx(
6668
classes?.root,
6769
isHighlighted && classes?.highlighted,

0 commit comments

Comments
 (0)