@jax-data-science/sci-image-visualizer 0.9.0 → 0.10.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/region-editor-api.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-store.contract.mjs +1 -1
- package/esm2022/lib/contracts/section-view.contract.mjs +2 -0
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/contracts/viz-config.mjs +1 -1
- package/esm2022/lib/geometry/loft.mjs +128 -0
- package/esm2022/lib/geometry/polylabel.mjs +156 -0
- package/esm2022/lib/geometry/reconstruct.mjs +315 -0
- package/esm2022/lib/geometry/reslice-image.mjs +57 -0
- package/esm2022/lib/geometry/section.mjs +215 -0
- package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +11 -7
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +20 -3
- package/esm2022/lib/implementations/napari-js/napari-region-mesh-pointer.mjs +100 -0
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +28 -5
- package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +9 -2
- package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +5 -2
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +81 -1
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +129 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +115 -4
- package/esm2022/lib/implementations/napari-js/napari-volume-slice-planes.mjs +103 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +15 -3
- package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +18 -7
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +38 -8
- package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +1 -1
- package/esm2022/lib/models/class-preset.mjs +1 -1
- package/esm2022/lib/models/polygon-factory.mjs +17 -1
- package/esm2022/lib/models/region-geojson.mjs +44 -6
- package/esm2022/lib/models/region.mjs +1 -1
- package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +156 -0
- package/esm2022/lib/region-editor/class-tree/class-tree.mjs +108 -0
- package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +77 -13
- package/esm2022/lib/region-editor/region-editor.component.mjs +527 -42
- package/esm2022/lib/region-editor/region-metrics.mjs +20 -2
- package/esm2022/lib/region-editor/region-persistence.service.mjs +36 -10
- package/esm2022/lib/region-editor/region-table/region-table.component.mjs +24 -8
- package/esm2022/lib/region-overlay/region-geometry.mjs +3 -3
- package/esm2022/lib/region-overlay/region-source-layer.mjs +378 -0
- package/esm2022/lib/region-overlay/region-style.mjs +97 -0
- package/esm2022/lib/region-source/http-region-source.mjs +104 -0
- package/esm2022/lib/region-source/region-source-ops.mjs +53 -0
- package/esm2022/lib/region-source/region-source-worker.mjs +10 -0
- package/esm2022/lib/region-source/region-source.mjs +67 -0
- package/esm2022/lib/region-source/region-tiles.mjs +708 -0
- package/esm2022/lib/region-source/worker-region-source.mjs +229 -0
- package/esm2022/lib/routing-visualizer.service.mjs +418 -22
- package/esm2022/lib/section-pane/section-pane.component.mjs +299 -0
- package/esm2022/lib/store/class-color.util.mjs +10 -5
- package/esm2022/lib/store/class-signatures.mjs +63 -0
- package/esm2022/lib/store/region-scope-cache.mjs +5 -1
- package/esm2022/lib/store/region-source-scope.mjs +171 -0
- package/esm2022/lib/store/region-store.service.mjs +724 -12
- package/esm2022/lib/store/visualizer-store.service.mjs +33 -6
- package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +8 -2
- package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +55 -15
- package/esm2022/lib/toolbar/toolbar.component.mjs +19 -5
- package/esm2022/lib/visualizer/region-load.mjs +67 -4
- package/esm2022/lib/visualizer/volume-sections.mjs +175 -0
- package/esm2022/lib/visualizer.component.mjs +128 -6
- package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs} +7239 -1153
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs.map +1 -0
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs} +4 -4
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs.map} +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +3 -3
- package/fesm2022/region-source.worker.js +1067 -0
- package/index.d.ts +6 -0
- package/lib/contracts/image.contract.d.ts +4 -0
- package/lib/contracts/region-editor-api.contract.d.ts +84 -0
- package/lib/contracts/region-store.contract.d.ts +22 -0
- package/lib/contracts/section-view.contract.d.ts +44 -0
- package/lib/contracts/visualizer.contract.d.ts +10 -0
- package/lib/contracts/viz-config.d.ts +8 -0
- package/lib/geometry/loft.d.ts +22 -0
- package/lib/geometry/polylabel.d.ts +23 -0
- package/lib/geometry/reconstruct.d.ts +54 -0
- package/lib/geometry/reslice-image.d.ts +33 -0
- package/lib/geometry/section.d.ts +52 -0
- package/lib/implementations/napari-js/napari-loading-badge.d.ts +4 -2
- package/lib/implementations/napari-js/napari-loading-state.d.ts +8 -1
- package/lib/implementations/napari-js/napari-region-mesh-pointer.d.ts +32 -0
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +6 -1
- package/lib/implementations/napari-js/napari-scene.d.ts +33 -0
- package/lib/implementations/napari-js/napari-spatial-hover.d.ts +3 -1
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +48 -0
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +66 -0
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +45 -1
- package/lib/implementations/napari-js/napari-volume-slice-planes.d.ts +43 -0
- package/lib/implementations/osd/osd-region-overlay-draw.d.ts +4 -3
- package/lib/implementations/osd/osd-region-overlay.d.ts +10 -3
- package/lib/implementations/tile-server/tile-protocol.d.ts +3 -0
- package/lib/models/class-preset.d.ts +7 -0
- package/lib/models/polygon-factory.d.ts +5 -0
- package/lib/models/region-geojson.d.ts +40 -0
- package/lib/models/region.d.ts +19 -0
- package/lib/region-editor/class-tree/class-tree.component.d.ts +78 -0
- package/lib/region-editor/class-tree/class-tree.d.ts +31 -0
- package/lib/region-editor/classes-panel/classes-panel.component.d.ts +36 -6
- package/lib/region-editor/region-editor.component.d.ts +133 -17
- package/lib/region-editor/region-metrics.d.ts +8 -0
- package/lib/region-editor/region-persistence.service.d.ts +12 -4
- package/lib/region-editor/region-table/region-table.component.d.ts +10 -4
- package/lib/region-overlay/region-geometry.d.ts +4 -3
- package/lib/region-overlay/region-source-layer.d.ts +96 -0
- package/lib/region-overlay/region-style.d.ts +52 -0
- package/lib/region-source/http-region-source.d.ts +45 -0
- package/lib/region-source/region-source-ops.d.ts +89 -0
- package/lib/region-source/region-source-worker.d.ts +7 -0
- package/lib/region-source/region-source.d.ts +82 -0
- package/lib/region-source/region-tiles.d.ts +289 -0
- package/lib/region-source/worker-region-source.d.ts +65 -0
- package/lib/routing-visualizer.service.d.ts +138 -1
- package/lib/section-pane/section-pane.component.d.ts +47 -0
- package/lib/store/class-color.util.d.ts +6 -3
- package/lib/store/class-signatures.d.ts +11 -0
- package/lib/store/region-scope-cache.d.ts +2 -0
- package/lib/store/region-source-scope.d.ts +68 -0
- package/lib/store/region-store.service.d.ts +206 -2
- package/lib/store/visualizer-store.service.d.ts +10 -0
- package/lib/toolbar/region-tools/region-tools.component.d.ts +3 -1
- package/lib/toolbar/stack-controls/stack-controls.component.d.ts +20 -9
- package/lib/toolbar/toolbar.component.d.ts +9 -2
- package/lib/visualizer/region-load.d.ts +23 -4
- package/lib/visualizer/volume-sections.d.ts +64 -0
- package/lib/visualizer.component.d.ts +31 -0
- package/package.json +2 -2
- package/src/lib/assets/slice.svg +23 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs.map +0 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { AfterViewInit, EventEmitter, NgZone, OnChanges, OnDestroy } from '@angular/core';
|
|
2
|
+
import type { SectionAxis, SectionView } from '../contracts/section-view.contract';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export declare class SectionPaneComponent implements AfterViewInit, OnChanges, OnDestroy {
|
|
5
|
+
private readonly zone;
|
|
6
|
+
axis: SectionAxis;
|
|
7
|
+
view: SectionView | null;
|
|
8
|
+
/** A point clicked, in section coordinates (u across, v down). */
|
|
9
|
+
readonly pick: EventEmitter<{
|
|
10
|
+
u: number;
|
|
11
|
+
v: number;
|
|
12
|
+
}>;
|
|
13
|
+
private canvasRef;
|
|
14
|
+
private zoom;
|
|
15
|
+
private pan;
|
|
16
|
+
private press;
|
|
17
|
+
private image;
|
|
18
|
+
private resize?;
|
|
19
|
+
private frame;
|
|
20
|
+
constructor(zone: NgZone);
|
|
21
|
+
protected get axisColor(): string;
|
|
22
|
+
protected get label(): string;
|
|
23
|
+
ngAfterViewInit(): void;
|
|
24
|
+
ngOnChanges(): void;
|
|
25
|
+
ngOnDestroy(): void;
|
|
26
|
+
/** Back to the whole section, centred. */
|
|
27
|
+
fit(): void;
|
|
28
|
+
protected onWheel(e: WheelEvent): void;
|
|
29
|
+
protected onDown(e: PointerEvent): void;
|
|
30
|
+
protected onMove(e: PointerEvent): void;
|
|
31
|
+
protected onUp(e: PointerEvent): void;
|
|
32
|
+
private local;
|
|
33
|
+
/** Section units → CSS px in the pane: scale per unit across and down, and the origin. */
|
|
34
|
+
private transform;
|
|
35
|
+
private toSection;
|
|
36
|
+
/** Redraw on the next frame (outside Angular: a canvas paint needs no change detection). */
|
|
37
|
+
private draw;
|
|
38
|
+
private paint;
|
|
39
|
+
/** Each class's cut: its outlines filled and stroked, its lines drawn (a dot for one point). */
|
|
40
|
+
private paintRegions;
|
|
41
|
+
/** The other planes: across (u) and down (v), dashed in their axis colours. */
|
|
42
|
+
private paintCrosshair;
|
|
43
|
+
/** The section's image on a canvas of its own size (made again only for a new image). */
|
|
44
|
+
private imageCanvas;
|
|
45
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SectionPaneComponent, never>;
|
|
46
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SectionPaneComponent, "viz-section-pane", never, { "axis": { "alias": "axis"; "required": true; }; "view": { "alias": "view"; "required": false; }; }, { "pick": "pick"; }, never, never, true, never>;
|
|
47
|
+
}
|
|
@@ -30,7 +30,10 @@ export declare function findPreset(label: string, set: PresetSet): ClassPreset |
|
|
|
30
30
|
* HSL hue. Same name -> same colour, every run.
|
|
31
31
|
*/
|
|
32
32
|
export declare function fallbackColorFor(label: string, palette: string[]): string;
|
|
33
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* Resolve a colour for `label`: a matching preset's colour, else the colour an imported file
|
|
35
|
+
* gave the class, else the deterministic fallback.
|
|
36
|
+
*/
|
|
34
37
|
export declare function colorForLabel(label: string, set: PresetSet): string;
|
|
35
38
|
/** Options for {@link applyPresetColors}. */
|
|
36
39
|
export interface ApplyPresetColorsOptions {
|
|
@@ -49,8 +52,8 @@ export interface ApplyPresetColorsOptions {
|
|
|
49
52
|
/**
|
|
50
53
|
* Resolve each labelled region's colour from the preset set (jit-ui#70). The
|
|
51
54
|
* presets are the source of truth: a matching preset gives the class colour,
|
|
52
|
-
* an unknown class
|
|
53
|
-
*
|
|
55
|
+
* an unknown class the colour an imported file gave it (`importedColors`) or else
|
|
56
|
+
* its deterministic fallback, **overriding any colour already on the region**. Unlabelled regions and
|
|
54
57
|
* ones the user recoloured (`colorOverridden`) are left untouched. Unknown
|
|
55
58
|
* classes are reported through `onPromote` when `autoPromote` is on.
|
|
56
59
|
*
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Region } from '../models/region';
|
|
2
|
+
/**
|
|
3
|
+
* A fingerprint of each class's regions (by label): their ids and geometry folded into one number
|
|
4
|
+
* per class. Two sets give the same fingerprint for a class when its regions did not change, so
|
|
5
|
+
* comparing a slice's fingerprints before and after an edit names the classes the edit touched
|
|
6
|
+
* (a recoloured or relabelled region touches its old class and its new one). Profile lines and
|
|
7
|
+
* unlabelled regions are left out: they are in no class.
|
|
8
|
+
*/
|
|
9
|
+
export declare function classSignatures(regions: readonly Region[]): Map<string, number>;
|
|
10
|
+
/** The classes whose fingerprints differ between `before` and `after` (added and removed included). */
|
|
11
|
+
export declare function changedClasses(before: ReadonlyMap<string, number>, after: ReadonlyMap<string, number>): Set<string>;
|
|
@@ -26,6 +26,8 @@ export declare class RegionScopeCache {
|
|
|
26
26
|
private initialNonEmpty;
|
|
27
27
|
/** The cache key for an image: its first URL, else its file name. */
|
|
28
28
|
static imageKey(imageInfo: IImageInfo | undefined): string | undefined;
|
|
29
|
+
/** The active image's cache key (see {@link imageKey}). */
|
|
30
|
+
get activeImage(): string | undefined;
|
|
29
31
|
/** True while a z-stack is loaded and regions are held per slice. */
|
|
30
32
|
get stackMode(): boolean;
|
|
31
33
|
/** The current display slice (zero-based; 0 outside stack mode unless set). */
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { RegionSource } from '../region-source/region-source';
|
|
2
|
+
/** Opens a region source on demand (and again after it was closed to save memory). */
|
|
3
|
+
export type RegionSourceOpener = () => Promise<RegionSource>;
|
|
4
|
+
/** Which slices a source serves: one slice (plane `plane` of the source), or every slice z
|
|
5
|
+
* from the source's plane z (a z-indexed GeoJSON over a whole stack). */
|
|
6
|
+
export type RegionSourceSlices = {
|
|
7
|
+
slice: number;
|
|
8
|
+
plane?: number;
|
|
9
|
+
} | 'planes';
|
|
10
|
+
/** The region source behind one slice: the source and which of its planes the slice shows. */
|
|
11
|
+
export interface RegionSourceBinding {
|
|
12
|
+
source: RegionSource;
|
|
13
|
+
plane: number;
|
|
14
|
+
}
|
|
15
|
+
/** Sources held open, past which the least recently used one is closed (never the one shown). */
|
|
16
|
+
export declare const OPEN_REGION_SOURCES = 6;
|
|
17
|
+
/**
|
|
18
|
+
* The region sources of every image the store has seen, per slice, and per slice the ids of
|
|
19
|
+
* the source features taken out of the source (into the working set, or deleted) — those the
|
|
20
|
+
* source no longer draws and an export leaves out.
|
|
21
|
+
*
|
|
22
|
+
* Sources open lazily, the first time their slice is shown or read, and at most
|
|
23
|
+
* {@link OPEN_REGION_SOURCES} stay open: the least recently used are closed and re-opened from
|
|
24
|
+
* their opener when used again (a source's ids are stable, so what was taken stays taken). The
|
|
25
|
+
* source of the slice on screen ({@link show}) is never closed for another: a read across every
|
|
26
|
+
* slice must not close the source the viewer draws and takes from.
|
|
27
|
+
*/
|
|
28
|
+
export declare class RegionSourceScope {
|
|
29
|
+
private readonly images;
|
|
30
|
+
/** Open entries, least recently used first. */
|
|
31
|
+
private readonly openOrder;
|
|
32
|
+
/** The entry of the slice on screen: kept open. */
|
|
33
|
+
private shown;
|
|
34
|
+
/** Attach `open` to `image` for `slices`, replacing (and closing) what was there. */
|
|
35
|
+
attach(image: string, open: RegionSourceOpener, slices: RegionSourceSlices): void;
|
|
36
|
+
/** Drop every source of `image` (closing the open ones) and what was taken from them. */
|
|
37
|
+
detachImage(image: string): void;
|
|
38
|
+
/** Drop the source of one slice of `image`. */
|
|
39
|
+
detachSlice(image: string, slice: number): void;
|
|
40
|
+
/** The slice on screen (null: none): its source stays open while others are read. */
|
|
41
|
+
show(image: string | undefined, slice: number | null): void;
|
|
42
|
+
/** Whether `image` has a source for `slice`. */
|
|
43
|
+
has(image: string | undefined, slice: number): boolean;
|
|
44
|
+
/** Whether `slice` of `image` has a source of its own (not a `'planes'` source's plane). */
|
|
45
|
+
hasOwnSource(image: string | undefined, slice: number): boolean;
|
|
46
|
+
/** Every slice of `image` with a source of its own (not counting a `'planes'` source). */
|
|
47
|
+
slicesWithSource(image: string | undefined): number[];
|
|
48
|
+
/** Whether `image` has one source over all its slices. */
|
|
49
|
+
hasPlanesSource(image: string | undefined): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* The source behind `slice` of `image`, opening it if needed. Resolves null when there is
|
|
52
|
+
* none, and rejects when it cannot be opened.
|
|
53
|
+
*/
|
|
54
|
+
binding(image: string | undefined, slice: number): Promise<RegionSourceBinding | null>;
|
|
55
|
+
/** The ids taken from `slice`'s source. */
|
|
56
|
+
taken(image: string | undefined, slice: number): ReadonlySet<string>;
|
|
57
|
+
/** Every id taken from any slice of `image` (a `'planes'` source's ids are unique across them). */
|
|
58
|
+
allTaken(image: string | undefined): string[];
|
|
59
|
+
/** The slices of `image` with anything taken from their source. */
|
|
60
|
+
slicesWithTaken(image: string | undefined): number[];
|
|
61
|
+
/** Replace the ids taken from `slice`'s source (copy-on-write: `ids` is kept as given). */
|
|
62
|
+
setTaken(image: string | undefined, slice: number, ids: ReadonlySet<string>): void;
|
|
63
|
+
private entry;
|
|
64
|
+
private imageSources;
|
|
65
|
+
private openEntry;
|
|
66
|
+
private close;
|
|
67
|
+
private closeSource;
|
|
68
|
+
}
|
|
@@ -3,9 +3,17 @@ import { IImageInfo } from '../contracts/image.contract';
|
|
|
3
3
|
import { Region, Rectangle, Polygon, MultiPolygon } from '../models/region';
|
|
4
4
|
import { VisualizerStore } from './visualizer-store.service';
|
|
5
5
|
import { IRegionStore } from '../contracts/visualizer.contract';
|
|
6
|
-
import { IRegionEditApi } from '../contracts/region-store.contract';
|
|
6
|
+
import { IRegionEditApi, IRegionSourceApi } from '../contracts/region-store.contract';
|
|
7
|
+
import type { Mesh } from 'napari-js/geometry';
|
|
8
|
+
import { SliceOutlines } from '../geometry/reconstruct';
|
|
7
9
|
import { StackSaveLayout } from './region-scope-cache';
|
|
10
|
+
import { RegionSourceOpener, RegionSourceSlices } from './region-source-scope';
|
|
11
|
+
import type { RegionSource, RegionSourceView } from '../region-source/region-source';
|
|
12
|
+
import type { RegionIndexPage, RegionIndexQuery } from '../region-source/region-tiles';
|
|
13
|
+
import { RegionStyle } from '../region-overlay/region-style';
|
|
8
14
|
import * as i0 from "@angular/core";
|
|
15
|
+
/** Selecting classes takes at most this many region-source features into the regions. */
|
|
16
|
+
export declare const SELECT_CLASSES_LIMIT = 5000;
|
|
9
17
|
/**
|
|
10
18
|
* Backend-neutral region store — the single source of truth for region state.
|
|
11
19
|
*
|
|
@@ -34,7 +42,7 @@ import * as i0 from "@angular/core";
|
|
|
34
42
|
* backends); GeoJSON import/export is `models/region-geojson`. All coordinates
|
|
35
43
|
* are image pixels.
|
|
36
44
|
*/
|
|
37
|
-
export declare class RegionStore implements IRegionStore, IRegionEditApi {
|
|
45
|
+
export declare class RegionStore implements IRegionStore, IRegionEditApi, IRegionSourceApi {
|
|
38
46
|
private store;
|
|
39
47
|
private static readonly UNDO_LIMIT;
|
|
40
48
|
private static readonly UNDO_COALESCE_MS;
|
|
@@ -78,6 +86,35 @@ export declare class RegionStore implements IRegionStore, IRegionEditApi {
|
|
|
78
86
|
/** Emit coalescing for live drags (see IRegionEditApi.beginBatch). */
|
|
79
87
|
private batchDepth;
|
|
80
88
|
private pendingEmit;
|
|
89
|
+
/**
|
|
90
|
+
* Large region sets held as tiled region sources rather than as regions (see
|
|
91
|
+
* {@link attachRegionSource}): per image and slice, with the ids taken out of each.
|
|
92
|
+
*/
|
|
93
|
+
private readonly sources;
|
|
94
|
+
private readonly sourceView$;
|
|
95
|
+
/** The region look the user chose (overrides the source's hint), field by field. */
|
|
96
|
+
private userStyle;
|
|
97
|
+
/** The current source's style hint. */
|
|
98
|
+
private hintStyle;
|
|
99
|
+
private readonly regionStyle$;
|
|
100
|
+
/** Bumped on every change of the slice's source, so a late open is dropped. */
|
|
101
|
+
private sourceGeneration;
|
|
102
|
+
/** The source last published as the view: a source shown again does not turn the labels back on. */
|
|
103
|
+
private shownSource;
|
|
104
|
+
/** Bumped when a region source is attached or dropped: what is read from the sources is stale. */
|
|
105
|
+
private sourcesVersion;
|
|
106
|
+
/**
|
|
107
|
+
* The region sources' part of {@link classVolumes}, by class and what the sources hold (see
|
|
108
|
+
* {@link sourceStateKey}): an edit of the regions leaves it, so the volumes of a slice being drawn
|
|
109
|
+
* on cost no source reads.
|
|
110
|
+
*/
|
|
111
|
+
private readonly sourceVolumeCache;
|
|
112
|
+
/** The region sources' outlines of the class sets reconstructed last (see {@link sourceOutlines}). */
|
|
113
|
+
private readonly sourceOutlineCache;
|
|
114
|
+
/** The classes hidden from view (names as given); every class is shown at first. */
|
|
115
|
+
private readonly hiddenClasses$;
|
|
116
|
+
/** {@link hiddenClasses$} by {@link presetKey}, as a region's label is matched. */
|
|
117
|
+
private hiddenKeys;
|
|
81
118
|
constructor(store: VisualizerStore);
|
|
82
119
|
/**
|
|
83
120
|
* Replace (or, with `append`, add to) the current image's regions. Mints ids
|
|
@@ -236,6 +273,10 @@ export declare class RegionStore implements IRegionStore, IRegionEditApi {
|
|
|
236
273
|
* region it edits) rather than changing them, so it never changes after this.
|
|
237
274
|
*/
|
|
238
275
|
private recordUndoSnapshot;
|
|
276
|
+
/** The state an undo step restores. */
|
|
277
|
+
private snapshot;
|
|
278
|
+
/** Parse GeoJSON into regions, remembering the class colours the file carries so they are
|
|
279
|
+
* kept for classes with no preset (see VisualizerStore.rememberImportedClassColors). */
|
|
239
280
|
importRegions(geoJsonStr: string): Region[];
|
|
240
281
|
/** Download `regions` as GeoJSON, named after `fileName` (extension
|
|
241
282
|
* replaced by `.geojson`) or `rois.geojson` without one. */
|
|
@@ -286,6 +327,169 @@ export declare class RegionStore implements IRegionStore, IRegionEditApi {
|
|
|
286
327
|
beginGesture(): void;
|
|
287
328
|
/** End the gesture opened by {@link beginGesture}; the next commit starts a new step. */
|
|
288
329
|
endGesture(): void;
|
|
330
|
+
/**
|
|
331
|
+
* Hold a large region set as a tiled region source instead of as regions: the backends that
|
|
332
|
+
* draw sources (OpenSeadragon, napari) draw its features at the detail the zoom shows, from
|
|
333
|
+
* the tiles in view, and a feature joins the regions — exactly, as an ordinary editable
|
|
334
|
+
* {@link Region} with its {@link Region.sourceId} — only when it is selected or edited
|
|
335
|
+
* ({@link takeSourceFeatures}). Until then {@link getRegions} does not include it.
|
|
336
|
+
*
|
|
337
|
+
* `source` may be an opener, called the first time its slice is shown (and again if the
|
|
338
|
+
* source was closed to save memory). `slices` says which slice of the current image it
|
|
339
|
+
* serves: one (default: the slice shown; plane 0 of the source), or `'planes'`, every slice z
|
|
340
|
+
* from plane z of a z-indexed source. Replaces the source those slices had.
|
|
341
|
+
*/
|
|
342
|
+
attachRegionSource(source: RegionSource | RegionSourceOpener, slices?: RegionSourceSlices): void;
|
|
343
|
+
/** Drop the current image's region sources (closing them) and what was taken from them. */
|
|
344
|
+
detachRegionSources(): void;
|
|
345
|
+
/**
|
|
346
|
+
* Drop the slice's region source, for regions imported in place of the slice's (a small file
|
|
347
|
+
* replacing a large one): a source of the slice's own is detached; a z-indexed source over every
|
|
348
|
+
* slice has this slice's features taken out (as deleted). The other slices keep theirs.
|
|
349
|
+
*/
|
|
350
|
+
dropSliceRegionSource(): Promise<void>;
|
|
351
|
+
/** Whether the slice shown has a region source. */
|
|
352
|
+
hasRegionSource(): boolean;
|
|
353
|
+
/** The slice's region source as a source layer draws it; null without one (or until it opens). */
|
|
354
|
+
getRegionSourceView(): RegionSourceView | null;
|
|
355
|
+
/** {@link getRegionSourceView} and every change of it (slice, taken ids, class colours). */
|
|
356
|
+
getRegionSourceView$(): Observable<RegionSourceView | null>;
|
|
357
|
+
/**
|
|
358
|
+
* Take source features into the working set for editing: their exact geometry becomes
|
|
359
|
+
* ordinary regions (minted, coloured and slice-tagged as any region entering the store) and
|
|
360
|
+
* the source stops drawing them. Not an undo step of its own — undoing past it puts the
|
|
361
|
+
* features back in the source. Resolves the region ids, in the order asked (a feature already
|
|
362
|
+
* taken resolves to its region); [] when the slice changed meanwhile.
|
|
363
|
+
*/
|
|
364
|
+
takeSourceFeatures(ids: readonly string[]): Promise<number[]>;
|
|
365
|
+
/** {@link takeSourceFeatures}, then select them (added to the selection with `additive`). */
|
|
366
|
+
selectSourceFeatures(ids: readonly string[], additive?: boolean): Promise<number[]>;
|
|
367
|
+
/**
|
|
368
|
+
* Features per class still in the slice's region source (not taken); {} without one. With
|
|
369
|
+
* `stack`, a z-stack's over every slice: its source's planes, or each slice's source added up.
|
|
370
|
+
*/
|
|
371
|
+
getRegionSourceClassCounts(stack?: boolean): Promise<Record<string, number>>;
|
|
372
|
+
/**
|
|
373
|
+
* Select every region of these classes on the slice — the regions', and the region source's,
|
|
374
|
+
* which are taken into the regions (at most {@link SELECT_CLASSES_LIMIT} of them). Added to the
|
|
375
|
+
* selection with `additive`. Resolves the selected region ids.
|
|
376
|
+
*/
|
|
377
|
+
selectClasses(classes: readonly string[], additive?: boolean): Promise<number[]>;
|
|
378
|
+
/**
|
|
379
|
+
* The 3D reconstruction of each group of classes over every slice of the stack (an atlas
|
|
380
|
+
* structure with its substructures, say): the outlines of the regions of those classes on every
|
|
381
|
+
* slice — the region sources' and those drawn or taken — stacked and meshed in a worker. Meshes
|
|
382
|
+
* are in image px (x, y) and slice indices (z). `pixelStep` is the in-plane voxel size (image
|
|
383
|
+
* px); the outlines are read at the matching level of detail. A group with no outline gets an
|
|
384
|
+
* empty mesh.
|
|
385
|
+
*/
|
|
386
|
+
reconstructClasses(groups: ReadonlyArray<{
|
|
387
|
+
key: string;
|
|
388
|
+
classes: readonly string[];
|
|
389
|
+
}>, pixelStep?: number): Promise<Array<{
|
|
390
|
+
key: string;
|
|
391
|
+
mesh: Mesh;
|
|
392
|
+
}>>;
|
|
393
|
+
/**
|
|
394
|
+
* Each class's volume over the whole stack, in px² × slices: its outlines' area on every slice
|
|
395
|
+
* (its features' union, see `outlinesArea`), one slice thick (Cavalieri's estimator), from the
|
|
396
|
+
* exact outlines. Where a feature is, a region source's or a drawn or taken region, does not
|
|
397
|
+
* change it: taking one leaves the volume as it was. The region sources' part is cached until
|
|
398
|
+
* what they hold changes (a feature taken or deleted, another source); only the slices with
|
|
399
|
+
* drawn or taken regions of the class are measured again.
|
|
400
|
+
*/
|
|
401
|
+
classVolumes(classes: readonly string[]): Promise<Map<string, number>>;
|
|
402
|
+
/** The region sources' part of a class's volume, cached by what they hold (see classVolumes). */
|
|
403
|
+
private sourceVolume;
|
|
404
|
+
/**
|
|
405
|
+
* Every slice's outlines of these classes, the region sources' then the regions': closed shapes'
|
|
406
|
+
* rings, and open polylines as `lines`.
|
|
407
|
+
*/
|
|
408
|
+
private classOutlines;
|
|
409
|
+
/**
|
|
410
|
+
* The region sources' outlines of these classes on every slice, without the features taken or
|
|
411
|
+
* deleted. The last few class sets are kept until what the sources hold changes: rebuilding a
|
|
412
|
+
* surface after an edit reads nothing again.
|
|
413
|
+
*/
|
|
414
|
+
private sourceOutlines;
|
|
415
|
+
private readSourceOutlines;
|
|
416
|
+
/**
|
|
417
|
+
* Every class's outlines on every slice, by class: the region sources' (one read for all, kept
|
|
418
|
+
* like {@link sourceOutlines}) and the drawn and taken regions'. What a section through the
|
|
419
|
+
* stack cuts (see `geometry/section`).
|
|
420
|
+
*/
|
|
421
|
+
outlinesByClass(level: number): Promise<Map<string, SliceOutlines[]>>;
|
|
422
|
+
/** The drawn and taken regions' outlines of these classes, by slice. */
|
|
423
|
+
private regionOutlines;
|
|
424
|
+
/** Each drawn or taken region's outlines (of the `wanted` classes; null: every class) with its class. */
|
|
425
|
+
private labelledRegionOutlines;
|
|
426
|
+
/** What the region sources of the image hold (see {@link sourceStateKey}): it changes when a
|
|
427
|
+
* feature is taken or deleted, or that is undone. */
|
|
428
|
+
getSourceStateKey(): string;
|
|
429
|
+
/**
|
|
430
|
+
* What the region sources of the image hold: the image, its sources (one attached or dropped
|
|
431
|
+
* bumps the version) and the features taken from them. A key for what is read from them.
|
|
432
|
+
*/
|
|
433
|
+
private sourceStateKey;
|
|
434
|
+
/** Delete source features without taking them (one undo step). */
|
|
435
|
+
deleteSourceFeatures(ids: readonly string[]): void;
|
|
436
|
+
/**
|
|
437
|
+
* A page of the slice source's features not taken from it (file order), e.g. for the Region
|
|
438
|
+
* Editor's list; an empty page without a source.
|
|
439
|
+
*/
|
|
440
|
+
getRegionSourceIndex(query: Omit<RegionIndexQuery, 'exclude'>): Promise<RegionIndexPage>;
|
|
441
|
+
/**
|
|
442
|
+
* `regions` as a GeoJSON FeatureCollection string merged with the region source behind them:
|
|
443
|
+
* the source's features that were not taken (or deleted), then `regions`. Without a source,
|
|
444
|
+
* {@link getGeoJsonString}. `slice` names a folder stack's slice (default the one shown);
|
|
445
|
+
* on a z-indexed stack's source (`'planes'`) the export spans every slice.
|
|
446
|
+
*/
|
|
447
|
+
getGeoJsonWithSource(regions: Region[], slice?: number): Promise<string>;
|
|
448
|
+
/**
|
|
449
|
+
* Whether a region of class `label` goes unlabelled because a subclass of it (by the region
|
|
450
|
+
* source's class hierarchy) is among the regions too — an atlas's "Isocortex" under its areas.
|
|
451
|
+
* False without a hierarchy.
|
|
452
|
+
*/
|
|
453
|
+
isLabelCovered(label: string | undefined): boolean;
|
|
454
|
+
private coveredFor;
|
|
455
|
+
/** The classes hidden from view (see {@link setClassesHidden}). */
|
|
456
|
+
getHiddenClasses(): ReadonlySet<string>;
|
|
457
|
+
/** {@link getHiddenClasses} and every change of it. */
|
|
458
|
+
getHiddenClasses$(): Observable<ReadonlySet<string>>;
|
|
459
|
+
/**
|
|
460
|
+
* Hide (or show again) these classes' regions: the overlays and the region source's layer stop
|
|
461
|
+
* drawing them, and a hidden region can be neither picked nor kept selected. The regions stay in
|
|
462
|
+
* the set (the table lists them; a save keeps them).
|
|
463
|
+
*/
|
|
464
|
+
setClassesHidden(classes: readonly string[], hidden: boolean): void;
|
|
465
|
+
/** Whether regions labelled `label` are hidden (an unlabelled region never is). */
|
|
466
|
+
isClassHidden(label: string | null | undefined): boolean;
|
|
467
|
+
/** The region look: outlines, or filled (an atlas's look); see `region-style`. */
|
|
468
|
+
getRegionStyle(): RegionStyle;
|
|
469
|
+
/** {@link getRegionStyle} and every change of it. */
|
|
470
|
+
getRegionStyle$(): Observable<RegionStyle>;
|
|
471
|
+
/**
|
|
472
|
+
* Choose the region look, field by field; it overrides a region source's hint for the session.
|
|
473
|
+
* The overlays redraw.
|
|
474
|
+
*/
|
|
475
|
+
setRegionStyle(patch: Partial<RegionStyle>): void;
|
|
476
|
+
/** The look now: the user's choice, else the source's hint, else outlines. */
|
|
477
|
+
private effectiveStyle;
|
|
478
|
+
/** Publish the look when it changed: the overlays redraw the regions, the source layer its features. */
|
|
479
|
+
private restyle;
|
|
480
|
+
/** Re-emit the source view with the current look and label setting. */
|
|
481
|
+
private republishView;
|
|
482
|
+
/** The slice a region source is keyed by: the display slice in stack mode, else 0. */
|
|
483
|
+
private get sourceSlice();
|
|
484
|
+
private currentTaken;
|
|
485
|
+
/** Replace the slice's taken ids and tell the source layers. */
|
|
486
|
+
private setTaken;
|
|
487
|
+
/**
|
|
488
|
+
* Look up (opening it if needed) the slice's source and publish it as the source view. The view
|
|
489
|
+
* is withdrawn at once: until the incoming source opens, nothing reads, takes or deletes from the
|
|
490
|
+
* outgoing one into the slice now shown.
|
|
491
|
+
*/
|
|
492
|
+
private refreshSourceView;
|
|
289
493
|
/**
|
|
290
494
|
* Switch the active image: snapshot the outgoing regions, restore the
|
|
291
495
|
* incoming image's (or [] if none), clear selection, and notify. Idempotent
|
|
@@ -36,6 +36,8 @@ export declare class VisualizerStore {
|
|
|
36
36
|
private readonly grayscale$;
|
|
37
37
|
private readonly invert$;
|
|
38
38
|
private presetSet;
|
|
39
|
+
/** Session-only class colours from imported files (see PresetSet.importedColors). */
|
|
40
|
+
private importedColors;
|
|
39
41
|
private readonly presetSet$;
|
|
40
42
|
private readonly savePresets$;
|
|
41
43
|
private presetsLoaded;
|
|
@@ -46,6 +48,8 @@ export declare class VisualizerStore {
|
|
|
46
48
|
private readonly spatialView$;
|
|
47
49
|
constructor(prefsPort?: PreferencesPort | null);
|
|
48
50
|
private initPresetPersistence;
|
|
51
|
+
/** Publish the preset set with this session's imported class colours. */
|
|
52
|
+
private emitPresetSet;
|
|
49
53
|
private normalizePresetSet;
|
|
50
54
|
/** Queue a debounced save. No-ops until the initial load resolves (and when no port is bound). */
|
|
51
55
|
private queuePresetSave;
|
|
@@ -114,6 +118,12 @@ export declare class VisualizerStore {
|
|
|
114
118
|
/** Upsert a single class colour (used by the editor's per-class colour picker). */
|
|
115
119
|
setClassificationColor(label: string, color: string): void;
|
|
116
120
|
getPresetSet(): PresetSet;
|
|
121
|
+
/**
|
|
122
|
+
* Remember the class colours an imported file carried (label → colour), so its regions keep
|
|
123
|
+
* them: a class with a preset keeps the preset's colour, and the latest import wins for the
|
|
124
|
+
* rest. Not persisted.
|
|
125
|
+
*/
|
|
126
|
+
rememberImportedClassColors(colors: ReadonlyMap<string, string>): void;
|
|
117
127
|
getPresetSet$(): Observable<PresetSet>;
|
|
118
128
|
setPresetSet(set: PresetSet): void;
|
|
119
129
|
/** Add or update a class (keyed by exact stored `name`). */
|
|
@@ -12,6 +12,8 @@ export declare class RegionToolsComponent {
|
|
|
12
12
|
activeDragMode: string | null;
|
|
13
13
|
/** The 3D cloud's screen-space lasso: no brush or polyline. */
|
|
14
14
|
is3dRegions: boolean;
|
|
15
|
+
/** Only the selection tool (a volume view: it picks the regions' surfaces in 3D). */
|
|
16
|
+
selectOnly: boolean;
|
|
15
17
|
/** The backend has a vertex-editing overlay (OSD + napari-js image). */
|
|
16
18
|
vertexTools: boolean;
|
|
17
19
|
/** Magic-wand sensitivity (the wand's slider value). */
|
|
@@ -56,5 +58,5 @@ export declare class RegionToolsComponent {
|
|
|
56
58
|
/** A single slider's value (a range slider never feeds these). */
|
|
57
59
|
protected asNumber(v: number | number[] | undefined): number | undefined;
|
|
58
60
|
static ɵfac: i0.ɵɵFactoryDeclaration<RegionToolsComponent, never>;
|
|
59
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<RegionToolsComponent, "toolbar-region-tools", never, { "activeDragMode": { "alias": "activeDragMode"; "required": false; }; "is3dRegions": { "alias": "is3dRegions"; "required": false; }; "vertexTools": { "alias": "vertexTools"; "required": false; }; "wandSensitivity": { "alias": "wandSensitivity"; "required": false; }; "brushSize": { "alias": "brushSize"; "required": false; }; "vertexEraserRadius": { "alias": "vertexEraserRadius"; "required": false; }; "canUndo": { "alias": "canUndo"; "required": false; }; "canRedo": { "alias": "canRedo"; "required": false; }; }, { "openRegionEditor": "openRegionEditor"; "toggleDragMode": "toggleDragMode"; "undoRegion": "undoRegion"; "redoRegion": "redoRegion"; "deleteRegion": "deleteRegion"; "wandSensitivityChange": "wandSensitivityChange"; "brushSizeChange": "brushSizeChange"; "vertexEraserRadiusChange": "vertexEraserRadiusChange"; }, never, never, true, never>;
|
|
61
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<RegionToolsComponent, "toolbar-region-tools", never, { "activeDragMode": { "alias": "activeDragMode"; "required": false; }; "is3dRegions": { "alias": "is3dRegions"; "required": false; }; "selectOnly": { "alias": "selectOnly"; "required": false; }; "vertexTools": { "alias": "vertexTools"; "required": false; }; "wandSensitivity": { "alias": "wandSensitivity"; "required": false; }; "brushSize": { "alias": "brushSize"; "required": false; }; "vertexEraserRadius": { "alias": "vertexEraserRadius"; "required": false; }; "canUndo": { "alias": "canUndo"; "required": false; }; "canRedo": { "alias": "canRedo"; "required": false; }; }, { "openRegionEditor": "openRegionEditor"; "toggleDragMode": "toggleDragMode"; "undoRegion": "undoRegion"; "redoRegion": "redoRegion"; "deleteRegion": "deleteRegion"; "wandSensitivityChange": "wandSensitivityChange"; "brushSizeChange": "brushSizeChange"; "vertexEraserRadiusChange": "vertexEraserRadiusChange"; }, never, never, true, never>;
|
|
60
62
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EventEmitter } from '@angular/core';
|
|
1
|
+
import { EventEmitter, OnDestroy } from '@angular/core';
|
|
2
2
|
import * as i0 from "@angular/core";
|
|
3
3
|
/** A stack-mode choice (`val` 'false' = single image, 'true' = stack). */
|
|
4
4
|
export interface StackOption {
|
|
@@ -6,11 +6,11 @@ export interface StackOption {
|
|
|
6
6
|
val: string;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
* The toolbar's z-stack group:
|
|
10
|
-
* slices in place
|
|
11
|
-
*
|
|
9
|
+
* The toolbar's z-stack group: the slice bar, and (Plotly heatmap) the single-image / stack
|
|
10
|
+
* toggle. The views that swap slices in place follow the bar as it moves; the heatmap's single
|
|
11
|
+
* image is re-plotted at the slice it settles on. Presentational: the host owns `zIndex`.
|
|
12
12
|
*/
|
|
13
|
-
export declare class StackControlsComponent {
|
|
13
|
+
export declare class StackControlsComponent implements OnDestroy {
|
|
14
14
|
/** Show the live slice scrubber. */
|
|
15
15
|
liveScrubber: boolean;
|
|
16
16
|
/** Show the single-image / stack toggle (Plotly heatmap). */
|
|
@@ -29,12 +29,23 @@ export declare class StackControlsComponent {
|
|
|
29
29
|
zSlide: EventEmitter<number | undefined>;
|
|
30
30
|
/** A stack-mode choice was picked. */
|
|
31
31
|
selectStackOption: EventEmitter<StackOption>;
|
|
32
|
-
/**
|
|
32
|
+
/** The heatmap's slice bar moved to a slice (the host shows its number). */
|
|
33
33
|
zIndexInput: EventEmitter<number>;
|
|
34
|
-
/**
|
|
34
|
+
/** The heatmap's slice bar settled: re-plot at that slice. */
|
|
35
35
|
reloadAndPlot: EventEmitter<void>;
|
|
36
|
-
/**
|
|
37
|
-
|
|
36
|
+
/** How long key steps on the heatmap's bar pause before the slice is re-plotted. */
|
|
37
|
+
static readonly REPLOT_DELAY_MS = 400;
|
|
38
|
+
/** A drag of the bar is under way (its end re-plots the heatmap, not each step). */
|
|
39
|
+
protected dragging: boolean;
|
|
40
|
+
private replot;
|
|
41
|
+
/** The heatmap in single-image mode: its bar re-plots the slice it settles on. */
|
|
42
|
+
protected get singleImage(): boolean;
|
|
43
|
+
/** The bar moved: a live view follows it; the heatmap shows the number, and re-plots after key steps pause. */
|
|
44
|
+
protected onSliceChange(z: number | undefined): void;
|
|
45
|
+
/** The bar was let go (a drag's end, or a click on its track). */
|
|
46
|
+
protected onSliceEnd(z: number | undefined): void;
|
|
47
|
+
private cancelReplot;
|
|
48
|
+
ngOnDestroy(): void;
|
|
38
49
|
static ɵfac: i0.ɵɵFactoryDeclaration<StackControlsComponent, never>;
|
|
39
50
|
static ɵcmp: i0.ɵɵComponentDeclaration<StackControlsComponent, "toolbar-stack-controls", never, { "liveScrubber": { "alias": "liveScrubber"; "required": false; }; "stackToggle": { "alias": "stackToggle"; "required": false; }; "showStack": { "alias": "showStack"; "required": false; }; "stackOptions": { "alias": "stackOptions"; "required": false; }; "zIndex": { "alias": "zIndex"; "required": false; }; "maxIndex": { "alias": "maxIndex"; "required": false; }; }, { "zScrub": "zScrub"; "zSlide": "zSlide"; "selectStackOption": "selectStackOption"; "zIndexInput": "zIndexInput"; "reloadAndPlot": "reloadAndPlot"; }, never, never, true, never>;
|
|
40
51
|
}
|
|
@@ -52,6 +52,10 @@ export declare class ToolbarComponent {
|
|
|
52
52
|
* controls — flipping that would show 2D pan/zoom and hide the orbit controls.
|
|
53
53
|
*/
|
|
54
54
|
is3dRegions: boolean;
|
|
55
|
+
/** A napari volume / isosurface view: the Region Editor (regions in 3D) without drawing tools. */
|
|
56
|
+
isVolumeView: boolean;
|
|
57
|
+
/** Whether the volume view is split with the slice editor (the slice, with every region tool). */
|
|
58
|
+
sliceEditor: boolean;
|
|
55
59
|
/** The armed tool's mode (zoom, pan, a drawing tool, `samPoint`, …), or null. */
|
|
56
60
|
activeDragMode: string | null;
|
|
57
61
|
/** The 3D camera mode (`turntable` / `orbit` / …). */
|
|
@@ -118,6 +122,8 @@ export declare class ToolbarComponent {
|
|
|
118
122
|
openSpatialControls: EventEmitter<void>;
|
|
119
123
|
/** Open the Region Editor dialog. */
|
|
120
124
|
openRegionEditor: EventEmitter<void>;
|
|
125
|
+
/** Split the volume view with the slice editor, or close it. */
|
|
126
|
+
toggleSliceEditor: EventEmitter<void>;
|
|
121
127
|
/** A single-image / stack choice was picked. */
|
|
122
128
|
selectStackOption: EventEmitter<{
|
|
123
129
|
name: string;
|
|
@@ -202,7 +208,8 @@ export declare class ToolbarComponent {
|
|
|
202
208
|
* view, the napari-js WebGPU image, the napari-js surface — which rebuilds the height field
|
|
203
209
|
* from the picked slice (jit-ui#102) — and the 2D spatial-omics view, where a 3D dataset's
|
|
204
210
|
* registered volume is the image and the slider picks the section whose observations are
|
|
205
|
-
* drawn.
|
|
211
|
+
* drawn. Also a split volume view, whose slice editor shows the slice picked. Drives the
|
|
212
|
+
* per-slice slider. */
|
|
206
213
|
protected get showsLiveSliceScrubber(): boolean;
|
|
207
214
|
/** Any napari-js WebGPU plot type. The single-image/stack toggle + slice-number field are
|
|
208
215
|
* Plotly-only stack controls, so they're hidden for napari (jit-ui#102). */
|
|
@@ -218,5 +225,5 @@ export declare class ToolbarComponent {
|
|
|
218
225
|
protected get isIntensityCapable(): boolean;
|
|
219
226
|
protected showHelp(): void;
|
|
220
227
|
static ɵfac: i0.ɵɵFactoryDeclaration<ToolbarComponent, never>;
|
|
221
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<ToolbarComponent, "plotting-toolbar", never, { "imageInfo": { "alias": "imageInfo"; "required": false; }; "hasSpatialDataset": { "alias": "hasSpatialDataset"; "required": false; }; "plotTypeOptions": { "alias": "plotTypeOptions"; "required": false; }; "selectedPlotType": { "alias": "selectedPlotType"; "required": false; }; "basePlotType": { "alias": "basePlotType"; "required": false; }; "isoRange": { "alias": "isoRange"; "required": false; }; "maxIndex": { "alias": "maxIndex"; "required": false; }; "zIndex": { "alias": "zIndex"; "required": false; }; "isHeatmap": { "alias": "isHeatmap"; "required": false; }; "is3dRegions": { "alias": "is3dRegions"; "required": false; }; "activeDragMode": { "alias": "activeDragMode"; "required": false; }; "activeSurface3dMode": { "alias": "activeSurface3dMode"; "required": false; }; "axesVisible": { "alias": "axesVisible"; "required": false; }; "wireframeActive": { "alias": "wireframeActive"; "required": false; }; "resolutionScale": { "alias": "resolutionScale"; "required": false; }; "wandSensitivity": { "alias": "wandSensitivity"; "required": false; }; "brushSize": { "alias": "brushSize"; "required": false; }; "vertexEraserRadius": { "alias": "vertexEraserRadius"; "required": false; }; "canUndo": { "alias": "canUndo"; "required": false; }; "canRedo": { "alias": "canRedo"; "required": false; }; "stackOptions": { "alias": "stackOptions"; "required": false; }; "tools": { "alias": "tools"; "required": false; }; "imageSmoothingEnabled": { "alias": "imageSmoothingEnabled"; "required": false; }; "samModels": { "alias": "samModels"; "required": false; }; "samModelId": { "alias": "samModelId"; "required": false; }; "contributedTools": { "alias": "contributedTools"; "required": false; }; "dialogTools": { "alias": "dialogTools"; "required": false; }; "openDialogToolId": { "alias": "openDialogToolId"; "required": false; }; "toolModelIds": { "alias": "toolModelIds"; "required": false; }; }, { "selectPlotType": "selectPlotType"; "addProfileLine": "addProfileLine"; "toggleImageSmoothing": "toggleImageSmoothing"; "isoRangeChange": "isoRangeChange"; "openChannelHistogram": "openChannelHistogram"; "openSpatialControls": "openSpatialControls"; "openRegionEditor": "openRegionEditor"; "selectStackOption": "selectStackOption"; "zScrub": "zScrub"; "zSlide": "zSlide"; "zIndexInput": "zIndexInput"; "reloadAndPlot": "reloadAndPlot"; "downloadImage": "downloadImage"; "autoscaleImage": "autoscaleImage"; "toggleDragMode": "toggleDragMode"; "zoomIn": "zoomIn"; "zoomOut": "zoomOut"; "toggleSurface3dMode": "toggleSurface3dMode"; "resetSurfaceCamera": "resetSurfaceCamera"; "toggleAxes": "toggleAxes"; "toggleWireframe": "toggleWireframe"; "selectResolution": "selectResolution"; "deleteRegion": "deleteRegion"; "undoRegion": "undoRegion"; "redoRegion": "redoRegion"; "segmentRegions": "segmentRegions"; "segmentCellpose": "segmentCellpose"; "runTool": "runTool"; "toggleDialogTool": "toggleDialogTool"; "toolModelChange": "toolModelChange"; "openToolParams": "openToolParams"; "samModelChange": "samModelChange"; "wandSensitivityChange": "wandSensitivityChange"; "brushSizeChange": "brushSizeChange"; "vertexEraserRadiusChange": "vertexEraserRadiusChange"; }, never, ["*"], true, never>;
|
|
228
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ToolbarComponent, "plotting-toolbar", never, { "imageInfo": { "alias": "imageInfo"; "required": false; }; "hasSpatialDataset": { "alias": "hasSpatialDataset"; "required": false; }; "plotTypeOptions": { "alias": "plotTypeOptions"; "required": false; }; "selectedPlotType": { "alias": "selectedPlotType"; "required": false; }; "basePlotType": { "alias": "basePlotType"; "required": false; }; "isoRange": { "alias": "isoRange"; "required": false; }; "maxIndex": { "alias": "maxIndex"; "required": false; }; "zIndex": { "alias": "zIndex"; "required": false; }; "isHeatmap": { "alias": "isHeatmap"; "required": false; }; "is3dRegions": { "alias": "is3dRegions"; "required": false; }; "isVolumeView": { "alias": "isVolumeView"; "required": false; }; "sliceEditor": { "alias": "sliceEditor"; "required": false; }; "activeDragMode": { "alias": "activeDragMode"; "required": false; }; "activeSurface3dMode": { "alias": "activeSurface3dMode"; "required": false; }; "axesVisible": { "alias": "axesVisible"; "required": false; }; "wireframeActive": { "alias": "wireframeActive"; "required": false; }; "resolutionScale": { "alias": "resolutionScale"; "required": false; }; "wandSensitivity": { "alias": "wandSensitivity"; "required": false; }; "brushSize": { "alias": "brushSize"; "required": false; }; "vertexEraserRadius": { "alias": "vertexEraserRadius"; "required": false; }; "canUndo": { "alias": "canUndo"; "required": false; }; "canRedo": { "alias": "canRedo"; "required": false; }; "stackOptions": { "alias": "stackOptions"; "required": false; }; "tools": { "alias": "tools"; "required": false; }; "imageSmoothingEnabled": { "alias": "imageSmoothingEnabled"; "required": false; }; "samModels": { "alias": "samModels"; "required": false; }; "samModelId": { "alias": "samModelId"; "required": false; }; "contributedTools": { "alias": "contributedTools"; "required": false; }; "dialogTools": { "alias": "dialogTools"; "required": false; }; "openDialogToolId": { "alias": "openDialogToolId"; "required": false; }; "toolModelIds": { "alias": "toolModelIds"; "required": false; }; }, { "selectPlotType": "selectPlotType"; "addProfileLine": "addProfileLine"; "toggleImageSmoothing": "toggleImageSmoothing"; "isoRangeChange": "isoRangeChange"; "openChannelHistogram": "openChannelHistogram"; "openSpatialControls": "openSpatialControls"; "openRegionEditor": "openRegionEditor"; "toggleSliceEditor": "toggleSliceEditor"; "selectStackOption": "selectStackOption"; "zScrub": "zScrub"; "zSlide": "zSlide"; "zIndexInput": "zIndexInput"; "reloadAndPlot": "reloadAndPlot"; "downloadImage": "downloadImage"; "autoscaleImage": "autoscaleImage"; "toggleDragMode": "toggleDragMode"; "zoomIn": "zoomIn"; "zoomOut": "zoomOut"; "toggleSurface3dMode": "toggleSurface3dMode"; "resetSurfaceCamera": "resetSurfaceCamera"; "toggleAxes": "toggleAxes"; "toggleWireframe": "toggleWireframe"; "selectResolution": "selectResolution"; "deleteRegion": "deleteRegion"; "undoRegion": "undoRegion"; "redoRegion": "redoRegion"; "segmentRegions": "segmentRegions"; "segmentCellpose": "segmentCellpose"; "runTool": "runTool"; "toggleDialogTool": "toggleDialogTool"; "toolModelChange": "toolModelChange"; "openToolParams": "openToolParams"; "samModelChange": "samModelChange"; "wandSensitivityChange": "wandSensitivityChange"; "brushSizeChange": "brushSizeChange"; "vertexEraserRadiusChange": "vertexEraserRadiusChange"; }, never, ["*"], true, never>;
|
|
222
229
|
}
|
|
@@ -1,7 +1,18 @@
|
|
|
1
|
+
import type { HttpClient } from '@angular/common/http';
|
|
1
2
|
import { IImageInfo } from '../contracts/image.contract';
|
|
2
3
|
import { IRegionStore } from '../contracts/visualizer.contract';
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
import { RegionSource } from '../region-source/region-source';
|
|
5
|
+
import type { RegionSourceOpener, RegionSourceSlices } from '../store/region-source-scope';
|
|
6
|
+
/** The region-store members {@link applyImageRois} writes through. A target without
|
|
7
|
+
* `attachRegionSource` loads every ROI file as regions. */
|
|
8
|
+
export type RegionLoadTarget = Pick<IRegionStore, 'importRegions' | 'enterStackMode' | 'setRegions' | 'resetUndoHistory'> & {
|
|
9
|
+
attachRegionSource?(source: RegionSource | RegionSourceOpener, slices?: RegionSourceSlices): void;
|
|
10
|
+
/** The slice shown now (what a stack's source, laid out once it opens, makes live). */
|
|
11
|
+
getDisplaySlice?(): number;
|
|
12
|
+
/** Record the slice shown (outside stack mode it only records it): see {@link applyImageRois}. */
|
|
13
|
+
setDisplaySlice?(z: number): void;
|
|
14
|
+
isStackMode?(): boolean;
|
|
15
|
+
};
|
|
5
16
|
/**
|
|
6
17
|
* Apply an image's saved ROIs once its render has landed, choosing the region
|
|
7
18
|
* layout from the image's shape:
|
|
@@ -22,6 +33,14 @@ export type RegionLoadTarget = Pick<IRegionStore, 'importRegions' | 'enterStackM
|
|
|
22
33
|
* Loading saved ROIs is not a user edit, so the undo history starts fresh and the
|
|
23
34
|
* first undo cannot wipe them (jit-ui#85).
|
|
24
35
|
*
|
|
25
|
-
*
|
|
36
|
+
* Large ROI files (`minSourceChars` and up) and a server-side source (`regionSourceUrl`)
|
|
37
|
+
* become tiled region sources instead of regions; a z-indexed one serves each slice its own
|
|
38
|
+
* plane. On a single-file stack the source is opened first, to tell which: one on the default
|
|
39
|
+
* plane only stays global, as its regions would. A folder stack's sources open lazily, the first
|
|
40
|
+
* time their slice is shown.
|
|
41
|
+
*
|
|
42
|
+
* `z` is the slice shown now; entering stack mode makes it live and resets undo. `http`, the
|
|
43
|
+
* host's `HttpClient`, carries a server-side source's requests, so the host's interceptors (its
|
|
44
|
+
* auth) apply to them as to the image tiles.
|
|
26
45
|
*/
|
|
27
|
-
export declare function applyImageRois(info: IImageInfo, target: RegionLoadTarget, z: number): void;
|
|
46
|
+
export declare function applyImageRois(info: IImageInfo, target: RegionLoadTarget, z: number, minSourceChars?: number, http?: HttpClient): void;
|