From 98debeb67c3e818d0c9a34a214882dd4deb71a98 Mon Sep 17 00:00:00 2001 From: Bilal Shafi Date: Tue, 7 Nov 2023 15:05:51 +0500 Subject: [PATCH 01/13] [DataGridPro] Add data source interface and basic documentation (#10543) Signed-off-by: Bilal Shafi --- .../data-grid/server-side-data/aggregation.md | 15 + docs/data/data-grid/server-side-data/index.md | 291 ++++++++++++++++++ .../server-side-data/infinite-loading.md | 15 + .../server-side-data/lazy-loading.md | 15 + .../server-side-data/row-grouping.md | 15 + .../data-grid/server-side-data/tree-data.md | 15 + docs/data/pages.ts | 33 ++ .../server-side-data/aggregation.js | 7 + .../react-data-grid/server-side-data/index.js | 7 + .../server-side-data/infinite-loading.js | 7 + .../server-side-data/lazy-loading.js | 7 + .../server-side-data/row-grouping.js | 7 + .../server-side-data/tree-data.js | 7 + .../x-data-grid-pro/src/models/dataSource.ts | 72 +++++ 14 files changed, 513 insertions(+) create mode 100644 docs/data/data-grid/server-side-data/aggregation.md create mode 100644 docs/data/data-grid/server-side-data/index.md create mode 100644 docs/data/data-grid/server-side-data/infinite-loading.md create mode 100644 docs/data/data-grid/server-side-data/lazy-loading.md create mode 100644 docs/data/data-grid/server-side-data/row-grouping.md create mode 100644 docs/data/data-grid/server-side-data/tree-data.md create mode 100644 docs/pages/x/react-data-grid/server-side-data/aggregation.js create mode 100644 docs/pages/x/react-data-grid/server-side-data/index.js create mode 100644 docs/pages/x/react-data-grid/server-side-data/infinite-loading.js create mode 100644 docs/pages/x/react-data-grid/server-side-data/lazy-loading.js create mode 100644 docs/pages/x/react-data-grid/server-side-data/row-grouping.js create mode 100644 docs/pages/x/react-data-grid/server-side-data/tree-data.js create mode 100644 packages/grid/x-data-grid-pro/src/models/dataSource.ts diff --git a/docs/data/data-grid/server-side-data/aggregation.md b/docs/data/data-grid/server-side-data/aggregation.md new file mode 100644 index 0000000000000..3836a25e9ed5a --- /dev/null +++ b/docs/data/data-grid/server-side-data/aggregation.md @@ -0,0 +1,15 @@ +--- +title: React Server-side row grouping +--- + +# Data Grid - Server-side aggregation 🚧 + +

Aggregation with server side data source.

+ +:::warning +This feature isn't implemented yet. It's coming. + +👍 Upvote [issue #10860](https://github.com/mui/mui-x/issues/10860) if you want to see it land faster. + +Don't hesitate to leave a comment on the same issue to influence what gets built. Especially if you already have a use case for this component, or if you are facing a pain point with your current solution. +::: diff --git a/docs/data/data-grid/server-side-data/index.md b/docs/data/data-grid/server-side-data/index.md new file mode 100644 index 0000000000000..f235a05581833 --- /dev/null +++ b/docs/data/data-grid/server-side-data/index.md @@ -0,0 +1,291 @@ +--- +title: React Data Grid - Server-side data +--- + +# Data Grid - Server-side data + +

The data grid server-side data

+ +## Overview + +Managing server-side data efficiently in a React application can become complex as the dataset grows. + +Without a dedicated module that abstracts its complexities, developers often face challenges related to manual data fetching, pagination, sorting, and filtering, and it often gets trickier to tackle performance issues, which can lead to a poor user experience. + +Have a look at an example: + +### Example scenario + +Imagine having a data grid that displays a list of users. The data grid has pagination enabled and the user can sort the data by clicking on the column headers and also apply filters. + +The data grid is configured to fetch data from the server whenever the user changes the page or updates filtering or sorting. + +```tsx +const [rows, setRows] = React.useState([]); +const [paginationModel, setPaginationModel] = React.useState({ + page: 0, + pageSize: 10, +}); +const [filterModel, setFilterModel] = React.useState({ + items: [], +}); +const [sortModel, setSortModel] = React.useState([]); + +React.useEffect(() => { + const fetcher = async () => { + // fetch data from server + const data = await fetch('https://my-api.com/data', { + method: 'GET', + body: JSON.stringify({ + page: paginationModel.page, + pageSize: paginationModel.pageSize, + sortModel, + filterModel, + }), + }); + setRows(data.rows); + }; + fetcher(); +}, [paginationModel, sortModel, filterModel]); + +; +``` + +This example only scratches the surface with a lot of problems still unsolved like: + +- Performance optimization +- Caching data/deduping requests +- More complex use-cases on the server like grouping, tree data, etc. +- Server side row editing +- Lazy loading of data +- Handling updates to the data like row editing, row deletion, etc. +- Refetching data on-demand + +Trying to solve these problems one after the other can make the code complex and hard to maintain. + +## Data source + +A very common pattern to solve these problems is to use a centralized data source. A data source is an abstraction layer that sits between the data grid and the server. It provides a simple interface to the data grid to fetch data and update it. It handles a lot of the complexities related to server-side data fetching. Let's delve a bit deeper into how it will look like. + +:::warning + +This feature is still under development and the information shared on this page is subject to change. Feel free to subscribe or comment on the official GitHub [issue](https://github.com/mui/mui-x/issues/8179). + +::: + +### Overview + +The Data Grid already supports manual server-side data fetching for features like sorting, filtering, etc. In order to make it more powerful and simple to use, the grid will support a data source interface that you can implement with your existing data fetching logic. + +The datasource will work with all the major data grid features which require server-side data fetching such as sorting, filtering, pagination, grouping, etc. + +### Usage + +The data grid server-side data source has an initial set of required methods that you need to implement. The data grid will call these methods internally when the data is required for a specific page. + +```tsx +interface DataSource { + /** + Fetcher Functions: + - `getRows` is required + - `updateRow` is optional + + `getRows` will be used by the grid to fetch data for the current page or children for the current parent group + It may return a `rowCount` to update the total count of rows in the grid + */ + getRows(params: GetRowsParams): Promise; + updateRow?(updatedRow: GridRowModel): Promise; +} +``` + +Here's how the code will look like for the above example when implemented with data source: + +```tsx +const customDataSource: DataSource = { + getRows: async (params: GetRowsParams): GetRowsResponse => { + // fetch data from server + const response = await fetch('https://my-api.com/data', { + method: 'GET', + body: JSON.stringify(params), + }); + const data = await response.json(); + // return the data and the total number of rows + return { + rows: data.rows, + rowCount: data.totalCount, + }; + }, +} + + +``` + +Not only the code has been reduced significantly, it has removed the hassle of managing controlled states and data fetching logic too. + +On top of that, the data source will also handle a lot of other aspects like caching and deduping of requests. + +#### Loading data + +The method `dataSource.getRows` will be called with the `GetRowsParams` object whenever some data from the server is needed. This object contains all the information that you need to fetch the data from the server. + +Since previously, the data grid did not support internal data fetching, the `rows` prop was the way to pass the data to the grid. However, with server-side data, the `rows` prop is no longer needed. Instead, the data grid will call the `getRows` method whenever it needs to fetch data. + +Here's the `GetRowsParams` object for reference: + +```tsx +interface GetRowsParams { + sortModel: GridSortModel; + filterModel: GridFilterModel; + /** + * Alternate to `start` and `end`, maps to `GridPaginationModel` interface + */ + paginationModel: GridPaginationModel; + /** + * First row index to fetch (number) or cursor information (number | string) + */ + start: number | string; // first row index to fetch or cursor information + /** + * Last row index to fetch + */ + end: number; // last row index to fetch + /** + * Array of keys returned by `getGroupKey` of all the parent rows until the row for which the data is requested + * `getGroupKey` prop must be implemented to use this + * Useful for `treeData` and `rowGrouping` only + */ + groupKeys: string[]; + /** + * List of grouped columns (only applicable with `rowGrouping`) + */ + groupFields: GridColDef['field'][]; // list of grouped columns (`rowGrouping`) +} +``` + +And here's the `GetRowsResponse` object for reference: + +```tsx +interface GetRowsResponse { + /** + * Subset of the rows as per the passed `GetRowsParams` + */ + rows: GridRowModel[]; + /** + * To reflect updates in total `rowCount` (optional) + * Useful when the `rowCount` is inaccurate (e.g. when filtering) or not available upfront + */ + rowCount?: number; + /** + * Additional `pageInfo` to help the grid determine if there are more rows to fetch (corner-cases) + * `hasNextPage`: When row count is unknown/inaccurate, if `truncated` is set or rowCount is not known, data will keep loading until `hasNextPage` is `false` + * `truncated`: To reflect `rowCount` is inaccurate (will trigger `x-y of many` in pagination after the count of rows fetched is greater than provided `rowCount`) + * It could be useful with: + * 1. Cursor based pagination: + * When rowCount is not known, grid will check for `hasNextPage` to determine + * if there are more rows to fetch. + * 2. Inaccurate `rowCount`: + * `truncated: true` will let the grid know that `rowCount` is estimated/truncated. + * Thus `hasNextPage` will come into play to check more rows are available to fetch after the number becomes >= provided `rowCount` + */ + pageInfo?: { + hasNextPage?: boolean; + truncated?: number; + }; +} +``` + +#### Updating data + +If provided, the method `dataSource.updateRow` will be called with the `GridRowModel` object whenever the user edits a row. This method is optional and you can skip it if you don't need to update the data on the server. It will work in a similar way as the `processRowUpdate` prop. + +#### Data Grid props + +These data grid props will work with the server-side data source: + +- `dataSource: DataSource`: the data source object that you need to implement +- `rows`: will be ignored, could be skipped when `dataSource` is provided +- `rowCount`: will be used to identify the total number of rows in the grid, if not provided, the grid will check for the _GetRowsResponse.rowCount_ value, unless the feature being used is infinite loading where no `rowCount` is available at all. + +Props related to grouped data (`treeData` and `rowGrouping`): + +- `getGroupKey(row: GridRowModel): string` + + will be used by the grid to group rows by their parent group + This effectively replaces `getTreeDataPath`. + Consider this structure: + + ```js + - (1) Sarah // groupKey 'Sarah' + - (2) Thomas // groupKey 'Thomas' + ``` + + When (2) is expanded, the `getRows` function will be called with group keys `['Sarah', 'Thomas']`. + +- `hasChildren?(row: GridRowModel): boolean` + + Will be used by the grid to determine if a row has children on server + +- `getChildrenCount?: (row: GridRowModel) => number` + + Will be used by the grid to determine the number of children of a row on server + +#### Existing server-side features + +The server-side data source will change a bit the way existing server-side features like `filtering`, `sorting`, and `pagination` work. + +**Without data source**: +When there's no data source, the features `filtering`, `sorting`, `pagination` will work on `client` by default. In order for them to work with server-side data, you need to set them to `server` explicitly and listen to the [`onFilterModelChange`](https://mui.com/x/react-data-grid/filtering/server-side/), [`onSortModelChange`](https://mui.com/x/react-data-grid/sorting/#server-side-sorting), [`onPaginationModelChange`](https://mui.com/x/react-data-grid/pagination/#server-side-pagination) events to fetch the data from the server based on the updated variables. + +```tsx + { + // fetch data from server + }} + onSortModelChange={(newSortModel) => { + // fetch data from server + }} + onFilterModelChange={(newFilterModel) => { + // fetch data from server + }} +/> +``` + +**With data source**: +However, with a valid data source passed the features `filtering`, `sorting`, `pagination` will automatically be set to `server`. + +You just need to implement the `getRows` method and the data grid will call the `getRows` method with the proper params whenever it needs data. + +```tsx + +``` + +#### Caching + +The data grid will cache the data it receives from the server. This means that if the user navigates to a page that has already been fetched, the grid will not call the `getRows` function again. This is to avoid unnecessary calls to the server. + +## API + +- [DataGrid](/x/api/data-grid/data-grid/) +- [DataGridPro](/x/api/data-grid/data-grid-pro/) +- [DataGridPremium](/x/api/data-grid/data-grid-premium/) diff --git a/docs/data/data-grid/server-side-data/infinite-loading.md b/docs/data/data-grid/server-side-data/infinite-loading.md new file mode 100644 index 0000000000000..6c2533f51fad1 --- /dev/null +++ b/docs/data/data-grid/server-side-data/infinite-loading.md @@ -0,0 +1,15 @@ +--- +title: React Server-side infinite loading +--- + +# Data Grid - Server-side infinite loading 🚧 + +

Row infinite loading with server side data source.

+ +:::warning +This feature isn't implemented yet. It's coming. + +👍 Upvote [issue #10858](https://github.com/mui/mui-x/issues/10858) if you want to see it land faster. + +Don't hesitate to leave a comment on the same issue to influence what gets built. Especially if you already have a use case for this component, or if you are facing a pain point with the [current solution](https://mui.com/x/react-data-grid/row-updates/#infinite-loading). +::: diff --git a/docs/data/data-grid/server-side-data/lazy-loading.md b/docs/data/data-grid/server-side-data/lazy-loading.md new file mode 100644 index 0000000000000..a8430737d67d9 --- /dev/null +++ b/docs/data/data-grid/server-side-data/lazy-loading.md @@ -0,0 +1,15 @@ +--- +title: React Server-side lazy loading +--- + +# Data Grid - Server-side lazy loading 🚧 + +

Row lazy-loading with server side data source.

+ +:::warning +This feature isn't implemented yet. It's coming. + +👍 Upvote [issue #10857](https://github.com/mui/mui-x/issues/10857) if you want to see it land faster. + +Don't hesitate to leave a comment on the same issue to influence what gets built. Especially if you already have a use case for this component, or if you are facing a pain point with the [current solution](https://mui.com/x/react-data-grid/row-updates/#lazy-loading). +::: diff --git a/docs/data/data-grid/server-side-data/row-grouping.md b/docs/data/data-grid/server-side-data/row-grouping.md new file mode 100644 index 0000000000000..72fd21756bc29 --- /dev/null +++ b/docs/data/data-grid/server-side-data/row-grouping.md @@ -0,0 +1,15 @@ +--- +title: React Server-side row grouping +--- + +# Data Grid - Server-side row grouping 🚧 + +

Lazy-loaded row grouping with server side data source.

+ +:::warning +This feature isn't implemented yet. It's coming. + +👍 Upvote [issue #10859](https://github.com/mui/mui-x/issues/10859) if you want to see it land faster. + +Don't hesitate to leave a comment on the same issue to influence what gets built. Especially if you already have a use case for this component, or if you are facing a pain point with your current solution. +::: diff --git a/docs/data/data-grid/server-side-data/tree-data.md b/docs/data/data-grid/server-side-data/tree-data.md new file mode 100644 index 0000000000000..ed69e9ac25d30 --- /dev/null +++ b/docs/data/data-grid/server-side-data/tree-data.md @@ -0,0 +1,15 @@ +--- +title: React Server-side tree data +--- + +# Data Grid - Server-side tree data 🚧 + +

Tree data lazy-loading with server side data source.

+ +:::warning +This feature isn't implemented yet. It's coming. + +👍 Upvote [issue #3377](https://github.com/mui/mui-x/issues/3377) if you want to see it land faster. + +Don't hesitate to leave a comment on the same issue to influence what gets built. Especially if you already have a use case for this component, or if you are facing a pain point with the [currently proposed workaround](https://mui.com/x/react-data-grid/tree-data/#children-lazy-loading). +::: diff --git a/docs/data/pages.ts b/docs/data/pages.ts index e7243b2f94308..3b071b6cd446a 100644 --- a/docs/data/pages.ts +++ b/docs/data/pages.ts @@ -112,6 +112,39 @@ const pages: MuiPage[] = [ { pathname: '/x/react-data-grid/pivoting', title: 'Pivoting 🚧', plan: 'premium' }, ], }, + { + pathname: '/x/react-data-grid/server-side-data-group', + title: 'Server-side data 🚧', + plan: 'pro', + children: [ + { pathname: '/x/react-data-grid/server-side-data', title: 'Overview' }, + { + pathname: '/x/react-data-grid/server-side-data/lazy-loading', + title: 'Lazy loading 🚧', + plan: 'pro', + }, + { + pathname: '/x/react-data-grid/server-side-data/infinite-loading', + title: 'Infinite loading 🚧', + plan: 'pro', + }, + { + pathname: '/x/react-data-grid/server-side-data/tree-data', + title: 'Tree data 🚧', + plan: 'pro', + }, + { + pathname: '/x/react-data-grid/server-side-data/row-grouping', + title: 'Row grouping 🚧', + plan: 'pro', + }, + { + pathname: '/x/react-data-grid/server-side-data/aggregation', + title: 'Aggregation 🚧', + plan: 'premium', + }, + ], + }, { title: 'Advanced', pathname: '/x/react-data-grid/advanced', diff --git a/docs/pages/x/react-data-grid/server-side-data/aggregation.js b/docs/pages/x/react-data-grid/server-side-data/aggregation.js new file mode 100644 index 0000000000000..35594f6fa6413 --- /dev/null +++ b/docs/pages/x/react-data-grid/server-side-data/aggregation.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docsx/data/data-grid/server-side-data/aggregation.md?@mui/markdown'; + +export default function Page() { + return ; +} diff --git a/docs/pages/x/react-data-grid/server-side-data/index.js b/docs/pages/x/react-data-grid/server-side-data/index.js new file mode 100644 index 0000000000000..8d183d6d499c0 --- /dev/null +++ b/docs/pages/x/react-data-grid/server-side-data/index.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docsx/data/data-grid/server-side-data/index.md?@mui/markdown'; + +export default function Page() { + return ; +} diff --git a/docs/pages/x/react-data-grid/server-side-data/infinite-loading.js b/docs/pages/x/react-data-grid/server-side-data/infinite-loading.js new file mode 100644 index 0000000000000..9b9c08c05e85f --- /dev/null +++ b/docs/pages/x/react-data-grid/server-side-data/infinite-loading.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docsx/data/data-grid/server-side-data/infinite-loading.md?@mui/markdown'; + +export default function Page() { + return ; +} diff --git a/docs/pages/x/react-data-grid/server-side-data/lazy-loading.js b/docs/pages/x/react-data-grid/server-side-data/lazy-loading.js new file mode 100644 index 0000000000000..f0b78beb6cac3 --- /dev/null +++ b/docs/pages/x/react-data-grid/server-side-data/lazy-loading.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docsx/data/data-grid/server-side-data/lazy-loading.md?@mui/markdown'; + +export default function Page() { + return ; +} diff --git a/docs/pages/x/react-data-grid/server-side-data/row-grouping.js b/docs/pages/x/react-data-grid/server-side-data/row-grouping.js new file mode 100644 index 0000000000000..06017357e71e6 --- /dev/null +++ b/docs/pages/x/react-data-grid/server-side-data/row-grouping.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docsx/data/data-grid/server-side-data/row-grouping.md?@mui/markdown'; + +export default function Page() { + return ; +} diff --git a/docs/pages/x/react-data-grid/server-side-data/tree-data.js b/docs/pages/x/react-data-grid/server-side-data/tree-data.js new file mode 100644 index 0000000000000..6d122e9e139f9 --- /dev/null +++ b/docs/pages/x/react-data-grid/server-side-data/tree-data.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docsx/data/data-grid/server-side-data/tree-data.md?@mui/markdown'; + +export default function Page() { + return ; +} diff --git a/packages/grid/x-data-grid-pro/src/models/dataSource.ts b/packages/grid/x-data-grid-pro/src/models/dataSource.ts new file mode 100644 index 0000000000000..e6dc9236529e9 --- /dev/null +++ b/packages/grid/x-data-grid-pro/src/models/dataSource.ts @@ -0,0 +1,72 @@ +import { + GridSortModel, + GridFilterModel, + GridColDef, + GridRowModel, + GridPaginationModel, +} from '@mui/x-data-grid'; + +interface GetRowsParams { + sortModel: GridSortModel; + filterModel: GridFilterModel; + /** + * Alternate to `start` and `end`, maps to `GridPaginationModel` interface + */ + paginationModel: GridPaginationModel; + /** + * First row index to fetch (number) or cursor information (number | string) + */ + start: number | string; // first row index to fetch or cursor information + /** + * Last row index to fetch + */ + end: number; // last row index to fetch + /** + * Array of keys returned by `getGroupKey` of all the parent rows until the row for which the data is requested + * `getGroupKey` prop must be implemented to use this + * Useful for `treeData` and `rowGrouping` only + */ + groupKeys: string[]; + /** + * List of grouped columns (only applicable with `rowGrouping`) + */ + groupFields: GridColDef['field'][]; // list of grouped columns (`rowGrouping`) +} + +interface GetRowsResponse { + rows: GridRowModel[]; + /** + * To reflect updates in total `rowCount` (optional) + * Useful when the `rowCount` is inaccurate (e.g. when filtering) or not available upfront + */ + rowCount?: number; + /** + * Additional `pageInfo` to help the grid determine if there are more rows to fetch (corner-cases) + * `hasNextPage`: When row count is unknown/inaccurate, if `truncated` is set or rowCount is not known, data will keep loading until `hasNextPage` is `false` + * `truncated`: To reflect `rowCount` is inaccurate (will trigger `x-y of many` in pagination after the count of rows fetched is greater than provided `rowCount`) + * It could be useful with: + * 1. Cursor based pagination: + * When rowCount is not known, grid will check for `hasNextPage` to determine + * if there are more rows to fetch. + * 2. Inaccurate `rowCount`: + * `truncated: true` will let the grid know that `rowCount` is estimated/truncated. + * Thus `hasNextPage` will come into play to check more rows are available to fetch after the number becomes >= provided `rowCount` + */ + pageInfo?: { + hasNextPage?: boolean; + truncated?: number; + }; +} + +export interface DataSource { + /** + Fetcher Functions: + - `getRows` is required + - `updateRow` is optional + + `getRows` will be used by the grid to fetch data for the current page or children for the current parent group + It may return a `rowCount` to update the total count of rows in the grid along with the optional `pageInfo` + */ + getRows(params: GetRowsParams): Promise; + updateRow?(rows: GridRowModel): Promise; +} From 35f9dd975b3a4ba866c15385bd6854af558f36c7 Mon Sep 17 00:00:00 2001 From: Rom Grk Date: Tue, 7 Nov 2023 19:11:51 -0500 Subject: [PATCH 02/13] [DataGrid] Fix undefined slot values (#10934) --- .../x-data-grid/src/internals/utils/computeSlots.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/grid/x-data-grid/src/internals/utils/computeSlots.ts b/packages/grid/x-data-grid/src/internals/utils/computeSlots.ts index 1f27d53bf0c90..6e22ff31bfcde 100644 --- a/packages/grid/x-data-grid/src/internals/utils/computeSlots.ts +++ b/packages/grid/x-data-grid/src/internals/utils/computeSlots.ts @@ -18,5 +18,14 @@ export function computeSlots({ return defaultSlots; } - return { ...defaultSlots, ...overrides }; + const result = { ...defaultSlots }; + Object.keys(overrides).forEach((key) => { + const k = key as keyof typeof overrides; + + if (overrides[k] !== undefined) { + result[k] = overrides[k] as any; + } + }); + + return result; } From 215a8200071b4a1beda1ea3fa6561515345ddbbf Mon Sep 17 00:00:00 2001 From: Michel Engelen <32863416+michelengelen@users.noreply.github.com> Date: Wed, 8 Nov 2023 11:29:43 +0100 Subject: [PATCH 03/13] [core] Adds new alpha version to version select on the docs (#10944) --- docs/pages/_app.js | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/docs/pages/_app.js b/docs/pages/_app.js index fb7f90d7d62ec..5eecdc355d223 100644 --- a/docs/pages/_app.js +++ b/docs/pages/_app.js @@ -213,6 +213,7 @@ function AppWrapper(props) { metadata: '', name: 'MUI X', versions: [ + { text: 'v7 (next)', href: `https://next.mui.com${languagePrefix}/x/introduction/` }, { text: `v${process.env.LIB_VERSION}`, current: true }, { text: 'v5', href: `https://v5.mui.com${languagePrefix}/x/introduction/` }, { text: 'v4', href: `https://v4.mui.com${languagePrefix}/components/data-grid/` }, @@ -224,6 +225,10 @@ function AppWrapper(props) { metadata: 'MUI X', name: 'Data Grid', versions: [ + { + text: 'v7 (next)', + href: `https://next.mui.com${languagePrefix}/components/data-grid/`, + }, { text: `v${process.env.DATA_GRID_VERSION}`, current: true }, { text: 'v5', href: `https://v5.mui.com${languagePrefix}/components/data-grid/` }, { text: 'v4', href: `https://v4.mui.com${languagePrefix}/components/data-grid/` }, @@ -234,6 +239,10 @@ function AppWrapper(props) { metadata: 'MUI X', name: 'Date Pickers', versions: [ + { + text: 'v7 (next)', + href: `https://next.mui.com${languagePrefix}/x/react-date-pickers/getting-started/`, + }, { text: `v${process.env.DATE_PICKERS_VERSION}`, current: true }, { text: 'v5', @@ -245,13 +254,25 @@ function AppWrapper(props) { productIdentifier = { metadata: 'MUI X', name: 'Charts', - versions: [{ text: `v${process.env.CHARTS_VERSION}`, current: true }], + versions: [ + { + text: 'v7 (next)', + href: `https://next.mui.com${languagePrefix}/x/react-charts/getting-started`, + }, + { text: `v${process.env.CHARTS_VERSION}`, current: true }, + ], }; } else if (productId === 'x-tree-view') { productIdentifier = { metadata: 'MUI X', name: 'Tree View', - versions: [{ text: `v${process.env.TREE_VIEW_VERSION}`, current: true }], + versions: [ + { + text: 'v7 (next)', + href: `https://next.mui.com${languagePrefix}/x/react-tree-view/getting-started`, + }, + { text: `v${process.env.TREE_VIEW_VERSION}`, current: true }, + ], }; } From efa968bde7ecc845192f07d78737b94706ff0a09 Mon Sep 17 00:00:00 2001 From: Maxime THOMAS Date: Wed, 8 Nov 2023 10:47:10 +0000 Subject: [PATCH 04/13] [charts] Add component (#10597) Co-authored-by: alexandre Co-authored-by: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com> Co-authored-by: Lukas --- docs/data/charts-component-api-pages.ts | 1 + docs/data/charts/axis/AxisWithComposition.js | 14 +- docs/data/charts/axis/AxisWithComposition.tsx | 14 +- docs/data/charts/axis/ReferenceLine.js | 66 +++++++++ docs/data/charts/axis/ReferenceLine.tsx | 66 +++++++++ .../charts/axis/ReferenceLine.tsx.preview | 13 ++ docs/data/charts/axis/axis.md | 11 ++ .../line-demo/LineChartWithReferenceLines.js | 43 ++++++ .../line-demo/LineChartWithReferenceLines.tsx | 43 ++++++ docs/data/charts/line-demo/line-demo.md | 4 + docs/pages/x/api/charts/bar-chart.json | 8 +- docs/pages/x/api/charts/charts-axis.json | 8 +- .../x/api/charts/charts-reference-line.js | 23 +++ .../x/api/charts/charts-reference-line.json | 42 ++++++ docs/pages/x/api/charts/charts-x-axis.json | 2 +- docs/pages/x/api/charts/charts-y-axis.json | 2 +- docs/pages/x/api/charts/line-chart.json | 8 +- docs/pages/x/api/charts/pie-chart.json | 8 +- docs/pages/x/api/charts/scatter-chart.json | 8 +- .../charts/charts-reference-line.json | 66 +++++++++ .../api-docs/charts/charts-x-axis.json | 2 +- .../api-docs/charts/charts-y-axis.json | 2 +- packages/x-charts/src/BarChart/BarChart.tsx | 8 +- packages/x-charts/src/BarChart/BarPlot.tsx | 12 +- .../x-charts/src/ChartsAxis/ChartsAxis.tsx | 10 +- .../src/ChartsLegend/ChartsLegend.tsx | 4 +- .../src/ChartsLegend/chartsLegendClasses.ts | 2 +- .../ChartsReferenceLine.tsx | 82 +++++++++++ .../ChartsXReferenceLine.tsx | 133 ++++++++++++++++++ .../ChartsYReferenceLine.tsx | 133 ++++++++++++++++++ .../chartsReferenceLineClasses.ts | 26 ++++ .../src/ChartsReferenceLine/common.tsx | 55 ++++++++ .../src/ChartsReferenceLine/index.tsx | 2 + .../x-charts/src/ChartsXAxis/ChartsXAxis.tsx | 8 +- .../x-charts/src/ChartsYAxis/ChartsYAxis.tsx | 8 +- packages/x-charts/src/LineChart/AreaPlot.tsx | 4 +- packages/x-charts/src/LineChart/LineChart.tsx | 8 +- .../src/LineChart/LineHighlightPlot.tsx | 2 +- packages/x-charts/src/LineChart/LinePlot.tsx | 2 +- packages/x-charts/src/LineChart/MarkPlot.tsx | 4 +- packages/x-charts/src/PieChart/PieChart.tsx | 8 +- .../src/ScatterChart/ScatterChart.tsx | 8 +- packages/x-charts/src/index.ts | 1 + .../x-charts/src/internals/isBandScale.ts | 6 +- packages/x-charts/src/internals/utils.ts | 3 + packages/x-charts/src/models/axis.ts | 49 ++++--- scripts/x-charts.exports.json | 5 + 47 files changed, 931 insertions(+), 106 deletions(-) create mode 100644 docs/data/charts/axis/ReferenceLine.js create mode 100644 docs/data/charts/axis/ReferenceLine.tsx create mode 100644 docs/data/charts/axis/ReferenceLine.tsx.preview create mode 100644 docs/data/charts/line-demo/LineChartWithReferenceLines.js create mode 100644 docs/data/charts/line-demo/LineChartWithReferenceLines.tsx create mode 100644 docs/pages/x/api/charts/charts-reference-line.js create mode 100644 docs/pages/x/api/charts/charts-reference-line.json create mode 100644 docs/translations/api-docs/charts/charts-reference-line.json create mode 100644 packages/x-charts/src/ChartsReferenceLine/ChartsReferenceLine.tsx create mode 100644 packages/x-charts/src/ChartsReferenceLine/ChartsXReferenceLine.tsx create mode 100644 packages/x-charts/src/ChartsReferenceLine/ChartsYReferenceLine.tsx create mode 100644 packages/x-charts/src/ChartsReferenceLine/chartsReferenceLineClasses.ts create mode 100644 packages/x-charts/src/ChartsReferenceLine/common.tsx create mode 100644 packages/x-charts/src/ChartsReferenceLine/index.tsx diff --git a/docs/data/charts-component-api-pages.ts b/docs/data/charts-component-api-pages.ts index f10b505b16bb1..8153086f99c08 100644 --- a/docs/data/charts-component-api-pages.ts +++ b/docs/data/charts-component-api-pages.ts @@ -9,6 +9,7 @@ export default [ { pathname: '/x/api/charts/charts-axis', title: 'ChartsAxis' }, { pathname: '/x/api/charts/charts-axis-highlight', title: 'ChartsAxisHighlight' }, { pathname: '/x/api/charts/charts-clip-path', title: 'ChartsClipPath' }, + { pathname: '/x/api/charts/charts-reference-line', title: 'ChartsReferenceLine' }, { pathname: '/x/api/charts/charts-tooltip', title: 'ChartsTooltip' }, { pathname: '/x/api/charts/charts-x-axis', title: 'ChartsXAxis' }, { pathname: '/x/api/charts/charts-y-axis', title: 'ChartsYAxis' }, diff --git a/docs/data/charts/axis/AxisWithComposition.js b/docs/data/charts/axis/AxisWithComposition.js index 76ccbc2a9922a..71a2a507fe90f 100644 --- a/docs/data/charts/axis/AxisWithComposition.js +++ b/docs/data/charts/axis/AxisWithComposition.js @@ -1,13 +1,11 @@ import * as React from 'react'; import Box from '@mui/material/Box'; -import { - ResponsiveChartContainer, - BarPlot, - LinePlot, - ChartsXAxis, - ChartsYAxis, - axisClasses, -} from '@mui/x-charts'; +import { ResponsiveChartContainer } from '@mui/x-charts/ResponsiveChartContainer'; +import { LinePlot } from '@mui/x-charts/LineChart'; +import { BarPlot } from '@mui/x-charts/BarChart'; +import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; +import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; +import { axisClasses } from '@mui/x-charts/ChartsAxis'; export default function AxisWithComposition() { return ( diff --git a/docs/data/charts/axis/AxisWithComposition.tsx b/docs/data/charts/axis/AxisWithComposition.tsx index 76ccbc2a9922a..71a2a507fe90f 100644 --- a/docs/data/charts/axis/AxisWithComposition.tsx +++ b/docs/data/charts/axis/AxisWithComposition.tsx @@ -1,13 +1,11 @@ import * as React from 'react'; import Box from '@mui/material/Box'; -import { - ResponsiveChartContainer, - BarPlot, - LinePlot, - ChartsXAxis, - ChartsYAxis, - axisClasses, -} from '@mui/x-charts'; +import { ResponsiveChartContainer } from '@mui/x-charts/ResponsiveChartContainer'; +import { LinePlot } from '@mui/x-charts/LineChart'; +import { BarPlot } from '@mui/x-charts/BarChart'; +import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; +import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; +import { axisClasses } from '@mui/x-charts/ChartsAxis'; export default function AxisWithComposition() { return ( diff --git a/docs/data/charts/axis/ReferenceLine.js b/docs/data/charts/axis/ReferenceLine.js new file mode 100644 index 0000000000000..844f9781c3f40 --- /dev/null +++ b/docs/data/charts/axis/ReferenceLine.js @@ -0,0 +1,66 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import { ResponsiveChartContainer } from '@mui/x-charts/ResponsiveChartContainer'; +import { LinePlot } from '@mui/x-charts/LineChart'; + +import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; +import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; +import { ChartsReferenceLine } from '@mui/x-charts/ChartsReferenceLine'; + +const timeData = [ + new Date(2023, 7, 31), + new Date(2023, 7, 31, 12), + new Date(2023, 8, 1), + new Date(2023, 8, 1, 12), + new Date(2023, 8, 2), + new Date(2023, 8, 2, 12), + new Date(2023, 8, 3), + new Date(2023, 8, 3, 12), + new Date(2023, 8, 4), +]; + +const y1 = [5, 5, 10, 90, 85, 70, 30, 25, 25]; +const y2 = [90, 85, 70, 25, 23, 40, 45, 40, 50]; + +const config = { + series: [ + { type: 'line', data: y1 }, + { type: 'line', data: y2 }, + ], + height: 400, + xAxis: [ + { + data: timeData, + scaleType: 'time', + valueFormatter: (date) => + date.getHours() === 0 + ? date.toLocaleDateString('fr-FR', { + month: '2-digit', + day: '2-digit', + }) + : date.toLocaleTimeString('fr-FR', { + hour: '2-digit', + }), + }, + ], +}; + +export default function ReferenceLine() { + return ( + + + + + + + + + + ); +} diff --git a/docs/data/charts/axis/ReferenceLine.tsx b/docs/data/charts/axis/ReferenceLine.tsx new file mode 100644 index 0000000000000..bef07764db741 --- /dev/null +++ b/docs/data/charts/axis/ReferenceLine.tsx @@ -0,0 +1,66 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import { ResponsiveChartContainer } from '@mui/x-charts/ResponsiveChartContainer'; +import { LinePlot } from '@mui/x-charts/LineChart'; +import { LineSeriesType } from '@mui/x-charts/models'; +import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; +import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; +import { ChartsReferenceLine } from '@mui/x-charts/ChartsReferenceLine'; + +const timeData = [ + new Date(2023, 7, 31), + new Date(2023, 7, 31, 12), + new Date(2023, 8, 1), + new Date(2023, 8, 1, 12), + new Date(2023, 8, 2), + new Date(2023, 8, 2, 12), + new Date(2023, 8, 3), + new Date(2023, 8, 3, 12), + new Date(2023, 8, 4), +]; + +const y1 = [5, 5, 10, 90, 85, 70, 30, 25, 25]; +const y2 = [90, 85, 70, 25, 23, 40, 45, 40, 50]; + +const config = { + series: [ + { type: 'line', data: y1 }, + { type: 'line', data: y2 }, + ] as LineSeriesType[], + height: 400, + xAxis: [ + { + data: timeData, + scaleType: 'time', + valueFormatter: (date: Date) => + date.getHours() === 0 + ? date.toLocaleDateString('fr-FR', { + month: '2-digit', + day: '2-digit', + }) + : date.toLocaleTimeString('fr-FR', { + hour: '2-digit', + }), + } as const, + ], +}; + +export default function ReferenceLine() { + return ( + + + + + + + + + + ); +} diff --git a/docs/data/charts/axis/ReferenceLine.tsx.preview b/docs/data/charts/axis/ReferenceLine.tsx.preview new file mode 100644 index 0000000000000..17c9fe4ec5d2e --- /dev/null +++ b/docs/data/charts/axis/ReferenceLine.tsx.preview @@ -0,0 +1,13 @@ + + + + + + + \ No newline at end of file diff --git a/docs/data/charts/axis/axis.md b/docs/data/charts/axis/axis.md index e0b59a21235aa..050f714cd97b1 100644 --- a/docs/data/charts/axis/axis.md +++ b/docs/data/charts/axis/axis.md @@ -170,3 +170,14 @@ You can choose their position with `position` props which accept `'top'`/`'botto Other props are similar to the ones defined in the [previous section](/x/react-charts/axis/#rendering). {{"demo": "AxisWithComposition.js"}} + +### Reference line + +The `` component add a reference line to the charts. +You can provide an `x` or `y` prop to get a vertical or horizontal line respectively at this value. + +You can add a `label` to this reference line. +It can be placed with `labelAlign` prop which accepts `'start'`, `'middle'`, and `'end'` values. +Elements can be styled with `lineStyle` and `labelStyle` props. + +{{"demo": "ReferenceLine.js"}} diff --git a/docs/data/charts/line-demo/LineChartWithReferenceLines.js b/docs/data/charts/line-demo/LineChartWithReferenceLines.js new file mode 100644 index 0000000000000..b991babc95b19 --- /dev/null +++ b/docs/data/charts/line-demo/LineChartWithReferenceLines.js @@ -0,0 +1,43 @@ +import * as React from 'react'; +import { ChartContainer } from '@mui/x-charts/ChartContainer'; +import { ChartsReferenceLine } from '@mui/x-charts'; +import { LinePlot, MarkPlot } from '@mui/x-charts/LineChart'; +import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; +import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; + +const uData = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; +const pData = [2400, 1398, 9800, 3908, 4800, 3800, 4300]; +const xLabels = [ + 'Page A', + 'Page B', + 'Page C', + 'Page D', + 'Page E', + 'Page F', + 'Page G', +]; + +export default function LineChartWithReferenceLines() { + return ( + + + + + + + + + ); +} diff --git a/docs/data/charts/line-demo/LineChartWithReferenceLines.tsx b/docs/data/charts/line-demo/LineChartWithReferenceLines.tsx new file mode 100644 index 0000000000000..b991babc95b19 --- /dev/null +++ b/docs/data/charts/line-demo/LineChartWithReferenceLines.tsx @@ -0,0 +1,43 @@ +import * as React from 'react'; +import { ChartContainer } from '@mui/x-charts/ChartContainer'; +import { ChartsReferenceLine } from '@mui/x-charts'; +import { LinePlot, MarkPlot } from '@mui/x-charts/LineChart'; +import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; +import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; + +const uData = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; +const pData = [2400, 1398, 9800, 3908, 4800, 3800, 4300]; +const xLabels = [ + 'Page A', + 'Page B', + 'Page C', + 'Page D', + 'Page E', + 'Page F', + 'Page G', +]; + +export default function LineChartWithReferenceLines() { + return ( + + + + + + + + + ); +} diff --git a/docs/data/charts/line-demo/line-demo.md b/docs/data/charts/line-demo/line-demo.md index c8b9ff2af5cc9..e79bd9d6ad06f 100644 --- a/docs/data/charts/line-demo/line-demo.md +++ b/docs/data/charts/line-demo/line-demo.md @@ -22,6 +22,10 @@ title: Charts - Line demonstration {{"demo": "BiaxialLineChart.js"}} +## LineChartWithReferenceLines + +{{"demo": "LineChartWithReferenceLines.js"}} + ## LineChartConnectNulls {{"demo": "LineChartConnectNulls.js"}} diff --git a/docs/pages/x/api/charts/bar-chart.json b/docs/pages/x/api/charts/bar-chart.json index 8bbff0857a776..ed628ca83572d 100644 --- a/docs/pages/x/api/charts/bar-chart.json +++ b/docs/pages/x/api/charts/bar-chart.json @@ -3,7 +3,7 @@ "bottomAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
| 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
| array
| func, tickLabelInterval?: 'auto'
| func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
| string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
| 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
| array
| func, tickLabelInterval?: 'auto'
| func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
| string" }, "default": "xAxisIds[0] The id of the first provided axis" }, @@ -13,14 +13,14 @@ "leftAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
| 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
| array
| func, tickLabelInterval?: 'auto'
| func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
| string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
| 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
| array
| func, tickLabelInterval?: 'auto'
| func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
| string" }, "default": "yAxisIds[0] The id of the first provided axis" }, "rightAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
| 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
| array
| func, tickLabelInterval?: 'auto'
| func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
| string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
| 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
| array
| func, tickLabelInterval?: 'auto'
| func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
| string" }, "default": "null" }, @@ -30,7 +30,7 @@ "topAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
| 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
| array
| func, tickLabelInterval?: 'auto'
| func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
| string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
| 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
| array
| func, tickLabelInterval?: 'auto'
| func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
| string" }, "default": "null" } diff --git a/docs/pages/x/api/charts/charts-axis.json b/docs/pages/x/api/charts/charts-axis.json index c198f3032049d..9845f37eb5803 100644 --- a/docs/pages/x/api/charts/charts-axis.json +++ b/docs/pages/x/api/charts/charts-axis.json @@ -3,21 +3,21 @@ "bottomAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
| 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
| array
| func, tickLabelInterval?: 'auto'
| func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
| string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
| 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
| array
| func, tickLabelInterval?: 'auto'
| func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
| string" }, "default": "xAxisIds[0] The id of the first provided axis" }, "leftAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
| 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
| array
| func, tickLabelInterval?: 'auto'
| func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
| string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
| 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
| array
| func, tickLabelInterval?: 'auto'
| func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
| string" }, "default": "yAxisIds[0] The id of the first provided axis" }, "rightAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
| 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
| array
| func, tickLabelInterval?: 'auto'
| func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
| string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
| 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
| array
| func, tickLabelInterval?: 'auto'
| func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
| string" }, "default": "null" }, @@ -26,7 +26,7 @@ "topAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
| 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
| array
| func, tickLabelInterval?: 'auto'
| func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
| string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
| 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
| array
| func, tickLabelInterval?: 'auto'
| func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
| string" }, "default": "null" } diff --git a/docs/pages/x/api/charts/charts-reference-line.js b/docs/pages/x/api/charts/charts-reference-line.js new file mode 100644 index 0000000000000..d4424ba41e0cb --- /dev/null +++ b/docs/pages/x/api/charts/charts-reference-line.js @@ -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-reference-line.json'; + +export default function Page(props) { + const { descriptions, pageContent } = props; + return ; +} + +Page.getInitialProps = () => { + const req = require.context( + 'docsx/translations/api-docs/charts', + false, + /\.\/charts-reference-line(-[a-z]{2})?\.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/x/api/charts/charts-reference-line.json b/docs/pages/x/api/charts/charts-reference-line.json new file mode 100644 index 0000000000000..36045f6f118ce --- /dev/null +++ b/docs/pages/x/api/charts/charts-reference-line.json @@ -0,0 +1,42 @@ +{ + "props": { + "axisId": { "type": { "name": "string" }, "default": "The `id` of the first defined axis." }, + "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, + "label": { "type": { "name": "string" } }, + "labelAlign": { + "type": { + "name": "enum", + "description": "'end'
| 'middle'
| 'start'" + }, + "default": "'middle'" + }, + "labelStyle": { "type": { "name": "object" } }, + "lineStyle": { "type": { "name": "object" } }, + "spacing": { + "type": { + "name": "union", + "description": "number
| { x?: number, y?: number }" + }, + "default": "5" + }, + "x": { + "type": { "name": "union", "description": "Date
| number
| string" } + }, + "y": { + "type": { "name": "union", "description": "Date
| number
| string" } + } + }, + "slots": [], + "name": "ChartsReferenceLine", + "imports": [ + "import { ChartsReferenceLine } from '@mui/x-charts/ChartsReferenceLine';", + "import { ChartsReferenceLine } from '@mui/x-charts';" + ], + "styles": { + "classes": ["root", "vertical", "horizontal", "line", "label"], + "globalClasses": {}, + "name": "MuiChartsReferenceLine" + }, + "filename": "/packages/x-charts/src/ChartsReferenceLine/ChartsReferenceLine.tsx", + "demos": "
    " +} diff --git a/docs/pages/x/api/charts/charts-x-axis.json b/docs/pages/x/api/charts/charts-x-axis.json index 9580898464ea8..3464148ac316f 100644 --- a/docs/pages/x/api/charts/charts-x-axis.json +++ b/docs/pages/x/api/charts/charts-x-axis.json @@ -1,6 +1,6 @@ { "props": { - "axisId": { "type": { "name": "string" }, "required": true }, + "axisId": { "type": { "name": "string" } }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, "disableLine": { "type": { "name": "bool" } }, "disableTicks": { "type": { "name": "bool" } }, diff --git a/docs/pages/x/api/charts/charts-y-axis.json b/docs/pages/x/api/charts/charts-y-axis.json index 24b012f47388b..f0e7874c67c86 100644 --- a/docs/pages/x/api/charts/charts-y-axis.json +++ b/docs/pages/x/api/charts/charts-y-axis.json @@ -1,6 +1,6 @@ { "props": { - "axisId": { "type": { "name": "string" }, "required": true }, + "axisId": { "type": { "name": "string" } }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, "disableLine": { "type": { "name": "bool" } }, "disableTicks": { "type": { "name": "bool" } }, diff --git a/docs/pages/x/api/charts/line-chart.json b/docs/pages/x/api/charts/line-chart.json index 58f9a9f375d6a..ad4f61d5517db 100644 --- a/docs/pages/x/api/charts/line-chart.json +++ b/docs/pages/x/api/charts/line-chart.json @@ -3,7 +3,7 @@ "bottomAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
    | 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
    | 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" }, "default": "xAxisIds[0] The id of the first provided axis" }, @@ -14,14 +14,14 @@ "leftAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
    | 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
    | 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" }, "default": "yAxisIds[0] The id of the first provided axis" }, "rightAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
    | 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
    | 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" }, "default": "null" }, @@ -30,7 +30,7 @@ "topAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
    | 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
    | 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" }, "default": "null" } diff --git a/docs/pages/x/api/charts/pie-chart.json b/docs/pages/x/api/charts/pie-chart.json index 89b1b13028991..87a086c5b7a05 100644 --- a/docs/pages/x/api/charts/pie-chart.json +++ b/docs/pages/x/api/charts/pie-chart.json @@ -3,7 +3,7 @@ "bottomAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
    | 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
    | 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" }, "default": "xAxisIds[0] The id of the first provided axis" }, @@ -13,14 +13,14 @@ "leftAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
    | 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
    | 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" }, "default": "yAxisIds[0] The id of the first provided axis" }, "rightAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
    | 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
    | 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" }, "default": "null" }, @@ -29,7 +29,7 @@ "topAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
    | 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
    | 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" }, "default": "null" } diff --git a/docs/pages/x/api/charts/scatter-chart.json b/docs/pages/x/api/charts/scatter-chart.json index c6f231f5a69b7..ed264b3492317 100644 --- a/docs/pages/x/api/charts/scatter-chart.json +++ b/docs/pages/x/api/charts/scatter-chart.json @@ -3,7 +3,7 @@ "bottomAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
    | 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
    | 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" }, "default": "xAxisIds[0] The id of the first provided axis" }, @@ -13,14 +13,14 @@ "leftAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
    | 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
    | 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" }, "default": "yAxisIds[0] The id of the first provided axis" }, "rightAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
    | 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'left'
    | 'right', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" }, "default": "null" }, @@ -29,7 +29,7 @@ "topAxis": { "type": { "name": "union", - "description": "{ axisId: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
    | 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" + "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
    | 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" }, "default": "null" } diff --git a/docs/translations/api-docs/charts/charts-reference-line.json b/docs/translations/api-docs/charts/charts-reference-line.json new file mode 100644 index 0000000000000..dc186914dfa34 --- /dev/null +++ b/docs/translations/api-docs/charts/charts-reference-line.json @@ -0,0 +1,66 @@ +{ + "componentDescription": "", + "propDescriptions": { + "axisId": { + "description": "The id of the axis used for the reference value.", + "deprecated": "", + "typeDescriptions": {} + }, + "classes": { + "description": "Override or extend the styles applied to the component.", + "deprecated": "", + "typeDescriptions": {} + }, + "label": { + "description": "The label to display along the reference line.", + "deprecated": "", + "typeDescriptions": {} + }, + "labelAlign": { + "description": "The alignment if the label is in the chart drawing area.", + "deprecated": "", + "typeDescriptions": {} + }, + "labelStyle": { + "description": "The style applied to the label.", + "deprecated": "", + "typeDescriptions": {} + }, + "lineStyle": { + "description": "The style applied to the line.", + "deprecated": "", + "typeDescriptions": {} + }, + "spacing": { + "description": "Additional space arround the label in px. Can be a number or an object { x, y } to distinguish space with the reference line and space with axes.", + "deprecated": "", + "typeDescriptions": {} + }, + "x": { + "description": "The x value associated with the reference line. If defined the reference line will be vertical.", + "deprecated": "", + "typeDescriptions": {} + }, + "y": { + "description": "The y value associated with the reference line. If defined the reference line will be horizontal.", + "deprecated": "", + "typeDescriptions": {} + } + }, + "classDescriptions": { + "root": { "description": "Styles applied to the root element." }, + "vertical": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "the reference line is vertical" + }, + "horizontal": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "the reference line is horizontal" + }, + "line": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the reference line" }, + "label": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the reference label" } + }, + "slotDescriptions": {} +} diff --git a/docs/translations/api-docs/charts/charts-x-axis.json b/docs/translations/api-docs/charts/charts-x-axis.json index d7bff24d1bb96..1d470313d7f1d 100644 --- a/docs/translations/api-docs/charts/charts-x-axis.json +++ b/docs/translations/api-docs/charts/charts-x-axis.json @@ -2,7 +2,7 @@ "componentDescription": "", "propDescriptions": { "axisId": { - "description": "Id of the axis to render.", + "description": "The id of the axis to render. If undefined, it will be the first defined axis.", "deprecated": "", "typeDescriptions": {} }, diff --git a/docs/translations/api-docs/charts/charts-y-axis.json b/docs/translations/api-docs/charts/charts-y-axis.json index d7bff24d1bb96..1d470313d7f1d 100644 --- a/docs/translations/api-docs/charts/charts-y-axis.json +++ b/docs/translations/api-docs/charts/charts-y-axis.json @@ -2,7 +2,7 @@ "componentDescription": "", "propDescriptions": { "axisId": { - "description": "Id of the axis to render.", + "description": "The id of the axis to render. If undefined, it will be the first defined axis.", "deprecated": "", "typeDescriptions": {} }, diff --git a/packages/x-charts/src/BarChart/BarChart.tsx b/packages/x-charts/src/BarChart/BarChart.tsx index eefa36e2167e1..f489fa3d49ff7 100644 --- a/packages/x-charts/src/BarChart/BarChart.tsx +++ b/packages/x-charts/src/BarChart/BarChart.tsx @@ -178,7 +178,7 @@ BarChart.propTypes = { */ bottomAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, @@ -223,7 +223,7 @@ BarChart.propTypes = { */ leftAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, @@ -277,7 +277,7 @@ BarChart.propTypes = { */ rightAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, @@ -368,7 +368,7 @@ BarChart.propTypes = { */ topAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, diff --git a/packages/x-charts/src/BarChart/BarPlot.tsx b/packages/x-charts/src/BarChart/BarPlot.tsx index b1c89ee87c532..e5e94c3d88580 100644 --- a/packages/x-charts/src/BarChart/BarPlot.tsx +++ b/packages/x-charts/src/BarChart/BarPlot.tsx @@ -143,12 +143,12 @@ const useCompletedData = (): CompletedBarData[] => { layout: series[seriesId].layout, x: verticalLayout ? xScale(xAxis[xAxisKey].data?.[dataIndex])! + barOffset - : xScale(bottom), - y: verticalLayout ? yScale(top) : yScale(yAxis[yAxisKey].data?.[dataIndex])! + barOffset, - xOrigin: xScale(0), - yOrigin: yScale(0), - height: verticalLayout ? Math.abs(yScale(bottom) - yScale(top)) : barWidth, - width: verticalLayout ? barWidth : Math.abs(xScale(bottom) - xScale(top)), + : xScale(bottom)!, + y: verticalLayout ? yScale(top)! : yScale(yAxis[yAxisKey].data?.[dataIndex])! + barOffset, + xOrigin: xScale(0)!, + yOrigin: yScale(0)!, + height: verticalLayout ? Math.abs(yScale(bottom)! - yScale(top)!) : barWidth, + width: verticalLayout ? barWidth : Math.abs(xScale(bottom)! - xScale(top)!), color, highlightScope: series[seriesId].highlightScope, }; diff --git a/packages/x-charts/src/ChartsAxis/ChartsAxis.tsx b/packages/x-charts/src/ChartsAxis/ChartsAxis.tsx index 4dff59527bd99..40551a6f7ebdd 100644 --- a/packages/x-charts/src/ChartsAxis/ChartsAxis.tsx +++ b/packages/x-charts/src/ChartsAxis/ChartsAxis.tsx @@ -55,7 +55,7 @@ const getAxisId = ( return null; } if (typeof propsValue === 'object') { - return propsValue.axisId; + return propsValue.axisId ?? null; } return propsValue; }; @@ -134,7 +134,7 @@ ChartsAxis.propTypes = { */ bottomAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, @@ -168,7 +168,7 @@ ChartsAxis.propTypes = { */ leftAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, @@ -202,7 +202,7 @@ ChartsAxis.propTypes = { */ rightAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, @@ -246,7 +246,7 @@ ChartsAxis.propTypes = { */ topAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, diff --git a/packages/x-charts/src/ChartsLegend/ChartsLegend.tsx b/packages/x-charts/src/ChartsLegend/ChartsLegend.tsx index 1f773fbb903f1..ef0e1b0624996 100644 --- a/packages/x-charts/src/ChartsLegend/ChartsLegend.tsx +++ b/packages/x-charts/src/ChartsLegend/ChartsLegend.tsx @@ -6,7 +6,7 @@ import { useThemeProps, useTheme, Theme, styled } from '@mui/material/styles'; import { DrawingArea, DrawingContext } from '../context/DrawingProvider'; import { AnchorPosition, Direction, getSeriesToDisplay } from './utils'; import { FormattedSeries, SeriesContext } from '../context/SeriesContextProvider'; -import { ChartsLegendClasses, getChartsLegendUtilityClass } from './chartsLegendClasses'; +import { ChartsLegendClasses, getLegendUtilityClass } from './chartsLegendClasses'; import { DefaultizedProps } from '../models/helpers'; import { LegendParams } from '../models/seriesType/config'; import { ChartsText, ChartsTextStyle, getWordsByLines } from '../internals/components/ChartsText'; @@ -58,7 +58,7 @@ const useUtilityClasses = (ownerState: DefaultizedChartsLegendProps & { theme: T series: ['series'], }; - return composeClasses(slots, getChartsLegendUtilityClass, classes); + return composeClasses(slots, getLegendUtilityClass, classes); }; export type ChartsLegendRootOwnerState = { diff --git a/packages/x-charts/src/ChartsLegend/chartsLegendClasses.ts b/packages/x-charts/src/ChartsLegend/chartsLegendClasses.ts index cebe5a885a229..5d710e5540569 100644 --- a/packages/x-charts/src/ChartsLegend/chartsLegendClasses.ts +++ b/packages/x-charts/src/ChartsLegend/chartsLegendClasses.ts @@ -20,7 +20,7 @@ export interface ChartsLegendClasses { export type ChartsLegendClassKey = keyof ChartsLegendClasses; -export function getChartsLegendUtilityClass(slot: string) { +export function getLegendUtilityClass(slot: string) { return generateUtilityClass('MuiChartsLegend', slot); } diff --git a/packages/x-charts/src/ChartsReferenceLine/ChartsReferenceLine.tsx b/packages/x-charts/src/ChartsReferenceLine/ChartsReferenceLine.tsx new file mode 100644 index 0000000000000..a8c9f1a6c0694 --- /dev/null +++ b/packages/x-charts/src/ChartsReferenceLine/ChartsReferenceLine.tsx @@ -0,0 +1,82 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import { ChartsXReferenceLine, ChartsXReferenceLineProps } from './ChartsXReferenceLine'; +import { ChartsYReferenceLine, ChartsYReferenceLineProps } from './ChartsYReferenceLine'; +import { XOR } from '../internals/utils'; + +type ChartsReferenceLineProps = XOR< + ChartsXReferenceLineProps, + ChartsYReferenceLineProps +>; + +function ChartsReferenceLine(props: ChartsReferenceLineProps) { + if (props.x !== undefined && props.y !== undefined) { + throw new Error('MUI-X: The ChartsReferenceLine can not have both `x` and `y` props set.'); + } + + if (props.x === undefined && props.y === undefined) { + throw new Error('MUI-X: The ChartsReferenceLine should have a value in `x` or `y` prop.'); + } + + if (props.x !== undefined) { + return ; + } + return ; +} + +ChartsReferenceLine.propTypes = { + // ----------------------------- Warning -------------------------------- + // | These PropTypes are generated from the TypeScript type definitions | + // | To update them edit the TypeScript types and run "yarn proptypes" | + // ---------------------------------------------------------------------- + /** + * The id of the axis used for the reference value. + * @default The `id` of the first defined axis. + */ + axisId: PropTypes.string, + /** + * Override or extend the styles applied to the component. + */ + classes: PropTypes.object, + /** + * The label to display along the reference line. + */ + label: PropTypes.string, + /** + * The alignment if the label is in the chart drawing area. + * @default 'middle' + */ + labelAlign: PropTypes.oneOf(['end', 'middle', 'start']), + /** + * The style applied to the label. + */ + labelStyle: PropTypes.object, + /** + * The style applied to the line. + */ + lineStyle: PropTypes.object, + /** + * Additional space arround the label in px. + * Can be a number or an object `{ x, y }` to distinguish space with the reference line and space with axes. + * @default 5 + */ + spacing: PropTypes.oneOfType([ + PropTypes.number, + PropTypes.shape({ + x: PropTypes.number, + y: PropTypes.number, + }), + ]), + /** + * The x value associated with the reference line. + * If defined the reference line will be vertical. + */ + x: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.number, PropTypes.string]), + /** + * The y value associated with the reference line. + * If defined the reference line will be horizontal. + */ + y: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.number, PropTypes.string]), +} as any; + +export { ChartsReferenceLine }; diff --git a/packages/x-charts/src/ChartsReferenceLine/ChartsXReferenceLine.tsx b/packages/x-charts/src/ChartsReferenceLine/ChartsXReferenceLine.tsx new file mode 100644 index 0000000000000..1cb83fa8fbe81 --- /dev/null +++ b/packages/x-charts/src/ChartsReferenceLine/ChartsXReferenceLine.tsx @@ -0,0 +1,133 @@ +import * as React from 'react'; +import composeClasses from '@mui/utils/composeClasses'; +import { useDrawingArea, useXScale } from '../hooks'; +import { CommonChartsReferenceLineProps, ReferenceLineRoot } from './common'; +import { ChartsText } from '../internals/components/ChartsText'; +import { + ChartsReferenceLineClasses, + getReferenceLineUtilityClass, +} from './chartsReferenceLineClasses'; + +export type ChartsXReferenceLineProps< + TValue extends string | number | Date = string | number | Date, +> = CommonChartsReferenceLineProps & { + /** + * The x value associated with the reference line. + * If defined the reference line will be vertical. + */ + x: TValue; +}; + +type GetTextPlacementParams = { + top: number; + height: number; + spacingY: number; +} & Pick; + +const getTextParams = ({ + top, + height, + spacingY, + labelAlign = 'middle', +}: GetTextPlacementParams) => { + switch (labelAlign) { + case 'start': + return { + y: top + spacingY, + style: { + dominantBaseline: 'hanging', + textAnchor: 'start', + } as const, + }; + + case 'end': + return { + y: top + height - spacingY, + style: { + dominantBaseline: 'auto', + textAnchor: 'start', + } as const, + }; + + default: + return { + y: top + height / 2, + style: { + dominantBaseline: 'central', + textAnchor: 'start', + } as const, + }; + } +}; + +export function getXReferenceLineClasses(classes?: Partial) { + return composeClasses( + { + root: ['root', 'vertical'], + line: ['line'], + label: ['label'], + }, + getReferenceLineUtilityClass, + classes, + ); +} + +let warnedOnce = false; + +function ChartsXReferenceLine(props: ChartsXReferenceLineProps) { + const { + x, + label = '', + spacing = 5, + classes: inClasses, + labelAlign, + lineStyle, + labelStyle, + axisId, + } = props; + + const { top, height } = useDrawingArea(); + const xAxisScale = useXScale(axisId); + + const xPosition = xAxisScale(x as any); + + if (xPosition === undefined) { + if (process.env.NODE_ENV !== 'production') { + if (!warnedOnce) { + warnedOnce = true; + console.error( + `MUI X: the value ${x} does not exist in the data of x axis with id ${axisId}.`, + ); + } + } + return null; + } + const d = `M ${xPosition} ${top} l 0 ${height}`; + + const classes = getXReferenceLineClasses(inClasses); + + const spacingX = typeof spacing === 'object' ? spacing.x ?? 0 : spacing; + const spacingY = typeof spacing === 'object' ? spacing.y ?? 0 : spacing; + + const textParams = { + x: xPosition + spacingX, + text: label, + fontSize: 12, + ...getTextParams({ + top, + height, + spacingY, + labelAlign, + }), + className: classes.label, + }; + + return ( + + + + + ); +} + +export { ChartsXReferenceLine }; diff --git a/packages/x-charts/src/ChartsReferenceLine/ChartsYReferenceLine.tsx b/packages/x-charts/src/ChartsReferenceLine/ChartsYReferenceLine.tsx new file mode 100644 index 0000000000000..9486bef8f9813 --- /dev/null +++ b/packages/x-charts/src/ChartsReferenceLine/ChartsYReferenceLine.tsx @@ -0,0 +1,133 @@ +import * as React from 'react'; +import composeClasses from '@mui/utils/composeClasses'; +import { useDrawingArea, useYScale } from '../hooks'; +import { CommonChartsReferenceLineProps, ReferenceLineRoot } from './common'; +import { ChartsText } from '../internals/components/ChartsText'; +import { + ChartsReferenceLineClasses, + getReferenceLineUtilityClass, +} from './chartsReferenceLineClasses'; + +export type ChartsYReferenceLineProps< + TValue extends string | number | Date = string | number | Date, +> = CommonChartsReferenceLineProps & { + /** + * The y value associated with the reference line. + * If defined the reference line will be horizontal. + */ + y: TValue; +}; + +type GetTextPlacementParams = { + left: number; + width: number; + spacingX: number; +} & Pick; + +const getTextParams = ({ + left, + width, + spacingX, + labelAlign = 'middle', +}: GetTextPlacementParams) => { + switch (labelAlign) { + case 'start': + return { + x: left + spacingX, + style: { + dominantBaseline: 'auto', + textAnchor: 'start', + } as const, + }; + + case 'end': + return { + x: left + width - spacingX, + style: { + dominantBaseline: 'auto', + textAnchor: 'end', + } as const, + }; + + default: + return { + x: left + width / 2, + style: { + dominantBaseline: 'auto', + textAnchor: 'middle', + } as const, + }; + } +}; + +let warnedOnce = false; + +export function getYReferenceLineClasses(classes?: Partial) { + return composeClasses( + { + root: ['root', 'horizontal'], + line: ['line'], + label: ['label'], + }, + getReferenceLineUtilityClass, + classes, + ); +} + +function ChartsYReferenceLine(props: ChartsYReferenceLineProps) { + const { + y, + label = '', + spacing = 5, + classes: inClasses, + labelAlign, + lineStyle, + labelStyle, + axisId, + } = props; + + const { left, width } = useDrawingArea(); + const yAxisScale = useYScale(axisId); + + const yPosition = yAxisScale(y as any); + + if (yPosition === undefined) { + if (process.env.NODE_ENV !== 'production') { + if (!warnedOnce) { + warnedOnce = true; + console.error( + `MUI X: the value ${y} does not exist in the data of y axis with id ${axisId}.`, + ); + } + } + return null; + } + + const d = `M ${left} ${yPosition} l ${width} 0`; + + const classes = getYReferenceLineClasses(inClasses); + + const spacingX = typeof spacing === 'object' ? spacing.x ?? 0 : spacing; + const spacingY = typeof spacing === 'object' ? spacing.y ?? 0 : spacing; + + const textParams = { + y: yPosition - spacingY, + text: label, + fontSize: 12, + ...getTextParams({ + left, + width, + spacingX, + labelAlign, + }), + className: classes.label, + }; + return ( + + + + + ); +} + +export { ChartsYReferenceLine }; diff --git a/packages/x-charts/src/ChartsReferenceLine/chartsReferenceLineClasses.ts b/packages/x-charts/src/ChartsReferenceLine/chartsReferenceLineClasses.ts new file mode 100644 index 0000000000000..882500714bc89 --- /dev/null +++ b/packages/x-charts/src/ChartsReferenceLine/chartsReferenceLineClasses.ts @@ -0,0 +1,26 @@ +import generateUtilityClass from '@mui/utils/generateUtilityClass'; +import generateUtilityClasses from '@mui/utils/generateUtilityClasses'; + +export interface ChartsReferenceLineClasses { + /** Styles applied to the root element. */ + root: string; + /** Styles applied to the root element if the reference line is vertical. */ + vertical: string; + /** Styles applied to the root element if the reference line is horizontal. */ + horizontal: string; + /** Styles applied to the reference line. */ + line: string; + /** Styles applied to the reference label. */ + label: string; +} + +export type ChartsReferenceLineClassKey = keyof ChartsReferenceLineClasses; + +export function getReferenceLineUtilityClass(slot: string) { + return generateUtilityClass('MuiChartsReferenceLine', slot); +} + +export const referenceLineClasses: ChartsReferenceLineClasses = generateUtilityClasses( + 'MuiChartsReferenceLine', + ['root', 'vertical', 'horizontal', 'line', 'label'], +); diff --git a/packages/x-charts/src/ChartsReferenceLine/common.tsx b/packages/x-charts/src/ChartsReferenceLine/common.tsx new file mode 100644 index 0000000000000..535bce12785d0 --- /dev/null +++ b/packages/x-charts/src/ChartsReferenceLine/common.tsx @@ -0,0 +1,55 @@ +import { styled } from '@mui/material/styles'; +import { referenceLineClasses, ChartsReferenceLineClasses } from './chartsReferenceLineClasses'; +import { ChartsTextStyle } from '../internals/components/ChartsText'; + +export type CommonChartsReferenceLineProps = { + /** + * The alignment if the label is in the chart drawing area. + * @default 'middle' + */ + labelAlign?: 'start' | 'middle' | 'end'; + /** + * The label to display along the reference line. + */ + label?: string; + /** + * Additional space arround the label in px. + * Can be a number or an object `{ x, y }` to distinguish space with the reference line and space with axes. + * @default 5 + */ + spacing?: number | { x?: number; y?: number }; + /** + * The id of the axis used for the reference value. + * @default The `id` of the first defined axis. + */ + axisId?: string; + /** + * The style applied to the label. + */ + labelStyle?: ChartsTextStyle; + /** + * The style applied to the line. + */ + lineStyle?: React.CSSProperties; + /** + * Override or extend the styles applied to the component. + */ + classes?: Partial; +}; + +export const ReferenceLineRoot = styled('g')(({ theme }) => ({ + [`& .${referenceLineClasses.line}`]: { + fill: 'none', + stroke: (theme.vars || theme).palette.text.primary, + shapeRendering: 'crispEdges', + strokeWidth: 1, + pointerEvents: 'none', + }, + [`& .${referenceLineClasses.label}`]: { + fill: (theme.vars || theme).palette.text.primary, + stroke: 'none', + pointerEvents: 'none', + fontSize: 12, + ...theme.typography.body1, + }, +})); diff --git a/packages/x-charts/src/ChartsReferenceLine/index.tsx b/packages/x-charts/src/ChartsReferenceLine/index.tsx new file mode 100644 index 0000000000000..630541c15e4ae --- /dev/null +++ b/packages/x-charts/src/ChartsReferenceLine/index.tsx @@ -0,0 +1,2 @@ +export * from './ChartsReferenceLine'; +export * from './chartsReferenceLineClasses'; diff --git a/packages/x-charts/src/ChartsXAxis/ChartsXAxis.tsx b/packages/x-charts/src/ChartsXAxis/ChartsXAxis.tsx index 98cfdc6b00d3d..2cda7958494ec 100644 --- a/packages/x-charts/src/ChartsXAxis/ChartsXAxis.tsx +++ b/packages/x-charts/src/ChartsXAxis/ChartsXAxis.tsx @@ -96,9 +96,10 @@ const defaultProps = { */ function ChartsXAxis(inProps: ChartsXAxisProps) { const props = useThemeProps({ props: { ...defaultProps, ...inProps }, name: 'MuiChartsXAxis' }); + const { xAxisIds } = React.useContext(CartesianContext); const { xAxis: { - [props.axisId]: { scale: xScale, tickNumber, ...settings }, + [props.axisId ?? xAxisIds[0]]: { scale: xScale, tickNumber, ...settings }, }, } = React.useContext(CartesianContext); @@ -233,9 +234,10 @@ ChartsXAxis.propTypes = { // | To update them edit the TypeScript types and run "yarn proptypes" | // ---------------------------------------------------------------------- /** - * Id of the axis to render. + * The id of the axis to render. + * If undefined, it will be the first defined axis. */ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, /** * Override or extend the styles applied to the component. */ diff --git a/packages/x-charts/src/ChartsYAxis/ChartsYAxis.tsx b/packages/x-charts/src/ChartsYAxis/ChartsYAxis.tsx index 878b08938848a..f22632a0a8a13 100644 --- a/packages/x-charts/src/ChartsYAxis/ChartsYAxis.tsx +++ b/packages/x-charts/src/ChartsYAxis/ChartsYAxis.tsx @@ -45,9 +45,10 @@ const defaultProps = { */ function ChartsYAxis(inProps: ChartsYAxisProps) { const props = useThemeProps({ props: { ...defaultProps, ...inProps }, name: 'MuiChartsYAxis' }); + const { yAxisIds } = React.useContext(CartesianContext); const { yAxis: { - [props.axisId]: { scale: yScale, tickNumber, ...settings }, + [props.axisId ?? yAxisIds[0]]: { scale: yScale, tickNumber, ...settings }, }, } = React.useContext(CartesianContext); @@ -168,9 +169,10 @@ ChartsYAxis.propTypes = { // | To update them edit the TypeScript types and run "yarn proptypes" | // ---------------------------------------------------------------------- /** - * Id of the axis to render. + * The id of the axis to render. + * If undefined, it will be the first defined axis. */ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, /** * Override or extend the styles applied to the component. */ diff --git a/packages/x-charts/src/LineChart/AreaPlot.tsx b/packages/x-charts/src/LineChart/AreaPlot.tsx index a27d167230576..100be4eac913d 100644 --- a/packages/x-charts/src/LineChart/AreaPlot.tsx +++ b/packages/x-charts/src/LineChart/AreaPlot.tsx @@ -79,8 +79,8 @@ function AreaPlot(props: AreaPlotProps) { }>() .x((d) => xScale(d.x)) .defined((_, i) => connectNulls || data[i] != null) - .y0((d) => d.y && yScale(d.y[0])) - .y1((d) => d.y && yScale(d.y[1])); + .y0((d) => d.y && yScale(d.y[0])!) + .y1((d) => d.y && yScale(d.y[1])!); const curve = getCurveFactory(series[seriesId].curve); const formattedData = xData?.map((x, index) => ({ x, y: stackedData[index] })) ?? []; diff --git a/packages/x-charts/src/LineChart/LineChart.tsx b/packages/x-charts/src/LineChart/LineChart.tsx index 704a90cd2db5f..8bffab3521602 100644 --- a/packages/x-charts/src/LineChart/LineChart.tsx +++ b/packages/x-charts/src/LineChart/LineChart.tsx @@ -183,7 +183,7 @@ LineChart.propTypes = { */ bottomAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, @@ -231,7 +231,7 @@ LineChart.propTypes = { */ leftAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, @@ -285,7 +285,7 @@ LineChart.propTypes = { */ rightAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, @@ -384,7 +384,7 @@ LineChart.propTypes = { */ topAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, diff --git a/packages/x-charts/src/LineChart/LineHighlightPlot.tsx b/packages/x-charts/src/LineChart/LineHighlightPlot.tsx index 1feab1b549797..5f043b2f81977 100644 --- a/packages/x-charts/src/LineChart/LineHighlightPlot.tsx +++ b/packages/x-charts/src/LineChart/LineHighlightPlot.tsx @@ -84,7 +84,7 @@ function LineHighlightPlot(props: LineHighlightPlotProps) { ); } const x = xScale(xData[highlightedIndex]); - const y = yScale(stackedData[highlightedIndex][1]); + const y = yScale(stackedData[highlightedIndex][1])!; // This should not be undefined since y should not be a band scale return ( () .x((d) => xScale(d.x)) .defined((_, i) => connectNulls || data[i] != null) - .y((d) => yScale(d.y[1])); + .y((d) => yScale(d.y[1])!); const curve = getCurveFactory(series[seriesId].curve); const formattedData = xData?.map((x, index) => ({ x, y: stackedData[index] })) ?? []; diff --git a/packages/x-charts/src/LineChart/MarkPlot.tsx b/packages/x-charts/src/LineChart/MarkPlot.tsx index 942a6a3cdb154..670f390d13455 100644 --- a/packages/x-charts/src/LineChart/MarkPlot.tsx +++ b/packages/x-charts/src/LineChart/MarkPlot.tsx @@ -96,7 +96,7 @@ function MarkPlot(props: MarkPlotProps) { const value = data[index] == null ? null : stackedData[index][1]; return { x: xScale(x), - y: value === null ? null : yScale(value), + y: value === null ? null : yScale(value)!, position: x, value, index, @@ -131,7 +131,7 @@ function MarkPlot(props: MarkPlotProps) { shape="circle" color={series[seriesId].color} x={x} - y={y} + y={y!} // Don't knwo why TS don't get from the filter that y can't be null highlightScope={series[seriesId].highlightScope} {...slotProps?.mark} /> diff --git a/packages/x-charts/src/PieChart/PieChart.tsx b/packages/x-charts/src/PieChart/PieChart.tsx index 56b8880894bfd..6930d48eca81a 100644 --- a/packages/x-charts/src/PieChart/PieChart.tsx +++ b/packages/x-charts/src/PieChart/PieChart.tsx @@ -157,7 +157,7 @@ PieChart.propTypes = { */ bottomAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, @@ -201,7 +201,7 @@ PieChart.propTypes = { */ leftAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, @@ -256,7 +256,7 @@ PieChart.propTypes = { */ rightAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, @@ -368,7 +368,7 @@ PieChart.propTypes = { */ topAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, diff --git a/packages/x-charts/src/ScatterChart/ScatterChart.tsx b/packages/x-charts/src/ScatterChart/ScatterChart.tsx index 75fa84546c919..819e9568141d2 100644 --- a/packages/x-charts/src/ScatterChart/ScatterChart.tsx +++ b/packages/x-charts/src/ScatterChart/ScatterChart.tsx @@ -136,7 +136,7 @@ ScatterChart.propTypes = { */ bottomAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, @@ -180,7 +180,7 @@ ScatterChart.propTypes = { */ leftAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, @@ -234,7 +234,7 @@ ScatterChart.propTypes = { */ rightAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, @@ -315,7 +315,7 @@ ScatterChart.propTypes = { */ topAxis: PropTypes.oneOfType([ PropTypes.shape({ - axisId: PropTypes.string.isRequired, + axisId: PropTypes.string, classes: PropTypes.object, disableLine: PropTypes.bool, disableTicks: PropTypes.bool, diff --git a/packages/x-charts/src/index.ts b/packages/x-charts/src/index.ts index df1245089c2fc..c16a933ab1d7e 100644 --- a/packages/x-charts/src/index.ts +++ b/packages/x-charts/src/index.ts @@ -4,6 +4,7 @@ export * from './hooks'; export * from './colorPalettes'; export * from './models'; export * from './ChartsClipPath'; +export * from './ChartsReferenceLine'; export * from './ChartsAxis'; export * from './ChartsXAxis'; export * from './ChartsYAxis'; diff --git a/packages/x-charts/src/internals/isBandScale.ts b/packages/x-charts/src/internals/isBandScale.ts index 3a828d8b9eccb..0479662fd6079 100644 --- a/packages/x-charts/src/internals/isBandScale.ts +++ b/packages/x-charts/src/internals/isBandScale.ts @@ -1,6 +1,8 @@ import type { ScaleBand, ScalePoint } from 'd3-scale'; import { D3Scale } from '../models/axis'; -export function isBandScale(scale: D3Scale): scale is ScaleBand | ScalePoint { - return (scale as ScaleBand | ScalePoint).bandwidth !== undefined; +export function isBandScale( + scale: D3Scale, +): scale is ScaleBand | ScalePoint { + return (scale as ScaleBand | ScalePoint).bandwidth !== undefined; } diff --git a/packages/x-charts/src/internals/utils.ts b/packages/x-charts/src/internals/utils.ts index 72d216c2e02ab..6c1b3ced4f09d 100644 --- a/packages/x-charts/src/internals/utils.ts +++ b/packages/x-charts/src/internals/utils.ts @@ -5,3 +5,6 @@ export function getSymbol(shape: SymbolsTypes): number { return symbolNames.indexOf(shape) || 0; } + +type Without = { [P in Exclude]?: never }; +export type XOR = T | U extends object ? (Without & U) | (Without & T) : T | U; diff --git a/packages/x-charts/src/models/axis.ts b/packages/x-charts/src/models/axis.ts index 8180704031af8..ee361350f30e9 100644 --- a/packages/x-charts/src/models/axis.ts +++ b/packages/x-charts/src/models/axis.ts @@ -10,19 +10,23 @@ import { ChartsAxisClasses } from '../ChartsAxis/axisClasses'; import type { TickParams } from '../hooks/useTicks'; import { ChartsTextProps } from '../internals/components/ChartsText'; -export type D3Scale = - | ScaleBand - | ScaleLogarithmic - | ScalePoint - | ScalePower - | ScaleTime - | ScaleLinear; +export type D3Scale< + Domain extends { toString(): string } = number | Date | string, + Range = number, + Output = number, +> = + | ScaleBand + | ScaleLogarithmic + | ScalePoint + | ScalePower + | ScaleTime + | ScaleLinear; -export type D3ContinuouseScale = - | ScaleLogarithmic - | ScalePower - | ScaleTime - | ScaleLinear; +export type D3ContinuouseScale = + | ScaleLogarithmic + | ScalePower + | ScaleTime + | ScaleLinear; export interface ChartsAxisSlotsComponent { axisLine?: React.JSXElementConstructor>; @@ -40,9 +44,10 @@ export interface ChartsAxisSlotComponentProps { export interface ChartsAxisProps extends TickParams { /** - * Id of the axis to render. + * The id of the axis to render. + * If undefined, it will be the first defined axis. */ - axisId: string; + axisId?: string; /** * If true, the axis line is disabled. * @default false @@ -135,7 +140,7 @@ export type ContinuouseScaleName = 'linear' | 'log' | 'pow' | 'sqrt' | 'time' | interface AxisScaleConfig { band: { scaleType: 'band'; - scale: ScaleBand; + scale: ScaleBand; /** * The ratio between the space allocated for padding between two categories and the category width. * 0 means no gap, and 1 no data. @@ -151,31 +156,31 @@ interface AxisScaleConfig { }; point: { scaleType: 'point'; - scale: ScalePoint; + scale: ScalePoint; }; log: { scaleType: 'log'; - scale: ScaleLogarithmic; + scale: ScaleLogarithmic; }; pow: { scaleType: 'pow'; - scale: ScalePower; + scale: ScalePower; }; sqrt: { scaleType: 'sqrt'; - scale: ScalePower; + scale: ScalePower; }; time: { scaleType: 'time'; - scale: ScaleTime; + scale: ScaleTime; }; utc: { scaleType: 'utc'; - scale: ScaleTime; + scale: ScaleTime; }; linear: { scaleType: 'linear'; - scale: ScaleLinear; + scale: ScaleLinear; }; } diff --git a/scripts/x-charts.exports.json b/scripts/x-charts.exports.json index c07a57d5614c5..84ced50c79121 100644 --- a/scripts/x-charts.exports.json +++ b/scripts/x-charts.exports.json @@ -36,6 +36,9 @@ { "name": "ChartsColorPalette", "kind": "TypeAlias" }, { "name": "ChartsColorPaletteCallback", "kind": "TypeAlias" }, { "name": "ChartsPieSorting", "kind": "TypeAlias" }, + { "name": "ChartsReferenceLine", "kind": "Function" }, + { "name": "ChartsReferenceLineClasses", "kind": "Interface" }, + { "name": "ChartsReferenceLineClassKey", "kind": "TypeAlias" }, { "name": "ChartsTooltip", "kind": "Function" }, { "name": "ChartsTooltipProps", "kind": "TypeAlias" }, { "name": "ChartsTooltipSlotComponentProps", "kind": "Interface" }, @@ -69,6 +72,7 @@ { "name": "getMarkElementUtilityClass", "kind": "Function" }, { "name": "getPieArcLabelUtilityClass", "kind": "Function" }, { "name": "getPieArcUtilityClass", "kind": "Function" }, + { "name": "getReferenceLineUtilityClass", "kind": "Function" }, { "name": "getValueToPositionMapper", "kind": "Function" }, { "name": "HighlightElementClassKey", "kind": "TypeAlias" }, { "name": "HighlightOptions", "kind": "TypeAlias" }, @@ -111,6 +115,7 @@ { "name": "PiePlot", "kind": "Function" }, { "name": "PieSeriesType", "kind": "Interface" }, { "name": "PieValueType", "kind": "TypeAlias" }, + { "name": "referenceLineClasses", "kind": "Variable" }, { "name": "ResponsiveChartContainer", "kind": "Variable" }, { "name": "ResponsiveChartContainerProps", "kind": "TypeAlias" }, { "name": "ScaleName", "kind": "TypeAlias" }, From a711a0e1b01fa75c5e4677a14edf1d04cf444066 Mon Sep 17 00:00:00 2001 From: Michel Engelen <32863416+michelengelen@users.noreply.github.com> Date: Wed, 8 Nov 2023 12:02:39 +0100 Subject: [PATCH 05/13] [DataGrid] Fix keyboard navigation for actions cell with disabled buttons (#10947) --- .../src/components/cell/GridActionsCell.tsx | 33 ++++-- .../src/components/cell/GridCell.tsx | 11 +- .../src/tests/keyboard.DataGrid.test.tsx | 110 +++++++++++++++++- 3 files changed, 138 insertions(+), 16 deletions(-) diff --git a/packages/grid/x-data-grid/src/components/cell/GridActionsCell.tsx b/packages/grid/x-data-grid/src/components/cell/GridActionsCell.tsx index 424901dafab19..c42d8627b895e 100644 --- a/packages/grid/x-data-grid/src/components/cell/GridActionsCell.tsx +++ b/packages/grid/x-data-grid/src/components/cell/GridActionsCell.tsx @@ -97,11 +97,13 @@ function GridActionsCell(props: GridActionsCellProps) { focus() { // If ignoreCallToFocus is true, then one of the buttons was clicked and the focus is already set if (!ignoreCallToFocus.current) { - setFocusedButtonIndex(0); + // find the first focusable button and pass the index to the state + const focusableButtonIndex = options.findIndex((o) => !o.props.disabled); + setFocusedButtonIndex(focusableButtonIndex); } }, }), - [], + [options], ); React.useEffect(() => { @@ -141,19 +143,26 @@ function GridActionsCell(props: GridActionsCellProps) { return; } + const getNewIndex = (index: number, direction: 'left' | 'right'): number => { + if (index < 0 || index > options.length) { + return index; + } + + // for rtl mode we need to reverse the direction + const rtlMod = theme.direction === 'rtl' ? -1 : 1; + const indexMod = (direction === 'left' ? -1 : 1) * rtlMod; + + // if the button that should receive focus is disabled go one more step + return options[index + indexMod]?.props.disabled + ? getNewIndex(index + indexMod, direction) + : index + indexMod; + }; + let newIndex: number = focusedButtonIndex; if (event.key === 'ArrowRight') { - if (theme.direction === 'rtl') { - newIndex -= 1; - } else { - newIndex += 1; - } + newIndex = getNewIndex(focusedButtonIndex, 'right'); } else if (event.key === 'ArrowLeft') { - if (theme.direction === 'rtl') { - newIndex += 1; - } else { - newIndex -= 1; - } + newIndex = getNewIndex(focusedButtonIndex, 'left'); } if (newIndex < 0 || newIndex >= numberOfButtons) { diff --git a/packages/grid/x-data-grid/src/components/cell/GridCell.tsx b/packages/grid/x-data-grid/src/components/cell/GridCell.tsx index bc74c127ad518..d55e0c431ca14 100644 --- a/packages/grid/x-data-grid/src/components/cell/GridCell.tsx +++ b/packages/grid/x-data-grid/src/components/cell/GridCell.tsx @@ -18,6 +18,7 @@ import { GridRowId, GridCellMode, GridEditCellProps, + GridActionsColDef, } from '../../models'; import { GridRenderEditCellParams, @@ -585,9 +586,13 @@ const GridCellV7 = React.forwardRef((props, ref const { cellMode, hasFocus, isEditable, value, formattedValue } = cellParamsWithAPI; - const managesOwnFocus = column.type === 'actions'; + const canManageOwnFocus = + column.type === 'actions' && + (column as GridActionsColDef) + .getActions?.(apiRef.current.getRowParams(rowId)) + .some((action) => !action.props.disabled); const tabIndex = - (cellMode === 'view' || !isEditable) && !managesOwnFocus ? cellParamsWithAPI.tabIndex : -1; + (cellMode === 'view' || !isEditable) && !canManageOwnFocus ? cellParamsWithAPI.tabIndex : -1; const { classes: rootClasses, getCellClassName } = rootProps; @@ -772,7 +777,7 @@ const GridCellV7 = React.forwardRef((props, ref ); } - if (React.isValidElement(children) && managesOwnFocus) { + if (React.isValidElement(children) && canManageOwnFocus) { children = React.cloneElement(children, { focusElementRef }); } diff --git a/packages/grid/x-data-grid/src/tests/keyboard.DataGrid.test.tsx b/packages/grid/x-data-grid/src/tests/keyboard.DataGrid.test.tsx index 036082a0ce0e7..1cd7a93ec6bff 100644 --- a/packages/grid/x-data-grid/src/tests/keyboard.DataGrid.test.tsx +++ b/packages/grid/x-data-grid/src/tests/keyboard.DataGrid.test.tsx @@ -10,8 +10,9 @@ import { getColumnValues, getRow, } from 'test/utils/helperFn'; -import { DataGrid, DataGridProps, GridColDef } from '@mui/x-data-grid'; +import { DataGrid, DataGridProps, GridActionsCellItem, GridColDef } from '@mui/x-data-grid'; import { useBasicDemoData, getBasicGridData } from '@mui/x-data-grid-generator'; +import RestoreIcon from '@mui/icons-material/Restore'; const isJSDOM = /jsdom/.test(window.navigator.userAgent); @@ -716,6 +717,113 @@ describe(' - Keyboard', () => { expect(virtualScroller.scrollLeft).to.equal(0); }); + it('should focus actions cell with one disabled item', () => { + const columns = [ + { + field: 'actions', + type: 'actions', + getActions: () => [ + } id={'action_1'} disabled />, + } id={'action_2'} />, + ], + }, + { field: 'id', width: 400 }, + { field: 'name' }, + ]; + const rows = [ + { id: 1, name: 'John' }, + { id: 2, name: 'Doe' }, + ]; + + render( +
    + +
    , + ); + + const cell = getCell(0, 1); + userEvent.mousePress(cell); + + fireEvent.keyDown(cell, { key: 'ArrowLeft' }); + expect(getActiveCell()).to.equal(`0-0`); + + // expect the only focusable button to be the active element + expect(document.activeElement?.id).to.equal('action_2'); + }); + + it('should focus actions cell with all items disabled', () => { + const columns = [ + { + field: 'actions', + type: 'actions', + getActions: () => [ + } id={'action_1'} disabled />, + } id={'action_2'} disabled />, + ], + }, + { field: 'id', width: 400 }, + { field: 'name' }, + ]; + const rows = [ + { id: 1, name: 'John' }, + { id: 2, name: 'Doe' }, + ]; + + render( +
    + +
    , + ); + + const cell = getCell(0, 1); + userEvent.mousePress(cell); + + fireEvent.keyDown(cell, { key: 'ArrowLeft' }); + expect(getActiveCell()).to.equal(`0-0`); + }); + + it('should be able to navigate the actions', () => { + const columns = [ + { + field: 'actions', + type: 'actions', + getActions: () => [ + } id={'action_1'} disabled />, + } id={'action_2'} />, + } id={'action_3'} disabled />, + } id={'action_4'} disabled />, + } id={'action_5'} />, + ], + }, + { field: 'id', width: 400 }, + { field: 'name' }, + ]; + const rows = [ + { id: 1, name: 'John' }, + { id: 2, name: 'Doe' }, + ]; + + render( +
    + +
    , + ); + + const cell = getCell(0, 1); + userEvent.mousePress(cell); + + fireEvent.keyDown(cell, { key: 'ArrowLeft' }); + expect(getActiveCell()).to.equal(`0-0`); + + // expect the only focusable button to be the active element + expect(document.activeElement?.id).to.equal('action_2'); + + fireEvent.keyDown(document.activeElement!, { key: 'ArrowRight' }); + + // expect the only focusable button to be the active element + expect(document.activeElement?.id).to.equal('action_5'); + }); + it('should not throw when moving into an empty grid', async () => { const columns = [{ field: 'id', width: 400 }, { field: 'name' }]; const rows = [] as any[]; From a0be8ca933d5b47bbf2aa6ab7180c8abac4870d5 Mon Sep 17 00:00:00 2001 From: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com> Date: Wed, 8 Nov 2023 15:58:55 +0100 Subject: [PATCH 06/13] [charts] Improve properties JSDoc (#10931) --- docs/pages/x/api/charts/bar-chart.json | 29 ++++++++++++ .../charts/cartesian-context-provider.json | 16 ++++++- docs/pages/x/api/charts/drawing-provider.json | 10 ++++- docs/pages/x/api/charts/line-chart.json | 29 ++++++++++++ docs/pages/x/api/charts/pie-chart.json | 23 ++++++++++ docs/pages/x/api/charts/scatter-chart.json | 23 ++++++++++ docs/pages/x/api/charts/spark-line-chart.json | 11 +++++ .../api-docs/charts/bar-chart.json | 40 +++++++++++++++++ .../charts/cartesian-context-provider.json | 18 +++++++- .../api-docs/charts/charts-axis.json | 4 +- .../api-docs/charts/charts-x-axis.json | 4 +- .../api-docs/charts/charts-y-axis.json | 4 +- .../api-docs/charts/drawing-provider.json | 8 +++- .../api-docs/charts/line-chart.json | 40 +++++++++++++++++ .../api-docs/charts/pie-chart.json | 35 +++++++++++++++ .../api-docs/charts/scatter-chart.json | 35 +++++++++++++++ .../api-docs/charts/spark-line-chart.json | 25 +++++++++++ packages/x-charts/src/BarChart/BarChart.tsx | 44 +++++++++++++++++++ .../x-charts/src/ChartsAxis/axisClasses.ts | 4 +- packages/x-charts/src/ChartsSurface.tsx | 11 +++++ packages/x-charts/src/LineChart/LineChart.tsx | 44 +++++++++++++++++++ packages/x-charts/src/PieChart/PieChart.tsx | 30 +++++++++++++ .../src/ResponsiveChartContainer/index.tsx | 15 ++++++- .../src/ScatterChart/ScatterChart.tsx | 30 +++++++++++++ .../src/SparkLineChart/SparkLineChart.tsx | 22 ++++++++++ .../src/context/CartesianContextProvider.tsx | 33 +++++++++++++- .../x-charts/src/context/DrawingProvider.tsx | 24 ++++++++++ .../src/context/HighlightProvider.tsx | 17 +++++++ .../src/context/InteractionProvider.tsx | 6 +++ .../src/context/SeriesContextProvider.tsx | 5 +++ .../src/internals/components/ChartsText.tsx | 2 +- packages/x-charts/src/internals/geometry.ts | 4 +- packages/x-charts/src/models/axis.ts | 19 +++++++- packages/x-charts/src/models/layout.ts | 6 +++ .../x-charts/src/models/seriesType/common.ts | 16 +++++++ scripts/x-charts.exports.json | 2 +- 36 files changed, 668 insertions(+), 20 deletions(-) diff --git a/docs/pages/x/api/charts/bar-chart.json b/docs/pages/x/api/charts/bar-chart.json index ed628ca83572d..c2aa08e4aedb1 100644 --- a/docs/pages/x/api/charts/bar-chart.json +++ b/docs/pages/x/api/charts/bar-chart.json @@ -1,5 +1,11 @@ { "props": { + "axisHighlight": { + "type": { + "name": "shape", + "description": "{ x?: 'band'
    | 'line'
    | 'none', y?: 'band'
    | 'line'
    | 'none' }" + } + }, "bottomAxis": { "type": { "name": "union", @@ -10,6 +16,9 @@ "colors": { "type": { "name": "union", "description": "Array<string>
    | func" } }, + "dataset": { "type": { "name": "arrayOf", "description": "Array<object>" } }, + "disableAxisListener": { "type": { "name": "bool" } }, + "height": { "type": { "name": "number" }, "default": "undefined" }, "leftAxis": { "type": { "name": "union", @@ -17,6 +26,13 @@ }, "default": "yAxisIds[0] The id of the first provided axis" }, + "margin": { + "type": { + "name": "shape", + "description": "{ bottom?: number, left?: number, right?: number, top?: number }" + }, + "default": "object Depends on the charts type." + }, "rightAxis": { "type": { "name": "union", @@ -33,6 +49,19 @@ "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
    | 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" }, "default": "null" + }, + "width": { "type": { "name": "number" }, "default": "undefined" }, + "xAxis": { + "type": { + "name": "arrayOf", + "description": "Array<{ axisId?: string, classes?: object, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, fill?: string, hideTooltip?: bool, id?: string, label?: string, labelFontSize?: number, labelStyle?: object, max?: Date
    | number, min?: Date
    | number, position?: 'bottom'
    | 'left'
    | 'right'
    | 'top', scaleType?: 'band'
    | 'linear'
    | 'log'
    | 'point'
    | 'pow'
    | 'sqrt'
    | 'time'
    | 'utc', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number, valueFormatter?: func }>" + } + }, + "yAxis": { + "type": { + "name": "arrayOf", + "description": "Array<{ axisId?: string, classes?: object, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, fill?: string, hideTooltip?: bool, id?: string, label?: string, labelFontSize?: number, labelStyle?: object, max?: Date
    | number, min?: Date
    | number, position?: 'bottom'
    | 'left'
    | 'right'
    | 'top', scaleType?: 'band'
    | 'linear'
    | 'log'
    | 'point'
    | 'pow'
    | 'sqrt'
    | 'time'
    | 'utc', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number, valueFormatter?: func }>" + } } }, "slots": [ diff --git a/docs/pages/x/api/charts/cartesian-context-provider.json b/docs/pages/x/api/charts/cartesian-context-provider.json index bf6b224c7ec15..5a654ee74bfdb 100644 --- a/docs/pages/x/api/charts/cartesian-context-provider.json +++ b/docs/pages/x/api/charts/cartesian-context-provider.json @@ -1,5 +1,19 @@ { - "props": {}, + "props": { + "dataset": { "type": { "name": "arrayOf", "description": "Array<object>" } }, + "xAxis": { + "type": { + "name": "arrayOf", + "description": "Array<{ axisId?: string, classes?: object, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, fill?: string, hideTooltip?: bool, id?: string, label?: string, labelFontSize?: number, labelStyle?: object, max?: Date
    | number, min?: Date
    | number, position?: 'bottom'
    | 'left'
    | 'right'
    | 'top', scaleType?: 'band'
    | 'linear'
    | 'log'
    | 'point'
    | 'pow'
    | 'sqrt'
    | 'time'
    | 'utc', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number, valueFormatter?: func }>" + } + }, + "yAxis": { + "type": { + "name": "arrayOf", + "description": "Array<{ axisId?: string, classes?: object, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, fill?: string, hideTooltip?: bool, id?: string, label?: string, labelFontSize?: number, labelStyle?: object, max?: Date
    | number, min?: Date
    | number, position?: 'bottom'
    | 'left'
    | 'right'
    | 'top', scaleType?: 'band'
    | 'linear'
    | 'log'
    | 'point'
    | 'pow'
    | 'sqrt'
    | 'time'
    | 'utc', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number, valueFormatter?: func }>" + } + } + }, "slots": [], "name": "CartesianContextProvider", "imports": [ diff --git a/docs/pages/x/api/charts/drawing-provider.json b/docs/pages/x/api/charts/drawing-provider.json index 04a2e652ed38a..47946baf9dda5 100644 --- a/docs/pages/x/api/charts/drawing-provider.json +++ b/docs/pages/x/api/charts/drawing-provider.json @@ -1,5 +1,13 @@ { - "props": {}, + "props": { + "margin": { + "type": { + "name": "shape", + "description": "{ bottom?: number, left?: number, right?: number, top?: number }" + }, + "default": "object Depends on the charts type." + } + }, "slots": [], "name": "DrawingProvider", "imports": [ diff --git a/docs/pages/x/api/charts/line-chart.json b/docs/pages/x/api/charts/line-chart.json index ad4f61d5517db..9ac45f784a759 100644 --- a/docs/pages/x/api/charts/line-chart.json +++ b/docs/pages/x/api/charts/line-chart.json @@ -1,5 +1,11 @@ { "props": { + "axisHighlight": { + "type": { + "name": "shape", + "description": "{ x?: 'band'
    | 'line'
    | 'none', y?: 'band'
    | 'line'
    | 'none' }" + } + }, "bottomAxis": { "type": { "name": "union", @@ -10,7 +16,10 @@ "colors": { "type": { "name": "union", "description": "Array<string>
    | func" } }, + "dataset": { "type": { "name": "arrayOf", "description": "Array<object>" } }, + "disableAxisListener": { "type": { "name": "bool" } }, "disableLineItemHighlight": { "type": { "name": "bool" } }, + "height": { "type": { "name": "number" }, "default": "undefined" }, "leftAxis": { "type": { "name": "union", @@ -18,6 +27,13 @@ }, "default": "yAxisIds[0] The id of the first provided axis" }, + "margin": { + "type": { + "name": "shape", + "description": "{ bottom?: number, left?: number, right?: number, top?: number }" + }, + "default": "object Depends on the charts type." + }, "rightAxis": { "type": { "name": "union", @@ -33,6 +49,19 @@ "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
    | 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" }, "default": "null" + }, + "width": { "type": { "name": "number" }, "default": "undefined" }, + "xAxis": { + "type": { + "name": "arrayOf", + "description": "Array<{ axisId?: string, classes?: object, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, fill?: string, hideTooltip?: bool, id?: string, label?: string, labelFontSize?: number, labelStyle?: object, max?: Date
    | number, min?: Date
    | number, position?: 'bottom'
    | 'left'
    | 'right'
    | 'top', scaleType?: 'band'
    | 'linear'
    | 'log'
    | 'point'
    | 'pow'
    | 'sqrt'
    | 'time'
    | 'utc', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number, valueFormatter?: func }>" + } + }, + "yAxis": { + "type": { + "name": "arrayOf", + "description": "Array<{ axisId?: string, classes?: object, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, fill?: string, hideTooltip?: bool, id?: string, label?: string, labelFontSize?: number, labelStyle?: object, max?: Date
    | number, min?: Date
    | number, position?: 'bottom'
    | 'left'
    | 'right'
    | 'top', scaleType?: 'band'
    | 'linear'
    | 'log'
    | 'point'
    | 'pow'
    | 'sqrt'
    | 'time'
    | 'utc', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number, valueFormatter?: func }>" + } } }, "slots": [ diff --git a/docs/pages/x/api/charts/pie-chart.json b/docs/pages/x/api/charts/pie-chart.json index 87a086c5b7a05..80256df705d63 100644 --- a/docs/pages/x/api/charts/pie-chart.json +++ b/docs/pages/x/api/charts/pie-chart.json @@ -10,6 +10,9 @@ "colors": { "type": { "name": "union", "description": "Array<string>
    | func" } }, + "dataset": { "type": { "name": "arrayOf", "description": "Array<object>" } }, + "disableAxisListener": { "type": { "name": "bool" } }, + "height": { "type": { "name": "number" }, "default": "undefined" }, "leftAxis": { "type": { "name": "union", @@ -17,6 +20,13 @@ }, "default": "yAxisIds[0] The id of the first provided axis" }, + "margin": { + "type": { + "name": "shape", + "description": "{ bottom?: number, left?: number, right?: number, top?: number }" + }, + "default": "object Depends on the charts type." + }, "rightAxis": { "type": { "name": "union", @@ -32,6 +42,19 @@ "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
    | 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" }, "default": "null" + }, + "width": { "type": { "name": "number" }, "default": "undefined" }, + "xAxis": { + "type": { + "name": "arrayOf", + "description": "Array<{ axisId?: string, classes?: object, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, fill?: string, hideTooltip?: bool, id?: string, label?: string, labelFontSize?: number, labelStyle?: object, max?: Date
    | number, min?: Date
    | number, position?: 'bottom'
    | 'left'
    | 'right'
    | 'top', scaleType?: 'band'
    | 'linear'
    | 'log'
    | 'point'
    | 'pow'
    | 'sqrt'
    | 'time'
    | 'utc', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number, valueFormatter?: func }>" + } + }, + "yAxis": { + "type": { + "name": "arrayOf", + "description": "Array<{ axisId?: string, classes?: object, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, fill?: string, hideTooltip?: bool, id?: string, label?: string, labelFontSize?: number, labelStyle?: object, max?: Date
    | number, min?: Date
    | number, position?: 'bottom'
    | 'left'
    | 'right'
    | 'top', scaleType?: 'band'
    | 'linear'
    | 'log'
    | 'point'
    | 'pow'
    | 'sqrt'
    | 'time'
    | 'utc', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number, valueFormatter?: func }>" + } } }, "slots": [], diff --git a/docs/pages/x/api/charts/scatter-chart.json b/docs/pages/x/api/charts/scatter-chart.json index ed264b3492317..9f6991e3d775f 100644 --- a/docs/pages/x/api/charts/scatter-chart.json +++ b/docs/pages/x/api/charts/scatter-chart.json @@ -10,6 +10,9 @@ "colors": { "type": { "name": "union", "description": "Array<string>
    | func" } }, + "dataset": { "type": { "name": "arrayOf", "description": "Array<object>" } }, + "disableAxisListener": { "type": { "name": "bool" } }, + "height": { "type": { "name": "number" }, "default": "undefined" }, "leftAxis": { "type": { "name": "union", @@ -17,6 +20,13 @@ }, "default": "yAxisIds[0] The id of the first provided axis" }, + "margin": { + "type": { + "name": "shape", + "description": "{ bottom?: number, left?: number, right?: number, top?: number }" + }, + "default": "object Depends on the charts type." + }, "rightAxis": { "type": { "name": "union", @@ -32,6 +42,19 @@ "description": "{ axisId?: string, classes?: object, disableLine?: bool, disableTicks?: bool, fill?: string, label?: string, labelFontSize?: number, labelStyle?: object, position?: 'bottom'
    | 'top', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number }
    | string" }, "default": "null" + }, + "width": { "type": { "name": "number" }, "default": "undefined" }, + "xAxis": { + "type": { + "name": "arrayOf", + "description": "Array<{ axisId?: string, classes?: object, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, fill?: string, hideTooltip?: bool, id?: string, label?: string, labelFontSize?: number, labelStyle?: object, max?: Date
    | number, min?: Date
    | number, position?: 'bottom'
    | 'left'
    | 'right'
    | 'top', scaleType?: 'band'
    | 'linear'
    | 'log'
    | 'point'
    | 'pow'
    | 'sqrt'
    | 'time'
    | 'utc', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number, valueFormatter?: func }>" + } + }, + "yAxis": { + "type": { + "name": "arrayOf", + "description": "Array<{ axisId?: string, classes?: object, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, fill?: string, hideTooltip?: bool, id?: string, label?: string, labelFontSize?: number, labelStyle?: object, max?: Date
    | number, min?: Date
    | number, position?: 'bottom'
    | 'left'
    | 'right'
    | 'top', scaleType?: 'band'
    | 'linear'
    | 'log'
    | 'point'
    | 'pow'
    | 'sqrt'
    | 'time'
    | 'utc', slotProps?: object, slots?: object, stroke?: string, tickFontSize?: number, tickInterval?: 'auto'
    | array
    | func, tickLabelInterval?: 'auto'
    | func, tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickSize?: number, valueFormatter?: func }>" + } } }, "slots": [ diff --git a/docs/pages/x/api/charts/spark-line-chart.json b/docs/pages/x/api/charts/spark-line-chart.json index 7adb9df48fcfc..225500cb1c45a 100644 --- a/docs/pages/x/api/charts/spark-line-chart.json +++ b/docs/pages/x/api/charts/spark-line-chart.json @@ -8,6 +8,16 @@ "colors": { "type": { "name": "union", "description": "Array<string>
    | func" } }, + "dataset": { "type": { "name": "arrayOf", "description": "Array<object>" } }, + "disableAxisListener": { "type": { "name": "bool" } }, + "height": { "type": { "name": "number" }, "default": "undefined" }, + "margin": { + "type": { + "name": "shape", + "description": "{ bottom?: number, left?: number, right?: number, top?: number }" + }, + "default": "object Depends on the charts type." + }, "plotType": { "type": { "name": "enum", "description": "'bar'
    | 'line'" }, "default": "'line'" @@ -24,6 +34,7 @@ "returned": "string" } }, + "width": { "type": { "name": "number" }, "default": "undefined" }, "xAxis": { "type": { "name": "shape", diff --git a/docs/translations/api-docs/charts/bar-chart.json b/docs/translations/api-docs/charts/bar-chart.json index bee22b81e0d3c..6c0d6d7be4f9d 100644 --- a/docs/translations/api-docs/charts/bar-chart.json +++ b/docs/translations/api-docs/charts/bar-chart.json @@ -1,6 +1,11 @@ { "componentDescription": "", "propDescriptions": { + "axisHighlight": { + "description": "Object { x, y } that defines how the charts highlight the mouse position along the x- and y-axes. The two properties accept the following values: - 'none': display nothing. - 'line': display a line at the current mouse position. - 'band': display a band at the current mouse position. Only available with band scale.", + "deprecated": "", + "typeDescriptions": {} + }, "bottomAxis": { "description": "Indicate which axis to display the bottom of the charts. Can be a string (the id of the axis) or an object ChartsXAxisProps.", "deprecated": "", @@ -11,11 +16,31 @@ "deprecated": "", "typeDescriptions": {} }, + "dataset": { + "description": "An array of objects that can be used to populate series and axes data using their dataKey property.", + "deprecated": "", + "typeDescriptions": {} + }, + "disableAxisListener": { + "description": "If true, the charts will not listen to the mouse move event. It might break interactive features, but will improve performance.", + "deprecated": "", + "typeDescriptions": {} + }, + "height": { + "description": "The height of the chart in px. If not defined, it takes the height of the parent element.", + "deprecated": "", + "typeDescriptions": {} + }, "leftAxis": { "description": "Indicate which axis to display the left of the charts. Can be a string (the id of the axis) or an object ChartsYAxisProps.", "deprecated": "", "typeDescriptions": {} }, + "margin": { + "description": "The margin between the SVG and the drawing area. It's used for leaving some space for extra information such as the x- and y-axis or legend. Accepts an object with the optional properties: top, bottom, left, and right.", + "deprecated": "", + "typeDescriptions": {} + }, "rightAxis": { "description": "Indicate which axis to display the right of the charts. Can be a string (the id of the axis) or an object ChartsYAxisProps.", "deprecated": "", @@ -40,6 +65,21 @@ "description": "Indicate which axis to display the top of the charts. Can be a string (the id of the axis) or an object ChartsXAxisProps.", "deprecated": "", "typeDescriptions": {} + }, + "width": { + "description": "The width of the chart in px. If not defined, it takes the width of the parent element.", + "deprecated": "", + "typeDescriptions": {} + }, + "xAxis": { + "description": "The configuration of the x-axes. If not provided, a default axis config is used with id set to DEFAULT_X_AXIS_KEY.", + "deprecated": "", + "typeDescriptions": {} + }, + "yAxis": { + "description": "The configuration of the y-axes. If not provided, a default axis config is used with id set to DEFAULT_Y_AXIS_KEY.", + "deprecated": "", + "typeDescriptions": {} } }, "classDescriptions": {}, diff --git a/docs/translations/api-docs/charts/cartesian-context-provider.json b/docs/translations/api-docs/charts/cartesian-context-provider.json index be9cfbbe310cd..7efe6db29fd49 100644 --- a/docs/translations/api-docs/charts/cartesian-context-provider.json +++ b/docs/translations/api-docs/charts/cartesian-context-provider.json @@ -1,6 +1,22 @@ { "componentDescription": "", - "propDescriptions": {}, + "propDescriptions": { + "dataset": { + "description": "An array of objects that can be used to populate series and axes data using their dataKey property.", + "deprecated": "", + "typeDescriptions": {} + }, + "xAxis": { + "description": "The configuration of the x-axes. If not provided, a default axis config is used with id set to DEFAULT_X_AXIS_KEY.", + "deprecated": "", + "typeDescriptions": {} + }, + "yAxis": { + "description": "The configuration of the y-axes. If not provided, a default axis config is used with id set to DEFAULT_Y_AXIS_KEY.", + "deprecated": "", + "typeDescriptions": {} + } + }, "classDescriptions": {}, "slotDescriptions": {} } diff --git a/docs/translations/api-docs/charts/charts-axis.json b/docs/translations/api-docs/charts/charts-axis.json index e3e74d1032287..ba8da4b4492b5 100644 --- a/docs/translations/api-docs/charts/charts-axis.json +++ b/docs/translations/api-docs/charts/charts-axis.json @@ -48,8 +48,8 @@ "description": "Styles applied to {{nodeName}}.", "nodeName": "the group containing the axis label" }, - "directionX": { "description": "Styles applied to {{nodeName}}.", "nodeName": "x axes" }, - "directionY": { "description": "Styles applied to {{nodeName}}.", "nodeName": "y axes" }, + "directionX": { "description": "Styles applied to {{nodeName}}.", "nodeName": "x-axes" }, + "directionY": { "description": "Styles applied to {{nodeName}}.", "nodeName": "y-axes" }, "top": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the top axis" }, "bottom": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the bottom axis" }, "left": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the left axis" }, diff --git a/docs/translations/api-docs/charts/charts-x-axis.json b/docs/translations/api-docs/charts/charts-x-axis.json index 1d470313d7f1d..3e977dd3e48ea 100644 --- a/docs/translations/api-docs/charts/charts-x-axis.json +++ b/docs/translations/api-docs/charts/charts-x-axis.json @@ -114,8 +114,8 @@ "description": "Styles applied to {{nodeName}}.", "nodeName": "the group containing the axis label" }, - "directionX": { "description": "Styles applied to {{nodeName}}.", "nodeName": "x axes" }, - "directionY": { "description": "Styles applied to {{nodeName}}.", "nodeName": "y axes" }, + "directionX": { "description": "Styles applied to {{nodeName}}.", "nodeName": "x-axes" }, + "directionY": { "description": "Styles applied to {{nodeName}}.", "nodeName": "y-axes" }, "top": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the top axis" }, "bottom": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the bottom axis" }, "left": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the left axis" }, diff --git a/docs/translations/api-docs/charts/charts-y-axis.json b/docs/translations/api-docs/charts/charts-y-axis.json index 1d470313d7f1d..3e977dd3e48ea 100644 --- a/docs/translations/api-docs/charts/charts-y-axis.json +++ b/docs/translations/api-docs/charts/charts-y-axis.json @@ -114,8 +114,8 @@ "description": "Styles applied to {{nodeName}}.", "nodeName": "the group containing the axis label" }, - "directionX": { "description": "Styles applied to {{nodeName}}.", "nodeName": "x axes" }, - "directionY": { "description": "Styles applied to {{nodeName}}.", "nodeName": "y axes" }, + "directionX": { "description": "Styles applied to {{nodeName}}.", "nodeName": "x-axes" }, + "directionY": { "description": "Styles applied to {{nodeName}}.", "nodeName": "y-axes" }, "top": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the top axis" }, "bottom": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the bottom axis" }, "left": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the left axis" }, diff --git a/docs/translations/api-docs/charts/drawing-provider.json b/docs/translations/api-docs/charts/drawing-provider.json index be9cfbbe310cd..a691b1e65b432 100644 --- a/docs/translations/api-docs/charts/drawing-provider.json +++ b/docs/translations/api-docs/charts/drawing-provider.json @@ -1,6 +1,12 @@ { "componentDescription": "", - "propDescriptions": {}, + "propDescriptions": { + "margin": { + "description": "The margin between the SVG and the drawing area. It's used for leaving some space for extra information such as the x- and y-axis or legend. Accepts an object with the optional properties: top, bottom, left, and right.", + "deprecated": "", + "typeDescriptions": {} + } + }, "classDescriptions": {}, "slotDescriptions": {} } diff --git a/docs/translations/api-docs/charts/line-chart.json b/docs/translations/api-docs/charts/line-chart.json index 67d7f050b9cb2..08e5e23e02278 100644 --- a/docs/translations/api-docs/charts/line-chart.json +++ b/docs/translations/api-docs/charts/line-chart.json @@ -1,6 +1,11 @@ { "componentDescription": "", "propDescriptions": { + "axisHighlight": { + "description": "Object { x, y } that defines how the charts highlight the mouse position along the x- and y-axes. The two properties accept the following values: - 'none': display nothing. - 'line': display a line at the current mouse position. - 'band': display a band at the current mouse position. Only available with band scale.", + "deprecated": "", + "typeDescriptions": {} + }, "bottomAxis": { "description": "Indicate which axis to display the bottom of the charts. Can be a string (the id of the axis) or an object ChartsXAxisProps.", "deprecated": "", @@ -11,16 +16,36 @@ "deprecated": "", "typeDescriptions": {} }, + "dataset": { + "description": "An array of objects that can be used to populate series and axes data using their dataKey property.", + "deprecated": "", + "typeDescriptions": {} + }, + "disableAxisListener": { + "description": "If true, the charts will not listen to the mouse move event. It might break interactive features, but will improve performance.", + "deprecated": "", + "typeDescriptions": {} + }, "disableLineItemHighlight": { "description": "If true, render the line highlight item.", "deprecated": "", "typeDescriptions": {} }, + "height": { + "description": "The height of the chart in px. If not defined, it takes the height of the parent element.", + "deprecated": "", + "typeDescriptions": {} + }, "leftAxis": { "description": "Indicate which axis to display the left of the charts. Can be a string (the id of the axis) or an object ChartsYAxisProps.", "deprecated": "", "typeDescriptions": {} }, + "margin": { + "description": "The margin between the SVG and the drawing area. It's used for leaving some space for extra information such as the x- and y-axis or legend. Accepts an object with the optional properties: top, bottom, left, and right.", + "deprecated": "", + "typeDescriptions": {} + }, "rightAxis": { "description": "Indicate which axis to display the right of the charts. Can be a string (the id of the axis) or an object ChartsYAxisProps.", "deprecated": "", @@ -40,6 +65,21 @@ "description": "Indicate which axis to display the top of the charts. Can be a string (the id of the axis) or an object ChartsXAxisProps.", "deprecated": "", "typeDescriptions": {} + }, + "width": { + "description": "The width of the chart in px. If not defined, it takes the width of the parent element.", + "deprecated": "", + "typeDescriptions": {} + }, + "xAxis": { + "description": "The configuration of the x-axes. If not provided, a default axis config is used with id set to DEFAULT_X_AXIS_KEY.", + "deprecated": "", + "typeDescriptions": {} + }, + "yAxis": { + "description": "The configuration of the y-axes. If not provided, a default axis config is used with id set to DEFAULT_Y_AXIS_KEY.", + "deprecated": "", + "typeDescriptions": {} } }, "classDescriptions": {}, diff --git a/docs/translations/api-docs/charts/pie-chart.json b/docs/translations/api-docs/charts/pie-chart.json index cab672234cc41..36ab78abec453 100644 --- a/docs/translations/api-docs/charts/pie-chart.json +++ b/docs/translations/api-docs/charts/pie-chart.json @@ -11,11 +11,31 @@ "deprecated": "", "typeDescriptions": {} }, + "dataset": { + "description": "An array of objects that can be used to populate series and axes data using their dataKey property.", + "deprecated": "", + "typeDescriptions": {} + }, + "disableAxisListener": { + "description": "If true, the charts will not listen to the mouse move event. It might break interactive features, but will improve performance.", + "deprecated": "", + "typeDescriptions": {} + }, + "height": { + "description": "The height of the chart in px. If not defined, it takes the height of the parent element.", + "deprecated": "", + "typeDescriptions": {} + }, "leftAxis": { "description": "Indicate which axis to display the left of the charts. Can be a string (the id of the axis) or an object ChartsYAxisProps.", "deprecated": "", "typeDescriptions": {} }, + "margin": { + "description": "The margin between the SVG and the drawing area. It's used for leaving some space for extra information such as the x- and y-axis or legend. Accepts an object with the optional properties: top, bottom, left, and right.", + "deprecated": "", + "typeDescriptions": {} + }, "rightAxis": { "description": "Indicate which axis to display the right of the charts. Can be a string (the id of the axis) or an object ChartsYAxisProps.", "deprecated": "", @@ -35,6 +55,21 @@ "description": "Indicate which axis to display the top of the charts. Can be a string (the id of the axis) or an object ChartsXAxisProps.", "deprecated": "", "typeDescriptions": {} + }, + "width": { + "description": "The width of the chart in px. If not defined, it takes the width of the parent element.", + "deprecated": "", + "typeDescriptions": {} + }, + "xAxis": { + "description": "The configuration of the x-axes. If not provided, a default axis config is used with id set to DEFAULT_X_AXIS_KEY.", + "deprecated": "", + "typeDescriptions": {} + }, + "yAxis": { + "description": "The configuration of the y-axes. If not provided, a default axis config is used with id set to DEFAULT_Y_AXIS_KEY.", + "deprecated": "", + "typeDescriptions": {} } }, "classDescriptions": {}, diff --git a/docs/translations/api-docs/charts/scatter-chart.json b/docs/translations/api-docs/charts/scatter-chart.json index 03154c1e5ef1f..1971b9e72b037 100644 --- a/docs/translations/api-docs/charts/scatter-chart.json +++ b/docs/translations/api-docs/charts/scatter-chart.json @@ -11,11 +11,31 @@ "deprecated": "", "typeDescriptions": {} }, + "dataset": { + "description": "An array of objects that can be used to populate series and axes data using their dataKey property.", + "deprecated": "", + "typeDescriptions": {} + }, + "disableAxisListener": { + "description": "If true, the charts will not listen to the mouse move event. It might break interactive features, but will improve performance.", + "deprecated": "", + "typeDescriptions": {} + }, + "height": { + "description": "The height of the chart in px. If not defined, it takes the height of the parent element.", + "deprecated": "", + "typeDescriptions": {} + }, "leftAxis": { "description": "Indicate which axis to display the left of the charts. Can be a string (the id of the axis) or an object ChartsYAxisProps.", "deprecated": "", "typeDescriptions": {} }, + "margin": { + "description": "The margin between the SVG and the drawing area. It's used for leaving some space for extra information such as the x- and y-axis or legend. Accepts an object with the optional properties: top, bottom, left, and right.", + "deprecated": "", + "typeDescriptions": {} + }, "rightAxis": { "description": "Indicate which axis to display the right of the charts. Can be a string (the id of the axis) or an object ChartsYAxisProps.", "deprecated": "", @@ -35,6 +55,21 @@ "description": "Indicate which axis to display the top of the charts. Can be a string (the id of the axis) or an object ChartsXAxisProps.", "deprecated": "", "typeDescriptions": {} + }, + "width": { + "description": "The width of the chart in px. If not defined, it takes the width of the parent element.", + "deprecated": "", + "typeDescriptions": {} + }, + "xAxis": { + "description": "The configuration of the x-axes. If not provided, a default axis config is used with id set to DEFAULT_X_AXIS_KEY.", + "deprecated": "", + "typeDescriptions": {} + }, + "yAxis": { + "description": "The configuration of the y-axes. If not provided, a default axis config is used with id set to DEFAULT_Y_AXIS_KEY.", + "deprecated": "", + "typeDescriptions": {} } }, "classDescriptions": {}, diff --git a/docs/translations/api-docs/charts/spark-line-chart.json b/docs/translations/api-docs/charts/spark-line-chart.json index 6c1257c5611ab..098cbc907bf3a 100644 --- a/docs/translations/api-docs/charts/spark-line-chart.json +++ b/docs/translations/api-docs/charts/spark-line-chart.json @@ -12,6 +12,26 @@ "typeDescriptions": {} }, "data": { "description": "Data to plot.", "deprecated": "", "typeDescriptions": {} }, + "dataset": { + "description": "An array of objects that can be used to populate series and axes data using their dataKey property.", + "deprecated": "", + "typeDescriptions": {} + }, + "disableAxisListener": { + "description": "If true, the charts will not listen to the mouse move event. It might break interactive features, but will improve performance.", + "deprecated": "", + "typeDescriptions": {} + }, + "height": { + "description": "The height of the chart in px. If not defined, it takes the height of the parent element.", + "deprecated": "", + "typeDescriptions": {} + }, + "margin": { + "description": "The margin between the SVG and the drawing area. It's used for leaving some space for extra information such as the x- and y-axis or legend. Accepts an object with the optional properties: top, bottom, left, and right.", + "deprecated": "", + "typeDescriptions": {} + }, "plotType": { "description": "Type of plot used.", "deprecated": "", "typeDescriptions": {} }, "showHighlight": { "description": "Set to true to highlight the value. With line, it shows a point. With bar, it shows a highlight band.", @@ -38,6 +58,11 @@ "deprecated": "", "typeDescriptions": { "value": "The value to format.", "string": "the formatted value." } }, + "width": { + "description": "The width of the chart in px. If not defined, it takes the width of the parent element.", + "deprecated": "", + "typeDescriptions": {} + }, "xAxis": { "description": "The xAxis configuration. Notice it is a single configuration object, not an array of configuration.", "deprecated": "", diff --git a/packages/x-charts/src/BarChart/BarChart.tsx b/packages/x-charts/src/BarChart/BarChart.tsx index f489fa3d49ff7..b09bee65b896a 100644 --- a/packages/x-charts/src/BarChart/BarChart.tsx +++ b/packages/x-charts/src/BarChart/BarChart.tsx @@ -43,6 +43,13 @@ export interface BarChartProps Pick { series: MakeOptional[]; tooltip?: ChartsTooltipProps; + /** + * Object `{ x, y }` that defines how the charts highlight the mouse position along the x- and y-axes. + * The two properties accept the following values: + * - 'none': display nothing. + * - 'line': display a line at the current mouse position. + * - 'band': display a band at the current mouse position. Only available with band scale. + */ axisHighlight?: ChartsAxisHighlightProps; /** * @deprecated Consider using `slotProps.legend` instead. @@ -167,6 +174,13 @@ BarChart.propTypes = { // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit the TypeScript types and run "yarn proptypes" | // ---------------------------------------------------------------------- + /** + * Object `{ x, y }` that defines how the charts highlight the mouse position along the x- and y-axes. + * The two properties accept the following values: + * - 'none': display nothing. + * - 'line': display a line at the current mouse position. + * - 'band': display a band at the current mouse position. Only available with band scale. + */ axisHighlight: PropTypes.shape({ x: PropTypes.oneOf(['band', 'line', 'none']), y: PropTypes.oneOf(['band', 'line', 'none']), @@ -211,9 +225,21 @@ BarChart.propTypes = { * Color palette used to colorize multiple series. */ colors: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string), PropTypes.func]), + /** + * An array of objects that can be used to populate series and axes data using their `dataKey` property. + */ dataset: PropTypes.arrayOf(PropTypes.object), desc: PropTypes.string, + /** + * If `true`, the charts will not listen to the mouse move event. + * It might break interactive features, but will improve performance. + * @default false + */ disableAxisListener: PropTypes.bool, + /** + * The height of the chart in px. If not defined, it takes the height of the parent element. + * @default undefined + */ height: PropTypes.number, layout: PropTypes.oneOf(['horizontal', 'vertical']), /** @@ -264,6 +290,12 @@ BarChart.propTypes = { slotProps: PropTypes.object, slots: PropTypes.object, }), + /** + * The margin between the SVG and the drawing area. + * It's used for leaving some space for extra information such as the x- and y-axis or legend. + * Accepts an object with the optional properties: `top`, `bottom`, `left`, and `right`. + * @default object Depends on the charts type. + */ margin: PropTypes.shape({ bottom: PropTypes.number, left: PropTypes.number, @@ -401,7 +433,15 @@ BarChart.propTypes = { x: PropTypes.number, y: PropTypes.number, }), + /** + * The width of the chart in px. If not defined, it takes the width of the parent element. + * @default undefined + */ width: PropTypes.number, + /** + * The configuration of the x-axes. + * If not provided, a default axis config is used with id set to `DEFAULT_X_AXIS_KEY`. + */ xAxis: PropTypes.arrayOf( PropTypes.shape({ axisId: PropTypes.string, @@ -438,6 +478,10 @@ BarChart.propTypes = { valueFormatter: PropTypes.func, }), ), + /** + * The configuration of the y-axes. + * If not provided, a default axis config is used with id set to `DEFAULT_Y_AXIS_KEY`. + */ yAxis: PropTypes.arrayOf( PropTypes.shape({ axisId: PropTypes.string, diff --git a/packages/x-charts/src/ChartsAxis/axisClasses.ts b/packages/x-charts/src/ChartsAxis/axisClasses.ts index 7386615ffa5a2..4bc68967b1fb8 100644 --- a/packages/x-charts/src/ChartsAxis/axisClasses.ts +++ b/packages/x-charts/src/ChartsAxis/axisClasses.ts @@ -16,9 +16,9 @@ export interface ChartsAxisClasses { tickLabel: string; /** Styles applied to the group containing the axis label. */ label: string; - /** Styles applied to x axes. */ + /** Styles applied to x-axes. */ directionX: string; - /** Styles applied to y axes. */ + /** Styles applied to y-axes. */ directionY: string; /** Styles applied to the top axis. */ top: string; diff --git a/packages/x-charts/src/ChartsSurface.tsx b/packages/x-charts/src/ChartsSurface.tsx index ed148ddd272ab..8f0e9dfb0d61f 100644 --- a/packages/x-charts/src/ChartsSurface.tsx +++ b/packages/x-charts/src/ChartsSurface.tsx @@ -9,7 +9,13 @@ type ViewBox = { height?: number; }; export interface ChartsSurfaceProps { + /** + * The width of the chart in px. + */ width: number; + /** + * The height of the chart in px. + */ height: number; viewBox?: ViewBox; className?: string; @@ -17,6 +23,11 @@ export interface ChartsSurfaceProps { desc?: string; sx?: SxProps; children?: React.ReactNode; + /** + * If `true`, the charts will not listen to the mouse move event. + * It might break interactive features, but will improve performance. + * @default false + */ disableAxisListener?: boolean; } diff --git a/packages/x-charts/src/LineChart/LineChart.tsx b/packages/x-charts/src/LineChart/LineChart.tsx index 8bffab3521602..b5e89965b2442 100644 --- a/packages/x-charts/src/LineChart/LineChart.tsx +++ b/packages/x-charts/src/LineChart/LineChart.tsx @@ -55,6 +55,13 @@ export interface LineChartProps Omit { series: MakeOptional[]; tooltip?: ChartsTooltipProps; + /** + * Object `{ x, y }` that defines how the charts highlight the mouse position along the x- and y-axes. + * The two properties accept the following values: + * - 'none': display nothing. + * - 'line': display a line at the current mouse position. + * - 'band': display a band at the current mouse position. Only available with band scale. + */ axisHighlight?: ChartsAxisHighlightProps; /** * @deprecated Consider using `slotProps.legend` instead. @@ -172,6 +179,13 @@ LineChart.propTypes = { // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit the TypeScript types and run "yarn proptypes" | // ---------------------------------------------------------------------- + /** + * Object `{ x, y }` that defines how the charts highlight the mouse position along the x- and y-axes. + * The two properties accept the following values: + * - 'none': display nothing. + * - 'line': display a line at the current mouse position. + * - 'band': display a band at the current mouse position. Only available with band scale. + */ axisHighlight: PropTypes.shape({ x: PropTypes.oneOf(['band', 'line', 'none']), y: PropTypes.oneOf(['band', 'line', 'none']), @@ -216,13 +230,25 @@ LineChart.propTypes = { * Color palette used to colorize multiple series. */ colors: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string), PropTypes.func]), + /** + * An array of objects that can be used to populate series and axes data using their `dataKey` property. + */ dataset: PropTypes.arrayOf(PropTypes.object), desc: PropTypes.string, + /** + * If `true`, the charts will not listen to the mouse move event. + * It might break interactive features, but will improve performance. + * @default false + */ disableAxisListener: PropTypes.bool, /** * If `true`, render the line highlight item. */ disableLineItemHighlight: PropTypes.bool, + /** + * The height of the chart in px. If not defined, it takes the height of the parent element. + * @default undefined + */ height: PropTypes.number, /** * Indicate which axis to display the left of the charts. @@ -272,6 +298,12 @@ LineChart.propTypes = { slotProps: PropTypes.object, slots: PropTypes.object, }), + /** + * The margin between the SVG and the drawing area. + * It's used for leaving some space for extra information such as the x- and y-axis or legend. + * Accepts an object with the optional properties: `top`, `bottom`, `left`, and `right`. + * @default object Depends on the charts type. + */ margin: PropTypes.shape({ bottom: PropTypes.number, left: PropTypes.number, @@ -417,7 +449,15 @@ LineChart.propTypes = { x: PropTypes.number, y: PropTypes.number, }), + /** + * The width of the chart in px. If not defined, it takes the width of the parent element. + * @default undefined + */ width: PropTypes.number, + /** + * The configuration of the x-axes. + * If not provided, a default axis config is used with id set to `DEFAULT_X_AXIS_KEY`. + */ xAxis: PropTypes.arrayOf( PropTypes.shape({ axisId: PropTypes.string, @@ -454,6 +494,10 @@ LineChart.propTypes = { valueFormatter: PropTypes.func, }), ), + /** + * The configuration of the y-axes. + * If not provided, a default axis config is used with id set to `DEFAULT_Y_AXIS_KEY`. + */ yAxis: PropTypes.arrayOf( PropTypes.shape({ axisId: PropTypes.string, diff --git a/packages/x-charts/src/PieChart/PieChart.tsx b/packages/x-charts/src/PieChart/PieChart.tsx index 6930d48eca81a..0d242655f582e 100644 --- a/packages/x-charts/src/PieChart/PieChart.tsx +++ b/packages/x-charts/src/PieChart/PieChart.tsx @@ -190,9 +190,21 @@ PieChart.propTypes = { * Color palette used to colorize multiple series. */ colors: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string), PropTypes.func]), + /** + * An array of objects that can be used to populate series and axes data using their `dataKey` property. + */ dataset: PropTypes.arrayOf(PropTypes.object), desc: PropTypes.string, + /** + * If `true`, the charts will not listen to the mouse move event. + * It might break interactive features, but will improve performance. + * @default false + */ disableAxisListener: PropTypes.bool, + /** + * The height of the chart in px. If not defined, it takes the height of the parent element. + * @default undefined + */ height: PropTypes.number, /** * Indicate which axis to display the left of the charts. @@ -242,6 +254,12 @@ PieChart.propTypes = { slotProps: PropTypes.object, slots: PropTypes.object, }), + /** + * The margin between the SVG and the drawing area. + * It's used for leaving some space for extra information such as the x- and y-axis or legend. + * Accepts an object with the optional properties: `top`, `bottom`, `left`, and `right`. + * @default object Depends on the charts type. + */ margin: PropTypes.shape({ bottom: PropTypes.number, left: PropTypes.number, @@ -401,7 +419,15 @@ PieChart.propTypes = { x: PropTypes.number, y: PropTypes.number, }), + /** + * The width of the chart in px. If not defined, it takes the width of the parent element. + * @default undefined + */ width: PropTypes.number, + /** + * The configuration of the x-axes. + * If not provided, a default axis config is used with id set to `DEFAULT_X_AXIS_KEY`. + */ xAxis: PropTypes.arrayOf( PropTypes.shape({ axisId: PropTypes.string, @@ -438,6 +464,10 @@ PieChart.propTypes = { valueFormatter: PropTypes.func, }), ), + /** + * The configuration of the y-axes. + * If not provided, a default axis config is used with id set to `DEFAULT_Y_AXIS_KEY`. + */ yAxis: PropTypes.arrayOf( PropTypes.shape({ axisId: PropTypes.string, diff --git a/packages/x-charts/src/ResponsiveChartContainer/index.tsx b/packages/x-charts/src/ResponsiveChartContainer/index.tsx index b59865c706af3..7c3775d890bd7 100644 --- a/packages/x-charts/src/ResponsiveChartContainer/index.tsx +++ b/packages/x-charts/src/ResponsiveChartContainer/index.tsx @@ -3,7 +3,6 @@ import useEnhancedEffect from '@mui/utils/useEnhancedEffect'; import ownerWindow from '@mui/utils/ownerWindow'; import { styled } from '@mui/material/styles'; import { ChartContainer, ChartContainerProps } from '../ChartContainer'; -import { MakeOptional } from '../models/helpers'; const useChartDimensions = ( inWidth?: number, @@ -90,7 +89,19 @@ const useChartDimensions = ( return [rootRef, inWidth ?? width, inHeight ?? height]; }; -export type ResponsiveChartContainerProps = MakeOptional; +export interface ResponsiveChartContainerProps + extends Omit { + /** + * The width of the chart in px. If not defined, it takes the width of the parent element. + * @default undefined + */ + width?: number; + /** + * The height of the chart in px. If not defined, it takes the height of the parent element. + * @default undefined + */ + height?: number; +} const ResizableContainer = styled('div', { name: 'MuiResponsiveChart', diff --git a/packages/x-charts/src/ScatterChart/ScatterChart.tsx b/packages/x-charts/src/ScatterChart/ScatterChart.tsx index 819e9568141d2..53dbbd16285a8 100644 --- a/packages/x-charts/src/ScatterChart/ScatterChart.tsx +++ b/packages/x-charts/src/ScatterChart/ScatterChart.tsx @@ -169,9 +169,21 @@ ScatterChart.propTypes = { * Color palette used to colorize multiple series. */ colors: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string), PropTypes.func]), + /** + * An array of objects that can be used to populate series and axes data using their `dataKey` property. + */ dataset: PropTypes.arrayOf(PropTypes.object), desc: PropTypes.string, + /** + * If `true`, the charts will not listen to the mouse move event. + * It might break interactive features, but will improve performance. + * @default false + */ disableAxisListener: PropTypes.bool, + /** + * The height of the chart in px. If not defined, it takes the height of the parent element. + * @default undefined + */ height: PropTypes.number, /** * Indicate which axis to display the left of the charts. @@ -221,6 +233,12 @@ ScatterChart.propTypes = { slotProps: PropTypes.object, slots: PropTypes.object, }), + /** + * The margin between the SVG and the drawing area. + * It's used for leaving some space for extra information such as the x- and y-axis or legend. + * Accepts an object with the optional properties: `top`, `bottom`, `left`, and `right`. + * @default object Depends on the charts type. + */ margin: PropTypes.shape({ bottom: PropTypes.number, left: PropTypes.number, @@ -348,7 +366,15 @@ ScatterChart.propTypes = { x: PropTypes.number, y: PropTypes.number, }), + /** + * The width of the chart in px. If not defined, it takes the width of the parent element. + * @default undefined + */ width: PropTypes.number, + /** + * The configuration of the x-axes. + * If not provided, a default axis config is used with id set to `DEFAULT_X_AXIS_KEY`. + */ xAxis: PropTypes.arrayOf( PropTypes.shape({ axisId: PropTypes.string, @@ -385,6 +411,10 @@ ScatterChart.propTypes = { valueFormatter: PropTypes.func, }), ), + /** + * The configuration of the y-axes. + * If not provided, a default axis config is used with id set to `DEFAULT_Y_AXIS_KEY`. + */ yAxis: PropTypes.arrayOf( PropTypes.shape({ axisId: PropTypes.string, diff --git a/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx b/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx index 18a71a0c0c67b..eadab90079b9b 100644 --- a/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx +++ b/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx @@ -233,10 +233,28 @@ SparkLineChart.propTypes = { * Data to plot. */ data: PropTypes.arrayOf(PropTypes.number).isRequired, + /** + * An array of objects that can be used to populate series and axes data using their `dataKey` property. + */ dataset: PropTypes.arrayOf(PropTypes.object), desc: PropTypes.string, + /** + * If `true`, the charts will not listen to the mouse move event. + * It might break interactive features, but will improve performance. + * @default false + */ disableAxisListener: PropTypes.bool, + /** + * The height of the chart in px. If not defined, it takes the height of the parent element. + * @default undefined + */ height: PropTypes.number, + /** + * The margin between the SVG and the drawing area. + * It's used for leaving some space for extra information such as the x- and y-axis or legend. + * Accepts an object with the optional properties: `top`, `bottom`, `left`, and `right`. + * @default object Depends on the charts type. + */ margin: PropTypes.shape({ bottom: PropTypes.number, left: PropTypes.number, @@ -296,6 +314,10 @@ SparkLineChart.propTypes = { x: PropTypes.number, y: PropTypes.number, }), + /** + * The width of the chart in px. If not defined, it takes the width of the parent element. + * @default undefined + */ width: PropTypes.number, /** * The xAxis configuration. diff --git a/packages/x-charts/src/context/CartesianContextProvider.tsx b/packages/x-charts/src/context/CartesianContextProvider.tsx index 65bf12143e5e6..3d826e060ce2d 100644 --- a/packages/x-charts/src/context/CartesianContextProvider.tsx +++ b/packages/x-charts/src/context/CartesianContextProvider.tsx @@ -29,8 +29,19 @@ import { MakeOptional } from '../models/helpers'; import { getTickNumber } from '../hooks/useTicks'; export type CartesianContextProviderProps = { + /** + * The configuration of the x-axes. + * If not provided, a default axis config is used with id set to `DEFAULT_X_AXIS_KEY`. + */ xAxis?: MakeOptional[]; + /** + * The configuration of the y-axes. + * If not provided, a default axis config is used with id set to `DEFAULT_Y_AXIS_KEY`. + */ yAxis?: MakeOptional[]; + /** + * An array of objects that can be used to populate series and axes data using their `dataKey` property. + */ dataset?: DatasetType; children: React.ReactNode; }; @@ -57,15 +68,24 @@ type DefaultizedAxisConfig = { export const CartesianContext = React.createContext<{ /** - * Mapping from axis key to scaling function + * Mapping from x-axis key to scaling configuration. */ xAxis: { DEFAULT_X_AXIS_KEY: AxisDefaultized; } & DefaultizedAxisConfig; + /** + * Mapping from y-axis key to scaling configuration. + */ yAxis: { DEFAULT_X_AXIS_KEY: AxisDefaultized; } & DefaultizedAxisConfig; + /** + * The x-axes IDs sorted by order they got provided. + */ xAxisIds: string[]; + /** + * The y-axes IDs sorted by order they got provided. + */ yAxisIds: string[]; // @ts-ignore }>({ xAxis: {}, yAxis: {}, xAxisIds: [], yAxisIds: [] }); @@ -300,7 +320,14 @@ CartesianContextProvider.propTypes = { // | To update them edit the TypeScript types and run "yarn proptypes" | // ---------------------------------------------------------------------- children: PropTypes.node, + /** + * An array of objects that can be used to populate series and axes data using their `dataKey` property. + */ dataset: PropTypes.arrayOf(PropTypes.object), + /** + * The configuration of the x-axes. + * If not provided, a default axis config is used with id set to `DEFAULT_X_AXIS_KEY`. + */ xAxis: PropTypes.arrayOf( PropTypes.shape({ axisId: PropTypes.string, @@ -337,6 +364,10 @@ CartesianContextProvider.propTypes = { valueFormatter: PropTypes.func, }), ), + /** + * The configuration of the y-axes. + * If not provided, a default axis config is used with id set to `DEFAULT_Y_AXIS_KEY`. + */ yAxis: PropTypes.arrayOf( PropTypes.shape({ axisId: PropTypes.string, diff --git a/packages/x-charts/src/context/DrawingProvider.tsx b/packages/x-charts/src/context/DrawingProvider.tsx index ff425a21b8b63..4fd46723cbd09 100644 --- a/packages/x-charts/src/context/DrawingProvider.tsx +++ b/packages/x-charts/src/context/DrawingProvider.tsx @@ -12,11 +12,29 @@ export interface DrawingProviderProps extends LayoutConfig { * Defines the area in which it is possible to draw the charts. */ export type DrawingArea = { + /** + * The gap between the left border of the SVG and the drawing area. + */ left: number; + /** + * The gap between the top border of the SVG and the drawing area. + */ top: number; + /** + * The gap between the bottom border of the SVG and the drawing area. + */ bottom: number; + /** + * The gap between the right border of the SVG and the drawing area. + */ right: number; + /** + * The width of the drawing area. + */ width: number; + /** + * The height of the drawing area. + */ height: number; }; @@ -52,6 +70,12 @@ DrawingProvider.propTypes = { // ---------------------------------------------------------------------- children: PropTypes.node, height: PropTypes.number.isRequired, + /** + * The margin between the SVG and the drawing area. + * It's used for leaving some space for extra information such as the x- and y-axis or legend. + * Accepts an object with the optional properties: `top`, `bottom`, `left`, and `right`. + * @default object Depends on the charts type. + */ margin: PropTypes.shape({ bottom: PropTypes.number, left: PropTypes.number, diff --git a/packages/x-charts/src/context/HighlightProvider.tsx b/packages/x-charts/src/context/HighlightProvider.tsx index f586da23334e7..346fe1b608f7a 100644 --- a/packages/x-charts/src/context/HighlightProvider.tsx +++ b/packages/x-charts/src/context/HighlightProvider.tsx @@ -11,7 +11,21 @@ export type HighlightOptions = 'none' | 'item' | 'series'; export type FadeOptions = 'none' | 'series' | 'global'; export type HighlightScope = { + /** + * The scope of highlighted elements. + * - 'none': no highlight. + * - 'item': only highlight the item. + * - 'series': highlight all elements of the same series. + * @default 'none' + */ highlighted: HighlightOptions; + /** + * The scope of faded elements. + * - 'none': no fading. + * - 'series': only fade element of the same series. + * - 'global': fade all elements that are not highlighted. + * @default 'none' + */ faded: FadeOptions; }; type HighlighActions = @@ -26,6 +40,9 @@ type HighlighActions = }; type HighlighState = { + /** + * The item that triggers the highlight state. + */ item: null | ItemHighlighData; scope: HighlightScope; dispatch: React.Dispatch; diff --git a/packages/x-charts/src/context/InteractionProvider.tsx b/packages/x-charts/src/context/InteractionProvider.tsx index ca638fb0695f0..dabe66abd9968 100644 --- a/packages/x-charts/src/context/InteractionProvider.tsx +++ b/packages/x-charts/src/context/InteractionProvider.tsx @@ -33,7 +33,13 @@ type InteractionActions = }; type InteractionState = { + /** + * The item currently interacting. + */ item: null | ItemInteractionData; + /** + * The x- and y-axes currently interacting. + */ axis: AxisInteractionData; dispatch: React.Dispatch; }; diff --git a/packages/x-charts/src/context/SeriesContextProvider.tsx b/packages/x-charts/src/context/SeriesContextProvider.tsx index 1833b4fd51ebe..b657e250cd00c 100644 --- a/packages/x-charts/src/context/SeriesContextProvider.tsx +++ b/packages/x-charts/src/context/SeriesContextProvider.tsx @@ -16,6 +16,11 @@ import { ChartsColorPalette, blueberryTwilightPalette } from '../colorPalettes'; export type SeriesContextProviderProps = { dataset?: DatasetType; + /** + * 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. + */ series: AllSeriesType[]; /** * Color palette used to colorize multiple series. diff --git a/packages/x-charts/src/internals/components/ChartsText.tsx b/packages/x-charts/src/internals/components/ChartsText.tsx index 5f06824c987e4..7f5db300c97b5 100644 --- a/packages/x-charts/src/internals/components/ChartsText.tsx +++ b/packages/x-charts/src/internals/components/ChartsText.tsx @@ -22,7 +22,7 @@ interface GetWordsByLinesParams { */ style?: ChartsTextStyle; /** - * If true, the line width is computed. + * If `true`, the line width is computed. * @default false */ needsComputation?: boolean; diff --git a/packages/x-charts/src/internals/geometry.ts b/packages/x-charts/src/internals/geometry.ts index eb2c6b3ff8c39..43fd024cacc39 100644 --- a/packages/x-charts/src/internals/geometry.ts +++ b/packages/x-charts/src/internals/geometry.ts @@ -6,8 +6,8 @@ let warnedOnce = false; * Return the minimal translation along the x-axis to avoid overflow of a rectangle of a given width, height, and rotation. * This assumes that all rectangles have the same height and angle between -90 and 90. * Otherwise it would be problematic because you need the height/width of the next rectangle to do the correct computation. - * @param width the side along the x axis. - * @param height the side along the y axis. + * @param width the side along the x-axis. + * @param height the side along the y-axis. * @param angle the rotation in degrees. */ export function getMinXTranslation(width: number, height: number, angle: number = 0) { diff --git a/packages/x-charts/src/models/axis.ts b/packages/x-charts/src/models/axis.ts index ee361350f30e9..540cf3472e91e 100644 --- a/packages/x-charts/src/models/axis.ts +++ b/packages/x-charts/src/models/axis.ts @@ -185,12 +185,26 @@ interface AxisScaleConfig { } export type AxisConfig = { + /** + * Id used to identify the axis. + */ id: string; + /** + * The minimal value of the domain. + * If not provided, it gets computed to display the entire chart data. + */ min?: number | Date; + /** + * The maximal value of the domain. + * If not provided, it gets computed to display the entire chart data. + */ max?: number | Date; + /** + * The data used by `'band'` and `'point'` scales. + */ data?: V[]; /** - * The key used to retrieve data from the dataset prop. + * The key used to retrieve `data` from the `dataset` prop. */ dataKey?: string; valueFormatter?: (value: V) => string; @@ -207,6 +221,9 @@ export type AxisDefaultized = Omit< 'scaleType' > & AxisScaleConfig[S] & { + /** + * An indication of the expected number of ticks. + */ tickNumber: number; }; diff --git a/packages/x-charts/src/models/layout.ts b/packages/x-charts/src/models/layout.ts index 85f09550b9f46..5cf2926569e5a 100644 --- a/packages/x-charts/src/models/layout.ts +++ b/packages/x-charts/src/models/layout.ts @@ -8,5 +8,11 @@ export interface CardinalDirections { export type LayoutConfig = { width: number; height: number; + /** + * The margin between the SVG and the drawing area. + * It's used for leaving some space for extra information such as the x- and y-axis or legend. + * Accepts an object with the optional properties: `top`, `bottom`, `left`, and `right`. + * @default object Depends on the charts type. + */ margin?: Partial>; }; diff --git a/packages/x-charts/src/models/seriesType/common.ts b/packages/x-charts/src/models/seriesType/common.ts index 39817459d9e0a..03cad304dbed2 100644 --- a/packages/x-charts/src/models/seriesType/common.ts +++ b/packages/x-charts/src/models/seriesType/common.ts @@ -16,13 +16,29 @@ export type CommonSeriesType = { export type CommonDefaultizedProps = 'id' | 'valueFormatter' | 'data'; export type CartesianSeriesType = { + /** + * The id of the x-axis used to render the series. + */ xAxisKey?: string; + /** + * The id of the y-axis used to render the series. + */ yAxisKey?: string; }; export type StackableSeriesType = { + /** + * The key that identifies the stacking group. + * Series with the same `stack` property will be stacked together. + */ stack?: string; + /** + * Defines how stacked series handle negative values. + */ stackOffset?: StackOffsetType; + /** + * The order in which series' of the same group are stacked together. + */ stackOrder?: StackOrderType; }; diff --git a/scripts/x-charts.exports.json b/scripts/x-charts.exports.json index 84ced50c79121..cf70eea0bae85 100644 --- a/scripts/x-charts.exports.json +++ b/scripts/x-charts.exports.json @@ -117,7 +117,7 @@ { "name": "PieValueType", "kind": "TypeAlias" }, { "name": "referenceLineClasses", "kind": "Variable" }, { "name": "ResponsiveChartContainer", "kind": "Variable" }, - { "name": "ResponsiveChartContainerProps", "kind": "TypeAlias" }, + { "name": "ResponsiveChartContainerProps", "kind": "Interface" }, { "name": "ScaleName", "kind": "TypeAlias" }, { "name": "Scatter", "kind": "Function" }, { "name": "ScatterChart", "kind": "Variable" }, From 02ce6bea509f5ffc8e5f23c71a577dfade439b02 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Wed, 8 Nov 2023 22:35:58 +0100 Subject: [PATCH 07/13] [core] Fix GitHub title tag consistency --- CHANGELOG.md | 10 +++++----- changelogOld/CHANGELOG.v4.md | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37c30862ecaa2..287579f178bde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -357,7 +357,7 @@ Same changes as in `@mui/x-date-pickers@6.16.1`, plus: - [core] Fix casing consistency with legal and marketing content @oliviertassinari - [core] Revert the link in the priority support ticket description (#10517) @michelengelen -- [CHANGELOG] Polish image @oliviertassinari +- [changelog] Polish image @oliviertassinari ## 6.16.0 @@ -1149,7 +1149,7 @@ Same changes as in `@mui/x-date-pickers@6.10.1`. ### Core - [core] Add `validate` command (#9714) @romgrk -- [CHANGELOG] Update generator to new format @oliviertassinari +- [changelog] Update generator to new format @oliviertassinari ## 6.10.0 @@ -1207,7 +1207,7 @@ Same changes as in `@mui/x-date-pickers@6.10.0`. - [core] Disambiguate eslint plugin name @oliviertassinari - [core] Update priority support issue template and prompt (#9574) @DanailH -- [CHANGELOG] Clarify each plan (#9446) @oliviertassinari +- [changelog] Clarify each plan (#9446) @oliviertassinari - [license] Fix error terminology (#9614) @oliviertassinari ## 6.9.2 @@ -1356,8 +1356,8 @@ Same changes as in `@mui/x-date-pickers@6.9.1`. - [core] Fix priority support prompt action (#9472) @DanailH - [core] Update `uses` for priority support action (#9480) @DanailH - [core] Bumb update monorepo (#9476) @alexfauquette -- [CHANGELOG] Fix media quality (#9439) @oliviertassinari -- [CHANGELOG] Remove height img attribute @oliviertassinari +- [changelog] Fix media quality (#9439) @oliviertassinari +- [changelog] Remove height img attribute @oliviertassinari - [test] Skip flaky row pinning tests in JSDOM (#9511) @cherniavskii ## 6.9.0 diff --git a/changelogOld/CHANGELOG.v4.md b/changelogOld/CHANGELOG.v4.md index b5559f2089792..47a7da8d933fd 100644 --- a/changelogOld/CHANGELOG.v4.md +++ b/changelogOld/CHANGELOG.v4.md @@ -1615,7 +1615,7 @@ Big thanks to the 5 contributors who made this release possible. Here are some h - [docs] Fix imports for x-grid-data-generator (#887) @DanailH - [docs] Skip download of playwright for docs @oliviertassinari -- [CHANGELOG] Polish @oliviertassinari +- [changelog] Polish @oliviertassinari ### core @@ -1674,7 +1674,7 @@ Big thanks to the 2 contributors who made this release possible. Here are some h - [core] Update peer dependencies for React 17 (#814) @DanailH - [core] Batch small changes (#800) @oliviertassinari -- [CHANGELOG] Use the format of the main repository @oliviertassinari +- [changelog] Use the format of the main repository @oliviertassinari ## [4.0.0-alpha.14](https://github.com/mui/mui-x/compare/v4.0.0-alpha.13...v4.0.0-alpha.14) From 0590e6f0922ace8e17303ce4117065db285bf215 Mon Sep 17 00:00:00 2001 From: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com> Date: Thu, 9 Nov 2023 09:31:57 +0100 Subject: [PATCH 08/13] [docs] Document how to hide the legend (#10951) (#10954) --- docs/data/charts/legend/HiddenLegend.js | 38 +++++++++++++++++++ docs/data/charts/legend/HiddenLegend.tsx | 38 +++++++++++++++++++ .../charts/legend/HiddenLegend.tsx.preview | 14 +++++++ docs/data/charts/legend/legend.md | 6 +++ .../src/ChartsLegend/ChartsLegend.tsx | 1 + 5 files changed, 97 insertions(+) create mode 100644 docs/data/charts/legend/HiddenLegend.js create mode 100644 docs/data/charts/legend/HiddenLegend.tsx create mode 100644 docs/data/charts/legend/HiddenLegend.tsx.preview diff --git a/docs/data/charts/legend/HiddenLegend.js b/docs/data/charts/legend/HiddenLegend.js new file mode 100644 index 0000000000000..80879da5f9bf5 --- /dev/null +++ b/docs/data/charts/legend/HiddenLegend.js @@ -0,0 +1,38 @@ +import * as React from 'react'; +import Stack from '@mui/material/Stack'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import Checkbox from '@mui/material/Checkbox'; +import { PieChart } from '@mui/x-charts/PieChart'; + +const series = [ + { + data: [ + { id: 0, value: 10, label: 'series A' }, + { id: 1, value: 15, label: 'series B' }, + { id: 2, value: 20, label: 'series C' }, + ], + }, +]; + +export default function HiddenLegend() { + const [isHidden, setIsHidden] = React.useState(false); + + return ( + + setIsHidden(event.target.checked)} /> + } + label="hide the legend" + labelPlacement="end" + /> + + + ); +} diff --git a/docs/data/charts/legend/HiddenLegend.tsx b/docs/data/charts/legend/HiddenLegend.tsx new file mode 100644 index 0000000000000..80879da5f9bf5 --- /dev/null +++ b/docs/data/charts/legend/HiddenLegend.tsx @@ -0,0 +1,38 @@ +import * as React from 'react'; +import Stack from '@mui/material/Stack'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import Checkbox from '@mui/material/Checkbox'; +import { PieChart } from '@mui/x-charts/PieChart'; + +const series = [ + { + data: [ + { id: 0, value: 10, label: 'series A' }, + { id: 1, value: 15, label: 'series B' }, + { id: 2, value: 20, label: 'series C' }, + ], + }, +]; + +export default function HiddenLegend() { + const [isHidden, setIsHidden] = React.useState(false); + + return ( + + setIsHidden(event.target.checked)} /> + } + label="hide the legend" + labelPlacement="end" + /> + + + ); +} diff --git a/docs/data/charts/legend/HiddenLegend.tsx.preview b/docs/data/charts/legend/HiddenLegend.tsx.preview new file mode 100644 index 0000000000000..52019cf368ffa --- /dev/null +++ b/docs/data/charts/legend/HiddenLegend.tsx.preview @@ -0,0 +1,14 @@ + setIsHidden(event.target.checked)} /> + } + label="hide the legend" + labelPlacement="end" +/> + \ No newline at end of file diff --git a/docs/data/charts/legend/legend.md b/docs/data/charts/legend/legend.md index d314dddb3e929..063e315f53f03 100644 --- a/docs/data/charts/legend/legend.md +++ b/docs/data/charts/legend/legend.md @@ -30,6 +30,12 @@ By default, the legend is placed above the charts. {{"demo": "LegendPositionNoSnap.js", "hideToolbar": true, "bg": "inline"}} +### Hidding + +You can hide the legend with the property `slotProps.legend.hidden`. + +{{"demo": "HiddenLegend.js"}} + ### Dimensions Inside the legend, you can customize the pixel value of the width and height of the mark with the `itemMarkWidth` and `itemMarkHeight` props. diff --git a/packages/x-charts/src/ChartsLegend/ChartsLegend.tsx b/packages/x-charts/src/ChartsLegend/ChartsLegend.tsx index ef0e1b0624996..b16ea60cf77fe 100644 --- a/packages/x-charts/src/ChartsLegend/ChartsLegend.tsx +++ b/packages/x-charts/src/ChartsLegend/ChartsLegend.tsx @@ -28,6 +28,7 @@ export type ChartsLegendProps = { classes?: Partial; /** * Set to true to hide the legend. + * @default false */ hidden?: boolean; /** From 43df40be20e9d603ddc48030c629c0d83f5f82f4 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskii Date: Thu, 9 Nov 2023 10:37:26 +0100 Subject: [PATCH 09/13] [DataGridPremium] Render aggregation label when `renderHeader` is used (#10961) --- .../src/components/GridAggregationHeader.tsx | 24 +++++++++++----- .../aggregation/wrapColumnWithAggregation.tsx | 12 ++++---- test/regressions/index.test.js | 28 ++++--------------- 3 files changed, 29 insertions(+), 35 deletions(-) diff --git a/packages/grid/x-data-grid-premium/src/components/GridAggregationHeader.tsx b/packages/grid/x-data-grid-premium/src/components/GridAggregationHeader.tsx index 59dff478d8afc..c2dd3b239ed5d 100644 --- a/packages/grid/x-data-grid-premium/src/components/GridAggregationHeader.tsx +++ b/packages/grid/x-data-grid-premium/src/components/GridAggregationHeader.tsx @@ -9,6 +9,7 @@ import { GridColumnHeaderParams, GridColumnHeaderTitle, } from '@mui/x-data-grid'; +import type { GridBaseColDef } from '@mui/x-data-grid/internals'; import { getAggregationFunctionLabel } from '../hooks/features/aggregation/gridAggregationUtils'; import { useGridApiContext } from '../hooks/utils/useGridApiContext'; import { useGridRootProps } from '../hooks/utils/useGridRootProps'; @@ -66,8 +67,13 @@ const useUtilityClasses = (ownerState: OwnerState) => { return composeClasses(slots, getDataGridUtilityClass, classes); }; -function GridAggregationHeader(props: GridColumnHeaderParams) { - const { colDef, aggregation } = props; +function GridAggregationHeader( + props: GridColumnHeaderParams & { + renderHeader: GridBaseColDef['renderHeader']; + }, +) { + const { renderHeader, ...params } = props; + const { colDef, aggregation } = params; const apiRef = useGridApiContext(); const rootProps = useGridRootProps(); @@ -86,11 +92,15 @@ function GridAggregationHeader(props: GridColumnHeaderParams) { return ( - + {renderHeader ? ( + renderHeader(params) + ) : ( + + )} {aggregationLabel} diff --git a/packages/grid/x-data-grid-premium/src/hooks/features/aggregation/wrapColumnWithAggregation.tsx b/packages/grid/x-data-grid-premium/src/hooks/features/aggregation/wrapColumnWithAggregation.tsx index 6ebb2d7531f1a..1e17be3bf312a 100644 --- a/packages/grid/x-data-grid-premium/src/hooks/features/aggregation/wrapColumnWithAggregation.tsx +++ b/packages/grid/x-data-grid-premium/src/hooks/features/aggregation/wrapColumnWithAggregation.tsx @@ -177,11 +177,13 @@ const getWrappedRenderHeader: ColumnPropertyWrapper<'renderHeader'> = ({ aggregationRule, }) => { const wrappedRenderHeader: GridBaseColDef['renderHeader'] = (params) => { - const aggregation = { aggregationRule }; - if (renderHeader) { - return renderHeader({ ...params, aggregation }); - } - return ; + return ( + + ); }; return wrappedRenderHeader; diff --git a/test/regressions/index.test.js b/test/regressions/index.test.js index 0fda626db48a8..7e8a390d1cbe8 100644 --- a/test/regressions/index.test.js +++ b/test/regressions/index.test.js @@ -101,29 +101,11 @@ async function main() { // Move cursor offscreen to not trigger unwanted hover effects. page.mouse.move(0, 0); - const pathsToNotWaitForFlagCDN = [ - '/docs-data-grid-filtering/HeaderFilteringDataGridPro', // No flag column - '/docs-data-grid-filtering/CustomHeaderFilterDataGridPro', // No flag column - '/docs-data-grid-filtering/CustomHeaderFilterSingleDataGridPro', // No flag column - '/docs-data-grid-filtering/SimpleHeaderFilteringDataGridPro', // No flag column - '/docs-data-grid-filtering/ServerFilterGrid', // No content rendered - '/docs-data-grid-filtering/CustomMultiValueOperator', // No content rendered - '/docs-data-grid-filtering/QuickFilteringInitialize', // No content rendered - '/docs-data-grid-sorting/FullyCustomSortComparator', // No flag column - '/docs-data-grid-sorting/ServerSortingGrid', // No flag column - '/docs-data-grid-filtering/QuickFilteringExcludeHiddenColumns', // No flag column - '/docs-data-grid-filtering/QuickFilteringDiacritics', // No flag column - ]; - - if ( - /^\/docs-data-grid-(filtering|sorting)/.test(pathURL) && - !pathsToNotWaitForFlagCDN.includes(pathURL) - ) { - // Wait for the flags to load - await page.waitForResponse((response) => - response.url().startsWith('https://flagcdn.com'), - ); - } + // Wait for the flags to load + await page.waitForFunction(() => { + const images = Array.from(document.querySelectorAll('img')); + return images.every((img) => img.complete); + }); if (/^\docs-charts-.*/.test(pathURL)) { // Run one tick of the clock to get the final animation state From 9be9e228ae43cec53e283787e36e46966310ace6 Mon Sep 17 00:00:00 2001 From: Michel Engelen <32863416+michelengelen@users.noreply.github.com> Date: Thu, 9 Nov 2023 12:18:43 +0100 Subject: [PATCH 10/13] [release] v6.18.1 (#10960) Signed-off-by: Michel Engelen <32863416+michelengelen@users.noreply.github.com> Co-authored-by: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com> Co-authored-by: Lukas Co-authored-by: Andrew Cherniavskii Co-authored-by: Bilal Shafi --- CHANGELOG.md | 58 +++++++++++++++++++ package.json | 2 +- .../grid/x-data-grid-generator/package.json | 4 +- .../grid/x-data-grid-premium/package.json | 6 +- packages/grid/x-data-grid-pro/package.json | 4 +- packages/grid/x-data-grid/package.json | 2 +- packages/x-charts/package.json | 2 +- packages/x-date-pickers-pro/package.json | 4 +- packages/x-date-pickers/package.json | 2 +- 9 files changed, 71 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 287579f178bde..f4a9551001619 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,64 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 6.18.1 + +_Nov 9, 2023_ + +We'd like to offer a big thanks to the 9 contributors who made this release possible. Here are some highlights ✨: + +- ✨ Fix aggregation label not showing when `renderHeader` is used (#10961) @cherniavskii +- 📘 Server side data source [early documentation](https://mui.com/x/react-data-grid/server-side-data/) published +- 📈 `` component is now available +- 🐞 Bugfixes +- 📚 Documentation improvements + +### Data Grid + +#### `@mui/x-data-grid@6.18.1` + +- [DataGrid] Fix cell value type in quick filtering v7 (#10884) @cherniavskii +- [DataGrid] Fix keyboard navigation for actions cell with disabled buttons (#10947) @michelengelen +- [DataGrid] Fix `undefined` slot values (#10934) @romgrk + +#### `@mui/x-data-grid-pro@6.18.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan') + +Same changes as in `@mui/x-data-grid@6.18.1`, plus: + +- [DataGridPro] Add data source interface and basic documentation (#10543) @MBilalShafi + +#### `@mui/x-data-grid-premium@6.18.1` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan') + +Same changes as in `@mui/x-data-grid-pro@6.18.1`, plus: + +- [DataGridPremium] Render aggregation label when `renderHeader` is used (#10961) @cherniavskii + +### Date Pickers + +#### `@mui/x-date-pickers@6.18.1` + +- [fields] Fix multi input date time field section selection (#10915) @noraleonte +- [pickers] Always use up-to-date `defaultView` (#10889) @LukasTy + +#### `@mui/x-date-pickers-pro@6.18.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan') + +Same changes as in `@mui/x-date-pickers@6.18.1`. + +### Charts / `@mui/x-charts@6.18.1` + +- [charts] Add `` component (#10597) @wascou +- [charts] Improve properties JSDoc (#10931) @alexfauquette + +### Docs + +- [docs] Fix charts docs as stable (#10888) @alexfauquette +- [docs] Document how to hide the legend (#10954) @alexfauquette + +### Core + +- [core] Adds new alpha version to version select on the docs (#10944) @michelengelen +- [core] Fix GitHub title tag consistency @oliviertassinari + ## 6.18.0 _Nov 3, 2023_ diff --git a/package.json b/package.json index 9181bdd075dff..1942ae2c6fe14 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "6.18.0", + "version": "6.18.1", "private": true, "scripts": { "start": "yarn && yarn docs:dev", diff --git a/packages/grid/x-data-grid-generator/package.json b/packages/grid/x-data-grid-generator/package.json index 3d2635b260fa8..f69b1a8ff8b77 100644 --- a/packages/grid/x-data-grid-generator/package.json +++ b/packages/grid/x-data-grid-generator/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-data-grid-generator", - "version": "6.18.0", + "version": "6.18.1", "description": "Generate fake data for demo purposes only.", "author": "MUI Team", "main": "src/index.ts", @@ -32,7 +32,7 @@ "dependencies": { "@babel/runtime": "^7.23.2", "@mui/base": "^5.0.0-beta.22", - "@mui/x-data-grid-premium": "6.18.0", + "@mui/x-data-grid-premium": "6.18.1", "chance": "^1.1.11", "clsx": "^2.0.0", "lru-cache": "^7.18.3" diff --git a/packages/grid/x-data-grid-premium/package.json b/packages/grid/x-data-grid-premium/package.json index 33ed5bb10dd07..f8b3bc7a14c17 100644 --- a/packages/grid/x-data-grid-premium/package.json +++ b/packages/grid/x-data-grid-premium/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-data-grid-premium", - "version": "6.18.0", + "version": "6.18.1", "description": "The Premium plan edition of the data grid component (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -44,8 +44,8 @@ "dependencies": { "@babel/runtime": "^7.23.2", "@mui/utils": "^5.14.16", - "@mui/x-data-grid": "6.18.0", - "@mui/x-data-grid-pro": "6.18.0", + "@mui/x-data-grid": "6.18.1", + "@mui/x-data-grid-pro": "6.18.1", "@mui/x-license-pro": "6.10.2", "@types/format-util": "^1.0.3", "clsx": "^2.0.0", diff --git a/packages/grid/x-data-grid-pro/package.json b/packages/grid/x-data-grid-pro/package.json index abedce9de2c20..2506e28bcf646 100644 --- a/packages/grid/x-data-grid-pro/package.json +++ b/packages/grid/x-data-grid-pro/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-data-grid-pro", - "version": "6.18.0", + "version": "6.18.1", "description": "The Pro plan edition of the data grid component (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -44,7 +44,7 @@ "dependencies": { "@babel/runtime": "^7.23.2", "@mui/utils": "^5.14.16", - "@mui/x-data-grid": "6.18.0", + "@mui/x-data-grid": "6.18.1", "@mui/x-license-pro": "6.10.2", "@types/format-util": "^1.0.3", "clsx": "^2.0.0", diff --git a/packages/grid/x-data-grid/package.json b/packages/grid/x-data-grid/package.json index c319be66aca0d..fd4bb44b9f413 100644 --- a/packages/grid/x-data-grid/package.json +++ b/packages/grid/x-data-grid/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-data-grid", - "version": "6.18.0", + "version": "6.18.1", "description": "The community edition of the data grid component (MUI X).", "author": "MUI Team", "main": "src/index.ts", diff --git a/packages/x-charts/package.json b/packages/x-charts/package.json index 43bfbf829840f..6137141d5513e 100644 --- a/packages/x-charts/package.json +++ b/packages/x-charts/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-charts", - "version": "6.18.0", + "version": "6.18.1", "description": "The community edition of the charts components (MUI X).", "author": "MUI Team", "main": "./src/index.js", diff --git a/packages/x-date-pickers-pro/package.json b/packages/x-date-pickers-pro/package.json index 539731747572b..5bd30a62a743f 100644 --- a/packages/x-date-pickers-pro/package.json +++ b/packages/x-date-pickers-pro/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-date-pickers-pro", - "version": "6.18.0", + "version": "6.18.1", "description": "The commercial edition of the date picker components (MUI X).", "author": "MUI Team", "main": "src/index.ts", @@ -44,7 +44,7 @@ "@babel/runtime": "^7.23.2", "@mui/base": "^5.0.0-beta.22", "@mui/utils": "^5.14.16", - "@mui/x-date-pickers": "6.18.0", + "@mui/x-date-pickers": "6.18.1", "@mui/x-license-pro": "6.10.2", "clsx": "^2.0.0", "prop-types": "^15.8.1", diff --git a/packages/x-date-pickers/package.json b/packages/x-date-pickers/package.json index aeb2ce0fe8da3..a38ec73bca611 100644 --- a/packages/x-date-pickers/package.json +++ b/packages/x-date-pickers/package.json @@ -1,6 +1,6 @@ { "name": "@mui/x-date-pickers", - "version": "6.18.0", + "version": "6.18.1", "description": "The community edition of the date picker components (MUI X).", "author": "MUI Team", "main": "src/index.ts", From 9cd93ceda1ac94829290e9191259b6d93958a086 Mon Sep 17 00:00:00 2001 From: Bilal Shafi Date: Thu, 9 Nov 2023 19:40:16 +0500 Subject: [PATCH 11/13] [l10n] Improve Czech (cs-CZ) locale (#10968) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ľuboš Repka <40338867+luborepka@users.noreply.github.com> --- packages/grid/x-data-grid/src/locales/csCZ.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grid/x-data-grid/src/locales/csCZ.ts b/packages/grid/x-data-grid/src/locales/csCZ.ts index a553a6a7661b1..b4eafa7dab0d9 100644 --- a/packages/grid/x-data-grid/src/locales/csCZ.ts +++ b/packages/grid/x-data-grid/src/locales/csCZ.ts @@ -174,8 +174,8 @@ const csCZGrid: Partial = { actionsCellMore: 'více', // Column pinning text - pinToLeft: 'Připnout na levo', - pinToRight: 'Připnout na pravo', + pinToLeft: 'Připnout vlevo', + pinToRight: 'Připnout vpravo', unpin: 'Odepnout', // Tree Data From 9ec35c44d0b0ab541d007568b92597846f33ad83 Mon Sep 17 00:00:00 2001 From: Lukas Date: Fri, 10 Nov 2023 12:44:39 +0200 Subject: [PATCH 12/13] [l10n] Add Basque (eu) locale and improve Spanish (es-ES) locale (#10985) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lajto 理德 <85128868+lajtomekadimon@users.noreply.github.com> Co-authored-by: David Andrés --- docs/data/date-pickers/localization/data.json | 10 ++- packages/x-date-pickers/src/locales/esES.ts | 18 ++-- packages/x-date-pickers/src/locales/eu.ts | 87 +++++++++++++++++++ packages/x-date-pickers/src/locales/index.ts | 1 + scripts/l10n.ts | 16 ++-- scripts/localeNames.js | 1 + scripts/x-date-pickers-pro.exports.json | 1 + scripts/x-date-pickers.exports.json | 1 + 8 files changed, 119 insertions(+), 16 deletions(-) create mode 100644 packages/x-date-pickers/src/locales/eu.ts diff --git a/docs/data/date-pickers/localization/data.json b/docs/data/date-pickers/localization/data.json index e4f077b2a1f49..2adcf451219a4 100644 --- a/docs/data/date-pickers/localization/data.json +++ b/docs/data/date-pickers/localization/data.json @@ -1,4 +1,12 @@ [ + { + "languageTag": "eu", + "importName": "eu", + "localeName": "Basque", + "missingKeysCount": 0, + "totalKeysCount": 37, + "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/eu.ts" + }, { "languageTag": "be-BY", "importName": "beBY", @@ -203,7 +211,7 @@ "languageTag": "es-ES", "importName": "esES", "localeName": "Spanish", - "missingKeysCount": 1, + "missingKeysCount": 0, "totalKeysCount": 37, "githubLink": "https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/locales/esES.ts" }, diff --git a/packages/x-date-pickers/src/locales/esES.ts b/packages/x-date-pickers/src/locales/esES.ts index e4cbf8c416438..c355724c62c79 100644 --- a/packages/x-date-pickers/src/locales/esES.ts +++ b/packages/x-date-pickers/src/locales/esES.ts @@ -42,8 +42,8 @@ const esESPickers: Partial> = { clockLabelText: (view, time, adapter) => `Seleccione ${views[view]}. ${ time === null - ? 'Sin tiempo seleccionado' - : `El tiempo seleccionado es ${adapter.format(time, 'fullTime')}` + ? 'No hay hora seleccionada' + : `La hora seleccionada es ${adapter.format(time, 'fullTime')}` }`, hoursClockNumberText: (hours) => `${hours} horas`, minutesClockNumberText: (minutes) => `${minutes} minutos`, @@ -61,17 +61,17 @@ const esESPickers: Partial> = { // Open picker labels openDatePickerDialogue: (value, utils) => value !== null && utils.isValid(value) - ? `Elige la fecha, la fecha elegida es ${utils.format(value, 'fullDate')}` - : 'Elige la fecha', + ? `Elige fecha, la fecha elegida es ${utils.format(value, 'fullDate')}` + : 'Elige fecha', openTimePickerDialogue: (value, utils) => value !== null && utils.isValid(value) - ? `Elige la hora, la hora elegido es ${utils.format(value, 'fullTime')}` - : 'Elige la hora', - // fieldClearLabel: 'Clear value', + ? `Elige hora, la hora elegida es ${utils.format(value, 'fullTime')}` + : 'Elige hora', + fieldClearLabel: 'Limpiar valor', // Table labels - timeTableLabel: 'elige la fecha', - dateTableLabel: 'elige la hora', + timeTableLabel: 'elige hora', + dateTableLabel: 'elige fecha', // Field section placeholders fieldYearPlaceholder: (params) => 'A'.repeat(params.digitAmount), diff --git a/packages/x-date-pickers/src/locales/eu.ts b/packages/x-date-pickers/src/locales/eu.ts new file mode 100644 index 0000000000000..d99e2febb7a18 --- /dev/null +++ b/packages/x-date-pickers/src/locales/eu.ts @@ -0,0 +1,87 @@ +import { PickersLocaleText } from './utils/pickersLocaleTextApi'; +import { getPickersLocalization } from './utils/getPickersLocalization'; +import { TimeViewWithMeridiem } from '../internals/models'; + +const views: Record = { + hours: 'orduak', + minutes: 'minutuak', + seconds: 'segunduak', + meridiem: 'meridianoa', +}; + +const euPickers: Partial> = { + // Calendar navigation + previousMonth: 'Azken hilabetea', + nextMonth: 'Hurrengo hilabetea', + + // View navigation + openPreviousView: 'azken bista ireki', + openNextView: 'hurrengo bista ireki', + calendarViewSwitchingButtonAriaLabel: (view) => + view === 'year' + ? 'urteko bista irekita dago, aldatu egutegi bistara' + : 'egutegi bista irekita dago, aldatu urteko bistara', + + // DateRange placeholders + start: 'Hasi', + end: 'Bukatu', + + // Action bar + cancelButtonLabel: 'Utxi', + clearButtonLabel: 'Garbitu', + okButtonLabel: 'OK', + todayButtonLabel: 'Gaur', + + // Toolbar titles + datePickerToolbarTitle: 'Data aukeratu', + dateTimePickerToolbarTitle: 'Data eta ordua aukeratu', + timePickerToolbarTitle: 'Ordua aukeratu', + dateRangePickerToolbarTitle: 'Data tartea aukeratu', + + // Clock labels + clockLabelText: (view, time, adapter) => + `Aukeratu ${views[view]}. ${ + time === null + ? 'Ez da ordurik aukertau' + : `Aukeratutako ordua ${adapter.format(time, 'fullTime')} da` + }`, + hoursClockNumberText: (hours) => `${hours} ordu`, + minutesClockNumberText: (minutes) => `${minutes} minutu`, + secondsClockNumberText: (seconds) => `${seconds} segundu`, + + // Digital clock labels + selectViewText: (view) => `Aukeratu ${views[view]}`, + + // Calendar labels + calendarWeekNumberHeaderLabel: 'Astea zenbakia', + calendarWeekNumberHeaderText: '#', + calendarWeekNumberAriaLabelText: (weekNumber) => `${weekNumber} astea`, + calendarWeekNumberText: (weekNumber) => `${weekNumber}`, + + // Open picker labels + openDatePickerDialogue: (value, utils) => + value !== null && utils.isValid(value) + ? `Data aukeratu, aukeratutako data ${utils.format(value, 'fullDate')} da` + : 'Data aukeratu', + openTimePickerDialogue: (value, utils) => + value !== null && utils.isValid(value) + ? `Ordua aukeratu, aukeratutako ordua ${utils.format(value, 'fullTime')} da` + : 'Ordua aukeratu', + fieldClearLabel: 'Balioa garbitu', + + // Table labels + timeTableLabel: 'ordua aukeratu', + dateTableLabel: 'data aukeratu', + + // Field section placeholders + fieldYearPlaceholder: (params) => 'Y'.repeat(params.digitAmount), + fieldMonthPlaceholder: (params) => (params.contentType === 'letter' ? 'MMMM' : 'MM'), + fieldDayPlaceholder: () => 'DD', + fieldWeekDayPlaceholder: (params) => (params.contentType === 'letter' ? 'EEEE' : 'EE'), + fieldHoursPlaceholder: () => 'hh', + fieldMinutesPlaceholder: () => 'mm', + fieldSecondsPlaceholder: () => 'ss', + fieldMeridiemPlaceholder: () => 'aa', +}; + +export const eu = getPickersLocalization(euPickers); diff --git a/packages/x-date-pickers/src/locales/index.ts b/packages/x-date-pickers/src/locales/index.ts index 610e3d41a476a..410f06361fae0 100644 --- a/packages/x-date-pickers/src/locales/index.ts +++ b/packages/x-date-pickers/src/locales/index.ts @@ -5,6 +5,7 @@ export * from './deDE'; export * from './elGR'; export * from './enUS'; export * from './esES'; +export * from './eu'; export * from './faIR'; export * from './fiFI'; export * from './frFR'; diff --git a/scripts/l10n.ts b/scripts/l10n.ts index 932119f26b745..25e9d2ceaee18 100644 --- a/scripts/l10n.ts +++ b/scripts/l10n.ts @@ -67,7 +67,7 @@ function plugin(existingTranslations: Translations): babel.PluginObj { } // Test if the variable name follows the pattern xxXXGrid or xxXXPickers - if (!/[a-z]{2}[A-Z]{2}(Grid|Pickers)/.test(node.id.name)) { + if (!/[a-z]{2}[A-Z]{2}|[a-z]{2}(Grid|Pickers)/.test(node.id.name)) { visitorPath.skip(); return; } @@ -164,7 +164,7 @@ function extractTranslations(translationsPath: string): [TranslationsByGroup, Tr function findLocales(localesDirectory: string, constantsPath: string) { const items = fse.readdirSync(localesDirectory); const locales: any[] = []; - const localeRegex = /^[a-z]{2}[A-Z]{2}/; + const localeRegex = /^[a-z]{2}[A-Z]{2}|^[a-z]{2}(?=.ts)/; items.forEach((item) => { const match = item.match(localeRegex); @@ -173,7 +173,10 @@ function findLocales(localesDirectory: string, constantsPath: string) { } const localePath = path.resolve(localesDirectory, item); - const code = match[0]; + if (fse.lstatSync(localePath).isDirectory()) { + return; + } + const code = match[0] || match[1]; if (constantsPath !== localePath) { // Ignore the locale used as a reference locales.push([localePath, code]); @@ -321,9 +324,10 @@ const generateDocReport = async ( return; } - const languageTag = `${importName.slice(0, 2).toLowerCase()}-${importName - .slice(2) - .toUpperCase()}`; + const languageTag = + importName.length > 2 + ? `${importName.slice(0, 2).toLowerCase()}-${importName.slice(2).toUpperCase()}` + : importName; const localeName = localeNames[languageTag]; if (localeName === undefined) { diff --git a/scripts/localeNames.js b/scripts/localeNames.js index f989f27b97c57..24ff47a663615 100644 --- a/scripts/localeNames.js +++ b/scripts/localeNames.js @@ -6,6 +6,7 @@ module.exports = { 'hy-AM': 'Armenian', 'az-AZ': 'Azerbaijani', 'bn-BD': 'Bangla', + eu: 'Basque', 'be-BY': 'Belarusian', 'bg-BG': 'Bulgarian', 'ca-ES': 'Catalan', diff --git a/scripts/x-date-pickers-pro.exports.json b/scripts/x-date-pickers-pro.exports.json index 42f2f6b4027ba..5002ac2590cdb 100644 --- a/scripts/x-date-pickers-pro.exports.json +++ b/scripts/x-date-pickers-pro.exports.json @@ -128,6 +128,7 @@ { "name": "elGR", "kind": "Variable" }, { "name": "enUS", "kind": "Variable" }, { "name": "esES", "kind": "Variable" }, + { "name": "eu", "kind": "Variable" }, { "name": "ExportedDateRangeCalendarProps", "kind": "Interface" }, { "name": "ExportedDigitalClockProps", "kind": "Interface" }, { "name": "ExportedMultiSectionDigitalClockSectionProps", "kind": "Interface" }, diff --git a/scripts/x-date-pickers.exports.json b/scripts/x-date-pickers.exports.json index 08052f41bf95f..9b3b709474868 100644 --- a/scripts/x-date-pickers.exports.json +++ b/scripts/x-date-pickers.exports.json @@ -98,6 +98,7 @@ { "name": "elGR", "kind": "Variable" }, { "name": "enUS", "kind": "Variable" }, { "name": "esES", "kind": "Variable" }, + { "name": "eu", "kind": "Variable" }, { "name": "ExportedDigitalClockProps", "kind": "Interface" }, { "name": "ExportedMultiSectionDigitalClockSectionProps", "kind": "Interface" }, { "name": "ExportedPickersCalendarHeaderProps", "kind": "TypeAlias" }, From 651e698658fad7eefdb573031c3bea702205e7e4 Mon Sep 17 00:00:00 2001 From: Lucas Hilgert <77863078+lhilgert9@users.noreply.github.com> Date: Mon, 13 Nov 2023 10:30:49 +0100 Subject: [PATCH 13/13] [docs] Fix Pickers CustomComponents Incorrect naming of a component in example (#11003) --- docs/data/date-pickers/custom-components/custom-components.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/date-pickers/custom-components/custom-components.md b/docs/data/date-pickers/custom-components/custom-components.md index edf7e96405d6f..55dde5af9d205 100644 --- a/docs/data/date-pickers/custom-components/custom-components.md +++ b/docs/data/date-pickers/custom-components/custom-components.md @@ -79,7 +79,7 @@ function MyApp() { ```jsx // ✅ The `toolbar` slot is defined only once, it will never remount. -const CustomActionBar = ({ name, setName }) => ( +const CustomToolbar = ({ name, setName }) => ( setName(event.target.value)} /> );