Skip to content

Conversation

JCQuintas
Copy link
Member

@JCQuintas JCQuintas commented Jul 14, 2025

Fixes #18777

Screenshot 2025-07-14 at 13 07 47

@JCQuintas JCQuintas self-assigned this Jul 14, 2025
@JCQuintas JCQuintas added the type: new feature Expand the scope of the product to solve a new problem. label Jul 14, 2025
@JCQuintas JCQuintas added the scope: charts Changes related to the charts. label Jul 14, 2025
@mui-bot
Copy link

mui-bot commented Jul 14, 2025

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

Updated pages:

Bundle size report

Total Size Change: 🔺+2.54KB(+0.02%) - Total Gzip Change: 🔺+1.16KB(+0.03%)
Files: 122 total (0 added, 0 removed, 37 changed)

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

@mui/x-chartsparsed: 🔺+250B(+0.08%) gzip: 🔺+116B(+0.13%)
@mui/x-charts-proparsed: 🔺+250B(+0.06%) gzip: 🔺+102B(+0.09%)
@mui/x-charts-pro/BarChartProparsed: 🔺+250B(+0.09%) gzip: 🔺+112B(+0.13%)
@mui/x-charts-pro/LineChartProparsed: 🔺+250B(+0.09%) gzip: 🔺+101B(+0.11%)
@mui/x-charts-pro/ScatterChartProparsed: 🔺+250B(+0.09%) gzip: 🔺+107B(+0.13%)
@mui/x-charts/BarChartparsed: 🔺+250B(+0.12%) gzip: 🔺+117B(+0.18%)
@mui/x-charts/SparkLineChartparsed: 🔺+250B(+0.12%) gzip: 🔺+116B(+0.18%)
@mui/x-charts-pro/ChartZoomSliderparsed: 🔺+205B(+0.19%) gzip: 🔺+81B(+0.23%)
@mui/x-charts-pro/ChartContainerProparsed: 🔺+45B(+0.02%) gzip: 🔺+23B(+0.04%)
@mui/x-charts-pro/ChartDataProviderProparsed: 🔺+45B(+0.03%) gzip: 🔺+21B(+0.04%)
@mui/x-charts-pro/FunnelChartparsed: 🔺+45B(+0.02%) gzip: 🔺+28B(+0.04%)
@mui/x-charts-pro/Heatmapparsed: 🔺+45B(+0.02%) gzip: 🔺+27B(+0.04%)
@mui/x-charts-pro/PieChartProparsed: 🔺+45B(+0.02%) gzip: 🔺+21B(+0.03%)
@mui/x-charts-pro/RadarChartProparsed: 🔺+45B(+0.02%) gzip: 🔺+22B(+0.03%)
@mui/x-charts/ChartContainerparsed: 🔺+45B(+0.03%) gzip: 🔺+19B(+0.04%)
@mui/x-charts/ChartDataProviderparsed: 🔺+45B(+0.03%) gzip: 🔺+21B(+0.05%)
@mui/x-charts/Gaugeparsed: 🔺+45B(+0.03%) gzip: 🔺+18B(+0.04%)
@mui/x-charts/LineChartparsed: 🔺+45B(+0.02%) gzip: 🔺+24B(+0.03%)
@mui/x-charts/PieChartparsed: 🔺+45B(+0.02%) gzip: 🔺+23B(+0.04%)
@mui/x-charts/RadarChartparsed: 🔺+45B(+0.02%) gzip: 🔺+24B(+0.04%)
@mui/x-charts/ScatterChartparsed: 🔺+45B(+0.02%) gzip: 🔺+21B(+0.03%)
@mui/x-charts-pro/ChartsToolbarProparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsAxisparsed: 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/ChartsGridparsed: 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/ChartsXAxisparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-charts/ChartsYAxisparsed: 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: 🔺+1B(0.00%)
@mui/x-data-grid-premium/DataGridPremiumparsed: 0B(0.00%) gzip: 🔺+2B(0.00%)
@mui/x-data-grid-proparsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-data-grid-pro/DataGridProparsed: 0B(0.00%) gzip: 0B(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: 🔺+1B(0.00%)
@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: 0B(0.00%)
@mui/x-date-pickers-pro/DateRangePickerparsed: 0B(0.00%) gzip: 🔺+2B(0.00%)
@mui/x-date-pickers-pro/DateRangePickerDayparsed: 0B(0.00%) gzip: ▼-2B(-0.03%)
@mui/x-date-pickers-pro/DateRangePickerDay2parsed: 0B(0.00%) gzip: 0B(0.00%)
@mui/x-date-pickers-pro/DateTimeRangePickerparsed: 0B(0.00%) gzip: 🔺+2B(0.00%)
@mui/x-date-pickers-pro/DesktopDateRangePickerparsed: 0B(0.00%) gzip: 🔺+1B(0.00%)
@mui/x-date-pickers-pro/DesktopDateTimeRangePickerparsed: 0B(0.00%) gzip: 🔺+2B(0.00%)
@mui/x-date-pickers-pro/DesktopTimeRangePickerparsed: 0B(0.00%) gzip: 🔺+1B(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: 🔺+1B(0.00%)
@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: 🔺+1B(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 5de95e8

Copy link

codspeed-hq bot commented Jul 14, 2025

CodSpeed Performance Report

Merging #18798 will not alter performance

Comparing JCQuintas:bar-min-height (5de95e8) with master (9d31fcb)

Summary

✅ 10 untouched benchmarks


// Size is above the minimum size, so we can return the bar size and the min value coordinate.
if (!isSizeLessThanMin) {
return [barSize, minValueCoord];
Copy link
Member

Choose a reason for hiding this comment

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

Why return an array instead of an object? This isn't a hook nor is it clear the order of the elements. It'd make sense if it were [x, y], for example.

@@ -61,6 +60,8 @@ const seriesProcessor: SeriesProcessor<'bar'> = (params, dataset) => {
completedSeries[id] = {
layout: 'vertical',
labelMarkType: 'square',
minBarSize: 0,
valueFormatter: series[id].valueFormatter ?? ((v) => (v == null ? '' : v.toLocaleString())),
Copy link
Member

Choose a reason for hiding this comment

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

Could we move the default value formatter outside so that it's a stable function? Should help reduce re-renders.

setMinBarSize(newValue);
};

return (
Copy link
Member

Choose a reason for hiding this comment

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

If the min bar size is too great, the bars start growing from the top:

Screen.Recording.2025-07-14.at.15.12.33.mov

Do we want to handle this case?

Also, should minBarSize impact what's visible? For example, if due to minBarSize a bar isn't totally visible, should we update the y-axis? In other words, should minBarSize somehow affect the range so that it's always visible (unless min/max are specified on the y-axis)?

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 understand what you mean by this. The prop is only changing the visual representation of the bar

Copy link
Member Author

Choose a reason for hiding this comment

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

Do we want to handle this case?

We could accept px or percentage, otherwise I would leave it as is.

Copy link
Member

Choose a reason for hiding this comment

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

I don't understand what you mean by this. The prop is only changing the visual representation of the bar

In the video, the bar for "Tue" moves from starting at 0 to starting at around 5 once the minBarSize increases from 117px to 139px. Is that intended?

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, no that's weird, I'm looking into it

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 was using the wrong param, should be fixed now

@@ -35,6 +35,12 @@ export interface BarSeriesType
* @default 'diverging'
*/
stackOffset?: StackOffsetType;
/**
* If provided, this will be used as the minimum size of the bar.
Copy link
Member

Choose a reason for hiding this comment

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

What are the units?

Comment on lines 189 to 190
const isSizeLessThanMin = Math.abs(maxValueCoord - minValueCoord) < minBarSize;
const barSize = isSizeLessThanMin ? minBarSize : Math.abs(maxValueCoord - minValueCoord);
Copy link
Member

Choose a reason for hiding this comment

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

Before we didn't need Math.abs, why do we need it now? Isn't maxValueCoord always greater than minValueCoord, so the result is always non-negative?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not needed yeah, we already run math.min/math.max to get the coords

minBarSize: number,
): { barSize: number; startCoordinate: number } {
const isSizeLessThanMin = maxValueCoord - minValueCoord < minBarSize;
const barSize = isSizeLessThanMin ? minBarSize : maxValueCoord - minValueCoord;
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
const barSize = isSizeLessThanMin ? minBarSize : maxValueCoord - minValueCoord;
const barSize = Math.max(minBarSize, maxValueCoord - minValueCoord);

@JCQuintas JCQuintas merged commit 9c42731 into mui:master Jul 15, 2025
23 checks passed
@JCQuintas JCQuintas deleted the bar-min-height branch July 15, 2025 07:54
@alexfauquette
Copy link
Member

alexfauquette commented Jul 15, 2025

@JCQuintas I see two main edge cases in this PR

  • First issue is the case 0 which is impacted by the minHeight. I think it should be like null (not impacted)
image
  • Small detail: I don't think the demo needs to set minBarSize up to 200px. IMO 10px or event 20px should be enough

  • Second edge case: This work for single bar chart. For stacked one, it will not work, because you do the trick at the rendering level. But stacking appears before.

image

Either we accept this limitation but should mark it as a warning. Or we move the the computation at the stacking level
But at that step we don't have access to the scales. In that case the minBarSize should to be in px but in user value

- .value((d, key) => d[key] ?? 0) // defaultize null value to 0
+ .value((d, key) => !d[key] ? 0 : Math.max(minBarValue : d[key])) // defaultize null value to 0

@JCQuintas
Copy link
Member Author

@alexfauquette I don't think it makes much sense to allow this to work on stacked series. I've added a pr here with the 0/null changes: #18816

@alexfauquette
Copy link
Member

I don't think it makes much sense to allow this to work on stacked series.

This guy might disagree 🙈 But Recharts does not support it too. It's doing the same stuff as you rimplementation.
recharts/recharts#2441

But I'm good with leaving that for later

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: new feature Expand the scope of the product to solve a new problem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[charts] set min-height to bar element.
4 participants