From e177f9d574d9cccbc76ec94eb188d6cfe91c7bd1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 13:21:31 +0100 Subject: [PATCH] [charts] Improve SVG `pattern` and `gradient` support (@JCQuintas) (#15724) Signed-off-by: Jose C Quintas Jr Co-authored-by: Jose C Quintas Jr Co-authored-by: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com> --- docs/data/charts/styling/GradientTooltip.js | 37 ++++++++++++++++ docs/data/charts/styling/GradientTooltip.tsx | 37 ++++++++++++++++ docs/data/charts/styling/PatternPie.js | 44 +++++++++++++++++++ docs/data/charts/styling/PatternPie.tsx | 44 +++++++++++++++++++ docs/data/charts/styling/styling.md | 19 ++++++++ .../src/ChartsTooltip/ChartsTooltipTable.ts | 2 +- packages/x-charts/src/PieChart/PieArc.tsx | 19 ++++++-- packages/x-charts/src/PieChart/PieArcPlot.tsx | 3 -- 8 files changed, 197 insertions(+), 8 deletions(-) create mode 100644 docs/data/charts/styling/GradientTooltip.js create mode 100644 docs/data/charts/styling/GradientTooltip.tsx create mode 100644 docs/data/charts/styling/PatternPie.js create mode 100644 docs/data/charts/styling/PatternPie.tsx diff --git a/docs/data/charts/styling/GradientTooltip.js b/docs/data/charts/styling/GradientTooltip.js new file mode 100644 index 0000000000000..37eabc894b977 --- /dev/null +++ b/docs/data/charts/styling/GradientTooltip.js @@ -0,0 +1,37 @@ +import * as React from 'react'; +import { BarChart } from '@mui/x-charts/BarChart'; + +export default function GradientTooltip() { + return ( + + + + + + + ); +} diff --git a/docs/data/charts/styling/GradientTooltip.tsx b/docs/data/charts/styling/GradientTooltip.tsx new file mode 100644 index 0000000000000..37eabc894b977 --- /dev/null +++ b/docs/data/charts/styling/GradientTooltip.tsx @@ -0,0 +1,37 @@ +import * as React from 'react'; +import { BarChart } from '@mui/x-charts/BarChart'; + +export default function GradientTooltip() { + return ( + + + + + + + ); +} diff --git a/docs/data/charts/styling/PatternPie.js b/docs/data/charts/styling/PatternPie.js new file mode 100644 index 0000000000000..02f53eebf0161 --- /dev/null +++ b/docs/data/charts/styling/PatternPie.js @@ -0,0 +1,44 @@ +import * as React from 'react'; +import { PieChart } from '@mui/x-charts/PieChart'; + +export default function PatternPie() { + return ( + + + + + + + ); +} diff --git a/docs/data/charts/styling/PatternPie.tsx b/docs/data/charts/styling/PatternPie.tsx new file mode 100644 index 0000000000000..02f53eebf0161 --- /dev/null +++ b/docs/data/charts/styling/PatternPie.tsx @@ -0,0 +1,44 @@ +import * as React from 'react'; +import { PieChart } from '@mui/x-charts/PieChart'; + +export default function PatternPie() { + return ( + + + + + + + ); +} diff --git a/docs/data/charts/styling/styling.md b/docs/data/charts/styling/styling.md index 9f795806ee5d0..fc64c9cb923d9 100644 --- a/docs/data/charts/styling/styling.md +++ b/docs/data/charts/styling/styling.md @@ -164,3 +164,22 @@ Chart components accept the `sx` props. From here, you can target any subcomponents with its class name. {{"demo": "SxStyling.js"}} + +### Gradients and patterns + +It is possible to use gradients and patterns to fill the charts. +This can be done by passing your gradient or pattern definition as children of the chart component. + +Note that the gradient or pattern defined that way is only usable for SVG. +So a direct definition like `color: "url(#Pattern)'` would cause undefined colors in HTML elements such as the tooltip. +The demo solves this issue by using a CSS variable `'--my-custom-pattern': 'url(#Pattern)'` to specify fallback color with `color: 'var(--my-custom-pattern, #123456)'`. + +{{"demo": "PatternPie.js"}} + +#### Using gradients on tooltips + +Gradients defined as SVG elements are not directly supported in HTML. +However you can use the [gradient functions](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Functions#gradient_functions) to define a gradient in CSS. +This gradient can be used in the tooltip by setting the `sx` prop on the tooltip component, instead of the fallback color used in the previous examples. + +{{"demo": "GradientTooltip.js"}} diff --git a/packages/x-charts/src/ChartsTooltip/ChartsTooltipTable.ts b/packages/x-charts/src/ChartsTooltip/ChartsTooltipTable.ts index a50e1c462c51c..e1334f6675cd1 100644 --- a/packages/x-charts/src/ChartsTooltip/ChartsTooltipTable.ts +++ b/packages/x-charts/src/ChartsTooltip/ChartsTooltipTable.ts @@ -85,7 +85,7 @@ export const ChartsTooltipMark = styled('div', { height: theme.spacing(1), borderRadius: '50%', boxShadow: theme.shadows[1], - backgroundColor: color, + background: color, borderColor: (theme.vars || theme).palette.background.paper, border: `solid ${(theme.vars || theme).palette.background.paper} ${theme.spacing(0.25)}`, boxSizing: 'content-box', diff --git a/packages/x-charts/src/PieChart/PieArc.tsx b/packages/x-charts/src/PieChart/PieArc.tsx index 6919b17363ed7..6f6c61104d629 100644 --- a/packages/x-charts/src/PieChart/PieArc.tsx +++ b/packages/x-charts/src/PieChart/PieArc.tsx @@ -42,9 +42,15 @@ export const pieArcClasses: PieArcClasses = generateUtilityClasses('MuiPieArc', ]); const useUtilityClasses = (ownerState: PieArcOwnerState) => { - const { classes, id, isFaded, isHighlighted } = ownerState; + const { classes, id, isFaded, isHighlighted, dataIndex } = ownerState; const slots = { - root: ['root', `series-${id}`, isHighlighted && 'highlighted', isFaded && 'faded'], + root: [ + 'root', + `series-${id}`, + `data-index-${dataIndex}`, + isHighlighted && 'highlighted', + isFaded && 'faded', + ], }; return composeClasses(slots, getPieArcUtilityClass, classes); @@ -55,9 +61,9 @@ const PieArcRoot = styled(animated.path, { slot: 'Root', overridesResolver: (_, styles) => styles.arc, })<{ ownerState: PieArcOwnerState }>(({ theme }) => ({ + // Got to move stroke to an element prop instead of style. stroke: (theme.vars || theme).palette.background.paper, - strokeWidth: 1, - strokeLinejoin: 'round', + transition: 'opacity 0.2s ease-in, fill 0.2s ease-in, filter 0.2s ease-in', })); export type PieArcProps = Omit, 'ref' | 'id'> & @@ -124,6 +130,11 @@ function PieArc(props: PieArcProps) { cursor={onClick ? 'pointer' : 'unset'} ownerState={ownerState} className={classes.root} + fill={ownerState.color} + opacity={ownerState.isFaded ? 0.3 : 1} + filter={ownerState.isHighlighted ? 'brightness(120%)' : 'none'} + strokeWidth={1} + strokeLinejoin="round" {...other} {...getInteractionItemProps({ type: 'pie', seriesId: id, dataIndex })} /> diff --git a/packages/x-charts/src/PieChart/PieArcPlot.tsx b/packages/x-charts/src/PieChart/PieArcPlot.tsx index 13e233d5b642a..1a340402c5658 100644 --- a/packages/x-charts/src/PieChart/PieArcPlot.tsx +++ b/packages/x-charts/src/PieChart/PieArcPlot.tsx @@ -112,10 +112,8 @@ function PieArcPlot(props: PieArcPlotProps) { endAngle, paddingAngle: pA, innerRadius: iR, - arcLabelRadius, outerRadius: oR, cornerRadius: cR, - ...style }, item, _, @@ -129,7 +127,6 @@ function PieArcPlot(props: PieArcPlotProps) { innerRadius={iR} outerRadius={oR} cornerRadius={cR} - style={style} id={id} color={item.color} dataIndex={index}