Skip to content

feat(react-charts): allow a function for cartesian tickFormat - #36369

Open
Michael Flanakin (flanakin) wants to merge 10 commits into
microsoft:masterfrom
flanakin:feat/react-charts-function-tickformat
Open

feat(react-charts): allow a function for cartesian tickFormat#36369
Michael Flanakin (flanakin) wants to merge 10 commits into
microsoft:masterfrom
flanakin:feat/react-charts-function-tickformat

Conversation

@flanakin

Copy link
Copy Markdown

Summary

Widens the cartesian tickFormat prop from string to string | ((value: number | Date) => string).

Motivation: A d3-format string cannot express two common value-axis needs:

  • A literal % — d3's % type multiplies by 100, double-scaling an already-0–100 axis (e.g. a 100%-stacked bar); there is no escape slot, so ~s%, %%, \% all throw invalid format.
  • App/i18n formatting — routing ticks through an app's own currency/number formatter so axis ticks match tooltip/callout values; d3's $ only emits its locale symbol.

HorizontalBarChartWithAxis (whose value axis is the x-axis) is most affected.

Change: When a function is passed, it is called directly with the tick value instead of going through d3Format. String behavior is unchanged — fully backward compatible.

Files changed

  • CartesianChart.types.tstickFormat type widened on CartesianChartProps and ModifiedCartesianChartProps.tickParams
  • utilities.tsITickParams.tickFormat type updated; createNumericXAxis and createDateXAxis branch on typeof tickFormat
  • UtilityUnitTests.test.ts — two new tests covering function tickFormat for numeric and date axes
  • HorizontalBarChartWithAxisFunctionTickFormat.stories.tsx — new Storybook story demonstrating literal % on a 0–100 axis
  • react-charts.api.md — API surface updated to match

Test plan

  • yarn nx run react-charts:test — 152 passed, 10 skipped (timezone-gated), 0 failed
  • New story verified visually in Storybook: x-axis renders 0%100% correctly
  • Existing string tickFormat behavior unchanged (covered by existing snapshot tests)
  • yarn nx run react-charts:lint
  • yarn nx run react-charts:type-check

Checklist

  • Change file added (change/@fluentui-react-charts-function-tickformat.json, type: minor)
  • Public API docs updated (react-charts.api.md)
  • Tests added for new behavior
  • Backward compatible — string path unchanged

🤖 Generated with Claude Code

The cartesian `tickFormat` prop is a d3-format string, applied as
`d3Format(tickFormat)(value)`. A string cannot express two common value-axis
needs:

- A literal `%` — d3's `%` type multiplies by 100 (`format('%')(50)` → `5000%`),
  double-scaling an already-0–100 axis (e.g. a 100%-stacked bar); there is no
  literal/escape slot, so `~s%`, `%%`, `\%`, `'%'` all throw `invalid format`.
- App/i18n formatting — routing ticks through the app's own currency/number
  formatter so axis ticks match tooltip/callout values; d3's `$` only emits its
  locale symbol.

`HorizontalBarChartWithAxis`, whose value axis is the x-axis, is most affected.

Widen `tickFormat` to `string | ((value: number | Date) => string)` and branch in
`createNumericXAxis` and `createDateXAxis`. Backward compatible: a string keeps
the exact current d3 behavior; only a function is new.
Copilot AI review requested due to automatic review settings July 5, 2026 08:16
@flanakin
Michael Flanakin (flanakin) requested a review from a team as a code owner July 5, 2026 08:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR extends the @fluentui/react-charts cartesian tickFormat API to accept either a d3-format string or a (value: number | Date) => string callback, enabling custom/i18n formatting and literal % rendering for 0–100 numeric axes.

Changes:

  • Widened tickFormat types in the cartesian chart public props and internal tick params.
  • Updated numeric/date x-axis tick formatting to support function-based formatting.
  • Added unit tests and a new HorizontalBarChartWithAxis Storybook example demonstrating literal % ticks.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/charts/react-charts/stories/src/HorizontalBarChartWithAxis/index.stories.tsx Adds export for the new tickFormat-function story.
