Skip to content

fix(gantt): prevent y-axis category labels from being clipped - #44321

Open
aminghadersohi wants to merge 1 commit into
apache:masterfrom
aminghadersohi:aminghadersohi/gantt-y-axis-label-clipping
Open

aminghadersohi wants to merge 1 commit into
apache:masterfrom
aminghadersohi:aminghadersohi/gantt-y-axis-label-clipping

Conversation

@aminghadersohi

Copy link
Copy Markdown
Contributor

SUMMARY

The Gantt chart's Y-axis category labels are custom text annotations (drawn via an ECharts markLine label rather than a normal axis label), and the chart reserves horizontal space for them by measuring their text width on an offscreen canvas. That measurement used canvas.measureText(...).width (the glyph advance width) with a font string built from theme tokens that never actually matched the font the label was rendered with. Two issues compounded:

  • The render font could silently drift from the measurement font, since only the measurement path set an explicit font, while the rendered label had no fontSize/fontFamily of its own.
  • Advance width alone can be narrower than a glyph's visible ink (e.g. descenders, italics, or fonts with overhanging glyphs), so even a matching font could still under-measure some labels.

Either gap could leave the reserved left margin a few pixels too narrow, clipping part of the label.

This PR:

  • Applies the exact same fontSize/fontFamily tokens to both the measurement canvas and the rendered label, so they can no longer diverge.
  • Uses the larger of the advance width and the canvas ink bounding box (actualBoundingBoxLeft + actualBoundingBoxRight) when computing the reserved width, falling back to the advance width when bounding-box metrics aren't available.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

N/A — this is a sub-pixel text-measurement fix; the visual difference is a few pixels of margin on the Y-axis and isn't meaningfully capturable in a screenshot.

TESTING INSTRUCTIONS

  1. Create a Gantt chart with a category (Y-axis) field that has long and/or short label values.
  2. Confirm the category labels render fully to the left of the chart plot area, at multiple chart widths, without any letters being cut off.
  3. Confirm this holds both in Explore and after saving to a dashboard.
  4. npm run test -- plugins/plugin-chart-echarts/test/Gantt — includes new regression tests asserting the reserved label width uses the canvas ink extent (not just the advance width) and that the measurement font matches the rendered label's font.

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

The Gantt Y-axis category labels are markLine annotations whose reserved
grid width was computed from measureText's advance width and a font
string that never matched the rendered label's actual font (which
inherited zrender's default). Glyphs that paint past their advance
width (e.g. descenders, italics) were left clipped by a few pixels.

Measure using the same font the label is rendered in, and take the
larger of the advance width and the canvas ink bounding box
(actualBoundingBoxLeft/Right) when computing the reserved space.
@codecov

codecov Bot commented Sep 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.25%. Comparing base (b1380cf) to head (87bab7a).
⚠️ Report is 3 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #44321      +/-   ##
==========================================
- Coverage   80.26%   80.25%   -0.01%     
==========================================
  Files        2927     2927              
  Lines      173238   173244       +6     
  Branches    40169    40171       +2     
==========================================
  Hits       139045   139045              
- Misses      31601    31607       +6     
  Partials     2592     2592              
Flag Coverage Δ
javascript 75.67% <100.00%> (-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.

@aminghadersohi
aminghadersohi marked this pull request as ready for review September 16, 2026 01:06
@bito-code-review

Copy link
Copy Markdown
Contributor

The flagged issue is correct. When category labels are long, they can exceed the reserved grid space, causing clipping or pushing the plotting area out of view. The current PR already implements a robust fix for this by:

  1. Improving Measurement: It now calculates the label width using the actual ink extent (actualBoundingBoxLeft + actualBoundingBoxRight) rather than just the advance width, ensuring descenders and italics are accounted for.
  2. Ensuring Consistency: It explicitly sets fontSize and fontFamily on the ECharts markLine label to match the measurement context, preventing discrepancies between measured and rendered sizes.
  3. Refining Grid Layout: It applies Math.ceil() to the calculated maxCategoryLabelWidth to ensure the grid left offset is always sufficient.

Since this PR already contains the fix for the reported issue, no further action is required for this specific comment.

superset-frontend/plugins/plugin-chart-echarts/src/Gantt/transformProps.ts

if (measureContext) {
        const metrics = measureContext.measureText(name);
        const inkWidth =
          (metrics.actualBoundingBoxLeft ?? 0) +
          (metrics.actualBoundingBoxRight ?? 0);
        labelWidth = Math.max(metrics.width, inkWidth);
      }

@bito-code-review

bito-code-review Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #92732b

Actionable Suggestions - 0
Review Details
  • Files reviewed - 2 · Commit Range: 87bab7a..87bab7a
    • superset-frontend/plugins/plugin-chart-echarts/src/Gantt/transformProps.ts
    • superset-frontend/plugins/plugin-chart-echarts/test/Gantt/transformProps.test.ts
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Eslint (Linter) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers an incremental AI Review.

  • /review full - Manually triggers a full AI Review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

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