[WEB-4877] fix: webapp crash because of bar chart (#7763)
* 🔧 fix: dynamic bar color handling and refactored color retrieval logic. * ♻️ refactor: updated any to Record in getBarColor
This commit is contained in:
parent
ac835bf287
commit
0f7bfdde91
1 changed files with 43 additions and 8 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useMemo, useState } from "react";
|
import React, { useCallback, useMemo, useState } from "react";
|
||||||
import {
|
import {
|
||||||
BarChart as CoreBarChart,
|
BarChart as CoreBarChart,
|
||||||
Bar,
|
Bar,
|
||||||
|
|
@ -21,6 +21,8 @@ import { CustomXAxisTick, CustomYAxisTick } from "../components/tick";
|
||||||
import { CustomTooltip } from "../components/tooltip";
|
import { CustomTooltip } from "../components/tooltip";
|
||||||
import { barShapeVariants } from "./bar";
|
import { barShapeVariants } from "./bar";
|
||||||
|
|
||||||
|
const DEFAULT_BAR_FILL_COLOR = "#000000";
|
||||||
|
|
||||||
export const BarChart = React.memo(<K extends string, T extends string>(props: TBarChartProps<K, T>) => {
|
export const BarChart = React.memo(<K extends string, T extends string>(props: TBarChartProps<K, T>) => {
|
||||||
const {
|
const {
|
||||||
data,
|
data,
|
||||||
|
|
@ -44,21 +46,55 @@ export const BarChart = React.memo(<K extends string, T extends string>(props: T
|
||||||
const [activeLegend, setActiveLegend] = useState<string | null>(null);
|
const [activeLegend, setActiveLegend] = useState<string | null>(null);
|
||||||
|
|
||||||
// derived values
|
// derived values
|
||||||
const { stackKeys, stackLabels, stackDotColors } = useMemo(() => {
|
const { stackKeys, stackLabels } = useMemo(() => {
|
||||||
const keys: string[] = [];
|
const keys: string[] = [];
|
||||||
const labels: Record<string, string> = {};
|
const labels: Record<string, string> = {};
|
||||||
const colors: Record<string, string> = {};
|
|
||||||
|
|
||||||
for (const bar of bars) {
|
for (const bar of bars) {
|
||||||
keys.push(bar.key);
|
keys.push(bar.key);
|
||||||
labels[bar.key] = bar.label;
|
labels[bar.key] = bar.label;
|
||||||
// For tooltip, we need a string color. If fill is a function, use a default color
|
|
||||||
colors[bar.key] = typeof bar.fill === "function" ? bar.fill({}) : bar.fill;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return { stackKeys: keys, stackLabels: labels, stackDotColors: colors };
|
return { stackKeys: keys, stackLabels: labels };
|
||||||
}, [bars]);
|
}, [bars]);
|
||||||
|
|
||||||
|
// get bar color dynamically based on payload
|
||||||
|
const getBarColor = useCallback(
|
||||||
|
(payload: Record<string, string>[], 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
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return bar.fill;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[bars]
|
||||||
|
);
|
||||||
|
|
||||||
|
// get all bar colors
|
||||||
|
const getAllBarColors = useCallback(
|
||||||
|
(payload: any[]) => {
|
||||||
|
const colors: Record<string, string> = {};
|
||||||
|
for (const bar of bars) {
|
||||||
|
colors[bar.key] = getBarColor(payload, bar.key);
|
||||||
|
}
|
||||||
|
return colors;
|
||||||
|
},
|
||||||
|
[bars, getBarColor]
|
||||||
|
);
|
||||||
|
|
||||||
const renderBars = useMemo(
|
const renderBars = useMemo(
|
||||||
() =>
|
() =>
|
||||||
bars.map((bar) => (
|
bars.map((bar) => (
|
||||||
|
|
@ -66,7 +102,6 @@ export const BarChart = React.memo(<K extends string, T extends string>(props: T
|
||||||
key={bar.key}
|
key={bar.key}
|
||||||
dataKey={bar.key}
|
dataKey={bar.key}
|
||||||
stackId={bar.stackId}
|
stackId={bar.stackId}
|
||||||
fill={typeof bar.fill === "function" ? bar.fill({}) : bar.fill}
|
|
||||||
opacity={!!activeLegend && activeLegend !== bar.key ? 0.1 : 1}
|
opacity={!!activeLegend && activeLegend !== bar.key ? 0.1 : 1}
|
||||||
shape={(shapeProps: any) => {
|
shape={(shapeProps: any) => {
|
||||||
const shapeVariant = barShapeVariants[bar.shapeVariant ?? "bar"];
|
const shapeVariant = barShapeVariants[bar.shapeVariant ?? "bar"];
|
||||||
|
|
@ -158,7 +193,7 @@ export const BarChart = React.memo(<K extends string, T extends string>(props: T
|
||||||
activeKey={activeBar}
|
activeKey={activeBar}
|
||||||
itemKeys={stackKeys}
|
itemKeys={stackKeys}
|
||||||
itemLabels={stackLabels}
|
itemLabels={stackLabels}
|
||||||
itemDotColors={stackDotColors}
|
itemDotColors={getAllBarColors(payload || [])}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue