-차트 데이터 개수만큼 차트가 그려지도록 수정정
This commit is contained in:
@@ -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) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user