@jax-data-science/sci-image-visualizer 0.1.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/LICENSE +21 -0
- package/README.md +404 -0
- package/esm2022/index.mjs +52 -0
- package/esm2022/jax-data-science-sci-image-visualizer.mjs +5 -0
- package/esm2022/lib/channel-histogram/channel-histogram.component.mjs +398 -0
- package/esm2022/lib/contracts/capabilities.contract.mjs +32 -0
- package/esm2022/lib/contracts/cell-segmenter.contract.mjs +12 -0
- package/esm2022/lib/contracts/channel-histogram-api.contract.mjs +14 -0
- package/esm2022/lib/contracts/colormap-lut.mjs +95 -0
- package/esm2022/lib/contracts/coordinate-transform.contract.mjs +2 -0
- package/esm2022/lib/contracts/display-types.mjs +8 -0
- package/esm2022/lib/contracts/image.contract.mjs +11 -0
- package/esm2022/lib/contracts/intensity.mjs +28 -0
- package/esm2022/lib/contracts/plot-type.mjs +112 -0
- package/esm2022/lib/contracts/ports/image-state.port.mjs +3 -0
- package/esm2022/lib/contracts/ports/preferences.port.mjs +3 -0
- package/esm2022/lib/contracts/ports/region-io.port.mjs +3 -0
- package/esm2022/lib/contracts/ports/tile-access.port.mjs +3 -0
- package/esm2022/lib/contracts/region-editor-api.contract.mjs +4 -0
- package/esm2022/lib/contracts/region-overlay.contract.mjs +2 -0
- package/esm2022/lib/contracts/region-store.contract.mjs +2 -0
- package/esm2022/lib/contracts/sam.contract.mjs +12 -0
- package/esm2022/lib/contracts/toolbar-config.mjs +8 -0
- package/esm2022/lib/contracts/visualizer.contract.mjs +10 -0
- package/esm2022/lib/contracts/viz-config.mjs +3 -0
- package/esm2022/lib/hex-color-picker/hex-color-picker.component.mjs +260 -0
- package/esm2022/lib/implementations/base-store-visualizer.mjs +76 -0
- package/esm2022/lib/implementations/napari-js/napari-axes-labels.mjs +106 -0
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +847 -0
- package/esm2022/lib/implementations/napari-js/napari-scale-bar.mjs +92 -0
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +2283 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-z-handle.mjs +126 -0
- package/esm2022/lib/implementations/osd/display-pipeline.mjs +143 -0
- package/esm2022/lib/implementations/osd/histogram-sampler.mjs +217 -0
- package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +1780 -0
- package/esm2022/lib/implementations/osd/osd-coordinate-transform.mjs +25 -0
- package/esm2022/lib/implementations/osd/osd-coords.mjs +53 -0
- package/esm2022/lib/implementations/osd/osd-lib.mjs +20 -0
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +1237 -0
- package/esm2022/lib/implementations/osd/osd-scale-bar.mjs +88 -0
- package/esm2022/lib/implementations/osd/slice-cache.mjs +488 -0
- package/esm2022/lib/implementations/osd/tile-client.mjs +29 -0
- package/esm2022/lib/implementations/plotly/plotly-coordinate-transform.mjs +37 -0
- package/esm2022/lib/implementations/plotly/plotly-region-overlay.mjs +31 -0
- package/esm2022/lib/implementations/plotly/plotly-trace-builders.mjs +183 -0
- package/esm2022/lib/implementations/plotly/plotly.service.mjs +2137 -0
- package/esm2022/lib/implementations/simple-slice-access.service.mjs +99 -0
- package/esm2022/lib/models/bezier.mjs +120 -0
- package/esm2022/lib/models/class-preset.mjs +46 -0
- package/esm2022/lib/models/geometry.mjs +198 -0
- package/esm2022/lib/models/region.mjs +166 -0
- package/esm2022/lib/models/shape.mjs +53 -0
- package/esm2022/lib/plot.utilities.mjs +693 -0
- package/esm2022/lib/processing/image-converter.service.mjs +90 -0
- package/esm2022/lib/processing/image-crop.mjs +62 -0
- package/esm2022/lib/processing/processing-image.mjs +50 -0
- package/esm2022/lib/provide-visualization.mjs +63 -0
- package/esm2022/lib/region-editor/mask-raster.mjs +95 -0
- package/esm2022/lib/region-editor/mask-worker.mjs +10 -0
- package/esm2022/lib/region-editor/region-editor.component.mjs +1190 -0
- package/esm2022/lib/region-ops.service.mjs +301 -0
- package/esm2022/lib/render-orchestrator.mjs +87 -0
- package/esm2022/lib/routing-visualizer.service.mjs +533 -0
- package/esm2022/lib/store/class-color.util.mjs +52 -0
- package/esm2022/lib/store/region-store.service.mjs +1029 -0
- package/esm2022/lib/store/visualizer-store.service.mjs +352 -0
- package/esm2022/lib/toolbar/brush/brush-tool.service.mjs +546 -0
- package/esm2022/lib/toolbar/crop/slide-crop.mjs +57 -0
- package/esm2022/lib/toolbar/segmentation/cell-segment-tool.service.mjs +115 -0
- package/esm2022/lib/toolbar/segmentation/cellpose-segmenter.service.mjs +84 -0
- package/esm2022/lib/toolbar/segmentation/onnx-sam-session.mjs +133 -0
- package/esm2022/lib/toolbar/segmentation/ort-runtime-config.mjs +31 -0
- package/esm2022/lib/toolbar/segmentation/sam-model-registry.mjs +108 -0
- package/esm2022/lib/toolbar/segmentation/sam-onnx-core.mjs +159 -0
- package/esm2022/lib/toolbar/segmentation/sam-point-tool.service.mjs +255 -0
- package/esm2022/lib/toolbar/segmentation/sam-prompt.mjs +94 -0
- package/esm2022/lib/toolbar/segmentation/sam-tool.service.mjs +188 -0
- package/esm2022/lib/toolbar/toolbar.component.mjs +311 -0
- package/esm2022/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.mjs +234 -0
- package/esm2022/lib/toolbar/wand/wand-tool.service.mjs +499 -0
- package/esm2022/lib/toolbar/wand/wand.service.mjs +921 -0
- package/esm2022/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.mjs +157 -0
- package/esm2022/lib/visualization.module.mjs +162 -0
- package/esm2022/lib/visualizer.component.mjs +1597 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-mask-worker-uhepXUhM.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-mask-worker-uhepXUhM.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-ci1q0xnJ.mjs +327 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-ci1q0xnJ.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +21314 -0
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -0
- package/fesm2022/mask.worker.js +989 -0
- package/fesm2022/onnx-sam.worker.js +202 -0
- package/index.d.ts +39 -0
- package/lib/channel-histogram/channel-histogram.component.d.ts +112 -0
- package/lib/contracts/capabilities.contract.d.ts +30 -0
- package/lib/contracts/cell-segmenter.contract.d.ts +40 -0
- package/lib/contracts/channel-histogram-api.contract.d.ts +98 -0
- package/lib/contracts/colormap-lut.d.ts +21 -0
- package/lib/contracts/coordinate-transform.contract.d.ts +43 -0
- package/lib/contracts/display-types.d.ts +41 -0
- package/lib/contracts/image.contract.d.ts +72 -0
- package/lib/contracts/intensity.d.ts +18 -0
- package/lib/contracts/plot-type.d.ts +108 -0
- package/lib/contracts/ports/image-state.port.d.ts +29 -0
- package/lib/contracts/ports/preferences.port.d.ts +19 -0
- package/lib/contracts/ports/region-io.port.d.ts +29 -0
- package/lib/contracts/ports/tile-access.port.d.ts +27 -0
- package/lib/contracts/region-editor-api.contract.d.ts +83 -0
- package/lib/contracts/region-overlay.contract.d.ts +47 -0
- package/lib/contracts/region-store.contract.d.ts +74 -0
- package/lib/contracts/sam.contract.d.ts +98 -0
- package/lib/contracts/toolbar-config.d.ts +24 -0
- package/lib/contracts/visualizer.contract.d.ts +346 -0
- package/lib/contracts/viz-config.d.ts +25 -0
- package/lib/hex-color-picker/hex-color-picker.component.d.ts +47 -0
- package/lib/implementations/base-store-visualizer.d.ts +71 -0
- package/lib/implementations/napari-js/napari-axes-labels.d.ts +47 -0
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +115 -0
- package/lib/implementations/napari-js/napari-scale-bar.d.ts +31 -0
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +455 -0
- package/lib/implementations/napari-js/napari-volume-z-handle.d.ts +46 -0
- package/lib/implementations/osd/display-pipeline.d.ts +47 -0
- package/lib/implementations/osd/histogram-sampler.d.ts +85 -0
- package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +476 -0
- package/lib/implementations/osd/osd-coordinate-transform.d.ts +17 -0
- package/lib/implementations/osd/osd-coords.d.ts +16 -0
- package/lib/implementations/osd/osd-lib.d.ts +19 -0
- package/lib/implementations/osd/osd-region-overlay.d.ts +191 -0
- package/lib/implementations/osd/osd-scale-bar.d.ts +17 -0
- package/lib/implementations/osd/slice-cache.d.ts +161 -0
- package/lib/implementations/osd/tile-client.d.ts +32 -0
- package/lib/implementations/plotly/plotly-coordinate-transform.d.ts +19 -0
- package/lib/implementations/plotly/plotly-region-overlay.d.ts +23 -0
- package/lib/implementations/plotly/plotly-trace-builders.d.ts +60 -0
- package/lib/implementations/plotly/plotly.service.d.ts +594 -0
- package/lib/implementations/simple-slice-access.service.d.ts +64 -0
- package/lib/models/bezier.d.ts +59 -0
- package/lib/models/class-preset.d.ts +39 -0
- package/lib/models/geometry.d.ts +66 -0
- package/lib/models/region.d.ts +132 -0
- package/lib/models/shape.d.ts +44 -0
- package/lib/plot.utilities.d.ts +107 -0
- package/lib/processing/image-converter.service.d.ts +28 -0
- package/lib/processing/image-crop.d.ts +18 -0
- package/lib/processing/processing-image.d.ts +17 -0
- package/lib/provide-visualization.d.ts +34 -0
- package/lib/region-editor/mask-raster.d.ts +61 -0
- package/lib/region-editor/mask-worker.d.ts +7 -0
- package/lib/region-editor/region-editor.component.d.ts +305 -0
- package/lib/region-ops.service.d.ts +92 -0
- package/lib/render-orchestrator.d.ts +59 -0
- package/lib/routing-visualizer.service.d.ts +227 -0
- package/lib/store/class-color.util.d.ts +26 -0
- package/lib/store/region-store.service.d.ts +315 -0
- package/lib/store/visualizer-store.service.d.ts +123 -0
- package/lib/toolbar/brush/brush-tool.service.d.ts +143 -0
- package/lib/toolbar/crop/slide-crop.d.ts +30 -0
- package/lib/toolbar/segmentation/cell-segment-tool.service.d.ts +32 -0
- package/lib/toolbar/segmentation/cellpose-segmenter.service.d.ts +39 -0
- package/lib/toolbar/segmentation/onnx-sam-session.d.ts +25 -0
- package/lib/toolbar/segmentation/ort-runtime-config.d.ts +4 -0
- package/lib/toolbar/segmentation/sam-model-registry.d.ts +36 -0
- package/lib/toolbar/segmentation/sam-onnx-core.d.ts +48 -0
- package/lib/toolbar/segmentation/sam-point-tool.service.d.ts +59 -0
- package/lib/toolbar/segmentation/sam-prompt.d.ts +34 -0
- package/lib/toolbar/segmentation/sam-tool.service.d.ts +50 -0
- package/lib/toolbar/toolbar.component.d.ts +167 -0
- package/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.d.ts +64 -0
- package/lib/toolbar/wand/wand-tool.service.d.ts +149 -0
- package/lib/toolbar/wand/wand.service.d.ts +133 -0
- package/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.d.ts +49 -0
- package/lib/visualization.module.d.ts +45 -0
- package/lib/visualizer.component.d.ts +378 -0
- package/package.json +73 -0
- package/src/lib/assets/3d-coordinates.svg +49 -0
- package/src/lib/assets/cells.svg +1 -0
- package/src/lib/assets/click.svg +1 -0
- package/src/lib/assets/colormap-luts.json +1 -0
- package/src/lib/assets/contour.svg +48 -0
- package/src/lib/assets/cube-3d.svg +1 -0
- package/src/lib/assets/edit-selection-white.svg +47 -0
- package/src/lib/assets/heatmap.svg +1 -0
- package/src/lib/assets/icons/colormap-Pastel1.png +0 -0
- package/src/lib/assets/icons/colormap-accent.png +0 -0
- package/src/lib/assets/icons/colormap-afmhot.png +0 -0
- package/src/lib/assets/icons/colormap-autumn.png +0 -0
- package/src/lib/assets/icons/colormap-berlin.png +0 -0
- package/src/lib/assets/icons/colormap-binary.png +0 -0
- package/src/lib/assets/icons/colormap-blackbody.png +0 -0
- package/src/lib/assets/icons/colormap-bluered.png +0 -0
- package/src/lib/assets/icons/colormap-blues.png +0 -0
- package/src/lib/assets/icons/colormap-bone.png +0 -0
- package/src/lib/assets/icons/colormap-brbg.png +0 -0
- package/src/lib/assets/icons/colormap-brg.png +0 -0
- package/src/lib/assets/icons/colormap-bugn.png +0 -0
- package/src/lib/assets/icons/colormap-bupu.png +0 -0
- package/src/lib/assets/icons/colormap-bwr.png +0 -0
- package/src/lib/assets/icons/colormap-cividis.png +0 -0
- package/src/lib/assets/icons/colormap-cmrmap.png +0 -0
- package/src/lib/assets/icons/colormap-cool.png +0 -0
- package/src/lib/assets/icons/colormap-coolwarm.png +0 -0
- package/src/lib/assets/icons/colormap-copper.png +0 -0
- package/src/lib/assets/icons/colormap-cubehelix.png +0 -0
- package/src/lib/assets/icons/colormap-dark2.png +0 -0
- package/src/lib/assets/icons/colormap-earth.png +0 -0
- package/src/lib/assets/icons/colormap-electric.png +0 -0
- package/src/lib/assets/icons/colormap-flag.png +0 -0
- package/src/lib/assets/icons/colormap-gist_earth.png +0 -0
- package/src/lib/assets/icons/colormap-gist_gray.png +0 -0
- package/src/lib/assets/icons/colormap-gist_heat.png +0 -0
- package/src/lib/assets/icons/colormap-gist_ncar.png +0 -0
- package/src/lib/assets/icons/colormap-gist_rainbow.png +0 -0
- package/src/lib/assets/icons/colormap-gist_stern.png +0 -0
- package/src/lib/assets/icons/colormap-gist_yarg.png +0 -0
- package/src/lib/assets/icons/colormap-gnbu.png +0 -0
- package/src/lib/assets/icons/colormap-gnuplot.png +0 -0
- package/src/lib/assets/icons/colormap-gnuplot2.png +0 -0
- package/src/lib/assets/icons/colormap-gray.png +0 -0
- package/src/lib/assets/icons/colormap-greens-inv.png +0 -0
- package/src/lib/assets/icons/colormap-greens.png +0 -0
- package/src/lib/assets/icons/colormap-greys-inv.png +0 -0
- package/src/lib/assets/icons/colormap-greys.png +0 -0
- package/src/lib/assets/icons/colormap-hot.png +0 -0
- package/src/lib/assets/icons/colormap-hsv.png +0 -0
- package/src/lib/assets/icons/colormap-inferno.png +0 -0
- package/src/lib/assets/icons/colormap-jet.png +0 -0
- package/src/lib/assets/icons/colormap-magma.png +0 -0
- package/src/lib/assets/icons/colormap-managua.png +0 -0
- package/src/lib/assets/icons/colormap-nipy_spectral.png +0 -0
- package/src/lib/assets/icons/colormap-ocean.png +0 -0
- package/src/lib/assets/icons/colormap-oranges.png +0 -0
- package/src/lib/assets/icons/colormap-orrd.png +0 -0
- package/src/lib/assets/icons/colormap-pastel2.png +0 -0
- package/src/lib/assets/icons/colormap-picnic.png +0 -0
- package/src/lib/assets/icons/colormap-pink.png +0 -0
- package/src/lib/assets/icons/colormap-piyg.png +0 -0
- package/src/lib/assets/icons/colormap-placeholder.png +0 -0
- package/src/lib/assets/icons/colormap-plasma.png +0 -0
- package/src/lib/assets/icons/colormap-portland.png +0 -0
- package/src/lib/assets/icons/colormap-prgn.png +0 -0
- package/src/lib/assets/icons/colormap-prism.png +0 -0
- package/src/lib/assets/icons/colormap-pubu.png +0 -0
- package/src/lib/assets/icons/colormap-pubugn.png +0 -0
- package/src/lib/assets/icons/colormap-puor.png +0 -0
- package/src/lib/assets/icons/colormap-purd.png +0 -0
- package/src/lib/assets/icons/colormap-purples.png +0 -0
- package/src/lib/assets/icons/colormap-rainbow.png +0 -0
- package/src/lib/assets/icons/colormap-rdbu.png +0 -0
- package/src/lib/assets/icons/colormap-rdgy.png +0 -0
- package/src/lib/assets/icons/colormap-rdpu.png +0 -0
- package/src/lib/assets/icons/colormap-rdylbu.png +0 -0
- package/src/lib/assets/icons/colormap-rdylgn.png +0 -0
- package/src/lib/assets/icons/colormap-reds.png +0 -0
- package/src/lib/assets/icons/colormap-seismic.png +0 -0
- package/src/lib/assets/icons/colormap-set1.png +0 -0
- package/src/lib/assets/icons/colormap-set2.png +0 -0
- package/src/lib/assets/icons/colormap-set3.png +0 -0
- package/src/lib/assets/icons/colormap-spectral.png +0 -0
- package/src/lib/assets/icons/colormap-spring.png +0 -0
- package/src/lib/assets/icons/colormap-summer.png +0 -0
- package/src/lib/assets/icons/colormap-tab10.png +0 -0
- package/src/lib/assets/icons/colormap-tab20.png +0 -0
- package/src/lib/assets/icons/colormap-tab20b.png +0 -0
- package/src/lib/assets/icons/colormap-tab20c.png +0 -0
- package/src/lib/assets/icons/colormap-terrain.png +0 -0
- package/src/lib/assets/icons/colormap-turbo.png +0 -0
- package/src/lib/assets/icons/colormap-twilight.png +0 -0
- package/src/lib/assets/icons/colormap-twilight_shifted.png +0 -0
- package/src/lib/assets/icons/colormap-vanimo.png +0 -0
- package/src/lib/assets/icons/colormap-viridis.png +0 -0
- package/src/lib/assets/icons/colormap-winter.png +0 -0
- package/src/lib/assets/icons/colormap-wistia.png +0 -0
- package/src/lib/assets/icons/colormap-ylgn.png +0 -0
- package/src/lib/assets/icons/colormap-ylgnbu-inv.png +0 -0
- package/src/lib/assets/icons/colormap-ylgnbu.png +0 -0
- package/src/lib/assets/icons/colormap-ylorbr.png +0 -0
- package/src/lib/assets/icons/colormap-ylorrd-inv.png +0 -0
- package/src/lib/assets/icons/colormap-ylorrd.png +0 -0
- package/src/lib/assets/interactive-segmentation-cursor.svg +1 -0
- package/src/lib/assets/invert.svg +1 -0
- package/src/lib/assets/isosurface.svg +7 -0
- package/src/lib/assets/mask.svg +1 -0
- package/src/lib/assets/paintbrush.svg +1 -0
- package/src/lib/assets/picture-segmentation.svg +43 -0
- package/src/lib/assets/polygon-vertices.svg +13 -0
- package/src/lib/assets/polyline.svg +3 -0
- package/src/lib/assets/redo.svg +39 -0
- package/src/lib/assets/region-editor.svg +37 -0
- package/src/lib/assets/region-move.svg +7 -0
- package/src/lib/assets/smooth.svg +56 -0
- package/src/lib/assets/spline-chart.svg +7 -0
- package/src/lib/assets/surface.svg +37 -0
- package/src/lib/assets/test/download-379.svg +1 -0
- package/src/lib/assets/test/download-98.svg +1 -0
- package/src/lib/assets/test/json-1.svg +1 -0
- package/src/lib/assets/test/load-53.svg +1 -0
- package/src/lib/assets/test/mask-44.svg +1 -0
- package/src/lib/assets/test/mask-download-44.svg +15 -0
- package/src/lib/assets/test/mask-save-44.svg +11 -0
- package/src/lib/assets/test/overlay-1.svg +1 -0
- package/src/lib/assets/test/overlay-4.svg +1 -0
- package/src/lib/assets/test/region-26.svg +1 -0
- package/src/lib/assets/test/save-56.svg +1 -0
- package/src/lib/assets/test/upload-43.svg +1 -0
- package/src/lib/assets/to-bezier.svg +15 -0
- package/src/lib/assets/to-polygon.svg +11 -0
- package/src/lib/assets/undo.svg +38 -0
- package/src/lib/assets/vertex-add.svg +12 -0
- package/src/lib/assets/vertex-delete.svg +12 -0
- package/src/lib/assets/wand.svg +54 -0
- package/src/lib/assets/zoom-box.svg +10 -0
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
import { Image } from 'image-js';
|
|
2
|
+
import { HttpClient } from '@angular/common/http';
|
|
3
|
+
import { Polygon, Rectangle, Region } from '../../models/region';
|
|
4
|
+
import { IImageInfo, IImageMetadata } from '../../contracts/image.contract';
|
|
5
|
+
import { TileAccessPort } from '../../contracts/ports/tile-access.port';
|
|
6
|
+
import { ImageStatePort } from '../../contracts/ports/image-state.port';
|
|
7
|
+
import { Observable } from 'rxjs';
|
|
8
|
+
import { MessageService } from 'primeng/api';
|
|
9
|
+
import { ShapeSelection } from '../../models/shape';
|
|
10
|
+
import { WandService, WandOptions } from '../../toolbar/wand/wand.service';
|
|
11
|
+
import { WandToolService } from '../../toolbar/wand/wand-tool.service';
|
|
12
|
+
import { BrushToolService, BrushOptions } from '../../toolbar/brush/brush-tool.service';
|
|
13
|
+
import { SamToolService } from '../../toolbar/segmentation/sam-tool.service';
|
|
14
|
+
import { SamPointToolService } from '../../toolbar/segmentation/sam-point-tool.service';
|
|
15
|
+
import { CellSegmentToolService } from '../../toolbar/segmentation/cell-segment-tool.service';
|
|
16
|
+
import { ICellSegmenter } from '../../contracts/cell-segmenter.contract';
|
|
17
|
+
import { VertexEraserToolService } from '../../toolbar/vertex-eraser/vertex-eraser-tool.service';
|
|
18
|
+
import { ZoomToBoxToolService } from '../../toolbar/zoom-to-box/zoom-to-box-tool.service';
|
|
19
|
+
import { PlotType, PlotTypeDescriptor } from '../../contracts/plot-type';
|
|
20
|
+
import { IVisualizer, IntensityProfile, IIsosurfaceControls, IIntensityControls } from '../../contracts/visualizer.contract';
|
|
21
|
+
import { IHistogram } from '../../contracts/channel-histogram-api.contract';
|
|
22
|
+
import { ViewerCapabilities } from '../../contracts/capabilities.contract';
|
|
23
|
+
import { IRegionOverlay } from '../../contracts/region-overlay.contract';
|
|
24
|
+
import { ICoordinateTransform } from '../../contracts/coordinate-transform.contract';
|
|
25
|
+
import { VisualizerStore } from '../../store/visualizer-store.service';
|
|
26
|
+
import { RegionStore } from '../../store/region-store.service';
|
|
27
|
+
import * as i0 from "@angular/core";
|
|
28
|
+
export { PlotType } from '../../contracts/plot-type';
|
|
29
|
+
export declare class PlotlyService implements IVisualizer {
|
|
30
|
+
private tiles;
|
|
31
|
+
private state;
|
|
32
|
+
messageService: MessageService;
|
|
33
|
+
private http;
|
|
34
|
+
private wandService;
|
|
35
|
+
private wandTool;
|
|
36
|
+
private brushTool;
|
|
37
|
+
private samTool;
|
|
38
|
+
private samPointTool;
|
|
39
|
+
private cellSegmentTool;
|
|
40
|
+
private cellSegmenter;
|
|
41
|
+
private vertexEraserTool;
|
|
42
|
+
private zoomToBoxTool;
|
|
43
|
+
private store;
|
|
44
|
+
private regionStore;
|
|
45
|
+
/**
|
|
46
|
+
* Plotly is the full-featured data backend: it supports every feature,
|
|
47
|
+
* including 3D scenes, live scalar colormaps, pixel readback and the
|
|
48
|
+
* server-side high-def zoom re-fetch. (OpenSeadragon's stub advertises only
|
|
49
|
+
* image display.)
|
|
50
|
+
*/
|
|
51
|
+
readonly capabilities: ViewerCapabilities;
|
|
52
|
+
private shapes;
|
|
53
|
+
private previousShapes;
|
|
54
|
+
private isRegionSavedOn;
|
|
55
|
+
private imageLength;
|
|
56
|
+
private screenHeight;
|
|
57
|
+
private plotDiv;
|
|
58
|
+
private isRealZoom;
|
|
59
|
+
private scaleratio;
|
|
60
|
+
private trueImgSize;
|
|
61
|
+
private zoomCoordinates;
|
|
62
|
+
private fileName;
|
|
63
|
+
private dragMode;
|
|
64
|
+
private urls;
|
|
65
|
+
imageInfo: IImageInfo;
|
|
66
|
+
private plotUtilities;
|
|
67
|
+
private plotType;
|
|
68
|
+
private onPlotMouseDown;
|
|
69
|
+
/** Pixel data cached for wand sampling. data[zIndex] is a 2-D matrix. */
|
|
70
|
+
private cachedImageFrames?;
|
|
71
|
+
private cachedImageWidth;
|
|
72
|
+
private cachedImageHeight;
|
|
73
|
+
private cachedImageRatios;
|
|
74
|
+
private cachedIsGrayscale;
|
|
75
|
+
/** Data-space coordinate of the cached frame's pixel (0,0). [0,0] for the full
|
|
76
|
+
* image; a crop's top-left when zoomed (so the intensity profile samples the
|
|
77
|
+
* zoom-level pixels at the right offset/resolution). */
|
|
78
|
+
private cachedFrameOrigin;
|
|
79
|
+
/** Last visible image-pixel rectangle from the active backend's viewport (set by
|
|
80
|
+
* the OSD viewport-change hook via refreshIntensitySamplingForRoi). New profile lines are
|
|
81
|
+
* placed within it so they land on-screen when zoomed in; null → use full image. */
|
|
82
|
+
private lastVisibleRoi;
|
|
83
|
+
/** events */
|
|
84
|
+
private onRelayoutEvent;
|
|
85
|
+
private stackLoading$;
|
|
86
|
+
private stackLoadingProgress$;
|
|
87
|
+
private zIndex;
|
|
88
|
+
private autoscaleEvent;
|
|
89
|
+
/** Bright, well-separated colours cycled as the user adds profile-line ROIs.
|
|
90
|
+
* The matching inset trace is drawn in the same colour. */
|
|
91
|
+
private readonly PROFILE_PALETTE;
|
|
92
|
+
/** Palette cursor for profile lines (never reset on delete, so colours keep
|
|
93
|
+
* cycling across the session). */
|
|
94
|
+
private profileColorSeq;
|
|
95
|
+
private intensityProfile$;
|
|
96
|
+
/** ISOSURFACE band as a 0–255 slider position, mapped onto the volume's real
|
|
97
|
+
* intensity range at render time (see mapIsoBand). Defaults to the full range
|
|
98
|
+
* so the first render shows the whole structure regardless of how bright or
|
|
99
|
+
* dark the volume is; the user then narrows the band to isolate intensities. */
|
|
100
|
+
private isoMin;
|
|
101
|
+
private isoMax;
|
|
102
|
+
/** Actual intensity range of the volume on screen ([min,max] over the loaded
|
|
103
|
+
* frames). The slider spans 0–255, but a given stack often occupies only a
|
|
104
|
+
* sub-range, so we clamp the iso band into this range (with a small margin)
|
|
105
|
+
* to guarantee non-degenerate surfaces — both on first render and on live
|
|
106
|
+
* slider moves. Null until an isosurface volume has been measured. */
|
|
107
|
+
private isoDataRange;
|
|
108
|
+
private imageCached;
|
|
109
|
+
private imageCachedSubscription;
|
|
110
|
+
private filenameSubscription;
|
|
111
|
+
/** Drives the intensity inset off region adds/drags/deletes (both backends). */
|
|
112
|
+
private regionUpdateSubscription?;
|
|
113
|
+
/** Live (per-frame, non-coalesced) region edits — so the inset tracks an OSD
|
|
114
|
+
* line ROI live during a drag (OSD batches regionUpdate$ until release). */
|
|
115
|
+
private regionLiveEditSubscription?;
|
|
116
|
+
private channelSub?;
|
|
117
|
+
private wandHost;
|
|
118
|
+
private eraserHost;
|
|
119
|
+
/** This backend's region renderer (lazily created in getRegionOverlay). */
|
|
120
|
+
private regionOverlay?;
|
|
121
|
+
private readonly coordinateTransform;
|
|
122
|
+
constructor(tiles: TileAccessPort, state: ImageStatePort, messageService: MessageService, http: HttpClient, wandService: WandService, wandTool: WandToolService, brushTool: BrushToolService, samTool: SamToolService, samPointTool: SamPointToolService, cellSegmentTool: CellSegmentToolService, cellSegmenter: ICellSegmenter | null, vertexEraserTool: VertexEraserToolService, zoomToBoxTool: ZoomToBoxToolService, store: VisualizerStore, regionStore: RegionStore);
|
|
123
|
+
getTrueImageSize(): {
|
|
124
|
+
width: number;
|
|
125
|
+
height: number;
|
|
126
|
+
} | null;
|
|
127
|
+
/**
|
|
128
|
+
* Load image
|
|
129
|
+
* @param imageInfo
|
|
130
|
+
* @param zIndex index of the image to load
|
|
131
|
+
* @return an object with data and ratio keys
|
|
132
|
+
*/
|
|
133
|
+
load(imageInfo: IImageInfo, zIndex: number): Promise<{
|
|
134
|
+
data: any[];
|
|
135
|
+
ratios: number[];
|
|
136
|
+
sizes: number[];
|
|
137
|
+
filename: string;
|
|
138
|
+
}>;
|
|
139
|
+
/**
|
|
140
|
+
*
|
|
141
|
+
* @param plotDiv
|
|
142
|
+
* @param imageLoaded object with data, ratios and sizes key
|
|
143
|
+
* @param imageInfo ImageInfo object
|
|
144
|
+
* @param screenHeight size of the available screen height
|
|
145
|
+
* @param plotType type of plotting
|
|
146
|
+
*/
|
|
147
|
+
/**
|
|
148
|
+
* @param inPlace when true, updates the existing plot via Plotly.react
|
|
149
|
+
* instead of Plotly.purge + Plotly.newPlot. Used by the multi-tier
|
|
150
|
+
* diagram swap (small → large) so the canvas doesn't briefly blank
|
|
151
|
+
* between phases.
|
|
152
|
+
*/
|
|
153
|
+
plot(plotDiv: string, imageLoaded: any, imageInfo: IImageInfo, screenHeight: number, plotType: PlotType, inPlace?: boolean): Promise<boolean>;
|
|
154
|
+
/**
|
|
155
|
+
* Function used to plot a grayscale heatmap
|
|
156
|
+
* @param plotDiv
|
|
157
|
+
* @param urls
|
|
158
|
+
* @param images
|
|
159
|
+
* @param trueImgSize array containing the following : [x0, x1, y0, y1]
|
|
160
|
+
* @param ratios
|
|
161
|
+
* @param screenHeight
|
|
162
|
+
* @return Promise true when plotting is finished
|
|
163
|
+
*/
|
|
164
|
+
private plotHeatmap;
|
|
165
|
+
/**
|
|
166
|
+
* Function used to plot a grayscale surface
|
|
167
|
+
* @param plotDiv
|
|
168
|
+
* @param urls
|
|
169
|
+
* @param images
|
|
170
|
+
* @param trueImgSize array containing the following : [x0, x1, y0, y1]
|
|
171
|
+
* @param ratios
|
|
172
|
+
* @param screenHeight
|
|
173
|
+
* @return Promise true when plotting is finished
|
|
174
|
+
*/
|
|
175
|
+
private plotSurface;
|
|
176
|
+
/**
|
|
177
|
+
* Function used to plot an RGB heatmap
|
|
178
|
+
* @param plotDiv
|
|
179
|
+
* @param urls
|
|
180
|
+
* @param images
|
|
181
|
+
* @param trueImgSize
|
|
182
|
+
* @param width
|
|
183
|
+
* @param height
|
|
184
|
+
* @param ratios
|
|
185
|
+
* @param screenHeight
|
|
186
|
+
* @return Promise
|
|
187
|
+
*/
|
|
188
|
+
private plotRGBHeatmap;
|
|
189
|
+
/**
|
|
190
|
+
* Assemble the normalised input the pluggable trace builders consume.
|
|
191
|
+
* Pure data only — no Plotly handles — so the builders stay backend-neutral.
|
|
192
|
+
*/
|
|
193
|
+
private buildTraceInput;
|
|
194
|
+
/** Min/max intensity over every voxel of the loaded frames (RGB → luminance),
|
|
195
|
+
* used to keep the iso band inside the data. Returns null for empty input. */
|
|
196
|
+
private measureIntensityRange;
|
|
197
|
+
/** Map the 0–255 slider band onto the volume's actual intensity range. The
|
|
198
|
+
* slider is fixed 0–255, but a stack often occupies only a narrow sub-range
|
|
199
|
+
* (e.g. this EDOF volume is ~2–50 with structure near 6–10). Mapping spreads
|
|
200
|
+
* the data across the whole slider so every intensity is easy to reach and
|
|
201
|
+
* the band always lands inside the data — a small inset keeps the extreme
|
|
202
|
+
* surfaces off the exact data edges, which are degenerate and draw nothing. */
|
|
203
|
+
private mapIsoBand;
|
|
204
|
+
/**
|
|
205
|
+
* Update the isosurface intensity bounds. When isosurface is on screen this
|
|
206
|
+
* restyles `isomin`/`isomax` in place for a live update (no volume rebuild).
|
|
207
|
+
* Slider values are mapped onto the volume's real range so the surfaces always
|
|
208
|
+
* have data to cross (matching the initial render).
|
|
209
|
+
*/
|
|
210
|
+
setIsoRange(isoMin: number, isoMax: number): void;
|
|
211
|
+
/** Plotly renders isosurfaces, so it exposes the isosurface controls (itself). */
|
|
212
|
+
getIsosurfaceControls(): IIsosurfaceControls | null;
|
|
213
|
+
/**
|
|
214
|
+
* Render a registry-backed plot type: build its traces from the input, pick
|
|
215
|
+
* the matching layout, render, and wire the usual relayout/click events.
|
|
216
|
+
* Mirrors the structure of the dedicated heatmap/surface renderers.
|
|
217
|
+
*/
|
|
218
|
+
private plotViaRegistry;
|
|
219
|
+
/** Plain 2D chart axes (intensity profile / line plots). */
|
|
220
|
+
private getChartLayout;
|
|
221
|
+
/** Image-aligned 2D axes without the z-plane slider (region scatter). */
|
|
222
|
+
private getOverlayLayout;
|
|
223
|
+
/** 3D scene for volumetric plot types (scatter3d, isosurface). */
|
|
224
|
+
private getVolumeLayout;
|
|
225
|
+
/** Plot types this backend advertises (drives the UI selector). */
|
|
226
|
+
getPlotTypeDescriptors(): PlotTypeDescriptor[];
|
|
227
|
+
/** This backend's region renderer. Plotly draws shapes natively, so the
|
|
228
|
+
* overlay is a thin adapter over this service's drag modes. */
|
|
229
|
+
getRegionOverlay(): IRegionOverlay;
|
|
230
|
+
/** Emits the full set of intensity profiles (one per profile-line region)
|
|
231
|
+
* whenever a profile line is added, moved, or removed. */
|
|
232
|
+
getIntensityProfile$(): Observable<IntensityProfile[]>;
|
|
233
|
+
/** Plotly renders the line ROIs + inset, so it exposes the intensity controls. */
|
|
234
|
+
getIntensityControls(): IIntensityControls | null;
|
|
235
|
+
/**
|
|
236
|
+
* Render the floating intensity-profile inset chart into `divId` — one line
|
|
237
|
+
* trace per ROI, each drawn in its ROI's colour. Kept here (not in the diagram
|
|
238
|
+
* component) so the consumer never touches Plotly directly.
|
|
239
|
+
*/
|
|
240
|
+
renderIntensityInset(divId: string, profiles: IntensityProfile[]): void;
|
|
241
|
+
/**
|
|
242
|
+
* Region shapes (filtered/redrawn for the current file). The profile-line ROIs
|
|
243
|
+
* are ordinary store regions (tagged `kind: 'profile'`), so they are already
|
|
244
|
+
* part of `this.shapes` — no separate append is needed.
|
|
245
|
+
*/
|
|
246
|
+
private currentRenderShapes;
|
|
247
|
+
/**
|
|
248
|
+
* IIntensityControls: add another intensity-profile line as a neutral Region
|
|
249
|
+
* (tagged `kind: 'profile'`). It is a horizontal open 2-point polyline spanning
|
|
250
|
+
* the image width, staggered vertically so successive lines stay distinct, in
|
|
251
|
+
* the next bright palette colour. Added to the shared store so both backends
|
|
252
|
+
* (Plotly + OpenSeadragon) render and drag it; excluded from the Regions tab
|
|
253
|
+
* and exports by its kind.
|
|
254
|
+
*/
|
|
255
|
+
addProfileLine(): Region | null;
|
|
256
|
+
/** The profile-line ROIs currently in the store (kind === 'profile'). */
|
|
257
|
+
private getProfileRegions;
|
|
258
|
+
/** Recompute and broadcast a profile for every profile-line region (id + colour
|
|
259
|
+
* tagged so the inset trace matches its line). */
|
|
260
|
+
private emitProfiles;
|
|
261
|
+
/**
|
|
262
|
+
* Sample the intensity profile for a profile-line region: extract its two
|
|
263
|
+
* polygon endpoints and reuse the shared `computeIntensityProfile` sampling.
|
|
264
|
+
*/
|
|
265
|
+
private computeIntensityProfileForRegion;
|
|
266
|
+
/**
|
|
267
|
+
* Supply pixel frames for intensity sampling (used by the OSD/image backend,
|
|
268
|
+
* whose cached frames may be empty). Optionally also sets the data/pixel ratios.
|
|
269
|
+
*/
|
|
270
|
+
setSamplingFrames(frames: any[], ratios: number[], origin?: [number, number]): void;
|
|
271
|
+
/**
|
|
272
|
+
* Populate the sampling cache for the intensity profiles when OpenSeadragon is
|
|
273
|
+
* the active backend (the Image plot type). In OSD mode Plotly never rendered,
|
|
274
|
+
* so `cachedImageFrames`/`trueImgSize` are unset — fetch the current slice's
|
|
275
|
+
* preview (the same pixels the heatmap would sample) so the line ROIs have
|
|
276
|
+
* pixel data and a placement extent. Re-emits the profiles once loaded.
|
|
277
|
+
*/
|
|
278
|
+
ensureIntensitySampling(imageInfo: IImageInfo, zIndex: number): Promise<void>;
|
|
279
|
+
/**
|
|
280
|
+
* {@link IIntensitySampling} stub — the viewport-change signal is OpenSeadragon's
|
|
281
|
+
* (it re-samples on OSD zoom/pan). Plotly's own high-def zoom updates the
|
|
282
|
+
* sampling cache inline, so it never emits here; returns EMPTY so a uniform
|
|
283
|
+
* `IVisualizer` consumer can subscribe regardless of the active backend.
|
|
284
|
+
*/
|
|
285
|
+
getViewportChange$(): Observable<{
|
|
286
|
+
x: number;
|
|
287
|
+
y: number;
|
|
288
|
+
width: number;
|
|
289
|
+
height: number;
|
|
290
|
+
}>;
|
|
291
|
+
/**
|
|
292
|
+
* Re-fetch the given image-pixel ROI at the display resolution and use it as
|
|
293
|
+
* the intensity-sampling source, so the profile reflects the data at the
|
|
294
|
+
* current zoom level. Shared by both backends: the OSD viewport-change hook
|
|
295
|
+
* calls it on zoom/pan; Plotly's own high-def zoom (triggerZoom) updates the
|
|
296
|
+
* same cache inline. `roi` is in full-image pixel coordinates.
|
|
297
|
+
*/
|
|
298
|
+
refreshIntensitySamplingForRoi(x: number, y: number, width: number, height: number, zIndex: number): void;
|
|
299
|
+
/**
|
|
300
|
+
* Sample the active frame's intensity (grayscale value or RGB luminance)
|
|
301
|
+
* along the line ROI. Returns distance-along-line positions and values.
|
|
302
|
+
*/
|
|
303
|
+
private computeIntensityProfile;
|
|
304
|
+
/** Physical pixel size (microns/pixel) for the current image, if known.
|
|
305
|
+
* mpp is constant across frames/channels, so the first metadata entry that
|
|
306
|
+
* carries a positive mppX wins. Returns nulls when the image is unscaled. */
|
|
307
|
+
private currentMpp;
|
|
308
|
+
/**
|
|
309
|
+
* autoscale the plot
|
|
310
|
+
*/
|
|
311
|
+
autoscale(): void;
|
|
312
|
+
/**
|
|
313
|
+
* relayout the plot
|
|
314
|
+
*/
|
|
315
|
+
relayout(trueImageSize?: number[]): void;
|
|
316
|
+
private setEvents;
|
|
317
|
+
private relayoutEventHandler;
|
|
318
|
+
reloadAndPlot(): void;
|
|
319
|
+
setWandMode(active: boolean, options?: WandOptions): void;
|
|
320
|
+
setWandOptions(options: WandOptions): void;
|
|
321
|
+
clearActiveWandRegion(): void;
|
|
322
|
+
setBrushMode(active: boolean, options?: BrushOptions): void;
|
|
323
|
+
setBrushOptions(options: BrushOptions): void;
|
|
324
|
+
setVertexEraserMode(active: boolean): void;
|
|
325
|
+
setVertexEraserRadius(radius: number): void;
|
|
326
|
+
setZoomToBoxMode(active: boolean): void;
|
|
327
|
+
/** Bind the shared zoom-to-box tool to this (Plotly) backend's host. */
|
|
328
|
+
private bindZoomToBoxHost;
|
|
329
|
+
/** Box-prompted SAM: segment the drawn rectangles. The SAM tool reuses the
|
|
330
|
+
* wand host (cached frame + coordinate transform + region store). */
|
|
331
|
+
segmentRectangles(): Promise<number>;
|
|
332
|
+
segmentRectanglesCellpose(): Promise<number>;
|
|
333
|
+
setSamModel(id: string): void;
|
|
334
|
+
setSamPointMode(active: boolean): void;
|
|
335
|
+
commitSamPoints(): void;
|
|
336
|
+
clearSamPoints(): void;
|
|
337
|
+
/**
|
|
338
|
+
* Tool-host callback: apply the zoom-to-box selection. Stack mode does a
|
|
339
|
+
* pure axis-range relayout; non-stack mode goes through the high-def
|
|
340
|
+
* triggerZoom pipeline so the image is re-fetched at the new resolution.
|
|
341
|
+
*/
|
|
342
|
+
/** Overlay-pixel -> Plotly data coords via the axis objects (subtracting the
|
|
343
|
+
* plot margin offset). The zoom-to-box tool calls this through its host. */
|
|
344
|
+
private zoomBoxPixelToData;
|
|
345
|
+
private applyZoomToBox;
|
|
346
|
+
/** The plot element the tool canvas overlays attach to. */
|
|
347
|
+
getOverlayContainer(): HTMLElement | null;
|
|
348
|
+
/** Plotly coordinate transform (screen <-> data via the axis objects). */
|
|
349
|
+
getCoordinateTransform(): ICoordinateTransform;
|
|
350
|
+
/** Pixel data the wand needs for sampling. null = no image loaded. */
|
|
351
|
+
private getCachedImageData;
|
|
352
|
+
/** Build Plotly shape dicts from the store's regions (the render projection). */
|
|
353
|
+
private regionsToShapeDicts;
|
|
354
|
+
/** Rebuild the dict working-set from the store (after an image switch, or when
|
|
355
|
+
* regions changed while another backend was rendering). */
|
|
356
|
+
private syncShapesFromStore;
|
|
357
|
+
/**
|
|
358
|
+
* Make the shared store authoritative for the current dict working-set: convert
|
|
359
|
+
* `this.shapes` to neutral regions and replace the store's list (the store
|
|
360
|
+
* mints ids, applies class colours, syncs its per-image cache and emits the
|
|
361
|
+
* region-update event). Store-minted ids are written back onto the dicts so the
|
|
362
|
+
* two representations stay aligned. Profile-line ROIs are ordinary regions
|
|
363
|
+
* (tagged `kind: 'profile'`) and round-trip through here too.
|
|
364
|
+
*/
|
|
365
|
+
private commitShapesToStore;
|
|
366
|
+
/**
|
|
367
|
+
* Push the current `this.shapes` to Plotly, mirror them into the shared store
|
|
368
|
+
* (which syncs its cache + emits the region-update event), and refresh the
|
|
369
|
+
* local previous-shapes buffer. The wand/eraser tools call this after mutating
|
|
370
|
+
* the shapes array directly.
|
|
371
|
+
*/
|
|
372
|
+
applyShapesChange(): void;
|
|
373
|
+
/** Active frame index in the cached image stack. */
|
|
374
|
+
private activeFrameIndex;
|
|
375
|
+
/** Capability-gated 3D scene controls (Plotly renders the 3D plot types). */
|
|
376
|
+
getSurface3dControls(): {
|
|
377
|
+
setSurfaceDragMode: (mode: string) => void;
|
|
378
|
+
resetSurfaceCamera: () => void;
|
|
379
|
+
};
|
|
380
|
+
setSurfaceDragMode(mode: string): void;
|
|
381
|
+
resetSurfaceCamera(): void;
|
|
382
|
+
private triggerZoom;
|
|
383
|
+
setPlotType(plotType: PlotType): void;
|
|
384
|
+
private setImageInfo;
|
|
385
|
+
getShapes(): any[];
|
|
386
|
+
/**
|
|
387
|
+
* Framework-neutral view of the current regions — delegates to the shared
|
|
388
|
+
* RegionStore (the single source of truth). The canonical accessor on the
|
|
389
|
+
* `IVisualizer` contract; consumers should prefer this over `getShapes()`
|
|
390
|
+
* (which exposes Plotly-shaped dicts).
|
|
391
|
+
*/
|
|
392
|
+
getRegions(): Region[];
|
|
393
|
+
/**
|
|
394
|
+
* Switch the active image. The shared RegionStore owns the per-image region
|
|
395
|
+
* cache (snapshot outgoing / restore incoming / clear selection / emit); we
|
|
396
|
+
* delegate to it, then re-project the store's regions into Plotly's dict
|
|
397
|
+
* working-set. Re-projecting unconditionally (even when the store no-ops for
|
|
398
|
+
* the same image) means Plotly also picks up regions another backend (OSD)
|
|
399
|
+
* added while it was off-screen. Called from `plot()` and from the router
|
|
400
|
+
* before any backend renders.
|
|
401
|
+
*/
|
|
402
|
+
setActiveImage(imageInfo: IImageInfo): void;
|
|
403
|
+
/** Test/dev hook — drop the entire per-image cache (logout / project switch). */
|
|
404
|
+
clearRegionsByImageKey(): void;
|
|
405
|
+
/**
|
|
406
|
+
* Get all the selected regions as polygons. Open polylines (closed === false)
|
|
407
|
+
* are excluded — they're annotation-only and cannot be used as filled regions
|
|
408
|
+
* for image processing. Delegates to the shared store.
|
|
409
|
+
*/
|
|
410
|
+
getRegionPolygons(): any[];
|
|
411
|
+
isRectangle(bnds: any): bnds is Rectangle;
|
|
412
|
+
isPolygon(bnds: any): bnds is Polygon;
|
|
413
|
+
/**
|
|
414
|
+
* Set plot regions. Delegates the state change to the shared RegionStore
|
|
415
|
+
* (id/name minting, classification colours, append de-duplication, per-image
|
|
416
|
+
* cache and the region-update event all live there), then re-projects the
|
|
417
|
+
* store's regions into Plotly's dict working-set and renders.
|
|
418
|
+
*
|
|
419
|
+
* When `isRegionSaveOn` is false the regions are shown transiently — rendered
|
|
420
|
+
* without altering the stored working-set (preserves the prior behaviour).
|
|
421
|
+
*/
|
|
422
|
+
setRegions(regions: Region[], showRegionLabel?: boolean, isRegionSaveOn?: boolean, fillColor?: string, append?: boolean): void;
|
|
423
|
+
/** The shapes-relayout payload: region shapes (profile-line ROIs included, as
|
|
424
|
+
* they are ordinary regions) plus the active-shape fill colour. */
|
|
425
|
+
private shapesRelayout;
|
|
426
|
+
/** Push the current dict working-set to Plotly (no-op when another backend
|
|
427
|
+
* owns the div). */
|
|
428
|
+
private renderShapes;
|
|
429
|
+
getShowShapeLabel(): boolean;
|
|
430
|
+
/**
|
|
431
|
+
* Set previous saved shapes
|
|
432
|
+
*/
|
|
433
|
+
plotPreviousShapes(): void;
|
|
434
|
+
setPreviousShapes(shapes: ShapeSelection[]): void;
|
|
435
|
+
getPreviousShapes(): ShapeSelection[];
|
|
436
|
+
undo(): void;
|
|
437
|
+
redo(): void;
|
|
438
|
+
canUndo(): boolean;
|
|
439
|
+
canRedo(): boolean;
|
|
440
|
+
getCanUndo$(): Observable<boolean>;
|
|
441
|
+
getCanRedo$(): Observable<boolean>;
|
|
442
|
+
resetUndoHistory(): void;
|
|
443
|
+
enterStackMode(slices: Map<number, Region[]>, initialZ?: number, saveLayout?: 'combined' | 'per-slice-file'): void;
|
|
444
|
+
exitStackMode(): void;
|
|
445
|
+
isStackMode(): boolean;
|
|
446
|
+
getStackSaveLayout(): 'combined' | 'per-slice-file';
|
|
447
|
+
setDisplaySlice(z: number): void;
|
|
448
|
+
getSliceRegions(): Region[];
|
|
449
|
+
getStackSaveSlices(): Map<number, Region[]>;
|
|
450
|
+
private getHeatmapLayout;
|
|
451
|
+
private shapesToRedraw;
|
|
452
|
+
/**
|
|
453
|
+
* Unused (will be used when surface plot is added)
|
|
454
|
+
* @param xRange
|
|
455
|
+
* @param yRange
|
|
456
|
+
* @param zRatio
|
|
457
|
+
* @private
|
|
458
|
+
*/
|
|
459
|
+
private getSurfaceLayout;
|
|
460
|
+
private getSteps;
|
|
461
|
+
/**
|
|
462
|
+
* Fetch an image via Angular HttpClient so that auth interceptors (Bearer token)
|
|
463
|
+
* are applied, then decode it with image-js. This avoids raw browser fetch()
|
|
464
|
+
* calls that bypass the interceptor chain and fail behind an OAuth2 proxy.
|
|
465
|
+
*/
|
|
466
|
+
private loadImage;
|
|
467
|
+
/**
|
|
468
|
+
* Get the currently displayed image as an image-js Image instance.
|
|
469
|
+
* Used by the processing pipeline to obtain the input image.
|
|
470
|
+
*/
|
|
471
|
+
getCurrentImage(): Promise<Image | null>;
|
|
472
|
+
/**
|
|
473
|
+
* Get the currently displayed plot pixel data as a flat Uint8ClampedArray.
|
|
474
|
+
* This captures whatever is actually rendered — including zoomed regions.
|
|
475
|
+
* Returns { width, height, channels, data } or null if no plot is displayed.
|
|
476
|
+
*/
|
|
477
|
+
getDisplayedPixelData(): {
|
|
478
|
+
width: number;
|
|
479
|
+
height: number;
|
|
480
|
+
channels: number;
|
|
481
|
+
data: Uint8ClampedArray;
|
|
482
|
+
} | null;
|
|
483
|
+
/**
|
|
484
|
+
* Region of the original image that the displayed `z` grid covers, in
|
|
485
|
+
* full-image pixel coords. On a server zoom (`triggerZoom`) the trace `z` is
|
|
486
|
+
* replaced with the high-def crop and the axes are relaid out to the crop's
|
|
487
|
+
* original-image bounds (`imageSize`), so the live axis ranges ARE that
|
|
488
|
+
* rectangle; when the whole image is in view the ranges span `trueImgSize`.
|
|
489
|
+
* Reading the ranges therefore yields the crop origin + extent without
|
|
490
|
+
* tracking zoom state separately. Falls back to the full image, then `null`.
|
|
491
|
+
*/
|
|
492
|
+
getDisplayedSourceRect(): {
|
|
493
|
+
x: number;
|
|
494
|
+
y: number;
|
|
495
|
+
width: number;
|
|
496
|
+
height: number;
|
|
497
|
+
} | null;
|
|
498
|
+
reset(): void;
|
|
499
|
+
/**
|
|
500
|
+
* Fully remove Plotly's DOM from the plot div (axes included). Used when
|
|
501
|
+
* handing the div to another backend (OpenSeadragon) — unlike `reset()`,
|
|
502
|
+
* which re-renders an empty plot and would leave the Plotly axes showing.
|
|
503
|
+
*/
|
|
504
|
+
purgePlot(): void;
|
|
505
|
+
/** Export the heatmap as a PNG (the rendered plot already reflects the active
|
|
506
|
+
* colormap/window). The full-res tile composite is OSD's job. */
|
|
507
|
+
exportComposite(): void;
|
|
508
|
+
downloadImage(): void;
|
|
509
|
+
resetAxes(): void;
|
|
510
|
+
setDragMode(mode: string | false): void;
|
|
511
|
+
/** {@link IDataRenderer} stub — Plotly has no overview navigator (it's an
|
|
512
|
+
* OpenSeadragon feature), so toggling it is a no-op here. */
|
|
513
|
+
setNavigatorVisible(_visible: boolean): void;
|
|
514
|
+
/** {@link IDataRenderer} stub — image smoothing is an OpenSeadragon canvas-drawer
|
|
515
|
+
* setting; the Plotly image/heatmap traces don't expose it, so it's a no-op. */
|
|
516
|
+
setImageSmoothingEnabled(_enabled: boolean): void;
|
|
517
|
+
zoomIn(): void;
|
|
518
|
+
/**
|
|
519
|
+
* Delete every currently selected shape. Falls back to the single
|
|
520
|
+
* `_activeShapeIndex` when no multi-selection is active (covers the case
|
|
521
|
+
* where Plotly clicked a shape without going through the table).
|
|
522
|
+
*/
|
|
523
|
+
deleteActiveShape(): void;
|
|
524
|
+
zoomOut(): void;
|
|
525
|
+
isStackLoading$(): Observable<boolean>;
|
|
526
|
+
setStackLoading(stackLoading: boolean): void;
|
|
527
|
+
getStackLoadingProgress$(): Observable<number>;
|
|
528
|
+
getColormapOptions(): any;
|
|
529
|
+
setColormap(colormap: any): void;
|
|
530
|
+
getColormap(): Observable<any>;
|
|
531
|
+
setReverseScale(reverscale: any): void;
|
|
532
|
+
getReverseScale(): Observable<boolean>;
|
|
533
|
+
setImageMeta(imageMeta: IImageMetadata[]): void;
|
|
534
|
+
getImageMeta(): Observable<IImageMetadata[]>;
|
|
535
|
+
setShowStack(showstack: boolean): void;
|
|
536
|
+
getAutoscaleEvent(): Observable<any>;
|
|
537
|
+
getRegionUpdateEvent(): Observable<any[]>;
|
|
538
|
+
/**
|
|
539
|
+
* Stream of the indices of currently selected regions — owned by the shared
|
|
540
|
+
* RegionStore so the selection is consistent across backends and the Region
|
|
541
|
+
* Editor table. Empty = nothing selected.
|
|
542
|
+
*/
|
|
543
|
+
getSelectedShapeIndices$(): Observable<number[]>;
|
|
544
|
+
/**
|
|
545
|
+
* Programmatically select regions (or clear with []). The shared store owns
|
|
546
|
+
* the selection state (validates/dedupes/emits); here we additionally point
|
|
547
|
+
* Plotly's `_activeShapeIndex` at the last selected shape so it gets the edit
|
|
548
|
+
* handles. No visual change to non-active shapes — Plotly's own active-shape
|
|
549
|
+
* rendering is the only highlight.
|
|
550
|
+
*/
|
|
551
|
+
setSelectedShapeIndices(indices: number[]): void;
|
|
552
|
+
/**
|
|
553
|
+
* Select a specific region (IRegionStore.selectRegion). Sets the shared store
|
|
554
|
+
* selection by identity and points Plotly's active-shape at the matching
|
|
555
|
+
* rendered shape so its edit handles appear.
|
|
556
|
+
*/
|
|
557
|
+
selectRegion(region: Region): void;
|
|
558
|
+
/**
|
|
559
|
+
* Read Plotly's `_activeShapeIndex` and push it as the selection. Called from
|
|
560
|
+
* the relayout handler and the post-click tick — Plotly doesn't fire a
|
|
561
|
+
* dedicated active-shape event for clicks, so we sample. The store no-ops if
|
|
562
|
+
* the selection is unchanged.
|
|
563
|
+
*/
|
|
564
|
+
private maybeEmitActiveShapeIndex;
|
|
565
|
+
setZIndex(zIndex: number): void;
|
|
566
|
+
getShapeColor(): string;
|
|
567
|
+
getFillColor(): string;
|
|
568
|
+
getClassificationColors(): Map<string, string>;
|
|
569
|
+
setClassificationColor(label: string, color: string): void;
|
|
570
|
+
/**
|
|
571
|
+
* Unsubscribe Subscriptions
|
|
572
|
+
*/
|
|
573
|
+
unsubscribe(): void;
|
|
574
|
+
/** Live-apply the channel display window (zmin/zmax) + reverse/invert to the
|
|
575
|
+
* heatmap. No-op when no Plotly plot is mounted (OSD owns the div). */
|
|
576
|
+
private applyChannelDisplay;
|
|
577
|
+
/** Binned intensity histogram for a channel from the cached source frames
|
|
578
|
+
* (raw, pre-LUT). Grayscale cells are numbers; RGB cells are [r,g,b]. */
|
|
579
|
+
getHistogram(channelIndex: number, _bins: number): IHistogram | null;
|
|
580
|
+
/** Async histogram stream — Plotly renders heatmap frame data (already in
|
|
581
|
+
* memory, 8-bit luminance), so this just wraps the synchronous 8-bit
|
|
582
|
+
* histogram. Native 16-bit histograms only apply to the OSD tile path. */
|
|
583
|
+
getHistogram$(channelIndex: number, bins: number): Observable<IHistogram | null>;
|
|
584
|
+
/** Data export (16-bit TIFF) is an OSD-tile-path feature backed by the server.
|
|
585
|
+
* Plotly renders heatmaps from frame data, so there's nothing to export here. */
|
|
586
|
+
exportData(): void;
|
|
587
|
+
importRegions(geoJsonStr: string): Region[];
|
|
588
|
+
exportRegions(regions: Region[]): void;
|
|
589
|
+
getGeoJsonString(regions: Region[]): string;
|
|
590
|
+
getStackLoadingProgress(): Observable<number>;
|
|
591
|
+
isStackLoading(): Observable<boolean>;
|
|
592
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PlotlyService, [null, null, null, null, null, null, null, null, null, null, { optional: true; }, null, null, null, null]>;
|
|
593
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<PlotlyService>;
|
|
594
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { HttpClient } from '@angular/common/http';
|
|
2
|
+
import { IImageInfo } from '../contracts/image.contract';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Shared access to a "simple" (`IImageInfo.tiled === false`) stack — a
|
|
6
|
+
* self-contained per-slice-URL image, as opposed to one server-tiled file
|
|
7
|
+
* with an internal z dimension (the tile-pyramid case each backend already
|
|
8
|
+
* handles on its own, since the tiling protocol itself IS backend-specific).
|
|
9
|
+
* A numbered image series assembled client-side from separate files (the
|
|
10
|
+
* jit-ui folder-stack feature) is the current producer of this shape.
|
|
11
|
+
*
|
|
12
|
+
* Every backend that can render a 2D image (OSD, napari-js) needs the exact
|
|
13
|
+
* same three things for this case — detect it, resolve `urls[z]`, and fetch
|
|
14
|
+
* that URL with the app's auth applied — so they live here once instead of
|
|
15
|
+
* being reimplemented per backend. Plotly needs no equivalent: its `load()`
|
|
16
|
+
* already fetches `urls[i]` generically for every plot type, with no
|
|
17
|
+
* tile-server concept to route around.
|
|
18
|
+
*
|
|
19
|
+
* Fetches go through Angular's `HttpClient` so the app's auth interceptor
|
|
20
|
+
* (Bearer token) applies — a raw `fetch()`/`<img src>` bypasses it and, behind
|
|
21
|
+
* an OAuth2-proxied deployment, gets redirected to the login page and then
|
|
22
|
+
* CORS-fails. Mirrors `PlotlyService.loadImage`, the reference
|
|
23
|
+
* implementation this generalizes for the other backends.
|
|
24
|
+
*/
|
|
25
|
+
export declare class SimpleSliceAccessService {
|
|
26
|
+
private http;
|
|
27
|
+
/** raw slice URL → already-fetched blob: URL, so a backend that opens a
|
|
28
|
+
* URL (OSD) doesn't repeat the auth round-trip revisiting a slice (scrub
|
|
29
|
+
* back, the small→large tier re-fetch). Shared across backends: switching
|
|
30
|
+
* plot types on the same file (e.g. Image → Volume) reuses entries. */
|
|
31
|
+
private readonly blobUrls;
|
|
32
|
+
private currentFileName;
|
|
33
|
+
constructor(http: HttpClient);
|
|
34
|
+
/** True when `imageInfo` is a self-contained per-slice-URL stack with no
|
|
35
|
+
* server tile pyramid to route to. */
|
|
36
|
+
isSimple(imageInfo: IImageInfo | null | undefined): boolean;
|
|
37
|
+
/** The URL for slice `z` of a simple stack (falls back to slice 0 if `z`
|
|
38
|
+
* is out of range or unset). */
|
|
39
|
+
urlFor(imageInfo: IImageInfo, z: number): string | undefined;
|
|
40
|
+
/** Call once per backend `load()` so the blob cache is evicted when a
|
|
41
|
+
* genuinely different file is selected — not on every phase/z-scrub of
|
|
42
|
+
* the SAME file, and not wrongly evicted by a second backend loading the
|
|
43
|
+
* same file for a different plot type. */
|
|
44
|
+
noteActiveFile(fileName: string | undefined): void;
|
|
45
|
+
/** Fetch a slice's own URL and hand back a blob: URL — for backends (OSD)
|
|
46
|
+
* that open a URL rather than decode bytes directly. A true in-memory
|
|
47
|
+
* blob:/data: URL (the processing-pipeline's original tiled:false use
|
|
48
|
+
* case) is already self-contained and returned as-is, no fetch/cache. */
|
|
49
|
+
fetchAsBlobUrl(rawUrl: string): Promise<string>;
|
|
50
|
+
/** Fetch a slice's own URL and decode it as an `ImageBitmap` — for
|
|
51
|
+
* backends (napari-js) that upload pixels directly rather than opening a
|
|
52
|
+
* URL. Not cached (ImageBitmaps are consumed once and closed by the
|
|
53
|
+
* caller); the underlying HTTP response may still hit the browser cache.
|
|
54
|
+
*
|
|
55
|
+
* A self-contained blob:/data: URL (e.g. the processing-pipeline's
|
|
56
|
+
* in-memory preview, which also emits `tiled:false`) needs no auth and
|
|
57
|
+
* isn't a server URL to route through the interceptor — read it directly
|
|
58
|
+
* via the browser. Only real server URLs go through HttpClient so the auth
|
|
59
|
+
* interceptor applies. Mirrors {@link fetchAsBlobUrl}'s blob:/data: branch. */
|
|
60
|
+
fetchAsBitmap(rawUrl: string): Promise<ImageBitmap>;
|
|
61
|
+
private revokeAll;
|
|
62
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SimpleSliceAccessService, never>;
|
|
63
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<SimpleSliceAccessService>;
|
|
64
|
+
}
|