Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[charts] Replace tooltip mark with style #16117

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
30 changes: 18 additions & 12 deletions docs/data/charts/styling/GradientTooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,40 @@ import { BarChart } from '@mui/x-charts/BarChart';
export default function GradientTooltip() {
return (
<BarChart
sx={{
'--my-custom-gradient': 'url(#GlobalGradient)',
}}
slotProps={{
tooltip: {
sx: {
'--my-custom-gradient': 'linear-gradient(0deg, #123456, #81b2e4);',
},
},
}}
series={[
{
label: 'series A',
data: [50],
color: 'url(#Pattern)',
},
{
label: 'series B',
data: [100],
color: 'var(--my-custom-gradient, #123456)',
color: 'url(#Gradient)',
},
]}
width={400}
height={200}
>
<linearGradient id="GlobalGradient" x1="0%" y1="100%" x2="0%" y2="0%">
<linearGradient id="Gradient" x1="0%" y1="100%" x2="0%" y2="0%">
<stop offset="0" stopColor="#123456" />
<stop offset="1" stopColor="#81b2e4" />
</linearGradient>
<pattern
id="Pattern"
patternUnits="userSpaceOnUse"
width="20"
height="40"
patternTransform="scale(0.5)"
>
<rect x="0" y="0" width="100%" height="100%" fill="#123456" />
<path
d="M0 30h20L10 50zm-10-20h20L0 30zm20 0h20L20 30zM0-10h20L10 10z"
strokeWidth="1"
stroke="#81b2e4"
fill="none"
/>
</pattern>
</BarChart>
);
}
30 changes: 18 additions & 12 deletions docs/data/charts/styling/GradientTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,40 @@ import { BarChart } from '@mui/x-charts/BarChart';
export default function GradientTooltip() {
return (
<BarChart
sx={{
'--my-custom-gradient': 'url(#GlobalGradient)',
}}
slotProps={{
tooltip: {
sx: {
'--my-custom-gradient': 'linear-gradient(0deg, #123456, #81b2e4);',
},
},
}}
series={[
{
label: 'series A',
data: [50],
color: 'url(#Pattern)',
},
{
label: 'series B',
data: [100],
color: 'var(--my-custom-gradient, #123456)',
color: 'url(#Gradient)',
},
]}
width={400}
height={200}
>
<linearGradient id="GlobalGradient" x1="0%" y1="100%" x2="0%" y2="0%">
<linearGradient id="Gradient" x1="0%" y1="100%" x2="0%" y2="0%">
<stop offset="0" stopColor="#123456" />
<stop offset="1" stopColor="#81b2e4" />
</linearGradient>
<pattern
id="Pattern"
patternUnits="userSpaceOnUse"
width="20"
height="40"
patternTransform="scale(0.5)"
>
<rect x="0" y="0" width="100%" height="100%" fill="#123456" />
<path
d="M0 30h20L10 50zm-10-20h20L0 30zm20 0h20L20 30zM0-10h20L10 10z"
strokeWidth="1"
stroke="#81b2e4"
fill="none"
/>
</pattern>
</BarChart>
);
}
47 changes: 0 additions & 47 deletions docs/data/charts/styling/PatternPie.js

This file was deleted.

47 changes: 0 additions & 47 deletions docs/data/charts/styling/PatternPie.tsx

This file was deleted.

11 changes: 1 addition & 10 deletions docs/data/charts/styling/styling.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,15 +171,6 @@ 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.
So a direct definition like `color: "url(#Pattern)'` would cause undefined colors in HTML elements.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
So a direct definition like `color: "url(#Pattern)'` would cause undefined colors in HTML elements.
So a direct definition like `color: "url(#Pattern)'` would cause undefined colors in HTML elements like the toltip or the legend.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tooltip and legend now use an SVG as the mark, so they can use that. 🙃


