Skip to content

Conversation

100pah
Copy link
Member

@100pah 100pah commented Jun 24, 2025

Brief Information

This pull request is in the type of:

  • bug fixing
  • new feature
  • others

Big thanks to @robin-gerling and @konrad-amtenbrink for their excellent work in #19534 and #16825!
This PR is a follow-up of them. Considering some backward compatibility, universally adoption and code maintainability, this PR make some changes in echarts option and implementation.

Brief:

  • Avoid axis labels and axis names overflowing the canvas (viewport) in Cartesian (grid component).
  • Avoid axis names overlapping with axis labels in Cartesian (grid component).
  • Make them the default.

Some related issues: #15654 #9265 #9286 #14996 #15562

Document and Usage

(The full document will be published on echarts website when v6.0.0 is released.)

Basic Usage

In most cases users do not need to set specific option, since this feature have been make as the default. But detailed tuning is require, check the new introduced options in:

Breaking Change and Restore

This feature introduces a breaking change against the previous echarts (v5.6.0-).

The position of Cartesian axes might shift slightly if the axis names or labels previously overflowed the canvas or overlapped, as anti-overflow and anti-axisLabel-axisName-overlap mechanism are enabled by default. In most cases that changes will be indiscernible to the naked eye. But if any unreasonable change occurs, you can use option grid.outerBoundsMode: 'none' to disable the anti-overflow mechanism, and/or use option xAxis/yAxis.axisLabel.nameMoveOverlap: false to disable the anti-axisLabel-axisName-overlap mechanism.

The old implementation of grid.containLabel:true has been moved to feature LegacyGridContainLabel.

  • In the prebuilt assets, LegacyGridContainLabel is imported by echarts/dist/echarts.all.js, but not imported by echarts/dist/echarts.common.js and echarts/dist/echarts.simple.js.
  • Or if manually importing, it needs to be explicitly imported by
    import * as echarts from 'echarts/core';
    import {LegacyGridContainLabel} from 'echarts/features';
    echarts.use(LegacyGridContainLabel);

If no LegacyGridContainLabel imported, grid.containLabel:true still works and uses the new implementation, which is more precise than the old one and is recommended.

Details

Before: What was the problem?

Axis labels and axis names may overflow the viewport:

grid.left/right/top/bottom/width/height determines a rect for cartesians (say, cartesianRect),

  • If grid.containLabel: false (default)
    • xAxis/yAxis line is placed on the edges of cartesianRect, the long axis labels and axis name may overflow the canvas (viewport), since the variation in seres.data makes it difficult for users to allocate proper spacing between axis line and viewport edges.
    • grid.containLabel: true can mitigate this issue.
  • If grid.containLabel: true,
    • the axis labels and axis lines are laid out inside the cartesianRect while touching the edges.
    • But there are still some defects:
      • Not precise - may overflow in some cases, due to the simple implementation of it.
      • Axis name not considered - they would still overflow.
      • Multiple charts - if multiple charts are on a same page, the axis lines can not align due to the variation of label length.
      • It's probably inappropriate to make grid.containLabel: true the default - doing so would introduce a significant breaking change, since many users have configured layout params based on grid.containLabel: false.

Axis name overlaps with axis labels

Especially when xAxis/yAxis.nameLocation: 'center'. This issues are not addressed previously, and the variation in axis label length (due to the variation in series.data) makes it difficult for users to allocate proper space between the axis name and axis line (by xAxis/yAxis.nameGap).

#19534 have made great implementation that makes containLabel also consider axisName. However, that would introduce significant breaking change, and it also introduced another way to compute the layout of axis names and axis labels. Having two mechanisms coexist could reduce the maintainability of the codebase. This is what this PR needed to resolve. Moreover, this PR aims to resolves all of the issues mentioned above, and makes overflow/overlap feature the default without bringing big breaking. And more edge cases are covered in this PR.

After: How does it behave after the fixing?

Avoid axis names overlapping with axis labels in Cartesian (grid component)
Before (if grid.containLabel: false):
z1_before_normal_speed

Before (if grid.containLabel: true):
z1_before_containLabel_speed

After:
z1_after_speed

Avoid axis labels and axis names overflowing the canvas (viewport) in Cartesian (grid component)
Before:
z2_before_speed

After:
z2_after_speed

The mechanism behind this:
grid.left/right/top/bottom/width/height determines a rect for cartesians (say, cartesianRect), and xAxis/yAxis line is firstly placed on the edges of cartesianRect. grid.outerBounds.left/right/top/bottom/width/height determines a rect for the outermost bounds (say, outerBoundsRect). If axis labels or names overflow the bounds, shrink the Cartesian to avoid overflowing. outerBoundsRect is the canvas (viewport) by default, and no need to be modified in most cases.

The example below uses colored indicator rectangles to visualize the cartesianRect and outerBoundsRect.
z3_indicator_0

The effect of modifying grid.left/right/top/bottom/width/height:
z3_indicator_1

The effect of modifying grid.outerBounds.left/right/top/bottom/width/height:
z3_indicator_2

Test

test/axis-layout-0.html

100pah added 16 commits April 6, 2025 18:53
… deprecated `grid.containLabel`. Support `grid.layoutContain.axisName` and `grid.layoutContain.axisLabel`.
…upport some complex input to build complex test cases. (3) Enhance mktest.
…in axisName (3) refactor: use the same logic to measure axisLabel/axisName contain and view build. (3) support auto avoid axisLabel and axisName overflow even containLabel is not specified, while also considered axis line alignment between different grids. Introduce `grid.outerBounds` and `grid.outerBoundsContain`.
… pure object. (2) fix name overlap cache bug. (3) make outerBounds merge as box layout merge.
# Conflicts:
#	src/component/axis/CartesianAxisView.ts
#	src/component/axis/axisBreakHelper.ts
#	src/coord/cartesian/Grid.ts
#	src/coord/cartesian/GridModel.ts
#	src/echarts.all.ts
#	src/export/features.ts
#	src/label/labelStyle.ts
#	src/util/graphic.ts
#	src/util/types.ts
#	test/build/mktest-tpl.html
#	test/lib/testHelper.js
#	test/tmp-base.html
….getBoundingRect wrongly include (0, 0, 0, 0) issue.
Copy link

echarts-bot bot commented Jun 24, 2025

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.

The pull request is marked to be PR: author is committer because you are a committer of this project.

⚠️ MISSING DOCUMENT INFO: Please make sure one of the document options are checked in this PR's description. Search "Document Info" in the description of this PR. This should be done either by the author or the reviewers of the PR.

@echarts-bot echarts-bot bot added the PR: awaiting doc Document changes is required for this PR. label Jun 24, 2025
Copy link

echarts-bot bot commented Jun 24, 2025

Document changes are required in this PR. Please also make a PR to apache/echarts-doc for document changes and update the issue id in the PR description. When the doc PR is merged, the maintainers will remove the PR: awaiting doc label.

Copy link
Contributor

The changes brought by this PR can be previewed at: https://echarts.apache.org/examples/editor?version=PR-21059@21d51a5

@Ovilia Ovilia merged commit b47e30c into next Jun 25, 2025
2 checks passed
Copy link

echarts-bot bot commented Jun 25, 2025

Congratulations! Your PR has been merged. Thanks for your contribution! 👍

Copy link

echarts-bot bot commented Jun 30, 2025

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR: author is committer PR: awaiting doc Document changes is required for this PR. size/XXL
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants