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: -10,
},
]}
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: -10,
JCQuintas marked this conversation as resolved.
Show resolved Hide resolved
},
]}
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: -10,
},
]}
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 change it, simply provide the wanted `baseline` number of a series.
It is also possible to provide `min` or `max` for the baseline to automatically follow the minimum or maximum value of the series.
JCQuintas marked this conversation as resolved.
Show resolved Hide resolved

:::info
Keep in mind the baseline only affects the area visuals. If you want to change the axis minimum or maximum values, you should use the `min/max` property of the axis.
:::
Copy link
Member

@alexfauquette alexfauquette Aug 12, 2024

Choose a reason for hiding this comment

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

Not exactly if the baseline means we will ignore 0 for extremum computation

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't get what you mean here 🤔

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, I forgot a part of the sentence

If the baseline is defined with min/max, the 0 will be ignored for axis extremums

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, this is an effect of your change, I didn't intend it at first. We can keep to the other discussion and I will update it with the outcomes


{{"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": "The value of the line at the base of the series area.<br /><br />If <code>baseline</code> is a number, it will be used as the value.<br /><br />- <code>&#39;min&#39;</code> the minimum value of the series will be used.<br />- <code>&#39;max&#39;</code> the maximum value of the series will be used."
},
"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
3 changes: 2 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,9 @@ 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' ? (d) => d : (d) => [d[1], d[1]];
JCQuintas marked this conversation as resolved.
Show resolved Hide resolved

const seriesExtremums = getSeriesExtremums(getValues, stackedData);

Expand Down
11 changes: 11 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,17 @@ export interface LineSeriesType
* @default 'none'
*/
stackOffset?: StackOffsetType;
/**
* The value of the line at the base of the series area.
*
* If `baseline` is a number, it will be used as the value.
*
* - `'min'` the minimum value of the series will be used.
* - `'max'` the maximum value of the series will be used.
JCQuintas marked this conversation as resolved.
Show resolved Hide resolved
*
* @default 0
*/
baseline?: number | 'min' | 'max';
}

/**
Expand Down