{{"demo": "GradientTooltip.js"}}
8 changes: 4 additions & 4 deletions docs/data/charts/tooltip/CustomAxisTooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ export function CustomAxisTooltip() {
},
},
tbody: {
'tr:first-child': { td: { paddingTop: 1.5 } },
'tr:last-child': { td: { paddingBottom: 1.5 } },
'tr:first-of-type': { td: { paddingTop: 1.5 } },
'tr:last-of-type': { td: { paddingBottom: 1.5 } },
tr: {
'td:first-child': { paddingLeft: 1.5 },
'td:last-child': { paddingRight: 1.5 },
'td:first-of-type': { paddingLeft: 1.5 },
'td:last-of-type': { paddingRight: 1.5 },
td: {
paddingRight: '7px',
paddingBottom: '10px',
Expand Down
8 changes: 4 additions & 4 deletions docs/data/charts/tooltip/CustomAxisTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ export function CustomAxisTooltip() {
},
},
tbody: {
'tr:first-child': { td: { paddingTop: 1.5 } },
'tr:last-child': { td: { paddingBottom: 1.5 } },
'tr:first-of-type': { td: { paddingTop: 1.5 } },
'tr:last-of-type': { td: { paddingBottom: 1.5 } },
tr: {
'td:first-child': { paddingLeft: 1.5 },
'td:last-child': { paddingRight: 1.5 },
'td:first-of-type': { paddingLeft: 1.5 },
'td:last-of-type': { paddingRight: 1.5 },
td: {
paddingRight: '7px',
paddingBottom: '10px',
Expand Down
6 changes: 3 additions & 3 deletions docs/data/charts/tooltip/ItemTooltipFixedY.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export function ItemTooltipFixedY({ children }) {
const handleMove = (event) => {
positionRef.current = {
x: event.clientX,
y: event.clientY,
y: (svgRef.current?.getBoundingClientRect().top ?? 0) + drawingArea.top,
};
popperRef.current?.update();
};
Expand Down Expand Up @@ -99,8 +99,8 @@ export function ItemTooltipFixedY({ children }) {
y: positionRef.current.y,
top: positionRef.current.y,
left: positionRef.current.x,
right: positionRef.current.x,
bottom: positionRef.current.y,
right: 0,
bottom: 0,
width: 0,
height: 0,
toJSON: () => '',
Expand Down
6 changes: 3 additions & 3 deletions docs/data/charts/tooltip/ItemTooltipFixedY.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export function ItemTooltipFixedY({ children }: React.PropsWithChildren) {
const handleMove = (event: PointerEvent) => {
positionRef.current = {
x: event.clientX,
y: event.clientY,
y: (svgRef.current?.getBoundingClientRect().top ?? 0) + drawingArea.top,
};
popperRef.current?.update();
};
Expand Down Expand Up @@ -105,8 +105,8 @@ export function ItemTooltipFixedY({ children }: React.PropsWithChildren) {
y: positionRef.current.y,
top: positionRef.current.y,
left: positionRef.current.x,
right: positionRef.current.x,
bottom: positionRef.current.y,
right: 0,
bottom: 0,
width: 0,
height: 0,
toJSON: () => '',
Expand Down
1 change: 1 addition & 0 deletions packages/x-charts/src/BarChart/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const formatter: SeriesFormatter<'bar'> = (params, dataset) => {
const dataKey = series[id].dataKey;
completedSeries[id] = {
layout: 'vertical',
labelMarkType: 'square',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved markType default from legend getter to series formatter as the tooltip doesn't use the legend getter

...series[id],
data: dataKey
? dataset!.map((data) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/x-charts/src/BarChart/legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const legendGetter: LegendGetter<'bar'> = (params) => {
}

acc.push({
markType: series[seriesId].labelMarkType ?? 'square',
markType: series[seriesId].labelMarkType,
id: seriesId,
seriesId,
color: series[seriesId].color,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import clsx from 'clsx';
import { ChartsTooltipClasses, useUtilityClasses } from './chartsTooltipClasses';
import {
ChartsTooltipCell,
ChartsTooltipMark,
ChartsTooltipPaper,
ChartsTooltipRow,
ChartsTooltipTable,
} from './ChartsTooltipTable';
import { useAxisTooltip } from './useAxisTooltip';
import { useXAxis, useYAxis } from '../hooks';
import { ChartsLabelMark } from '../ChartsLabel/ChartsLabelMark';

export interface ChartsAxisTooltipContentProps {
/**
Expand Down Expand Up @@ -53,14 +53,16 @@ function ChartsAxisTooltipContent(props: ChartsAxisTooltipContentProps) {
)}

<tbody>
{seriesItems.map(({ seriesId, color, formattedValue, formattedLabel }) => {
{seriesItems.map(({ seriesId, color, formattedValue, formattedLabel, markType }) => {
if (formattedValue == null) {
return null;
}
return (
<ChartsTooltipRow key={seriesId} className={classes.row}>
<ChartsTooltipCell className={clsx(classes.markCell, classes.cell)}>
{color && <ChartsTooltipMark color={color} className={classes.mark} />}
{color && (
<ChartsLabelMark type={markType} color={color} className={classes.mark} />
)}
</ChartsTooltipCell>
<ChartsTooltipCell className={clsx(classes.labelCell, classes.cell)}>
{formattedLabel ? <Typography>{formattedLabel}</Typography> : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { ChartsTooltipClasses, useUtilityClasses } from './chartsTooltipClasses'
import { useItemTooltip } from './useItemTooltip';
import {
ChartsTooltipCell,
ChartsTooltipMark,
ChartsTooltipPaper,
ChartsTooltipRow,
ChartsTooltipTable,
} from './ChartsTooltipTable';
import { ChartsLabelMark } from '../ChartsLabel/ChartsLabelMark';

export interface ChartsItemTooltipContentProps {
/**
Expand All @@ -30,15 +30,15 @@ function ChartsItemTooltipContent(props: ChartsItemTooltipContentProps) {
if (!tooltipData) {
return null;
}
const { color, label, formattedValue } = tooltipData;
const { color, label, formattedValue, markType } = tooltipData;

return (
<ChartsTooltipPaper sx={sx} className={classes.paper}>
<ChartsTooltipTable className={classes.table}>
<tbody>
<ChartsTooltipRow className={classes.row}>
<ChartsTooltipCell className={clsx(classes.markCell, classes.cell)}>
<ChartsTooltipMark color={color} className={classes.mark} />
<ChartsLabelMark type={markType} color={color} className={classes.mark} />
</ChartsTooltipCell>
<ChartsTooltipCell className={clsx(classes.labelCell, classes.cell)}>
{label}
Expand Down
17 changes: 0 additions & 17 deletions packages/x-charts/src/ChartsTooltip/ChartsTooltipTable.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { styled } from '@mui/material/styles';
import { shouldForwardProp } from '@mui/system/createStyled';
import { chartsTooltipClasses } from './chartsTooltipClasses';

/**
Expand Down Expand Up @@ -77,19 +76,3 @@ export const ChartsTooltipCell = styled('td', {
paddingRight: theme.spacing(1.5),
},
}));

/**
* @ignore - internal component.
*/
export const ChartsTooltipMark = styled('div', {
name: 'MuiChartsTooltip',
slot: 'Mark',
overridesResolver: (props, styles) => styles.mark,
shouldForwardProp: (prop) => shouldForwardProp(prop) && prop !== 'color',
})<{ color: string }>(({ theme, color }) => ({
width: theme.spacing(1),
height: theme.spacing(1),
borderRadius: '50%',
background: color,
boxSizing: 'content-box',
}));
Loading
Loading