Skip to content

Conversation

@hcopp
Copy link
Contributor

@hcopp hcopp commented Jan 7, 2026

What changed? Why?

This PR enables customization of axis grid lines and tick marks when in band scale. Band scale is for discrete data, not continuous. Our bar charts use band scale for the x axis, and can use a continuous scale for y axis (linear or log).

Band scale has bands and steps, where the step portion contains padding. We allow placement in code when using getPointOnScale to be any of these anchor positions (such as stepStart or bandEnd) but only use the step start/end for the grid lines.

image

Previously our axis grid lines would be placed in the middle of the band:

image

Now, the default will be to have the grid lines be at the 'edges', which places them at the start and adds one more at the end for the last tick:

image

This can also be customized by teams.

image image

This feature is found in some other libraries and it is 50/50 on if their default is middle or edges/extremities for the grid lines.

We also support this for tick marks, but I did not add support for tick labels - something we could do in the future if a customer had a use case for it.

UI changes

iOS

Web

image image image image

Testing

How has it been tested?

  • Unit tests
  • Interaction tests
  • Pseudo State tests
  • Manual - Web
  • Manual - Android (Emulator / Device)
  • Manual - iOS (Emulator / Device)

Testing instructions

Illustrations/Icons Checklist

Required if this PR changes files under packages/illustrations/** or packages/icons/**

  • verified visreg changes with Terran (include link to visreg run/approval)
  • all illustration/icons names have been reviewed by Dom and/or Terran

Change management

type=routine
risk=low
impact=sev5

automerge=false

@hcopp hcopp self-assigned this Jan 7, 2026
@cb-heimdall
Copy link
Collaborator

cb-heimdall commented Jan 7, 2026

✅ Heimdall Review Status

Requirement Status More Info
Reviews 1/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 1
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1
CODEOWNERS ✅ See below

CODEOWNERS

Code Owner Status Calculation
ui-systems-eng-team 1/1
Denominator calculation
Additional CODEOWNERS Requirement
Show calculation
Sum 0
0
From CODEOWNERS 1
Sum 1

transition={animate ? { duration: 0.2, ease: 'easeOut' } : undefined}
transition={
animate ? { duration: accessoryFadeTransitionDuration, ease: 'easeOut' } : undefined
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Want to match the animation of grid lines

strokeCap="square"
strokeWidth={1}
/>
))}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Even though this functionality is being added to YAxis, there is no feasible way for customers to use a bandscale on y axis at this point in time.

However, this PR is laying the groundwork so we can support horizontal layouts (horizontal bar charts that go from left to right instead of bottom to top).

}
```

On band scales, you can also use `bandGridPlacement` to control where grid lines appear relative to each band.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't update BarChart's documentation since I plan on revamping the whole component doc in my next PR involving this work, where I hope to add support for layout="horizontal" to bar charts.

},
export const axisUpdateAnimationTransition = {
duration: accessoryFadeTransitionDuration,
};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We weren't correctly doing this animation on mobile so I removed it. The initial goal for this functionality was to nicely fade in and out grid lines coinciding with text as that previously wouldn't show immediately.

This is still the case on web but with our new mobile library we can immediately show text, since we are able to synchronously measure the bounding box of it with Skia.


import { useCartesianChartContext } from '../ChartProvider';
import { DottedLine } from '../line/DottedLine';
import { ReferenceLine } from '../line/ReferenceLine';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We previously used ReferenceLine to render the grid lines but this is no longer possible as we need to target a specific anchor within a band to render the lines at. ReferenceLine will always render in the middle of the band.

default:
return 'middle';
}
};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe having these two decoupled would be best, AxisBandPlacement and PointAnchor. PointAnchor could allow for more offsets in the future if we decide on supporting more scale types but these placements within the axis would likely not support those other positions.

position: position + ((scaleFunction as any).bandwidth?.() ?? 0) / 2,
};
})
.filter(Boolean) as Array<{ tick: number; position: number }>;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We are able to simplify several spots where we needed to manually find the middle of the band before.

@hcopp hcopp marked this pull request as ready for review January 7, 2026 21:43
.range([range.min, range.max])
.padding(padding);
.paddingInner(padding)
.paddingOuter(padding / 2);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change makes us have even spacing between each edge of the step and the band, meaning two bars next to each other now have twice as much space as the last bar has to the edge of the drawing area.

Before

Image

After

Image

This matches other libraries, such as MUI

Image

Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if this can be customized (or is it a strong enough use case for us to enable this customization?). If customer prefer the old outer padding can they switch it back?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could potentially open this up, but other libraries hardcode this ratio as well - https://github.com/mui/mui-x/blob/master/packages/x-charts/src/internals/plugins/featurePlugins/useChartCartesianAxis/getAxisScale.ts#L41.

There could be a benefit to allowing custom scales in general in the future, could be a clean way to open this up https://d3js.org/d3-scale/band since they'd get more than just being able to customize padding.

Copy link
Contributor

@haoruikun-cb haoruikun-cb left a comment

Choose a reason for hiding this comment

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

Great job! Left some suggestions & question

.range([range.min, range.max])
.padding(padding);
.paddingInner(padding)
.paddingOuter(padding / 2);
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if this can be customized (or is it a strong enough use case for us to enable this customization?). If customer prefer the old outer padding can they switch it back?

@hcopp hcopp merged commit 5264e97 into master Jan 8, 2026
22 checks passed
@hcopp hcopp deleted the hunter/chart-axis-band-line-alignment branch January 8, 2026 23:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

3 participants