Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 0 additions & 2 deletions docs/data/charts/heatmap/heatmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,6 @@ You can modify it with `slots.legend` and `slotProps.legend`.

{{"demo": "HeatmapLegend.js"}}

## Labels 🚧

## Custom item

{{"demo": "CustomItem.js"}}
40 changes: 40 additions & 0 deletions docs/data/charts/scatter/ScatterCSSSelectors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as React from 'react';
import { ScatterChart } from '@mui/x-charts/ScatterChart';

import { data } from './randomData';

const series = [
{
id: 'series-1',
type: 'scatter',
label: 'Series A',
data: data.map((v) => ({ x: v.x1, y: v.y1, id: v.id })),
highlightScope: { highlight: 'item', fade: 'global' },
},
{
id: 'series-2',
type: 'scatter',
label: 'Series B',
data: data.map((v) => ({ x: v.x1, y: v.y2, id: v.id })),
highlightScope: { highlight: 'item', fade: 'global' },
},
];

export default function ScatterCSSSelectors() {
return (
<ScatterChart
height={300}
voronoiMaxRadius={30}
series={series}
sx={{
'& [data-faded=true]': { opacity: 0.4 },
"& [data-series='series-1'] [data-faded=true]": { fill: 'gray' },
"& [data-series='series-1'] [data-highlighted=true]": {
stroke: 'blue',
strokeWidth: 3,
fill: 'none',
},
}}
/>
);
}
40 changes: 40 additions & 0 deletions docs/data/charts/scatter/ScatterCSSSelectors.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as React from 'react';
import { ScatterChart } from '@mui/x-charts/ScatterChart';
import { ScatterSeriesType } from '@mui/x-charts/models';
import { data } from './randomData';

const series: ScatterSeriesType[] = [
{
id: 'series-1',
type: 'scatter',
label: 'Series A',
data: data.map((v) => ({ x: v.x1, y: v.y1, id: v.id })),
highlightScope: { highlight: 'item', fade: 'global' },
},
{
id: 'series-2',
type: 'scatter',
label: 'Series B',
data: data.map((v) => ({ x: v.x1, y: v.y2, id: v.id })),
highlightScope: { highlight: 'item', fade: 'global' },
},
];

export default function ScatterCSSSelectors() {
return (
<ScatterChart
height={300}
voronoiMaxRadius={30}
series={series}
sx={{
'& [data-faded=true]': { opacity: 0.4 },
"& [data-series='series-1'] [data-faded=true]": { fill: 'gray' },
"& [data-series='series-1'] [data-highlighted=true]": {
stroke: 'blue',
strokeWidth: 3,
fill: 'none',
},
}}
/>
);
}
14 changes: 14 additions & 0 deletions docs/data/charts/scatter/ScatterCSSSelectors.tsx.preview
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<ScatterChart
height={300}
voronoiMaxRadius={30}
series={series}
sx={{
'& [data-faded=true]': { opacity: 0.4 },
"& [data-series='series-1'] [data-faded=true]": { fill: 'gray' },
"& [data-series='series-1'] [data-highlighted=true]": {
stroke: 'blue',
strokeWidth: 3,
fill: 'none',
},
}}
/>
14 changes: 13 additions & 1 deletion docs/data/charts/scatter/scatter.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,19 @@ See [Axis—Grid](/x/react-charts/axis/#grid) documentation for more information

{{"demo": "GridDemo.js"}}

### CSS 🚧
### CSS

You can target scatter markers with the following CSS selectors:

- `[data-series='<series id>']` Selects the group containing markers of the series with the given id.
- `[data-highlighted=true]` Selects markers with highlighted state.
- `[data-faded=true]` Selects markers with faded state.

To select all marker groups, use the `scatterClasses.root` class name.

Here is an example that customizes the look of highlighted items depending on the series they belong to.

{{"demo": "ScatterCSSSelectors.js"}}

### Shape

Expand Down
9 changes: 8 additions & 1 deletion docs/pages/x/api/charts/scatter.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,14 @@
"class": null
}
],
"classes": [],
"classes": [
{
"key": "root",
"className": "MuiScatter-root",
"description": "Styles applied to the root element.",
"isGlobal": false
}
],
"muiName": "MuiScatter",
"filename": "/packages/x-charts/src/ScatterChart/Scatter.tsx",
"inheritance": null,
Expand Down
2 changes: 1 addition & 1 deletion docs/translations/api-docs/charts/scatter/scatter.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
}
}
},
"classDescriptions": {},
"classDescriptions": { "root": { "description": "Styles applied to the root element." } },
"slotDescriptions": { "marker": "The component that renders the marker for a scatter point." }
}
21 changes: 19 additions & 2 deletions packages/x-charts/src/ScatterChart/Scatter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { useChartContext } from '../context/ChartProvider';
import { ScatterMarker } from './ScatterMarker';
import { SeriesId } from '../models/seriesType/common';
import { ColorGetter } from '../internals/plugins/models/seriesConfig';
import { ScatterClasses, useUtilityClasses } from './scatterClasses';

export interface ScatterProps {
series: DefaultizedScatterSeriesType;
Expand All @@ -38,6 +39,7 @@ export interface ScatterProps {
event: React.MouseEvent<SVGElement, MouseEvent>,
scatterItemIdentifier: ScatterItemIdentifier,
) => void;
classes?: Partial<ScatterClasses>;
slots?: ScatterSlots;
slotProps?: ScatterSlotProps;
}
Expand All @@ -57,7 +59,17 @@ export interface ScatterSlotProps extends ScatterMarkerSlotProps {}
* - [Scatter API](https://mui.com/x/api/charts/scatter/)
*/
function Scatter(props: ScatterProps) {
const { series, xScale, yScale, color, colorGetter, onItemClick, slots, slotProps } = props;
const {
series,
xScale,
yScale,
color,
colorGetter,
onItemClick,
classes: inClasses,
slots,
slotProps,
} = props;

const { instance } = useChartContext();
const store = useStore<[UseChartVoronoiSignature]>();
Expand Down Expand Up @@ -134,8 +146,10 @@ function Scatter(props: ScatterProps) {
ownerState: {},
});

const classes = useUtilityClasses(inClasses);

return (
<g>
<g data-series={series.id} className={classes.root}>
{cleanData.map((dataPoint, i) => (
<Marker
key={dataPoint.id ?? dataPoint.dataIndex}
Expand All @@ -154,6 +168,8 @@ function Scatter(props: ScatterProps) {
dataIndex: dataPoint.dataIndex,
}))
}
data-highlighted={dataPoint.isHighlighted || undefined}
data-faded={dataPoint.isFaded || undefined}
{...interactionItemProps[i]}
{...markerProps}
/>
Expand All @@ -167,6 +183,7 @@ Scatter.propTypes = {
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "pnpm proptypes" |
// ----------------------------------------------------------------------
classes: PropTypes.object,
color: PropTypes.string.isRequired,
colorGetter: PropTypes.func,
/**
Expand Down
2 changes: 2 additions & 0 deletions packages/x-charts/src/ScatterChart/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ export * from './ScatterPlot';
export * from './Scatter';
export * from './ScatterMarker.types';
export * from './ScatterMarker';
export type { ScatterClasses } from './scatterClasses';
export { scatterClasses } from './scatterClasses';
24 changes: 24 additions & 0 deletions packages/x-charts/src/ScatterChart/scatterClasses.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import generateUtilityClass from '@mui/utils/generateUtilityClass';
import composeClasses from '@mui/utils/composeClasses';
import generateUtilityClasses from '@mui/utils/generateUtilityClasses';

export interface ScatterClasses {
/** Styles applied to the root element. */
root: string;
}

export type ScatterClassKey = keyof ScatterClasses;

export function getScatterUtilityClass(slot: string) {
return generateUtilityClass('MuiScatter', slot);
}

export const scatterClasses: ScatterClasses = generateUtilityClasses('MuiScatter', ['root']);

export const useUtilityClasses = (classes?: Partial<ScatterClasses>) => {
const slots = {
root: ['root'],
};

return composeClasses(slots, getScatterUtilityClass, classes);
};
2 changes: 2 additions & 0 deletions scripts/x-charts-pro.exports.json
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,8 @@
{ "name": "ScatterChartProSlots", "kind": "Interface" },
{ "name": "ScatterChartSlotProps", "kind": "Interface" },
{ "name": "ScatterChartSlots", "kind": "Interface" },
{ "name": "scatterClasses", "kind": "Variable" },
{ "name": "ScatterClasses", "kind": "Interface" },
{ "name": "ScatterItemIdentifier", "kind": "TypeAlias" },
{ "name": "ScatterMarker", "kind": "Function" },
{ "name": "ScatterMarkerProps", "kind": "Interface" },
Expand Down
2 changes: 2 additions & 0 deletions scripts/x-charts.exports.json
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@
{ "name": "ScatterChartProps", "kind": "Interface" },
{ "name": "ScatterChartSlotProps", "kind": "Interface" },
{ "name": "ScatterChartSlots", "kind": "Interface" },
{ "name": "scatterClasses", "kind": "Variable" },
{ "name": "ScatterClasses", "kind": "Interface" },
{ "name": "ScatterItemIdentifier", "kind": "TypeAlias" },
{ "name": "ScatterMarker", "kind": "Function" },
{ "name": "ScatterMarkerProps", "kind": "Interface" },
Expand Down