Skip to content

feat(charts): percentage stacked bar chart mode - #724

Merged
alfredo1996 merged 4 commits into
devfrom
feat/issue-167-percent-stacked-bar
May 14, 2026
Merged

feat(charts): percentage stacked bar chart mode#724
alfredo1996 merged 4 commits into
devfrom
feat/issue-167-percent-stacked-bar

Conversation

@alfredo1996

@alfredo1996 alfredo1996 commented May 12, 2026

Copy link
Copy Markdown
Owner

Summary

Add 100% stacked bar chart option. Replaces the boolean "Stacked" toggle with a 3-option dropdown: Normal / Stacked / 100% Stacked.

Normal (grouped)

Bars side by side — existing default behavior.

Stacked

Bars stacked on absolute values — existing behavior.

100% Stacked (new)

Each category's values normalized to percentages. Y-axis shows 0%-100%. Tooltip shows both percentage and absolute value.

Backward compatibility

Existing dashboards with stacked: true still work — the legacy boolean prop falls back to "stacked" mode when stackMode is not set.

Test plan

  • 7 new unit tests for percent mode (normalization, y-axis, tooltip, zero totals, backward compat)
  • 28/28 bar chart tests pass
  • 1927 app tests pass
  • TypeScript clean

Closes #167

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a "Stack Mode" option for bar charts with None, Stacked, and Percent modes; Percent displays values as 0–100% with Y-axis and tooltips showing percent plus absolute.
  • Bug Fixes

    • Preserved backward compatibility with the legacy stacking setting.
  • Tests

    • Added tests covering percent-mode normalization, y-axis bounds, stacking behavior, and legacy compatibility.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 12, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@alfredo1996 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 47 minutes and 50 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8f3111ed-5b43-4dd1-9b54-3a4bd47f91cb

📥 Commits

Reviewing files that changed from the base of the PR and between 1c3f18f and efa4a00.

📒 Files selected for processing (4)
  • app/src/app/(auth)/signup/__tests__/page.test.tsx
  • component/src/charts/__tests__/bar-chart.test.tsx
  • component/src/charts/bar-chart.tsx
  • component/src/charts/chart-utils.ts

Walkthrough

Adds a stackMode enum (none|stacked|percent) to bar charts, implements percent-mode normalization (0–100%) with updated axis and tooltip, preserves legacy stacked boolean, forwards setting from the plugin, replaces the UI toggle with a select, and adds tests for percent behavior and compatibility.

Changes

Percent-Stacked Bar Chart Mode

Layer / File(s) Summary
Stack mode type contract and exports
component/src/charts/bar-chart.tsx, component/src/charts/index.ts
New BarStackMode union type added and stackMode?: BarStackMode added to BarChartProps; BarStackMode re-exported from charts barrel.
Percent-mode normalization and rendering
component/src/charts/bar-chart.tsx
Derives effective stack mode (prop or legacy boolean), precomputes per-row totals, normalizes display values to percentages in percent mode, sets y-axis 0–100 formatting, builds tooltip showing percent plus absolute value, and updates memo deps for isStacked/isPercent.
Settings schema and plugin integration
app/src/plugins/bar/settings.ts, app/src/plugins/bar/component.tsx
Adds stackMode enum to bar settings schema (default "none"), retains deprecated stacked boolean, and BarPluginComponent forwards settings.stackMode to BarChart.
Chart options UI control
component/src/components/composed/chart-options/bar.ts
Replaces stacked boolean option with stackMode select (none, stacked, percent) in chart options metadata and labels.
Test coverage
component/src/charts/__tests__/bar-chart.test.tsx, component/src/components/composed/__tests__/chart-options-panel.test.tsx, component/src/components/composed/__tests__/chart-options-schema.test.ts
Adds tests for percent-mode normalization, zero-total edge cases, y-axis max, stacking modes and legacy compatibility; updates UI/schema tests to assert stackMode and label changes; minor test render/fixture formatting changes.

Sequence Diagram

sequenceDiagram
  participant Settings
  participant BarPluginComponent
  participant BarChart
  participant ECharts
  Settings->>BarPluginComponent: settings.stackMode
  BarPluginComponent->>BarChart: stackMode prop (or legacy stacked)
  BarChart->>BarChart: compute per-row totals (percent mode)
  BarChart->>BarChart: normalize values to 0-100
  BarChart->>ECharts: pass series data, axis config, tooltip formatter
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

