@jax-data-science/sci-image-visualizer 0.4.0 → 0.5.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/README.md +60 -0
- package/esm2022/index.mjs +2 -1
- package/esm2022/lib/contracts/plot-type-contribution.contract.mjs +66 -0
- package/esm2022/lib/contracts/plot-type.mjs +6 -1
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +69 -6
- package/esm2022/lib/implementations/osd/osd-coordinate-transform.mjs +8 -1
- package/esm2022/lib/plot-mode/plot-mode-controller.mjs +329 -0
- package/esm2022/lib/routing-visualizer.service.mjs +6 -1
- package/esm2022/lib/toolbar/toolbar.component.mjs +37 -20
- package/esm2022/lib/visualizer.component.mjs +262 -40
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +772 -62
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/lib/contracts/plot-type-contribution.contract.d.ts +172 -0
- package/lib/contracts/plot-type.d.ts +10 -0
- package/lib/contracts/visualizer.contract.d.ts +5 -0
- package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +21 -0
- package/lib/implementations/osd/osd-coordinate-transform.d.ts +6 -0
- package/lib/plot-mode/plot-mode-controller.d.ts +130 -0
- package/lib/routing-visualizer.service.d.ts +4 -0
- package/lib/toolbar/toolbar.component.d.ts +18 -6
- package/lib/visualizer.component.d.ts +68 -7
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export * from './lib/contracts/image.contract';
|
|
|
19
19
|
export * from './lib/contracts/plot-type';
|
|
20
20
|
export * from './lib/contracts/toolbar-config';
|
|
21
21
|
export * from './lib/contracts/toolbar-tool.contract';
|
|
22
|
+
export * from './lib/contracts/plot-type-contribution.contract';
|
|
22
23
|
export * from './lib/contracts/capabilities.contract';
|
|
23
24
|
export * from './lib/contracts/region-overlay.contract';
|
|
24
25
|
export * from './lib/contracts/display-types';
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a plot mode gets into the plot-type selector without this library knowing
|
|
3
|
+
* what it is.
|
|
4
|
+
*
|
|
5
|
+
* A package contributes a mode by providing a {@link PlotTypeContribution} on the
|
|
6
|
+
* {@link PLOT_TYPE_CONTRIBUTIONS} multi-provider token, the same way
|
|
7
|
+
* `TOOLBAR_TOOLS` contributes toolbar tools. Nothing registers at import time:
|
|
8
|
+
* installing a package makes a mode available, and adding its provider turns it
|
|
9
|
+
* on. A plain object works, so the contributing package needs no Angular
|
|
10
|
+
* compiler and no decorators:
|
|
11
|
+
*
|
|
12
|
+
* { provide: PLOT_TYPE_CONTRIBUTIONS, useValue: myContribution, multi: true }
|
|
13
|
+
* { provide: PLOT_TYPE_CONTRIBUTIONS, useFactory: () => makeContribution(), multi: true }
|
|
14
|
+
*
|
|
15
|
+
* Provide nothing and the selector, the render path and the panel area behave
|
|
16
|
+
* exactly as they did before this extension point existed.
|
|
17
|
+
*
|
|
18
|
+
* WHY A CONTRIBUTED MODE RIDES ON A BUILT-IN ONE
|
|
19
|
+
* A contributed mode does not bring a renderer. It names a built-in
|
|
20
|
+
* {@link ContributedPlotTypeDescriptor.baseType} — in v1 only `PlotType.IMAGE`,
|
|
21
|
+
* the OpenSeadragon view — and the visualizer plots exactly as if that type had
|
|
22
|
+
* been selected: same backend, same toolbar, same region tools, same wheel
|
|
23
|
+
* handling. The contribution then draws over it through the
|
|
24
|
+
* {@link PlotModeViewport} and talks to the viewer through the public
|
|
25
|
+
* {@link IVisualizer}. That keeps every rendering decision in one place and means
|
|
26
|
+
* a contribution can never be half-supported by some code path that switches on
|
|
27
|
+
* the plot type.
|
|
28
|
+
*
|
|
29
|
+
* WHAT THE VISUALIZER GUARANTEES
|
|
30
|
+
* 1. Contributed descriptors are appended after the built-in ones and curated by
|
|
31
|
+
* the same `productionLabel` / test-mode / `requires*` rules.
|
|
32
|
+
* 2. Selecting one plots with `baseType`'s backend, then calls `activate(ctx)`
|
|
33
|
+
* once the viewport is ready.
|
|
34
|
+
* 3. Leaving the mode — another type, an image switch (or any re-render of the
|
|
35
|
+
* base view), or the visualizer being destroyed — calls `session.deactivate()`
|
|
36
|
+
* exactly once, before the next mode draws. If the mode is still selected
|
|
37
|
+
* when the new image has plotted, a fresh session is activated for it.
|
|
38
|
+
* 4. `panel` is shown only while a session is live.
|
|
39
|
+
* 5. A thrown error or rejected promise from `activate`, `deactivate`, `mount`
|
|
40
|
+
* or a mount's teardown is caught and logged; none escapes, so a contribution
|
|
41
|
+
* cannot break the viewer. Failing to start (`activate`, `mount`, or a panel
|
|
42
|
+
* component throwing while it is created / first rendered) falls back
|
|
43
|
+
* to `baseType`. Failing to clean up falls back when that same mode is being
|
|
44
|
+
* re-activated (base re-render, image switch) — immediately if it already is
|
|
45
|
+
* live again — and is only logged when the user has moved to another mode; the
|
|
46
|
+
* user explicitly selecting it again gets a fresh attempt.
|
|
47
|
+
* 6. {@link PLOT_TYPE_CONTRIBUTIONS} has no factory: no providers, no modes.
|
|
48
|
+
*/
|
|
49
|
+
import { InjectionToken, Type } from '@angular/core';
|
|
50
|
+
import type { Observable } from 'rxjs';
|
|
51
|
+
import type { IImageInfo } from './image.contract';
|
|
52
|
+
import type { PlotType, PlotTypeDescriptor, PlotTypeId } from './plot-type';
|
|
53
|
+
import type { IVisualizer } from './visualizer.contract';
|
|
54
|
+
/** A rectangle in level-0 image pixels. */
|
|
55
|
+
export interface PlotModeRect {
|
|
56
|
+
x: number;
|
|
57
|
+
y: number;
|
|
58
|
+
width: number;
|
|
59
|
+
height: number;
|
|
60
|
+
}
|
|
61
|
+
/** Selector metadata for a contributed plot mode. */
|
|
62
|
+
export interface ContributedPlotTypeDescriptor {
|
|
63
|
+
/** Unique id, namespaced, e.g. 'dianne'. Must not clash with PlotType values. */
|
|
64
|
+
type: string;
|
|
65
|
+
/** Test-mode label, e.g. 'Digital Pathology - DIANNE'. */
|
|
66
|
+
label: string;
|
|
67
|
+
/** Default-selector label; omit to make the mode test-only (same rule as built-ins). */
|
|
68
|
+
productionLabel?: string;
|
|
69
|
+
/** 'pi pi-…' class or asset path, same as PlotTypeDescriptor.icon. */
|
|
70
|
+
icon?: string;
|
|
71
|
+
/** Always '2d' in v1. */
|
|
72
|
+
dimensions: '2d';
|
|
73
|
+
/** Built-in type whose backend renders the base image. v1 supports PlotType.IMAGE (OSD). */
|
|
74
|
+
baseType: PlotType;
|
|
75
|
+
/** Same gates as PlotTypeDescriptor, evaluated in addition to the base type's own. */
|
|
76
|
+
requiresGrayscale?: boolean;
|
|
77
|
+
requiresStack?: boolean;
|
|
78
|
+
/** Hidden until a `SpatialDataset` is published on SPATIAL_DATA_PORT (an overlay of spatial observations). */
|
|
79
|
+
requiresSpatialData?: boolean;
|
|
80
|
+
/** Hidden unless the published dataset carries `observations.z`. */
|
|
81
|
+
requiresSpatial3d?: boolean;
|
|
82
|
+
}
|
|
83
|
+
/** The base view's viewport, as a contributed mode sees it. */
|
|
84
|
+
export interface PlotModeViewport {
|
|
85
|
+
/** Element the mode's overlay canvas/SVG attaches to; fills the plot area. */
|
|
86
|
+
getOverlayContainer(): HTMLElement | null;
|
|
87
|
+
/** Level-0 image px -> client px, and the reverse. */
|
|
88
|
+
dataToClient(x: number, y: number): {
|
|
89
|
+
x: number;
|
|
90
|
+
y: number;
|
|
91
|
+
};
|
|
92
|
+
clientToData(clientX: number, clientY: number): {
|
|
93
|
+
x: number;
|
|
94
|
+
y: number;
|
|
95
|
+
};
|
|
96
|
+
/** Screen px per image px at the current zoom. */
|
|
97
|
+
dataLengthToScreen(len: number): number;
|
|
98
|
+
isReady(): boolean;
|
|
99
|
+
/** Visible image rect in level-0 px, emitted on every redraw frame (pan/zoom animation).
|
|
100
|
+
* A new subscriber first receives the current rect when the viewport is ready. */
|
|
101
|
+
frame$: Observable<PlotModeRect>;
|
|
102
|
+
/** Same rect, emitted once the viewport settles (existing getViewportChange$ semantics).
|
|
103
|
+
* A new subscriber first receives the current rect when the viewport is ready. */
|
|
104
|
+
settled$: Observable<PlotModeRect>;
|
|
105
|
+
}
|
|
106
|
+
/** Everything a contributed mode gets to work with while it is active. */
|
|
107
|
+
export interface PlotModeContext {
|
|
108
|
+
/** Full public visualizer API: regions, region overlay (tool modes), undo, etc. */
|
|
109
|
+
visualizer: IVisualizer;
|
|
110
|
+
viewport: PlotModeViewport;
|
|
111
|
+
/** Current image info from IMAGE_STATE_PORT (null until an image is loaded). */
|
|
112
|
+
imageInfo$: Observable<IImageInfo | null>;
|
|
113
|
+
}
|
|
114
|
+
/** A live activation of a contributed mode. */
|
|
115
|
+
export interface PlotModeSession {
|
|
116
|
+
/** Called when the user leaves the mode, the image changes, or the visualizer is destroyed. */
|
|
117
|
+
deactivate(): void;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* The mode's side panel, shown in the visualizer's right-hand panel area while
|
|
121
|
+
* a session is live. Two forms:
|
|
122
|
+
*
|
|
123
|
+
* - `component`: an Angular component, rendered through `NgComponentOutlet`
|
|
124
|
+
* with {@link PLOT_MODE_CONTEXT} and {@link PLOT_MODE_SESSION} in its
|
|
125
|
+
* injector. Needs an AOT-compiled (partial-Ivy) component.
|
|
126
|
+
* - `mount`: framework-agnostic. The visualizer hands over an empty host
|
|
127
|
+
* element after `activate` resolves; the function renders into it and returns
|
|
128
|
+
* a teardown. The teardown is called exactly once when the mode deactivates,
|
|
129
|
+
* before `session.deactivate()`, and the host element is then removed.
|
|
130
|
+
*/
|
|
131
|
+
export type PlotModePanel = {
|
|
132
|
+
title: string;
|
|
133
|
+
component: Type<unknown>;
|
|
134
|
+
} | {
|
|
135
|
+
title: string;
|
|
136
|
+
mount(host: HTMLElement, ctx: PlotModeContext, session: PlotModeSession): () => void;
|
|
137
|
+
};
|
|
138
|
+
/** A plot mode contributed to the selector. A plain object is enough. */
|
|
139
|
+
export interface PlotTypeContribution {
|
|
140
|
+
descriptor: ContributedPlotTypeDescriptor;
|
|
141
|
+
/** Called after the base backend has plotted the image in this mode. */
|
|
142
|
+
activate(ctx: PlotModeContext): PlotModeSession | Promise<PlotModeSession>;
|
|
143
|
+
/**
|
|
144
|
+
* Optional side panel, rendered in the visualizer's right-hand panel area while the
|
|
145
|
+
* mode is active. A component panel can inject PLOT_MODE_CONTEXT and PLOT_MODE_SESSION.
|
|
146
|
+
*/
|
|
147
|
+
panel?: PlotModePanel;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Multi-provider token for contributed plot modes.
|
|
151
|
+
*
|
|
152
|
+
* Deliberately has no `factory`: unregistered means no contributed modes, and the
|
|
153
|
+
* library behaves exactly as before. The visualizer injects it `{ optional: true }`
|
|
154
|
+
* and treats null as empty.
|
|
155
|
+
*/
|
|
156
|
+
export declare const PLOT_TYPE_CONTRIBUTIONS: InjectionToken<readonly PlotTypeContribution[]>;
|
|
157
|
+
/** The active mode's context, in a component panel's injector. */
|
|
158
|
+
export declare const PLOT_MODE_CONTEXT: InjectionToken<PlotModeContext>;
|
|
159
|
+
/** The active mode's session, in a component panel's injector. */
|
|
160
|
+
export declare const PLOT_MODE_SESSION: InjectionToken<PlotModeSession>;
|
|
161
|
+
/**
|
|
162
|
+
* One entry in the plot-type selector: a built-in {@link PlotTypeDescriptor}
|
|
163
|
+
* as-is, or a contributed descriptor completed with its base type's `source`.
|
|
164
|
+
* Every entry therefore carries the same fields the selector curates by.
|
|
165
|
+
*/
|
|
166
|
+
export interface PlotTypeOption extends Omit<PlotTypeDescriptor, 'type'> {
|
|
167
|
+
type: PlotTypeId;
|
|
168
|
+
/** Set only for a contributed mode: the built-in type that renders it. */
|
|
169
|
+
baseType?: PlotType;
|
|
170
|
+
}
|
|
171
|
+
/** The selector entry for a contributed mode, given its base type's descriptor. */
|
|
172
|
+
export declare function contributedPlotTypeOption(d: ContributedPlotTypeDescriptor, base: PlotTypeDescriptor): PlotTypeOption;
|
|
@@ -42,6 +42,16 @@ export declare enum PlotType {
|
|
|
42
42
|
* {@link SPATIAL_OMICS}: a single-plane dataset has no z to render. */
|
|
43
43
|
SPATIAL_OMICS_3D = "spatial-omics-3d"
|
|
44
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* A value the plot-type selector can hold: a built-in {@link PlotType}, or the
|
|
47
|
+
* `type` of a contributed mode (`ContributedPlotTypeDescriptor.type`, see
|
|
48
|
+
* `plot-type-contribution.contract.ts`). Everything that decides HOW to render
|
|
49
|
+
* keeps taking a {@link PlotType}; a contributed id is resolved to its
|
|
50
|
+
* `baseType` first, so no rendering switch ever sees one.
|
|
51
|
+
*/
|
|
52
|
+
export type PlotTypeId = PlotType | string;
|
|
53
|
+
/** Whether an id names a built-in plot type (as opposed to a contributed one). */
|
|
54
|
+
export declare function isBuiltinPlotType(id: PlotTypeId | null | undefined): id is PlotType;
|
|
45
55
|
/** How many spatial dimensions a plot type renders in. */
|
|
46
56
|
export type PlotDimensions = '2d' | '3d';
|
|
47
57
|
/**
|
|
@@ -10,6 +10,7 @@ import { IHistogram } from './channel-histogram-api.contract';
|
|
|
10
10
|
import { ColormapNode, IWandOptions, IBrushOptions, SpatialViewState, SpatialColorBy } from './display-types';
|
|
11
11
|
import { SpatialDataset, SpatialEmbedding } from './spatial-dataset.contract';
|
|
12
12
|
import { SpatialSelectionMask } from '../spatial/spatial-selection';
|
|
13
|
+
import type { PlotModeViewport } from './plot-type-contribution.contract';
|
|
13
14
|
/**
|
|
14
15
|
* Backend-neutral visualization contract. Plotly is one implementation;
|
|
15
16
|
* OpenSeadragon is another (for the image plot type). The abstraction renders
|
|
@@ -419,6 +420,10 @@ export interface IVisualizer extends IDataRenderer, IRegionStore, IToolControlle
|
|
|
419
420
|
* Optional: only the routing service implements it, since the state is shared
|
|
420
421
|
* rather than owned by any one backend. */
|
|
421
422
|
getSpatialControls?(): ISpatialControls | null;
|
|
423
|
+
/** The viewport a contributed plot mode draws over, when the backend on
|
|
424
|
+
* screen can provide one (OpenSeadragon), else null. Optional: backends that
|
|
425
|
+
* no contributed mode rides on need not implement it. */
|
|
426
|
+
getPlotModeViewport?(): PlotModeViewport | null;
|
|
422
427
|
/** Binned intensity histogram for a channel from the currently-displayed
|
|
423
428
|
* pixels, or null when none are available. Feeds the Channels & Histogram
|
|
424
429
|
* pane. */
|
|
@@ -10,6 +10,7 @@ import { PlotType, PlotTypeDescriptor } from '../../contracts/plot-type';
|
|
|
10
10
|
import { IVisualizer, PixelData, IntensityProfile, IIsosurfaceControls, IIntensityControls, ISurface3dControls } from '../../contracts/visualizer.contract';
|
|
11
11
|
import { ViewerCapabilities } from '../../contracts/capabilities.contract';
|
|
12
12
|
import { IRegionOverlay } from '../../contracts/region-overlay.contract';
|
|
13
|
+
import { PlotModeViewport } from '../../contracts/plot-type-contribution.contract';
|
|
13
14
|
import { BaseStoreVisualizer } from '../base-store-visualizer';
|
|
14
15
|
import { SimpleSliceAccessService } from '../simple-slice-access.service';
|
|
15
16
|
import { WandToolService } from '../../toolbar/wand/wand-tool.service';
|
|
@@ -221,6 +222,11 @@ export declare class OpenSeadragonVisualizerService extends BaseStoreVisualizer
|
|
|
221
222
|
/** Visible image region (full-image pixel coords) emitted when the view
|
|
222
223
|
* settles, so the intensity inset can re-sample at the current zoom level. */
|
|
223
224
|
private readonly viewportChange$;
|
|
225
|
+
/** The visible rect on every redraw, coalesced to one emission per animation
|
|
226
|
+
* frame. Feeds {@link PlotModeViewport.frame$}. */
|
|
227
|
+
private readonly frame$;
|
|
228
|
+
private frameRaf;
|
|
229
|
+
private plotModeViewport;
|
|
224
230
|
private readonly intensityProfile$;
|
|
225
231
|
/**
|
|
226
232
|
* Subscribe to the shared VisualizerStore colormap/reverse so OSD recolors in
|
|
@@ -410,6 +416,21 @@ export declare class OpenSeadragonVisualizerService extends BaseStoreVisualizer
|
|
|
410
416
|
/** Compute the current viewport's image-pixel rectangle (clamped to the image)
|
|
411
417
|
* and broadcast it. */
|
|
412
418
|
private emitViewportChange;
|
|
419
|
+
/** The current viewport's image-pixel rectangle, clamped to the image, or
|
|
420
|
+
* null when there is no laid-out viewport. */
|
|
421
|
+
private visibleImageRect;
|
|
422
|
+
/** Coalesce redraws into one {@link frame$} emission per animation frame.
|
|
423
|
+
* Skipped entirely while nothing listens. */
|
|
424
|
+
private scheduleFrame;
|
|
425
|
+
/**
|
|
426
|
+
* The viewport a contributed plot mode draws over. One stable object per
|
|
427
|
+
* service: every method reads the CURRENT viewer, so it stays valid across a
|
|
428
|
+
* viewer rebuild and reports `isReady() === false` while none is mounted
|
|
429
|
+
* (conversions then return NaN rather than throwing).
|
|
430
|
+
*/
|
|
431
|
+
getPlotModeViewport(): PlotModeViewport;
|
|
432
|
+
/** `source`, preceded by the current visible rect for each subscriber (when ready). */
|
|
433
|
+
private withCurrentRect;
|
|
413
434
|
/** OSD targets the image display; the scalar/3D plot types belong to Plotly. */
|
|
414
435
|
getPlotTypeDescriptors(): PlotTypeDescriptor[];
|
|
415
436
|
getIntensityProfile$(): Observable<IntensityProfile[]>;
|
|
@@ -13,5 +13,11 @@ export declare class OsdCoordinateTransform implements ICoordinateTransform {
|
|
|
13
13
|
x: number;
|
|
14
14
|
y: number;
|
|
15
15
|
};
|
|
16
|
+
/** Data (image-pixel) coordinates -> client (mouse event) pixel. The inverse
|
|
17
|
+
* of {@link clientToData}. */
|
|
18
|
+
dataToClient(x: number, y: number): {
|
|
19
|
+
x: number;
|
|
20
|
+
y: number;
|
|
21
|
+
};
|
|
16
22
|
dataLengthToScreen(dataLength: number): number;
|
|
17
23
|
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { PlotType, PlotTypeId } from '../contracts/plot-type';
|
|
2
|
+
import { ContributedPlotTypeDescriptor, PlotModeContext, PlotModeSession, PlotTypeContribution } from '../contracts/plot-type-contribution.contract';
|
|
3
|
+
/**
|
|
4
|
+
* Lifecycle of the contributed plot modes ({@link PlotTypeContribution}) for one
|
|
5
|
+
* visualizer instance. Package-internal: the visualizer component owns one and
|
|
6
|
+
* drives it from its render pipeline.
|
|
7
|
+
*
|
|
8
|
+
* Owns three things the component should not have to reason about:
|
|
9
|
+
* - which contributions are usable (validated and de-duplicated once);
|
|
10
|
+
* - the single live session, so `deactivate()` runs exactly once per session
|
|
11
|
+
* however many exits race each other (type change, image change, destroy,
|
|
12
|
+
* a superseded async activation);
|
|
13
|
+
* - isolation: nothing a contribution throws or rejects escapes this class.
|
|
14
|
+
* A failure is logged and reported through `onFailed`, and the component
|
|
15
|
+
* falls back to the mode's base type.
|
|
16
|
+
*/
|
|
17
|
+
/** The live activation of a contributed mode, as the component renders it. */
|
|
18
|
+
export interface ActivePlotMode {
|
|
19
|
+
readonly contribution: PlotTypeContribution;
|
|
20
|
+
readonly ctx: PlotModeContext;
|
|
21
|
+
readonly session: PlotModeSession;
|
|
22
|
+
/** Host element handed to a `mount` panel, or null for a component / no panel. */
|
|
23
|
+
readonly panelHost: HTMLElement | null;
|
|
24
|
+
}
|
|
25
|
+
export interface PlotModeControllerHooks {
|
|
26
|
+
/** A session is live (and a `mount` panel, if any, has been mounted). */
|
|
27
|
+
onActivated(active: ActivePlotMode): void;
|
|
28
|
+
/** The live session is about to end. Called BEFORE any teardown, so a
|
|
29
|
+
* component panel can be destroyed while its session is still valid. */
|
|
30
|
+
onDeactivating(active: ActivePlotMode): void;
|
|
31
|
+
/** Activation failed (threw, rejected, never got a ready viewport, or its
|
|
32
|
+
* panel failed to mount). The component falls back to the base type. */
|
|
33
|
+
onFailed(contribution: PlotTypeContribution, error: unknown): void;
|
|
34
|
+
}
|
|
35
|
+
/** Minimal logger, injectable for tests. */
|
|
36
|
+
export interface PlotModeLogger {
|
|
37
|
+
warn(...args: unknown[]): void;
|
|
38
|
+
error(...args: unknown[]): void;
|
|
39
|
+
}
|
|
40
|
+
/** Base types a contributed mode can ride on in this version. */
|
|
41
|
+
export declare const SUPPORTED_CONTRIBUTION_BASE_TYPES: readonly PlotType[];
|
|
42
|
+
/**
|
|
43
|
+
* Validate what arrived on `PLOT_TYPE_CONTRIBUTIONS`. A malformed or clashing
|
|
44
|
+
* contribution is dropped with a warning rather than breaking the selector:
|
|
45
|
+
* - a nested array (`useValue: [a, b], multi: true`) is flattened one level;
|
|
46
|
+
* - `type` must be a non-empty string that is not a built-in `PlotType` value;
|
|
47
|
+
* - the first contribution with a given `type` wins;
|
|
48
|
+
* - `baseType` must be one of {@link SUPPORTED_CONTRIBUTION_BASE_TYPES};
|
|
49
|
+
* - `activate` must be a function.
|
|
50
|
+
*/
|
|
51
|
+
export declare function normalizeContributions(raw: readonly unknown[] | null | undefined, log?: PlotModeLogger): PlotTypeContribution[];
|
|
52
|
+
export declare class PlotModeController {
|
|
53
|
+
private readonly hooks;
|
|
54
|
+
private readonly log;
|
|
55
|
+
readonly contributions: readonly PlotTypeContribution[];
|
|
56
|
+
private readonly byId;
|
|
57
|
+
private active;
|
|
58
|
+
private teardown;
|
|
59
|
+
/** Bumped by every activate/deactivate, so a pending async activation can
|
|
60
|
+
* tell it has been superseded. */
|
|
61
|
+
private generation;
|
|
62
|
+
private readyFrame;
|
|
63
|
+
/** Contributions whose last cleanup (panel teardown / `deactivate()`) threw or
|
|
64
|
+
* rejected. Their next automatic re-activation (base re-render, image switch)
|
|
65
|
+
* falls back to the base type instead; an explicit selection clears the mark. */
|
|
66
|
+
private readonly failedCleanup;
|
|
67
|
+
private readyCb;
|
|
68
|
+
constructor(raw: readonly unknown[] | null | undefined, hooks: PlotModeControllerHooks, log?: PlotModeLogger);
|
|
69
|
+
/** Descriptors of the usable contributions, in registration order. */
|
|
70
|
+
descriptors(): ContributedPlotTypeDescriptor[];
|
|
71
|
+
/** The contribution for a selector id, if it is a contributed mode. */
|
|
72
|
+
find(id: PlotTypeId | null | undefined): PlotTypeContribution | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* The built-in type that renders `id`: a built-in type is itself, a
|
|
75
|
+
* contributed id is its `baseType`, and an id that is neither (a stale
|
|
76
|
+
* contributed id whose provider is gone) resolves to `PlotType.IMAGE`, the
|
|
77
|
+
* default view.
|
|
78
|
+
*/
|
|
79
|
+
baseTypeOf(id: PlotTypeId | null | undefined): PlotType;
|
|
80
|
+
/** The live session, if any. */
|
|
81
|
+
get current(): ActivePlotMode | null;
|
|
82
|
+
/** Whether an activation is waiting on the contribution or the viewport. */
|
|
83
|
+
get pending(): boolean;
|
|
84
|
+
private pendingId;
|
|
85
|
+
/**
|
|
86
|
+
* Start a session for `contribution`. Ends any live one first. Resolves when
|
|
87
|
+
* the attempt has finished (successfully or not); it never rejects.
|
|
88
|
+
*/
|
|
89
|
+
activate(contribution: PlotTypeContribution, ctx: PlotModeContext): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* End the live session, if any: the component panel is dropped (via
|
|
92
|
+
* `onDeactivating`), a `mount` panel's teardown runs, then
|
|
93
|
+
* `session.deactivate()`, then the mount host is removed. Each step is
|
|
94
|
+
* isolated. A pending activation is cancelled; if it resolves later its
|
|
95
|
+
* session is deactivated on arrival. Idempotent.
|
|
96
|
+
*/
|
|
97
|
+
deactivate(): void;
|
|
98
|
+
/**
|
|
99
|
+
* Forget recorded cleanup failures. The host calls this when the USER picks a
|
|
100
|
+
* plot type: an explicit choice gets a fresh attempt, only automatic
|
|
101
|
+
* re-activations fall back.
|
|
102
|
+
*/
|
|
103
|
+
clearCleanupFailures(): void;
|
|
104
|
+
private start;
|
|
105
|
+
/**
|
|
106
|
+
* The host could not make the live mode usable (its panel threw while being
|
|
107
|
+
* created or first rendered): end the session once, then fall back to its base.
|
|
108
|
+
* No-op when nothing is live.
|
|
109
|
+
*/
|
|
110
|
+
failActive(err: unknown): void;
|
|
111
|
+
private fail;
|
|
112
|
+
private guard;
|
|
113
|
+
/** Like `guard`, for a contribution callback typed `void` that may still return a
|
|
114
|
+
* promise: a rejection is logged instead of escaping as an unhandled rejection. */
|
|
115
|
+
private guardLogged;
|
|
116
|
+
/** Run a live session's cleanup; a throw OR a rejection goes to `cleanupFailed`. */
|
|
117
|
+
private cleanup;
|
|
118
|
+
/**
|
|
119
|
+
* A contribution's cleanup failed. If that same contribution is live or starting
|
|
120
|
+
* again (a base re-render / image switch re-activated it — or, for an async
|
|
121
|
+
* rejection, already has), end it and fall back to its base type. Otherwise the
|
|
122
|
+
* user has moved on: remember it, so the next automatic re-activation falls back.
|
|
123
|
+
*/
|
|
124
|
+
private cleanupFailed;
|
|
125
|
+
/** Call `cb(true)` once the viewport reports ready (now, or on a later
|
|
126
|
+
* animation frame), or `cb(false)` after {@link MAX_READY_FRAMES}. */
|
|
127
|
+
private whenReady;
|
|
128
|
+
/** Stop waiting for the viewport; the waiting activation resolves as superseded. */
|
|
129
|
+
private cancelReadyWait;
|
|
130
|
+
}
|
|
@@ -17,6 +17,7 @@ import { IChannelHistogramApi, IChannelState, IHistogram } from './contracts/cha
|
|
|
17
17
|
import { VisualizerStore } from './store/visualizer-store.service';
|
|
18
18
|
import { NapariVisualizerService } from './implementations/napari-js/napari-visualizer.service';
|
|
19
19
|
import { VizConfig } from './contracts/viz-config';
|
|
20
|
+
import { PlotModeViewport } from './contracts/plot-type-contribution.contract';
|
|
20
21
|
import * as i0 from "@angular/core";
|
|
21
22
|
export declare class RoutingVisualizerService implements IVisualizer, IRegionEditorApi, IChannelHistogramApi {
|
|
22
23
|
private plotly;
|
|
@@ -98,6 +99,9 @@ export declare class RoutingVisualizerService implements IVisualizer, IRegionEdi
|
|
|
98
99
|
resetSurfaceCamera(): void;
|
|
99
100
|
setResolutionScale(scale: number): void;
|
|
100
101
|
getResolutionScale(): number;
|
|
102
|
+
/** The viewport of the backend on screen, for a contributed plot mode. Null
|
|
103
|
+
* when that backend cannot provide one (e.g. OSD fell back to Plotly). */
|
|
104
|
+
getPlotModeViewport(): PlotModeViewport | null;
|
|
101
105
|
getPlotTypeDescriptors(): PlotTypeDescriptor[];
|
|
102
106
|
setStackLoading(b: boolean): void;
|
|
103
107
|
cancelLoading(): void;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
|
|
2
2
|
import { MenuItem } from 'primeng/api';
|
|
3
3
|
import { IImageInfo } from '../contracts/image.contract';
|
|
4
|
-
import { PlotType,
|
|
4
|
+
import { PlotType, PlotTypeId } from '../contracts/plot-type';
|
|
5
5
|
import { ToolbarToolVisibility } from '../contracts/toolbar-config';
|
|
6
6
|
import { ToolbarToolContribution } from '../contracts/toolbar-tool.contract';
|
|
7
|
+
import { PlotTypeOption } from '../contracts/plot-type-contribution.contract';
|
|
7
8
|
import * as i0 from "@angular/core";
|
|
8
9
|
/**
|
|
9
10
|
* Presentational toolbar for the plotting viewport.
|
|
@@ -20,9 +21,18 @@ import * as i0 from "@angular/core";
|
|
|
20
21
|
export declare class ToolbarComponent implements OnChanges {
|
|
21
22
|
/** Current image (gates which control groups are shown). */
|
|
22
23
|
imageInfo: IImageInfo | undefined;
|
|
23
|
-
/** Plot types the active backend advertises. */
|
|
24
|
-
plotTypeOptions:
|
|
25
|
-
|
|
24
|
+
/** Plot types the active backend advertises, then any contributed modes. */
|
|
25
|
+
plotTypeOptions: PlotTypeOption[];
|
|
26
|
+
/** The selector's value: a built-in type or a contributed mode's id. */
|
|
27
|
+
selectedPlotType: PlotTypeId;
|
|
28
|
+
/**
|
|
29
|
+
* The built-in type that renders {@link selectedPlotType} — its `baseType`
|
|
30
|
+
* for a contributed mode. Every tool/control decision below reads
|
|
31
|
+
* {@link effectivePlotType}, so a contributed mode gets exactly its base
|
|
32
|
+
* type's toolbar. When unbound, a built-in selection is its own base and
|
|
33
|
+
* anything else is treated as the default Image view.
|
|
34
|
+
*/
|
|
35
|
+
basePlotType: PlotType | null;
|
|
26
36
|
/** Isosurface band as a 0–255 slider position (mapped onto the volume's real
|
|
27
37
|
* intensity range by the renderer). Defaults to the full range. */
|
|
28
38
|
isoRange: number[];
|
|
@@ -82,7 +92,7 @@ export declare class ToolbarComponent implements OnChanges {
|
|
|
82
92
|
contributedTools: ToolbarToolContribution[];
|
|
83
93
|
/** Active checkpoint per contributed tool, keyed by tool id. */
|
|
84
94
|
toolModelIds: Record<string, string>;
|
|
85
|
-
selectPlotType: EventEmitter<
|
|
95
|
+
selectPlotType: EventEmitter<string>;
|
|
86
96
|
/** Intensity (LINE) mode: add another colored line ROI + inset trace. */
|
|
87
97
|
addProfileLine: EventEmitter<void>;
|
|
88
98
|
/** Toggle image smoothing (bilinear) vs nearest-neighbour (crisp pixels). */
|
|
@@ -196,6 +206,8 @@ export declare class ToolbarComponent implements OnChanges {
|
|
|
196
206
|
/** Keeps each contributed tool's `p-menu` overlay alive across CD ticks —
|
|
197
207
|
* re-creating it mid-interaction swallows the click on a menu item. */
|
|
198
208
|
trackToolById(_index: number, tool: ToolbarToolContribution): string;
|
|
209
|
+
/** The built-in type whose tools and controls apply to the current selection. */
|
|
210
|
+
get effectivePlotType(): PlotType;
|
|
199
211
|
/** The Image plot type renders as a natively pan/zoom-able raster, so the
|
|
200
212
|
* generic zoom/pan tools are hidden. */
|
|
201
213
|
get isImageView(): boolean;
|
|
@@ -230,5 +242,5 @@ export declare class ToolbarComponent implements OnChanges {
|
|
|
230
242
|
get isIntensityCapable(): boolean;
|
|
231
243
|
showHelp(): void;
|
|
232
244
|
static ɵfac: i0.ɵɵFactoryDeclaration<ToolbarComponent, never>;
|
|
233
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<ToolbarComponent, "plotting-toolbar", never, { "imageInfo": { "alias": "imageInfo"; "required": false; }; "plotTypeOptions": { "alias": "plotTypeOptions"; "required": false; }; "selectedPlotType": { "alias": "selectedPlotType"; "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; }; "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"; "toolModelChange": "toolModelChange"; "openToolParams": "openToolParams"; "samModelChange": "samModelChange"; "wandSensitivityChange": "wandSensitivityChange"; "brushSizeChange": "brushSizeChange"; "vertexEraserRadiusChange": "vertexEraserRadiusChange"; }, never, ["*"], false, never>;
|
|
245
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ToolbarComponent, "plotting-toolbar", never, { "imageInfo": { "alias": "imageInfo"; "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; }; "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"; "toolModelChange": "toolModelChange"; "openToolParams": "openToolParams"; "samModelChange": "samModelChange"; "wandSensitivityChange": "wandSensitivityChange"; "brushSizeChange": "brushSizeChange"; "vertexEraserRadiusChange": "vertexEraserRadiusChange"; }, never, ["*"], false, never>;
|
|
234
246
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChangeDetectorRef, AfterViewInit, EventEmitter, NgZone, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
|
|
1
|
+
import { ChangeDetectorRef, AfterViewInit, ElementRef, EventEmitter, Injector, NgZone, OnChanges, OnDestroy, OnInit, SimpleChanges, Type } from '@angular/core';
|
|
2
2
|
import { Subscription } from 'rxjs';
|
|
3
3
|
import { MenuItem, MessageService, TreeNode } from 'primeng/api';
|
|
4
4
|
import { ContextMenu } from 'primeng/contextmenu';
|
|
@@ -7,7 +7,9 @@ import { ImageStatePort } from './contracts/ports/image-state.port';
|
|
|
7
7
|
import { Polygon } from './models/region';
|
|
8
8
|
import { RegionOpsService } from './region-ops.service';
|
|
9
9
|
import { VisualizerStore } from './store/visualizer-store.service';
|
|
10
|
-
import { PlotType, PlotTypeDescriptor } from './contracts/plot-type';
|
|
10
|
+
import { PlotType, PlotTypeDescriptor, PlotTypeId } from './contracts/plot-type';
|
|
11
|
+
import { PlotTypeContribution, PlotTypeOption } from './contracts/plot-type-contribution.contract';
|
|
12
|
+
import { PlotModeController } from './plot-mode/plot-mode-controller';
|
|
11
13
|
import { IVisualizer } from './contracts/visualizer.contract';
|
|
12
14
|
import { SamToolService } from './toolbar/segmentation/sam-tool.service';
|
|
13
15
|
import { SamPointToolService } from './toolbar/segmentation/sam-point-tool.service';
|
|
@@ -30,6 +32,7 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
30
32
|
private regionOps;
|
|
31
33
|
private vizConfig?;
|
|
32
34
|
private spatialData?;
|
|
35
|
+
private injector?;
|
|
33
36
|
/** Per-instance toast key. MessageService is a global singleton, so two live
|
|
34
37
|
* `<visualizer>` instances (main viewer + pipeline-dialog preview) sharing
|
|
35
38
|
* one key would each render the same message — a duplicate toast. A unique
|
|
@@ -204,9 +207,48 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
204
207
|
wireframeActive: boolean;
|
|
205
208
|
/** napari 3D decimate factor (1 = Full … 8 = ⅛; default ½); changing it re-plots. */
|
|
206
209
|
resolutionScale: number;
|
|
207
|
-
/**
|
|
210
|
+
/** The selector's entries: the built-in plot types the active backend
|
|
211
|
+
* advertises (3D gated by capability), then any contributed modes
|
|
212
|
+
* ({@link PLOT_TYPE_CONTRIBUTIONS}). */
|
|
213
|
+
plotTypeMenu: PlotTypeOption[];
|
|
214
|
+
/**
|
|
215
|
+
* The built-in plot types on offer — {@link plotTypeMenu} without contributed
|
|
216
|
+
* modes. Kept with its original type so existing readers are unaffected.
|
|
217
|
+
*/
|
|
208
218
|
plotTypeOptions: PlotTypeDescriptor[];
|
|
209
|
-
|
|
219
|
+
/**
|
|
220
|
+
* What the selector shows: a built-in type or a contributed mode's id. Every
|
|
221
|
+
* rendering and tool decision goes through {@link basePlotType} instead, so a
|
|
222
|
+
* contributed mode behaves exactly like the built-in type it rides on.
|
|
223
|
+
*/
|
|
224
|
+
selectedPlotTypeId: PlotTypeId;
|
|
225
|
+
/**
|
|
226
|
+
* The built-in plot type being rendered. With no contributed mode active this
|
|
227
|
+
* is the selection itself; during one it is the mode's `baseType`. Kept with its
|
|
228
|
+
* original `PlotType` type for existing readers — use {@link selectedPlotTypeId}
|
|
229
|
+
* for the selector's id. Assigning selects that built-in type.
|
|
230
|
+
*/
|
|
231
|
+
get selectedPlotType(): PlotType;
|
|
232
|
+
set selectedPlotType(type: PlotType);
|
|
233
|
+
/** Contributed plot modes and their single live session. */
|
|
234
|
+
readonly plotModes: PlotModeController;
|
|
235
|
+
/**
|
|
236
|
+
* The live contributed mode's side panel, as the template renders it: an
|
|
237
|
+
* Angular component with its own injector, or a plain host element a `mount`
|
|
238
|
+
* panel rendered into. Null while no contributed session is live.
|
|
239
|
+
*/
|
|
240
|
+
plotModePanel: {
|
|
241
|
+
title: string;
|
|
242
|
+
component: Type<unknown> | null;
|
|
243
|
+
injector: Injector | null;
|
|
244
|
+
host: HTMLElement | null;
|
|
245
|
+
} | null;
|
|
246
|
+
private destroying;
|
|
247
|
+
/** Where a `mount` panel's host element is attached once the dialog renders. */
|
|
248
|
+
set plotModePanelSlot(ref: ElementRef<HTMLElement> | undefined);
|
|
249
|
+
/** The built-in type actually rendered for {@link selectedPlotTypeId}: itself
|
|
250
|
+
* for a built-in type, `baseType` for a contributed mode. */
|
|
251
|
+
get basePlotType(): PlotType;
|
|
210
252
|
/** Floating intensity-profile inset (LINE mode). */
|
|
211
253
|
readonly intensityInsetDiv = "intensity-inset-plot";
|
|
212
254
|
profilePanelPos: {
|
|
@@ -276,7 +318,7 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
276
318
|
private wheelListener?;
|
|
277
319
|
/** Debounced z-slice scrubbing (see SliceScrubber — refactoring plan Step 7). */
|
|
278
320
|
private readonly scrubber;
|
|
279
|
-
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 ToolbarToolContribution[], spatialData?: SpatialDataPort | undefined);
|
|
321
|
+
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 ToolbarToolContribution[], spatialData?: SpatialDataPort | undefined, plotTypeContributions?: readonly PlotTypeContribution[], injector?: Injector | undefined);
|
|
280
322
|
/**
|
|
281
323
|
* Plot types offered in the selector for the current image:
|
|
282
324
|
* - Outside **test mode**, only the curated default set (descriptors with a
|
|
@@ -544,9 +586,28 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
544
586
|
* the toolbar/context-menu logic relies on, deactivates 2D-only tools when
|
|
545
587
|
* moving to a 3D type, then re-plots.
|
|
546
588
|
*/
|
|
547
|
-
onSelectPlotType(
|
|
589
|
+
onSelectPlotType(selected: PlotTypeId): void;
|
|
590
|
+
/**
|
|
591
|
+
* Start the selected contributed mode's session, once its base view has
|
|
592
|
+
* plotted. No-op for a built-in type, or when the base on screen is not the
|
|
593
|
+
* one the mode rides on. A backend that cannot provide a viewport for it
|
|
594
|
+
* (e.g. OSD fell back to Plotly) counts as a failed activation.
|
|
595
|
+
*/
|
|
596
|
+
private activateSelectedPlotMode;
|
|
597
|
+
/** Render the live mode's panel. Activation can resolve outside Angular (an
|
|
598
|
+
* OSD callback, a contribution's own promise), hence the zone re-entry. */
|
|
599
|
+
private showPlotModePanel;
|
|
600
|
+
/** Drop the panel (destroying a component panel) before the session ends. */
|
|
601
|
+
private hidePlotModePanel;
|
|
602
|
+
/**
|
|
603
|
+
* A contributed mode could not start. Its base type is already on screen —
|
|
604
|
+
* the base plotted first — so just select it: nothing needs to re-plot.
|
|
605
|
+
*/
|
|
606
|
+
private fallBackFromPlotMode;
|
|
607
|
+
/** Run change detection; returns what it threw (logged), or null. */
|
|
608
|
+
private detectChangesSafely;
|
|
548
609
|
/** Deactivate whatever tool is armed and clear every tool mode. */
|
|
549
610
|
private deactivateActiveTool;
|
|
550
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<VisualizerComponent, [null, null, null, null, null, null, null, null, null, null, { optional: true; }, { optional: true; }, { optional: true; }]>;
|
|
611
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<VisualizerComponent, [null, null, null, null, null, null, null, null, null, null, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }]>;
|
|
551
612
|
static ɵcmp: i0.ɵɵComponentDeclaration<VisualizerComponent, "visualizer", never, { "toolbarTools": { "alias": "toolbarTools"; "required": false; }; "testMode": { "alias": "testMode"; "required": false; }; }, { "isStackEvent": "isStackEvent"; "isGrayscaleEvent": "isGrayscaleEvent"; }, never, ["*"], false, never>;
|
|
552
613
|
}
|