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 domainLimit to axis config #15294

Merged
merged 11 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 41 additions & 8 deletions docs/data/charts/sparkline/CustomDomainYAxis.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,51 @@ const settings = {
showHighlight: true,
};

const values = [60, -25, 66, 68, 87, 82, 83, 100, 92, 75, 76, 50, 91];
// Extend a value to match a multiple of the step.
function extend(value, step) {
if (value > 0) {
// If >0 go to the next step
return step * Math.ceil(value / step);
}
// If <0 go to the previous step
return step * Math.floor(value / step);
}

const values = [60, -15, 66, 68, 87, 82, 83, 85, 92, 75, 76, 50, 91];
JCQuintas marked this conversation as resolved.
Show resolved Hide resolved

export default function CustomDomainYAxis() {
return (
<Stack sx={{ width: '100%' }}>
<Typography>Without strict domain limit</Typography>
<Stack sx={{ width: '100%', mb: 2 }} direction="row" spacing={2}>
<Stack
sx={(theme) => ({
width: '100%',
'& p': { mb: 1, mt: 2 },
'& svg': {
borderWidth: 1,
borderStyle: 'solid',
borderColor: theme.palette.divider,
JCQuintas marked this conversation as resolved.
Show resolved Hide resolved
},
})}
>
<Typography>
<code>domainLimit=&quot;nice&quot;</code>, range from -100 to 100
</Typography>
<Stack
sx={{
width: '100%',
}}
direction="row"
spacing={2}
>
<Box sx={{ flexGrow: 1 }}>
<SparkLineChart data={values} {...settings} />
</Box>
<Box sx={{ flexGrow: 1 }}>
<SparkLineChart plotType="bar" data={values} {...settings} />
</Box>
</Stack>
<Typography>With strict domain limit</Typography>
<Typography>
<code>domainLimit=&quot;strict&quot;</code>, range from -15 to 92
</Typography>
<Stack sx={{ width: '100%' }} direction="row" spacing={2}>
<Box sx={{ flexGrow: 1 }}>
<SparkLineChart
Expand All @@ -43,13 +73,16 @@ export default function CustomDomainYAxis() {
/>
</Box>
</Stack>
<Typography>With custom function domain limit</Typography>
<Typography>custom function, range from -50 to 100</Typography>
<Stack sx={{ width: '100%' }} direction="row" spacing={2}>
<Box sx={{ flexGrow: 1 }}>
<SparkLineChart
data={values}
yAxis={{
domainLimit: ([min, max]) => [min - (min % 10), max + 10 - (max % 10)],
domainLimit: ([min, max]) => [
min - (Math.abs(min) % 50),
max + 50 - (Math.abs(max) % 50),
],
}}
{...settings}
/>
Expand All @@ -59,7 +92,7 @@ export default function CustomDomainYAxis() {
plotType="bar"
data={values}
yAxis={{
domainLimit: ([min, max]) => [min - (min % 10), max + 10 - (max % 10)],
domainLimit: ([min, max]) => [extend(min, 50), extend(max, 50)],
}}
{...settings}
/>
Expand Down
49 changes: 41 additions & 8 deletions docs/data/charts/sparkline/CustomDomainYAxis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,51 @@ const settings = {
showHighlight: true,
} as const;

const values = [60, -25, 66, 68, 87, 82, 83, 100, 92, 75, 76, 50, 91];
// Extend a value to match a multiple of the step.
function extend(value: number, step: number) {
if (value > 0) {
// If >0 go to the next step
return step * Math.ceil(value / step);
}
// If <0 go to the previous step
return step * Math.floor(value / step);
}

const values = [60, -15, 66, 68, 87, 82, 83, 85, 92, 75, 76, 50, 91];

export default function CustomDomainYAxis() {
return (
<Stack sx={{ width: '100%' }}>
<Typography>Without strict domain limit</Typography>
<Stack sx={{ width: '100%', mb: 2 }} direction="row" spacing={2}>
<Stack
sx={(theme) => ({
width: '100%',
'& p': { mb: 1, mt: 2 },
'& svg': {
borderWidth: 1,
borderStyle: 'solid',
borderColor: theme.palette.divider,
},
})}
>
<Typography>
<code>domainLimit=&quot;nice&quot;</code>, range from -100 to 100
</Typography>
<Stack
sx={{
width: '100%',
}}
direction="row"
spacing={2}
>
<Box sx={{ flexGrow: 1 }}>
<SparkLineChart data={values} {...settings} />
</Box>
<Box sx={{ flexGrow: 1 }}>
<SparkLineChart plotType="bar" data={values} {...settings} />
</Box>
</Stack>
<Typography>With strict domain limit</Typography>
<Typography>
<code>domainLimit=&quot;strict&quot;</code>, range from -15 to 92
</Typography>
<Stack sx={{ width: '100%' }} direction="row" spacing={2}>
<Box sx={{ flexGrow: 1 }}>
<SparkLineChart
Expand All @@ -43,13 +73,16 @@ export default function CustomDomainYAxis() {
/>
</Box>
</Stack>
<Typography>With custom function domain limit</Typography>
<Typography>custom function, range from -50 to 100</Typography>
<Stack sx={{ width: '100%' }} direction="row" spacing={2}>
<Box sx={{ flexGrow: 1 }}>
<SparkLineChart
data={values}
yAxis={{
domainLimit: ([min, max]) => [min - (min % 10), max + 10 - (max % 10)],
domainLimit: ([min, max]) => [
min - (Math.abs(min) % 50),
max + 50 - (Math.abs(max) % 50),
],
}}
{...settings}
/>
Expand All @@ -59,7 +92,7 @@ export default function CustomDomainYAxis() {
plotType="bar"
data={values}
yAxis={{
domainLimit: ([min, max]) => [min - (min % 10), max + 10 - (max % 10)],
domainLimit: ([min, max]) => [extend(min, 50), extend(max, 50)],
}}
{...settings}
/>
Expand Down
9 changes: 8 additions & 1 deletion docs/data/charts/sparkline/sparkline.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ The first row has the default y-axis values, while on the second row a fixed ran

{{"demo": "CustomYAxis.js"}}

You can adjust the y-axis range of a sparkline using the `domainLimit` option in the `yAxis` configuration. The demo below shows different ways to set the y-axis range, including default behavior, a strict data-bound range, and a custom function that adjusts the range to rounded values.
You can adjust the y-axis range of a sparkline relatively to its data by using the `domainLimit` option in the `yAxis` configuration.

- `"nice"` Rounds the domain at human friendly values. It's the default behavior.
- `"strict"` Sets the domain to the min/max value to display.
- `([minValue, maxValue]) => [min, max]` Takes the range of value to be display by the axis and return the axis range.

The demo below shows different ways to set the y-axis range.
They always display the same data, going from -15 to 92, but with different `domainLimit` settings.
JCQuintas marked this conversation as resolved.
Show resolved Hide resolved

{{"demo": "CustomDomainYAxis.js"}}
2 changes: 1 addition & 1 deletion docs/translations/api-docs/charts/axis-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"description": "The key used to retrieve <code>data</code> from the <code>dataset</code> prop."
},
"domainLimit": {
"description": "Defines the axis scale domain based on the min/max values of series linked to it.<br />- &#39;nice&#39;: Rounds the domain at human friendly values.<br />- &#39;strict&#39;: Set the domain to the min/max value provided. No extras space is added.<br />- function: takes as an argument an array with the min/max displayed values, and return the domain."
"description": "Defines the axis scale domain based on the min/max values of series linked to it.<br />- &#39;nice&#39;: Rounds the domain at human friendly values.<br />- &#39;strict&#39;: Set the domain to the min/max value provided. No extras space is added.<br />- function: Takes the extremums to display as an arrgument, and return the axis domain."
},
"hideTooltip": { "description": "If <code>true</code>, hide this value in the tooltip" },
"max": {
Expand Down
8 changes: 5 additions & 3 deletions packages/x-charts/src/internals/computeAxisValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,17 +198,19 @@ export function computeAxisValue({

const scaleType = axis.scaleType ?? ('linear' as const);

const domainLimit = axis.domainLimit ?? 'nice';

const axisExtremums =
typeof axis.domainLimit === 'function'
? axis.domainLimit([minData, maxData])
typeof domainLimit === 'function'
? domainLimit([minData, maxData])
: [axis.min ?? minData, axis.max ?? maxData];
const rawTickNumber = getTickNumber({ ...axis, range, domain: axisExtremums });
const tickNumber = rawTickNumber / ((zoomRange[1] - zoomRange[0]) / 100);

const zoomedRange = zoomScaleRange(range, zoomRange);

const scale = getScale(scaleType, axisExtremums, zoomedRange);
const finalScale = axis.domainLimit === 'strict' ? scale : scale.nice(rawTickNumber);
const finalScale = domainLimit === 'nice' ? scale.nice(rawTickNumber) : scale;
GuillaumeMeheut marked this conversation as resolved.
Show resolved Hide resolved
const [minDomain, maxDomain] = finalScale.domain();
const domain = [axis.min ?? minDomain, axis.max ?? maxDomain];

Expand Down
2 changes: 1 addition & 1 deletion packages/x-charts/src/models/axis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ export type AxisConfig<
* Defines the axis scale domain based on the min/max values of series linked to it.
* - 'nice': Rounds the domain at human friendly values.
* - 'strict': Set the domain to the min/max value provided. No extras space is added.
* - function: takes as an argument an array with the min/max displayed values, and return the domain.
* - function: Takes the extremums to display as an arrgument, and return the axis domain.
JCQuintas marked this conversation as resolved.
Show resolved Hide resolved
*/
domainLimit?: 'nice' | 'strict' | ((range: [number, number]) => [number, number]);
JCQuintas marked this conversation as resolved.
Show resolved Hide resolved
} & Omit<Partial<AxisProps>, 'axisId'> &
Expand Down