diff --git a/docs/data/charts/line-demo/LineWithPrediction.js b/docs/data/charts/line-demo/LineWithPrediction.js
new file mode 100644
index 000000000000..277ce031aeb0
--- /dev/null
+++ b/docs/data/charts/line-demo/LineWithPrediction.js
@@ -0,0 +1,70 @@
+import * as React from 'react';
+import { LineChart, AnimatedLine } from '@mui/x-charts/LineChart';
+import { useChartId, useDrawingArea, useXScale } from '@mui/x-charts/hooks';
+
+function CustomAnimatedLine(props) {
+ const { limit, sxBefore, sxAfter, ...other } = props;
+ const { top, bottom, height, left, width } = useDrawingArea();
+ const scale = useXScale();
+ const chartId = useChartId();
+
+ if (limit === undefined) {
+ return ;
+ }
+
+ const limitPosition = scale(limit); // Convert value to x coordinate.
+
+ if (limitPosition === undefined) {
+ return ;
+ }
+
+ const clipIdleft = `${chartId}-${props.ownerState.id}-line-limit-${limit}-1`;
+ const clipIdRight = `${chartId}-${props.ownerState.id}-line-limit-${limit}-2`;
+ return (
+
+ {/* Clip to show the line before the limit */}
+
+
+
+ {/* Clip to show the line after the limit */}
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default function LineWithPrediction() {
+ return (
+ `${v}${i.dataIndex > 5 ? ' (estimated)' : ''}`,
+ },
+ ]}
+ xAxis={[{ data: [0, 1, 2, 3, 4, 5, 6, 7, 8] }]}
+ height={200}
+ width={400}
+ slots={{ line: CustomAnimatedLine }}
+ slotProps={{ line: { limit: 5, sxAfter: { strokeDasharray: '10 5' } } }}
+ />
+ );
+}
diff --git a/docs/data/charts/line-demo/LineWithPrediction.tsx b/docs/data/charts/line-demo/LineWithPrediction.tsx
new file mode 100644
index 000000000000..55fd42deb244
--- /dev/null
+++ b/docs/data/charts/line-demo/LineWithPrediction.tsx
@@ -0,0 +1,77 @@
+import * as React from 'react';
+import { LineChart, AnimatedLine, AnimatedLineProps } from '@mui/x-charts/LineChart';
+import { useChartId, useDrawingArea, useXScale } from '@mui/x-charts/hooks';
+import { SxProps, Theme } from '@mui/system';
+
+interface CustomAnimatedLineProps extends AnimatedLineProps {
+ limit?: number;
+ sxBefore?: SxProps;
+ sxAfter?: SxProps;
+}
+
+function CustomAnimatedLine(props: CustomAnimatedLineProps) {
+ const { limit, sxBefore, sxAfter, ...other } = props;
+ const { top, bottom, height, left, width } = useDrawingArea();
+ const scale = useXScale();
+ const chartId = useChartId();
+
+ if (limit === undefined) {
+ return ;
+ }
+
+ const limitPosition = scale(limit); // Convert value to x coordinate.
+
+ if (limitPosition === undefined) {
+ return ;
+ }
+
+ const clipIdleft = `${chartId}-${props.ownerState.id}-line-limit-${limit}-1`;
+ const clipIdRight = `${chartId}-${props.ownerState.id}-line-limit-${limit}-2`;
+ return (
+
+ {/* Clip to show the line before the limit */}
+
+
+
+ {/* Clip to show the line after the limit */}
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default function LineWithPrediction() {
+ return (
+ `${v}${i.dataIndex > 5 ? ' (estimated)' : ''}`,
+ },
+ ]}
+ xAxis={[{ data: [0, 1, 2, 3, 4, 5, 6, 7, 8] }]}
+ height={200}
+ width={400}
+ slots={{ line: CustomAnimatedLine }}
+ slotProps={{ line: { limit: 5, sxAfter: { strokeDasharray: '10 5' } } as any }}
+ />
+ );
+}
diff --git a/docs/data/charts/line-demo/LineWithPrediction.tsx.preview b/docs/data/charts/line-demo/LineWithPrediction.tsx.preview
new file mode 100644
index 000000000000..1dc0a8f94a59
--- /dev/null
+++ b/docs/data/charts/line-demo/LineWithPrediction.tsx.preview
@@ -0,0 +1,14 @@
+ `${v}${i.dataIndex > 5 ? ' (estimated)' : ''}`,
+ },
+ ]}
+ xAxis={[{ data: [0, 1, 2, 3, 4, 5, 6, 7, 8] }]}
+ height={200}
+ width={400}
+ slots={{ line: CustomAnimatedLine }}
+ slotProps={{ line: { limit: 5, sxAfter: { strokeDasharray: '10 5' } } as any }}
+/>
\ No newline at end of file
diff --git a/docs/data/charts/line-demo/line-demo.md b/docs/data/charts/line-demo/line-demo.md
index d79eae58f84a..e74ae9c5cade 100644
--- a/docs/data/charts/line-demo/line-demo.md
+++ b/docs/data/charts/line-demo/line-demo.md
@@ -31,3 +31,15 @@ components: LineChart, LineElement, LineHighlightElement, LineHighlightPlot, Lin
## LineChartConnectNulls
{{"demo": "LineChartConnectNulls.js"}}
+
+## Line with forecast
+
+To show that parts of the data have different meanings, you can render stylised lines for each of them.
+
+In the following example, the chart shows a dotted line to exemplify that the data is estimated.
+To do so, the `slots.line` is set with a custom components that render the default line twice.
+
+- The first one is clipped to show known values (from the left of the chart to the limit).
+- The second one is clipped to show predictions (from the limit to the right of the chart) with dash styling.
+
+{{"demo": "LineWithPrediction.js"}}