Merge commit '068c6a08cd2669fa34daac1ce835c4a484f96b4b' into iipbs/wr/form_fuction

This commit is contained in:
jyha00
2025-06-10 18:30:30 +09:00
2 changed files with 145 additions and 1 deletions
@@ -0,0 +1,137 @@
"use client"
import { Bar, BarChart, CartesianGrid, Legend, XAxis, YAxis } from "recharts";
import {
ChartContainer,
ChartTooltip,
type ChartConfig
} from "./lib/chart";
import type { CSSProperties } from "react";
const customStyles = {
legendContainer: {
display: "flex",
justifyContent: "center",
gap: "20px",
fontSize: "9px",
fontWeight : "bold",
marginTop: "10px",
} as CSSProperties,
};
type BarChartProps = {
chartConfig: ChartConfig | undefined;
chartData: any[] | undefined;
chartTitle: string;
chartClassName?: string;
graphSize?: number;
yFieldText?: string;
showLegend?: boolean;
}
// 커스텀 툴팁
const CustomTooltip = ({
active,
payload,
label
}: {
active?: boolean;
payload?: Array<{
name: string;
value: number;
color: string;
}>;
label?: string;
}) => {
if (active && payload && payload.length) {
return (
<div className="w-[180px] rounded bg-white p-2.5 shadow-[0px_2px_10px_rgba(0,0,0,0.2)]">
<p className="text-[12px] font-bold m-3">{label}</p>
{payload.map((item, index) => (
<div key={index} style={{ marginTop: "10px", display: "flex", alignItems: "center", gap: "8px" }}>
{/* 색상 박스 추가 (범례 색상과 동일) */}
<div style={{ width: "10px", height: "10px", backgroundColor: item.color, borderRadius: "50%" }}></div>
<span className="text-[11px] font-bold">{` ${item.name} : ${item.value}`}</span>
</div>
))}
</div>
);
}
return null;
};
// 커스텀 범례 (글씨 크기 키우기 + 스타일 추가)
const CustomLegend = (props: any) => {
const { payload } = props;
return (
<div style={customStyles.legendContainer}>
{payload.map((entry: unknown, index: number) => (
<div key={`legend-${index}`} className="flex items-center gap-2">
<div className="w-[14px] h-[14px] ml-10" style={{ backgroundColor: (entry as {color: string}).color }}></div>
<span className="text-[12px]">{(entry as {value: string}).value}</span>
</div>
))}
</div>
);
};
export default function DoubleBarChart({chartConfig=undefined, chartData=[], chartTitle='차트', chartClassName='w-full h-full', graphSize=40, yFieldText='', showLegend=false} : BarChartProps) {
const colors = ["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4", "#FFEEAD", "#D4A5A5"];
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());
};
console.log(chartData);
const barMaxValue = getMaxValue(chartData, 'barVal');
return (
<>
{chartTitle && chartTitle !== "" && chartTitle !== "undefined" ? (
<div className="!mt-3 text-[2.5rem] font-bold">
{chartTitle}
</div>): null}
<div className="flex justify-center">
<ChartContainer config={chartConfig ?? {}} className={chartClassName + " !w-[90%]"}>
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} />
<XAxis
dataKey="label"
tickLine={true}
tickMargin={10}
axisLine={true}
fontSize={13}
fontWeight={500}
/>
<YAxis
tickLine={true}
tickMargin={10}
tickCount={6}
axisLine={true}
fontSize={12}
fontWeight={500}
domain={[0, Math.ceil(barMaxValue * 1)]}
label={yFieldText ? { value: yFieldText, className:"text-[13px] font-bold", position: 'insideLeft', angle: -90, offset: 20 } : undefined}
/>
<ChartTooltip cursor={false} content={<CustomTooltip active={undefined} payload={undefined} label={undefined} />}/>
{chartData && chartData.length > 0 && (
Object.keys(chartData[0])
.filter(key => key !== "label")
.map((key, idx) => (
<Bar
dataKey={key}
radius={5}
key={key}
stackId="a"
barSize={graphSize}
fill={colors[idx]}
/>
))
)}
{showLegend && <Legend content={CustomLegend}/>}
</BarChart>
</ChartContainer>
</div>
</>
)
}
@@ -5,6 +5,7 @@ import DoughnutChart from './DoughnutChart';
import { type ChartConfig } from './lib/chart';
import LineChart from './LineChart';
import LineBarchart from './LineBarChart';
import DoubleBarChart from './DoubleBar';
/**차트 FORM */
const CHART_FORM = {
@@ -15,7 +16,9 @@ const CHART_FORM = {
/**도넛 차트 형태*/
DN :'daughnut',
/**LINE,BAR차트 */
LINEBAR : 'linebar'
LINEBAR : 'linebar',
/**더블바 차트 형태*/
DOUBLEBAR : 'doublebar'
};
/**
@@ -61,6 +64,10 @@ function MainChart(props: MainChartProps) {
return (
<LineBarchart chartConfig={props.chartConfig} chartData={props.chartData} chartTitle={props.chartTitle} chartClassName={props.chartClassName} graphSize={props.graphSize} yFieldText={props.yFieldText} yFieldText2={props.yFieldText2} showLegend={props.showLegend}/>
);
} else if (props.chartForm == CHART_FORM.DOUBLEBAR){
return (
<DoubleBarChart chartConfig={props.chartConfig} chartData={props.chartData} chartTitle={props.chartTitle} chartClassName={props.chartClassName} graphSize={props.graphSize} yFieldText={props.yFieldText} showLegend={props.showLegend}/>
);
}
}