@jax-data-science/sci-image-visualizer 0.3.3 → 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 +268 -4
- package/esm2022/index.mjs +21 -1
- package/esm2022/lib/contracts/display-types.mjs +20 -2
- package/esm2022/lib/contracts/image.contract.mjs +1 -1
- package/esm2022/lib/contracts/plot-type-contribution.contract.mjs +66 -0
- package/esm2022/lib/contracts/plot-type.mjs +41 -1
- package/esm2022/lib/contracts/ports/spatial-data.port.mjs +3 -0
- package/esm2022/lib/contracts/spatial-dataset.contract.mjs +45 -0
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-axes-labels.mjs +10 -19
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +71 -7
- package/esm2022/lib/implementations/napari-js/napari-scale-bar.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-spatial-tooltip.mjs +96 -0
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +1934 -55
- package/esm2022/lib/implementations/napari-js/napari-zoom.mjs +18 -0
- package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +73 -8
- package/esm2022/lib/implementations/osd/osd-coordinate-transform.mjs +8 -1
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +3 -4
- package/esm2022/lib/implementations/osd/osd-zoom.mjs +20 -0
- package/esm2022/lib/implementations/plotly/omics-trace-builders.mjs +555 -0
- package/esm2022/lib/implementations/plotly/plotly.service.mjs +13 -7
- package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +304 -0
- package/esm2022/lib/implementations/spatial-data-http/spatial-wire.mjs +179 -0
- package/esm2022/lib/plot-mode/plot-mode-controller.mjs +329 -0
- package/esm2022/lib/routing-visualizer.service.mjs +228 -12
- package/esm2022/lib/spatial/embedding-compute.mjs +142 -0
- package/esm2022/lib/spatial/gene-search.mjs +77 -0
- package/esm2022/lib/spatial/spatial-density.mjs +224 -0
- package/esm2022/lib/spatial/spatial-encoding.mjs +232 -0
- package/esm2022/lib/spatial/spatial-expression.mjs +257 -0
- package/esm2022/lib/spatial/spatial-framing.mjs +60 -0
- package/esm2022/lib/spatial/spatial-heatmap.mjs +185 -0
- package/esm2022/lib/spatial/spatial-hover.mjs +79 -0
- package/esm2022/lib/spatial/spatial-sections.mjs +96 -0
- package/esm2022/lib/spatial/spatial-selection.mjs +264 -0
- package/esm2022/lib/spatial/spatial-volume-image.mjs +163 -0
- package/esm2022/lib/spatial/tsne-worker.mjs +10 -0
- package/esm2022/lib/spatial/world-grid.mjs +77 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +1278 -0
- package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +621 -0
- package/esm2022/lib/store/spatial-selection.service.mjs +47 -0
- package/esm2022/lib/store/visualizer-store.service.mjs +23 -1
- package/esm2022/lib/toolbar/toolbar.component.mjs +61 -21
- package/esm2022/lib/visualization.module.mjs +23 -5
- package/esm2022/lib/visualizer.component.mjs +527 -44
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-ci1q0xnJ.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs} +6 -4
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-ci1q0xnJ.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs.map} +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer-tsne-worker-B_nXDGf0.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-tsne-worker-B_nXDGf0.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +15971 -7808
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
- package/fesm2022/tsne.worker.js +19091 -0
- package/index.d.ts +16 -0
- package/lib/contracts/display-types.d.ts +131 -0
- package/lib/contracts/image.contract.d.ts +7 -0
- package/lib/contracts/plot-type-contribution.contract.d.ts +172 -0
- package/lib/contracts/plot-type.d.ts +52 -2
- package/lib/contracts/ports/spatial-data.port.d.ts +90 -0
- package/lib/contracts/spatial-dataset.contract.d.ts +281 -0
- package/lib/contracts/visualizer.contract.d.ts +104 -1
- package/lib/implementations/napari-js/napari-axes-labels.d.ts +9 -7
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +38 -4
- package/lib/implementations/napari-js/napari-scale-bar.d.ts +7 -3
- package/lib/implementations/napari-js/napari-spatial-tooltip.d.ts +32 -0
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +497 -16
- package/lib/implementations/napari-js/napari-zoom.d.ts +15 -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/implementations/osd/osd-zoom.d.ts +19 -0
- package/lib/implementations/plotly/omics-trace-builders.d.ts +193 -0
- package/lib/implementations/plotly/plotly.service.d.ts +9 -0
- package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +123 -0
- package/lib/implementations/spatial-data-http/spatial-wire.d.ts +115 -0
- package/lib/plot-mode/plot-mode-controller.d.ts +130 -0
- package/lib/routing-visualizer.service.d.ts +49 -6
- package/lib/spatial/embedding-compute.d.ts +73 -0
- package/lib/spatial/gene-search.d.ts +48 -0
- package/lib/spatial/spatial-density.d.ts +73 -0
- package/lib/spatial/spatial-encoding.d.ts +155 -0
- package/lib/spatial/spatial-expression.d.ts +144 -0
- package/lib/spatial/spatial-framing.d.ts +37 -0
- package/lib/spatial/spatial-heatmap.d.ts +111 -0
- package/lib/spatial/spatial-hover.d.ts +49 -0
- package/lib/spatial/spatial-sections.d.ts +59 -0
- package/lib/spatial/spatial-selection.d.ts +113 -0
- package/lib/spatial/spatial-volume-image.d.ts +67 -0
- package/lib/spatial/tsne-worker.d.ts +7 -0
- package/lib/spatial/world-grid.d.ts +58 -0
- package/lib/spatial-controls/spatial-charts/spatial-charts.component.d.ts +439 -0
- package/lib/spatial-controls/spatial-controls.component.d.ts +257 -0
- package/lib/store/spatial-selection.service.d.ts +27 -0
- package/lib/store/visualizer-store.service.d.ts +13 -0
- package/lib/toolbar/toolbar.component.d.ts +36 -8
- package/lib/visualization.module.d.ts +28 -24
- package/lib/visualizer.component.d.ts +139 -7
- package/package.json +6 -2
- package/src/lib/assets/spatial-omics-3d.svg +31 -0
- package/src/lib/assets/spatial-omics.svg +27 -0
|
@@ -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';
|
|
@@ -15,6 +17,7 @@ import { CellSegmentToolService } from './toolbar/segmentation/cell-segment-tool
|
|
|
15
17
|
import { NumberParamSpec, SelectParamSpec, ToolParamSpec, ToolbarToolContribution } from './contracts/toolbar-tool.contract';
|
|
16
18
|
import { ToolbarToolVisibility } from './contracts/toolbar-config';
|
|
17
19
|
import { VizConfig } from './contracts/viz-config';
|
|
20
|
+
import { SpatialDataPort } from './contracts/ports/spatial-data.port';
|
|
18
21
|
import * as i0 from "@angular/core";
|
|
19
22
|
export declare class VisualizerComponent implements OnInit, OnChanges, AfterViewInit, OnDestroy {
|
|
20
23
|
private state;
|
|
@@ -28,6 +31,8 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
28
31
|
private samPointTool;
|
|
29
32
|
private regionOps;
|
|
30
33
|
private vizConfig?;
|
|
34
|
+
private spatialData?;
|
|
35
|
+
private injector?;
|
|
31
36
|
/** Per-instance toast key. MessageService is a global singleton, so two live
|
|
32
37
|
* `<visualizer>` instances (main viewer + pipeline-dialog preview) sharing
|
|
33
38
|
* one key would each render the same message — a duplicate toast. A unique
|
|
@@ -177,6 +182,8 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
177
182
|
selectedColormap: any;
|
|
178
183
|
/** Channels & Histogram dialog visibility (opened from the toolbar). */
|
|
179
184
|
showChannelHistogram: boolean;
|
|
185
|
+
/** Spatial-omics controls dialog visibility (toolbar button). */
|
|
186
|
+
showSpatialControls: boolean;
|
|
180
187
|
/** Region Editor dialog visibility (opened from the toolbar). */
|
|
181
188
|
showRegionEditor: boolean;
|
|
182
189
|
/** Region Editor dialog width. On open it is set to the configured host
|
|
@@ -200,9 +207,48 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
200
207
|
wireframeActive: boolean;
|
|
201
208
|
/** napari 3D decimate factor (1 = Full … 8 = ⅛; default ½); changing it re-plots. */
|
|
202
209
|
resolutionScale: number;
|
|
203
|
-
/**
|
|
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
|
+
*/
|
|
204
218
|
plotTypeOptions: PlotTypeDescriptor[];
|
|
205
|
-
|
|
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;
|
|
206
252
|
/** Floating intensity-profile inset (LINE mode). */
|
|
207
253
|
readonly intensityInsetDiv = "intensity-inset-plot";
|
|
208
254
|
profilePanelPos: {
|
|
@@ -230,6 +276,10 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
230
276
|
private profileDragMoveListener?;
|
|
231
277
|
private profileDragUpListener?;
|
|
232
278
|
private profileResizeListener?;
|
|
279
|
+
/** True while the 3D spatial cloud is the active mode. The controls drop the ROI
|
|
280
|
+
* selection there: region tools are screen-space, and against an orbiting
|
|
281
|
+
* camera a drawn rectangle has no fixed meaning in the data. */
|
|
282
|
+
get isSpatial3dMode(): boolean;
|
|
233
283
|
/** LINE plot type shows the image + draggable line ROI + intensity inset. */
|
|
234
284
|
get isProfileMode(): boolean;
|
|
235
285
|
/** True for the Image plot type, which renders as a natively pan/zoom-able
|
|
@@ -239,6 +289,24 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
239
289
|
/** Isosurface band as a 0–255 slider position, mapped onto the volume's real
|
|
240
290
|
* intensity range by the renderer. Defaults to the full range. */
|
|
241
291
|
isoRange: number[];
|
|
292
|
+
/** Whether a spatial-omics dataset is currently published on
|
|
293
|
+
* `SPATIAL_DATA_PORT` — gates the spatial plot types in the selector. */
|
|
294
|
+
private hasSpatialDataset;
|
|
295
|
+
/** Whether that dataset's observations carry a z, gating the 3D spatial mode. */
|
|
296
|
+
private hasSpatial3dDataset;
|
|
297
|
+
/** Whether it carries a registered volume. Change detection only: a volume
|
|
298
|
+
* appearing is what publishes it as the image, and the plot-type gates then
|
|
299
|
+
* see an ordinary grayscale stack. */
|
|
300
|
+
private hasSpatialVolume;
|
|
301
|
+
/** Dataset identity + capability shape the last emission was handled at, so a
|
|
302
|
+
* switch between two datasets of the same shape is not mistaken for a repeat. */
|
|
303
|
+
private spatialDatasetKey;
|
|
304
|
+
/** Dataset + geometry the currently published volume image was built from, so a
|
|
305
|
+
* re-emitted dataset doesn't re-fetch megabytes or reset the user's scrub. */
|
|
306
|
+
private volumeImageKey;
|
|
307
|
+
/** Blob URLs backing that image — ours to revoke. */
|
|
308
|
+
private volumeImageUrls;
|
|
309
|
+
private spatialDatasetSubscription?;
|
|
242
310
|
plotWidthSubscription?: Subscription;
|
|
243
311
|
imageLoadingSubscription?: Subscription;
|
|
244
312
|
imgLoadingMessageSubscription?: Subscription;
|
|
@@ -250,7 +318,7 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
250
318
|
private wheelListener?;
|
|
251
319
|
/** Debounced z-slice scrubbing (see SliceScrubber — refactoring plan Step 7). */
|
|
252
320
|
private readonly scrubber;
|
|
253
|
-
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[]);
|
|
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);
|
|
254
322
|
/**
|
|
255
323
|
* Plot types offered in the selector for the current image:
|
|
256
324
|
* - Outside **test mode**, only the curated default set (descriptors with a
|
|
@@ -263,12 +331,55 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
263
331
|
* - scalar-intensity types (contour, surface, isosurface) hidden for RGB
|
|
264
332
|
* images — they map a single intensity per pixel. Image and Heatmap render
|
|
265
333
|
* any image.
|
|
334
|
+
* - spatial-omics types hidden until a `SpatialDataset` is published on
|
|
335
|
+
* `SPATIAL_DATA_PORT` — the mode has nothing to draw without observations,
|
|
336
|
+
* exactly as a volume has nothing to draw without a stack.
|
|
337
|
+
*/
|
|
338
|
+
/**
|
|
339
|
+
* Track whether a spatial-omics dataset is available. A dataset appearing (or
|
|
340
|
+
* being cleared) changes which plot types make sense, so it drives the same
|
|
341
|
+
* recompute + reconcile that the image stream and the test-mode toggle do.
|
|
342
|
+
*
|
|
343
|
+
* No-op when the host provides no `SPATIAL_DATA_PORT` — the spatial types then
|
|
344
|
+
* stay hidden for the life of the component.
|
|
266
345
|
*/
|
|
346
|
+
private watchSpatialDataset;
|
|
347
|
+
/**
|
|
348
|
+
* Publish a dataset's reference volume AS the image, and open the 2D Image view
|
|
349
|
+
* on it.
|
|
350
|
+
*
|
|
351
|
+
* The volume is a 3D image delivered in one file, so for a dataset that has no
|
|
352
|
+
* section image it is the honest thing to put on screen: the slice bar scrubs z,
|
|
353
|
+
* and the contrast window, colormaps and region tools all work because the
|
|
354
|
+
* volume genuinely is the image now. The 3D cloud stays one menu pick away.
|
|
355
|
+
*
|
|
356
|
+
* Keyed by dataset + geometry: the dataset stream re-emits on things like a
|
|
357
|
+
* colour-column change, and rebuilding then would re-fetch the voxels and throw
|
|
358
|
+
* the user back to the middle slice.
|
|
359
|
+
*/
|
|
360
|
+
private showVolumeAsImage;
|
|
361
|
+
/** Forget the published volume image so re-selecting the dataset rebuilds it.
|
|
362
|
+
* The URLs deliberately stay alive: the host may still be displaying that image
|
|
363
|
+
* at this instant, and revoking under it would break every later tile read. They
|
|
364
|
+
* are freed when the next volume replaces them, or on destroy. */
|
|
365
|
+
private dropVolumeImage;
|
|
366
|
+
private revokeVolumeImageUrls;
|
|
267
367
|
private computePlotTypeOptions;
|
|
268
368
|
ngOnChanges(changes: SimpleChanges): void;
|
|
269
369
|
/** If the active plot type is no longer in the offered options (e.g. test mode
|
|
270
370
|
* turned off while a test-only type was active, or a scalar type carried onto
|
|
271
371
|
* an RGB image), fall back to the default 2D Image view. */
|
|
372
|
+
/** Whether the live spatial dataset brings pixels of its own — a tissue image it
|
|
373
|
+
* registers onto, or a volume that is published as a z-stack image. */
|
|
374
|
+
private spatialDatasetHasPixels;
|
|
375
|
+
/**
|
|
376
|
+
* The host published NO image — a spatial dataset that brings none does this.
|
|
377
|
+
*
|
|
378
|
+
* Without handling the empty emission, `imageInfo` keeps the LAST image's metadata: the
|
|
379
|
+
* selector goes on offering pixel modes for pixels that are gone, and every
|
|
380
|
+
* `isStack`/`isGrayscale` decision is made against a file that is no longer loaded.
|
|
381
|
+
*/
|
|
382
|
+
private onImageCleared;
|
|
272
383
|
private reconcileSelectedPlotType;
|
|
273
384
|
ngOnInit(): void;
|
|
274
385
|
ngAfterViewInit(): void;
|
|
@@ -302,6 +413,8 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
302
413
|
selectColormap(colormapNode: TreeNode): void;
|
|
303
414
|
/** Open the Channels & Histogram dialog (toolbar button). */
|
|
304
415
|
openChannelHistogram(): void;
|
|
416
|
+
/** Toolbar → open the spatial-omics controls. */
|
|
417
|
+
openSpatialControls(): void;
|
|
305
418
|
/** Open the Region Editor dialog (toolbar button). The editor stays linked to
|
|
306
419
|
* this plotting instance through the root RegionStore singleton, so it works
|
|
307
420
|
* the same as the former right-panel Regions tab. */
|
|
@@ -473,9 +586,28 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
473
586
|
* the toolbar/context-menu logic relies on, deactivates 2D-only tools when
|
|
474
587
|
* moving to a 3D type, then re-plots.
|
|
475
588
|
*/
|
|
476
|
-
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;
|
|
477
609
|
/** Deactivate whatever tool is armed and clear every tool mode. */
|
|
478
610
|
private deactivateActiveTool;
|
|
479
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<VisualizerComponent, [null, null, null, null, null, null, null, null, null, null, { 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; }]>;
|
|
480
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>;
|
|
481
613
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jax-data-science/sci-image-visualizer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"engines": {
|
|
5
|
+
"node": ">=20.9.0"
|
|
6
|
+
},
|
|
4
7
|
"description": "Browser-based scientific image visualization for Angular — gigapixel whole-slide (OpenSeadragon), 2D/3D (Plotly) and WebGPU (napari-js) rendering, with region/annotation editing and in-browser SAM segmentation.",
|
|
5
8
|
"keywords": [
|
|
6
9
|
"angular",
|
|
@@ -34,9 +37,10 @@
|
|
|
34
37
|
"access": "public"
|
|
35
38
|
},
|
|
36
39
|
"dependencies": {
|
|
40
|
+
"@jax-js/jax": "^0.1.24",
|
|
37
41
|
"cellpose-js": "^0.6.0",
|
|
38
42
|
"fast-png": "^6.4.0",
|
|
39
|
-
"napari-js": "^0.
|
|
43
|
+
"napari-js": "^0.14.0",
|
|
40
44
|
"openseadragon": "^6.0.2",
|
|
41
45
|
"plotly.js-dist-min": "^3.0.1",
|
|
42
46
|
"tslib": "^2.3.0"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 512 512">
|
|
2
|
+
<!-- Spatial omics in 3D: the same observations as spatial-omics.svg — dots
|
|
3
|
+
whose SIZE varies with the value they carry — but arranged on a cube
|
|
4
|
+
lattice instead of a flat grid. Two square planes of four, the back one
|
|
5
|
+
offset up-right and drawn smaller, which is the whole 3D cue: no edges,
|
|
6
|
+
no perspective lines, nothing that needs a stroke to survive.
|
|
7
|
+
|
|
8
|
+
Sized for a 16px toolbar icon (1rem in the toolbar, 1.1rem in the
|
|
9
|
+
plot-mode dropdown), which drives every choice, exactly as in the 2D
|
|
10
|
+
icon it sits beside:
|
|
11
|
+
- Solid fills only. Both call sites tint with `filter: brightness(0) …`,
|
|
12
|
+
which flattens every colour to one — tone cannot carry meaning, so
|
|
13
|
+
the arrangement has to.
|
|
14
|
+
- Ink at 6-14% of the viewBox and 23% of the box overall, matching
|
|
15
|
+
spatial-omics.svg so the pair reads at one weight in the toolbar.
|
|
16
|
+
- Eight dots, not the 2D icon's nine plus a second layer: at 16px the
|
|
17
|
+
gaps are what make a lattice legible, and 4+4 keeps every gap above
|
|
18
|
+
2px where an 18-dot stack would silt up into a blob. -->
|
|
19
|
+
<g fill="#000000">
|
|
20
|
+
<!-- front plane -->
|
|
21
|
+
<circle cx="77" cy="180" r="59"/>
|
|
22
|
+
<circle cx="331" cy="180" r="42"/>
|
|
23
|
+
<circle cx="77" cy="434" r="71"/>
|
|
24
|
+
<circle cx="331" cy="434" r="50"/>
|
|
25
|
+
<!-- back plane, offset (+127, -127) and scaled to 0.78 -->
|
|
26
|
+
<circle cx="204" cy="53" r="38"/>
|
|
27
|
+
<circle cx="458" cy="53" r="48"/>
|
|
28
|
+
<circle cx="204" cy="307" r="33"/>
|
|
29
|
+
<circle cx="458" cy="307" r="43"/>
|
|
30
|
+
</g>
|
|
31
|
+
</svg>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 512 512">
|
|
2
|
+
<!-- Spatial omics: an array of observations (spots / cells) whose SIZE varies
|
|
3
|
+
with the value they carry — the thing this plot mode draws.
|
|
4
|
+
Deliberately frameless, so it does not read as cells.svg (the cellpose
|
|
5
|
+
button, a framed dot cluster) sitting in the same toolbar.
|
|
6
|
+
|
|
7
|
+
Sized for a 16px toolbar icon, which drives every choice:
|
|
8
|
+
- Solid fills only. The toolbar tints icons with
|
|
9
|
+
`filter: brightness(0) …`, which flattens every colour to black — a
|
|
10
|
+
white highlight inside a dark shape simply disappears, so shape has to
|
|
11
|
+
carry the meaning, not tone.
|
|
12
|
+
- Ink at ~7-13% of the viewBox. Thin strokes (the 6/512 and 12/512 of the
|
|
13
|
+
previous version) render sub-pixel at 16px, antialias to ~20-40% alpha,
|
|
14
|
+
and the recolour filter then washes them out to an illegible smudge.
|
|
15
|
+
- No low-opacity decoration: invisible at 16px either way. -->
|
|
16
|
+
<g fill="#000000">
|
|
17
|
+
<circle cx="128" cy="128" r="34"/>
|
|
18
|
+
<circle cx="256" cy="128" r="52"/>
|
|
19
|
+
<circle cx="384" cy="128" r="40"/>
|
|
20
|
+
<circle cx="128" cy="256" r="52"/>
|
|
21
|
+
<circle cx="256" cy="256" r="68"/>
|
|
22
|
+
<circle cx="384" cy="256" r="34"/>
|
|
23
|
+
<circle cx="128" cy="384" r="40"/>
|
|
24
|
+
<circle cx="256" cy="384" r="34"/>
|
|
25
|
+
<circle cx="384" cy="384" r="52"/>
|
|
26
|
+
</g>
|
|
27
|
+
</svg>
|