Skip to content

[WEB-4877] fix: webapp crash because of bar chart#7763

Merged
pushya22 merged 2 commits intopreviewfrom
fix-bar-chart
Sep 10, 2025
Merged

[WEB-4877] fix: webapp crash because of bar chart#7763
pushya22 merged 2 commits intopreviewfrom
fix-bar-chart

Conversation

@JayashTripathy
Copy link
Member

@JayashTripathy JayashTripathy commented Sep 10, 2025

Description

Fixed app runtime crashing by updating the bar color extraction logic in propel

Type of Change

  • Bug fix (non-breaking change which fixes an issue)

Summary by CodeRabbit

  • New Features

    • Bar charts support per-item color definitions (including dynamic color functions) with reliable defaults.
    • Tooltips now show indicators that match each bar's displayed color.
  • Bug Fixes

    • Prevented errors when custom color logic encounters missing or invalid data.
    • Ensured a consistent default bar color when no color is provided.
    • Fixed mismatches between bar colors and tooltip dot colors.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 10, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds centralized, safe color resolution for bars: introduces DEFAULT_BAR_FILL_COLOR, getBarColor and getAllBarColors callbacks, removes inline Bar fill assignment and stackDotColors derivation, and passes a per-key color map into Tooltip via itemDotColors.

Changes

