Skip to content

fix(time): support formatter functions in time axis label formatter - #21821

Open
xh123637 wants to merge 1 commit into
apache:masterfrom
xh123637:fix/20027-time-axis-leveled-formatter
Open

xh123637 wants to merge 1 commit into
apache:masterfrom
xh123637:fix/20027-time-axis-leveled-formatter

Conversation

@xh123637

@xh123637 xh123637 commented Nov 6, 2026

Copy link
Copy Markdown

Brief Information

This pull request is in the type of:

  • bug fixing
  • new feature
  • others

What does this PR do?

Support formatter functions in the time axis label formatter dictionary, so a function can be used for a single time unit or level instead of only as a top-level formatter.

Fixed issues

Details

Before: What was the problem?

A time axis axisLabel.formatter given as a per-level dictionary of functions, e.g.

xAxis: {
    type: 'time',
    axisLabel: {
        formatter: {
            year: (value, index) => value + ' {yyyy}',
            month: (value, index) => value + '{MMM}',
            day: (value, index) => value + '{d}. {MMM}',
            // ...
        }
    }
}

did not work: parseTimeAxisLabelFormatterDictionary silently dropped the functions (they fell through to the default-template branch), so the labels were rendered with the default templates and the callbacks were never called. A function used inside a leveled template array, e.g. day: ['{d}', fn], was even worse: it survived into the parsed dictionary and leveledFormat passed it to format as a string template, throwing (template || "").replace is not a function and leaving the axis blank.

After: How does it behave after the fixing?

A formatter function can now be used in place of a string template at any position of the dictionary: per time unit ({year: fn, ...}), in the nested dictionary form ({day: {year: fn}}), or as an element of a leveled template array ({day: ['{d}', fn]}). The function is called with (value, index, extra) like a top-level formatter function, and its return value is used as the template for placeholder substitution, matching the existing top-level formatter behavior.

The dictionary builder now keeps function values as-is, and the string-concatenation and {primary|...} highlight logic only applies to string templates, so functions are never coerced to strings.

Tests

New leveledFormat tests in test/ut/spec/util/time.test.ts (5 cases):

  • per-level functions from the issue (flat dictionary), including the exact reproducer;
  • a function as a level-1 template in an array;
  • a function in the nested dictionary form;
  • the (value, index, extra) arguments passed to the function;
  • default templates still used for units without a formatter function.

All 5 new tests fail on the unmodified code (the flat-dictionary functions are ignored, the array form throws) and pass with the fix. test/ut/spec/util/time.test.ts: 20/20 pass; test/ut/spec/scale + test/ut/spec/util: 61/61 pass; test/ut/spec/component: 30/30 pass. npx tsc --noEmit and ESLint on the changed files are clean.

@echarts-bot

echarts-bot Bot commented Nov 6, 2026

Copy link
Copy Markdown

Thanks for your contribution!
The community will review it ASAP. In the meanwhile, please checkout the coding standard and Wiki about How to make a pull request.

Please DO NOT commit the files in dist, i18n, and ssr/client/dist folders in a non-release pull request. These folders are for release use only.

To reviewers: If this PR is going to be described in the changelog in the future release, please make sure this PR has one of the following labels: PR: doc ready, PR: awaiting doc, PR: doc unchanged

This message is shown because the PR description doesn't contain the document related template.

This branch has not been deployed

No deployments
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.

1 participant