Merge remote-tracking branch 'origin/iipbs/common/main' into iipbs/wr/pfmncSttn

This commit is contained in:
jyha00
2025-07-17 13:16:56 +09:00
3 changed files with 75 additions and 29 deletions
@@ -87,7 +87,7 @@ const getGlobalMax = (data: Record<string, number>[]) => {
};
export default function Chart({chartConfig=undefined, chartData=[], chartTitle='차트', chartClassName='w-full h-full', graphSize=40, yFieldText='', showLegend=false} : BarChartProps) {
const colors = ["#FF6B6B", "#4ECDC4", "#45B7D1", "#FED16A", "#FFEEAD", "#D4A5A5"];
const colors = ["#FF6B6B", "#4ECDC4", "#44ad57", "#FED16A", "#FFEEAD", "#D4A5A5"];
const globalMax = getGlobalMax(chartData);
const tickCount = 5;
// interval을 globalMax / tickCount로 계산
@@ -53,12 +53,37 @@ const customStyles = {
minHeight: "32px", // 범례 영역 높이 통일
} as CSSProperties,
};
const renderCustomizedLabel = ({
cx,
cy,
midAngle,
outerRadius,
payload,
}: any) => {
const RADIAN = Math.PI / 180;
const radius = outerRadius + 25;
const x = cx + radius * Math.cos(-midAngle * RADIAN);
const y = cy + radius * Math.sin(-midAngle * RADIAN);
return (
<text
x={x}
y={y}
fill="#333"
fontSize={11}
textAnchor={x > cx ? "start" : "end"}
dominantBaseline="central"
>
{`${payload.label}: ${payload.val.toLocaleString()}`}
</text>
);
};
// 커스텀 툴팁
const CustomTooltip = ({ active, payload, label }: {
active?: boolean;
payload?: TooltipPayloadItem[];
label?: string
const CustomTooltip = ({ active, payload, label }: {
active?: boolean;
payload?: TooltipPayloadItem[];
label?: string
}) => {
if (active && payload && payload.length) {
return (
@@ -79,7 +104,6 @@ const CustomTooltip = ({ active, payload, label }: {
const CustomLegend = (props: LegendProps) => {
const { payload } = props;
if (!payload) return null;
return (
<div style={customStyles.legendContainer}>
{payload.map((entry: LegendEntry, index: number) => (
@@ -111,9 +135,9 @@ const CustomLegend = (props: LegendProps) => {
);
};
export default function DoughnutChart(props: {
chartConfig: ChartConfig;
chartData: ChartDataItem[] | undefined;
export default function DoughnutChart(props: {
chartConfig: ChartConfig;
chartData: ChartDataItem[] | undefined;
chartTitle: string
}) {
const legendData = props.chartData?.map(item => ({
@@ -125,19 +149,20 @@ export default function DoughnutChart(props: {
fill: props.chartConfig?.[item.label]?.color || 'blue'
}
})) ?? [];
return (
<Card className="flex flex-col">
<CardContent className="flex-1 pb-0">
{props.chartTitle && props.chartTitle !== "" && props.chartTitle !== "undefined" ? (
<div style={{ textAlign: "left", fontSize: "13px", fontWeight: "bold", marginTop:"13px", marginBottom: "10px" }}>
<div style={{ textAlign: "left", fontSize: "13px", fontWeight: "bold", marginTop: "13px", marginBottom: "10px" }}>
{props.chartTitle}
</div>
) : null}
<div className="h-[calc(100%-42px)] justify-center">
<ChartContainer
config={props.chartConfig}
className="mx-auto aspect-square max-h-[300px]"
// className="mx-auto aspect-square max-h-[300px]"
className="min-h-[300px] w-full"
>
<PieChart>
<ChartTooltip
@@ -152,10 +177,14 @@ export default function DoughnutChart(props: {
dataKey="val"
nameKey="label"
innerRadius={60}
/>
label={(props) => {
return renderCustomizedLabel(props);
}}
>
</Pie>
</PieChart>
</ChartContainer>
<CustomLegend payload={legendData} />
<CustomLegend payload={legendData} />
</div>
</CardContent>
</Card>
@@ -32,10 +32,27 @@ export function DatePicker({
}: DatePickerProps) {
const [open, setOpen] = useState(false);
// const handleSelect = (date: Date | undefined) => {
// console.log("날짜", date)
// if (!readOnly) {
// // readOnly가 아닐 때만 변경 허용
// field.onChange(date); // React Hook Form 업데이트
// setOpen(false);
// }
// };
//저장시 9시간 전으로 돌아가는 문제
const handleSelect = (date: Date | undefined) => {
if (!readOnly) {
// readOnly가 아닐 때만 변경 허용
field.onChange(date); // React Hook Form 업데이트
if (date) {
const utcMidnight = new Date(
//utc 삽입
Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())
);
field.onChange(utcMidnight);
} else {
field.onChange(undefined);
}
setOpen(false);
}
};
@@ -53,17 +70,17 @@ export function DatePicker({
className={
!selectClass
? cn(
"w-[240px] pl-3 text-left font-normal",
!field?.value && "text-muted-foreground",
"w-[240px] pl-3 text-left font-normal",
!field?.value && "text-muted-foreground",
//감리 지적사항으로 삭제 예정 리드온리는 리드온리 로만 보일수 있도록 수정
// disabled={readOnly} // readOnly일 때 버튼 비활성화
//readOnly && "opacity-60 cursor-not-allowed" 감리 지적사항으로
)
//감리 지적사항으로 삭제 예정 리드온리는 리드온리 로만 보일수 있도록 수정
// disabled={readOnly} // readOnly일 때 버튼 비활성화
//readOnly && "opacity-60 cursor-not-allowed" 감리 지적사항으로
)
: cn(
selectClass,
// , readOnly && "opacity-60 cursor-not-allowed"
)
selectClass,
// , readOnly && "opacity-60 cursor-not-allowed"
)
}
>
{field?.value ? (
@@ -87,10 +104,10 @@ export function DatePicker({
className="w-full"
//-- 데이트 피커가 드롭박스 형태로 년월을 선택할수 있도록 하는 Props 로 활성화 되면 드롭박스로 선택
// captionLayout="dropdown-buttons"
// fromYear={2000}
// toYear={new Date().getFullYear()}
// captionLayout="dropdown-buttons"
// fromYear={2000}
// toYear={new Date().getFullYear()}
toDate={new Date()} // 금일까지만 표시됨 (금일 이후는 안보임)
showOutsideDays={false} // 금월 까지만 표출되도록
mode="single"