Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[charts] Add baseline property to the LineChart series #14153

Merged
merged 14 commits into from
Aug 12, 2024
19 changes: 19 additions & 0 deletions docs/data/charts/lines/AreaBaseline.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as React from 'react';
import { LineChart } from '@mui/x-charts/LineChart';

export default function AreaBaseline() {
return (
<LineChart
xAxis={[{ data: [1, 2, 3, 5, 8, 10] }]}
series={[
{
data: [2, -5.5, 2, -7.5, 1.5, 6],
area: true,
baseline: 'min',
},
]}
width={500}
height={300}
/>
);
}
19 changes: 19 additions & 0 deletions docs/data/charts/lines/AreaBaseline.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as React from 'react';
import { LineChart } from '@mui/x-charts/LineChart';

export default function AreaBaseline() {
return (
<LineChart
xAxis={[{ data: [1, 2, 3, 5, 8, 10] }]}
series={[
{
data: [2, -5.5, 2, -7.5, 1.5, 6],
area: true,
baseline: 'min',
},
]}
width={500}
height={300}
/>
);
}
12 changes: 12 additions & 0 deletions docs/data/charts/lines/AreaBaseline.tsx.preview
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<LineChart
xAxis={[{ data: [1, 2, 3, 5, 8, 10] }]}
series={[
{
data: [2, -5.5, 2, -7.5, 1.5, 6],
area: true,
baseline: 'min',
},
]}
width={500}
height={300}
/>
14 changes: 14 additions & 0 deletions docs/data/charts/lines/lines.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,20 @@ Different series could even have different interpolations.

{{"demo": "InterpolationDemoNoSnap.js", "hideToolbar": true}}

### Baseline

The area chart draws a `baseline` on the Y axis `0`.
This is useful as a base value, but customized visualizations may require a different baseline.

To get the area filling the space above or below the line, set `baseline` to `"min"` or `"max"`.
It is also possible to provide a `number` value to fix the baseline at the desired position.

:::warning
The `baseline` should not be used with stacked areas, as it will not work as expected.
:::

{{"demo": "AreaBaseline.js"}}

### Optimization

To show mark elements, use `showMark` series property.
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/charts/line-series-type.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"properties": {
"type": { "type": { "description": "'line'" }, "required": true },
"area": { "type": { "description": "boolean" } },
"baseline": { "type": { "description": "number | 'min' | 'max'" }, "default": "0" },
"color": { "type": { "description": "string" } },
"connectNulls": { "type": { "description": "boolean" }, "default": "false" },
"curve": { "type": { "description": "CurveType" } },
Expand Down
3 changes: 3 additions & 0 deletions docs/translations/api-docs/charts/line-series-type.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"propertiesDescriptions": {
"type": { "description": "" },
"area": { "description": "" },
"baseline": {
"description": "<p>The value of the line at the base of the series area.<br /><br />- <code>&#39;min&#39;</code> the area will fill the space <strong>under</strong> the line.<br />- <code>&#39;max&#39;</code> the area will fill the space <strong>above</strong> the line.<br />- <code>number</code> the area will fill the space between this value and the line</p>\n"
},
"color": { "description": "" },
"connectNulls": {
"description": "If <code>true</code>, line and area connect points separated by <code>null</code> values."
Expand Down
11 changes: 11 additions & 0 deletions packages/x-charts/src/LineChart/AreaPlot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const useAggregatedData = () => {
stackedData,
data,
connectNulls,
baseline,
} = series[seriesId];

const xAxisId = xAxisIdProp ?? xAxisKey;
Expand Down Expand Up @@ -97,6 +98,16 @@ const useAggregatedData = () => {
.x((d) => xScale(d.x))
.defined((_, i) => connectNulls || data[i] != null)
.y0((d) => {
if (typeof baseline === 'number') {
return yScale(baseline)!;
}
if (baseline === 'max') {
return yScale.range()[1];
}
if (baseline === 'min') {
return yScale.range()[0];
}

const value = d.y && yScale(d.y[0])!;
if (Number.isNaN(value)) {
return yScale.range()[0];
Expand Down
5 changes: 4 additions & 1 deletion packages/x-charts/src/LineChart/extremums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,11 @@ export const getExtremumY: ExtremumGetter<'line'> = (params) => {
const { area, stackedData } = series[seriesId];
const isArea = area !== undefined;

// Since this series is not used to display an area, we do not consider the base (the d[0]).
const getValues: GetValuesTypes =
isArea && axis.scaleType !== 'log' ? (d) => d : (d) => [d[1], d[1]]; // Since this series is not used to display an area, we do not consider the base (the d[0]).
isArea && axis.scaleType !== 'log' && typeof series[seriesId].baseline !== 'string'
? (d) => d
: (d) => [d[1], d[1]];

const seriesExtremums = getSeriesExtremums(getValues, stackedData);

Expand Down
10 changes: 10 additions & 0 deletions packages/x-charts/src/models/seriesType/line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ export interface LineSeriesType
* @default 'none'
*/
stackOffset?: StackOffsetType;
/**
* The value of the line at the base of the series area.
*
* - `'min'` the area will fill the space **under** the line.
* - `'max'` the area will fill the space **above** the line.
* - `number` the area will fill the space between this value and the line
*
* @default 0
*/
baseline?: number | 'min' | 'max';
}

/**
Expand Down