open-plant 1.3.7 → 1.4.0
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/CHANGELOG.md +22 -0
- package/README.md +35 -30
- package/dist/index.cjs +9 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3425 -2700
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +23 -8
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/react/draw-layer-stamp.d.ts +9 -2
- package/dist/types/react/draw-layer-stamp.d.ts.map +1 -1
- package/dist/types/react/draw-layer-types.d.ts +9 -1
- package/dist/types/react/draw-layer-types.d.ts.map +1 -1
- package/dist/types/react/draw-layer.d.ts +1 -1
- package/dist/types/react/draw-layer.d.ts.map +1 -1
- package/dist/types/react/drawing-layer.d.ts +13 -0
- package/dist/types/react/drawing-layer.d.ts.map +1 -0
- package/dist/types/react/overlay-layer.d.ts +6 -0
- package/dist/types/react/overlay-layer.d.ts.map +1 -0
- package/dist/types/react/overview-map.d.ts +1 -1
- package/dist/types/react/overview-map.d.ts.map +1 -1
- package/dist/types/react/patch-layer.d.ts +8 -0
- package/dist/types/react/patch-layer.d.ts.map +1 -0
- package/dist/types/react/point-layer.d.ts +23 -0
- package/dist/types/react/point-layer.d.ts.map +1 -0
- package/dist/types/react/region-layer.d.ts +21 -0
- package/dist/types/react/region-layer.d.ts.map +1 -0
- package/dist/types/react/use-point-clipping.d.ts +5 -0
- package/dist/types/react/use-point-clipping.d.ts.map +1 -0
- package/dist/types/react/use-point-hit-test.d.ts +12 -0
- package/dist/types/react/use-point-hit-test.d.ts.map +1 -0
- package/dist/types/react/use-region-label-auto-lift.d.ts +10 -0
- package/dist/types/react/use-region-label-auto-lift.d.ts.map +1 -0
- package/dist/types/react/use-renderer-sync.d.ts +23 -0
- package/dist/types/react/use-renderer-sync.d.ts.map +1 -0
- package/dist/types/react/viewer-context.d.ts +23 -0
- package/dist/types/react/viewer-context.d.ts.map +1 -0
- package/dist/types/react/wsi-viewer-canvas-types.d.ts +143 -0
- package/dist/types/react/wsi-viewer-canvas-types.d.ts.map +1 -0
- package/dist/types/react/wsi-viewer-canvas.d.ts +3 -137
- package/dist/types/react/wsi-viewer-canvas.d.ts.map +1 -1
- package/dist/types/react/wsi-viewer.d.ts +32 -0
- package/dist/types/react/wsi-viewer.d.ts.map +1 -0
- package/dist/types/wsi/wsi-input-handlers.d.ts +5 -2
- package/dist/types/wsi/wsi-input-handlers.d.ts.map +1 -1
- package/dist/types/wsi/wsi-interaction.d.ts +8 -1
- package/dist/types/wsi/wsi-interaction.d.ts.map +1 -1
- package/dist/types/wsi/wsi-renderer-types.d.ts +6 -0
- package/dist/types/wsi/wsi-renderer-types.d.ts.map +1 -1
- package/dist/types/wsi/wsi-tile-renderer.d.ts +10 -1
- package/dist/types/wsi/wsi-tile-renderer.d.ts.map +1 -1
- package/dist/types/wsi/wsi-view-ops.d.ts +1 -0
- package/dist/types/wsi/wsi-view-ops.d.ts.map +1 -1
- package/dist/types/wsi/wsi-zoom-snap.d.ts +24 -0
- package/dist/types/wsi/wsi-zoom-snap.d.ts.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,25 +7,47 @@ and this project follows [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.4.0] - 2026-03-16
|
|
11
|
+
|
|
10
12
|
### Added
|
|
13
|
+
- **선언적 레이어 컴포지션 API**: `WsiViewer` + 자식 레이어 컴포넌트로 관심사 분리.
|
|
14
|
+
- `WsiViewer`: Context Provider + WebGL 캔버스 관리 (~15개 core props).
|
|
15
|
+
- `PointLayer`: 포인트 렌더링, 클리핑, 히트 테스트 캡슐화.
|
|
16
|
+
- `RegionLayer`: ROI 리전 렌더링, 라벨, hover/active 상태 관리.
|
|
17
|
+
- `DrawingLayer`: 드로잉 도구 (freehand, rectangle, circular, stamp, brush).
|
|
18
|
+
- `PatchLayer`: 패치 리전 렌더링.
|
|
19
|
+
- `OverlayLayer`: 오버레이 셰이프 렌더링.
|
|
20
|
+
- `ViewerContext` + `useViewerContext()`: 레이어 간 `rendererRef`, 좌표 변환, draw registry 공유.
|
|
21
|
+
- `PointQueryHandle` + `forwardRef` 패턴: `getCellByCoordinatesRef`를 대체하는 `PointLayer` imperative handle.
|
|
22
|
+
- `DrawTool` 타입 확장: `"eraser"`, `"region-brush"`, `"region-eraser"` 문자열 리터럴 추가.
|
|
23
|
+
- `StampToolConfig` 구조화 타입: `{ stamp: { shape: "circle", areaMm2: 0.2 } }` — 매직 스트링 대체.
|
|
24
|
+
- `StampShape` 타입: `"rectangle" | "circle"`.
|
|
25
|
+
- `RegionLayerProps.labelStyle`: `Partial<RegionLabelStyle> | RegionLabelStyleResolver` 통합 prop.
|
|
11
26
|
- Web Worker 기반 포인트 공간 인덱스 빌드 (`point-hit-index-worker`). 메인 스레드 ~175ms 블로킹 제거.
|
|
12
27
|
- `FlatPointSpatialIndex` flat typed array 자료구조 + open-addressing hash table lookup.
|
|
13
28
|
- `buildPointSpatialIndexAsync()`, `lookupCellIndex()`, `terminatePointHitIndexWorker()` public API.
|
|
14
29
|
- 인접 tier (T±1) 타일 prefetch: 빠른 줌 시 blank frame 감소.
|
|
15
30
|
- `getVisibleTilesForTier(tier)` public method on `WsiTileRenderer`.
|
|
31
|
+
- 배율 스냅 줌 API: `zoomSnaps`, `zoomSnapFitAsMin` (`WsiViewerCanvas`/`WsiTileRenderer`).
|
|
32
|
+
- `WsiTileRenderer.getViewBounds()` public method.
|
|
16
33
|
- 최적화 리포트: `perf-optimization-report.md`.
|
|
17
34
|
|
|
18
35
|
### Changed
|
|
36
|
+
- `WsiViewerCanvasProps`에 `@deprecated` JSDoc 추가. 기존 인터페이스는 동일하게 유지.
|
|
19
37
|
- `pointHitIndex` 빌드가 `useMemo` (동기) → `useEffect` + `useState` (비동기 워커)로 전환.
|
|
20
38
|
- 워커 인덱스 알고리즘: nested `Map` → 4-pass counting sort (GC-free, typed arrays only).
|
|
21
39
|
- 워커 프로토콜: positions/ids를 워커가 반환하지 않음 — 메인 스레드가 원본 참조 (전송량 ~120MB → ~48MB).
|
|
22
40
|
- `getCellByCoordinates` 내부 lookup: nested `Map.get()` → `Int32Array` hash table O(1).
|
|
23
41
|
- 타일 스케줄링: 현재 tier 외 인접 tier 타일을 `distance2` 페널티 기반 낮은 우선순위로 포함.
|
|
24
42
|
- 내부 perf logging (`logPerf`, `shouldLogPerf`, `PERF_LOG_*`) 제거.
|
|
43
|
+
- Overview map viewport 인디케이터 렌더 경로 개선: `getViewBounds`가 없어도 `getViewCorners`만으로 현재 뷰포트 표시 가능.
|
|
44
|
+
- Overview map 기본 viewport border 색상을 고대비 주황 계열로 조정.
|
|
25
45
|
|
|
26
46
|
### Docs
|
|
27
47
|
- `performance-optimization.md` 업데이트: 워커 인덱스, prefetch, flat hash 내용 추가.
|
|
28
48
|
- `README.md` 프로젝트 구조: 워커/클라이언트 파일 반영.
|
|
49
|
+
- `README.md` API/props 섹션을 현재 export/동작 기준으로 정리(중복 제거 포함).
|
|
50
|
+
- EN/KO API reference와 Getting Started에 `zoomSnaps`, `zoomSnapFitAsMin`, `pointInnerFillOpacity`, `regionLabelAnchor`, `clampRegionLabelToViewport` 반영.
|
|
29
51
|
|
|
30
52
|
## [1.2.4] - 2026-02-25
|
|
31
53
|
|
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<a href="https://github.com/frorong/open-plant">GitHub</a>
|
|
15
15
|
</p>
|
|
16
16
|
|
|
17
|
-
> Engine
|
|
17
|
+
> Engine process note: [`engine-build-process.md`](./engine-build-process.md)
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
@@ -76,8 +76,10 @@ draw mode에 진입하면 `setPointerCapture`로 입력을 독점해 팬(드래
|
|
|
76
76
|
| **타일 전용 색상 보정** | `imageColorSettings`로 brightness/contrast/saturation 실시간 반영 (cell/ROI/draw overlay는 영향 없음) |
|
|
77
77
|
| **회전 인터랙션** | `WsiViewState.rotationDeg`, `Ctrl/Cmd + drag` 회전, `resetRotation` 경로 |
|
|
78
78
|
| **줌 범위 제어 + 전환 애니메이션** | `minZoom`/`maxZoom` clamp + `viewTransition`(duration/easing) |
|
|
79
|
+
| **배율 스냅 줌** | `zoomSnaps`, `zoomSnapFitAsMin`으로 wheel/더블클릭을 표준 배율 단계에 맞춰 이동 |
|
|
79
80
|
| **포인트 오버레이** | WebGL2 `gl.POINTS`로 수십, 수백만 개 포인트를 팔레트 텍스처 기반 컬러링. 파싱된 TypedArray만 입력 |
|
|
80
81
|
| **포인트 크기 커스터마이즈** | `pointSizeByZoom` 객체로 zoom별 셀(px) 크기 지정 + 내부 선형 보간 |
|
|
82
|
+
| **포인트 내부 채움 제어** | `pointInnerFillOpacity`로 ring 내부 채움 강도 제어 |
|
|
81
83
|
| **포인트 렌더 모드 제어** | `pointData.fillModes`로 ring/solid 렌더링 제어 |
|
|
82
84
|
| **모바일 타겟 성능** | iPhone 15급 환경에서 수백만 cell 워크로드를 전제로 pan/zoom 응답성을 유지하도록 설계 |
|
|
83
85
|
| **드로잉 / ROI 도구** | Freehand · Rectangle · Circular · Brush + Stamp(사각형/원, mm² 지정) |
|
|
@@ -150,6 +152,8 @@ import { WsiViewerCanvas } from "open-plant";
|
|
|
150
152
|
minZoom={0.25} // 미지정 시 fitZoom * 0.5
|
|
151
153
|
maxZoom={1} // 미지정 시 fitZoom * 8
|
|
152
154
|
viewTransition={{ duration: 300 }}
|
|
155
|
+
zoomSnaps={[1.25, 2.5, 5, 10, 20, 40]}
|
|
156
|
+
zoomSnapFitAsMin
|
|
153
157
|
authToken={bearerToken}
|
|
154
158
|
pointData={pointPayload}
|
|
155
159
|
pointPalette={termPalette.colors}
|
|
@@ -159,6 +163,7 @@ import { WsiViewerCanvas } from "open-plant";
|
|
|
159
163
|
10: 17.5,
|
|
160
164
|
12: 28,
|
|
161
165
|
}}
|
|
166
|
+
pointInnerFillOpacity={0.15}
|
|
162
167
|
clipPointsToRois
|
|
163
168
|
clipMode="worker"
|
|
164
169
|
onClipStats={(s) => console.log(s.mode, s.durationMs)}
|
|
@@ -206,6 +211,14 @@ import { WsiViewerCanvas } from "open-plant";
|
|
|
206
211
|
// stamp-rectangle-4096px 전용
|
|
207
212
|
handlePatch(patch);
|
|
208
213
|
}}
|
|
214
|
+
overviewMapConfig={{
|
|
215
|
+
show: true,
|
|
216
|
+
options: {
|
|
217
|
+
viewportBorderStyle: "dash",
|
|
218
|
+
viewportBorderColor: "rgba(255, 106, 61, 0.95)",
|
|
219
|
+
viewportFillColor: "rgba(255, 106, 61, 0.08)",
|
|
220
|
+
},
|
|
221
|
+
}}
|
|
209
222
|
onViewStateChange={handleViewChange}
|
|
210
223
|
onStats={setStats}
|
|
211
224
|
/>
|
|
@@ -219,6 +232,8 @@ import { WsiViewerCanvas } from "open-plant";
|
|
|
219
232
|
- `activeRegionId`를 주면 controlled mode, 생략하면 uncontrolled mode로 동작합니다.
|
|
220
233
|
- `minZoom`/`maxZoom`은 휠/더블클릭/`setViewState`/`fitToImage` 전 경로에 동일 clamp가 적용됩니다.
|
|
221
234
|
- `viewTransition`은 `setViewState`/`fitToImage`/`zoomBy` 전환에 적용되며 `duration` 최대값은 `2000ms`입니다.
|
|
235
|
+
- `zoomSnaps`는 배율(magnification) 배열 입력이며 `source.mpp`를 기준으로 내부 zoom 값으로 정규화됩니다.
|
|
236
|
+
- `zoomSnapFitAsMin=true`이면 snap-out 경로에서 fit zoom을 하한으로 취급합니다.
|
|
222
237
|
- `drawFillColor` 기본값은 `transparent`입니다.
|
|
223
238
|
- `brushOptions.radius`는 HTML/CSS px 기준이며, 줌이 바뀌어도 on-screen 크기는 고정됩니다.
|
|
224
239
|
- `brushOptions.clickSelectRoi=true`이면 브러시 탭(드래그 없음) 시 ROI를 먼저 선택하고, ROI 외부 탭은 일반 브러시 결과를 반환합니다.
|
|
@@ -226,7 +241,7 @@ import { WsiViewerCanvas } from "open-plant";
|
|
|
226
241
|
- `drawAreaTooltip.enabled=true`이면 freehand/rectangle/circular 그리기 중 커서 근처에 실시간 면적(mm²)을 표시합니다.
|
|
227
242
|
- `roiRegions[].coordinates`는 ring / polygon(with holes) / multipolygon을 모두 지원합니다.
|
|
228
243
|
|
|
229
|
-
#### WsiViewerCanvas Props
|
|
244
|
+
#### WsiViewerCanvas Props by concern
|
|
230
245
|
|
|
231
246
|
**View / Camera**
|
|
232
247
|
|
|
@@ -240,6 +255,8 @@ import { WsiViewerCanvas } from "open-plant";
|
|
|
240
255
|
| `ctrlDragRotate` | `boolean` | 기본 `true` |
|
|
241
256
|
| `minZoom` / `maxZoom` | `number` | 미지정 시 `fitZoom*0.5` / `fitZoom*8` |
|
|
242
257
|
| `viewTransition` | `{ duration?: number; easing?: (t)=>number }` | 기본 즉시 반영(duration 0) |
|
|
258
|
+
| `zoomSnaps` | `number[]` | 확대 배율 스냅 목록(배율 단위) |
|
|
259
|
+
| `zoomSnapFitAsMin` | `boolean` | 스냅 아웃 시 fit zoom을 하한으로 취급할지 여부 |
|
|
243
260
|
| `authToken` | `string` | 타일/포인트 요청 인증 |
|
|
244
261
|
| `overviewMapConfig` | `OverviewMapConfig` | 미니맵 표시/옵션 |
|
|
245
262
|
|
|
@@ -252,6 +269,7 @@ import { WsiViewerCanvas } from "open-plant";
|
|
|
252
269
|
| `pointPalette` | `Uint8Array \| null` | RGBA 팔레트 텍스처 |
|
|
253
270
|
| `pointSizeByZoom` | `Record<number, number>` | continuous zoom stop |
|
|
254
271
|
| `pointStrokeScale` | `number` | point ring 두께 스케일 |
|
|
272
|
+
| `pointInnerFillOpacity` | `number` | 포인트 내부 채움 불투명도 (`0..1`) |
|
|
255
273
|
| `clipPointsToRois` | `boolean` | ROI 외부 포인트 필터 |
|
|
256
274
|
| `clipMode` | `"sync" \| "worker" \| "hybrid-webgpu"` | 기본 `"worker"` |
|
|
257
275
|
| `onClipStats` | `(event) => void` | clip 실행 통계 |
|
|
@@ -273,8 +291,10 @@ import { WsiViewerCanvas } from "open-plant";
|
|
|
273
291
|
| `patchStrokeStyle` | `Partial<RegionStrokeStyle>` | patch 선 스타일 |
|
|
274
292
|
| `resolveRegionStrokeStyle` | `RegionStrokeStyleResolver` | 상태별 동적 stroke |
|
|
275
293
|
| `regionLabelStyle` | `Partial<RegionLabelStyle>` | 기본 배지 스타일 override |
|
|
294
|
+
| `regionLabelAnchor` | `RegionLabelAnchorMode` | 라벨 anchor 모드 (`top-center`, `centroid`) |
|
|
276
295
|
| `resolveRegionLabelStyle` | `RegionLabelStyleResolver` | 줌/region별 동적 라벨 스타일 |
|
|
277
296
|
| `autoLiftRegionLabelAtMaxZoom` | `boolean` | max zoom 도달 시 라벨 auto-lift |
|
|
297
|
+
| `clampRegionLabelToViewport` | `boolean` | 라벨 화면 경계 clamp 적용 |
|
|
278
298
|
| `drawAreaTooltip` | `DrawAreaTooltipOptions` | draw 중 실시간 mm² tooltip |
|
|
279
299
|
| `overlayShapes` | `DrawOverlayShape[]` | 커스텀 도형/반전 마스크 |
|
|
280
300
|
| `customLayers` | `WsiCustomLayer[]` | host React 오버레이 슬롯 |
|
|
@@ -308,14 +328,25 @@ import { WsiViewerCanvas } from "open-plant";
|
|
|
308
328
|
|
|
309
329
|
현재 뷰포트를 표시하는 인터랙티브 미니맵입니다. `overviewMapConfig.show`를 `true`로 설정하면 `WsiViewerCanvas`에 함께 렌더링됩니다.
|
|
310
330
|
|
|
331
|
+
| Option | Type | Notes |
|
|
332
|
+
|---|---|---|
|
|
333
|
+
| `width` / `height` | `number` | 미니맵 캔버스 크기 |
|
|
334
|
+
| `margin`, `position`, `borderRadius` | `number`, enum | 배치/모서리 |
|
|
335
|
+
| `backgroundColor`, `borderColor` | `string` | 배경/테두리 색 |
|
|
336
|
+
| `viewportBorderStyle` | `"stroke" \| "dash"` | 현재 뷰포트 선 스타일 |
|
|
337
|
+
| `viewportBorderColor`, `viewportFillColor` | `string` | 현재 뷰포트 선/채움 |
|
|
338
|
+
| `interactive` | `boolean` | 클릭/드래그로 recenter |
|
|
339
|
+
| `showThumbnail`, `maxThumbnailTiles` | `boolean`, `number` | 썸네일 렌더링 제어 |
|
|
340
|
+
| `onClose`, `closeIcon`, `closeButtonStyle` | callback / `ReactNode` / `CSSProperties` | 닫기 버튼 UI 옵션 |
|
|
341
|
+
|
|
311
342
|
## API
|
|
312
343
|
|
|
313
344
|
| Export | 설명 |
|
|
314
345
|
|---|---|
|
|
315
346
|
| `WsiViewerCanvas`, `DrawLayer`, `OverviewMap`, `TileViewerCanvas` | React 컴포넌트 |
|
|
316
347
|
| `WsiTileRenderer`, `M1TileRenderer`, `TileScheduler` | 렌더러/스케줄러 클래스 |
|
|
317
|
-
| `normalizeImageInfo`, `toTileUrl` |
|
|
318
|
-
| `buildTermPalette`, `calcScaleResolution`, `calcScaleLength`, `toBearerToken` | 공통 유틸 |
|
|
348
|
+
| `normalizeImageInfo`, `toTileUrl`, `toRoiGeometry`, `parseWkt` | 이미지/좌표 유틸 |
|
|
349
|
+
| `buildTermPalette`, `calcScaleResolution`, `calcScaleLength`, `toBearerToken`, `clamp` | 공통 유틸 |
|
|
319
350
|
| `filterPointDataByPolygons`, `filterPointDataByPolygonsInWorker`, `filterPointDataByPolygonsHybrid` | ROI 포인트 클리핑 |
|
|
320
351
|
| `filterPointIndicesByPolygons`, `filterPointIndicesByPolygonsInWorker`, `terminateRoiClipWorker` | 인덱스 기반 클리핑/워커 관리 |
|
|
321
352
|
| `buildPointSpatialIndexAsync`, `lookupCellIndex`, `terminatePointHitIndexWorker` | 포인트 공간 인덱스 (워커) |
|
|
@@ -324,32 +355,6 @@ import { WsiViewerCanvas } from "open-plant";
|
|
|
324
355
|
| `closeRing`, `createRectangle`, `createCircle` | 도형 유틸 |
|
|
325
356
|
| 타입 export (`WsiViewerCanvasProps`, `WsiImageSource`, `WsiPointData`, `WsiViewTransitionOptions` 등) | TypeScript 통합용 공개 타입 |
|
|
326
357
|
|
|
327
|
-
### `<DrawLayer>`
|
|
328
|
-
|
|
329
|
-
Freehand, Rectangle, Circular + Stamp(사각형/원) 드로잉 오버레이.
|
|
330
|
-
|
|
331
|
-
### `<OverviewMap>`
|
|
332
|
-
|
|
333
|
-
현재 뷰포트를 표시하는 인터랙티브 미니맵.
|
|
334
|
-
|
|
335
|
-
## API
|
|
336
|
-
|
|
337
|
-
| Export | 설명 |
|
|
338
|
-
|---|---|
|
|
339
|
-
| `WsiTileRenderer` | WebGL2 WSI 타일 + 포인트 렌더러 클래스 |
|
|
340
|
-
| `M1TileRenderer` | 기본 타일 렌더러 클래스 |
|
|
341
|
-
| `normalizeImageInfo(raw, tileBaseUrl)` | API 응답 + 타일 베이스 URL을 `WsiImageSource`로 변환 |
|
|
342
|
-
| `filterPointDataByPolygons()` | ROI 폴리곤으로 포인트 필터링 |
|
|
343
|
-
| `filterPointDataByPolygonsInWorker()` | 워커 스레드 ROI 필터링 |
|
|
344
|
-
| `filterPointIndicesByPolygons()` | 폴리곤 내부 원본 포인트 인덱스 추출(패치 JSON export용) |
|
|
345
|
-
| `filterPointIndicesByPolygonsInWorker()` | 포인트 인덱스 추출 워커 버전 |
|
|
346
|
-
| `filterPointDataByPolygonsHybrid()` | WebGPU bbox prefilter + polygon 정밀 판정(실험) |
|
|
347
|
-
| `getWebGpuCapabilities()` | WebGPU 지원/어댑터 정보 조회 |
|
|
348
|
-
| `buildTermPalette()` | Term 기반 컬러 팔레트 생성 |
|
|
349
|
-
| `toTileUrl()` | 타일 URL 생성 |
|
|
350
|
-
| `calcScaleResolution()` | 현재 줌 기준 μm/px 계산 |
|
|
351
|
-
| `calcScaleLength()` | 100px 스케일 라벨 문자열 생성 |
|
|
352
|
-
|
|
353
358
|
## Scripts
|
|
354
359
|
|
|
355
360
|
```bash
|