packages/charts/react-charts/stories/src/HorizontalBarChartWithAxis/HorizontalBarChartWithAxisFunctionTickFormat.stories.tsx New story demonstrating function tickFormat for literal % on a 0–100 axis.
packages/charts/react-charts/library/src/utilities/UtilityUnitTests.test.ts Adds tests for function-based tickFormat on numeric and date axes.
packages/charts/react-charts/library/src/utilities/utilities.ts Implements function handling for tickFormat in numeric/date axis creation.
packages/charts/react-charts/library/src/components/CommonComponents/CartesianChart.types.ts Updates public prop types/docs for tickFormat and tickParams.tickFormat.
packages/charts/react-charts/library/etc/react-charts.api.md Updates extracted API to reflect widened tickFormat types.
change/@fluentui-react-charts-function-tickformat.json Adds a minor change file for the public API enhancement.

Comment thread packages/charts/react-charts/library/src/utilities/utilities.ts
Comment thread packages/charts/react-charts/library/src/utilities/utilities.ts Outdated
…rmat

- Convert NumberValue to primitive before passing to function tickFormat
  in createNumericXAxis so consumer formatters always receive a number
- Move function tickFormat check above timeFormatLocale in createDateXAxis
  so callers can override locale formatting

Co-Authored-By: Copilot <copilot@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@@ -0,0 +1,7 @@
{
"type": "minor",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

change type to patch

@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown

📊 Bundle size report

Package & Exports Baseline (minified/GZIP) PR Change
react-charts
AreaChart
406.892 kB
127.178 kB
407.018 kB
127.198 kB
126 B
20 B
react-charts
DeclarativeChart
758.436 kB
222.685 kB
758.562 kB
222.699 kB
126 B
14 B
react-charts
GanttChart
390.022 kB
121.659 kB
390.148 kB
121.68 kB
126 B
21 B
react-charts
GroupedVerticalBarChart
398.105 kB
124.449 kB
398.231 kB
124.47 kB
126 B
21 B
react-charts
HeatMapChart
392.162 kB
122.7 kB
392.288 kB
122.723 kB
126 B
23 B
react-charts
LineChart
418.241 kB
130.308 kB
418.367 kB
130.325 kB
126 B
17 B
react-charts
ScatterChart
397.565 kB
124.365 kB
397.691 kB
124.383 kB
126 B
18 B
react-charts
VerticalBarChart
434.556 kB
129.335 kB
434.682 kB
129.354 kB
126 B
19 B
react-charts
VerticalStackedBarChart
404.12 kB
125.841 kB
404.246 kB
125.857 kB
126 B
16 B
Unchanged fixtures
Package & Exports Size (minified/GZIP)
react-charts
DonutChart
317.723 kB
97.973 kB
react-charts
FunnelChart
309.123 kB
94.771 kB
react-charts
GaugeChart
317.073 kB
97.398 kB
react-charts
HorizontalBarChart
297.399 kB
90.467 kB
react-charts
HorizontalBarChartWithAxis
63 B
83 B
react-charts
Legends
236.586 kB
71.05 kB
react-charts
PolarChart
345.578 kB
108.001 kB
react-charts
SankeyChart
213.787 kB
68.717 kB
react-charts
Sparkline
80.888 kB
26.864 kB
🤖 This report was generated against 25b0646fa18bb93e2d7ed052379b852a1f45d8f4

@github-actions

Copy link
Copy Markdown

Pull request demo site: URL

@@ -0,0 +1,7 @@
{

@github-actions github-actions Bot Aug 17, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🕵🏾‍♀️ visual changes to review in the Visual Change Report

vr-tests-react-components/Menu Converged - submenuIndicator slotted content 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Menu Converged - submenuIndicator slotted content.default - RTL.submenus open.chromium.png 404 Changed
vr-tests-react-components/Menu Converged - submenuIndicator slotted content.default.submenus open.chromium.png 413 Changed
vr-tests-react-components/Positioning 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Positioning.Positioning end.updated 2 times.chromium.png 515 Changed
vr-tests-react-components/ProgressBar converged 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness - Dark Mode.default.chromium.png 25 Changed
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness.default.chromium.png 54 Changed
vr-tests-react-components/TagPicker 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/TagPicker.disabled - RTL.disabled input hover.chromium.png 635 Changed
vr-tests-react-components/TagPicker.disabled.disabled input hover.chromium.png 677 Changed

There were 2 duplicate changes discarded. Check the build logs for more information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants