@jax-data-science/sci-image-visualizer 0.3.1 → 0.3.2
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/esm2022/lib/models/region.mjs +57 -1
- package/esm2022/lib/store/region-store.service.mjs +8 -2
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +63 -1
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
- package/lib/models/region.d.ts +20 -0
- package/package.json +1 -1
|
@@ -1002,6 +1002,62 @@ class MultiPolygon {
|
|
|
1002
1002
|
this.polygons = [];
|
|
1003
1003
|
}
|
|
1004
1004
|
}
|
|
1005
|
+
/**
|
|
1006
|
+
* Rebuild a plain-object `bounds` as the class instance the renderers expect
|
|
1007
|
+
* (jit-ui#124).
|
|
1008
|
+
*
|
|
1009
|
+
* Regions that arrive as JSON — a host's server response, a `structuredClone`,
|
|
1010
|
+
* anything that has been through `JSON.parse` — carry a `bounds` that has the
|
|
1011
|
+
* right *fields* but not the right *prototype*. The renderers disagree about
|
|
1012
|
+
* whether that is acceptable: `Region.getShape()` (Plotly) and the napari
|
|
1013
|
+
* overlay duck-type the bounds, while the OpenSeadragon overlay discriminates
|
|
1014
|
+
* with `bounds instanceof Rectangle`. So a JSON region drew in Heatmap mode and
|
|
1015
|
+
* silently vanished in Image mode. `instanceof` also gates the store's own
|
|
1016
|
+
* geometry de-duplication, `moveRegion`, and the GeoJSON export — a JSON region
|
|
1017
|
+
* is undraggable and absent from a save in *every* mode.
|
|
1018
|
+
*
|
|
1019
|
+
* Rather than duck-type ~20 call sites, the store normalizes here on the way in,
|
|
1020
|
+
* so everything downstream can keep relying on `instanceof`. Values that are
|
|
1021
|
+
* already instances are returned **by reference**, untouched: overlays and tools
|
|
1022
|
+
* hold onto the bounds they created and mutate them in place during a drag.
|
|
1023
|
+
*/
|
|
1024
|
+
function hydrateBounds(bounds) {
|
|
1025
|
+
if (!bounds ||
|
|
1026
|
+
bounds instanceof Rectangle ||
|
|
1027
|
+
bounds instanceof Polygon ||
|
|
1028
|
+
bounds instanceof MultiPolygon) {
|
|
1029
|
+
return bounds;
|
|
1030
|
+
}
|
|
1031
|
+
if (Array.isArray(bounds.polygons)) {
|
|
1032
|
+
const multi = new MultiPolygon();
|
|
1033
|
+
multi.polygons = bounds.polygons.map((part) => hydratePolygon(part));
|
|
1034
|
+
return multi;
|
|
1035
|
+
}
|
|
1036
|
+
if ('npoints' in bounds || 'xpoints' in bounds) {
|
|
1037
|
+
return hydratePolygon(bounds);
|
|
1038
|
+
}
|
|
1039
|
+
if ('width' in bounds && 'height' in bounds) {
|
|
1040
|
+
return Object.assign(new Rectangle(), bounds);
|
|
1041
|
+
}
|
|
1042
|
+
// Nothing recognisable — hand it back rather than coerce it into the wrong
|
|
1043
|
+
// geometry. It renders nowhere either way, but a caller can still inspect it.
|
|
1044
|
+
return bounds;
|
|
1045
|
+
}
|
|
1046
|
+
/** {@link hydrateBounds} for one polygon, deriving the fields a lean serializer
|
|
1047
|
+
* omits: JIT's Java `PolygonSerializer` writes only `npoints`/`xpoints`/
|
|
1048
|
+
* `ypoints`, while the GeoJSON export reads `coordinates` and the overlays read
|
|
1049
|
+
* `closed`. */
|
|
1050
|
+
function hydratePolygon(raw) {
|
|
1051
|
+
if (raw instanceof Polygon)
|
|
1052
|
+
return raw;
|
|
1053
|
+
const polygon = Object.assign(new Polygon(), raw);
|
|
1054
|
+
polygon.xpoints = [...(raw.xpoints ?? [])];
|
|
1055
|
+
polygon.ypoints = [...(raw.ypoints ?? [])];
|
|
1056
|
+
polygon.npoints = raw.npoints ?? polygon.xpoints.length;
|
|
1057
|
+
polygon.coordinates = raw.coordinates ?? polygon.xpoints.map((x, i) => [x, polygon.ypoints[i]]);
|
|
1058
|
+
polygon.closed = raw.closed ?? true;
|
|
1059
|
+
return polygon;
|
|
1060
|
+
}
|
|
1005
1061
|
|
|
1006
1062
|
/**
|
|
1007
1063
|
* Preset annotation classes (jit-ui#70).
|
|
@@ -10359,6 +10415,10 @@ class RegionStore {
|
|
|
10359
10415
|
region.id = this.nextId++;
|
|
10360
10416
|
if (region.name == null)
|
|
10361
10417
|
region.name = `shape${region.id}`;
|
|
10418
|
+
// JSON in, class instances out — everything downstream (the overlays'
|
|
10419
|
+
// rendering, geometry de-dup, moveRegion, GeoJSON export) discriminates
|
|
10420
|
+
// the bounds with `instanceof` (jit-ui#124).
|
|
10421
|
+
region.bounds = hydrateBounds(region.bounds);
|
|
10362
10422
|
}
|
|
10363
10423
|
this.applyClassificationColors(regions);
|
|
10364
10424
|
this.isRegionSavedOn = isRegionSaveOn;
|
|
@@ -10511,6 +10571,7 @@ class RegionStore {
|
|
|
10511
10571
|
if (region.name == null)
|
|
10512
10572
|
region.name = `shape${region.id}`;
|
|
10513
10573
|
region.z = z;
|
|
10574
|
+
region.bounds = hydrateBounds(region.bounds); // jit-ui#124
|
|
10514
10575
|
}
|
|
10515
10576
|
this.applyClassificationColors(regions);
|
|
10516
10577
|
return regions.slice();
|
|
@@ -10762,6 +10823,7 @@ class RegionStore {
|
|
|
10762
10823
|
region.id = this.nextId++;
|
|
10763
10824
|
if (region.name == null)
|
|
10764
10825
|
region.name = `shape${region.id}`;
|
|
10826
|
+
region.bounds = hydrateBounds(region.bounds); // jit-ui#124
|
|
10765
10827
|
// A region drawn on a stack belongs to the slice currently displayed, so
|
|
10766
10828
|
// it saves/reloads on that slice (jit-ui#93). No-op for single-plane images
|
|
10767
10829
|
// (currentSliceZ stays 0).
|
|
@@ -22098,5 +22160,5 @@ function provideVisualization() {
|
|
|
22098
22160
|
* Generated bundle index. Do not edit.
|
|
22099
22161
|
*/
|
|
22100
22162
|
|
|
22101
|
-
export { ALL_TOOLBAR_TOOLS, CELL_SEGMENTER, CHANNEL_HISTOGRAM_API, CellposeSegmenterService, ChannelHistogramComponent, DEFAULT_FALLBACK_PALETTE, DEFAULT_SAM_MODEL_ID, HexColorPickerComponent, IMAGE_STATE_PORT, INSTANCE_SEGMENTER, ImageConverterService, LUT_COLORS, MultiPolygon, NAPARI_DECIMATE_OPTIONS, NAPARI_DEFAULT_DECIMATE, PLOT_TYPE_DESCRIPTORS, PREFERENCES_PORT, PlotType, Polygon, ProcessingImage, REGION_EDITOR_API, REGION_IO_PORT, Rectangle, Region, RegionEditorComponent, RoutingVisualizerService, SAM_MODELS, SEMANTIC_SEGMENTER, ShapeSelection, TILE_ACCESS_PORT, TOOLBAR_TOOLS, VISUALIZER, VIZ_CONFIG, ViewerFeature, VisualizationModule, VisualizerComponent, capabilitiesOf, cropImage, defaultPresetSet, getDefaultSamModelId, getOrtWasmBase, getPlotTypeDescriptor, getSamModel, isEmptyPresetSet, isNapari3d, isNapariIsosurface, isNapariScatter, isNapariScatter3d, isNapariSurface, isNapariVolume, isSamModelReady, isThreeDimensional, provideVisualization, setDefaultSamModel, setOrtWasmBase, setSamModelUrls, sortToolContributions, visibleToolContributions };
|
|
22163
|
+
export { ALL_TOOLBAR_TOOLS, CELL_SEGMENTER, CHANNEL_HISTOGRAM_API, CellposeSegmenterService, ChannelHistogramComponent, DEFAULT_FALLBACK_PALETTE, DEFAULT_SAM_MODEL_ID, HexColorPickerComponent, IMAGE_STATE_PORT, INSTANCE_SEGMENTER, ImageConverterService, LUT_COLORS, MultiPolygon, NAPARI_DECIMATE_OPTIONS, NAPARI_DEFAULT_DECIMATE, PLOT_TYPE_DESCRIPTORS, PREFERENCES_PORT, PlotType, Polygon, ProcessingImage, REGION_EDITOR_API, REGION_IO_PORT, Rectangle, Region, RegionEditorComponent, RoutingVisualizerService, SAM_MODELS, SEMANTIC_SEGMENTER, ShapeSelection, TILE_ACCESS_PORT, TOOLBAR_TOOLS, VISUALIZER, VIZ_CONFIG, ViewerFeature, VisualizationModule, VisualizerComponent, capabilitiesOf, cropImage, defaultPresetSet, getDefaultSamModelId, getOrtWasmBase, getPlotTypeDescriptor, getSamModel, hydrateBounds, isEmptyPresetSet, isNapari3d, isNapariIsosurface, isNapariScatter, isNapariScatter3d, isNapariSurface, isNapariVolume, isSamModelReady, isThreeDimensional, provideVisualization, setDefaultSamModel, setOrtWasmBase, setSamModelUrls, sortToolContributions, visibleToolContributions };
|
|
22102
22164
|
//# sourceMappingURL=jax-data-science-sci-image-visualizer.mjs.map
|