Skip to content

[charts-pro] Fix highlight shifting on sampled bar charts#23190

Merged
JCQuintas merged 2 commits into
mui:masterfrom
noraleonte:fix-bars-highlight-shift
Jul 22, 2026
Merged

[charts-pro] Fix highlight shifting on sampled bar charts#23190
JCQuintas merged 2 commits into
mui:masterfrom
noraleonte:fix-bars-highlight-shift

Conversation

@noraleonte

Copy link
Copy Markdown
Contributor

Fix sampled bars and axis highlight misaligning on band axes (#22997):

  • Anchor sampled buckets at their left-most slot so reversed axes mirror instead of shifting off-screen.
  • Center the merged bar within its bucket region so the axis highlight sits on the bar instead of drifting into the inter-bucket gap

Before:
image
After:
image

closes #22997

@noraleonte
noraleonte requested a review from JCQuintas July 21, 2026 12:48
@noraleonte noraleonte self-assigned this Jul 21, 2026
@noraleonte noraleonte added type: bug It doesn't behave as expected. plan: Pro Impact at least one Pro user. scope: charts Changes related to the charts. labels Jul 21, 2026
@code-infra-dashboard

code-infra-dashboard Bot commented Jul 21, 2026

Copy link
Copy Markdown

Deploy preview

https://deploy-preview-23190--material-ui-x.netlify.app/
QR code for https://deploy-preview-23190--material-ui-x.netlify.app/

Bundle size

Bundle Parsed size Gzip size
@mui/x-data-grid 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-pro 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-premium 0B(0.00%) 0B(0.00%)
@mui/x-charts 🔺+188B(+0.05%) 🔺+67B(+0.06%)
@mui/x-charts-pro 🔺+188B(+0.04%) 🔺+59B(+0.04%)
@mui/x-charts-premium 🔺+188B(+0.03%) 🔺+73B(+0.04%)
@mui/x-date-pickers 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers-pro 0B(0.00%) 0B(0.00%)
@mui/x-tree-view 0B(0.00%) 0B(0.00%)
@mui/x-tree-view-pro 0B(0.00%) 0B(0.00%)
@mui/x-scheduler 0B(0.00%) 0B(0.00%)
@mui/x-scheduler-premium 0B(0.00%) 0B(0.00%)
@mui/x-chat 0B(0.00%) 0B(0.00%)
@mui/x-license 0B(0.00%) 0B(0.00%)

Details of bundle changes

Performance

Total duration: 1,358.36 ms -117.28 ms(-7.9%) | Renders: 63 (+0) | Paint: 1,924.33 ms -122.10 ms(-6.0%)

Test Duration Renders
RadialLineChart with big data amount 37.26 ms 🔺+9.99 ms(+36.6%) 2 (+0)
ScatterChartPro with big data amount (single renderer) 21.07 ms 🔺+7.92 ms(+60.3%) 2 (+0)
ScatterChartPro with big data amount and zoomed in (single renderer) 10.61 ms 🔺+3.79 ms(+55.6%) 2 (+0)
ScatterChartPro with big data amount (batch renderer) 11.01 ms 🔺+3.14 ms(+39.9%) 2 (+0)
RadialBarChart stacked with multiple series 13.10 ms ▼-15.04 ms(-53.5%) 2 (+0)

…and 6 more (+15 within noise) — details

Metric alarms

Test Metric Change
RadialLineChart with big data amount bench:paint 🔺 +12.87 ms
ScatterChartPro with big data amount (single renderer) bench:paint 🔺 +12.61 ms
ScatterChartPro with big data amount and zoomed in (single renderer) bench:paint 🔺 +4.96 ms
ScatterChartPro with big data amount (batch renderer) bench:paint 🔺 +5.70 ms
BarChartPro with big data amount bench:paint 🔺 +14.16 ms

Check out the code infra dashboard for more information about this PR.

@JCQuintas JCQuintas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice work, mostly nit picks

It also seems that argos picked a fix where we were drawing the initial bar from edge rather than from the "gap" 👍

Comment on lines +76 to +95
const geometry = (reverse: boolean) => {
const { container } = render(
<BarChartPro
series={[{ data: range(256) }]}
xAxis={[{ data: range(256).map(String), zoom: true, reverse }]}
yAxis={[{ position: 'none' }]}
width={width}
height={200}
margin={0}
sampling="minmax"
skipAnimation
/>,
);
return Array.from(container.querySelectorAll(`.${barClasses.element}`))
.map((bar) => ({ x: Number(bar.getAttribute('x')), width: Number(bar.getAttribute('width')) }))
.sort((a, b) => a.x - b.x);
};

const normal = geometry(false);
const reversed = geometry(true);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not sure it is a good idea to call render twice in the same test 🤔

Probably a more orthodox approach would be to either render both and use selectors for each, or "render, select, update props to reverse, select"

Comment on lines +25 to +28
[
{ reverse: false, leftIndex: 0 },
{ reverse: true, leftIndex: 3 },
].forEach(({ reverse, leftIndex }) => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Vitest has a it.for for these cases, but it's not necessary to change 😆

Comment on lines +37 to +38
// Anchor at the left edge: on a reversed axis `data[bucketStart]` is the right-most slot.
bandStart = Math.min(scale(data[bucketStart])!, scale(data[bucketEnd])!) - halfPadding;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe we should have a getBucketRegion(scale, startIndex, endIndex) fn

so that this and the code in createGetBarDimension are synced

@JCQuintas
JCQuintas merged commit dbb51f0 into mui:master Jul 22, 2026
22 checks passed
JCQuintas added a commit to SamanPandey-in/mui-x that referenced this pull request Jul 23, 2026
Master added getSampledBandHighlight.test.ts in mui#23052/mui#23190; keep that
suite and re-add the Date-reference regression test on top of it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

plan: Pro Impact at least one Pro user. 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-pro] Sampled bars/highlight drawn shifted on a reversed band axis

2 participants