@jax-data-science/sci-image-visualizer 0.10.0 → 0.12.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/esm2022/index.mjs +7 -1
- package/esm2022/lib/contracts/image.contract.mjs +1 -1
- package/esm2022/lib/contracts/ports/region-io.port.mjs +1 -1
- package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +70 -2
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +2 -2
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +11 -1
- package/esm2022/lib/implementations/osd/openseadragon-viewer-options.mjs +18 -2
- package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +9 -1
- package/esm2022/lib/implementations/osd/osd-tile-loading.mjs +71 -0
- package/esm2022/lib/implementations/osd/osd-viewer-like.mjs +1 -1
- package/esm2022/lib/implementations/osd/slice-cache.mjs +35 -6
- package/esm2022/lib/region-editor/region-editor.component.mjs +152 -4
- package/esm2022/lib/region-editor/region-persistence.service.mjs +9 -1
- package/esm2022/lib/region-import/label-classes.mjs +149 -0
- package/esm2022/lib/region-import/label-volume.mjs +225 -0
- package/esm2022/lib/region-import/ome-zarr-labels.mjs +253 -0
- package/esm2022/lib/region-import/open-annotations.mjs +289 -0
- package/esm2022/lib/region-import/region-import.mjs +71 -0
- package/esm2022/lib/region-import/zarr-codecs.mjs +167 -0
- package/esm2022/lib/region-import/zip.mjs +157 -0
- package/esm2022/lib/routing-visualizer.service.mjs +112 -7
- package/esm2022/lib/store/region-source-scope.mjs +19 -4
- package/esm2022/lib/store/region-store.service.mjs +64 -14
- package/esm2022/lib/visualizer/region-load.mjs +16 -1
- package/esm2022/lib/visualizer.component.mjs +28 -2
- package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-a68Hw5rw.mjs} +2057 -196
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-a68Hw5rw.mjs.map +1 -0
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-CvadfzjS.mjs} +4 -2
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-CvadfzjS.mjs.map} +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +3 -1
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
- package/index.d.ts +12 -0
- package/lib/contracts/image.contract.d.ts +7 -0
- package/lib/contracts/ports/region-io.port.d.ts +24 -0
- package/lib/contracts/region-editor-api.contract.d.ts +19 -1
- package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +40 -1
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +5 -0
- package/lib/implementations/osd/openseadragon-viewer-options.d.ts +2 -0
- package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +2 -0
- package/lib/implementations/osd/osd-tile-loading.d.ts +43 -0
- package/lib/implementations/osd/osd-viewer-like.d.ts +14 -0
- package/lib/implementations/osd/slice-cache.d.ts +13 -3
- package/lib/region-editor/region-editor.component.d.ts +27 -0
- package/lib/region-editor/region-persistence.service.d.ts +5 -1
- package/lib/region-import/label-classes.d.ts +39 -0
- package/lib/region-import/label-volume.d.ts +35 -0
- package/lib/region-import/ome-zarr-labels.d.ts +36 -0
- package/lib/region-import/open-annotations.d.ts +73 -0
- package/lib/region-import/region-import.d.ts +46 -0
- package/lib/region-import/zarr-codecs.d.ts +14 -0
- package/lib/region-import/zip.d.ts +31 -0
- package/lib/routing-visualizer.service.d.ts +39 -1
- package/lib/store/region-source-scope.d.ts +8 -2
- package/lib/store/region-store.service.d.ts +15 -5
- package/lib/visualizer.component.d.ts +9 -0
- package/package.json +2 -1
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs.map +0 -1
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { IImageInfo } from '../contracts/image.contract';
|
|
2
|
+
import type { RegionSource } from '../region-source/region-source';
|
|
3
|
+
import { LabelClasses } from './label-classes';
|
|
4
|
+
import { Gunzip } from './label-volume';
|
|
5
|
+
import { LabelStack } from './ome-zarr-labels';
|
|
6
|
+
import { RegionImportFile } from './region-import';
|
|
7
|
+
import { Inflate } from './zarr-codecs';
|
|
8
|
+
import { InflateRaw } from './zip';
|
|
9
|
+
/** The longest side an image built for annotations may have: OpenSeadragon's non-tiled limit. */
|
|
10
|
+
export declare const ANNOTATION_IMAGE_MAX_DIM = 8192;
|
|
11
|
+
/** Opens a slice's region source (again, after the store closed it). */
|
|
12
|
+
type Opener = () => Promise<RegionSource>;
|
|
13
|
+
/** Decoders, injectable for tests and workers (defaults: the platform's streams). */
|
|
14
|
+
export interface AnnotationDecoders {
|
|
15
|
+
inflateRaw?: InflateRaw;
|
|
16
|
+
inflate?: Inflate;
|
|
17
|
+
gunzip?: Gunzip;
|
|
18
|
+
/** Open a GeoJSON text as a region source (default: in the shared region worker). */
|
|
19
|
+
openGeoJson?: (text: string) => Promise<RegionSource>;
|
|
20
|
+
/**
|
|
21
|
+
* Give a label image's regions the atlas look (dark outlines, labels) when its ontology names
|
|
22
|
+
* no style: drawn over the label image itself, outlines in their classes' own colours would not
|
|
23
|
+
* show. (Imported over a real image, the default look reads.)
|
|
24
|
+
*/
|
|
25
|
+
outlineLabels?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/** The annotations among some files, as one region source per slice. */
|
|
28
|
+
export interface AnnotationSlices {
|
|
29
|
+
kind: 'labels' | 'folder' | 'single';
|
|
30
|
+
/** A name for what was opened (the label image's, the folder's, the file's). */
|
|
31
|
+
name: string;
|
|
32
|
+
slices: number;
|
|
33
|
+
/** One opener per slice index. */
|
|
34
|
+
openers: Map<number, Opener>;
|
|
35
|
+
/** A label image's slices and classes (to draw them, see openAnnotations). */
|
|
36
|
+
labels?: {
|
|
37
|
+
stack: LabelStack;
|
|
38
|
+
classes: LabelClasses;
|
|
39
|
+
};
|
|
40
|
+
/** Slice width and height, when known without opening the sources (a label image's). */
|
|
41
|
+
size?: [number, number];
|
|
42
|
+
/** Voxel size x, y, z in micrometres, when the source says. */
|
|
43
|
+
spacing?: [number, number, number];
|
|
44
|
+
/** What was read, for a message ("12 slices of 456 × 320"). */
|
|
45
|
+
summary: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The annotations among `files` (zips expanded), as one region source per slice; null when there
|
|
49
|
+
* are none to read. A label image's slices are traced, and a GeoJSON parsed, when the slice is
|
|
50
|
+
* first shown.
|
|
51
|
+
*/
|
|
52
|
+
export declare function readAnnotationSlices(chosen: readonly RegionImportFile[], decoders?: AnnotationDecoders): Promise<AnnotationSlices | null>;
|
|
53
|
+
/** What {@link openAnnotations} built: the image to publish, and how to release it. */
|
|
54
|
+
export interface OpenedAnnotations {
|
|
55
|
+
info: IImageInfo;
|
|
56
|
+
summary: string;
|
|
57
|
+
/** Revoke the image's blob URLs, and release the slices' sources the region store never took
|
|
58
|
+
* (once another image replaced it). */
|
|
59
|
+
dispose(): void;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The image `files`' annotations are shown on by themselves (see the module comment). Throws when
|
|
63
|
+
* there are none, or when their regions span more than {@link ANNOTATION_IMAGE_MAX_DIM} pixels
|
|
64
|
+
* (they are then imported onto the image they were drawn on).
|
|
65
|
+
*/
|
|
66
|
+
export declare function openAnnotations(files: readonly RegionImportFile[], decoders?: AnnotationDecoders): Promise<OpenedAnnotations>;
|
|
67
|
+
/**
|
|
68
|
+
* One GeoJSON's slices: a collection whose features name planes (`geometry.plane.z`) split into
|
|
69
|
+
* one collection per plane, each keeping the set's class tree and style, its features moved to
|
|
70
|
+
* plane 0 (a slice's source shows plane 0); any other GeoJSON is one slice as it is.
|
|
71
|
+
*/
|
|
72
|
+
export declare function splitByPlane(text: string): string[];
|
|
73
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** A file to import regions from: one the user chose, or one the host's server sent. */
|
|
2
|
+
export interface RegionImportFile {
|
|
3
|
+
name: string;
|
|
4
|
+
text(): Promise<string>;
|
|
5
|
+
bytes(): Promise<Uint8Array>;
|
|
6
|
+
}
|
|
7
|
+
/** A file's contents as the host may hand them over (see `ServerRegionPick`). */
|
|
8
|
+
export type RegionImportData = Blob | ArrayBuffer | Uint8Array | string;
|
|
9
|
+
/** `data`, named `name`, as an import file. A `File`'s own name is used when `name` is omitted. */
|
|
10
|
+
export declare function importFile(data: RegionImportData, name?: string): RegionImportFile;
|
|
11
|
+
/** What a set of chosen files imports as. */
|
|
12
|
+
export type RegionImportPlan =
|
|
13
|
+
/** A label volume, its classes named by an ontology (or a region set description) beside it. */
|
|
14
|
+
{
|
|
15
|
+
kind: 'volume';
|
|
16
|
+
volume: RegionImportFile;
|
|
17
|
+
ontology: RegionImportFile | null;
|
|
18
|
+
}
|
|
19
|
+
/** A folder of per-slice region files, in slice order, with the set's `regionset.json`. */
|
|
20
|
+
| {
|
|
21
|
+
kind: 'folder';
|
|
22
|
+
slices: RegionImportFile[];
|
|
23
|
+
regionSet: RegionImportFile | null;
|
|
24
|
+
}
|
|
25
|
+
/** One region file. */
|
|
26
|
+
| {
|
|
27
|
+
kind: 'single';
|
|
28
|
+
file: RegionImportFile;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* What `files` import as: a label volume (`.nii`, `.nii.gz`, `.nrrd`) with the ontology JSON chosen
|
|
32
|
+
* with it (a `regionset.json`, else an Allen `structure_graph*.json`, else any `.json`); several
|
|
33
|
+
* region files (a folder of per-slice `.geojson`, in natural name order, its `regionset.json`
|
|
34
|
+
* apart); or one region file (`.geojson` or `.json`). Null when none of them is one.
|
|
35
|
+
*/
|
|
36
|
+
export declare function planRegionImport(files: readonly RegionImportFile[]): RegionImportPlan | null;
|
|
37
|
+
/** "slice_2" before "slice_10": runs of digits compared as numbers. */
|
|
38
|
+
export declare function naturalCompare(a: string, b: string): number;
|
|
39
|
+
/**
|
|
40
|
+
* A folder slice's GeoJSON with the set's class tree and style (its `regionset.json`) as the
|
|
41
|
+
* collection's own members, unless the file has its own: what a served folder's slice carries.
|
|
42
|
+
*/
|
|
43
|
+
export declare function folderSliceGeoJson(file: RegionImportFile, regionSet: {
|
|
44
|
+
classHierarchy?: unknown;
|
|
45
|
+
style?: unknown;
|
|
46
|
+
} | null): Promise<string>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Inflate gzip or zlib data (default: the platform's `DecompressionStream`). */
|
|
2
|
+
export type Inflate = (bytes: Uint8Array, format: 'gzip' | 'deflate') => Promise<Uint8Array>;
|
|
3
|
+
/** Decode a Blosc frame. */
|
|
4
|
+
export declare function bloscDecompress(frame: Uint8Array, inflate?: Inflate): Promise<Uint8Array>;
|
|
5
|
+
/** Decode one LZ4 block (no frame) of `size` bytes. */
|
|
6
|
+
export declare function lz4BlockDecompress(src: Uint8Array, size: number): Uint8Array;
|
|
7
|
+
/**
|
|
8
|
+
* Decode a zarr chunk through `codecs`, outermost last as zarr lists them (v2: the one
|
|
9
|
+
* `compressor`; v3: the bytes-to-bytes codecs after `bytes`).
|
|
10
|
+
*/
|
|
11
|
+
export declare function decodeChunk(bytes: Uint8Array, codecs: readonly {
|
|
12
|
+
id: string;
|
|
13
|
+
[k: string]: unknown;
|
|
14
|
+
}[], inflate?: Inflate): Promise<Uint8Array>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The members of a `.zip`, read in the browser: annotations handed over as one archive (a folder
|
|
3
|
+
* of per-slice GeoJSON, a label volume with its ontology, an OME-Zarr store's labels).
|
|
4
|
+
*
|
|
5
|
+
* Only what such archives use: stored or deflated members, ZIP64 sizes and offsets, UTF-8 or
|
|
6
|
+
* legacy names. An encrypted or otherwise compressed member throws when it is read, rather than be
|
|
7
|
+
* read wrongly; a member's CRC-32 is checked. Members are read on demand, so an archive of many
|
|
8
|
+
* chunks (a zarr store) is not inflated whole. Pure: usable from workers.
|
|
9
|
+
*/
|
|
10
|
+
import type { RegionImportFile } from './region-import';
|
|
11
|
+
/** One member of an archive. */
|
|
12
|
+
export interface ZipEntry {
|
|
13
|
+
/** Its path in the archive, '/'-separated. */
|
|
14
|
+
name: string;
|
|
15
|
+
/** Its uncompressed size, in bytes. */
|
|
16
|
+
size: number;
|
|
17
|
+
bytes(): Promise<Uint8Array>;
|
|
18
|
+
}
|
|
19
|
+
/** Inflate raw DEFLATE data (default: the platform's `DecompressionStream('deflate-raw')`). */
|
|
20
|
+
export type InflateRaw = (bytes: Uint8Array) => Promise<Uint8Array>;
|
|
21
|
+
/** Whether a file name is a zip archive. */
|
|
22
|
+
export declare function isZipName(name: string): boolean;
|
|
23
|
+
/** The members of the archive in `bytes` (directories and macOS metadata left out). */
|
|
24
|
+
export declare function readZip(bytes: Uint8Array, inflateRaw?: InflateRaw): ZipEntry[];
|
|
25
|
+
/**
|
|
26
|
+
* `files` with every `.zip` among them replaced by its members, named by their paths in it (a
|
|
27
|
+
* single top folder the archive wraps everything in is kept, as a folder pick would keep it).
|
|
28
|
+
*/
|
|
29
|
+
export declare function expandZips(files: readonly RegionImportFile[], inflateRaw?: InflateRaw): Promise<RegionImportFile[]>;
|
|
30
|
+
/** CRC-32 (IEEE), as zip records it. */
|
|
31
|
+
export declare function crc32(data: Uint8Array): number;
|
|
@@ -75,8 +75,14 @@ export declare class RoutingVisualizerService implements IVisualizer, IRegionEdi
|
|
|
75
75
|
private plottedFileName;
|
|
76
76
|
/** The div the backends render into (every backend shares it); '' before the first plot. */
|
|
77
77
|
private plotDiv;
|
|
78
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* Whether regions can be shown in 3D on screen: a napari volume (or isosurface) view, or the 3D
|
|
80
|
+
* spatial cloud over a stack image (its reference volume's, see showVolumeAsImage). Both draw the
|
|
81
|
+
* region reconstructions the same way (VolumeRegionMeshes), in the volume's box.
|
|
82
|
+
*/
|
|
79
83
|
private readonly volumeView$;
|
|
84
|
+
/** Whether a napari volume (or isosurface) view is the current plot type: the slice pane's. */
|
|
85
|
+
private imageVolumeView;
|
|
80
86
|
/** Whether the volume view's slice pane is wanted (see {@link setSliceEditor}). */
|
|
81
87
|
private readonly sliceEditor$;
|
|
82
88
|
/** Whether the volume view draws the region reconstructions through the volume. */
|
|
@@ -114,6 +120,8 @@ export declare class RoutingVisualizerService implements IVisualizer, IRegionEdi
|
|
|
114
120
|
private readonly sectionSubs;
|
|
115
121
|
/** The image info and screen height of the last plot (what the slice pane mounts). */
|
|
116
122
|
private plottedInfo;
|
|
123
|
+
/** The current region import (see regionImportTicket): its id and the image it was taken for. */
|
|
124
|
+
private importTicket;
|
|
117
125
|
private plottedHeight;
|
|
118
126
|
constructor(plotly: PlotlyService, osd: OpenSeadragonVisualizerService, napari: NapariVisualizerService, store: VisualizerStore, config: VizConfig, regionStore: RegionStore, selectionStore: SpatialSelectionStore, intensity: IntensityProfileService, spatialData?: SpatialDataPort | null);
|
|
119
127
|
/** A class's colour: its classification colour, else its region source's, else a default. */
|
|
@@ -265,12 +273,42 @@ export declare class RoutingVisualizerService implements IVisualizer, IRegionEdi
|
|
|
265
273
|
attachRegionSource(source: RegionSource | RegionSourceOpener, slices?: RegionSourceSlices): void;
|
|
266
274
|
importRegionSource(geoJsonStr: string): Promise<boolean>;
|
|
267
275
|
dropRegionSource(): Promise<void>;
|
|
276
|
+
/**
|
|
277
|
+
* A ticket for a region import that is about to read or decode its files: the import methods
|
|
278
|
+
* given it change nothing once it is stale — another import took a ticket since, another image
|
|
279
|
+
* was plotted, or the service was destroyed — so an import that finishes late never lands on an
|
|
280
|
+
* image it was not started for.
|
|
281
|
+
*/
|
|
282
|
+
regionImportTicket(): number;
|
|
283
|
+
/** Whether `ticket` is still the current import's, on the image it was taken for. */
|
|
284
|
+
private importTicketValid;
|
|
285
|
+
private importImageKey;
|
|
286
|
+
/**
|
|
287
|
+
* Replace the image's regions and region sources with one source per slice, as an imported label
|
|
288
|
+
* volume or folder of per-slice region files gives them: `openers` by slice index, each opened
|
|
289
|
+
* the first time its slice is shown. A single image takes slice 0's. Returns how many slices
|
|
290
|
+
* have a source, or null (changing nothing) when `ticket` is stale (see
|
|
291
|
+
* {@link regionImportTicket}). The sources are marked imported, so a save writes every slice.
|
|
292
|
+
*/
|
|
293
|
+
importSliceRegionSources(openers: ReadonlyMap<number, RegionSourceOpener>, ticket?: number): number | null;
|
|
294
|
+
/**
|
|
295
|
+
* Replace the image's regions and region sources with one imported source (a region set the
|
|
296
|
+
* host's server serves): over every slice of a stack when it is z-indexed, else on the slice
|
|
297
|
+
* shown, as {@link applyImageRois} lays out an image's own. Resolves false, changing nothing
|
|
298
|
+
* (and disposing the source), when the import went stale while it opened: another import, or
|
|
299
|
+
* another image (see {@link regionImportTicket}; one is taken here when `ticket` is not given).
|
|
300
|
+
*/
|
|
301
|
+
importRegionSourceOpener(open: RegionSourceOpener, ticket?: number): Promise<boolean>;
|
|
302
|
+
/** Empty every slice of a stack (its regions and undo history) for regions imported over it. */
|
|
303
|
+
private enterImportedStack;
|
|
268
304
|
getRegionSourceView$(): Observable<RegionSourceView | null>;
|
|
269
305
|
getRegionSourceIndex(query: Omit<RegionIndexQuery, 'exclude'>): Promise<RegionIndexPage>;
|
|
270
306
|
selectSourceFeatures(ids: readonly string[], additive?: boolean): Promise<number[]>;
|
|
271
307
|
deleteSourceFeatures(ids: readonly string[]): void;
|
|
272
308
|
getRegionStyle$(): Observable<RegionStyle>;
|
|
273
309
|
setRegionStyle(patch: Partial<RegionStyle>): void;
|
|
310
|
+
/** Recompute which 3D view is on screen for `plotType` (see {@link volumeView$}). */
|
|
311
|
+
private updateVolumeView;
|
|
274
312
|
/** Whether a napari volume (or isosurface) view is on screen: regions can be shown in 3D. */
|
|
275
313
|
getVolumeView$(): Observable<boolean>;
|
|
276
314
|
/** Whether the volume view's slice pane is wanted (it shows while a volume view is on screen). */
|
|
@@ -31,8 +31,12 @@ export declare class RegionSourceScope {
|
|
|
31
31
|
private readonly openOrder;
|
|
32
32
|
/** The entry of the slice on screen: kept open. */
|
|
33
33
|
private shown;
|
|
34
|
-
/**
|
|
35
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Attach `open` to `image` for `slices`, replacing (and closing) what was there. `imported` names
|
|
36
|
+
* the slices it brings that a save must write (see {@link importedSlices}): for a source of one
|
|
37
|
+
* slice, that slice when non-empty; for a `'planes'` source, the slices its planes cover.
|
|
38
|
+
*/
|
|
39
|
+
attach(image: string, open: RegionSourceOpener, slices: RegionSourceSlices, imported?: readonly number[]): void;
|
|
36
40
|
/** Drop every source of `image` (closing the open ones) and what was taken from them. */
|
|
37
41
|
detachImage(image: string): void;
|
|
38
42
|
/** Drop the source of one slice of `image`. */
|
|
@@ -56,6 +60,8 @@ export declare class RegionSourceScope {
|
|
|
56
60
|
taken(image: string | undefined, slice: number): ReadonlySet<string>;
|
|
57
61
|
/** Every id taken from any slice of `image` (a `'planes'` source's ids are unique across them). */
|
|
58
62
|
allTaken(image: string | undefined): string[];
|
|
63
|
+
/** The slices of `image` whose source was imported (see {@link attach}), in order. */
|
|
64
|
+
importedSlices(image: string | undefined): number[];
|
|
59
65
|
/** The slices of `image` with anything taken from their source. */
|
|
60
66
|
slicesWithTaken(image: string | undefined): number[];
|
|
61
67
|
/** Replace the ids taken from `slice`'s source (copy-on-write: `ids` is kept as given). */
|
|
@@ -338,8 +338,13 @@ export declare class RegionStore implements IRegionStore, IRegionEditApi, IRegio
|
|
|
338
338
|
* source was closed to save memory). `slices` says which slice of the current image it
|
|
339
339
|
* serves: one (default: the slice shown; plane 0 of the source), or `'planes'`, every slice z
|
|
340
340
|
* from plane z of a z-indexed source. Replaces the source those slices had.
|
|
341
|
+
*
|
|
342
|
+
* `imported` marks a source brought in over the image (an imported volume, folder or served set)
|
|
343
|
+
* rather than the image's own regions: it is on no file yet, so a save writes its slices though
|
|
344
|
+
* nothing was taken from it — `true` for a source of one slice, the slices its planes cover for a
|
|
345
|
+
* `'planes'` source. The image's own sources are not marked: loading them changes nothing to save.
|
|
341
346
|
*/
|
|
342
|
-
attachRegionSource(source: RegionSource | RegionSourceOpener, slices?: RegionSourceSlices): void;
|
|
347
|
+
attachRegionSource(source: RegionSource | RegionSourceOpener, slices?: RegionSourceSlices, imported?: boolean | readonly number[]): void;
|
|
343
348
|
/** Drop the current image's region sources (closing them) and what was taken from them. */
|
|
344
349
|
detachRegionSources(): void;
|
|
345
350
|
/**
|
|
@@ -439,10 +444,15 @@ export declare class RegionStore implements IRegionStore, IRegionEditApi, IRegio
|
|
|
439
444
|
*/
|
|
440
445
|
getRegionSourceIndex(query: Omit<RegionIndexQuery, 'exclude'>): Promise<RegionIndexPage>;
|
|
441
446
|
/**
|
|
442
|
-
* `regions` as a GeoJSON FeatureCollection string merged with the region
|
|
443
|
-
* the
|
|
444
|
-
* {@link getGeoJsonString}.
|
|
445
|
-
*
|
|
447
|
+
* `regions` as a GeoJSON FeatureCollection string merged with the region sources behind them:
|
|
448
|
+
* the sources' features that were not taken (or deleted), then `regions`. Without a source,
|
|
449
|
+
* {@link getGeoJsonString}.
|
|
450
|
+
*
|
|
451
|
+
* `slice` names one slice-file of a folder stack (a per-slice-file save): its source's features,
|
|
452
|
+
* on the file's own plane — of a z-indexed source over every slice, only that slice's plane.
|
|
453
|
+
* Without it, the export is the image's: on a stack saved as one file, every slice's source
|
|
454
|
+
* (each feature on its slice's plane, `geometry.plane.z`) and a z-indexed source's every plane;
|
|
455
|
+
* otherwise the source of the slice shown.
|
|
446
456
|
*/
|
|
447
457
|
getGeoJsonWithSource(regions: Region[], slice?: number): Promise<string>;
|
|
448
458
|
/**
|
|
@@ -290,6 +290,8 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
290
290
|
protected get hasSpatialDataset(): boolean;
|
|
291
291
|
/** Keyboard, wheel and context-menu handling; created once the view exists. */
|
|
292
292
|
private shortcuts?;
|
|
293
|
+
/** Waits for a viewer created outside the document to be attached (see {@link whenInDocument}). */
|
|
294
|
+
private attachObserver;
|
|
293
295
|
/** Debounced z-slice scrubbing (see SliceScrubber — refactoring plan Step 7). */
|
|
294
296
|
private readonly scrubber;
|
|
295
297
|
constructor(state: ImageStatePort, plotService: IVisualizer, messageService: MessageService, ngZone: NgZone, cdr: ChangeDetectorRef, session: VisualizerStore, samTool: SamToolService, cellSegmentTool: CellSegmentToolService, samPointTool: SamPointToolService, regionOps: RegionOpsService, vizConfig?: VizConfig | undefined, toolContributions?: readonly ToolbarContribution[], spatialData?: SpatialDataPort | undefined, plotTypeContributions?: readonly PlotTypeContribution[], injector?: Injector | undefined, hostRef?: ElementRef<HTMLElement> | undefined, destroyRef?: DestroyRef);
|
|
@@ -338,6 +340,13 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
338
340
|
ngAfterViewInit(): void;
|
|
339
341
|
/** The plot div exists now: run an image-less draw that arrived before it did. */
|
|
340
342
|
private onViewReady;
|
|
343
|
+
/**
|
|
344
|
+
* Run `ready` once this viewer is in the document. A host may create it detached — a closed
|
|
345
|
+
* dialog's projected content, such as jit-ui's pipeline preview — and the backends find the
|
|
346
|
+
* plot div by id, so a draw then found no target and alerted "the renderer could not start"
|
|
347
|
+
* over another viewer. Until then its view is not ready, and an image-less draw waits.
|
|
348
|
+
*/
|
|
349
|
+
private whenInDocument;
|
|
341
350
|
/** What the keyboard, wheel and context-menu shortcuts act on. Their listeners live
|
|
342
351
|
* outside this view, so every action that changes what it shows marks it for check. */
|
|
343
352
|
private shortcutHost;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jax-data-science/sci-image-visualizer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=20.9.0"
|
|
6
6
|
},
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"cellpose-js": "^0.6.0",
|
|
41
41
|
"fast-png": "^6.4.0",
|
|
42
|
+
"fzstd": "^0.1.1",
|
|
42
43
|
"napari-js": "^0.18.0",
|
|
43
44
|
"openseadragon": "^6.0.2",
|
|
44
45
|
"plotly.js-dist-min": "^3.0.1",
|