Skip to content

Conversation

bernardobelchior
Copy link
Member

@bernardobelchior bernardobelchior commented Jul 9, 2025

Fixes #18239.

Fix y-axis tick label overlap when using log scale and a custom valueFormatter.

Testing

Added zoom: true to the y-axis of the demos below.

Before:

Screen.Recording.2025-07-09.at.09.28.01.mov

After:

Screen.Recording.2025-07-09.at.09.27.26.mov

@bernardobelchior bernardobelchior added type: bug It doesn't behave as expected. scope: charts Changes related to the charts. labels Jul 9, 2025
@mui-bot
Copy link

mui-bot commented Jul 9, 2025

Deploy preview: https://deploy-preview-18744--material-ui-x.netlify.app/

Updated pages:

Bundle size report

Total Size Change: 🔺+5.29KB(+0.04%) - Total Gzip Change: 🔺+913B(+0.02%)
Files: 122 total (0 added, 0 removed, 38 changed)

Show details for 100 more bundles (22 more not shown)

@mui/x-chartsparsed: 🔺+392B(+0.13%) gzip: 🔺+65B(+0.07%)
@mui/x-charts-proparsed: 🔺+392B(+0.10%) gzip: 🔺+58B(+0.05%)
@mui/x-charts/ChartsYAxisparsed: 🔺+386B(+0.58%) gzip: 🔺+92B(+0.38%)
@mui/x-charts/ChartsXAxisparsed: 🔺+383B(+0.56%) gzip: 🔺+91B(+0.37%)
@mui/x-charts-pro/BarChartProparsed: 🔺+369B(+0.13%) gzip: 🔺+66B(+0.08%)
@mui/x-charts-pro/FunnelChartparsed: 🔺+369B(+0.15%) gzip: 🔺+48B(+0.06%)
@mui/x-charts-pro/Heatmapparsed: 🔺+369B(+0.16%) gzip: 🔺+49B(+0.07%)
@mui/x-charts-pro/LineChartProparsed: 🔺+369B(+0.13%) gzip: 🔺+119B(+0.13%)
@mui/x-charts-pro/ScatterChartProparsed: 🔺+369B(+0.14%) gzip: 🔺+62B(+0.07%)
@mui/x-charts/BarChartparsed: 🔺+369B(+0.17%) gzip: 🔺+78B(+0.12%)
@mui/x-charts/ChartsAxisparsed: 🔺+369B(+0.52%) gzip: 🔺+49B(+0.19%)
@mui/x-charts/ChartsGridparsed: 🔺+369B(+0.62%) gzip: 🔺+61B(+0.29%)
@mui/x-charts/LineChartparsed: 🔺+369B(+0.16%) gzip: 🔺+60B(+0.09%)
@mui/x-charts/ScatterChartparsed: 🔺+369B(+0.19%) gzip: 🔺+48B(+0.08%)
@mui/x-charts-pro/RadarChartProparsed: 🔺+23B(+0.01%) gzip: 🔺+13B(+0.02%)
@mui/x-charts/RadarChartparsed: 🔺+23B(+0.01%) gzip: 🔺+13B(+0.02%)
@mui/x-charts-pro/ChartContainerProparsed: 0B(0.00%) gzip: ▼-6B(-0.01%)
@mui/x-charts-pro/ChartDataProviderProparsed: 0B(0.00%) gzip: ▼-3B(-0.01%)
@mui/x-charts-pro/ChartsToolbarProparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts-pro/ChartZoomSliderparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts-pro/PieChartProparsed: 0B(0.00%) gzip: ▼-1B(0.00%)
@mui/x-charts/ChartContainerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartDataProviderparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsAxisHighlightparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsClipPathparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsLabelparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsLegendparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsLocalizationProviderparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsOverlayparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsReferenceLineparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsSurfaceparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsTextparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsTooltipparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/Gaugeparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/PieChartparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/SparkLineChartparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/Toolbarparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-data-gridparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-data-grid-premiumparsed: 0B(0.00%) gzip: ▼-3B(0.00%)
@mui/x-data-grid-premium/DataGridPremiumparsed: 0B(0.00%) gzip: ▼-4B(0.00%)
@mui/x-data-grid-proparsed: 0B(0.00%) gzip: ▼-1B(0.00%)
@mui/x-data-grid-pro/DataGridProparsed: 0B(0.00%) gzip: ▼-1B(0.00%)
@mui/x-data-grid/DataGridparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickersparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-proparsed: 0B(0.00%) gzip: ▼-5B(-0.01%)
@mui/x-date-pickers-pro/AdapterDateFnsparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/AdapterDateFnsJalaliparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/AdapterDayjsparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/AdapterLuxonparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/AdapterMomentparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/AdapterMomentHijriparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/AdapterMomentJalaaliparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/DateRangeCalendarparsed: 0B(0.00%) gzip: ▼-3B(-0.01%)
@mui/x-date-pickers-pro/DateRangePickerparsed: 0B(0.00%) gzip: ▼-3B(-0.01%)
@mui/x-date-pickers-pro/DateRangePickerDayparsed: 0B(0.00%) gzip: ▼-3B(-0.04%)
@mui/x-date-pickers-pro/DateRangePickerDay2parsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/DateTimeRangePickerparsed: 0B(0.00%) gzip: ▼-3B(0.00%)
@mui/x-date-pickers-pro/DesktopDateRangePickerparsed: 0B(0.00%) gzip: ▼-4B(-0.01%)
@mui/x-date-pickers-pro/DesktopDateTimeRangePickerparsed: 0B(0.00%) gzip: ▼-3B(-0.01%)
@mui/x-date-pickers-pro/DesktopTimeRangePickerparsed: 0B(0.00%) gzip: ▼-2B(0.00%)
@mui/x-date-pickers-pro/LocalizationProviderparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/MobileDateRangePickerparsed: 0B(0.00%) gzip: ▼-3B(-0.01%)
@mui/x-date-pickers-pro/MobileDateTimeRangePickerparsed: 0B(0.00%) gzip: ▼-4B(-0.01%)
@mui/x-date-pickers-pro/MobileTimeRangePickerparsed: 0B(0.00%) gzip: ▼-1B(0.00%)
@mui/x-date-pickers-pro/MultiInputDateRangeFieldparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/MultiInputDateTimeRangeFieldparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/MultiInputTimeRangeFieldparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/PickersRangeCalendarHeaderparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/SingleInputDateRangeFieldparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/SingleInputDateTimeRangeFieldparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/SingleInputTimeRangeFieldparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/StaticDateRangePickerparsed: 0B(0.00%) gzip: ▼-1B(0.00%)
@mui/x-date-pickers-pro/TimeRangePickerparsed: 0B(0.00%) gzip: ▼-2B(0.00%)
@mui/x-date-pickers/AdapterDateFnsparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/AdapterDateFnsBaseparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/AdapterDateFnsJalaliparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/AdapterDayjsparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/AdapterLuxonparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/AdapterMomentparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/AdapterMomentHijriparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/AdapterMomentJalaaliparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DateCalendarparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DateFieldparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DatePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DateTimeFieldparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DateTimePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DayCalendarSkeletonparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DesktopDatePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DesktopDateTimePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DesktopTimePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/DigitalClockparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/LocalizationProviderparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/MobileDatePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/MobileDateTimePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/MobileTimePickerparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/MonthCalendarparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/MultiSectionDigitalClockparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/PickerDay2parsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/PickersActionBarparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers/PickersCalendarHeaderparsed: 0B(0.00%) gzip: 0B(0.00%)