Cohort / File(s) Summary
Bar color resolution & tooltip colors
packages/propel/src/charts/bar-chart/root.tsx
Added DEFAULT_BAR_FILL_COLOR. Introduced getBarColor(payload, barKey) and getAllBarColors(payload) via useCallback to resolve fills (handling functional fills with payload lookup and errors). Removed stackDotColors from memo, removed inline Bar fill prop, and pass itemDotColors to Tooltip from `getAllBarColors(payload

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant BC as BarChart (root.tsx)
  participant Bars as Bars[]
  participant TT as Tooltip
  rect rgb(245,249,255)
  note right of BC: render -> derive stackKeys/stackLabels
  end
  U->>BC: render with data payload
  BC->>BC: derive stackKeys & stackLabels (useMemo)
  BC->>BC: getAllBarColors(payload)
  loop for each barKey
    BC->>BC: getBarColor(payload, barKey)
    alt bar found and bar.fill is function
      BC->>Bars: find bar by key
      BC->>BC: find matching payload item
      BC->>BC: color = safeCall(bar.fill, item.payload)
      note right of BC: on error/missing → DEFAULT_BAR_FILL_COLOR
    else bar.fill is value
      BC->>BC: color = bar.fill
    else bar not found
      BC->>BC: color = DEFAULT_BAR_FILL_COLOR
    end
  end
  BC->>TT: content({ itemDotColors: colorMap })
  note over TT,BC: Tooltip uses provided per-key colors
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

🌐frontend

Suggested reviewers

  • aaryan610
  • anmolsinghbhatia
  • sriramveeraghanta

Poem

I nibble code like clover leaves, delight!
New hues bloom where the bars take flight.
If colors hide, I hop to defaults true—
A fallback burrow of trusty hue.
Tooltip twinkles, dots aligned— 🐇🎨

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning While the description provides a summary and marks this as a bug fix, it omits required template sections for Test Scenarios and References, leaving out how the change was verified and what issue it addresses. Add a Test Scenarios section outlining the steps or tests performed to validate the fix and a References section linking to the corresponding issue or ticket to fully align with the repository’s PR description template.
✅ Passed checks (2 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
Title Check ✅ Passed The title clearly states the main purpose of the changeset, indicating the resolution of a webapp crash related to the bar chart and referencing the associated ticket, making it concise and informative for teammates scanning the history.
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-bar-chart

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.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes a runtime crash in the bar chart component by improving the bar color extraction logic. The fix addresses issues with function-based fill colors and ensures proper fallback handling.

  • Replaced static color extraction with dynamic color resolution that handles function-based fills properly
  • Added error handling and fallback colors to prevent crashes when color functions fail
  • Removed direct function calls with empty objects that could cause runtime errors
Comments suppressed due to low confidence (1)

packages/propel/src/charts/bar-chart/root.tsx:1

  • The fill prop is being removed from the Bar component but no replacement is provided. This will likely cause the bars to render without any fill color since the dynamic color resolution in getBarColor is only used for tooltips.
/* eslint-disable @typescript-eslint/no-explicit-any */

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@JayashTripathy JayashTripathy changed the title fix: bar chart [WEB-4877] fix: bar chart Sep 10, 2025
@makeplane
Copy link

makeplane bot commented Sep 10, 2025

Pull Request Linked with Plane Work Items

Comment Automatically Generated by Plane

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
packages/propel/src/charts/bar-chart/root.tsx (4)

24-25: Avoid hard-coded black; prefer theme token or configurable fallback.

Using a design token (e.g., a CSS variable) or a prop-based override keeps charts consistent with theming and dark mode. Keeping "#000000" is fine as a fallback if a token isn’t available.


49-60: Tighten typing for keys/labels and simplify construction.

Leverage generic K to keep types precise and reduce loop boilerplate.

-  const { stackKeys, stackLabels } = useMemo(() => {
-    const keys: string[] = [];
-    const labels: Record<string, string> = {};
-
-    for (const bar of bars) {
-      keys.push(bar.key);
-      labels[bar.key] = bar.label;
-    }
-
-    return { stackKeys: keys, stackLabels: labels };
-  }, [bars]);
+  const { stackKeys, stackLabels } = useMemo(() => {
+    const keys = bars.map((b) => b.key) as K[];
+    const labels = Object.fromEntries(bars.map((b) => [b.key, b.label])) as Record<K, string>;
+    return { stackKeys: keys, stackLabels: labels };
+  }, [bars]);

61-85: Harden getBarColor: handle falsy strings, invalid returns, and quiet logs in prod.

Prevents undefined/empty colors and avoids noisy console.error in production.

   const getBarColor = useCallback(
     (payload: any[], barKey: string) => {
       const bar = bars.find((b) => b.key === barKey);
       if (!bar) return DEFAULT_BAR_FILL_COLOR;
 
       if (typeof bar.fill === "function") {
-        const payloadItem = payload?.find((item) => item.dataKey === barKey);
-        if (payloadItem?.payload) {
-          try {
-            return bar.fill(payloadItem.payload);
-          } catch (error) {
-            console.error(error);
-            return DEFAULT_BAR_FILL_COLOR;
-          }
-        } else {
-          return DEFAULT_BAR_FILL_COLOR; // fallback color when no payload data
-        }
+        const payloadItem = Array.isArray(payload) ? payload.find((item) => item.dataKey === barKey) : undefined;
+        let color: unknown;
+        if (payloadItem?.payload) {
+          try {
+            color = bar.fill(payloadItem.payload);
+          } catch (error) {
+            if (process.env.NODE_ENV !== "production") {
+              // eslint-disable-next-line no-console
+              console.warn(`[BarChart] bar.fill threw for key "${barKey}"`, error);
+            }
+          }
+        }
+        return typeof color === "string" && color ? color : DEFAULT_BAR_FILL_COLOR;
       } else {
-        return bar.fill;
+        const color = bar.fill as string | undefined;
+        return color && color.length > 0 ? color : DEFAULT_BAR_FILL_COLOR;
       }
     },
     [bars]
   );

86-97: Minor perf: avoid O(nBars × nPayload) lookup.

Today you scan payload for each bar via getBarColor. Not a big deal for small charts, but you can pre-index payload by dataKey once per tooltip render and reuse it.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ac835bf and f578268.

📒 Files selected for processing (1)
  • packages/propel/src/charts/bar-chart/root.tsx (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Build and lint web apps
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
packages/propel/src/charts/bar-chart/root.tsx (2)

4-4: LGTM: import changes are appropriate.

useCallback addition matches new helpers.


196-197: CustomTooltip prop contract verified. itemDotColors is correctly implemented across all chart components and the CustomTooltip interface no longer references stackDotColors; no external tooltips require stackDotColors.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
packages/propel/src/charts/bar-chart/root.tsx (1)

86-97: Replace any[] with typed Recharts payload and tighten return type

Keeps tooltip interop sound and avoids accidental shape mistakes.

-  const getAllBarColors = useCallback(
-    (payload: any[]) => {
-      const colors: Record<string, string> = {};
+  const getAllBarColors = useCallback(
+    (payload: ReadonlyArray<TooltipPayload<number | string, string>> | undefined) => {
+      const colors: Record<string, string> = {};
       for (const bar of bars) {
         colors[bar.key] = getBarColor(payload, bar.key);
       }
       return colors;
     },
     [bars, getBarColor]
   );
🧹 Nitpick comments (4)
packages/propel/src/charts/bar-chart/root.tsx (4)

4-14: Type tooltip payloads to remove implicit anys and tighten signatures

Import Recharts’ Payload type for use in getBarColor/getAllBarColors.

 import React, { useCallback, useMemo, useState } from "react";
 import {
   BarChart as CoreBarChart,
   Bar,
   ResponsiveContainer,
   Tooltip,
   XAxis,
   YAxis,
   Legend,
   CartesianGrid,
 } from "recharts";
+import type { Payload as TooltipPayload } from "recharts/types/component/DefaultTooltipContent";

24-24: Prefer theme token over hardcoded black

Use a design-token fallback so dots match the app theme in light/dark modes.

-const DEFAULT_BAR_FILL_COLOR = "#000000";
+const DEFAULT_BAR_FILL_COLOR = "rgba(var(--color-text-100), 1)";

61-85: Harden color resolution + add types and safer fallbacks

  • Strongly type payload.
  • Guard when bar.fill is falsy or throws.
  • Add contextual logging (dev-only).
-  const getBarColor = useCallback(
-    (payload: Record<string, string>[], barKey: string) => {
+  const getBarColor = useCallback(
+    (payload: ReadonlyArray<TooltipPayload<number | string, string>> | undefined, barKey: string): string => {
       const bar = bars.find((b) => b.key === barKey);
       if (!bar) return DEFAULT_BAR_FILL_COLOR;
 
       if (typeof bar.fill === "function") {
-        const payloadItem = payload?.find((item) => item.dataKey === barKey);
-        if (payloadItem?.payload) {
+        const payloadItem = payload?.find((item) => item.dataKey === barKey);
+        if (payloadItem?.payload) {
           try {
             return bar.fill(payloadItem.payload);
           } catch (error) {
-            console.error(error);
+            if (process.env.NODE_ENV !== "production") {
+              // eslint-disable-next-line no-console
+              console.error(`[BarChart] bar.fill failed for key "${barKey}"`, error);
+            }
             return DEFAULT_BAR_FILL_COLOR;
           }
         } else {
           return DEFAULT_BAR_FILL_COLOR; // fallback color when no payload data
         }
       } else {
-        return bar.fill;
+        return bar.fill ?? DEFAULT_BAR_FILL_COLOR;
       }
     },
     [bars]
   );

196-196: Avoid allocating an empty array; let helper handle undefined

getAllBarColors already guards undefined payload.

-                    itemDotColors={getAllBarColors(payload || [])}
+                    itemDotColors={getAllBarColors(payload)}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f578268 and 75674e9.

📒 Files selected for processing (1)
  • packages/propel/src/charts/bar-chart/root.tsx (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Build and lint web apps
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (1)
packages/propel/src/charts/bar-chart/root.tsx (1)

49-60: LGTM: derived keys/labels memo

Clean and efficient; dependencies are correct.

@JayashTripathy JayashTripathy changed the title [WEB-4877] fix: bar chart [WEB-4877] fix: webapp crash because of bar chart Sep 10, 2025
@pushya22 pushya22 merged commit 0f7bfdd into preview Sep 10, 2025
6 of 7 checks passed
@pushya22 pushya22 deleted the fix-bar-chart branch September 10, 2025 12:14
yarikoptic pushed a commit to yarikoptic/plane that referenced this pull request Oct 1, 2025
* 🔧 fix: dynamic bar color handling and refactored color retrieval logic.

* ♻️  refactor: updated any to Record in getBarColor
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.

4 participants