From b60dc29643ad13a362d7d050f0f7263a0b302cf1 Mon Sep 17 00:00:00 2001 From: Jose C Quintas Jr Date: Mon, 16 Sep 2024 17:47:52 +0200 Subject: [PATCH] [charts] Fix `LineChart` animation being stuck with initial drawing area value (#14553) --- docs/pages/x/api/charts/bar-chart-pro.json | 1 + docs/pages/x/api/charts/bar-chart.json | 1 + docs/pages/x/api/charts/heatmap.json | 1 + docs/pages/x/api/charts/line-chart-pro.json | 1 + docs/pages/x/api/charts/line-chart.json | 1 + docs/pages/x/api/charts/pie-chart.json | 1 + .../responsive-chart-container-pro.json | 1 + .../charts/responsive-chart-container.json | 1 + .../pages/x/api/charts/scatter-chart-pro.json | 1 + docs/pages/x/api/charts/scatter-chart.json | 1 + docs/pages/x/api/charts/spark-line-chart.json | 1 + .../charts/bar-chart-pro/bar-chart-pro.json | 3 ++ .../api-docs/charts/bar-chart/bar-chart.json | 3 ++ .../api-docs/charts/heatmap/heatmap.json | 3 ++ .../charts/line-chart-pro/line-chart-pro.json | 3 ++ .../charts/line-chart/line-chart.json | 3 ++ .../api-docs/charts/pie-chart/pie-chart.json | 3 ++ .../responsive-chart-container-pro.json | 3 ++ .../responsive-chart-container.json | 3 ++ .../scatter-chart-pro/scatter-chart-pro.json | 3 ++ .../charts/scatter-chart/scatter-chart.json | 3 ++ .../spark-line-chart/spark-line-chart.json | 3 ++ .../src/BarChartPro/BarChartPro.tsx | 10 +++++ packages/x-charts-pro/src/Heatmap/Heatmap.tsx | 10 +++++ .../src/LineChartPro/LineChartPro.tsx | 10 +++++ .../ResponsiveChartContainerPro.tsx | 10 +++++ .../src/ScatterChartPro/ScatterChartPro.tsx | 10 +++++ packages/x-charts/src/BarChart/BarChart.tsx | 10 +++++ .../x-charts/src/LineChart/AnimatedLine.tsx | 27 +++++++----- packages/x-charts/src/LineChart/LineChart.tsx | 10 +++++ packages/x-charts/src/PieChart/PieChart.tsx | 10 +++++ .../ResponsiveChartContainer.tsx | 20 +++++++++ .../useChartContainerDimensions.ts | 43 +++++++++++++++---- .../useResponsiveChartContainerProps.ts | 3 +- .../src/ScatterChart/ScatterChart.tsx | 10 +++++ .../src/SparkLineChart/SparkLineChart.tsx | 10 +++++ 36 files changed, 218 insertions(+), 19 deletions(-) diff --git a/docs/pages/x/api/charts/bar-chart-pro.json b/docs/pages/x/api/charts/bar-chart-pro.json index 8cc679f15c36f..3b730fea231b1 100644 --- a/docs/pages/x/api/charts/bar-chart-pro.json +++ b/docs/pages/x/api/charts/bar-chart-pro.json @@ -80,6 +80,7 @@ "describedArgs": ["zoomData"] } }, + "resolveSizeBeforeRender": { "type": { "name": "bool" }, "default": "false" }, "rightAxis": { "type": { "name": "union", "description": "object
| string" }, "default": "null" diff --git a/docs/pages/x/api/charts/bar-chart.json b/docs/pages/x/api/charts/bar-chart.json index 4fbc846f99487..8d3a4dfad015c 100644 --- a/docs/pages/x/api/charts/bar-chart.json +++ b/docs/pages/x/api/charts/bar-chart.json @@ -73,6 +73,7 @@ "describedArgs": ["event", "barItemIdentifier"] } }, + "resolveSizeBeforeRender": { "type": { "name": "bool" }, "default": "false" }, "rightAxis": { "type": { "name": "union", "description": "object
| string" }, "default": "null" diff --git a/docs/pages/x/api/charts/heatmap.json b/docs/pages/x/api/charts/heatmap.json index 22b2bb7bbaa1e..9b6928effba9a 100644 --- a/docs/pages/x/api/charts/heatmap.json +++ b/docs/pages/x/api/charts/heatmap.json @@ -61,6 +61,7 @@ "describedArgs": ["highlightedItem"] } }, + "resolveSizeBeforeRender": { "type": { "name": "bool" }, "default": "false" }, "rightAxis": { "type": { "name": "union", "description": "object
| string" }, "default": "null" diff --git a/docs/pages/x/api/charts/line-chart-pro.json b/docs/pages/x/api/charts/line-chart-pro.json index 51abfb3bb0dbf..b2072c09fcafe 100644 --- a/docs/pages/x/api/charts/line-chart-pro.json +++ b/docs/pages/x/api/charts/line-chart-pro.json @@ -73,6 +73,7 @@ "describedArgs": ["zoomData"] } }, + "resolveSizeBeforeRender": { "type": { "name": "bool" }, "default": "false" }, "rightAxis": { "type": { "name": "union", "description": "object
| string" }, "default": "null" diff --git a/docs/pages/x/api/charts/line-chart.json b/docs/pages/x/api/charts/line-chart.json index 9fa4d4ef823b7..7307cfde6c468 100644 --- a/docs/pages/x/api/charts/line-chart.json +++ b/docs/pages/x/api/charts/line-chart.json @@ -66,6 +66,7 @@ }, "onLineClick": { "type": { "name": "func" } }, "onMarkClick": { "type": { "name": "func" } }, + "resolveSizeBeforeRender": { "type": { "name": "bool" }, "default": "false" }, "rightAxis": { "type": { "name": "union", "description": "object
| string" }, "default": "null" diff --git a/docs/pages/x/api/charts/pie-chart.json b/docs/pages/x/api/charts/pie-chart.json index dfb20738cb2a4..184cd16695e58 100644 --- a/docs/pages/x/api/charts/pie-chart.json +++ b/docs/pages/x/api/charts/pie-chart.json @@ -61,6 +61,7 @@ } }, "onItemClick": { "type": { "name": "func" } }, + "resolveSizeBeforeRender": { "type": { "name": "bool" }, "default": "false" }, "rightAxis": { "type": { "name": "union", "description": "object
| string" }, "default": "null" diff --git a/docs/pages/x/api/charts/responsive-chart-container-pro.json b/docs/pages/x/api/charts/responsive-chart-container-pro.json index 469801ba978d5..27561b8a05e07 100644 --- a/docs/pages/x/api/charts/responsive-chart-container-pro.json +++ b/docs/pages/x/api/charts/responsive-chart-container-pro.json @@ -39,6 +39,7 @@ } }, "plugins": { "type": { "name": "arrayOf", "description": "Array<object>" } }, + "resolveSizeBeforeRender": { "type": { "name": "bool" }, "default": "false" }, "width": { "type": { "name": "number" } }, "xAxis": { "type": { diff --git a/docs/pages/x/api/charts/responsive-chart-container.json b/docs/pages/x/api/charts/responsive-chart-container.json index 830314a5fcee8..4c989c7b0e957 100644 --- a/docs/pages/x/api/charts/responsive-chart-container.json +++ b/docs/pages/x/api/charts/responsive-chart-container.json @@ -32,6 +32,7 @@ } }, "plugins": { "type": { "name": "arrayOf", "description": "Array<object>" } }, + "resolveSizeBeforeRender": { "type": { "name": "bool" }, "default": "false" }, "width": { "type": { "name": "number" } }, "xAxis": { "type": { diff --git a/docs/pages/x/api/charts/scatter-chart-pro.json b/docs/pages/x/api/charts/scatter-chart-pro.json index 8dbc6b9ebc781..5aca23918a830 100644 --- a/docs/pages/x/api/charts/scatter-chart-pro.json +++ b/docs/pages/x/api/charts/scatter-chart-pro.json @@ -69,6 +69,7 @@ "describedArgs": ["zoomData"] } }, + "resolveSizeBeforeRender": { "type": { "name": "bool" }, "default": "false" }, "rightAxis": { "type": { "name": "union", "description": "object
| string" }, "default": "null" diff --git a/docs/pages/x/api/charts/scatter-chart.json b/docs/pages/x/api/charts/scatter-chart.json index f9daa7ae5b4b4..0299bfabd4c7c 100644 --- a/docs/pages/x/api/charts/scatter-chart.json +++ b/docs/pages/x/api/charts/scatter-chart.json @@ -62,6 +62,7 @@ "describedArgs": ["event", "scatterItemIdentifier"] } }, + "resolveSizeBeforeRender": { "type": { "name": "bool" }, "default": "false" }, "rightAxis": { "type": { "name": "union", "description": "object
| string" }, "default": "null" diff --git a/docs/pages/x/api/charts/spark-line-chart.json b/docs/pages/x/api/charts/spark-line-chart.json index 3efe0080de11f..f226435f1df6f 100644 --- a/docs/pages/x/api/charts/spark-line-chart.json +++ b/docs/pages/x/api/charts/spark-line-chart.json @@ -36,6 +36,7 @@ "type": { "name": "enum", "description": "'bar'
| 'line'" }, "default": "'line'" }, + "resolveSizeBeforeRender": { "type": { "name": "bool" }, "default": "false" }, "showHighlight": { "type": { "name": "bool" }, "default": "false" }, "showTooltip": { "type": { "name": "bool" }, "default": "false" }, "slotProps": { "type": { "name": "object" }, "default": "{}" }, diff --git a/docs/translations/api-docs/charts/bar-chart-pro/bar-chart-pro.json b/docs/translations/api-docs/charts/bar-chart-pro/bar-chart-pro.json index 58fc1a173e710..e4f68a9e30703 100644 --- a/docs/translations/api-docs/charts/bar-chart-pro/bar-chart-pro.json +++ b/docs/translations/api-docs/charts/bar-chart-pro/bar-chart-pro.json @@ -56,6 +56,9 @@ "description": "Callback fired when the zoom has changed.", "typeDescriptions": { "zoomData": "Updated zoom data." } }, + "resolveSizeBeforeRender": { + "description": "The chart will try to wait for the parent container to resolve its size before it renders for the first time.
This can be useful in some scenarios where the chart appear to grow after the first render, like when used inside a grid." + }, "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." }, diff --git a/docs/translations/api-docs/charts/bar-chart/bar-chart.json b/docs/translations/api-docs/charts/bar-chart/bar-chart.json index b20ef3bdfad0c..e01b93a00534b 100644 --- a/docs/translations/api-docs/charts/bar-chart/bar-chart.json +++ b/docs/translations/api-docs/charts/bar-chart/bar-chart.json @@ -52,6 +52,9 @@ "barItemIdentifier": "The bar item identifier." } }, + "resolveSizeBeforeRender": { + "description": "The chart will try to wait for the parent container to resolve its size before it renders for the first time.
This can be useful in some scenarios where the chart appear to grow after the first render, like when used inside a grid." + }, "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." }, diff --git a/docs/translations/api-docs/charts/heatmap/heatmap.json b/docs/translations/api-docs/charts/heatmap/heatmap.json index 8db3fec541fc5..c693b034952ff 100644 --- a/docs/translations/api-docs/charts/heatmap/heatmap.json +++ b/docs/translations/api-docs/charts/heatmap/heatmap.json @@ -35,6 +35,9 @@ "description": "The callback fired when the highlighted item changes.", "typeDescriptions": { "highlightedItem": "The newly highlighted item." } }, + "resolveSizeBeforeRender": { + "description": "The chart will try to wait for the parent container to resolve its size before it renders for the first time.
This can be useful in some scenarios where the chart appear to grow after the first render, like when used inside a grid." + }, "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." }, diff --git a/docs/translations/api-docs/charts/line-chart-pro/line-chart-pro.json b/docs/translations/api-docs/charts/line-chart-pro/line-chart-pro.json index dd0182cc08187..542459c99c73e 100644 --- a/docs/translations/api-docs/charts/line-chart-pro/line-chart-pro.json +++ b/docs/translations/api-docs/charts/line-chart-pro/line-chart-pro.json @@ -53,6 +53,9 @@ "description": "Callback fired when the zoom has changed.", "typeDescriptions": { "zoomData": "Updated zoom data." } }, + "resolveSizeBeforeRender": { + "description": "The chart will try to wait for the parent container to resolve its size before it renders for the first time.
This can be useful in some scenarios where the chart appear to grow after the first render, like when used inside a grid." + }, "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." }, diff --git a/docs/translations/api-docs/charts/line-chart/line-chart.json b/docs/translations/api-docs/charts/line-chart/line-chart.json index efe9d5f8cf90e..958581f064a52 100644 --- a/docs/translations/api-docs/charts/line-chart/line-chart.json +++ b/docs/translations/api-docs/charts/line-chart/line-chart.json @@ -49,6 +49,9 @@ }, "onLineClick": { "description": "Callback fired when a line element is clicked." }, "onMarkClick": { "description": "Callback fired when a mark element is clicked." }, + "resolveSizeBeforeRender": { + "description": "The chart will try to wait for the parent container to resolve its size before it renders for the first time.
This can be useful in some scenarios where the chart appear to grow after the first render, like when used inside a grid." + }, "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." }, diff --git a/docs/translations/api-docs/charts/pie-chart/pie-chart.json b/docs/translations/api-docs/charts/pie-chart/pie-chart.json index 7f1be4fa44ccf..68cc51cc76a85 100644 --- a/docs/translations/api-docs/charts/pie-chart/pie-chart.json +++ b/docs/translations/api-docs/charts/pie-chart/pie-chart.json @@ -34,6 +34,9 @@ "typeDescriptions": { "highlightedItem": "The newly highlighted item." } }, "onItemClick": { "description": "Callback fired when a pie arc is clicked." }, + "resolveSizeBeforeRender": { + "description": "The chart will try to wait for the parent container to resolve its size before it renders for the first time.
This can be useful in some scenarios where the chart appear to grow after the first render, like when used inside a grid." + }, "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." }, diff --git a/docs/translations/api-docs/charts/responsive-chart-container-pro/responsive-chart-container-pro.json b/docs/translations/api-docs/charts/responsive-chart-container-pro/responsive-chart-container-pro.json index 469366dd9aad7..06357f4b5fd47 100644 --- a/docs/translations/api-docs/charts/responsive-chart-container-pro/responsive-chart-container-pro.json +++ b/docs/translations/api-docs/charts/responsive-chart-container-pro/responsive-chart-container-pro.json @@ -28,6 +28,9 @@ "plugins": { "description": "An array of plugins defining how to preprocess data. If not provided, the container supports line, bar, scatter and pie charts." }, + "resolveSizeBeforeRender": { + "description": "The chart will try to wait for the parent container to resolve its size before it renders for the first time.
This can be useful in some scenarios where the chart appear to grow after the first render, like when used inside a grid." + }, "series": { "description": "The array of series to display. Each type of series has its own specificity. Please refer to the appropriate docs page to learn more about it." }, diff --git a/docs/translations/api-docs/charts/responsive-chart-container/responsive-chart-container.json b/docs/translations/api-docs/charts/responsive-chart-container/responsive-chart-container.json index 1623c12c44cda..6b371581a9ca8 100644 --- a/docs/translations/api-docs/charts/responsive-chart-container/responsive-chart-container.json +++ b/docs/translations/api-docs/charts/responsive-chart-container/responsive-chart-container.json @@ -24,6 +24,9 @@ "plugins": { "description": "An array of plugins defining how to preprocess data. If not provided, the container supports line, bar, scatter and pie charts." }, + "resolveSizeBeforeRender": { + "description": "The chart will try to wait for the parent container to resolve its size before it renders for the first time.
This can be useful in some scenarios where the chart appear to grow after the first render, like when used inside a grid." + }, "series": { "description": "The array of series to display. Each type of series has its own specificity. Please refer to the appropriate docs page to learn more about it." }, diff --git a/docs/translations/api-docs/charts/scatter-chart-pro/scatter-chart-pro.json b/docs/translations/api-docs/charts/scatter-chart-pro/scatter-chart-pro.json index 6a6c1e0b1bf6a..141cc067550f1 100644 --- a/docs/translations/api-docs/charts/scatter-chart-pro/scatter-chart-pro.json +++ b/docs/translations/api-docs/charts/scatter-chart-pro/scatter-chart-pro.json @@ -47,6 +47,9 @@ "description": "Callback fired when the zoom has changed.", "typeDescriptions": { "zoomData": "Updated zoom data." } }, + "resolveSizeBeforeRender": { + "description": "The chart will try to wait for the parent container to resolve its size before it renders for the first time.
This can be useful in some scenarios where the chart appear to grow after the first render, like when used inside a grid." + }, "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." }, diff --git a/docs/translations/api-docs/charts/scatter-chart/scatter-chart.json b/docs/translations/api-docs/charts/scatter-chart/scatter-chart.json index 5e9b1baac91e9..23a06f78b85c5 100644 --- a/docs/translations/api-docs/charts/scatter-chart/scatter-chart.json +++ b/docs/translations/api-docs/charts/scatter-chart/scatter-chart.json @@ -43,6 +43,9 @@ "scatterItemIdentifier": "The scatter item identifier." } }, + "resolveSizeBeforeRender": { + "description": "The chart will try to wait for the parent container to resolve its size before it renders for the first time.
This can be useful in some scenarios where the chart appear to grow after the first render, like when used inside a grid." + }, "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." }, diff --git a/docs/translations/api-docs/charts/spark-line-chart/spark-line-chart.json b/docs/translations/api-docs/charts/spark-line-chart/spark-line-chart.json index c4595d0c6f196..faa29963435e4 100644 --- a/docs/translations/api-docs/charts/spark-line-chart/spark-line-chart.json +++ b/docs/translations/api-docs/charts/spark-line-chart/spark-line-chart.json @@ -26,6 +26,9 @@ "typeDescriptions": { "highlightedItem": "The newly highlighted item." } }, "plotType": { "description": "Type of plot used." }, + "resolveSizeBeforeRender": { + "description": "The chart will try to wait for the parent container to resolve its size before it renders for the first time.
This can be useful in some scenarios where the chart appear to grow after the first render, like when used inside a grid." + }, "showHighlight": { "description": "Set to true to highlight the value. With line, it shows a point. With bar, it shows a highlight band." }, diff --git a/packages/x-charts-pro/src/BarChartPro/BarChartPro.tsx b/packages/x-charts-pro/src/BarChartPro/BarChartPro.tsx index 628a47acce0e9..8d716850bf7d9 100644 --- a/packages/x-charts-pro/src/BarChartPro/BarChartPro.tsx +++ b/packages/x-charts-pro/src/BarChartPro/BarChartPro.tsx @@ -230,6 +230,16 @@ BarChartPro.propTypes = { * @param {ZoomData[]} zoomData Updated zoom data. */ onZoomChange: PropTypes.func, + /** + * The chart will try to wait for the parent container to resolve its size + * before it renders for the first time. + * + * This can be useful in some scenarios where the chart appear to grow after + * the first render, like when used inside a grid. + * + * @default false + */ + resolveSizeBeforeRender: PropTypes.bool, /** * Indicate which axis to display the right of the charts. * Can be a string (the id of the axis) or an object `ChartsYAxisProps`. diff --git a/packages/x-charts-pro/src/Heatmap/Heatmap.tsx b/packages/x-charts-pro/src/Heatmap/Heatmap.tsx index 0d146c49c8b66..de7683f394aed 100644 --- a/packages/x-charts-pro/src/Heatmap/Heatmap.tsx +++ b/packages/x-charts-pro/src/Heatmap/Heatmap.tsx @@ -286,6 +286,16 @@ Heatmap.propTypes = { * @param {HighlightItemData | null} highlightedItem The newly highlighted item. */ onHighlightChange: PropTypes.func, + /** + * The chart will try to wait for the parent container to resolve its size + * before it renders for the first time. + * + * This can be useful in some scenarios where the chart appear to grow after + * the first render, like when used inside a grid. + * + * @default false + */ + resolveSizeBeforeRender: PropTypes.bool, /** * Indicate which axis to display the right of the charts. * Can be a string (the id of the axis) or an object `ChartsYAxisProps`. diff --git a/packages/x-charts-pro/src/LineChartPro/LineChartPro.tsx b/packages/x-charts-pro/src/LineChartPro/LineChartPro.tsx index a698d20f44f09..ec09c9711bb99 100644 --- a/packages/x-charts-pro/src/LineChartPro/LineChartPro.tsx +++ b/packages/x-charts-pro/src/LineChartPro/LineChartPro.tsx @@ -251,6 +251,16 @@ LineChartPro.propTypes = { * @param {ZoomData[]} zoomData Updated zoom data. */ onZoomChange: PropTypes.func, + /** + * The chart will try to wait for the parent container to resolve its size + * before it renders for the first time. + * + * This can be useful in some scenarios where the chart appear to grow after + * the first render, like when used inside a grid. + * + * @default false + */ + resolveSizeBeforeRender: PropTypes.bool, /** * Indicate which axis to display the right of the charts. * Can be a string (the id of the axis) or an object `ChartsYAxisProps`. diff --git a/packages/x-charts-pro/src/ResponsiveChartContainerPro/ResponsiveChartContainerPro.tsx b/packages/x-charts-pro/src/ResponsiveChartContainerPro/ResponsiveChartContainerPro.tsx index 2669f806ca5c7..c8375edd27f5a 100644 --- a/packages/x-charts-pro/src/ResponsiveChartContainerPro/ResponsiveChartContainerPro.tsx +++ b/packages/x-charts-pro/src/ResponsiveChartContainerPro/ResponsiveChartContainerPro.tsx @@ -93,6 +93,16 @@ ResponsiveChartContainerPro.propTypes = { * If not provided, the container supports line, bar, scatter and pie charts. */ plugins: PropTypes.arrayOf(PropTypes.object), + /** + * The chart will try to wait for the parent container to resolve its size + * before it renders for the first time. + * + * This can be useful in some scenarios where the chart appear to grow after + * the first render, like when used inside a grid. + * + * @default false + */ + resolveSizeBeforeRender: PropTypes.bool, /** * The array of series to display. * Each type of series has its own specificity. diff --git a/packages/x-charts-pro/src/ScatterChartPro/ScatterChartPro.tsx b/packages/x-charts-pro/src/ScatterChartPro/ScatterChartPro.tsx index 7b49dc343bc23..b6d659fcd8c79 100644 --- a/packages/x-charts-pro/src/ScatterChartPro/ScatterChartPro.tsx +++ b/packages/x-charts-pro/src/ScatterChartPro/ScatterChartPro.tsx @@ -205,6 +205,16 @@ ScatterChartPro.propTypes = { * @param {ZoomData[]} zoomData Updated zoom data. */ onZoomChange: PropTypes.func, + /** + * The chart will try to wait for the parent container to resolve its size + * before it renders for the first time. + * + * This can be useful in some scenarios where the chart appear to grow after + * the first render, like when used inside a grid. + * + * @default false + */ + resolveSizeBeforeRender: PropTypes.bool, /** * Indicate which axis to display the right of the charts. * Can be a string (the id of the axis) or an object `ChartsYAxisProps`. diff --git a/packages/x-charts/src/BarChart/BarChart.tsx b/packages/x-charts/src/BarChart/BarChart.tsx index 31ac61783bacc..e3c53e9d0271a 100644 --- a/packages/x-charts/src/BarChart/BarChart.tsx +++ b/packages/x-charts/src/BarChart/BarChart.tsx @@ -291,6 +291,16 @@ BarChart.propTypes = { * @param {BarItemIdentifier} barItemIdentifier The bar item identifier. */ onItemClick: PropTypes.func, + /** + * The chart will try to wait for the parent container to resolve its size + * before it renders for the first time. + * + * This can be useful in some scenarios where the chart appear to grow after + * the first render, like when used inside a grid. + * + * @default false + */ + resolveSizeBeforeRender: PropTypes.bool, /** * Indicate which axis to display the right of the charts. * Can be a string (the id of the axis) or an object `ChartsYAxisProps`. diff --git a/packages/x-charts/src/LineChart/AnimatedLine.tsx b/packages/x-charts/src/LineChart/AnimatedLine.tsx index 6283db6dbaf67..c0e66f8e370ba 100644 --- a/packages/x-charts/src/LineChart/AnimatedLine.tsx +++ b/packages/x-charts/src/LineChart/AnimatedLine.tsx @@ -48,19 +48,21 @@ export interface AnimatedLineProps extends React.ComponentPropsWithoutRef<'path' */ function AnimatedLine(props: AnimatedLineProps) { const { d, skipAnimation, ownerState, ...other } = props; - const { left, top, bottom, width, height, right } = useDrawingArea(); + const drawingArea = useDrawingArea(); const chartId = useChartId(); const stringInterpolator = useStringInterpolator(d); - const transitionAppear = useTransition([1], { - from: { animatedWidth: left }, - to: { animatedWidth: width + left + right }, - enter: { animatedWidth: width + left + right }, - leave: { animatedWidth: left }, - reset: false, - immediate: skipAnimation, - }); + const transitionAppear = useTransition( + [drawingArea], + { + from: (v) => ({ animatedWidth: v.left }), + enter: (v) => ({ animatedWidth: v.width + v.left + v.right }), + leave: (v) => ({ animatedWidth: v.width + v.left + v.right }), + reset: false, + immediate: skipAnimation, + }, + ); const transitionChange = useTransition([stringInterpolator], { from: { value: 0 }, @@ -75,7 +77,12 @@ function AnimatedLine(props: AnimatedLineProps) { {transitionAppear((style) => ( - + ))} diff --git a/packages/x-charts/src/LineChart/LineChart.tsx b/packages/x-charts/src/LineChart/LineChart.tsx index b4e3bc03d708a..c688859d63be0 100644 --- a/packages/x-charts/src/LineChart/LineChart.tsx +++ b/packages/x-charts/src/LineChart/LineChart.tsx @@ -326,6 +326,16 @@ LineChart.propTypes = { * Callback fired when a mark element is clicked. */ onMarkClick: PropTypes.func, + /** + * The chart will try to wait for the parent container to resolve its size + * before it renders for the first time. + * + * This can be useful in some scenarios where the chart appear to grow after + * the first render, like when used inside a grid. + * + * @default false + */ + resolveSizeBeforeRender: PropTypes.bool, /** * Indicate which axis to display the right of the charts. * Can be a string (the id of the axis) or an object `ChartsYAxisProps`. diff --git a/packages/x-charts/src/PieChart/PieChart.tsx b/packages/x-charts/src/PieChart/PieChart.tsx index e976de30675df..4f146326fcd5a 100644 --- a/packages/x-charts/src/PieChart/PieChart.tsx +++ b/packages/x-charts/src/PieChart/PieChart.tsx @@ -328,6 +328,16 @@ PieChart.propTypes = { * Callback fired when a pie arc is clicked. */ onItemClick: PropTypes.func, + /** + * The chart will try to wait for the parent container to resolve its size + * before it renders for the first time. + * + * This can be useful in some scenarios where the chart appear to grow after + * the first render, like when used inside a grid. + * + * @default false + */ + resolveSizeBeforeRender: PropTypes.bool, /** * Indicate which axis to display the right of the charts. * Can be a string (the id of the axis) or an object `ChartsYAxisProps`. diff --git a/packages/x-charts/src/ResponsiveChartContainer/ResponsiveChartContainer.tsx b/packages/x-charts/src/ResponsiveChartContainer/ResponsiveChartContainer.tsx index 7932c917cc6d1..e1978ceedde96 100644 --- a/packages/x-charts/src/ResponsiveChartContainer/ResponsiveChartContainer.tsx +++ b/packages/x-charts/src/ResponsiveChartContainer/ResponsiveChartContainer.tsx @@ -15,6 +15,16 @@ export interface ResponsiveChartContainerProps * The height of the chart in px. If not defined, it takes the height of the parent element. */ height?: number; + /** + * The chart will try to wait for the parent container to resolve its size + * before it renders for the first time. + * + * This can be useful in some scenarios where the chart appear to grow after + * the first render, like when used inside a grid. + * + * @default false + */ + resolveSizeBeforeRender?: boolean; } const ResponsiveChartContainer = React.forwardRef(function ResponsiveChartContainer( @@ -88,6 +98,16 @@ ResponsiveChartContainer.propTypes = { * If not provided, the container supports line, bar, scatter and pie charts. */ plugins: PropTypes.arrayOf(PropTypes.object), + /** + * The chart will try to wait for the parent container to resolve its size + * before it renders for the first time. + * + * This can be useful in some scenarios where the chart appear to grow after + * the first render, like when used inside a grid. + * + * @default false + */ + resolveSizeBeforeRender: PropTypes.bool, /** * The array of series to display. * Each type of series has its own specificity. diff --git a/packages/x-charts/src/ResponsiveChartContainer/useChartContainerDimensions.ts b/packages/x-charts/src/ResponsiveChartContainer/useChartContainerDimensions.ts index c256d2167b8e5..73eed0dd181ba 100644 --- a/packages/x-charts/src/ResponsiveChartContainer/useChartContainerDimensions.ts +++ b/packages/x-charts/src/ResponsiveChartContainer/useChartContainerDimensions.ts @@ -3,8 +3,12 @@ import * as React from 'react'; import useEnhancedEffect from '@mui/utils/useEnhancedEffect'; import ownerWindow from '@mui/utils/ownerWindow'; -export const useChartContainerDimensions = (inWidth?: number, inHeight?: number) => { - const displayError = React.useRef(false); +export const useChartContainerDimensions = ( + inWidth?: number, + inHeight?: number, + resolveSizeBeforeRender?: boolean, +) => { + const stateRef = React.useRef({ displayError: false, initialCompute: true, computeRun: 0 }); const rootRef = React.useRef(null); const [width, setWidth] = React.useState(0); @@ -15,7 +19,7 @@ export const useChartContainerDimensions = (inWidth?: number, inHeight?: number) const mainEl = rootRef?.current; if (!mainEl) { - return; + return {}; } const win = ownerWindow(mainEl); @@ -26,13 +30,36 @@ export const useChartContainerDimensions = (inWidth?: number, inHeight?: number) setWidth(newWidth); setHeight(newHeight); + + return { width: newWidth, height: newHeight }; }, []); React.useEffect(() => { // Ensure the error detection occurs after the first rendering. - displayError.current = true; + stateRef.current.displayError = true; }, []); + // This effect is used to compute the size of the container on the initial render. + // It is not bound to the raf loop to avoid an unwanted "resize" event. + // https://github.com/mui/mui-x/issues/13477#issuecomment-2336634785 + useEnhancedEffect(() => { + // computeRun is used to avoid infinite loops. + if ( + !resolveSizeBeforeRender || + !stateRef.current.initialCompute || + stateRef.current.computeRun > 20 + ) { + return; + } + + const computedSize = computeSize(); + if (computedSize.width !== width || computedSize.height !== height) { + stateRef.current.computeRun += 1; + } else if (stateRef.current.initialCompute) { + stateRef.current.initialCompute = false; + } + }, [width, height, computeSize, resolveSizeBeforeRender]); + useEnhancedEffect(() => { if (inWidth !== undefined && inHeight !== undefined) { return () => {}; @@ -68,17 +95,17 @@ export const useChartContainerDimensions = (inWidth?: number, inHeight?: number) }, [computeSize, inHeight, inWidth]); if (process.env.NODE_ENV !== 'production') { - if (displayError.current && inWidth === undefined && width === 0) { + if (stateRef.current.displayError && inWidth === undefined && width === 0) { console.error( `MUI X: ChartContainer does not have \`width\` prop, and its container has no \`width\` defined.`, ); - displayError.current = false; + stateRef.current.displayError = false; } - if (displayError.current && inHeight === undefined && height === 0) { + if (stateRef.current.displayError && inHeight === undefined && height === 0) { console.error( `MUI X: ChartContainer does not have \`height\` prop, and its container has no \`height\` defined.`, ); - displayError.current = false; + stateRef.current.displayError = false; } } diff --git a/packages/x-charts/src/ResponsiveChartContainer/useResponsiveChartContainerProps.ts b/packages/x-charts/src/ResponsiveChartContainer/useResponsiveChartContainerProps.ts index 94b91affe7b86..bb2234b6c80e6 100644 --- a/packages/x-charts/src/ResponsiveChartContainer/useResponsiveChartContainerProps.ts +++ b/packages/x-charts/src/ResponsiveChartContainer/useResponsiveChartContainerProps.ts @@ -10,6 +10,7 @@ export const useResponsiveChartContainerProps = ( const { width, height, + resolveSizeBeforeRender, margin, children, series, @@ -33,7 +34,7 @@ export const useResponsiveChartContainerProps = ( containerRef, width: dWidth, height: dHeight, - } = useChartContainerDimensions(width, height); + } = useChartContainerDimensions(width, height, resolveSizeBeforeRender); const resizableChartContainerProps = { ...other, diff --git a/packages/x-charts/src/ScatterChart/ScatterChart.tsx b/packages/x-charts/src/ScatterChart/ScatterChart.tsx index cbbe56dfa9e8c..1c9d3e8ad780a 100644 --- a/packages/x-charts/src/ScatterChart/ScatterChart.tsx +++ b/packages/x-charts/src/ScatterChart/ScatterChart.tsx @@ -280,6 +280,16 @@ ScatterChart.propTypes = { * @param {ScatterItemIdentifier} scatterItemIdentifier The scatter item identifier. */ onItemClick: PropTypes.func, + /** + * The chart will try to wait for the parent container to resolve its size + * before it renders for the first time. + * + * This can be useful in some scenarios where the chart appear to grow after + * the first render, like when used inside a grid. + * + * @default false + */ + resolveSizeBeforeRender: PropTypes.bool, /** * Indicate which axis to display the right of the charts. * Can be a string (the id of the axis) or an object `ChartsYAxisProps`. diff --git a/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx b/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx index da1d649bdb0b7..455b8eda85269 100644 --- a/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx +++ b/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx @@ -320,6 +320,16 @@ SparkLineChart.propTypes = { * @default 'line' */ plotType: PropTypes.oneOf(['bar', 'line']), + /** + * The chart will try to wait for the parent container to resolve its size + * before it renders for the first time. + * + * This can be useful in some scenarios where the chart appear to grow after + * the first render, like when used inside a grid. + * + * @default false + */ + resolveSizeBeforeRender: PropTypes.bool, /** * Set to `true` to highlight the value. * With line, it shows a point.