From b00e5c48435a3507ad24cf5c8fab12f1d86e5ced Mon Sep 17 00:00:00 2001 From: YangJinSoo94 Date: Tue, 10 Jun 2025 15:50:25 +0900 Subject: [PATCH] =?UTF-8?q?=EB=8F=84=EB=84=9B=EB=B0=94=20=EC=83=89?= =?UTF-8?q?=EC=83=81=EC=9E=85=ED=9E=88=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/ui/chart/DoughnutChart.tsx | 125 +++++++++++++++--- .../src/ui/chart/LineBarChart.tsx | 3 - 2 files changed, 109 insertions(+), 19 deletions(-) diff --git a/packages/common/business_components/src/ui/chart/DoughnutChart.tsx b/packages/common/business_components/src/ui/chart/DoughnutChart.tsx index f88b35476..d666f1d14 100644 --- a/packages/common/business_components/src/ui/chart/DoughnutChart.tsx +++ b/packages/common/business_components/src/ui/chart/DoughnutChart.tsx @@ -1,27 +1,116 @@ "use client" import { Pie, PieChart } from "recharts"; - +import type { CSSProperties } from "react"; import { Card, CardContent } from "./lib/card"; -import { - ChartContainer, - ChartTooltip, - ChartTooltipContent, - type ChartConfig -} from "./lib/chart"; +import { ChartContainer, ChartTooltip } from "./lib/chart"; -// eslint-disable-next-line react-refresh/only-export-components -export default (props: { chartConfig: ChartConfig; chartData: never[] | undefined; chartTitle:string}) =>{ +type ChartDataItem = { + label: string; + val: number; +}; + +type ChartConfigItem = { + label: string; + fill: string; +}; + +type ChartConfig = { + [key: string]: ChartConfigItem; +}; + +type TooltipPayloadItem = { + name: string; + value: number; + payload: { + label: string; + val: number; + fill: string; + }; +}; + +type LegendEntry = { + value: string; + fill: string; + type?: string; + payload: { + label: string; + val: number; + fill: string; + }; +}; + +type LegendProps = { + payload?: LegendEntry[]; +}; + +/** 차트 기본 스타일 */ +const customStyles = { + legendContainer: { + display: "flex", + justifyContent: "center", + gap: "20px", + fontSize: "9px", + fontWeight: "bold", + marginTop: "10px", + } as CSSProperties, +}; + +// 커스텀 툴팁 +const CustomTooltip = ({ active, payload, label }: { + active?: boolean; + payload?: TooltipPayloadItem[]; + label?: string +}) => { + if (active && payload && payload.length) { + return ( +
+

{label}

+ {payload.map((item, index) => ( +
+
+ {` ${item.name} : ${item.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}`} +
+ ))} +
+ ); + } + return null; +}; + +// 커스텀 범례 +const CustomLegend = (props: LegendProps) => { + const { payload } = props; + if (!payload) return null; + + return ( +
+ {payload.map((entry: LegendEntry, index: number) => ( +
+
+ {entry.value} +
+ ))} +
+ ); +}; + +export default function DoughnutChart(props: { + chartConfig: ChartConfig; + chartData: ChartDataItem[] | undefined; + chartTitle: string +}) { return ( - {props.chartTitle && props.chartTitle !== "" && props.chartTitle !== "undefined" ? ( -
- {props.chartTitle} -
): null} + {props.chartTitle && props.chartTitle !== "" && props.chartTitle !== "undefined" ? ( +
+ {props.chartTitle} +
+ ) : null}
} + content={} /> ({ + ...item, + fill: props.chartConfig[item.label]?.fill || 'blue' + }))} dataKey="val" nameKey="label" innerRadius={60} /> +
- ) + ); } diff --git a/packages/common/business_components/src/ui/chart/LineBarChart.tsx b/packages/common/business_components/src/ui/chart/LineBarChart.tsx index 2e83458d8..8c7202104 100644 --- a/packages/common/business_components/src/ui/chart/LineBarChart.tsx +++ b/packages/common/business_components/src/ui/chart/LineBarChart.tsx @@ -92,9 +92,6 @@ export default function LineBarchart({ return
데이터가 없습니다.
; } - const barConfig = chartConfig?.barVal; - const lineConfig = chartConfig?.lineVal; - // 데이터의 최대값 계산 const getMaxValue = (data: any[], keyPrefix: string) => { return Math.max(...data.map(item =>