Skip to content

[charts] Add a localization provider #17325

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

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Copy link
Member

Choose a reason for hiding this comment

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

Should this be called ChartsLocalizationTableNoSnap? It seems like we're using enUS spelling

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as React from 'react';
import LocalisationTable from 'docsx/src/modules/components/LocalizationTable';
import data from './data.json';

export default function ChartsLocalisationTableNoSnap() {
return <LocalisationTable data={data} />;
}
15 changes: 15 additions & 0 deletions docs/data/charts/localization/CustomLocaleOverlay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as React from 'react';
import { BarChart } from '@mui/x-charts/BarChart';

export default function CustomLocaleOverlay() {
return (
<BarChart
loading
localeText={{ loading: 'Data are coming 🧙‍♂️' }}
series={[]}
height={200}
width={300}
xAxis={[{ scaleType: 'band', data: ['Q1', 'Q2', 'Q3', 'Q4'] }]}
/>
);
}
15 changes: 15 additions & 0 deletions docs/data/charts/localization/CustomLocaleOverlay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as React from 'react';
import { BarChart } from '@mui/x-charts/BarChart';

export default function CustomLocaleOverlay() {
return (
<BarChart
loading
localeText={{ loading: 'Data are coming 🧙‍♂️' }}
series={[]}
height={200}
width={300}
xAxis={[{ scaleType: 'band', data: ['Q1', 'Q2', 'Q3', 'Q4'] }]}
/>
);
}
8 changes: 8 additions & 0 deletions docs/data/charts/localization/CustomLocaleOverlay.tsx.preview
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<BarChart
loading
localeText={{ loading: 'Data are coming 🧙‍♂️' }}
series={[]}
height={200}
width={300}
xAxis={[{ scaleType: 'band', data: ['Q1', 'Q2', 'Q3', 'Q4'] }]}
/>
10 changes: 10 additions & 0 deletions docs/data/charts/localization/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"languageTag": "fr-FR",
"importName": "frFR",
"localeName": "French",
"missingKeysCount": 0,
"totalKeysCount": 2,
"githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-charts/src/locales/frFR.ts"
}
]
117 changes: 117 additions & 0 deletions docs/data/charts/localization/localization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
title: Charts - Localization
productId: x-charts
components: ChartsLocalizationProvider, ChartsDataContainer, ChartsLocalizationProvider
---

# Charts - Localization

<p class="description">The Charts allows to support users from different locales, with formatting, and localized strings.</p>

The default locale of MUI X is English (United States). If you want to use other locales, follow the instructions below.

## Translation keys

You can use the `localeText` prop to pass in your own text and translations.
You can find all the translation keys supported in [the source](https://github.com/mui/mui-x/blob/-/packages/x-charts/src/constants/defaultLocale.ts)
in the GitHub repository.
In the following example, the labels of the loading overlay are customized.

{{"demo": "CustomLocaleOverlay.js", "bg": "inline"}}

## Locale text

The default locale of MUI X is English (United States).

You can use the theme to configure the locale text:

```jsx
import { createTheme, ThemeProvider } from '@mui/material/styles';
import { BarChart } from '@mui/x-charts/BarChart';
import { frFR } from '@mui/x-charts/locales';
// Or import { frFR } from '@mui/x-charts-pro/locales';

const theme = createTheme(
{
palette: {
primary: { main: '#1976d2' },
},
},
frFR,
);

<ThemeProvider theme={theme}>
<BarChart />
</ThemeProvider>;
```

Note that `createTheme()` accepts any number of arguments.
If you are already using the [translations of the core components](/material-ui/guides/localization/#locale-text), you can add `frFR` as a new argument.
The same import works for Charts Pro as it's an extension of Charts.

```jsx
import { createTheme, ThemeProvider } from '@mui/material/styles';
import { BarChart } from '@mui/x-charts/BarChart';
import { frFR } from '@mui/x-charts/locales';
import { frFR as dataGridFrFR } from '@mui/x-date-pickers/locales';
import { frFR as pickersFrFR } from '@mui/x-date-pickers/locales';
import { frFR as coreFrFR } from '@mui/material/locale';

const theme = createTheme(
{
palette: {
primary: { main: '#1976d2' },
},
},
frFR, // x-charts translations
dataGridFrFR, // x-data-grid translations
pickersFrFR, // x-date-pickers translations
coreFrFR, // core translations
);

<ThemeProvider theme={theme}>
<BarChart />
</ThemeProvider>;
```

If you want to pass language translations directly to the Data Grid without using `createTheme()` and `ThemeProvider`, you can directly load the language translations from `@mui/x-data-grid/locales`.

```jsx
import { BarChart } from '@mui/x-charts';
import { nlNL } from '@mui/x-charts/locales';

<BarChart
localeText={nlNL.components.MuiChartsLocalizationProvider.defaultProps.localeText}
/>;
```

### Using ChartsLocalizationProvider

If you want to pass language translations without using `createTheme()` and `ThemeProvider`,
you can directly load the language translations from the `@mui/x-charts` or `@mui/x-charts-pro` package and pass them to the `ChartsLocalizationProvider`.

```jsx
import { ChartsLocalizationProvider } from '@mui/x-date-pickers/ChartsLocalizationProvider';
import { deDE } from '@mui/x-date-pickers/locales';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';

<ChartsLocalizationProvider
localeText={deDE.components.MuiChartsLocalizationProvider.defaultProps.localeText}
>
<DatePicker />
</ChartsLocalizationProvider>;
```

### Supported locales

{{"demo": "ChartsLocalisationTableNoSnap.js", "hideToolbar": true, "bg": "inline"}}

You can [find the source](https://github.com/mui/mui-x/tree/HEAD/packages/x-charts/src/locales) in the GitHub repository.

To create your own translation or to customize the English text, copy this file to your project, make any changes needed and import the locale from there.
Note that these translations of the Data Grid component depend on the [Localization strategy](/material-ui/guides/localization/) of the whole library.

## RTL Support

Right-to-left languages such as Arabic, Persian, or Hebrew are supported.
Follow [this guide](/material-ui/customization/right-to-left/) to use them.
4 changes: 4 additions & 0 deletions docs/data/chartsApiPages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ const chartsApiPages: MuiPage[] = [
pathname: '/x/api/charts/charts-legend',
title: 'ChartsLegend',
},
{
pathname: '/x/api/charts/charts-localization-provider',
title: 'ChartsLocalizationProvider',
},
{
pathname: '/x/api/charts/charts-reference-line',
title: 'ChartsReferenceLine',
Expand Down
1 change: 1 addition & 0 deletions docs/data/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ const pages: MuiPage[] = [
{ pathname: '/x/react-charts/composition' },
{ pathname: '/x/react-charts/label' },
{ pathname: '/x/react-charts/legend' },
{ pathname: '/x/react-chart/localization' },
{ pathname: '/x/react-charts/stacking' },
{ pathname: '/x/react-charts/styling' },
{ pathname: '/x/react-charts/tooltip' },
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/charts/bar-chart-pro.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"default": "'vertical'"
},
"loading": { "type": { "name": "bool" }, "default": "false" },
"localeText": { "type": { "name": "object" } },
"margin": {
"type": {
"name": "union",
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/charts/bar-chart.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"default": "'vertical'"
},
"loading": { "type": { "name": "bool" }, "default": "false" },
"localeText": { "type": { "name": "object" } },
"margin": {
"type": {
"name": "union",
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/charts/chart-container.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
}
},
"id": { "type": { "name": "string" } },
"localeText": { "type": { "name": "object" } },
"margin": {
"type": {
"name": "union",
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/charts/chart-data-provider-pro.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"dataset": { "type": { "name": "arrayOf", "description": "Array&lt;object&gt;" } },
"height": { "type": { "name": "number" } },
"id": { "type": { "name": "string" } },
"localeText": { "type": { "name": "object" } },
"margin": {
"type": {
"name": "union",
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/charts/chart-data-provider.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"dataset": { "type": { "name": "arrayOf", "description": "Array&lt;object&gt;" } },
"height": { "type": { "name": "number" } },
"id": { "type": { "name": "string" } },
"localeText": { "type": { "name": "object" } },
"margin": {
"type": {
"name": "union",
Expand Down
23 changes: 23 additions & 0 deletions docs/pages/x/api/charts/charts-localization-provider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
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-localization-provider.json';

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

Page.getInitialProps = () => {
const req = require.context(
'docsx/translations/api-docs/charts/charts-localization-provider',
false,
/\.\/charts-localization-provider.*.json$/,
);
const descriptions = mapApiPageTranslations(req);

return {
descriptions,
pageContent: jsonPageContent,
};
};
17 changes: 17 additions & 0 deletions docs/pages/x/api/charts/charts-localization-provider.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"props": { "localeText": { "type": { "name": "object" } } },
"name": "ChartsLocalizationProvider",
"imports": [
"import { ChartsLocalizationProvider } from '@mui/x-charts/ChartsLocalizationProvider';",
"import { ChartsLocalizationProvider } from '@mui/x-charts';",
"import { ChartsLocalizationProvider } from '@mui/x-charts-pro';"
],
"classes": [],
"spread": true,
"themeDefaultProps": null,
"muiName": "MuiChartsLocalizationProvider",
"filename": "/packages/x-charts/src/ChartsLocalizationProvider/ChartsLocalizationProvider.tsx",
"inheritance": null,
"demos": "<ul><li><a href=\"/x/react-charts/localization/\">Charts - Localization</a></li></ul>",
"cssComponent": false
}
1 change: 1 addition & 0 deletions docs/pages/x/api/charts/funnel-chart.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
}
},
"loading": { "type": { "name": "bool" }, "default": "false" },
"localeText": { "type": { "name": "object" } },
"margin": {
"type": {
"name": "union",
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/charts/heatmap.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
},
"id": { "type": { "name": "string" } },
"loading": { "type": { "name": "bool" }, "default": "false" },
"localeText": { "type": { "name": "object" } },
"margin": {
"type": {
"name": "union",
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/charts/line-chart-pro.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
}
},
"loading": { "type": { "name": "bool" }, "default": "false" },
"localeText": { "type": { "name": "object" } },
"margin": {
"type": {
"name": "union",
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/charts/line-chart.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
},
"id": { "type": { "name": "string" } },
"loading": { "type": { "name": "bool" }, "default": "false" },
"localeText": { "type": { "name": "object" } },
"margin": {
"type": {
"name": "union",
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/charts/pie-chart.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
},
"id": { "type": { "name": "string" } },
"loading": { "type": { "name": "bool" }, "default": "false" },
"localeText": { "type": { "name": "object" } },
"margin": {
"type": {
"name": "union",
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/charts/radar-chart.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
},
"id": { "type": { "name": "string" } },
"loading": { "type": { "name": "bool" }, "default": "false" },
"localeText": { "type": { "name": "object" } },
"margin": {
"type": {
"name": "union",
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/charts/radar-data-provider.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
}
},
"id": { "type": { "name": "string" } },
"localeText": { "type": { "name": "object" } },
"margin": {
"type": {
"name": "union",
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/charts/scatter-chart-pro.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
}
},
"loading": { "type": { "name": "bool" }, "default": "false" },
"localeText": { "type": { "name": "object" } },
"margin": {
"type": {
"name": "union",
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/charts/scatter-chart.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
},
"id": { "type": { "name": "string" } },
"loading": { "type": { "name": "bool" }, "default": "false" },
"localeText": { "type": { "name": "object" } },
"margin": {
"type": {
"name": "union",
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/charts/spark-line-chart.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
}
},
"id": { "type": { "name": "string" } },
"localeText": { "type": { "name": "object" } },
"margin": {
"type": {
"name": "union",
Expand Down
7 changes: 7 additions & 0 deletions docs/pages/x/react-charts/localization.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as React from 'react';
import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs';
import * as pageProps from 'docsx/data/charts/localization/localization.md?muiMarkdown';

export default function Page() {
return <MarkdownDocs {...pageProps} disableAd />;
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
},
"layout": { "description": "The direction of the bar elements." },
"loading": { "description": "If <code>true</code>, a loading overlay is displayed." },
"localeText": { "description": "Locale for charts components texts" },
"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>."
},
Expand Down
1 change: 1 addition & 0 deletions docs/translations/api-docs/charts/bar-chart/bar-chart.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
},
"layout": { "description": "The direction of the bar elements." },
"loading": { "description": "If <code>true</code>, a loading overlay is displayed." },
"localeText": { "description": "Locale for charts components texts" },
"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>."
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"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": "Locale for charts components texts" },
"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>."
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"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": "Locale for charts components texts" },
"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>."
},
Expand Down
Loading