@mint-ui/map 1.2.0-test.46 → 1.2.0-test.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/mint-map/core/advanced/woongCanvasPolygon/WoongCanvasPolygon.d.ts +125 -3
- package/dist/components/mint-map/core/advanced/woongCanvasPolygon/WoongCanvasPolygon.js +16 -18
- package/dist/components/mint-map/core/advanced/woongCanvasPolygon/renderer.d.ts +63 -0
- package/dist/components/mint-map/core/advanced/woongCanvasPolygon/renderer.js +183 -0
- package/dist/index.es.js +197 -18
- package/dist/index.umd.js +197 -18
- package/package.json +1 -1
|
@@ -4,11 +4,65 @@ import { CanvasData } from "../shared";
|
|
|
4
4
|
export { WoongCanvasProvider, LRUCache, SpatialHashGrid } from "../shared";
|
|
5
5
|
export type { CanvasOption, CanvasData, RenderUtils } from "../shared";
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* 폴리곤 스타일 정의
|
|
8
|
+
*/
|
|
9
|
+
export interface PolygonStyle {
|
|
10
|
+
/** 채우기 색상 */
|
|
11
|
+
fillColor: string;
|
|
12
|
+
/** 테두리 색상 */
|
|
13
|
+
strokeColor: string;
|
|
14
|
+
/** 테두리 두께 */
|
|
15
|
+
lineWidth: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 폴리곤 스타일 컨텍스트 (선택/호버/활성 상태 정보)
|
|
19
|
+
*/
|
|
20
|
+
export interface PolygonStyleContext {
|
|
21
|
+
/** 선택 여부 */
|
|
22
|
+
isSelected: boolean;
|
|
23
|
+
/** 호버 여부 */
|
|
24
|
+
isHovered: boolean;
|
|
25
|
+
/** 활성 여부 (마지막 선택된 항목) */
|
|
26
|
+
isActive: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 폴리곤 스타일 함수 타입
|
|
8
30
|
*
|
|
9
|
-
*
|
|
31
|
+
* item 데이터와 상태 정보를 기반으로 자유롭게 스타일을 결정할 수 있습니다.
|
|
32
|
+
*
|
|
33
|
+
* @param item 폴리곤 데이터
|
|
34
|
+
* @param context 선택/호버/활성 상태 정보
|
|
35
|
+
* @returns 폴리곤 스타일
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* getStyle={(item, context) => {
|
|
40
|
+
* // item의 속성에 따라 동적으로 스타일 결정
|
|
41
|
+
* if (item.someProperty > 100) {
|
|
42
|
+
* return { fillColor: 'red', strokeColor: 'darkred', lineWidth: 3 };
|
|
43
|
+
* }
|
|
44
|
+
*
|
|
45
|
+
* // 상태 정보를 기반으로 스타일 결정
|
|
46
|
+
* if (context.isActive) {
|
|
47
|
+
* return { fillColor: 'yellow', strokeColor: 'orange', lineWidth: 5 };
|
|
48
|
+
* }
|
|
49
|
+
* if (context.isHovered) {
|
|
50
|
+
* return { fillColor: 'blue', strokeColor: 'darkblue', lineWidth: 3 };
|
|
51
|
+
* }
|
|
52
|
+
* if (context.isSelected) {
|
|
53
|
+
* return { fillColor: 'green', strokeColor: 'darkgreen', lineWidth: 4 };
|
|
54
|
+
* }
|
|
55
|
+
*
|
|
56
|
+
* // 기본 스타일
|
|
57
|
+
* return { fillColor: 'gray', strokeColor: 'black', lineWidth: 2 };
|
|
58
|
+
* }}
|
|
59
|
+
* ```
|
|
10
60
|
*/
|
|
11
|
-
export
|
|
61
|
+
export declare type PolygonStyleFunction<T> = (item: CanvasData<T>, context: PolygonStyleContext) => PolygonStyle;
|
|
62
|
+
/**
|
|
63
|
+
* 공통 Props (두 방식 모두 공통)
|
|
64
|
+
*/
|
|
65
|
+
interface WoongCanvasPolygonBaseProps<T> extends Pick<MarkerOptions, 'zIndex' | 'anchor' | 'visible'> {
|
|
12
66
|
/** 렌더링할 폴리곤 데이터 배열 */
|
|
13
67
|
data: CanvasData<T>[];
|
|
14
68
|
/** 폴리곤 클릭 시 호출되는 콜백 함수 */
|
|
@@ -27,6 +81,13 @@ export interface WoongCanvasPolygonProps<T> extends Pick<MarkerOptions, 'zIndex'
|
|
|
27
81
|
selectedItem?: CanvasData<T> | null;
|
|
28
82
|
/** 상호작용 비활성화 여부 (기본값: false) */
|
|
29
83
|
disableInteraction?: boolean;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 개별 Props 방식 (기존 방식)
|
|
87
|
+
*
|
|
88
|
+
* baseFillColor, baseStrokeColor, baseLineWidth가 있으면 자동으로 개별 props 방식으로 인식됩니다.
|
|
89
|
+
*/
|
|
90
|
+
interface WoongCanvasPolygonPropsWithIndividualStyles<T> extends WoongCanvasPolygonBaseProps<T> {
|
|
30
91
|
/** 기본 폴리곤 채우기 색상 (필수) */
|
|
31
92
|
baseFillColor: string;
|
|
32
93
|
/** 기본 폴리곤 테두리 색상 (필수) */
|
|
@@ -51,7 +112,68 @@ export interface WoongCanvasPolygonProps<T> extends Pick<MarkerOptions, 'zIndex'
|
|
|
51
112
|
hoveredStrokeColor?: string;
|
|
52
113
|
/** Hover 시 폴리곤 테두리 두께 */
|
|
53
114
|
hoveredLineWidth?: number;
|
|
115
|
+
/** 함수 방식 props는 사용 불가 */
|
|
116
|
+
renderStyle?: never;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* 함수 Props 방식 (새로운 방식)
|
|
120
|
+
*
|
|
121
|
+
* renderStyle 함수가 있으면 자동으로 함수 방식으로 인식됩니다.
|
|
122
|
+
* item 데이터와 상태 정보를 기반으로 자유롭게 스타일을 커스터마이징할 수 있습니다.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* renderStyle={(item, context) => {
|
|
127
|
+
* // item의 속성에 따라 동적으로 스타일 결정
|
|
128
|
+
* if (item.someProperty > 100) {
|
|
129
|
+
* return { fillColor: 'red', strokeColor: 'darkred', lineWidth: 3 };
|
|
130
|
+
* }
|
|
131
|
+
* // 상태 정보를 기반으로 스타일 결정
|
|
132
|
+
* if (context.isActive) {
|
|
133
|
+
* return { fillColor: 'yellow', strokeColor: 'orange', lineWidth: 5 };
|
|
134
|
+
* }
|
|
135
|
+
* // ...
|
|
136
|
+
* }}
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
interface WoongCanvasPolygonPropsWithFunctionStyle<T> extends WoongCanvasPolygonBaseProps<T> {
|
|
140
|
+
/**
|
|
141
|
+
* 폴리곤 스타일 함수 (item 데이터와 상태 정보를 기반으로 스타일 반환)
|
|
142
|
+
*
|
|
143
|
+
* @param item 폴리곤 데이터 (item의 속성을 기반으로 자유롭게 스타일 커스터마이징 가능)
|
|
144
|
+
* @param context 선택/호버/활성 상태 정보
|
|
145
|
+
* @returns 폴리곤 스타일
|
|
146
|
+
*/
|
|
147
|
+
renderStyle: PolygonStyleFunction<T>;
|
|
148
|
+
/** 개별 props는 사용 불가 */
|
|
149
|
+
baseFillColor?: never;
|
|
150
|
+
baseStrokeColor?: never;
|
|
151
|
+
baseLineWidth?: never;
|
|
152
|
+
selectedFillColor?: never;
|
|
153
|
+
selectedStrokeColor?: never;
|
|
154
|
+
selectedLineWidth?: never;
|
|
155
|
+
activeFillColor?: never;
|
|
156
|
+
activeStrokeColor?: never;
|
|
157
|
+
activeLineWidth?: never;
|
|
158
|
+
hoveredFillColor?: never;
|
|
159
|
+
hoveredStrokeColor?: never;
|
|
160
|
+
hoveredLineWidth?: never;
|
|
54
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* WoongCanvasPolygon Props (Discriminated Union)
|
|
164
|
+
*
|
|
165
|
+
* 두 가지 스타일 지정 방식을 지원:
|
|
166
|
+
* 1. 개별 props 방식: baseFillColor, baseStrokeColor, baseLineWidth가 있으면 자동으로 개별 props 방식
|
|
167
|
+
* 2. 함수 방식: renderStyle 함수가 있으면 자동으로 함수 방식
|
|
168
|
+
*
|
|
169
|
+
* 두 방식은 동시에 사용할 수 없습니다 (mutually exclusive).
|
|
170
|
+
* styleMode prop은 필요 없으며, renderStyle 또는 baseFillColor의 존재 여부로 자동 판단됩니다.
|
|
171
|
+
*
|
|
172
|
+
* 함수 방식에서는 item 데이터를 기반으로 자유롭게 스타일을 커스터마이징할 수 있습니다.
|
|
173
|
+
*
|
|
174
|
+
* @template T 폴리곤 데이터의 추가 속성 타입
|
|
175
|
+
*/
|
|
176
|
+
export declare type WoongCanvasPolygonProps<T> = WoongCanvasPolygonPropsWithIndividualStyles<T> | WoongCanvasPolygonPropsWithFunctionStyle<T>;
|
|
55
177
|
declare const WoongCanvasPolygon: <T>(props: WoongCanvasPolygonProps<T>) => React.ReactPortal;
|
|
56
178
|
/**
|
|
57
179
|
* WoongCanvasPolygon - Konva 기반 고성능 폴리곤 렌더링 컴포넌트
|
|
@@ -39,23 +39,16 @@ var WoongCanvasPolygon = function (props) {
|
|
|
39
39
|
externalSelectedItem = props.selectedItem,
|
|
40
40
|
_e = props.disableInteraction,
|
|
41
41
|
disableInteraction = _e === void 0 ? false : _e,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
activeStrokeColor = props.activeStrokeColor,
|
|
50
|
-
activeLineWidth = props.activeLineWidth,
|
|
51
|
-
hoveredFillColor = props.hoveredFillColor,
|
|
52
|
-
hoveredStrokeColor = props.hoveredStrokeColor,
|
|
53
|
-
hoveredLineWidth = props.hoveredLineWidth,
|
|
54
|
-
options = tslib.__rest(props, ["data", "onClick", "enableMultiSelect", "enableViewportCulling", "cullingMargin", "maxCacheSize", "selectedItems", "selectedItem", "disableInteraction", "baseFillColor", "baseStrokeColor", "baseLineWidth", "selectedFillColor", "selectedStrokeColor", "selectedLineWidth", "activeFillColor", "activeStrokeColor", "activeLineWidth", "hoveredFillColor", "hoveredStrokeColor", "hoveredLineWidth"]); // --------------------------------------------------------------------------
|
|
42
|
+
options = tslib.__rest(props, ["data", "onClick", "enableMultiSelect", "enableViewportCulling", "cullingMargin", "maxCacheSize", "selectedItems", "selectedItem", "disableInteraction"]); // renderStyle이 있으면 함수 방식, baseFillColor가 있으면 개별 props 방식
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
var isFunctionMode = 'renderStyle' in props && props.renderStyle !== undefined; // 개별 props 방식일 때만 추출
|
|
46
|
+
|
|
47
|
+
var individualProps = isFunctionMode ? undefined : props;
|
|
48
|
+
var functionProps = isFunctionMode ? props : undefined; // --------------------------------------------------------------------------
|
|
55
49
|
// Hooks & Context
|
|
56
50
|
// --------------------------------------------------------------------------
|
|
57
51
|
|
|
58
|
-
|
|
59
52
|
var controller = MintMapProvider.useMintMapController();
|
|
60
53
|
var context$1 = context.useWoongCanvasContext();
|
|
61
54
|
var currentZIndex = options.zIndex !== undefined ? options.zIndex : 0; // DOM Refs
|
|
@@ -157,10 +150,14 @@ var WoongCanvasPolygon = function (props) {
|
|
|
157
150
|
getOrComputeMarkerOffset: function () {
|
|
158
151
|
return null;
|
|
159
152
|
}
|
|
160
|
-
}; // 렌더링 함수 생성
|
|
153
|
+
}; // 렌더링 함수 생성 (스타일 지정 방식에 따라 분기)
|
|
161
154
|
|
|
162
|
-
var renderBase = renderer.renderPolygonBase(baseFillColor, baseStrokeColor, baseLineWidth)
|
|
163
|
-
|
|
155
|
+
var renderBase = isFunctionMode && functionProps ? renderer.renderPolygonBaseWithFunction(functionProps.renderStyle) : individualProps ? renderer.renderPolygonBase(individualProps.baseFillColor, individualProps.baseStrokeColor, individualProps.baseLineWidth) : function () {
|
|
156
|
+
throw new Error('Invalid props: either renderStyle or individual style props must be provided');
|
|
157
|
+
}();
|
|
158
|
+
var renderEvent = isFunctionMode && functionProps ? renderer.renderPolygonEventWithFunction(functionProps.renderStyle) : individualProps ? renderer.renderPolygonEvent(individualProps.baseFillColor, individualProps.baseStrokeColor, individualProps.baseLineWidth, individualProps.selectedFillColor, individualProps.selectedStrokeColor, individualProps.selectedLineWidth, individualProps.activeFillColor, individualProps.activeStrokeColor, individualProps.activeLineWidth, individualProps.hoveredFillColor, individualProps.hoveredStrokeColor, individualProps.hoveredLineWidth) : function () {
|
|
159
|
+
throw new Error('Invalid props: either renderStyle or individual style props must be provided');
|
|
160
|
+
}(); // Base Layer 렌더링 (뷰포트 컬링 적용)
|
|
164
161
|
|
|
165
162
|
var doRenderBase = function () {
|
|
166
163
|
var layer = baseLayerRef.current;
|
|
@@ -332,7 +329,8 @@ var WoongCanvasPolygon = function (props) {
|
|
|
332
329
|
}
|
|
333
330
|
|
|
334
331
|
selectedIdsRef.current = newSelected;
|
|
335
|
-
}
|
|
332
|
+
} // Event Layer 업데이트 (선택된 항목 표시)
|
|
333
|
+
|
|
336
334
|
|
|
337
335
|
doRenderEvent();
|
|
338
336
|
}; // 클릭 이벤트 핸들러
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* GeoJSON MultiPolygon 형식을 지원하며, 도넛 폴리곤(구멍이 있는 폴리곤)도 처리할 수 있습니다.
|
|
6
6
|
*/
|
|
7
7
|
import { CustomRenderBase, CustomRenderEvent } from "../shared/types";
|
|
8
|
+
import type { PolygonStyleFunction } from "./WoongCanvasPolygon";
|
|
8
9
|
/**
|
|
9
10
|
* 폴리곤 그리기 파라미터 인터페이스
|
|
10
11
|
*/
|
|
@@ -117,4 +118,66 @@ export declare const renderPolygonBase: <T = any>(baseFillColor: string, baseStr
|
|
|
117
118
|
* ```
|
|
118
119
|
*/
|
|
119
120
|
export declare const renderPolygonEvent: <T = any>(baseFillColor: string, baseStrokeColor: string, baseLineWidth: number, selectedFillColor?: string, selectedStrokeColor?: string, selectedLineWidth?: number, activeFillColor?: string, activeStrokeColor?: string, activeLineWidth?: number, hoveredFillColor?: string, hoveredStrokeColor?: string, hoveredLineWidth?: number) => CustomRenderEvent<T>;
|
|
121
|
+
/**
|
|
122
|
+
* 폴리곤 Base 렌더링 함수 팩토리 (함수 방식)
|
|
123
|
+
*
|
|
124
|
+
* Base Layer에서 사용할 렌더링 함수를 생성합니다.
|
|
125
|
+
* renderStyle 함수를 사용하여 각 폴리곤의 상태에 따라 스타일을 동적으로 결정합니다.
|
|
126
|
+
*
|
|
127
|
+
* @template T 폴리곤 데이터의 추가 속성 타입
|
|
128
|
+
* @param renderStyle 폴리곤 스타일 함수
|
|
129
|
+
* @returns Base Layer 렌더링 함수
|
|
130
|
+
*
|
|
131
|
+
* @remarks
|
|
132
|
+
* - 선택된 항목은 Event Layer에서 그려지므로 Base Layer에서는 스킵
|
|
133
|
+
* - 성능: O(n), n은 렌더링할 폴리곤 개수
|
|
134
|
+
* - 좌표 변환은 자동으로 캐싱되어 성능 최적화됨
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* const renderBase = renderPolygonBaseWithFunction<MyDataType>(
|
|
139
|
+
* (item, context) => ({
|
|
140
|
+
* fillColor: 'rgba(255, 100, 100, 0.5)',
|
|
141
|
+
* strokeColor: 'rgba(200, 50, 50, 0.8)',
|
|
142
|
+
* lineWidth: 2
|
|
143
|
+
* })
|
|
144
|
+
* );
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
export declare const renderPolygonBaseWithFunction: <T = any>(renderStyle: PolygonStyleFunction<T>) => CustomRenderBase<T>;
|
|
148
|
+
/**
|
|
149
|
+
* 폴리곤 Event 렌더링 함수 팩토리 (함수 방식)
|
|
150
|
+
*
|
|
151
|
+
* Event Layer에서 사용할 렌더링 함수를 생성합니다.
|
|
152
|
+
* renderStyle 함수를 사용하여 각 폴리곤의 상태에 따라 스타일을 동적으로 결정합니다.
|
|
153
|
+
*
|
|
154
|
+
* @template T 폴리곤 데이터의 추가 속성 타입
|
|
155
|
+
* @param renderStyle 폴리곤 스타일 함수
|
|
156
|
+
* @returns Event Layer 렌더링 함수
|
|
157
|
+
*
|
|
158
|
+
* @remarks
|
|
159
|
+
* - **렌더링 순서**: 선택된 항목 → 마지막 선택된 항목 → hover된 항목 (최상단)
|
|
160
|
+
* - **성능**: O(m), m은 선택된 항목 수 + hover된 항목 수
|
|
161
|
+
* - 좌표 변환은 자동으로 캐싱되어 성능 최적화됨
|
|
162
|
+
* - hover된 항목이 선택되어 있으면 active 스타일 적용
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```typescript
|
|
166
|
+
* const renderEvent = renderPolygonEventWithFunction<MyDataType>(
|
|
167
|
+
* (item, context) => {
|
|
168
|
+
* if (context.isActive) {
|
|
169
|
+
* return { fillColor: 'rgba(255, 152, 0, 0.8)', strokeColor: 'rgba(255, 87, 34, 1)', lineWidth: 5 };
|
|
170
|
+
* }
|
|
171
|
+
* if (context.isHovered) {
|
|
172
|
+
* return { fillColor: 'rgba(100, 150, 255, 0.8)', strokeColor: 'rgba(0, 100, 200, 1)', lineWidth: 3 };
|
|
173
|
+
* }
|
|
174
|
+
* if (context.isSelected) {
|
|
175
|
+
* return { fillColor: 'rgba(255, 193, 7, 0.7)', strokeColor: 'rgba(255, 152, 0, 1)', lineWidth: 4 };
|
|
176
|
+
* }
|
|
177
|
+
* return { fillColor: 'rgba(255, 100, 100, 0.5)', strokeColor: 'rgba(200, 50, 50, 0.8)', lineWidth: 2 };
|
|
178
|
+
* }
|
|
179
|
+
* );
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
export declare const renderPolygonEventWithFunction: <T = any>(renderStyle: PolygonStyleFunction<T>) => CustomRenderEvent<T>;
|
|
120
183
|
export {};
|
|
@@ -289,7 +289,190 @@ var renderPolygonEvent = function (baseFillColor, baseStrokeColor, baseLineWidth
|
|
|
289
289
|
}
|
|
290
290
|
};
|
|
291
291
|
};
|
|
292
|
+
/**
|
|
293
|
+
* 폴리곤 Base 렌더링 함수 팩토리 (함수 방식)
|
|
294
|
+
*
|
|
295
|
+
* Base Layer에서 사용할 렌더링 함수를 생성합니다.
|
|
296
|
+
* renderStyle 함수를 사용하여 각 폴리곤의 상태에 따라 스타일을 동적으로 결정합니다.
|
|
297
|
+
*
|
|
298
|
+
* @template T 폴리곤 데이터의 추가 속성 타입
|
|
299
|
+
* @param renderStyle 폴리곤 스타일 함수
|
|
300
|
+
* @returns Base Layer 렌더링 함수
|
|
301
|
+
*
|
|
302
|
+
* @remarks
|
|
303
|
+
* - 선택된 항목은 Event Layer에서 그려지므로 Base Layer에서는 스킵
|
|
304
|
+
* - 성능: O(n), n은 렌더링할 폴리곤 개수
|
|
305
|
+
* - 좌표 변환은 자동으로 캐싱되어 성능 최적화됨
|
|
306
|
+
*
|
|
307
|
+
* @example
|
|
308
|
+
* ```typescript
|
|
309
|
+
* const renderBase = renderPolygonBaseWithFunction<MyDataType>(
|
|
310
|
+
* (item, context) => ({
|
|
311
|
+
* fillColor: 'rgba(255, 100, 100, 0.5)',
|
|
312
|
+
* strokeColor: 'rgba(200, 50, 50, 0.8)',
|
|
313
|
+
* lineWidth: 2
|
|
314
|
+
* })
|
|
315
|
+
* );
|
|
316
|
+
* ```
|
|
317
|
+
*/
|
|
318
|
+
|
|
319
|
+
var renderPolygonBaseWithFunction = function (renderStyle) {
|
|
320
|
+
return function (_a) {
|
|
321
|
+
var ctx = _a.ctx,
|
|
322
|
+
items = _a.items,
|
|
323
|
+
selectedIds = _a.selectedIds,
|
|
324
|
+
utils = _a.utils;
|
|
325
|
+
|
|
326
|
+
for (var _i = 0, items_2 = items; _i < items_2.length; _i++) {
|
|
327
|
+
var item = items_2[_i]; // 선택된 항목은 Event Layer에서 그림 (중복 렌더링 방지)
|
|
328
|
+
|
|
329
|
+
if (selectedIds.has(item.id)) continue; // paths가 없으면 스킵
|
|
330
|
+
|
|
331
|
+
if (!item.paths) continue; // 좌표 변환 (자동 캐싱)
|
|
332
|
+
|
|
333
|
+
var polygonOffsets = utils.getOrComputePolygonOffsets(item);
|
|
334
|
+
if (!polygonOffsets) continue; // 스타일 함수로 스타일 가져오기 (Base Layer는 선택되지 않은 항목만)
|
|
335
|
+
|
|
336
|
+
var context = {
|
|
337
|
+
isSelected: false,
|
|
338
|
+
isHovered: false,
|
|
339
|
+
isActive: false
|
|
340
|
+
};
|
|
341
|
+
var style = renderStyle(item, context); // 폴리곤 그리기
|
|
342
|
+
|
|
343
|
+
drawPolygon({
|
|
344
|
+
ctx: ctx,
|
|
345
|
+
polygonOffsets: polygonOffsets,
|
|
346
|
+
isDonutPolygon: item.isDonutPolygon || false,
|
|
347
|
+
fillColor: style.fillColor,
|
|
348
|
+
strokeColor: style.strokeColor,
|
|
349
|
+
lineWidth: style.lineWidth
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
};
|
|
354
|
+
/**
|
|
355
|
+
* 폴리곤 Event 렌더링 함수 팩토리 (함수 방식)
|
|
356
|
+
*
|
|
357
|
+
* Event Layer에서 사용할 렌더링 함수를 생성합니다.
|
|
358
|
+
* renderStyle 함수를 사용하여 각 폴리곤의 상태에 따라 스타일을 동적으로 결정합니다.
|
|
359
|
+
*
|
|
360
|
+
* @template T 폴리곤 데이터의 추가 속성 타입
|
|
361
|
+
* @param renderStyle 폴리곤 스타일 함수
|
|
362
|
+
* @returns Event Layer 렌더링 함수
|
|
363
|
+
*
|
|
364
|
+
* @remarks
|
|
365
|
+
* - **렌더링 순서**: 선택된 항목 → 마지막 선택된 항목 → hover된 항목 (최상단)
|
|
366
|
+
* - **성능**: O(m), m은 선택된 항목 수 + hover된 항목 수
|
|
367
|
+
* - 좌표 변환은 자동으로 캐싱되어 성능 최적화됨
|
|
368
|
+
* - hover된 항목이 선택되어 있으면 active 스타일 적용
|
|
369
|
+
*
|
|
370
|
+
* @example
|
|
371
|
+
* ```typescript
|
|
372
|
+
* const renderEvent = renderPolygonEventWithFunction<MyDataType>(
|
|
373
|
+
* (item, context) => {
|
|
374
|
+
* if (context.isActive) {
|
|
375
|
+
* return { fillColor: 'rgba(255, 152, 0, 0.8)', strokeColor: 'rgba(255, 87, 34, 1)', lineWidth: 5 };
|
|
376
|
+
* }
|
|
377
|
+
* if (context.isHovered) {
|
|
378
|
+
* return { fillColor: 'rgba(100, 150, 255, 0.8)', strokeColor: 'rgba(0, 100, 200, 1)', lineWidth: 3 };
|
|
379
|
+
* }
|
|
380
|
+
* if (context.isSelected) {
|
|
381
|
+
* return { fillColor: 'rgba(255, 193, 7, 0.7)', strokeColor: 'rgba(255, 152, 0, 1)', lineWidth: 4 };
|
|
382
|
+
* }
|
|
383
|
+
* return { fillColor: 'rgba(255, 100, 100, 0.5)', strokeColor: 'rgba(200, 50, 50, 0.8)', lineWidth: 2 };
|
|
384
|
+
* }
|
|
385
|
+
* );
|
|
386
|
+
* ```
|
|
387
|
+
*/
|
|
388
|
+
|
|
389
|
+
var renderPolygonEventWithFunction = function (renderStyle) {
|
|
390
|
+
return function (_a) {
|
|
391
|
+
var ctx = _a.ctx,
|
|
392
|
+
hoveredItem = _a.hoveredItem,
|
|
393
|
+
utils = _a.utils,
|
|
394
|
+
selectedItems = _a.selectedItems,
|
|
395
|
+
selectedItem = _a.selectedItem;
|
|
396
|
+
var selectedIdsSet = selectedItems ? new Set(selectedItems.map(function (item) {
|
|
397
|
+
return item.id;
|
|
398
|
+
})) : new Set();
|
|
399
|
+
var hoveredItemId = hoveredItem === null || hoveredItem === void 0 ? void 0 : hoveredItem.id;
|
|
400
|
+
var selectedItemId = selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id; // 1. 선택된 항목들 그리기 (마지막 선택 항목과 호버된 항목 제외)
|
|
401
|
+
|
|
402
|
+
if (selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.length) {
|
|
403
|
+
for (var _i = 0, selectedItems_2 = selectedItems; _i < selectedItems_2.length; _i++) {
|
|
404
|
+
var item = selectedItems_2[_i]; // 마지막 선택 항목과 호버된 항목은 나중에 따로 그림
|
|
405
|
+
|
|
406
|
+
if (item.id === selectedItemId || item.id === hoveredItemId) continue;
|
|
407
|
+
if (!item.paths) continue;
|
|
408
|
+
var polygonOffsets = utils.getOrComputePolygonOffsets(item);
|
|
409
|
+
if (!polygonOffsets) continue;
|
|
410
|
+
var context = {
|
|
411
|
+
isSelected: true,
|
|
412
|
+
isHovered: false,
|
|
413
|
+
isActive: false
|
|
414
|
+
};
|
|
415
|
+
var style = renderStyle(item, context);
|
|
416
|
+
drawPolygon({
|
|
417
|
+
ctx: ctx,
|
|
418
|
+
polygonOffsets: polygonOffsets,
|
|
419
|
+
isDonutPolygon: item.isDonutPolygon || false,
|
|
420
|
+
fillColor: style.fillColor,
|
|
421
|
+
strokeColor: style.strokeColor,
|
|
422
|
+
lineWidth: style.lineWidth
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
} // 2. 마지막 선택된 항목 그리기 (호버되지 않은 경우)
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
if ((selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.paths) && hoveredItemId !== selectedItemId) {
|
|
429
|
+
var polygonOffsets = utils.getOrComputePolygonOffsets(selectedItem);
|
|
430
|
+
|
|
431
|
+
if (polygonOffsets) {
|
|
432
|
+
var context = {
|
|
433
|
+
isSelected: true,
|
|
434
|
+
isHovered: false,
|
|
435
|
+
isActive: true
|
|
436
|
+
};
|
|
437
|
+
var style = renderStyle(selectedItem, context);
|
|
438
|
+
drawPolygon({
|
|
439
|
+
ctx: ctx,
|
|
440
|
+
polygonOffsets: polygonOffsets,
|
|
441
|
+
isDonutPolygon: selectedItem.isDonutPolygon || false,
|
|
442
|
+
fillColor: style.fillColor,
|
|
443
|
+
strokeColor: style.strokeColor,
|
|
444
|
+
lineWidth: style.lineWidth
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
} // 3. 호버된 항목 그리기 (가장 위에 표시)
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
if (hoveredItem === null || hoveredItem === void 0 ? void 0 : hoveredItem.paths) {
|
|
451
|
+
var polygonOffsets = utils.getOrComputePolygonOffsets(hoveredItem);
|
|
452
|
+
if (!polygonOffsets) return; // 좌표 변환 실패 시 스킵 (return은 렌더링 함수 종료)
|
|
453
|
+
// hover된 항목이 선택되어 있는지 확인
|
|
454
|
+
|
|
455
|
+
var isSelected = selectedIdsSet.has(hoveredItem.id);
|
|
456
|
+
var context = {
|
|
457
|
+
isSelected: isSelected,
|
|
458
|
+
isHovered: true,
|
|
459
|
+
isActive: isSelected && hoveredItem.id === selectedItemId
|
|
460
|
+
};
|
|
461
|
+
var style = renderStyle(hoveredItem, context);
|
|
462
|
+
drawPolygon({
|
|
463
|
+
ctx: ctx,
|
|
464
|
+
polygonOffsets: polygonOffsets,
|
|
465
|
+
isDonutPolygon: hoveredItem.isDonutPolygon || false,
|
|
466
|
+
fillColor: style.fillColor,
|
|
467
|
+
strokeColor: style.strokeColor,
|
|
468
|
+
lineWidth: style.lineWidth
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
};
|
|
292
473
|
|
|
293
474
|
exports.drawPolygon = drawPolygon;
|
|
294
475
|
exports.renderPolygonBase = renderPolygonBase;
|
|
476
|
+
exports.renderPolygonBaseWithFunction = renderPolygonBaseWithFunction;
|
|
295
477
|
exports.renderPolygonEvent = renderPolygonEvent;
|
|
478
|
+
exports.renderPolygonEventWithFunction = renderPolygonEventWithFunction;
|
package/dist/index.es.js
CHANGED
|
@@ -6551,6 +6551,187 @@ var renderPolygonEvent = function (baseFillColor, baseStrokeColor, baseLineWidth
|
|
|
6551
6551
|
}
|
|
6552
6552
|
};
|
|
6553
6553
|
};
|
|
6554
|
+
/**
|
|
6555
|
+
* 폴리곤 Base 렌더링 함수 팩토리 (함수 방식)
|
|
6556
|
+
*
|
|
6557
|
+
* Base Layer에서 사용할 렌더링 함수를 생성합니다.
|
|
6558
|
+
* renderStyle 함수를 사용하여 각 폴리곤의 상태에 따라 스타일을 동적으로 결정합니다.
|
|
6559
|
+
*
|
|
6560
|
+
* @template T 폴리곤 데이터의 추가 속성 타입
|
|
6561
|
+
* @param renderStyle 폴리곤 스타일 함수
|
|
6562
|
+
* @returns Base Layer 렌더링 함수
|
|
6563
|
+
*
|
|
6564
|
+
* @remarks
|
|
6565
|
+
* - 선택된 항목은 Event Layer에서 그려지므로 Base Layer에서는 스킵
|
|
6566
|
+
* - 성능: O(n), n은 렌더링할 폴리곤 개수
|
|
6567
|
+
* - 좌표 변환은 자동으로 캐싱되어 성능 최적화됨
|
|
6568
|
+
*
|
|
6569
|
+
* @example
|
|
6570
|
+
* ```typescript
|
|
6571
|
+
* const renderBase = renderPolygonBaseWithFunction<MyDataType>(
|
|
6572
|
+
* (item, context) => ({
|
|
6573
|
+
* fillColor: 'rgba(255, 100, 100, 0.5)',
|
|
6574
|
+
* strokeColor: 'rgba(200, 50, 50, 0.8)',
|
|
6575
|
+
* lineWidth: 2
|
|
6576
|
+
* })
|
|
6577
|
+
* );
|
|
6578
|
+
* ```
|
|
6579
|
+
*/
|
|
6580
|
+
|
|
6581
|
+
var renderPolygonBaseWithFunction = function (renderStyle) {
|
|
6582
|
+
return function (_a) {
|
|
6583
|
+
var ctx = _a.ctx,
|
|
6584
|
+
items = _a.items,
|
|
6585
|
+
selectedIds = _a.selectedIds,
|
|
6586
|
+
utils = _a.utils;
|
|
6587
|
+
|
|
6588
|
+
for (var _i = 0, items_2 = items; _i < items_2.length; _i++) {
|
|
6589
|
+
var item = items_2[_i]; // 선택된 항목은 Event Layer에서 그림 (중복 렌더링 방지)
|
|
6590
|
+
|
|
6591
|
+
if (selectedIds.has(item.id)) continue; // paths가 없으면 스킵
|
|
6592
|
+
|
|
6593
|
+
if (!item.paths) continue; // 좌표 변환 (자동 캐싱)
|
|
6594
|
+
|
|
6595
|
+
var polygonOffsets = utils.getOrComputePolygonOffsets(item);
|
|
6596
|
+
if (!polygonOffsets) continue; // 스타일 함수로 스타일 가져오기 (Base Layer는 선택되지 않은 항목만)
|
|
6597
|
+
|
|
6598
|
+
var context = {
|
|
6599
|
+
isSelected: false,
|
|
6600
|
+
isHovered: false,
|
|
6601
|
+
isActive: false
|
|
6602
|
+
};
|
|
6603
|
+
var style = renderStyle(item, context); // 폴리곤 그리기
|
|
6604
|
+
|
|
6605
|
+
drawPolygon({
|
|
6606
|
+
ctx: ctx,
|
|
6607
|
+
polygonOffsets: polygonOffsets,
|
|
6608
|
+
isDonutPolygon: item.isDonutPolygon || false,
|
|
6609
|
+
fillColor: style.fillColor,
|
|
6610
|
+
strokeColor: style.strokeColor,
|
|
6611
|
+
lineWidth: style.lineWidth
|
|
6612
|
+
});
|
|
6613
|
+
}
|
|
6614
|
+
};
|
|
6615
|
+
};
|
|
6616
|
+
/**
|
|
6617
|
+
* 폴리곤 Event 렌더링 함수 팩토리 (함수 방식)
|
|
6618
|
+
*
|
|
6619
|
+
* Event Layer에서 사용할 렌더링 함수를 생성합니다.
|
|
6620
|
+
* renderStyle 함수를 사용하여 각 폴리곤의 상태에 따라 스타일을 동적으로 결정합니다.
|
|
6621
|
+
*
|
|
6622
|
+
* @template T 폴리곤 데이터의 추가 속성 타입
|
|
6623
|
+
* @param renderStyle 폴리곤 스타일 함수
|
|
6624
|
+
* @returns Event Layer 렌더링 함수
|
|
6625
|
+
*
|
|
6626
|
+
* @remarks
|
|
6627
|
+
* - **렌더링 순서**: 선택된 항목 → 마지막 선택된 항목 → hover된 항목 (최상단)
|
|
6628
|
+
* - **성능**: O(m), m은 선택된 항목 수 + hover된 항목 수
|
|
6629
|
+
* - 좌표 변환은 자동으로 캐싱되어 성능 최적화됨
|
|
6630
|
+
* - hover된 항목이 선택되어 있으면 active 스타일 적용
|
|
6631
|
+
*
|
|
6632
|
+
* @example
|
|
6633
|
+
* ```typescript
|
|
6634
|
+
* const renderEvent = renderPolygonEventWithFunction<MyDataType>(
|
|
6635
|
+
* (item, context) => {
|
|
6636
|
+
* if (context.isActive) {
|
|
6637
|
+
* return { fillColor: 'rgba(255, 152, 0, 0.8)', strokeColor: 'rgba(255, 87, 34, 1)', lineWidth: 5 };
|
|
6638
|
+
* }
|
|
6639
|
+
* if (context.isHovered) {
|
|
6640
|
+
* return { fillColor: 'rgba(100, 150, 255, 0.8)', strokeColor: 'rgba(0, 100, 200, 1)', lineWidth: 3 };
|
|
6641
|
+
* }
|
|
6642
|
+
* if (context.isSelected) {
|
|
6643
|
+
* return { fillColor: 'rgba(255, 193, 7, 0.7)', strokeColor: 'rgba(255, 152, 0, 1)', lineWidth: 4 };
|
|
6644
|
+
* }
|
|
6645
|
+
* return { fillColor: 'rgba(255, 100, 100, 0.5)', strokeColor: 'rgba(200, 50, 50, 0.8)', lineWidth: 2 };
|
|
6646
|
+
* }
|
|
6647
|
+
* );
|
|
6648
|
+
* ```
|
|
6649
|
+
*/
|
|
6650
|
+
|
|
6651
|
+
var renderPolygonEventWithFunction = function (renderStyle) {
|
|
6652
|
+
return function (_a) {
|
|
6653
|
+
var ctx = _a.ctx,
|
|
6654
|
+
hoveredItem = _a.hoveredItem,
|
|
6655
|
+
utils = _a.utils,
|
|
6656
|
+
selectedItems = _a.selectedItems,
|
|
6657
|
+
selectedItem = _a.selectedItem;
|
|
6658
|
+
var selectedIdsSet = selectedItems ? new Set(selectedItems.map(function (item) {
|
|
6659
|
+
return item.id;
|
|
6660
|
+
})) : new Set();
|
|
6661
|
+
var hoveredItemId = hoveredItem === null || hoveredItem === void 0 ? void 0 : hoveredItem.id;
|
|
6662
|
+
var selectedItemId = selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id; // 1. 선택된 항목들 그리기 (마지막 선택 항목과 호버된 항목 제외)
|
|
6663
|
+
|
|
6664
|
+
if (selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.length) {
|
|
6665
|
+
for (var _i = 0, selectedItems_2 = selectedItems; _i < selectedItems_2.length; _i++) {
|
|
6666
|
+
var item = selectedItems_2[_i]; // 마지막 선택 항목과 호버된 항목은 나중에 따로 그림
|
|
6667
|
+
|
|
6668
|
+
if (item.id === selectedItemId || item.id === hoveredItemId) continue;
|
|
6669
|
+
if (!item.paths) continue;
|
|
6670
|
+
var polygonOffsets = utils.getOrComputePolygonOffsets(item);
|
|
6671
|
+
if (!polygonOffsets) continue;
|
|
6672
|
+
var context = {
|
|
6673
|
+
isSelected: true,
|
|
6674
|
+
isHovered: false,
|
|
6675
|
+
isActive: false
|
|
6676
|
+
};
|
|
6677
|
+
var style = renderStyle(item, context);
|
|
6678
|
+
drawPolygon({
|
|
6679
|
+
ctx: ctx,
|
|
6680
|
+
polygonOffsets: polygonOffsets,
|
|
6681
|
+
isDonutPolygon: item.isDonutPolygon || false,
|
|
6682
|
+
fillColor: style.fillColor,
|
|
6683
|
+
strokeColor: style.strokeColor,
|
|
6684
|
+
lineWidth: style.lineWidth
|
|
6685
|
+
});
|
|
6686
|
+
}
|
|
6687
|
+
} // 2. 마지막 선택된 항목 그리기 (호버되지 않은 경우)
|
|
6688
|
+
|
|
6689
|
+
|
|
6690
|
+
if ((selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.paths) && hoveredItemId !== selectedItemId) {
|
|
6691
|
+
var polygonOffsets = utils.getOrComputePolygonOffsets(selectedItem);
|
|
6692
|
+
|
|
6693
|
+
if (polygonOffsets) {
|
|
6694
|
+
var context = {
|
|
6695
|
+
isSelected: true,
|
|
6696
|
+
isHovered: false,
|
|
6697
|
+
isActive: true
|
|
6698
|
+
};
|
|
6699
|
+
var style = renderStyle(selectedItem, context);
|
|
6700
|
+
drawPolygon({
|
|
6701
|
+
ctx: ctx,
|
|
6702
|
+
polygonOffsets: polygonOffsets,
|
|
6703
|
+
isDonutPolygon: selectedItem.isDonutPolygon || false,
|
|
6704
|
+
fillColor: style.fillColor,
|
|
6705
|
+
strokeColor: style.strokeColor,
|
|
6706
|
+
lineWidth: style.lineWidth
|
|
6707
|
+
});
|
|
6708
|
+
}
|
|
6709
|
+
} // 3. 호버된 항목 그리기 (가장 위에 표시)
|
|
6710
|
+
|
|
6711
|
+
|
|
6712
|
+
if (hoveredItem === null || hoveredItem === void 0 ? void 0 : hoveredItem.paths) {
|
|
6713
|
+
var polygonOffsets = utils.getOrComputePolygonOffsets(hoveredItem);
|
|
6714
|
+
if (!polygonOffsets) return; // 좌표 변환 실패 시 스킵 (return은 렌더링 함수 종료)
|
|
6715
|
+
// hover된 항목이 선택되어 있는지 확인
|
|
6716
|
+
|
|
6717
|
+
var isSelected = selectedIdsSet.has(hoveredItem.id);
|
|
6718
|
+
var context = {
|
|
6719
|
+
isSelected: isSelected,
|
|
6720
|
+
isHovered: true,
|
|
6721
|
+
isActive: isSelected && hoveredItem.id === selectedItemId
|
|
6722
|
+
};
|
|
6723
|
+
var style = renderStyle(hoveredItem, context);
|
|
6724
|
+
drawPolygon({
|
|
6725
|
+
ctx: ctx,
|
|
6726
|
+
polygonOffsets: polygonOffsets,
|
|
6727
|
+
isDonutPolygon: hoveredItem.isDonutPolygon || false,
|
|
6728
|
+
fillColor: style.fillColor,
|
|
6729
|
+
strokeColor: style.strokeColor,
|
|
6730
|
+
lineWidth: style.lineWidth
|
|
6731
|
+
});
|
|
6732
|
+
}
|
|
6733
|
+
};
|
|
6734
|
+
};
|
|
6554
6735
|
|
|
6555
6736
|
var WoongCanvasPolygon = function (props) {
|
|
6556
6737
|
var data = props.data,
|
|
@@ -6567,23 +6748,16 @@ var WoongCanvasPolygon = function (props) {
|
|
|
6567
6748
|
externalSelectedItem = props.selectedItem,
|
|
6568
6749
|
_e = props.disableInteraction,
|
|
6569
6750
|
disableInteraction = _e === void 0 ? false : _e,
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
activeStrokeColor = props.activeStrokeColor,
|
|
6578
|
-
activeLineWidth = props.activeLineWidth,
|
|
6579
|
-
hoveredFillColor = props.hoveredFillColor,
|
|
6580
|
-
hoveredStrokeColor = props.hoveredStrokeColor,
|
|
6581
|
-
hoveredLineWidth = props.hoveredLineWidth,
|
|
6582
|
-
options = __rest(props, ["data", "onClick", "enableMultiSelect", "enableViewportCulling", "cullingMargin", "maxCacheSize", "selectedItems", "selectedItem", "disableInteraction", "baseFillColor", "baseStrokeColor", "baseLineWidth", "selectedFillColor", "selectedStrokeColor", "selectedLineWidth", "activeFillColor", "activeStrokeColor", "activeLineWidth", "hoveredFillColor", "hoveredStrokeColor", "hoveredLineWidth"]); // --------------------------------------------------------------------------
|
|
6751
|
+
options = __rest(props, ["data", "onClick", "enableMultiSelect", "enableViewportCulling", "cullingMargin", "maxCacheSize", "selectedItems", "selectedItem", "disableInteraction"]); // renderStyle이 있으면 함수 방식, baseFillColor가 있으면 개별 props 방식
|
|
6752
|
+
|
|
6753
|
+
|
|
6754
|
+
var isFunctionMode = 'renderStyle' in props && props.renderStyle !== undefined; // 개별 props 방식일 때만 추출
|
|
6755
|
+
|
|
6756
|
+
var individualProps = isFunctionMode ? undefined : props;
|
|
6757
|
+
var functionProps = isFunctionMode ? props : undefined; // --------------------------------------------------------------------------
|
|
6583
6758
|
// Hooks & Context
|
|
6584
6759
|
// --------------------------------------------------------------------------
|
|
6585
6760
|
|
|
6586
|
-
|
|
6587
6761
|
var controller = useMintMapController();
|
|
6588
6762
|
var context = useWoongCanvasContext();
|
|
6589
6763
|
var currentZIndex = options.zIndex !== undefined ? options.zIndex : 0; // DOM Refs
|
|
@@ -6685,10 +6859,14 @@ var WoongCanvasPolygon = function (props) {
|
|
|
6685
6859
|
getOrComputeMarkerOffset: function () {
|
|
6686
6860
|
return null;
|
|
6687
6861
|
}
|
|
6688
|
-
}; // 렌더링 함수 생성
|
|
6862
|
+
}; // 렌더링 함수 생성 (스타일 지정 방식에 따라 분기)
|
|
6689
6863
|
|
|
6690
|
-
var renderBase = renderPolygonBase(baseFillColor, baseStrokeColor, baseLineWidth)
|
|
6691
|
-
|
|
6864
|
+
var renderBase = isFunctionMode && functionProps ? renderPolygonBaseWithFunction(functionProps.renderStyle) : individualProps ? renderPolygonBase(individualProps.baseFillColor, individualProps.baseStrokeColor, individualProps.baseLineWidth) : function () {
|
|
6865
|
+
throw new Error('Invalid props: either renderStyle or individual style props must be provided');
|
|
6866
|
+
}();
|
|
6867
|
+
var renderEvent = isFunctionMode && functionProps ? renderPolygonEventWithFunction(functionProps.renderStyle) : individualProps ? renderPolygonEvent(individualProps.baseFillColor, individualProps.baseStrokeColor, individualProps.baseLineWidth, individualProps.selectedFillColor, individualProps.selectedStrokeColor, individualProps.selectedLineWidth, individualProps.activeFillColor, individualProps.activeStrokeColor, individualProps.activeLineWidth, individualProps.hoveredFillColor, individualProps.hoveredStrokeColor, individualProps.hoveredLineWidth) : function () {
|
|
6868
|
+
throw new Error('Invalid props: either renderStyle or individual style props must be provided');
|
|
6869
|
+
}(); // Base Layer 렌더링 (뷰포트 컬링 적용)
|
|
6692
6870
|
|
|
6693
6871
|
var doRenderBase = function () {
|
|
6694
6872
|
var layer = baseLayerRef.current;
|
|
@@ -6860,7 +7038,8 @@ var WoongCanvasPolygon = function (props) {
|
|
|
6860
7038
|
}
|
|
6861
7039
|
|
|
6862
7040
|
selectedIdsRef.current = newSelected;
|
|
6863
|
-
}
|
|
7041
|
+
} // Event Layer 업데이트 (선택된 항목 표시)
|
|
7042
|
+
|
|
6864
7043
|
|
|
6865
7044
|
doRenderEvent();
|
|
6866
7045
|
}; // 클릭 이벤트 핸들러
|
package/dist/index.umd.js
CHANGED
|
@@ -6555,6 +6555,187 @@
|
|
|
6555
6555
|
}
|
|
6556
6556
|
};
|
|
6557
6557
|
};
|
|
6558
|
+
/**
|
|
6559
|
+
* 폴리곤 Base 렌더링 함수 팩토리 (함수 방식)
|
|
6560
|
+
*
|
|
6561
|
+
* Base Layer에서 사용할 렌더링 함수를 생성합니다.
|
|
6562
|
+
* renderStyle 함수를 사용하여 각 폴리곤의 상태에 따라 스타일을 동적으로 결정합니다.
|
|
6563
|
+
*
|
|
6564
|
+
* @template T 폴리곤 데이터의 추가 속성 타입
|
|
6565
|
+
* @param renderStyle 폴리곤 스타일 함수
|
|
6566
|
+
* @returns Base Layer 렌더링 함수
|
|
6567
|
+
*
|
|
6568
|
+
* @remarks
|
|
6569
|
+
* - 선택된 항목은 Event Layer에서 그려지므로 Base Layer에서는 스킵
|
|
6570
|
+
* - 성능: O(n), n은 렌더링할 폴리곤 개수
|
|
6571
|
+
* - 좌표 변환은 자동으로 캐싱되어 성능 최적화됨
|
|
6572
|
+
*
|
|
6573
|
+
* @example
|
|
6574
|
+
* ```typescript
|
|
6575
|
+
* const renderBase = renderPolygonBaseWithFunction<MyDataType>(
|
|
6576
|
+
* (item, context) => ({
|
|
6577
|
+
* fillColor: 'rgba(255, 100, 100, 0.5)',
|
|
6578
|
+
* strokeColor: 'rgba(200, 50, 50, 0.8)',
|
|
6579
|
+
* lineWidth: 2
|
|
6580
|
+
* })
|
|
6581
|
+
* );
|
|
6582
|
+
* ```
|
|
6583
|
+
*/
|
|
6584
|
+
|
|
6585
|
+
var renderPolygonBaseWithFunction = function (renderStyle) {
|
|
6586
|
+
return function (_a) {
|
|
6587
|
+
var ctx = _a.ctx,
|
|
6588
|
+
items = _a.items,
|
|
6589
|
+
selectedIds = _a.selectedIds,
|
|
6590
|
+
utils = _a.utils;
|
|
6591
|
+
|
|
6592
|
+
for (var _i = 0, items_2 = items; _i < items_2.length; _i++) {
|
|
6593
|
+
var item = items_2[_i]; // 선택된 항목은 Event Layer에서 그림 (중복 렌더링 방지)
|
|
6594
|
+
|
|
6595
|
+
if (selectedIds.has(item.id)) continue; // paths가 없으면 스킵
|
|
6596
|
+
|
|
6597
|
+
if (!item.paths) continue; // 좌표 변환 (자동 캐싱)
|
|
6598
|
+
|
|
6599
|
+
var polygonOffsets = utils.getOrComputePolygonOffsets(item);
|
|
6600
|
+
if (!polygonOffsets) continue; // 스타일 함수로 스타일 가져오기 (Base Layer는 선택되지 않은 항목만)
|
|
6601
|
+
|
|
6602
|
+
var context = {
|
|
6603
|
+
isSelected: false,
|
|
6604
|
+
isHovered: false,
|
|
6605
|
+
isActive: false
|
|
6606
|
+
};
|
|
6607
|
+
var style = renderStyle(item, context); // 폴리곤 그리기
|
|
6608
|
+
|
|
6609
|
+
drawPolygon({
|
|
6610
|
+
ctx: ctx,
|
|
6611
|
+
polygonOffsets: polygonOffsets,
|
|
6612
|
+
isDonutPolygon: item.isDonutPolygon || false,
|
|
6613
|
+
fillColor: style.fillColor,
|
|
6614
|
+
strokeColor: style.strokeColor,
|
|
6615
|
+
lineWidth: style.lineWidth
|
|
6616
|
+
});
|
|
6617
|
+
}
|
|
6618
|
+
};
|
|
6619
|
+
};
|
|
6620
|
+
/**
|
|
6621
|
+
* 폴리곤 Event 렌더링 함수 팩토리 (함수 방식)
|
|
6622
|
+
*
|
|
6623
|
+
* Event Layer에서 사용할 렌더링 함수를 생성합니다.
|
|
6624
|
+
* renderStyle 함수를 사용하여 각 폴리곤의 상태에 따라 스타일을 동적으로 결정합니다.
|
|
6625
|
+
*
|
|
6626
|
+
* @template T 폴리곤 데이터의 추가 속성 타입
|
|
6627
|
+
* @param renderStyle 폴리곤 스타일 함수
|
|
6628
|
+
* @returns Event Layer 렌더링 함수
|
|
6629
|
+
*
|
|
6630
|
+
* @remarks
|
|
6631
|
+
* - **렌더링 순서**: 선택된 항목 → 마지막 선택된 항목 → hover된 항목 (최상단)
|
|
6632
|
+
* - **성능**: O(m), m은 선택된 항목 수 + hover된 항목 수
|
|
6633
|
+
* - 좌표 변환은 자동으로 캐싱되어 성능 최적화됨
|
|
6634
|
+
* - hover된 항목이 선택되어 있으면 active 스타일 적용
|
|
6635
|
+
*
|
|
6636
|
+
* @example
|
|
6637
|
+
* ```typescript
|
|
6638
|
+
* const renderEvent = renderPolygonEventWithFunction<MyDataType>(
|
|
6639
|
+
* (item, context) => {
|
|
6640
|
+
* if (context.isActive) {
|
|
6641
|
+
* return { fillColor: 'rgba(255, 152, 0, 0.8)', strokeColor: 'rgba(255, 87, 34, 1)', lineWidth: 5 };
|
|
6642
|
+
* }
|
|
6643
|
+
* if (context.isHovered) {
|
|
6644
|
+
* return { fillColor: 'rgba(100, 150, 255, 0.8)', strokeColor: 'rgba(0, 100, 200, 1)', lineWidth: 3 };
|
|
6645
|
+
* }
|
|
6646
|
+
* if (context.isSelected) {
|
|
6647
|
+
* return { fillColor: 'rgba(255, 193, 7, 0.7)', strokeColor: 'rgba(255, 152, 0, 1)', lineWidth: 4 };
|
|
6648
|
+
* }
|
|
6649
|
+
* return { fillColor: 'rgba(255, 100, 100, 0.5)', strokeColor: 'rgba(200, 50, 50, 0.8)', lineWidth: 2 };
|
|
6650
|
+
* }
|
|
6651
|
+
* );
|
|
6652
|
+
* ```
|
|
6653
|
+
*/
|
|
6654
|
+
|
|
6655
|
+
var renderPolygonEventWithFunction = function (renderStyle) {
|
|
6656
|
+
return function (_a) {
|
|
6657
|
+
var ctx = _a.ctx,
|
|
6658
|
+
hoveredItem = _a.hoveredItem,
|
|
6659
|
+
utils = _a.utils,
|
|
6660
|
+
selectedItems = _a.selectedItems,
|
|
6661
|
+
selectedItem = _a.selectedItem;
|
|
6662
|
+
var selectedIdsSet = selectedItems ? new Set(selectedItems.map(function (item) {
|
|
6663
|
+
return item.id;
|
|
6664
|
+
})) : new Set();
|
|
6665
|
+
var hoveredItemId = hoveredItem === null || hoveredItem === void 0 ? void 0 : hoveredItem.id;
|
|
6666
|
+
var selectedItemId = selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id; // 1. 선택된 항목들 그리기 (마지막 선택 항목과 호버된 항목 제외)
|
|
6667
|
+
|
|
6668
|
+
if (selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.length) {
|
|
6669
|
+
for (var _i = 0, selectedItems_2 = selectedItems; _i < selectedItems_2.length; _i++) {
|
|
6670
|
+
var item = selectedItems_2[_i]; // 마지막 선택 항목과 호버된 항목은 나중에 따로 그림
|
|
6671
|
+
|
|
6672
|
+
if (item.id === selectedItemId || item.id === hoveredItemId) continue;
|
|
6673
|
+
if (!item.paths) continue;
|
|
6674
|
+
var polygonOffsets = utils.getOrComputePolygonOffsets(item);
|
|
6675
|
+
if (!polygonOffsets) continue;
|
|
6676
|
+
var context = {
|
|
6677
|
+
isSelected: true,
|
|
6678
|
+
isHovered: false,
|
|
6679
|
+
isActive: false
|
|
6680
|
+
};
|
|
6681
|
+
var style = renderStyle(item, context);
|
|
6682
|
+
drawPolygon({
|
|
6683
|
+
ctx: ctx,
|
|
6684
|
+
polygonOffsets: polygonOffsets,
|
|
6685
|
+
isDonutPolygon: item.isDonutPolygon || false,
|
|
6686
|
+
fillColor: style.fillColor,
|
|
6687
|
+
strokeColor: style.strokeColor,
|
|
6688
|
+
lineWidth: style.lineWidth
|
|
6689
|
+
});
|
|
6690
|
+
}
|
|
6691
|
+
} // 2. 마지막 선택된 항목 그리기 (호버되지 않은 경우)
|
|
6692
|
+
|
|
6693
|
+
|
|
6694
|
+
if ((selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.paths) && hoveredItemId !== selectedItemId) {
|
|
6695
|
+
var polygonOffsets = utils.getOrComputePolygonOffsets(selectedItem);
|
|
6696
|
+
|
|
6697
|
+
if (polygonOffsets) {
|
|
6698
|
+
var context = {
|
|
6699
|
+
isSelected: true,
|
|
6700
|
+
isHovered: false,
|
|
6701
|
+
isActive: true
|
|
6702
|
+
};
|
|
6703
|
+
var style = renderStyle(selectedItem, context);
|
|
6704
|
+
drawPolygon({
|
|
6705
|
+
ctx: ctx,
|
|
6706
|
+
polygonOffsets: polygonOffsets,
|
|
6707
|
+
isDonutPolygon: selectedItem.isDonutPolygon || false,
|
|
6708
|
+
fillColor: style.fillColor,
|
|
6709
|
+
strokeColor: style.strokeColor,
|
|
6710
|
+
lineWidth: style.lineWidth
|
|
6711
|
+
});
|
|
6712
|
+
}
|
|
6713
|
+
} // 3. 호버된 항목 그리기 (가장 위에 표시)
|
|
6714
|
+
|
|
6715
|
+
|
|
6716
|
+
if (hoveredItem === null || hoveredItem === void 0 ? void 0 : hoveredItem.paths) {
|
|
6717
|
+
var polygonOffsets = utils.getOrComputePolygonOffsets(hoveredItem);
|
|
6718
|
+
if (!polygonOffsets) return; // 좌표 변환 실패 시 스킵 (return은 렌더링 함수 종료)
|
|
6719
|
+
// hover된 항목이 선택되어 있는지 확인
|
|
6720
|
+
|
|
6721
|
+
var isSelected = selectedIdsSet.has(hoveredItem.id);
|
|
6722
|
+
var context = {
|
|
6723
|
+
isSelected: isSelected,
|
|
6724
|
+
isHovered: true,
|
|
6725
|
+
isActive: isSelected && hoveredItem.id === selectedItemId
|
|
6726
|
+
};
|
|
6727
|
+
var style = renderStyle(hoveredItem, context);
|
|
6728
|
+
drawPolygon({
|
|
6729
|
+
ctx: ctx,
|
|
6730
|
+
polygonOffsets: polygonOffsets,
|
|
6731
|
+
isDonutPolygon: hoveredItem.isDonutPolygon || false,
|
|
6732
|
+
fillColor: style.fillColor,
|
|
6733
|
+
strokeColor: style.strokeColor,
|
|
6734
|
+
lineWidth: style.lineWidth
|
|
6735
|
+
});
|
|
6736
|
+
}
|
|
6737
|
+
};
|
|
6738
|
+
};
|
|
6558
6739
|
|
|
6559
6740
|
var WoongCanvasPolygon = function (props) {
|
|
6560
6741
|
var data = props.data,
|
|
@@ -6571,23 +6752,16 @@
|
|
|
6571
6752
|
externalSelectedItem = props.selectedItem,
|
|
6572
6753
|
_e = props.disableInteraction,
|
|
6573
6754
|
disableInteraction = _e === void 0 ? false : _e,
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
6581
|
-
activeStrokeColor = props.activeStrokeColor,
|
|
6582
|
-
activeLineWidth = props.activeLineWidth,
|
|
6583
|
-
hoveredFillColor = props.hoveredFillColor,
|
|
6584
|
-
hoveredStrokeColor = props.hoveredStrokeColor,
|
|
6585
|
-
hoveredLineWidth = props.hoveredLineWidth,
|
|
6586
|
-
options = tslib.__rest(props, ["data", "onClick", "enableMultiSelect", "enableViewportCulling", "cullingMargin", "maxCacheSize", "selectedItems", "selectedItem", "disableInteraction", "baseFillColor", "baseStrokeColor", "baseLineWidth", "selectedFillColor", "selectedStrokeColor", "selectedLineWidth", "activeFillColor", "activeStrokeColor", "activeLineWidth", "hoveredFillColor", "hoveredStrokeColor", "hoveredLineWidth"]); // --------------------------------------------------------------------------
|
|
6755
|
+
options = tslib.__rest(props, ["data", "onClick", "enableMultiSelect", "enableViewportCulling", "cullingMargin", "maxCacheSize", "selectedItems", "selectedItem", "disableInteraction"]); // renderStyle이 있으면 함수 방식, baseFillColor가 있으면 개별 props 방식
|
|
6756
|
+
|
|
6757
|
+
|
|
6758
|
+
var isFunctionMode = 'renderStyle' in props && props.renderStyle !== undefined; // 개별 props 방식일 때만 추출
|
|
6759
|
+
|
|
6760
|
+
var individualProps = isFunctionMode ? undefined : props;
|
|
6761
|
+
var functionProps = isFunctionMode ? props : undefined; // --------------------------------------------------------------------------
|
|
6587
6762
|
// Hooks & Context
|
|
6588
6763
|
// --------------------------------------------------------------------------
|
|
6589
6764
|
|
|
6590
|
-
|
|
6591
6765
|
var controller = useMintMapController();
|
|
6592
6766
|
var context = useWoongCanvasContext();
|
|
6593
6767
|
var currentZIndex = options.zIndex !== undefined ? options.zIndex : 0; // DOM Refs
|
|
@@ -6689,10 +6863,14 @@
|
|
|
6689
6863
|
getOrComputeMarkerOffset: function () {
|
|
6690
6864
|
return null;
|
|
6691
6865
|
}
|
|
6692
|
-
}; // 렌더링 함수 생성
|
|
6866
|
+
}; // 렌더링 함수 생성 (스타일 지정 방식에 따라 분기)
|
|
6693
6867
|
|
|
6694
|
-
var renderBase = renderPolygonBase(baseFillColor, baseStrokeColor, baseLineWidth)
|
|
6695
|
-
|
|
6868
|
+
var renderBase = isFunctionMode && functionProps ? renderPolygonBaseWithFunction(functionProps.renderStyle) : individualProps ? renderPolygonBase(individualProps.baseFillColor, individualProps.baseStrokeColor, individualProps.baseLineWidth) : function () {
|
|
6869
|
+
throw new Error('Invalid props: either renderStyle or individual style props must be provided');
|
|
6870
|
+
}();
|
|
6871
|
+
var renderEvent = isFunctionMode && functionProps ? renderPolygonEventWithFunction(functionProps.renderStyle) : individualProps ? renderPolygonEvent(individualProps.baseFillColor, individualProps.baseStrokeColor, individualProps.baseLineWidth, individualProps.selectedFillColor, individualProps.selectedStrokeColor, individualProps.selectedLineWidth, individualProps.activeFillColor, individualProps.activeStrokeColor, individualProps.activeLineWidth, individualProps.hoveredFillColor, individualProps.hoveredStrokeColor, individualProps.hoveredLineWidth) : function () {
|
|
6872
|
+
throw new Error('Invalid props: either renderStyle or individual style props must be provided');
|
|
6873
|
+
}(); // Base Layer 렌더링 (뷰포트 컬링 적용)
|
|
6696
6874
|
|
|
6697
6875
|
var doRenderBase = function () {
|
|
6698
6876
|
var layer = baseLayerRef.current;
|
|
@@ -6864,7 +7042,8 @@
|
|
|
6864
7042
|
}
|
|
6865
7043
|
|
|
6866
7044
|
selectedIdsRef.current = newSelected;
|
|
6867
|
-
}
|
|
7045
|
+
} // Event Layer 업데이트 (선택된 항목 표시)
|
|
7046
|
+
|
|
6868
7047
|
|
|
6869
7048
|
doRenderEvent();
|
|
6870
7049
|
}; // 클릭 이벤트 핸들러
|