Details of bundle changes

Generated by 🚫 dangerJS against 3153dfb

Copy link

codspeed-hq bot commented Jul 9, 2025

CodSpeed Performance Report

Merging #18744 will not alter performance

Comparing bernardobelchior:fix-log-label-overlap (3153dfb) with master (dfe85de)

Summary

✅ 10 untouched benchmarks

@@ -175,7 +175,6 @@ export const rawData = [
{ code: 'SLB', population: 728147, gdpPerCapita: 2223.66502559565 },
{ code: 'SOM', population: 16030971, gdpPerCapita: 539.893931565468 },
{ code: 'ZAF', population: 59587885, gdpPerCapita: 6533.71121032856 },
{ code: 'KOR', population: 51764822, gdpPerCapita: 31902.4169048194 },
Copy link
Member Author

Choose a reason for hiding this comment

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

This entry was duplicated:

Image

@@ -64,120 +64,148 @@ export type TickItemType = {
labelOffset: number;
};

export function useTicks(
export function getTicks(
Copy link
Member Author

Choose a reason for hiding this comment

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

The diff is a bit tricky, but transformed the of useMemo inside useTicks into getTicks so it's easier to test

import { expect } from 'vitest';
import { getTicks } from './useTicks';

describe('getTicks', () => {
Copy link
Member Author

Choose a reason for hiding this comment

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

Second test is failing when running against the same code as master:

Image

@bernardobelchior bernardobelchior marked this pull request as ready for review July 9, 2025 08:27
Copy link
Member

@JCQuintas JCQuintas left a comment

Choose a reason for hiding this comment

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

minor question

*/
scale: AxisScaleConfig[S]['scale'];
/**
* The tick label shown by default if the value isn't formatted.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* The tick label shown by default if the value isn't formatted.
* The tick label shown by default if the value isn't formatted.
* With log scale it can be an empty string to display ticks without labels.
* @see See {@link https://d3js.org/d3-scale/log#log_tickFormat D3 log scale docs} for more details.```

Copy link
Member Author

Choose a reason for hiding this comment

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

What is the reasoning for including the link to D3? I wasn't planning on doing that, but I also changed the docs a bit.

Copy link
Member

Choose a reason for hiding this comment

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

My idea was per sentence

  1. Explicitly say that for log-scale formatted value can be an empty string. Which might be disturbing
  2. Link users to the root explanation about which tick gets a label and which don't get one.

If you find it more confusing than helping, no issue for not including that

Copy link
Member Author

Choose a reason for hiding this comment

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

Added 👍

scale: AxisScaleConfig[S]['scale'];
/**
* The tick label shown by default if the value isn't formatted.
* This value might be an empty string if no tick label should be displayed, which is particularly useful in log
Copy link
Member

Choose a reason for hiding this comment

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

From what I know this behavior is specific to log scales. All the other ones always retruen a non empty string

@bernardobelchior bernardobelchior merged commit afe97c1 into mui:master Jul 16, 2025
23 checks passed
@bernardobelchior bernardobelchior deleted the fix-log-label-overlap branch July 16, 2025 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
scope: charts Changes related to the charts. type: bug It doesn't behave as expected.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[charts] Overlapping tick labels in y axis when using log scale
4 participants