feat(component): auto-rotate and truncate axis labels - #171
Conversation
Add buildCategoryAxisLabel() utility to chart-utils.ts: - Auto-rotate 30° at 8+ categories, 45° at 15+ - Truncate labels >15 chars with ellipsis (U+2026) - Tooltip shows full text on hover - Configurable rotation override via chart option Wire into BarChart component with axisLabelRotation prop. Add "Axis Label Rotation" option to chart-options-schema. Closes #137 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
✅ Files skipped from review due to trivial changes (2)
🚧 Files skipped from review as they are similar to previous changes (2)
WalkthroughAdds automatic rotation and truncation for category axis labels and exposes an optional Changes
Sequence Diagram(s)sequenceDiagram
participant BarChart as BarChart (component)
participant Utils as buildCategoryAxisLabel()
participant ECharts as ECharts (renderer)
participant User as User (hover)
BarChart->>Utils: compute axisLabelConfig(categoryCount, { compact?, rotateOverride?, maxLabelLength? })
Utils-->>BarChart: axisLabelConfig { rotate, formatter?, show, tooltip:{show} }
BarChart->>ECharts: render chart with category axis using axisLabelConfig
User->>ECharts: hover truncated label
ECharts-->>User: show tooltip (full label) per axisLabelConfig.tooltip
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
component/src/charts/chart-utils.ts (1)
40-49: Consider handling-1sentinel within the utility for defensive programming.The utility accepts any
rotateOverridevalue without validation. While the immediate fix should be inbar-chart.tsx, making the utility defensive against the-1sentinel (and potentially other invalid values) would prevent future misuse.♻️ Optional defensive enhancement
let rotate: number; - if (rotateOverride !== undefined) { + if (rotateOverride !== undefined && rotateOverride >= 0) { rotate = rotateOverride; } else if (categoryCount >= 15) {This treats any negative value as "use automatic", which aligns with the documented behavior (0-90 valid range).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@component/src/charts/chart-utils.ts` around lines 40 - 49, Update the rotation selection logic to treat negative rotateOverride values (e.g., -1 sentinel) as "automatic" rather than a literal override: when determining rotate (using the rotateOverride and categoryCount variables), only accept rotateOverride if it is defined and within the valid 0–90 range; if rotateOverride is undefined or negative (or out of range) fall back to the categoryCount heuristics (categoryCount >= 15 => 45, >= 8 => 30, else 0). Ensure this defensive check is applied where rotate and rotateOverride are used so future callers cannot force invalid rotations.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@component/src/charts/__tests__/axis-label-utils.test.ts`:
- Around line 36-44: Add a test that verifies rotateOverride: -1 is treated as
the "automatic" sentinel and not used as a negative angle: update the tests for
buildCategoryAxisLabel to include a case (e.g., it("treats -1 rotateOverride as
automatic", ...)) that calls buildCategoryAxisLabel(20, { rotateOverride: -1 })
and asserts result.rotate equals the automatic angle (45 for 20 categories);
ensure the test references buildCategoryAxisLabel and rotateOverride so behavior
is documented and prevents returning -1 as the angle.
In `@component/src/charts/bar-chart.tsx`:
- Around line 88-91: axisLabelRotation may be the sentinel -1 (meaning
"automatic") but is passed directly as rotateOverride to buildCategoryAxisLabel
causing an invalid angle; normalize axisLabelRotation to undefined when it
equals -1 before calling buildCategoryAxisLabel (e.g., compute a local
rotateOverride = axisLabelRotation === -1 ? undefined : axisLabelRotation and
pass that) so buildCategoryAxisLabel and axisLabelConfig receive undefined for
automatic mode rather than -1.
---
Nitpick comments:
In `@component/src/charts/chart-utils.ts`:
- Around line 40-49: Update the rotation selection logic to treat negative
rotateOverride values (e.g., -1 sentinel) as "automatic" rather than a literal
override: when determining rotate (using the rotateOverride and categoryCount
variables), only accept rotateOverride if it is defined and within the valid
0–90 range; if rotateOverride is undefined or negative (or out of range) fall
back to the categoryCount heuristics (categoryCount >= 15 => 45, >= 8 => 30,
else 0). Ensure this defensive check is applied where rotate and rotateOverride
are used so future callers cannot force invalid rotations.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 08131565-6b82-4340-8b41-ac236444252f
📒 Files selected for processing (4)
component/src/charts/__tests__/axis-label-utils.test.tscomponent/src/charts/bar-chart.tsxcomponent/src/charts/chart-utils.tscomponent/src/components/composed/chart-options-schema.ts
| const axisLabelConfig = buildCategoryAxisLabel(categoryLabels.length, { | ||
| compact, | ||
| rotateOverride: axisLabelRotation, | ||
| }); |
There was a problem hiding this comment.
Sentinel value -1 not normalized before passing to utility.
When axisLabelRotation is -1 (the schema default for "automatic"), it's passed directly to buildCategoryAxisLabel as rotateOverride. The utility treats any defined value as an explicit override, resulting in rotate: -1 — an invalid ECharts angle.
Normalize -1 to undefined before passing:
🐛 Proposed fix
const axisLabelConfig = buildCategoryAxisLabel(categoryLabels.length, {
compact,
- rotateOverride: axisLabelRotation,
+ rotateOverride: axisLabelRotation === -1 ? undefined : axisLabelRotation,
});📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const axisLabelConfig = buildCategoryAxisLabel(categoryLabels.length, { | |
| compact, | |
| rotateOverride: axisLabelRotation, | |
| }); | |
| const axisLabelConfig = buildCategoryAxisLabel(categoryLabels.length, { | |
| compact, | |
| rotateOverride: axisLabelRotation === -1 ? undefined : axisLabelRotation, | |
| }); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@component/src/charts/bar-chart.tsx` around lines 88 - 91, axisLabelRotation
may be the sentinel -1 (meaning "automatic") but is passed directly as
rotateOverride to buildCategoryAxisLabel causing an invalid angle; normalize
axisLabelRotation to undefined when it equals -1 before calling
buildCategoryAxisLabel (e.g., compute a local rotateOverride = axisLabelRotation
=== -1 ? undefined : axisLabelRotation and pass that) so buildCategoryAxisLabel
and axisLabelConfig receive undefined for automatic mode rather than -1.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The -1 sentinel (automatic mode) was passed directly to ECharts as rotate: -1 which is invalid. Now normalized to undefined so ECharts uses its default auto-rotation. Added test for -1 sentinel case. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
…els, markLine, pie donut) Merges PRs #169, #170, #171, #173, #174 into a single release branch. Resolves merge conflicts in chart-utils.ts, bar-chart.tsx, line-chart.tsx, and chart-options-schema.ts. Includes: - Number formatting for single-value and tooltips (#169) - DataZoom support for bar and line charts (#170) - Auto-rotate and truncate axis labels (#171) - Reference lines (markLine) for bar and line charts (#173) - Donut center text and Top-N grouping for pie chart (#174) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Superseded by consolidated PR #185 (release/chart-improvements) |
…els, markLine, pie donut) Merges PRs #169, #170, #171, #173, #174 into a single release branch. Resolves merge conflicts in chart-utils.ts, bar-chart.tsx, line-chart.tsx, and chart-options-schema.ts. Includes: - Number formatting for single-value and tooltips (#169) - DataZoom support for bar and line charts (#170) - Auto-rotate and truncate axis labels (#171) - Reference lines (markLine) for bar and line charts (#173) - Donut center text and Top-N grouping for pie chart (#174) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>



Summary
Auto-rotate and truncate category axis labels for the bar chart when there are many categories. Prevents overlapping labels and improves readability for large datasets.
Changes
buildCategoryAxisLabel()in chart-utils.ts — auto-rotation (30° at 8+, 45° at 15+ categories), truncation (>15 chars → ellipsis), tooltip for full textBarChart— uses the new utility, newaxisLabelRotationpropchart-options-schema.ts— "Axis Label Rotation" option for bar chart (-1 = auto)Test plan
cd component && npm test— 68 suites, 1018 testscd app && npm test— 72 suites, 1260 testsCloses #137
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Tests