-차트 데이터 개수만큼 차트가 그려지도록 수정정

This commit is contained in:
YangJinSoo94
2025-05-19 14:40:19 +09:00
parent 40fae4f613
commit 72df272fd2
2 changed files with 86 additions and 24 deletions
@@ -7,7 +7,7 @@ import {
} from "./lib/chart"; } from "./lib/chart";
import type { ContentType } from "recharts/types/component/DefaultLegendContent"; import type { ContentType } from "recharts/types/component/DefaultLegendContent";
// 툴팁 커스텀 css // 툴크 커스텀 css
/** 차트 기본 스타일 */ /** 차트 기본 스타일 */
const customStyles = { const customStyles = {
legendContainer: { legendContainer: {
@@ -52,7 +52,7 @@ const CustomTooltip = ({ active, payload, label }: { active?: boolean; payload?:
<div key={index} style={{ marginTop: "10px", display: "flex", alignItems: "center", gap: "8px" }}> <div key={index} style={{ marginTop: "10px", display: "flex", alignItems: "center", gap: "8px" }}>
{/* 색상 박스 추가 (범례 색상과 동일) */} {/* 색상 박스 추가 (범례 색상과 동일) */}
<div style={{ width: "10px", height: "10px", backgroundColor: item.color, borderRadius: "50%" }}></div> <div style={{ width: "10px", height: "10px", backgroundColor: item.color, borderRadius: "50%" }}></div>
<span className="text-[11px] font-bold">{` ${item.name} : ${item.value}`}</span> <span className="text-[11px] font-bold">{` ${item.name} : ${item.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}`}</span>
</div> </div>
))} ))}
</div> </div>
@@ -95,6 +95,18 @@ export default function LineBarchart({
const barConfig = chartConfig?.barVal; const barConfig = chartConfig?.barVal;
const lineConfig = chartConfig?.lineVal; const lineConfig = chartConfig?.lineVal;
// 데이터의 최대값 계산
const getMaxValue = (data: any[], keyPrefix: string) => {
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 ( return (
<div className={chartClassName}> <div className={chartClassName}>
{chartTitle && chartTitle !== "" && chartTitle !== "undefined" ? ( {chartTitle && chartTitle !== "" && chartTitle !== "undefined" ? (
@@ -113,29 +125,62 @@ export default function LineBarchart({
<CartesianGrid strokeDasharray="3 3" /> <CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="label" fontSize="8px" fontWeight="bold"/> <XAxis dataKey="label" fontSize="8px" fontWeight="bold"/>
{/* 왼쪽 Y축: lineVal */} {/* 왼쪽 Y축: lineVal */}
{yFieldText && <YAxis yAxisId="left" className="text-[12px] font-bold" orientation="left" label={{ value: yFieldText, angle: -90, position: 'insideLeft' }} />} {yFieldText && <YAxis
yAxisId="left"
className="text-[12px] font-bold"
tickCount={6}
orientation="left"
domain={[0, Math.ceil(lineMaxValue * 1.1)]}
label={{ value: yFieldText, angle: -90, position: 'insideLeft' }}
/>}
{/* 오른쪽 Y축: barVal */} {/* 오른쪽 Y축: barVal */}
{yFieldText2 && <YAxis yAxisId="right" className="text-[12px] font-bold" fontWeight="bold" orientation="right" label={{ value: yFieldText2, angle: -90, position: 'insideRight' }} />} {yFieldText2 && <YAxis
yAxisId="right"
className="text-[12px] font-bold"
tickCount={6}
orientation="right"
domain={[0, Math.ceil(barMaxValue * 1.1)]}
label={{ value: yFieldText2, angle: -90, position: 'insideRight' }}
reversed={true}
/>}
<Tooltip content={<CustomTooltip active={undefined} payload={undefined} label={undefined} />} /> <Tooltip content={<CustomTooltip active={undefined} payload={undefined} label={undefined} />} />
{showLegend && <Legend content={CustomLegend as ContentType}/>} {showLegend && <Legend content={CustomLegend as ContentType}/>}
{/* 바 차트 (오른쪽 Y축 사용) */} {/* 바 차트 (오른쪽 Y축 사용) */}
<Bar {Object.keys(chartData[0]).map((key, index) => {
yAxisId="right" const config = chartConfig?.[key];
dataKey="barVal" if(key.includes("barVal")) {
fill={barConfig?.color || "black"} return (
name={String(barConfig?.label || "Y축")} <Bar
maxBarSize={80} key={`bar-${key}-${index}`}
/> yAxisId="right"
dataKey={key}
fill={config?.color || "black"}
name={String(config?.label || "Y축")}
maxBarSize={80}
/>
);
}
return null;
})}
{/* 라인 차트 (왼쪽 Y축 사용) */} {/* 라인 차트 (왼쪽 Y축 사용) */}
<Line {Object.keys(chartData[0]).map((key, index) => {
yAxisId="left" const config = chartConfig?.[key];
type="monotone" if(key.includes("lineVal")) {
dataKey="lineVal" return (
stroke={lineConfig?.color || "black"} <Line
strokeWidth={2} key={`line-${key}-${index}`}
dot={{r: 0}} yAxisId="left"
name={String(lineConfig?.label || "X축")} type="linear"
/> dataKey={key}
stroke={config?.color || "black"}
strokeWidth={2}
dot={{r: 0}}
name={String(config?.label || "X축")}
/>
);
}
return null;
})}
</ComposedChart> </ComposedChart>
</ChartContainer> </ChartContainer>
</div> </div>
@@ -91,10 +91,16 @@ export default function Linechart({
yFieldText, yFieldText,
showLegend = true showLegend = true
}: LineChartProps) { }: LineChartProps) {
if(!chartData || Object.keys(chartData).length === 0){ if (!chartData || Object.keys(chartData).length === 0) {
return <div>데이터가 없습니다.</div> return <div>데이터가 없습니다.</div>;
} }
// 모든 데이터셋이 비어있는지 확인
const hasNoData = Object.values(chartData).every(dataset => !dataset || dataset.length === 0);
if (hasNoData) {
return <div>데이터가 없습니다.</div>;
}
// 데이터 병합 및 변환 // 데이터 병합 및 변환
const mergedData = Object.entries(chartData).reduce<Array<{[key: string]: string | number}>>((acc, [key, dataset]) => { const mergedData = Object.entries(chartData).reduce<Array<{[key: string]: string | number}>>((acc, [key, dataset]) => {
dataset.forEach((entry, index) => { dataset.forEach((entry, index) => {
@@ -106,6 +112,17 @@ export default function Linechart({
return acc; return acc;
}, []); }, []);
// 데이터의 최대값 계산
const getMaxValue = (data: ChartDataType, keyPrefix: string) => {
return Math.max(...Object.values(data).map(item =>
Object.keys(item)
.filter(key => key.includes(keyPrefix))
.map(key => item[key] as unknown as number)
).flat());
};
const lineMaxValue = getMaxValue(chartData, 'lineVal');
return ( return (
<div className={chartClassName}> <div className={chartClassName}>
{chartTitle && chartTitle !== "" && chartTitle !== "undefined" ? ( {chartTitle && chartTitle !== "" && chartTitle !== "undefined" ? (
@@ -122,8 +139,8 @@ export default function Linechart({
margin={{ top: 5, right: 30, left: 20, bottom: 5 }} margin={{ top: 5, right: 30, left: 20, bottom: 5 }}
> >
<CartesianGrid vertical={false} /> <CartesianGrid vertical={false} />
<XAxis dataKey="label" fontSize="8px" fontWeight="bold"/> <XAxis dataKey="label" fontSize="8px" fontWeight="bold" />
<YAxis yAxisId="left" className="text-[12px] font-bold" orientation="left" label={{ value: yFieldText, className:"text-[12px] foont-bold", angle: -90, position: 'insideLeft' }} /> <YAxis yAxisId="left" className="text-[12px] font-bold" domain={[0, Math.ceil(lineMaxValue * 1.1)]} tickCount={6} orientation="left" label={{ value: yFieldText, className:"text-[12px] font-bold", angle: -90, position: 'insideLeft' }} />
<Tooltip content={<CustomTooltip />} /> <Tooltip content={<CustomTooltip />} />
{showLegend && <Legend content={CustomLegend as ContentType}/>} {showLegend && <Legend content={CustomLegend as ContentType}/>}
{Object.keys(chartData).map((key) => { {Object.keys(chartData).map((key) => {