Skip to content

fix(echarts): keep forced x-axis boundary labels from overlapping and… - #45850

Open
PrakharAgarwal17 wants to merge 6 commits into
apache:masterfrom
PrakharAgarwal17:fix/timeseries-boundary-labels
Open

PrakharAgarwal17 wants to merge 6 commits into
apache:masterfrom
PrakharAgarwal17:fix/timeseries-boundary-labels

Conversation

@PrakharAgarwal17

Copy link
Copy Markdown

SUMMARY

Fixes #45489.

Forced x-axis boundary labels could overlap nearby regular ticks and lacked enough date context with Adaptive formatting.

This change:

  • Shows standalone daily boundary dates, such as Wed 5 Mar 2014 and Mon 17 Aug 2026.
  • Reserves space for both boundary labels, hiding regular ticks that would collide with them.
  • Accounts for boundary alignment and the chart’s actual left/right padding.
  • Preserves explicit custom formats, the “All labels” option, and Hour-grain precision.

Regression coverage includes both boundaries, repeated formatting passes, exact spacing thresholds, narrow plots, missing or degenerate domains, custom formats, and Day/Date/Hour grains.

Implementation and tests were developed with AI assistance.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Before: Wed 05 lacks month/year context, and 2026 overlaps Mon 17.

Superset Dark Dashboard Chart

After: Boundary labels include full date context, and colliding regular ticks are hidden.

Screenshot 2026-10-29 204129

TESTING INSTRUCTIONS

  1. Create a Line Chart with Day grain and data spanning 2014-03-05 to 2026-08-17.
  2. Select Adaptive formatting, label rotation 0, and automatic label spacing.
  3. Resize the dashboard around 1,280–1,400px, where the final year tick would collide with the boundary label.
  4. Confirm both boundary dates have standalone context and nearby regular ticks yield to them.

Automated validation: 217 tests passed across two focused Jest suites, plus scoped pre-commit checks including formatting, lint, and TypeScript checking.

Jest command, run from superset-frontend in the prepared test environment:

node node_modules/jest/bin/jest.js \
  --runInBand \
  --cacheDirectory=node_modules/.cache/jest \
  --runTestsByPath \
  plugins/plugin-chart-echarts/test/utils/formatters.test.ts \
  plugins/plugin-chart-echarts/test/Timeseries/transformProps.test.ts \
  --roots plugins/plugin-chart-echarts/test/utils \
  plugins/plugin-chart-echarts/test/Timeseries spec

ADDITIONAL INFORMATION

@codeant-ai-for-open-source

codeant-ai-for-open-source Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

CodeAnt  CodeAnt PR Risk

🟢  Low Risk

  • The PR appears safe to merge; no actionable issues were identified in the review.

Assessed commit: 8577108d8749

@codecov

codecov Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.95918% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.69%. Comparing base (7ad1d7f) to head (1cbf02b).
⚠️ Report is 28 commits behind head on master.

Files with missing lines Patch % Lines
...hart-echarts/src/MixedTimeseries/transformProps.ts 50.00% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master   #45850   +/-   ##
=======================================
  Coverage   84.69%   84.69%           
=======================================
  Files        3069     3069           
  Lines      205489   205573   +84     
  Branches    48314    48361   +47     
=======================================
+ Hits       174035   174119   +84     
  Misses      28164    28164           
  Partials     3290     3290           
Flag Coverage Δ
javascript 80.95% <97.95%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@villebro

Copy link
Copy Markdown
Member

@sadpandajoe are we ok to merge? This one is going into 7.0.0rc3

TIMESERIES_CONSTANTS.xAxisLabelMinGapPx
((domainMin !== undefined &&
domainMax !== undefined &&
value >= domainMin &&

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.

domainMin/domainMax and pixelsPerMs are fixed to the full data extent when the formatter is built, so after a zoom the reservation still protects boundary labels that are no longer on screen. Example: daily data Jan 1 2026–Jan 1 2027, 400px plot, %Y-%m-%d; zoom to Jan 10–Mar 1. Jan 10 is ~9px from domainMin in full-domain scale, well under the reserved boundary width, so every visible tick (including both zoom edges) formats to '' and the axis is blank, where before it kept Jan 10. Should the reservation be skipped (or computed from the visible extent) when the boundary label isn't within the zoomed range?

@PrakharAgarwal17 PrakharAgarwal17 Oct 30, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks for pointing out , I'll look into this issue and try to reproduce it locally first then fix it

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.

This still reproduces at the current head: ECharts keeps calling this same formatter for the zoomed ticks, so with daily data Jan 1 2026–Jan 1 2027, a 400px plot and %Y-%m-%d, zooming to Jan 10–Mar 1 returns '' for all 10 visible ticks, because the reserved width belongs to the off-screen full-range boundary labels. Could the reservation apply only when a boundary is actually in view, or be skipped once dataZoom narrows the range? A test that dispatches a dataZoom to a sub-range and asserts the visible labels are not all empty would pin it.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks for the detailed reproduction. The formatter now uses the visible axis extent and actual plot width, so off-screen boundaries no longer reserve space after zooming.

I also added a regression test using a real ECharts dataZoom action for the exact 400px, Jan 10–Mar 1 case. It checks the rendered endpoint labels after zooming, panning, and resetting. The test passes locally.

Math.max(width - 2 * TIMESERIES_CONSTANTS.gridOffsetLeft, 0),
Math.max(width - padding.left - padding.right, 0),
showAllLabels,
getTooltipTimeFormatter(boundaryTimeFormat, resolvedTimeGrain),

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.

On a narrow chart the two full-date boundary labels can now collide: a 180px-wide Day-grain chart spanning Mar 5 2014–Aug 17 2026 renders Wed 5 Mar 2014 and Mon 17 Aug 2026 overlapping by roughly 69px (before this change the short Wed 05 / Mon 17 stayed separate), and the spacing check never blanks a boundary label while hideOverlap is off. Should the full-date format fall back to the short one when both boundary labels don't fit in the plot width?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed this as well. When both full-date boundary labels cannot fit on one row, the last label moves to a second row, preserving the standalone date context.

Added a regression test for the exact 180px chart that checks both dates remain inside the canvas without overlapping. Also verified it manually in the browser.

@netlify

netlify Bot commented Oct 30, 2026

Copy link
Copy Markdown

✅ Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 8577108
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6ae48150c855581d8fa6ff92
😎 Deploy Preview https://deploy-preview-45850--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@sfirke

sfirke commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

I deployed this to my test environment and it looks good to me from a user acceptance testing (UAT) perspective. I did not review the code, just manual QA. Here's what the chart from my bug report looks like now:
image

The front/end dates change dynamically as you drag the zoom slider, which is pretty slick.

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.

Timeseries x-axis: forced first/last date labels overlap the neighboring tick label and show no month or year (7.0.0rc2)

4 participants