enhancement, area:charts, pkg:component, pkg:app

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main feature—a percentage stacked bar chart mode—which is the core addition across multiple files.
Linked Issues check ✅ Passed All objectives from issue #167 are met: stackMode option with Normal/Stacked/100% modes, percent normalization per category, Y-axis 0-100% display, tooltip showing absolute+percentage, and backward compatibility with legacy stacked boolean.
Out of Scope Changes check ✅ Passed All changes directly support the stackMode feature and backward compatibility; no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/issue-167-percent-stacked-bar

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@alfredo1996
alfredo1996 force-pushed the feat/issue-167-percent-stacked-bar branch from d60695b to c6da501 Compare May 12, 2026 16:10
alfredorubin96 and others added 2 commits May 13, 2026 15:30
Replace boolean "Stacked" toggle with a 3-option "Stack Mode" dropdown:
- Normal (grouped) — bars side by side
- Stacked — absolute values stacked
- 100% Stacked — values normalized to percentages (0%-100%)

In percent mode:
- Each bar's values are normalized to their row total percentage
- Y-axis displays 0%-100% with percent formatter
- Tooltip shows both percentage and absolute value
- Zero-total rows display as 0% (no NaN)

Backward compatible — existing dashboards with stacked:true still work
via the legacy boolean prop fallback.

Closes #167

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@alfredo1996
alfredo1996 force-pushed the feat/issue-167-percent-stacked-bar branch from 82d82d5 to 1c3f18f Compare May 13, 2026 13:30

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/src/plugins/bar/component.tsx`:
- Around line 36-37: The component is always passing the schema-defaulted
settings.stackMode which masks “unset”; change the JSX to only supply the
stackMode prop when the raw/unprocessed setting was explicitly provided (e.g.,
check rawSettings.stackMode !== undefined) and otherwise omit the prop, while
keeping stacked={settings.stacked} unchanged; in short, replace the
unconditional stackMode={settings.stackMode} with a conditional spread/prop that
only sets stackMode when the original raw setting exists.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 70cfdf01-3f54-487a-93b5-12965a0f46a7

📥 Commits

Reviewing files that changed from the base of the PR and between 82d82d5 and 1c3f18f.

📒 Files selected for processing (8)
  • app/src/plugins/bar/component.tsx
  • app/src/plugins/bar/settings.ts
  • component/src/charts/__tests__/bar-chart.test.tsx
  • component/src/charts/bar-chart.tsx
  • component/src/charts/index.ts
  • component/src/components/composed/__tests__/chart-options-panel.test.tsx
  • component/src/components/composed/__tests__/chart-options-schema.test.ts
  • component/src/components/composed/chart-options/bar.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • component/src/components/composed/chart-options/bar.ts
  • component/src/charts/index.ts
  • app/src/plugins/bar/settings.ts
  • component/src/components/composed/tests/chart-options-schema.test.ts
  • component/src/components/composed/tests/chart-options-panel.test.tsx
  • component/src/charts/bar-chart.tsx
  • component/src/charts/tests/bar-chart.test.tsx

Comment on lines +36 to 37
stackMode={settings.stackMode}
stacked={settings.stacked}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve legacy fallback by not always forcing stackMode.

Line 36 currently passes a schema-defaulted value, which can mask “unset” and break legacy stacked: true behavior. Pass stackMode only when it was explicitly provided in raw settings.

Suggested fix
 function BarPluginComponent({
   data,
   settings: raw,
@@
 }: PluginProps) {
   const onClick = useEChartsClick(onChartClick, data);
   const settings = barSettingsSchema.parse(raw);
+  const hasExplicitStackMode =
+    raw != null &&
+    typeof raw === "object" &&
+    "stackMode" in (raw as Record<string, unknown>);
 
   return (
     <BarChart
       data={(data as BarChartDataPoint[]) ?? []}
       orientation={settings.orientation}
-      stackMode={settings.stackMode}
+      stackMode={hasExplicitStackMode ? settings.stackMode : undefined}
       stacked={settings.stacked}
       showValues={settings.showValues}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/plugins/bar/component.tsx` around lines 36 - 37, The component is
always passing the schema-defaulted settings.stackMode which masks “unset”;
change the JSX to only supply the stackMode prop when the raw/unprocessed
setting was explicitly provided (e.g., check rawSettings.stackMode !==
undefined) and otherwise omit the prop, while keeping stacked={settings.stacked}
unchanged; in short, replace the unconditional stackMode={settings.stackMode}
with a conditional spread/prop that only sets stackMode when the original raw
setting exists.

alfredorubin96 and others added 2 commits May 14, 2026 11:58
Extract inline percent tooltip formatter from bar-chart.tsx into
buildPercentTooltipFormatter in chart-utils.ts, reusing the existing
TooltipParam type. Add renderBarOptions test helper to eliminate
repeated render + extract-options boilerplate across 20+ test cases.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
62.7% Coverage on New Code (required ≥ 80%)
4.5% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@alfredo1996
alfredo1996 merged commit f1c3dd2 into dev May 14, 2026
12 of 13 checks passed
@alfredo1996
alfredo1996 deleted the feat/issue-167-percent-stacked-bar branch May 16, 2026 17:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(component): percentage stacked bar chart mode

2 participants