diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/rdiiChart.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/rdiiChart.tsx
index 39617eb21..12289254c 100644
--- a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/rdiiChart.tsx
+++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/rdiiChart.tsx
@@ -1,282 +1,318 @@
'use client'
-import { CHART_FORM, type ChartConfig, MainChart, UiModal } from "@common/business_components";
+
+import React, { useEffect, useMemo, useState } from 'react';
+import moment from 'moment';
+
+import {
+ CHART_FORM,
+ type ChartConfig,
+ MainChart,
+ UiModal,
+} from '@common/business_components';
import { SelectBox } from '@common/business_components/ui';
import { Button, Input, Label } from '@common/components';
-import React, { useEffect, useState } from 'react';
-import moment from "moment";
import type { TRdiiAnls } from './aplcnYms';
import * as fn from './aplcnYms';
-import { useRdiiChartModalStore } from '../chartModalStore'; // 모달 상태 관리 스토어
+import { useRdiiChartModalStore } from '../chartModalStore';
type ModalOpenProp = {
- pplMngNo: string, // 관로관리번호
-}
-// 차트
-type lineBarChartData = {
- label : string;
- lineVal0 : number;
- barVal0 : number;
-}
+ pplMngNo?: string; // 관로관리번호
+};
+type LineBarChartData = {
+ label: string;
+ lineVal0: number;
+ barVal0: number;
+};
-const RdiiChart = ({ pplMngNo }: ModalOpenProp) => {
- const { isOpen: isModalOpen, setIsOpen: setIsModalOpen } = useRdiiChartModalStore(); // 모달 상태 관리 스토어
- const [popupOpen, setPopupOpen] = React.useState(false); // 조회조건팝업
- const buttonRef = React.useRef
(null); // 버튼 참조
- const [popupPosition, setPopupPosition] = useState<{ top: number; left: number }>({ top: 0, left: 0 }); // 팝업 위치
- const [aplcnYm, setAplcnYm] = useState("");
+const INITIAL_ANALYSIS_OPTIONS = [{ val: 0, text: '선택' }];
+
+const RdiiChart = ({ pplMngNo = '' }: ModalOpenProp) => {
+ const { isOpen: isModalOpen, setIsOpen: setIsModalOpen } = useRdiiChartModalStore();
+
+ const [aplcnYm, setAplcnYm] = useState('');
const [rdiiAnlss, setRdiiAnlss] = useState([]);
- const [rdiiAnlsInfos, setRdiiAnlsInfos] = useState<{ text: string; val: number; hidden?: boolean }[]>([{ val: 0, text: '선택' }]); // 강우유입수분석정보 options
+ const [rdiiAnlsInfos, setRdiiAnlsInfos] = useState<{ text: string; val: number; hidden?: boolean }[]>(
+ INITIAL_ANALYSIS_OPTIONS,
+ );
const [rdiiAnls, setRdiiAnls] = useState(null); // 강우유입수분석정보
- const [rainInfwtAnlsSn, setRainInfwtAnlsSn] = useState(0); // 강우유입수분석 정보 선택시 사용
- const [chartData, setChartData] = useState([]);
- const [rdiiQty, setRdiiQty] = useState("0"); // 강우유입수량
- const [rainTotal, setRainTotal] = useState("0"); // 적용강우량
- const [totalVolume, setTotalVolume] = useState("0"); // 총체적 m³/mm
+ const [rainInfwtAnlsSn, setRainInfwtAnlsSn] = useState(0);// 강우유입수분석 정보 선택시 사용
+ const [chartData, setChartData] = useState([]);
+ const [rdiiQty, setRdiiQty] = useState('0'); // 강우유입수량
+ const [rainTotal, setRainTotal] = useState('0'); // 적용강우량
+ const [totalVolume, setTotalVolume] = useState('0');// 총체적 m³/mm
+
const aplcnYms = fn.useAplcnYms('rdiiAnlsRslt'); // 상수사용월 데이터 가져오기
- pplMngNo = "L"+pplMngNo; // "L13101003";
-
- const openPopup = () => {
- if (buttonRef.current) {
- const rect = buttonRef.current.getBoundingClientRect(); // 버튼 위치 계산
- setPopupPosition({
- top: rect.bottom + window.scrollY, // 버튼 아래쪽
- left: rect.left + window.scrollX, // 버튼 왼쪽
- });
- }
- setPopupOpen(true); // 팝업 열기
- };
+ const normalizedPplMngNo = pplMngNo ? `L${pplMngNo}` : '';
const chartForm = CHART_FORM.LINEBAR2;
const chartConfig = {
- barVal0: {
+ barVal0: {
label: '강수량',
- color: "#33AAFF",
+ color: '#33AAFF',
},
lineVal0: {
label: 'RDII',
- color: "#FF0000",
+ color: '#FF0000',
},
} as ChartConfig;
+ const hasChartData = useMemo(() => chartData.length > 0, [chartData]);
+
+ const resetState = () => {
+ setAplcnYm(''); // 상수사용월 초기화
+ setRdiiAnlss([]); // 강우유입수분석 초기화
+ setRdiiAnlsInfos(INITIAL_ANALYSIS_OPTIONS); // 강우유입수분석정보 초기화
+ setRdiiAnls(null); // 강우유입수분석정보 초기화
+ setRainInfwtAnlsSn(0); // 강우유입수분석 일련번호 초기화
+ setChartData([]);
+ setRdiiQty('0'); // 강우유입수량 초기화
+ setRainTotal('0');// 적용강우량 초기화
+ setTotalVolume('0');// 총체적 m³/mm 초기화
+ };
+
useEffect(() => {
- if (isModalOpen === false) {
- setPopupOpen(true); // 모달이 닫힐 때 팝업은
- setAplcnYm(""); // 상수사용월 초기화
- setRdiiAnlss([]); // 강우유입수분석 초기화
- setRdiiAnlsInfos([{ val: 0, text: '선택' }]); // 강우유입수분석정보 초기화
- setRdiiAnls(null); // 강우유입수분석정보 초기화
- setRainInfwtAnlsSn(0); // 강우유입수분석 일련번호 초기화
- setChartData([]); // 차트 데이터 초기화
- setRdiiQty("0"); // 강우유입수량 초기화
- setRainTotal("0"); // 적용강우량 초기화
- setTotalVolume("0"); // 총체적 m³/mm 초기화
+ if (!isModalOpen) {
+ resetState();
}
}, [isModalOpen]);
- // 상수사용월 변경시 분석 정보 리스트 가져오기
- useEffect(() => {
- // aplcnYm이 비어있거나 "0"이면 API 호출하지 않음
- if (!aplcnYm || aplcnYm === "0" || aplcnYm === "") {
- setRainInfwtAnlsSn(0); // 초기화
- setRdiiAnlsInfos([]);
+ const handleAplcnYmChange = async (val: string | number) => {
+ const selectedValue = String(val);
+
+ setAplcnYm(selectedValue);
+ setRdiiAnlss([]);
+ setRdiiAnls(null);
+ setRainInfwtAnlsSn(0);
+ setChartData([]);
+ setRdiiQty('0');
+ setRainTotal('0');
+ setTotalVolume('0');
+
+ if (!selectedValue || selectedValue === '0') {
+ setRdiiAnlsInfos(INITIAL_ANALYSIS_OPTIONS);
return;
}
- fn.selectRdiiAnls(aplcnYm)
- .then((data) => {
- setRdiiAnlss(data ?? []); // 선택한 월의 분석성공한 RDII분석데이터[]
- setRdiiAnlsInfos(fn.getOptionsRdiiAnlsInfo(data));
- setRdiiAnls(null); // 오수전환율 이후 초기화
- setRainInfwtAnlsSn(0); // 초기화
- })
- .catch((error) => {
- console.error("selectrdiiAnls 에러:", error);
- setRdiiAnlss([]);
- setRdiiAnlsInfos([]);
- });
- }, [aplcnYm]);
- // 값 표시
- useEffect(() => {
- // 선택된 강우유입수분석 정보에 대한 처리 로직
- if (rainInfwtAnlsSn === 0) return;
- const selectedAnls = rdiiAnlss.find(anls => anls.rainInfwtAnlsSn === rainInfwtAnlsSn);
- if (selectedAnls) {
- setRdiiAnls(selectedAnls);
+ try {
+ const data = await fn.selectRdiiAnls(selectedValue); // 상수사용월 변경시 분석 정보 리스트 가져오기
+ const list = data ?? [];
+ setRdiiAnlss(list);
+ setRdiiAnlsInfos(fn.getOptionsRdiiAnlsInfo(list));
+ } catch (error) {
+ console.error('selectRdiiAnls 에러:', error);
+ setRdiiAnlss([]);
+ setRdiiAnlsInfos(INITIAL_ANALYSIS_OPTIONS);
}
- }, [rainInfwtAnlsSn, rdiiAnlss]);
-
- const closePopup = () => { // 팝업 닫기
- setPopupOpen(false);
- }
- const rdiiRsltChart = () => { // 그래프 & 팝업 닫기
- fetchFilteredData();
- fn.selectPplRdiiQty(rainInfwtAnlsSn, pplMngNo).then((data) => {// 강우유입수량 조회
- setRdiiQty(Math.round(data?.rdiih*24).toLocaleString('ko-KR')); // cmd: m³/d 단위로 변환
- if (data?.raintotal && data?.rainTotal !== 0) {
- setRainTotal(data?.raintotal.toLocaleString('ko-KR')); // 총강우량mm
- setTotalVolume(Math.round(data?.rdiih * data?.sustaintime / data?.raintotal).toLocaleString('ko-KR')); // 총체적 m³/mm
- }
- });
- setPopupOpen(false);
};
- const fetchFilteredData: () => Promise = async () => {
- const rsltData = await fn.selectRdiiAnlsRslt(rainInfwtAnlsSn, pplMngNo);
- const rsltDataformatted = fn.getChartDataRdiiAnlsRslt(rsltData ?? []); // format 변경
- const rainData = await fn.selectRainData(rainInfwtAnlsSn);
- const rainDataformatted = fn.getChartDataRainData(rainData ?? []); // format 변경
- const rainMap = new Map(rainDataformatted.map(item => [item.label, item.barVal0]));
+ const handleRdiiAnlsSnChange = (val: string | number) => {
+ const selectedValue = Number(val);
+
+ setRainInfwtAnlsSn(selectedValue);
+ setChartData([]);
+ setRdiiQty('0');
+ setRainTotal('0');
+ setTotalVolume('0');
+
+ if (selectedValue === 0) {
+ setRdiiAnls(null);
+ return;
+ }
+
+ const selectedAnls = rdiiAnlss.find((anls) => anls.rainInfwtAnlsSn === selectedValue) ?? null;
+ setRdiiAnls(selectedAnls);
+ };
+
+ const fetchFilteredData = async () => {
+ if (!rainInfwtAnlsSn || !normalizedPplMngNo) {
+ setChartData([]);
+ setRdiiQty('0');
+ setRainTotal('0');
+ setTotalVolume('0');
+ return;
+ }
+
+ try {
+ const [rsltData, rainData, qtyData] = await Promise.all([
+ fn.selectRdiiAnlsRslt(rainInfwtAnlsSn, normalizedPplMngNo),
+ fn.selectRainData(rainInfwtAnlsSn),
+ fn.selectPplRdiiQty(rainInfwtAnlsSn, normalizedPplMngNo),
+ ]);
+
+ const rsltDataFormatted = fn.getChartDataRdiiAnlsRslt(rsltData ?? []);
+ const rainDataFormatted = fn.getChartDataRainData(rainData ?? []);
+ const rainMap = new Map(rainDataFormatted.map((item) => [item.label, item.barVal0]));
+
+ rsltDataFormatted.forEach((item) => {
+ const matchedVal = rainMap.get(item.label);
+ if (matchedVal !== undefined) {
+ item.barVal0 = matchedVal;
+ }
+ });
+
+ setChartData(rsltDataFormatted);// 차트 데이터 설정
+
+ const avgRdii = Number(qtyData?.rdiih ?? 0);
+ const appliedRainfall = Number(qtyData?.raintotal ?? 0);
+ const rdiiPerRainfall =
+ qtyData?.raintotal && qtyData?.raintotal !== 0
+ ? Math.round(avgRdii * Number(qtyData?.sustaintime ?? 0) / qtyData.raintotal)
+ : 0;
+
+ setRdiiQty(Math.round(avgRdii * 24).toLocaleString('ko-KR'));
+ setRainTotal(appliedRainfall.toLocaleString('ko-KR'));
+ setTotalVolume(rdiiPerRainfall.toLocaleString('ko-KR'));
+ } catch (error) {
+ console.error('rdiiRsltChart 에러:', error);
+ setChartData([]);
+ setRdiiQty('0');
+ setRainTotal('0');
+ setTotalVolume('0');
+ }
+ };
+
+ const renderInfoInput = (label: string, value?: string | number | null) => (
+
+
+
+
+ );
- rsltDataformatted.forEach(item => {
- const matchedVal = rainMap.get(item.label);
- if (matchedVal !== undefined) {
- item.barVal0 = matchedVal;
- }
- });
- setChartData(rsltDataformatted); // 차트 데이터 설정
- }
const renderBody = () => (
- <>
- RDII분석결과
-
-
-
-
- {/* 상수사용량 적용연월 */}
-
-
● 상수사용량 적용연월
-
-
- {(aplcnYm)? moment(aplcnYm, "YYYYMM").format("YYYY-MM"):""}
-
-
-
-
- {/* 강우유입수량 분석결과 */}
-
-
● 강우유입수량 분석결과
-
- 평균RDII :
- {rdiiQty}
- m³/d
-
-
- 적용강우량 :
- {rainTotal}
- mm
-
-
- 강우량대비RDII :
- {totalVolume}
- m³/mm
-
-
-
- {/* 차트 */}
-
-
-
+
+
- {popupOpen && (
-
-
강우유입수분석 입력현황
-
-
-
- {
- setAplcnYm(String(val));
- }}
- />
-
-
-
- {
- setRainInfwtAnlsSn(Number(val));
- }}
- />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ 강우유입수분석 선택 조건
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {renderInfoInput('오수전환율:', rdiiAnls?.drtwSwtcRt ?? '')}
+ {renderInfoInput('수용가-맨홀 매칭:', rdiiAnls?.atflMpngNm ?? '')}
+ {renderInfoInput('관망도 파일명:', rdiiAnls?.atflInpNm ?? '')}
+ {renderInfoInput('강우 파일명:', rdiiAnls?.atflRainNm ?? '')}
+ {renderInfoInput('RTK계수 출처:', rdiiAnls?.srcNm ?? '')}
-
-
-
+
+
+
+
+
-
)}
- {/* */}
- >
- )
+
+
+
+
+ 강우유입수분석 결과
+
+
+
+
+
+ 상수사용량 적용연월
+
+
+ {aplcnYm ? moment(aplcnYm, 'YYYYMM').format('YYYY-MM') : '-'}
+
+
+
+
+
+ 강우유입수량 분석결과
+
+
+
+
평균RDII
+
+ {rdiiQty}
+ m³/d
+
+
+
+
적용강우량
+
+ {rainTotal}
+ mm
+
+
+
+
강우량대비 RDII
+
+ {totalVolume}
+ m³/mm
+
+
+
+
+
+
+
+ {hasChartData ? (
+
+ ) : (
+
+ 데이터가 없습니다.
+
+ )}
+
+
+
+
+ );
return (
{
onOpenChange={setIsModalOpen}
headerTitle=""
bodyClass={`
- min-h-[50vh]
- w-[55vw]
- max-w-none
- max-h-none
- overflow-visible
- z-[50]
- `}
+ w-[78vw]
+ max-w-none
+ min-h-[74vh]
+ max-h-none
+ overflow-visible
+ z-[50]
+ `}
body={renderBody()}
- noFooterYn = 'Y'
+ noFooterYn="Y"
/>
- )
-}
+ );
+};
-export default React.memo(RdiiChart);
\ No newline at end of file
+export default React.memo(RdiiChart);