Merge branch 'iipbs/common/main' into iipbs/fo/dev
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
type ChartConfig
|
||||
} from "./lib/chart";
|
||||
import type { CSSProperties } from "react";
|
||||
import { formatCommaNumber } from "./lib/function";
|
||||
|
||||
const customStyles = {
|
||||
legendContainer: {
|
||||
@@ -119,6 +120,7 @@ export default function Chart({chartConfig=undefined, chartData=[], chartTitle='
|
||||
fontWeight={500}
|
||||
domain={[0, globalMax]}
|
||||
ticks={ticks}
|
||||
tickFormatter={(value) => formatCommaNumber(value)}
|
||||
label={yFieldText ? { value: yFieldText, className:"text-[15px] font-bold", position: 'insideLeft', angle: -90, offset: -30 } : undefined}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<CustomTooltip active={undefined} payload={undefined} label={undefined} />}/>
|
||||
|
||||
@@ -94,6 +94,7 @@ export default function LineBarchart({
|
||||
|
||||
// 데이터의 최대값 계산
|
||||
const getMaxValue = (data: any[], keyPrefix: string) => {
|
||||
if (!data || data.length === 0) return 0;
|
||||
return Math.max(...data.map(item =>
|
||||
Object.keys(item)
|
||||
.filter(key => key.includes(keyPrefix))
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// 숫자입력시 , 삽입
|
||||
export const formatCommaNumber = (
|
||||
value: number | string | undefined | null
|
||||
): string => {
|
||||
if (value === undefined || value === null || value === "") return "";
|
||||
const num = Number(value);
|
||||
// 숫자로 변환할 수 없는 값이 들어올 경우 빈 문자열을 반환하여 예상치 못한 "NaN" 출력을 방지합니다.
|
||||
if (isNaN(num)) {
|
||||
return "";
|
||||
}
|
||||
return num.toLocaleString();
|
||||
};
|
||||
@@ -20,6 +20,73 @@ import GisApp from './lib/gis.core';
|
||||
|
||||
export const GisContext = createContext({ gisCore: null, gisMap: null, treeData: null, checkedLayerIds: null });
|
||||
export const useGisContext = () => useContext(GisContext);
|
||||
export const searchUpperPpls = async (fcltMngNo) => {
|
||||
const BASE_URL = process.env.NEXT_PUBLIC_SEWERAGE_API_URL || '';
|
||||
|
||||
const res = await fetch(`${BASE_URL}/v1/fcltmhl/upperPpls/${fcltMngNo}`, {
|
||||
method: "GET",
|
||||
});
|
||||
|
||||
let data = null;
|
||||
if (res.ok) {
|
||||
try {
|
||||
// 응답이 비어있는지 확인
|
||||
const contentLength = res.headers.get('content-length');
|
||||
if (contentLength === '0') alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`);
|
||||
|
||||
// 응답 텍스트를 먼저 가져와서 빈 문자열인지 확인
|
||||
const text = await res.text();
|
||||
if (!text || text.trim() === '') alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`);
|
||||
|
||||
// JSON 파싱 시도
|
||||
data = JSON.parse(text);
|
||||
} catch (error) {
|
||||
console.error('JSON parsing error:', error);
|
||||
alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`);
|
||||
}
|
||||
}
|
||||
|
||||
const select = GisApp.Module.select;
|
||||
|
||||
const gisMap = GisApp.Module.core?.map;
|
||||
|
||||
let foundFeature = null;
|
||||
|
||||
data.forEach(item => {
|
||||
const pplMngNo = item.ppl_mng_no.trim();
|
||||
|
||||
gisMap.getLayers().getArray().filter(e => e.get("lyrTyNm") == 'tb_ms_swage_ppl').forEach(layer => {
|
||||
const source = layer.getSource?.();
|
||||
if (source?.getFeatures) {
|
||||
const features = source.getFeatures();
|
||||
for (const f of features) {
|
||||
if (f.values_.fclt_mng_no.trim() === pplMngNo) {
|
||||
foundFeature = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (foundFeature) select.selectMultiFeature(foundFeature, true);
|
||||
});
|
||||
|
||||
if (!foundFeature) alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`);
|
||||
|
||||
let geometry = foundFeature?.getGeometry();
|
||||
if (geometry) {
|
||||
let extent = geometry.getExtent();
|
||||
|
||||
gisMap.getView().fit(extent, {
|
||||
duration: 300,
|
||||
padding: [50, 50, 50, 50],
|
||||
maxZoom: 14,
|
||||
constrainResolution: true,
|
||||
nearest: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function Gis({
|
||||
isOpen,
|
||||
@@ -86,20 +153,28 @@ function Gis({
|
||||
foundFeature = data;
|
||||
} else {
|
||||
// 아니면 featureId로 맵에서 Feature 인스턴스를 찾아서 사용
|
||||
let featureId
|
||||
let featureId = data.fid;
|
||||
const layerName = layerNmRef.current
|
||||
if (layerName === '하수재이용시설') {
|
||||
featureId = data.searchPk;
|
||||
} else if (layerName === '빗물이용시설'|| layerName == '중수도시설') {
|
||||
} else if (layerName === '빗물이용시설' || layerName == '중수도시설') {
|
||||
featureId = data.bdstInfoSn;
|
||||
} else if (layerName === '하수처리시설') {
|
||||
} else if (layerName === '하수처리시설') {
|
||||
featureId = data.bscFctCd;
|
||||
} else if (layerName === '온배수시설' ) {
|
||||
} else if (layerName === '온배수시설') {
|
||||
featureId = data.bdstRuseFcltSn;
|
||||
} else {
|
||||
} else {
|
||||
console.warn('해당 레이어에 대한 featureId 매핑 없음', layerNm);
|
||||
featureId = data.fid || data.id || data.ftrIdn;
|
||||
}
|
||||
}
|
||||
// gisMap.getLayers().getArray().forEach(layer => {
|
||||
// const source = layer.getSource?.();
|
||||
// if (source?.getFeatureById) {
|
||||
// const feature = source.getFeatureById(String(featureId).trim());
|
||||
// if (feature) foundFeature = feature;
|
||||
// }
|
||||
// });
|
||||
// const [layerType, id] = String(featureId).split('.');
|
||||
gisMap.getLayers().getArray().forEach(layer => {
|
||||
const source = layer.getSource?.();
|
||||
if (source?.getFeatures) {
|
||||
@@ -410,7 +485,7 @@ function Gis({
|
||||
onFeatureSelect={handleFeatureSelect}
|
||||
/>
|
||||
)}
|
||||
<GisLonLat />
|
||||
{/* <GisLonLat /> */}
|
||||
<GisToolBar />
|
||||
<GisMapToggle />
|
||||
<GisSelect onFeatureSelect={handleFeatureSelect} />
|
||||
|
||||
@@ -429,6 +429,19 @@ GisOlSelect.prototype = {
|
||||
auto: auto,
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 피처 다중 셀렉트
|
||||
*/
|
||||
selectMultiFeature: function (feature, auto) {
|
||||
let me = this;
|
||||
me.selectedFeatures.push(feature);
|
||||
me.selectInteraction.dispatchEvent({
|
||||
type: 'select',
|
||||
selected: me.selectedFeatures,
|
||||
deselected: [],
|
||||
auto: auto,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default GisOlSelect;
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/**
|
||||
* @remarks
|
||||
* 이 버전은 SearchModal에서 사용하기 위해 `SelectContent`의 z-index를 `z-[101]`로 수정하였습니다.
|
||||
*/
|
||||
import { Label } from "@common/components";
|
||||
import React from "react";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./lib/selectBox";
|
||||
|
||||
/** 차트 기본 스타일 */
|
||||
interface SelectBox1 {
|
||||
text:string,
|
||||
val:string|number
|
||||
}
|
||||
|
||||
const SelectBox2 = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement> & {
|
||||
label:string,
|
||||
selectClass:string|undefined,
|
||||
className:string,
|
||||
selectArray:SelectBox1[],
|
||||
onSelectValue:(val:string|number)=>void,
|
||||
value?: string|number
|
||||
}
|
||||
>(({ label, className, selectClass, selectArray, onSelectValue, value }, ref)=>{
|
||||
const placeHolder = selectArray?.[0]?.text ?? "";
|
||||
|
||||
return (
|
||||
<div className={className+" flex items-center flex-nowrap"} ref={ref}>
|
||||
{label && <Label className="inline-block w-auto whitespace-nowrap text-xl text-gray-600 mr-2">{label}</Label>}
|
||||
<Select onValueChange={onSelectValue} value={value !== undefined ? String(value) : undefined}>
|
||||
<SelectTrigger className={selectClass?selectClass:"flex-1 p-2 border rounded"}>
|
||||
<SelectValue placeholder={placeHolder} />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="z-[101]">
|
||||
{selectArray.map((selectArray) => (
|
||||
<SelectItem key={selectArray.val} value={String(selectArray.val)}>{selectArray.text}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
export { SelectBox2 };
|
||||
@@ -27,6 +27,7 @@ const SelectBox = React.forwardRef<
|
||||
onSelectValue: (val: string | number) => void;
|
||||
value?: string | number;
|
||||
readOnly?: boolean; // readOnly 속성 추가
|
||||
selectContentClass?: string;
|
||||
}
|
||||
>(
|
||||
(
|
||||
@@ -38,6 +39,7 @@ const SelectBox = React.forwardRef<
|
||||
onSelectValue,
|
||||
value,
|
||||
readOnly = false,
|
||||
selectContentClass,
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
@@ -87,7 +89,7 @@ const SelectBox = React.forwardRef<
|
||||
>
|
||||
<SelectValue placeholder={placeHolder} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectContent className={selectContentClass}>
|
||||
{visibleItems.map((selectArray) => (
|
||||
<SelectItem key={selectArray.val} value={String(selectArray.val)}>
|
||||
{selectArray.text}
|
||||
|
||||
Reference in New Issue
Block a user