Skip to content
Open
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
9 changes: 9 additions & 0 deletions docs/data/charts/radial-lines/radial-lines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: React Radial Line chart
productId: x-charts
components: ChartsRadialDataProvider
---

# Charts - Radial Lines

<p class="description">Use radial line charts to show trends along periodic values.</p>
4 changes: 4 additions & 0 deletions docs/data/chartsApiPages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ const chartsApiPages: MuiPage[] = [
pathname: '/x/api/charts/charts-localization-provider',
title: 'ChartsLocalizationProvider',
},
{
pathname: '/x/api/charts/charts-radial-data-provider',
title: 'ChartsRadialDataProvider',
},
{
pathname: '/x/api/charts/charts-reference-line',
title: 'ChartsReferenceLine',
Expand Down
4 changes: 2 additions & 2 deletions docs/pages/x/api/charts/charts-container.json

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions docs/pages/x/api/charts/charts-radial-data-provider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as React from 'react';
import ApiPage from 'docs/src/modules/components/ApiPage';
import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations';
import jsonPageContent from './charts-radial-data-provider.json';

export default function Page(props) {
const { descriptions } = props;
return <ApiPage descriptions={descriptions} pageContent={jsonPageContent} />;
}

export async function getStaticProps() {
const req = require.context(
'docsx/translations/api-docs/charts/charts-radial-data-provider',
false,
/\.\/charts-radial-data-provider.*\.json$/,
);
const descriptions = mapApiPageTranslations(req);

return { props: { descriptions } };
}
41 changes: 41 additions & 0 deletions docs/pages/x/api/charts/charts-radial-data-provider.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"props": {
"colors": {
"type": { "name": "union", "description": "Array&lt;string&gt;<br>&#124;&nbsp;func" },
"default": "rainbowSurgePalette"
},
"height": { "type": { "name": "number" } },
"id": { "type": { "name": "string" } },
"localeText": { "type": { "name": "object" } },
"margin": {
"type": {
"name": "union",
"description": "number<br>&#124;&nbsp;{ bottom?: number, left?: number, right?: number, top?: number }"
}
},
"series": { "type": { "name": "arrayOf", "description": "Array&lt;object&gt;" } },
"skipAnimation": { "type": { "name": "bool" } },
"slotProps": { "type": { "name": "object" } },
"slots": { "type": { "name": "object" }, "additionalInfo": { "slotsApi": true } },
"width": { "type": { "name": "number" } }
},
"name": "ChartsRadialDataProvider",
"imports": [
"import { ChartsRadialDataProvider } from '@mui/x-charts/ChartsRadialDataProvider';",
"import { ChartsRadialDataProvider } from '@mui/x-charts';",
"import { ChartsRadialDataProvider } from '@mui/x-charts-pro';",
"import { ChartsRadialDataProvider } from '@mui/x-charts-premium';"
],
"slots": [
{ "name": "baseButton", "description": "", "class": null },
{ "name": "baseIconButton", "description": "", "class": null }
],
"classes": [],
"spread": true,
"themeDefaultProps": null,
"muiName": "MuiChartsRadialDataProvider",
"filename": "/packages/x-charts/src/ChartsRadialDataProvider/ChartsRadialDataProvider.tsx",
"inheritance": null,
"demos": "<ul><li><a href=\"/x/react-charts/radial-lines/\">Charts - Radial Lines</a></li></ul>",
"cssComponent": false
}
6 changes: 6 additions & 0 deletions docs/pages/x/react-charts/radial-lines.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs';
import * as pageProps from 'docsx/data/charts/radial-lines/radial-lines.md?muiMarkdown';

