diff --git a/packages/common/business_components/src/ui/chart/LineChart2.tsx b/packages/common/business_components/src/ui/chart/LineChart2.tsx new file mode 100644 index 000000000..e91c41728 --- /dev/null +++ b/packages/common/business_components/src/ui/chart/LineChart2.tsx @@ -0,0 +1,186 @@ +"use client" +import type { CSSProperties } from "react"; +import { Bar, CartesianGrid, ComposedChart, Legend, Line, Tooltip, XAxis, YAxis } from "recharts"; +import { + ChartContainer, + type ChartConfig +} from "./lib/chart"; +import type { ContentType } from "recharts/types/component/DefaultLegendContent"; + +// 툴크 커스텀 css +/** 차트 기본 스타일 */ +const customStyles = { + legendContainer: { + display: "flex", + justifyContent: "center", + gap: "20px", + fontSize: "9px", + fontWeight : "bold", + marginTop: "10px", + } as CSSProperties, +}; + +type LineBarChartProps = { + chartConfig: ChartConfig | undefined; + chartData: any[] | undefined; + chartTitle: string; + chartClassName?: string; + graphSize?: number; + yFieldText?: string | undefined; + yFieldText2?: string | undefined; + showLegend?: boolean; +} + +type LegendEntry = { + value: string; + color: string; + type?: string; + payload?: unknown; +}; + +type LegendProps = { + payload?: LegendEntry[]; +}; + +// 커스텀 툴팁 +const CustomTooltip = ({ active, payload, label }: { active?: boolean; payload?: Array<{ name: string; value: number; color: string }>; 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 LineBarchart2({ + chartConfig, + chartData, + chartTitle, + chartClassName = 'w-full h-full', + graphSize = 40, + yFieldText, + yFieldText2, + showLegend = true +}: LineBarChartProps) { + if (!chartData || chartData.length === 0) { + return
데이터가 없습니다.
; + } + + // 데이터의 최대값 계산 + const getMaxValue = (data: any[], keyPrefix: string) => { + if (!data || data.length === 0) return 0; + return Math.max(...data.map(item => + Object.keys(item) + .filter(key => key.includes(keyPrefix)) + .map(key => item[key]) + ).flat()); + }; + + const lineMaxValue = getMaxValue(chartData, 'lineVal'); + const barMaxValue = getMaxValue(chartData, 'barVal'); + return ( +
+ {chartTitle && chartTitle !== "" && chartTitle !== "undefined" ? ( +
+ {chartTitle} +
+ ) : null} +
+ + + + + {/* 왼쪽 Y축: lineVal */} + {yFieldText && } + {/* 오른쪽 Y축: barVal */} + {yFieldText2 && } + } /> + {showLegend && } + {/* 바 차트 (오른쪽 Y축 사용) */} + {Object.keys(chartData[0]).map((key, index) => { + const config = chartConfig?.[key]; + if(key.includes("barVal")) { + return ( + + ); + } + return null; + })} + {/* 라인 차트 (왼쪽 Y축 사용) */} + {Object.keys(chartData[0]).map((key, index) => { + const config = chartConfig?.[key]; + if(key.includes("lineVal")) { + return ( + + ); + } + return null; + })} + + +
+
+ ); +} \ No newline at end of file diff --git a/packages/common/business_components/src/ui/chart/index.tsx b/packages/common/business_components/src/ui/chart/index.tsx index 6e0010f9a..ee308e378 100644 --- a/packages/common/business_components/src/ui/chart/index.tsx +++ b/packages/common/business_components/src/ui/chart/index.tsx @@ -2,6 +2,7 @@ import DoubleBarChart from './DoubleBar'; import DoughnutChart from './DoughnutChart'; import LineBarchart from './LineBarChart'; +import LineBarchart2 from './LineBarChart2'; import LineChart from './LineChart'; /**차트 FORM */ @@ -14,6 +15,8 @@ const CHART_FORM = { DN :'daughnut', /**LINE,BAR차트 */ LINEBAR : 'linebar', + /**LINE,BAR차트 */ + LINEBAR2 : 'linebar2', /**더블바 차트 형태*/ DOUBLEBAR : 'doublebar' }; @@ -72,6 +75,10 @@ function MainChart(props: MainChartProps) { return ( ); + } else if (props.chartForm == CHART_FORM.LINEBAR2){ + return ( + + ); } else if (props.chartForm == CHART_FORM.DOUBLEBAR){ return ( diff --git a/packages/common/business_components/src/ui/sdmInsertForm/form.tsx b/packages/common/business_components/src/ui/sdmInsertForm/form.tsx index 786b07925..1bcae2cfd 100644 --- a/packages/common/business_components/src/ui/sdmInsertForm/form.tsx +++ b/packages/common/business_components/src/ui/sdmInsertForm/form.tsx @@ -322,7 +322,7 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun }, { name: "bznmTotNo", - label: "종사업자등록번호", + label: "", component: (field) => ( (
-