export default function Page() {
return <MarkdownDocs {...pageProps} />;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"componentDescription": "Orchestrates the data providers for radial chart components and hooks.\n\nSimilar to `ChartsDataProvider`, but uses the radial axis plugin instead of the cartesian one,\nand only supports the line series config.",
"propDescriptions": {
"colors": { "description": "Color palette used to colorize multiple series." },
"height": {
"description": "The height of the chart in px. If not defined, it takes the height of the parent element."
},
"id": {
"description": "This prop is used to help implement the accessibility logic. If you don&#39;t provide this prop. It falls back to a randomly generated id."
},
"localeText": { "description": "Localized text for chart components." },
"margin": {
"description": "The margin between the SVG and the drawing area. It&#39;s used for leaving some space for extra information such as the x- and y-axis or legend.<br>Accepts a <code>number</code> to be used on all sides or an object with the optional properties: <code>top</code>, <code>bottom</code>, <code>left</code>, and <code>right</code>."
},
"series": {
"description": "The array of series to display. Each type of series has its own specificity. Please refer to the appropriate docs page to learn more about it."
},
"skipAnimation": {
"description": "If <code>true</code>, animations are skipped. If unset or <code>false</code>, the animations respects the user&#39;s <code>prefers-reduced-motion</code> setting."
},
"slotProps": { "description": "The props for the slots." },
"slots": { "description": "Slots to customize charts&#39; components." },
"width": {
"description": "The width of the chart in px. If not defined, it takes the width of the parent element."
}
},
"classDescriptions": {},
"slotDescriptions": { "baseButton": "", "baseIconButton": "" }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Re-export automatically generated, to customize, simply remove this line.
export * from '@mui/x-charts/ChartsRadialDataProvider';
2 changes: 2 additions & 0 deletions packages/x-charts-pro/src/ChartsRadialDataProvider/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Re-export automatically generated, to customize, simply remove this line.
export * from '@mui/x-charts/ChartsRadialDataProvider';
20 changes: 10 additions & 10 deletions packages/x-charts/src/ChartsContainer/ChartsContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ ChartsContainer.propTypes = {
domainLimit: PropTypes.oneOfType([PropTypes.oneOf(['nice', 'strict']), PropTypes.func]),
height: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]),
hideTooltip: PropTypes.bool,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
ignoreTooltip: PropTypes.bool,
label: PropTypes.string,
labelStyle: PropTypes.object,
Expand Down Expand Up @@ -423,7 +423,7 @@ ChartsContainer.propTypes = {
),
height: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]),
hideTooltip: PropTypes.bool,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
ignoreTooltip: PropTypes.bool,
label: PropTypes.string,
labelGap: PropTypes.number,
Expand Down Expand Up @@ -514,7 +514,7 @@ ChartsContainer.propTypes = {
),
height: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]),
hideTooltip: PropTypes.bool,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
ignoreTooltip: PropTypes.bool,
label: PropTypes.string,
labelGap: PropTypes.number,
Expand Down Expand Up @@ -589,7 +589,7 @@ ChartsContainer.propTypes = {
endAngle: PropTypes.number,
height: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]),
hideTooltip: PropTypes.bool,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
ignoreTooltip: PropTypes.bool,
label: PropTypes.string,
labelGap: PropTypes.number,
Expand Down Expand Up @@ -657,7 +657,7 @@ ChartsContainer.propTypes = {
endAngle: PropTypes.number,
height: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]),
hideTooltip: PropTypes.bool,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
ignoreTooltip: PropTypes.bool,
label: PropTypes.string,
labelGap: PropTypes.number,
Expand Down Expand Up @@ -724,7 +724,7 @@ ChartsContainer.propTypes = {
endAngle: PropTypes.number,
height: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]),
hideTooltip: PropTypes.bool,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
ignoreTooltip: PropTypes.bool,
label: PropTypes.string,
labelGap: PropTypes.number,
Expand Down Expand Up @@ -791,7 +791,7 @@ ChartsContainer.propTypes = {
endAngle: PropTypes.number,
height: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]),
hideTooltip: PropTypes.bool,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
ignoreTooltip: PropTypes.bool,
label: PropTypes.string,
labelGap: PropTypes.number,
Expand Down Expand Up @@ -858,7 +858,7 @@ ChartsContainer.propTypes = {
endAngle: PropTypes.number,
height: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]),
hideTooltip: PropTypes.bool,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
ignoreTooltip: PropTypes.bool,
label: PropTypes.string,
labelGap: PropTypes.number,
Expand Down Expand Up @@ -935,7 +935,7 @@ ChartsContainer.propTypes = {
endAngle: PropTypes.number,
height: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]),
hideTooltip: PropTypes.bool,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
ignoreTooltip: PropTypes.bool,
label: PropTypes.string,
labelGap: PropTypes.number,
Expand Down Expand Up @@ -1012,7 +1012,7 @@ ChartsContainer.propTypes = {
endAngle: PropTypes.number,
height: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]),
hideTooltip: PropTypes.bool,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
ignoreTooltip: PropTypes.bool,
label: PropTypes.string,
labelGap: PropTypes.number,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {
useChartPolarAxis,
type UseChartPolarAxisSignature,
} from '../internals/plugins/featurePlugins/useChartPolarAxis';
import {
useChartTooltip,
type UseChartTooltipSignature,
} from '../internals/plugins/featurePlugins/useChartTooltip';
import {
useChartInteraction,
type UseChartInteractionSignature,
} from '../internals/plugins/featurePlugins/useChartInteraction';
import {
useChartHighlight,
type UseChartHighlightSignature,
} from '../internals/plugins/featurePlugins/useChartHighlight';
import {
useChartKeyboardNavigation,
type UseChartKeyboardNavigationSignature,
} from '../internals/plugins/featurePlugins/useChartKeyboardNavigation';
import {
useChartVisibilityManager,
type UseChartVisibilityManagerSignature,
} from '../internals/plugins/featurePlugins/useChartVisibilityManager';
import type { PolarChartSeriesType } from '../models/seriesType/config';

export const RADIAL_PLUGINS = [
useChartTooltip,
useChartInteraction,
useChartPolarAxis,
useChartHighlight,
useChartKeyboardNavigation,
useChartVisibilityManager,
] as const;

export type RadialPluginSignatures<SeriesType extends PolarChartSeriesType = PolarChartSeriesType> =
[
UseChartTooltipSignature<SeriesType>,
UseChartInteractionSignature,
UseChartPolarAxisSignature,
UseChartHighlightSignature<SeriesType>,
UseChartKeyboardNavigationSignature,
UseChartVisibilityManagerSignature<SeriesType>,
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import * as React from 'react';
import { vi } from 'vitest';
import { createRenderer } from '@mui/internal-test-utils';
import { useChartsLocalization } from '@mui/x-charts/hooks';
import { type ChartsLocaleText } from '@mui/x-charts/locales';
import { Unstable_ChartsRadialDataProvider as ChartsRadialDataProvider } from '@mui/x-charts/ChartsRadialDataProvider';
import { useChartsSlots } from '../context/ChartsSlotsContext';
import { useStore } from '../internals/store/useStore';
import { selectorChartPolarAxisState } from '../internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.selectors';
import { selectorChartCartesianAxisState } from '../internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisLayout.selectors';

describe('<ChartsRadialDataProvider />', () => {
const { render } = createRenderer();

it('should setup localization', () => {
const handleContextChange = vi.fn();

function LocaleListener() {
const context = useChartsLocalization();
React.useEffect(() => {
handleContextChange(context);
}, [context]);
return null;
}

render(
<ChartsRadialDataProvider width={100} height={100} localeText={{ noData: 'Aucune donnée' }}>
<LocaleListener />
</ChartsRadialDataProvider>,
);

const localeText: ChartsLocaleText = handleContextChange.mock.lastCall?.[0].localeText;
expect(localeText.noData).to.equal('Aucune donnée');
// Default values should still be available
expect(localeText.loading).to.equal('Loading data…');
});

it('should propagate slots and slotProps', () => {
const handleSlotsChange = vi.fn();
function CustomButton() {
return <button>custom</button>;
}

function SlotsListener() {
const context = useChartsSlots();
React.useEffect(() => {
handleSlotsChange(context);
}, [context]);
return null;
}

render(
<ChartsRadialDataProvider
width={100}
height={100}
slots={{ baseButton: CustomButton }}
slotProps={{ baseButton: { disabled: true } }}
>
<SlotsListener />
</ChartsRadialDataProvider>,
);

const { slots, slotProps } = handleSlotsChange.mock.lastCall![0];
expect(slots.baseButton).to.equal(CustomButton);
expect(slotProps.baseButton).to.deep.equal({ disabled: true });
});

it('should setup a store with rotation/radius axes but not x/y axes', () => {
const handleStoreChange = vi.fn();

function StoreListener() {
const store = useStore();
React.useEffect(() => {
const state = store.getSnapshot();
handleStoreChange({
polarAxis: selectorChartPolarAxisState(state),
cartesianAxis: selectorChartCartesianAxisState(state),
});
});
return null;
}

render(
<ChartsRadialDataProvider
width={100}
height={100}
rotationAxis={[{ scaleType: 'band', data: ['A', 'B', 'C'] }]}
radiusAxis={[{ id: 'radius-1' }]}
>
<StoreListener />
</ChartsRadialDataProvider>,
);

const { polarAxis, cartesianAxis } = handleStoreChange.mock.lastCall![0];

// Polar axes should be defined
expect(polarAxis).to.not.equal(undefined);
expect(polarAxis.rotation).to.have.length(1);
expect(polarAxis.radius).to.have.length(1);
expect(polarAxis.radius[0].id).to.equal('radius-1');

// Cartesian axes should not be defined
expect(cartesianAxis).to.equal(undefined);
});
});
Loading
Loading