@jax-data-science/sci-image-visualizer 0.16.0 → 0.18.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.
Files changed (127) hide show
  1. package/esm2022/lib/contracts/display-types.mjs +4 -2
  2. package/esm2022/lib/contracts/image.contract.mjs +1 -1
  3. package/esm2022/lib/contracts/ports/spatial-data.port.mjs +1 -1
  4. package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
  5. package/esm2022/lib/contracts/region-store.contract.mjs +1 -1
  6. package/esm2022/lib/contracts/spatial-dataset.contract.mjs +1 -1
  7. package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
  8. package/esm2022/lib/geometry/cell-meshes.mjs +37 -0
  9. package/esm2022/lib/geometry/place.mjs +47 -0
  10. package/esm2022/lib/implementations/napari-js/napari-camera-depth.mjs +93 -0
  11. package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +1 -1
  12. package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +2 -2
  13. package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
  14. package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +86 -18
  15. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-cells.mjs +746 -0
  16. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +343 -18
  17. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-transcripts.mjs +427 -0
  18. package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +11 -4
  19. package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +95 -5
  20. package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +15 -1
  21. package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +35 -8
  22. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +40 -1
  23. package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +136 -28
  24. package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +19 -3
  25. package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +188 -52
  26. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +35 -11
  27. package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +2 -2
  28. package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +10 -1
  29. package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +30 -3
  30. package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +15 -3
  31. package/esm2022/lib/region-editor/region-editor.component.mjs +24 -4
  32. package/esm2022/lib/region-source/region-source-ops.mjs +7 -1
  33. package/esm2022/lib/region-source/region-tiles.mjs +1 -1
  34. package/esm2022/lib/region-source/worker-region-source.mjs +24 -1
  35. package/esm2022/lib/routing-visualizer.service.mjs +404 -7
  36. package/esm2022/lib/spatial/observations-in-selection.mjs +83 -0
  37. package/esm2022/lib/spatial/plane-cells.mjs +119 -0
  38. package/esm2022/lib/spatial/spatial-controls.facade.mjs +304 -8
  39. package/esm2022/lib/spatial/spatial-encoding.mjs +52 -3
  40. package/esm2022/lib/spatial/spatial-hover.mjs +34 -1
  41. package/esm2022/lib/spatial/spatial-planes.mjs +49 -0
  42. package/esm2022/lib/spatial/spatial-selection.mjs +2 -2
  43. package/esm2022/lib/spatial/spatial-tile-merge.mjs +38 -1
  44. package/esm2022/lib/spatial/transcripts-in-selection.mjs +208 -0
  45. package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +42 -65
  46. package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +6 -2
  47. package/esm2022/lib/spatial-controls/spatial-color-by/spatial-color-by.component.mjs +187 -0
  48. package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +51 -12
  49. package/esm2022/lib/spatial-controls/spatial-gene-style/spatial-gene-style.component.mjs +7 -3
  50. package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +21 -6
  51. package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +94 -13
  52. package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +3 -3
  53. package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +3 -3
  54. package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +79 -57
  55. package/esm2022/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.mjs +101 -0
  56. package/esm2022/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.mjs +94 -0
  57. package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +9 -3
  58. package/esm2022/lib/store/region-source-scope.mjs +10 -1
  59. package/esm2022/lib/store/region-store.service.mjs +33 -2
  60. package/esm2022/lib/toolbar/toolbar.component.mjs +10 -3
  61. package/esm2022/lib/visualizer/spatial-region-set.mjs +95 -0
  62. package/esm2022/lib/visualizer.component.mjs +40 -4
  63. package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CYsPzX3J.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CBiLcnE6.mjs} +4838 -656
  64. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CBiLcnE6.mjs.map +1 -0
  65. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-DaZVXq1s.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-BXHjv4PE.mjs} +2 -2
  66. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-DaZVXq1s.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-BXHjv4PE.mjs.map} +1 -1
  67. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +1 -1
  68. package/fesm2022/region-source.worker.js +84 -2
  69. package/lib/contracts/display-types.d.ts +99 -6
  70. package/lib/contracts/image.contract.d.ts +6 -0
  71. package/lib/contracts/ports/spatial-data.port.d.ts +7 -0
  72. package/lib/contracts/region-editor-api.contract.d.ts +9 -0
  73. package/lib/contracts/region-store.contract.d.ts +6 -0
  74. package/lib/contracts/spatial-dataset.contract.d.ts +7 -1
  75. package/lib/contracts/visualizer.contract.d.ts +43 -1
  76. package/lib/geometry/cell-meshes.d.ts +27 -0
  77. package/lib/geometry/place.d.ts +45 -0
  78. package/lib/implementations/napari-js/napari-camera-depth.d.ts +23 -0
  79. package/lib/implementations/napari-js/napari-loading-state.d.ts +1 -1
  80. package/lib/implementations/napari-js/napari-scene.d.ts +12 -0
  81. package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +19 -3
  82. package/lib/implementations/napari-js/napari-spatial-3d-cells.d.ts +141 -0
  83. package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +89 -0
  84. package/lib/implementations/napari-js/napari-spatial-3d-transcripts.d.ts +103 -0
  85. package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +9 -2
  86. package/lib/implementations/napari-js/napari-spatial-hover.d.ts +22 -0
  87. package/lib/implementations/napari-js/napari-spatial-scene.d.ts +12 -0
  88. package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +20 -6
  89. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +27 -1
  90. package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +48 -16
  91. package/lib/implementations/napari-js/napari-volume-scene.d.ts +2 -0
  92. package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +54 -1
  93. package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +11 -2
  94. package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +7 -0
  95. package/lib/region-editor/class-tree/class-tree.component.d.ts +16 -1
  96. package/lib/region-editor/classes-panel/classes-panel.component.d.ts +10 -1
  97. package/lib/region-editor/region-editor.component.d.ts +4 -0
  98. package/lib/region-source/region-source-ops.d.ts +12 -0
  99. package/lib/region-source/region-tiles.d.ts +8 -0
  100. package/lib/region-source/worker-region-source.d.ts +18 -0
  101. package/lib/routing-visualizer.service.d.ts +140 -1
  102. package/lib/spatial/observations-in-selection.d.ts +43 -0
  103. package/lib/spatial/plane-cells.d.ts +37 -0
  104. package/lib/spatial/spatial-controls.facade.d.ts +59 -0
  105. package/lib/spatial/spatial-encoding.d.ts +24 -1
  106. package/lib/spatial/spatial-hover.d.ts +23 -0
  107. package/lib/spatial/spatial-planes.d.ts +22 -0
  108. package/lib/spatial/spatial-selection.d.ts +2 -1
  109. package/lib/spatial/spatial-tile-merge.d.ts +9 -0
  110. package/lib/spatial/transcripts-in-selection.d.ts +95 -0
  111. package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +19 -28
  112. package/lib/spatial-controls/spatial-color-by/spatial-color-by.component.d.ts +64 -0
  113. package/lib/spatial-controls/spatial-controls.component.d.ts +19 -2
  114. package/lib/spatial-controls/spatial-gene-style/spatial-gene-style.component.d.ts +3 -1
  115. package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +7 -0
  116. package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +28 -7
  117. package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +26 -23
  118. package/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.d.ts +48 -0
  119. package/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.d.ts +43 -0
  120. package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +3 -1
  121. package/lib/store/region-source-scope.d.ts +4 -0
  122. package/lib/store/region-store.service.d.ts +21 -0
  123. package/lib/toolbar/toolbar.component.d.ts +6 -1
  124. package/lib/visualizer/spatial-region-set.d.ts +55 -0
  125. package/lib/visualizer.component.d.ts +14 -0
  126. package/package.json +2 -2
  127. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CYsPzX3J.mjs.map +0 -1
@@ -0,0 +1,64 @@
1
+ import { EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
2
+ import type { ISpatialControls } from '../../contracts/visualizer.contract';
3
+ import type { SpatialDataset } from '../../contracts/spatial-dataset.contract';
4
+ import { ColormapNode, SpatialViewState } from '../../contracts/display-types';
5
+ import type { PanelOption } from '../../spatial/spatial-panel-model';
6
+ import type { GenePickerModel } from '../spatial-gene-picker';
7
+ import type { SpatialLegendEntry } from '../spatial-key/spatial-key.model';
8
+ import * as i0 from "@angular/core";
9
+ /** What colours the observations: a grouping, a gene, a measurement, or one colour. */
10
+ export type ColorByMode = 'group' | 'gene' | 'measure' | 'single';
11
+ /**
12
+ * The Observations section's "Colour by": one colouring for the markers and the cells alike —
13
+ * a grouping (the {@link SpatialGroupsPanelComponent groups} with their colours and switches),
14
+ * one gene's expression, a measurement (a numeric column), or one colour. Each choice writes
15
+ * the markers' colour source (`colorBy`) and the cells' (`cellColorMode` and its own fields)
16
+ * together, so the two cannot disagree.
17
+ *
18
+ * Writes only through `controls.setViewState`.
19
+ */
20
+ export declare class SpatialColorByComponent implements OnChanges {
21
+ /** The spatial controls this panel reads and writes through; null without a `SPATIAL_DATA_PORT`. */
22
+ controls: ISpatialControls | null;
23
+ /** The dataset on offer, or null. */
24
+ dataset: SpatialDataset | null;
25
+ /** The current spatial view state. */
26
+ view: SpatialViewState;
27
+ /** The gene list the gene colouring picks from, shared with the other gene dropdowns. */
28
+ genes: GenePickerModel | null;
29
+ /** The key's categorical legend, or null (continuous). */
30
+ legend: SpatialLegendEntry[] | null;
31
+ /** The key's continuous colour bar (a CSS gradient), or null. */
32
+ colorBarCss: string | null;
33
+ /** The selected category (its code), for highlighting its group. */
34
+ selectedCategory: number | null;
35
+ /** Colormap tree for the continuous colour scale. */
36
+ colormapOptions: ColormapNode[];
37
+ /** A group was clicked: its category's code, to select its observations. */
38
+ readonly categoryClicked: EventEmitter<number>;
39
+ /** Virtual-scrolled only past this many options (see the gene dropdowns elsewhere). */
40
+ protected readonly geneVirtualScrollFrom = 200;
41
+ /** The modes the dataset can be coloured in. */
42
+ protected modeOptions: PanelOption<ColorByMode>[];
43
+ /** The dataset's numeric columns. */
44
+ protected measureOptions: PanelOption<string>[];
45
+ /** A mode picked before its gene or measurement is: shown, nothing written yet. */
46
+ private pending;
47
+ ngOnChanges(changes: SimpleChanges): void;
48
+ /** The mode on show: one picked and waiting for its value, else what the view is coloured by. */
49
+ protected get mode(): ColorByMode | null;
50
+ /** What the view is coloured by, as a mode; null for the flat default. */
51
+ private get viewMode();
52
+ /** The gene the observations are coloured by, or null. */
53
+ protected get selectedGene(): string | null;
54
+ /** The measurement the observations are coloured by, or null. */
55
+ protected get selectedMeasure(): string | null;
56
+ protected onMode(mode: ColorByMode | null): void;
57
+ /** Colour the markers and the cells by gene `name`. */
58
+ protected onGene(name: string | null): void;
59
+ /** Colour the markers and the cells by measurement `name`. */
60
+ protected onMeasure(name: string | null): void;
61
+ protected onSingleColor(hex: string): void;
62
+ static ɵfac: i0.ɵɵFactoryDeclaration<SpatialColorByComponent, never>;
63
+ static ɵcmp: i0.ɵɵComponentDeclaration<SpatialColorByComponent, "spatial-color-by", never, { "controls": { "alias": "controls"; "required": false; }; "dataset": { "alias": "dataset"; "required": false; }; "view": { "alias": "view"; "required": false; }; "genes": { "alias": "genes"; "required": false; }; "legend": { "alias": "legend"; "required": false; }; "colorBarCss": { "alias": "colorBarCss"; "required": false; }; "selectedCategory": { "alias": "selectedCategory"; "required": false; }; "colormapOptions": { "alias": "colormapOptions"; "required": false; }; }, { "categoryClicked": "categoryClicked"; }, never, never, true, never>;
64
+ }
@@ -1,7 +1,7 @@
1
1
  import { EventEmitter, NgZone, OnInit } from '@angular/core';
2
2
  import { IVisualizer, ISpatialControls, RoiSelectionMode } from '../contracts/visualizer.contract';
3
3
  import { SpatialDataset } from '../contracts/spatial-dataset.contract';
4
- import { ColormapNode, SpatialViewState } from '../contracts/display-types';
4
+ import { Cells3dStatus, ColormapNode, SpatialViewState } from '../contracts/display-types';
5
5
  import { PanelOption, parseGeneGroups } from '../spatial/spatial-panel-model';
6
6
  import { SpatialSelectionMask } from '../spatial/spatial-selection';
7
7
  import { GenePickerModel } from './spatial-gene-picker';
@@ -137,12 +137,29 @@ export declare class SpatialControlsComponent implements OnInit {
137
137
  protected get hasSelection(): boolean;
138
138
  /** Boundaries on offer: tiled (level-of-detail) or whole-dataset rings. */
139
139
  protected get hasCells(): boolean;
140
+ /** The 3D view's individual cells as they stand (null: none drawn). */
141
+ protected cells3dStatus: Cells3dStatus | null;
142
+ /**
143
+ * Whether the router has the dataset's region set attached and placed (null: it does not say).
144
+ * See {@link hasCells3d}.
145
+ */
146
+ protected cells3dAvailable: boolean | null;
147
+ /**
148
+ * The dataset's cells can be drawn in 3D: its boundaries name a 3D segmentation's region set, and
149
+ * it is attached with its planes (else the 3D view draws no cells, and the markers stay).
150
+ */
151
+ protected get hasCells3d(): boolean;
140
152
  /** Transcripts on offer: tiles to draw, or a density map. */
141
153
  protected get hasTranscripts(): boolean;
154
+ /** Whether the 3D cloud can draw the transcripts too: they carry z (a MERFISH volume's do). */
155
+ protected get hasTranscripts3d(): boolean;
142
156
  protected onShowImage(on: boolean): void;
157
+ /** The reference volume, in 3D (the Volume section's switch). */
158
+ protected onShowVolume(on: boolean): void;
159
+ protected onVolumeOpacity(value: number | undefined): void;
143
160
  protected onShowAnnotations(on: boolean): void;
144
161
  /** Which collapsible sections are open. Per dialog instance, not persisted. */
145
- protected open: Record<'images' | 'cells' | 'transcripts' | 'annotations' | 'observations', boolean>;
162
+ protected open: Record<'images' | 'volume' | 'transcripts' | 'annotations' | 'observations', boolean>;
146
163
  protected toggleSection(name: keyof SpatialControlsComponent['open']): void;
147
164
  /** Expand or collapse a section — what a panel's header asks for. */
148
165
  protected setOpen(name: keyof SpatialControlsComponent['open'], on: boolean): void;
@@ -17,6 +17,8 @@ export declare class SpatialGeneStyleComponent {
17
17
  glyph: TranscriptGlyphName;
18
18
  /** A note under the icons, e.g. where they show; none when null. */
19
19
  iconHint: string | null;
20
+ /** False for a colour alone (a cell group, or every gene drawn with one icon): no icon grid. */
21
+ showIcons: boolean;
20
22
  readonly colorChange: EventEmitter<string>;
21
23
  readonly glyphChange: EventEmitter<TranscriptGlyphName>;
22
24
  /** Back to the gene's default icon and colour. */
@@ -26,5 +28,5 @@ export declare class SpatialGeneStyleComponent {
26
28
  /** A typed hex colour, accepted as `#rrggbb` or `rrggbb`; anything else is ignored. */
27
29
  protected onHex(text: string): void;
28
30
  static ɵfac: i0.ɵɵFactoryDeclaration<SpatialGeneStyleComponent, never>;
29
- static ɵcmp: i0.ɵɵComponentDeclaration<SpatialGeneStyleComponent, "spatial-gene-style", never, { "gene": { "alias": "gene"; "required": false; }; "what": { "alias": "what"; "required": false; }; "color": { "alias": "color"; "required": false; }; "glyph": { "alias": "glyph"; "required": false; }; "iconHint": { "alias": "iconHint"; "required": false; }; }, { "colorChange": "colorChange"; "glyphChange": "glyphChange"; "resetStyle": "resetStyle"; }, never, never, true, never>;
31
+ static ɵcmp: i0.ɵɵComponentDeclaration<SpatialGeneStyleComponent, "spatial-gene-style", never, { "gene": { "alias": "gene"; "required": false; }; "what": { "alias": "what"; "required": false; }; "color": { "alias": "color"; "required": false; }; "glyph": { "alias": "glyph"; "required": false; }; "iconHint": { "alias": "iconHint"; "required": false; }; "showIcons": { "alias": "showIcons"; "required": false; }; }, { "colorChange": "colorChange"; "glyphChange": "glyphChange"; "resetStyle": "resetStyle"; }, never, never, true, never>;
30
32
  }
@@ -21,6 +21,8 @@ interface AllGeneRowView {
21
21
  shown: boolean;
22
22
  /** Its colour when coloured by gene, or null when the dataset's code order is unknown. */
23
23
  swatch: string | null;
24
+ /** Its code in the dataset's gene list (what its palette colour is picked by). */
25
+ code: number;
24
26
  count: number | null;
25
27
  }
26
28
  /**
@@ -131,6 +133,11 @@ export declare class SpatialGeneTreeComponent implements OnChanges {
131
133
  /** The colour gene `slot` is drawn in when transcripts are coloured by gene. */
132
134
  geneColor(slot: number): string;
133
135
  protected geneColorOf(gene: string): string;
136
+ /**
137
+ * The colour the open picker shows: with "All genes", the gene's colour among every gene (its
138
+ * chosen one, else the palette's by its code), as its row and its markers have it.
139
+ */
140
+ protected styleColorOf(gene: string): string;
134
141
  /** In Cluster colouring, a gene's swatch is its cluster's colour, as its markers are. */
135
142
  protected geneSwatchOf(gene: string): string;
136
143
  protected geneCountOf(gene: string): number | null;
@@ -1,16 +1,18 @@
1
- import { ChangeDetectorRef, NgZone, OnChanges, SimpleChanges } from '@angular/core';
1
+ import { ChangeDetectorRef, EventEmitter, NgZone, OnChanges, SimpleChanges } from '@angular/core';
2
2
  import type { ISpatialControls } from '../../contracts/visualizer.contract';
3
3
  import type { SpatialDataset } from '../../contracts/spatial-dataset.contract';
4
4
  import { SpatialViewState } from '../../contracts/display-types';
5
5
  import { GroupOptionSection, GroupRow, PanelOption } from '../../spatial/spatial-panel-model';
6
6
  import * as i0 from "@angular/core";
7
7
  /**
8
- * The cells' grouping, as Xenium Explorer's Groups section: the group picker (columns under
9
- * their section heading, a k-means family once, with its k beside it), CSV import of a new
10
- * grouping, and the grouping's categories with their colours, cell counts and show/hide
11
- * switches.
8
+ * The observations' grouping, as Xenium Explorer's Groups section: the group picker (columns
9
+ * under their section heading, a k-means family once, with its k beside it), CSV import of a new
10
+ * grouping, and the grouping's categories with their colours (each one's swatch opens a colour
11
+ * picker), cell counts and show/hide switches. A group's name selects its observations.
12
12
  *
13
- * Writes only through `controls.setViewState` (`cellTypeColumn`, `hiddenGroups`).
13
+ * The Observations section's "Colour by" in Group mode: the grouping colours the markers and the
14
+ * cells alike. Writes only through `controls.setViewState` (`cellTypeColumn` with `colorBy` and
15
+ * `cellColorMode`, `hiddenGroups`, `groupColors`).
14
16
  */
15
17
  export declare class SpatialGroupsPanelComponent implements OnChanges {
16
18
  private readonly zone;
@@ -21,6 +23,10 @@ export declare class SpatialGroupsPanelComponent implements OnChanges {
21
23
  dataset: SpatialDataset | null;
22
24
  /** The current spatial view state: what is drawn, and how. */
23
25
  view: SpatialViewState;
26
+ /** The category selected (its code in the grouping), for highlighting its row. */
27
+ selectedCategory: number | null;
28
+ /** A group's name was clicked: its category's code in the grouping, to select its observations. */
29
+ readonly categoryClicked: EventEmitter<number>;
24
30
  /**
25
31
  * The group picker: categorical columns under their section heading, a family of
26
32
  * variants (k-means at k = 2…10) listed once. Values are a column name, or
@@ -42,6 +48,8 @@ export declare class SpatialGroupsPanelComponent implements OnChanges {
42
48
  private readonly groupRowsLoad;
43
49
  protected groupImportError: string | null;
44
50
  protected groupImporting: boolean;
51
+ /** The group the open colour picker edits. */
52
+ protected styleGroup: string | null;
45
53
  constructor(zone: NgZone, cdr: ChangeDetectorRef);
46
54
  ngOnChanges(changes: SimpleChanges): void;
47
55
  /** The categorical column the cells are grouped by. */
@@ -51,12 +59,25 @@ export declare class SpatialGroupsPanelComponent implements OnChanges {
51
59
  protected onGroupEntry(value: string): void;
52
60
  protected onGroupVariant(name: string): void;
53
61
  onCellTypeColumn(name: string | null): void;
62
+ /** Group `label`'s category code in the active grouping, or -1. */
63
+ protected codeOf(label: string): number;
64
+ /** Select (or, selected already, clear) group `label`'s observations. */
65
+ protected onGroupClicked(label: string): void;
54
66
  /** {@link SpatialViewState.hiddenGroups} as a set, for the per-row checks. */
55
67
  private hiddenGroups;
56
68
  protected isGroupShown(label: string): boolean;
57
69
  protected get allGroupsShown(): boolean;
58
70
  protected onGroupShown(label: string, on: boolean): void;
59
71
  protected onAllGroupsShown(on: boolean): void;
72
+ protected openGroupStyle(event: Event, label: string, panel: {
73
+ toggle(e: Event): void;
74
+ hide(): void;
75
+ }): void;
76
+ /** The colour group `label` is drawn in now (the user's, else the column's or the palette's). */
77
+ protected groupColorOf(label: string): string;
78
+ protected onGroupColor(label: string, hex: string): void;
79
+ /** Back to the group's own colour (the column's, else the palette's). */
80
+ protected resetGroupColor(label: string): void;
60
81
  protected get canImportGroups(): boolean;
61
82
  /** '+': a CSV/TSV of `cell_id` and group, named after the file. */
62
83
  protected onImportGroupsFile(input: HTMLInputElement): Promise<void>;
@@ -68,5 +89,5 @@ export declare class SpatialGroupsPanelComponent implements OnChanges {
68
89
  /** Apply an async result inside the zone and re-render this OnPush panel. */
69
90
  private apply;
70
91
  static ɵfac: i0.ɵɵFactoryDeclaration<SpatialGroupsPanelComponent, never>;
71
- static ɵcmp: i0.ɵɵComponentDeclaration<SpatialGroupsPanelComponent, "spatial-groups-panel", never, { "controls": { "alias": "controls"; "required": false; }; "dataset": { "alias": "dataset"; "required": false; }; "view": { "alias": "view"; "required": false; }; }, {}, never, never, true, never>;
92
+ static ɵcmp: i0.ɵɵComponentDeclaration<SpatialGroupsPanelComponent, "spatial-groups-panel", never, { "controls": { "alias": "controls"; "required": false; }; "dataset": { "alias": "dataset"; "required": false; }; "view": { "alias": "view"; "required": false; }; "selectedCategory": { "alias": "selectedCategory"; "required": false; }; }, { "categoryClicked": "categoryClicked"; }, never, never, true, never>;
72
93
  }
@@ -8,16 +8,6 @@ import { PanelOption } from '../../spatial/spatial-panel-model';
8
8
  import type { GenePickerModel } from '../spatial-gene-picker';
9
9
  import type { SpatialLegendEntry } from '../spatial-key/spatial-key.model';
10
10
  import * as i0 from "@angular/core";
11
- /**
12
- * The Observations section — one marker per observation (cell centroid, Visium spot) — and
13
- * what else draws them: what colours them (a column or a gene, mutually exclusive, with
14
- * the {@link SpatialKeyComponent key}), point size and opacity, the gene map, the 3D scene
15
- * (volume, cloud, sections, density volumes) and the continuous-only knobs.
16
- *
17
- * Renders the section and the sections after it as siblings in the dialog body
18
- * (`display: contents`). Writes only through the port: `setViewState`, and the colour
19
- * source's own `colorByColumn` / `colorByFeature` / `clearColorBy`.
20
- */
21
11
  export declare class SpatialObservationsPanelComponent implements OnChanges {
22
12
  /** The spatial controls this panel reads and writes through; null without a `SPATIAL_DATA_PORT`. */
23
13
  controls: ISpatialControls | null;
@@ -43,6 +33,11 @@ export declare class SpatialObservationsPanelComponent implements OnChanges {
43
33
  open: boolean;
44
34
  /** Asks to open or close it; two-way with `open`. */
45
35
  readonly openChange: EventEmitter<boolean>;
36
+ /**
37
+ * Whether the dataset's cells can be drawn here (a cell segmentation, and in 3D a 3D one): the
38
+ * observations are shown as Markers or as Cell segmentations.
39
+ */
40
+ cellsAvailable: boolean;
46
41
  /** A legend row was clicked (see the key). */
47
42
  readonly categoryClicked: EventEmitter<number>;
48
43
  protected readonly clipOptions: PanelOption<[number, number]>[];
@@ -50,10 +45,10 @@ export declare class SpatialObservationsPanelComponent implements OnChanges {
50
45
  protected readonly matchOptions: PanelOption<SpatialViewState['observationGenesMatch']>[];
51
46
  /** Virtual-scrolled only past this many options (see the cells panel's gene dropdown). */
52
47
  protected readonly geneVirtualScrollFrom = 200;
53
- /** Colour-by column choices — "None" plus every column the dataset declares. */
54
- protected columnOptions: PanelOption<string | null>[];
55
- protected selectedColumn: string | null;
56
- protected selectedGene: string | null;
48
+ /** What the observations are shown as, with a cell segmentation. */
49
+ protected readonly showAsOptions: PanelOption<'markers' | 'cells'>[];
50
+ /** The choice of Markers or Cell segmentations, kept while the observations are hidden. */
51
+ private chosenShownAs;
57
52
  /**
58
53
  * The dataset's imaged section positions, or null when its z is continuous rather than
59
54
  * sectioned. Read once per dataset — the scan walks the z of every observation, so it
@@ -61,10 +56,22 @@ export declare class SpatialObservationsPanelComponent implements OnChanges {
61
56
  */
62
57
  protected sections: Float32Array | null;
63
58
  ngOnChanges(changes: SimpleChanges): void;
64
- /** Column dropdown. Choosing a column supersedes any gene selection. */
65
- protected onColumn(name: string | null): void;
66
- /** A gene was picked; it supersedes any column selection. */
67
- protected onGene(name: string | null): void;
59
+ /** Whether the cells are drawn (the explicit choice, or automatically for data that has them). */
60
+ private get cellsOn();
61
+ /** Whether the observations are shown at all, as markers or as cells. */
62
+ protected get observationsShown(): boolean;
63
+ /** What the observations are shown as (the toggle): the cells while they are drawn, else the
64
+ * markers, or, hidden, what was last chosen. */
65
+ protected get shownAs(): 'markers' | 'cells';
66
+ /** Show or hide the observations, as what they were shown as. */
67
+ protected onShowObservations(on: boolean): void;
68
+ protected onShownAs(as: 'markers' | 'cells' | null): void;
69
+ /**
70
+ * Draw the observations as the markers, or as the cells: one or the other, never both (the
71
+ * renderers draw no markers while the cells are drawn). The markers stay switched on under the
72
+ * cells, so a view without them (spatial 3D of a 2D segmentation) still shows the markers.
73
+ */
74
+ private showAs;
68
75
  /** Genes picked for the observation filter; none draws every observation. */
69
76
  protected onObservationGenes(genes: string[] | null): void;
70
77
  protected onObservationGenesMatch(match: SpatialViewState['observationGenesMatch'] | null): void;
@@ -94,8 +101,6 @@ export declare class SpatialObservationsPanelComponent implements OnChanges {
94
101
  protected resetGeneStyle(gene: string): void;
95
102
  /** What the filter hides, in words. */
96
103
  protected get geneFilterHint(): string;
97
- /** Cell outlines on offer, which changes what the circles mean. */
98
- protected get hasCells(): boolean;
99
104
  /** True while a selection is active — everything else renders muted. */
100
105
  get hasSelection(): boolean;
101
106
  /** Whether log/clip apply — they are continuous-only knobs. */
@@ -122,8 +127,6 @@ export declare class SpatialObservationsPanelComponent implements OnChanges {
122
127
  protected get geneMapVolumeNote(): string;
123
128
  /** True while a gene is the colour source — the only thing a gene map can map. */
124
129
  protected get canMapGene(): boolean;
125
- protected onShowVolume(on: boolean): void;
126
- protected onVolumeOpacity(value: number | undefined): void;
127
130
  protected onShowPoints(on: boolean): void;
128
131
  /** The "one section at a time" switch: null restores the whole stack. */
129
132
  protected onOneSection(on: boolean): void;
@@ -145,5 +148,5 @@ export declare class SpatialObservationsPanelComponent implements OnChanges {
145
148
  private static readonly DENSITY_MAX_CLUSTERS;
146
149
  protected onClip(value: [number, number]): void;
147
150
  static ɵfac: i0.ɵɵFactoryDeclaration<SpatialObservationsPanelComponent, never>;
148
- static ɵcmp: i0.ɵɵComponentDeclaration<SpatialObservationsPanelComponent, "spatial-observations-panel", never, { "controls": { "alias": "controls"; "required": false; }; "dataset": { "alias": "dataset"; "required": false; }; "view": { "alias": "view"; "required": false; }; "genes": { "alias": "genes"; "required": false; }; "legend": { "alias": "legend"; "required": false; }; "colorBarCss": { "alias": "colorBarCss"; "required": false; }; "selection": { "alias": "selection"; "required": false; }; "selectedCategory": { "alias": "selectedCategory"; "required": false; }; "colormapOptions": { "alias": "colormapOptions"; "required": false; }; "is3d": { "alias": "is3d"; "required": false; }; "open": { "alias": "open"; "required": false; }; }, { "openChange": "openChange"; "categoryClicked": "categoryClicked"; }, never, never, true, never>;
151
+ static ɵcmp: i0.ɵɵComponentDeclaration<SpatialObservationsPanelComponent, "spatial-observations-panel", never, { "controls": { "alias": "controls"; "required": false; }; "dataset": { "alias": "dataset"; "required": false; }; "view": { "alias": "view"; "required": false; }; "genes": { "alias": "genes"; "required": false; }; "legend": { "alias": "legend"; "required": false; }; "colorBarCss": { "alias": "colorBarCss"; "required": false; }; "selection": { "alias": "selection"; "required": false; }; "selectedCategory": { "alias": "selectedCategory"; "required": false; }; "colormapOptions": { "alias": "colormapOptions"; "required": false; }; "is3d": { "alias": "is3d"; "required": false; }; "open": { "alias": "open"; "required": false; }; "cellsAvailable": { "alias": "cellsAvailable"; "required": false; }; }, { "openChange": "openChange"; "categoryClicked": "categoryClicked"; }, never, ["spatial-cells-panel"], true, never>;
149
152
  }
@@ -0,0 +1,48 @@
1
+ import { ChangeDetectorRef, NgZone, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
2
+ import type { ISpatialControls } from '../../contracts/visualizer.contract';
3
+ import type { ObservationsInSelection } from '../../contracts/display-types';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * "Observations in selection", in the Observations section: the observations of what is selected —
7
+ * a cell, a cell type picked on the canvas, the selected regions — by the grouping they are coloured
8
+ * by (else the cell types), with a few measurements' means, or one cell's id, groupings and values.
9
+ * Every observation in spatial 3D; in 2D those on the plane shown. See
10
+ * `ISpatialControls.getObservationsInSelection$`.
11
+ *
12
+ * Collapsible; followed only while expanded (and while the Observations section, which holds it, is
13
+ * open).
14
+ */
15
+ export declare class SpatialSelectionObservationsComponent implements OnChanges, OnDestroy {
16
+ private readonly zone;
17
+ private readonly cdr;
18
+ /** The spatial controls the list is read through; null without a `SPATIAL_DATA_PORT`. */
19
+ controls: ISpatialControls | null;
20
+ /** In spatial 3D: the list is of the whole volume. */
21
+ is3d: boolean;
22
+ /** Expanded: the list is followed and shown. */
23
+ protected expanded: boolean;
24
+ /** The selection's observations (null until the first answer). */
25
+ protected list: ObservationsInSelection | null;
26
+ private sub;
27
+ constructor(zone: NgZone, cdr: ChangeDetectorRef);
28
+ ngOnChanges(changes: SimpleChanges): void;
29
+ ngOnDestroy(): void;
30
+ /** Whether there is a list to offer. */
31
+ protected get available(): boolean;
32
+ /** The largest group, for the bars. */
33
+ protected get max(): number;
34
+ protected toggle(): void;
35
+ private watch;
36
+ /** A measurement as shown: a number to 3 significant figures (with its unit), text as it is. */
37
+ protected format(m: {
38
+ value: string | number;
39
+ unit?: string;
40
+ }): string;
41
+ /** The groups as tab-separated text (group, observations), for a spreadsheet. */
42
+ protected copy(): void;
43
+ protected trackGroup(_i: number, g: {
44
+ name: string;
45
+ }): string;
46
+ static ɵfac: i0.ɵɵFactoryDeclaration<SpatialSelectionObservationsComponent, never>;
47
+ static ɵcmp: i0.ɵɵComponentDeclaration<SpatialSelectionObservationsComponent, "spatial-selection-observations", never, { "controls": { "alias": "controls"; "required": false; }; "is3d": { "alias": "is3d"; "required": false; }; }, {}, never, never, true, never>;
48
+ }
@@ -0,0 +1,43 @@
1
+ import { ChangeDetectorRef, NgZone, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
2
+ import type { ISpatialControls } from '../../contracts/visualizer.contract';
3
+ import type { TranscriptsInSelection } from '../../contracts/display-types';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * "Transcripts in selection", in the Transcripts section: the transcripts of what is selected, by
7
+ * gene, most frequent first — through the volume in spatial 3D (a cell, or a cell type picked on the
8
+ * canvas), on the plane shown in 2D (the selected cells or regions). See
9
+ * `ISpatialControls.getTranscriptsInSelection$`.
10
+ *
11
+ * Collapsible; counted only while expanded (and while the Transcripts section, which holds it, is
12
+ * open): the counts read the finest transcript tiles of the selection.
13
+ */
14
+ export declare class SpatialSelectionTranscriptsComponent implements OnChanges, OnDestroy {
15
+ private readonly zone;
16
+ private readonly cdr;
17
+ /** The spatial controls the list is read through; null without a `SPATIAL_DATA_PORT`. */
18
+ controls: ISpatialControls | null;
19
+ /** In spatial 3D: the list is of the whole volume. */
20
+ is3d: boolean;
21
+ /** Expanded: the list is counted and shown. */
22
+ protected expanded: boolean;
23
+ /** The selection's transcripts by gene (null until the first answer). */
24
+ protected list: TranscriptsInSelection | null;
25
+ private sub;
26
+ constructor(zone: NgZone, cdr: ChangeDetectorRef);
27
+ ngOnChanges(changes: SimpleChanges): void;
28
+ ngOnDestroy(): void;
29
+ /** Whether there is a list to offer: the controls count transcripts. */
30
+ protected get available(): boolean;
31
+ /** The largest gene count, for the bars. */
32
+ protected get max(): number;
33
+ protected toggle(): void;
34
+ /** Subscribe while expanded, else not (a collapsed list reads nothing). */
35
+ private watch;
36
+ /** The list as tab-separated text (gene, count), for a spreadsheet. */
37
+ protected copy(): void;
38
+ protected trackGene(_i: number, g: {
39
+ name: string;
40
+ }): string;
41
+ static ɵfac: i0.ɵɵFactoryDeclaration<SpatialSelectionTranscriptsComponent, never>;
42
+ static ɵcmp: i0.ɵɵComponentDeclaration<SpatialSelectionTranscriptsComponent, "spatial-selection-transcripts", never, { "controls": { "alias": "controls"; "required": false; }; "is3d": { "alias": "is3d"; "required": false; }; }, {}, never, never, true, never>;
43
+ }
@@ -29,6 +29,8 @@ export declare class SpatialTranscriptsPanelComponent implements OnChanges {
29
29
  controls: ISpatialControls | null;
30
30
  /** The dataset on offer, or null. */
31
31
  dataset: SpatialDataset | null;
32
+ /** In spatial 3D (the transcripts in selection are then the whole volume's). */
33
+ is3d: boolean;
32
34
  /** The current spatial view state: what is drawn, and how. */
33
35
  view: SpatialViewState;
34
36
  /** The gene list the transcript genes are picked from, shared with the other gene dropdowns. */
@@ -150,5 +152,5 @@ export declare class SpatialTranscriptsPanelComponent implements OnChanges {
150
152
  /** '⋮' menu. */
151
153
  private buildGeneMenu;
152
154
  static ɵfac: i0.ɵɵFactoryDeclaration<SpatialTranscriptsPanelComponent, never>;
153
- static ɵcmp: i0.ɵɵComponentDeclaration<SpatialTranscriptsPanelComponent, "spatial-transcripts-panel", never, { "controls": { "alias": "controls"; "required": false; }; "dataset": { "alias": "dataset"; "required": false; }; "view": { "alias": "view"; "required": false; }; "genes": { "alias": "genes"; "required": false; }; "estimate": { "alias": "estimate"; "required": false; }; "densityStats": { "alias": "densityStats"; "required": false; }; "geneCounts": { "alias": "geneCounts"; "required": false; }; "colormapOptions": { "alias": "colormapOptions"; "required": false; }; "open": { "alias": "open"; "required": false; }; }, { "openChange": "openChange"; }, never, never, true, never>;
155
+ static ɵcmp: i0.ɵɵComponentDeclaration<SpatialTranscriptsPanelComponent, "spatial-transcripts-panel", never, { "controls": { "alias": "controls"; "required": false; }; "dataset": { "alias": "dataset"; "required": false; }; "is3d": { "alias": "is3d"; "required": false; }; "view": { "alias": "view"; "required": false; }; "genes": { "alias": "genes"; "required": false; }; "estimate": { "alias": "estimate"; "required": false; }; "densityStats": { "alias": "densityStats"; "required": false; }; "geneCounts": { "alias": "geneCounts"; "required": false; }; "colormapOptions": { "alias": "colormapOptions"; "required": false; }; "open": { "alias": "open"; "required": false; }; }, { "openChange": "openChange"; }, never, never, true, never>;
154
156
  }
@@ -51,6 +51,10 @@ export declare class RegionSourceScope {
51
51
  slicesWithSource(image: string | undefined): number[];
52
52
  /** Whether `image` has one source over all its slices. */
53
53
  hasPlanesSource(image: string | undefined): boolean;
54
+ /** The opener of `image`'s source over all its slices (as attached), or null without one. */
55
+ planesOpener(image: string | undefined): RegionSourceOpener | null;
56
+ /** Whether `image` has any source: one over all its slices, or one of a slice's own. */
57
+ hasAny(image: string | undefined): boolean;
54
58
  /**
55
59
  * The source behind `slice` of `image`, opening it if needed. Resolves null when there is
56
60
  * none, and rejects when it cannot be opened.
@@ -92,6 +92,8 @@ export declare class RegionStore implements IRegionStore, IRegionEditApi, IRegio
92
92
  */
93
93
  private readonly sources;
94
94
  private readonly sourceView$;
95
+ /** Whether the overlays draw the source (see setRegionSourceDrawn). */
96
+ private readonly sourceDrawn$;
95
97
  /** The region look the user chose (overrides the source's hint), field by field. */
96
98
  private userStyle;
97
99
  /** The current source's style hint. */
@@ -355,10 +357,29 @@ export declare class RegionStore implements IRegionStore, IRegionEditApi, IRegio
355
357
  dropSliceRegionSource(): Promise<void>;
356
358
  /** Whether the slice shown has a region source. */
357
359
  hasRegionSource(): boolean;
360
+ /** Whether the current image has any region source, over all its slices or a slice's own. */
361
+ hasAnyRegionSource(): boolean;
362
+ /**
363
+ * The opener of the current image's source over all its slices, as attached (see
364
+ * {@link attachRegionSource}), or null without one: tells whose source it still is.
365
+ */
366
+ getPlanesSourceOpener(): RegionSourceOpener | null;
358
367
  /** The slice's region source as a source layer draws it; null without one (or until it opens). */
359
368
  getRegionSourceView(): RegionSourceView | null;
360
369
  /** {@link getRegionSourceView} and every change of it (slice, taken ids, class colours). */
361
370
  getRegionSourceView$(): Observable<RegionSourceView | null>;
371
+ /**
372
+ * The source view the overlays draw: {@link getRegionSourceView$}, or null while the source is
373
+ * drawn by another layer instead (see {@link setRegionSourceDrawn}). The Region Editor's list
374
+ * and the source's other uses keep reading the source itself.
375
+ */
376
+ getDrawnRegionSourceView$(): Observable<RegionSourceView | null>;
377
+ /**
378
+ * Whether the overlays draw the region source (default), or leave it to another layer that draws
379
+ * the same outlines (the 2D spatial view's cells, from a 3D segmentation's region set), so they
380
+ * are not drawn twice. Only the drawing: the source stays attached, listed and editable.
381
+ */
382
+ setRegionSourceDrawn(drawn: boolean): void;
362
383
  /**
363
384
  * Take source features into the working set for editing: their exact geometry becomes
364
385
  * ordinary regions (minted, coloured and slice-tagged as any region entering the store) and
@@ -41,6 +41,11 @@ export declare class ToolbarComponent {
41
41
  isoRange: number[];
42
42
  /** The last slice index of a stack. */
43
43
  maxIndex: number;
44
+ /**
45
+ * The image is one plane, but a spatial dataset's region set slices it into planes: the live
46
+ * views offer the slider over them ({@link maxIndex} is the last plane), as over a stack.
47
+ */
48
+ planeSlices: boolean;
44
49
  /** The current slice (0-based). */
45
50
  zIndex: number;
46
51
  /** True for any 2D (non Surface-3D) plot type. */
@@ -231,5 +236,5 @@ export declare class ToolbarComponent {
231
236
  protected get isIntensityCapable(): boolean;
232
237
  protected showHelp(): void;
233
238
  static ɵfac: i0.ɵɵFactoryDeclaration<ToolbarComponent, never>;
234
- static ɵcmp: i0.ɵɵComponentDeclaration<ToolbarComponent, "plotting-toolbar", never, { "imageInfo": { "alias": "imageInfo"; "required": false; }; "hasSpatialDataset": { "alias": "hasSpatialDataset"; "required": false; }; "plotTypeOptions": { "alias": "plotTypeOptions"; "required": false; }; "selectedPlotType": { "alias": "selectedPlotType"; "required": false; }; "basePlotType": { "alias": "basePlotType"; "required": false; }; "isoRange": { "alias": "isoRange"; "required": false; }; "maxIndex": { "alias": "maxIndex"; "required": false; }; "zIndex": { "alias": "zIndex"; "required": false; }; "isHeatmap": { "alias": "isHeatmap"; "required": false; }; "is3dRegions": { "alias": "is3dRegions"; "required": false; }; "isVolumeView": { "alias": "isVolumeView"; "required": false; }; "sliceEditor": { "alias": "sliceEditor"; "required": false; }; "activeDragMode": { "alias": "activeDragMode"; "required": false; }; "activeSurface3dMode": { "alias": "activeSurface3dMode"; "required": false; }; "axesVisible": { "alias": "axesVisible"; "required": false; }; "wireframeActive": { "alias": "wireframeActive"; "required": false; }; "resolutionScale": { "alias": "resolutionScale"; "required": false; }; "wandSensitivity": { "alias": "wandSensitivity"; "required": false; }; "brushSize": { "alias": "brushSize"; "required": false; }; "vertexEraserRadius": { "alias": "vertexEraserRadius"; "required": false; }; "canUndo": { "alias": "canUndo"; "required": false; }; "canRedo": { "alias": "canRedo"; "required": false; }; "stackOptions": { "alias": "stackOptions"; "required": false; }; "tools": { "alias": "tools"; "required": false; }; "imageSmoothingEnabled": { "alias": "imageSmoothingEnabled"; "required": false; }; "samModels": { "alias": "samModels"; "required": false; }; "samModelId": { "alias": "samModelId"; "required": false; }; "contributedTools": { "alias": "contributedTools"; "required": false; }; "dialogTools": { "alias": "dialogTools"; "required": false; }; "openDialogToolId": { "alias": "openDialogToolId"; "required": false; }; "toolModelIds": { "alias": "toolModelIds"; "required": false; }; }, { "selectPlotType": "selectPlotType"; "addProfileLine": "addProfileLine"; "toggleImageSmoothing": "toggleImageSmoothing"; "isoRangeChange": "isoRangeChange"; "openChannelHistogram": "openChannelHistogram"; "openSpatialControls": "openSpatialControls"; "openRegionEditor": "openRegionEditor"; "toggleSliceEditor": "toggleSliceEditor"; "selectStackOption": "selectStackOption"; "zScrub": "zScrub"; "zSlide": "zSlide"; "zIndexInput": "zIndexInput"; "reloadAndPlot": "reloadAndPlot"; "downloadImage": "downloadImage"; "autoscaleImage": "autoscaleImage"; "toggleDragMode": "toggleDragMode"; "zoomIn": "zoomIn"; "zoomOut": "zoomOut"; "toggleSurface3dMode": "toggleSurface3dMode"; "resetSurfaceCamera": "resetSurfaceCamera"; "toggleAxes": "toggleAxes"; "toggleWireframe": "toggleWireframe"; "selectResolution": "selectResolution"; "deleteRegion": "deleteRegion"; "undoRegion": "undoRegion"; "redoRegion": "redoRegion"; "segmentRegions": "segmentRegions"; "segmentCellpose": "segmentCellpose"; "runTool": "runTool"; "toggleDialogTool": "toggleDialogTool"; "toolModelChange": "toolModelChange"; "openToolParams": "openToolParams"; "samModelChange": "samModelChange"; "wandSensitivityChange": "wandSensitivityChange"; "brushSizeChange": "brushSizeChange"; "vertexEraserRadiusChange": "vertexEraserRadiusChange"; }, never, ["*"], true, never>;
239
+ static ɵcmp: i0.ɵɵComponentDeclaration<ToolbarComponent, "plotting-toolbar", never, { "imageInfo": { "alias": "imageInfo"; "required": false; }; "hasSpatialDataset": { "alias": "hasSpatialDataset"; "required": false; }; "plotTypeOptions": { "alias": "plotTypeOptions"; "required": false; }; "selectedPlotType": { "alias": "selectedPlotType"; "required": false; }; "basePlotType": { "alias": "basePlotType"; "required": false; }; "isoRange": { "alias": "isoRange"; "required": false; }; "maxIndex": { "alias": "maxIndex"; "required": false; }; "planeSlices": { "alias": "planeSlices"; "required": false; }; "zIndex": { "alias": "zIndex"; "required": false; }; "isHeatmap": { "alias": "isHeatmap"; "required": false; }; "is3dRegions": { "alias": "is3dRegions"; "required": false; }; "isVolumeView": { "alias": "isVolumeView"; "required": false; }; "sliceEditor": { "alias": "sliceEditor"; "required": false; }; "activeDragMode": { "alias": "activeDragMode"; "required": false; }; "activeSurface3dMode": { "alias": "activeSurface3dMode"; "required": false; }; "axesVisible": { "alias": "axesVisible"; "required": false; }; "wireframeActive": { "alias": "wireframeActive"; "required": false; }; "resolutionScale": { "alias": "resolutionScale"; "required": false; }; "wandSensitivity": { "alias": "wandSensitivity"; "required": false; }; "brushSize": { "alias": "brushSize"; "required": false; }; "vertexEraserRadius": { "alias": "vertexEraserRadius"; "required": false; }; "canUndo": { "alias": "canUndo"; "required": false; }; "canRedo": { "alias": "canRedo"; "required": false; }; "stackOptions": { "alias": "stackOptions"; "required": false; }; "tools": { "alias": "tools"; "required": false; }; "imageSmoothingEnabled": { "alias": "imageSmoothingEnabled"; "required": false; }; "samModels": { "alias": "samModels"; "required": false; }; "samModelId": { "alias": "samModelId"; "required": false; }; "contributedTools": { "alias": "contributedTools"; "required": false; }; "dialogTools": { "alias": "dialogTools"; "required": false; }; "openDialogToolId": { "alias": "openDialogToolId"; "required": false; }; "toolModelIds": { "alias": "toolModelIds"; "required": false; }; }, { "selectPlotType": "selectPlotType"; "addProfileLine": "addProfileLine"; "toggleImageSmoothing": "toggleImageSmoothing"; "isoRangeChange": "isoRangeChange"; "openChannelHistogram": "openChannelHistogram"; "openSpatialControls": "openSpatialControls"; "openRegionEditor": "openRegionEditor"; "toggleSliceEditor": "toggleSliceEditor"; "selectStackOption": "selectStackOption"; "zScrub": "zScrub"; "zSlide": "zSlide"; "zIndexInput": "zIndexInput"; "reloadAndPlot": "reloadAndPlot"; "downloadImage": "downloadImage"; "autoscaleImage": "autoscaleImage"; "toggleDragMode": "toggleDragMode"; "zoomIn": "zoomIn"; "zoomOut": "zoomOut"; "toggleSurface3dMode": "toggleSurface3dMode"; "resetSurfaceCamera": "resetSurfaceCamera"; "toggleAxes": "toggleAxes"; "toggleWireframe": "toggleWireframe"; "selectResolution": "selectResolution"; "deleteRegion": "deleteRegion"; "undoRegion": "undoRegion"; "redoRegion": "redoRegion"; "segmentRegions": "segmentRegions"; "segmentCellpose": "segmentCellpose"; "runTool": "runTool"; "toggleDialogTool": "toggleDialogTool"; "toolModelChange": "toolModelChange"; "openToolParams": "openToolParams"; "samModelChange": "samModelChange"; "wandSensitivityChange": "wandSensitivityChange"; "brushSizeChange": "brushSizeChange"; "vertexEraserRadiusChange": "vertexEraserRadiusChange"; }, never, ["*"], true, never>;
235
240
  }
@@ -0,0 +1,55 @@
1
+ import { Observable } from 'rxjs';
2
+ import { IImageInfo } from '../contracts/image.contract';
3
+ import { SpatialDataPort } from '../contracts/ports/spatial-data.port';
4
+ import { SpatialDataset } from '../contracts/spatial-dataset.contract';
5
+ import type { RegionSourceOpener } from '../store/region-source-scope';
6
+ /** What {@link SpatialRegionSetLink} attaches a dataset's region set through (the router). */
7
+ export interface DatasetRegionSetTarget {
8
+ attachDatasetRegionSet?(open: RegionSourceOpener, key: string): Promise<boolean>;
9
+ releaseDatasetRegionSet?(keep: string | null): void;
10
+ }
11
+ /**
12
+ * The region set a spatial dataset's boundaries name (a 3D segmentation's cells, see
13
+ * `SpatialPolygonTilesMeta.sets`): the default set's when it names one, else the first that does.
14
+ */
15
+ export declare function datasetRegionSet(dataset: SpatialDataset | null | undefined): string | null;
16
+ /**
17
+ * Whether `info` is the dataset's own image, the one its `imageRef` names. Exactly, when the host
18
+ * gives the image's id ({@link IImageInfo.imageId}); otherwise by the file name the id ends in (the
19
+ * host opens the image by that id, a path), which images of other datasets can share: then the link
20
+ * only takes an image that landed after the dataset was selected (see {@link SpatialRegionSetLink}).
21
+ * Not the reference volume's stack, which a dataset without an `imageRef` is drawn over: the region
22
+ * set's coordinates are not its pixels.
23
+ */
24
+ export declare function isDatasetImage(info: IImageInfo | null | undefined, dataset: SpatialDataset | null | undefined): boolean;
25
+ /**
26
+ * Attaches a spatial dataset's region set to its image in the region editor, once both are there:
27
+ * the dataset (the port's) and its image, landed. Each time either changes it asks again; the
28
+ * target attaches once per image and set.
29
+ *
30
+ * An image that landed while another dataset was selected is not taken for this one by its file name,
31
+ * only by its id ({@link IImageInfo.imageId}): a host selects the dataset and then opens its image,
32
+ * and until that lands the image on screen is the previous dataset's, though its file name may be the
33
+ * same (every converted bundle's is `plate.ome.tif`). One that landed with no dataset selected may be.
34
+ */
35
+ export declare class SpatialRegionSetLink {
36
+ private readonly port;
37
+ private readonly target;
38
+ private dataset;
39
+ private image;
40
+ /** The dataset selected when the image landed (its id), or null: none was. */
41
+ private imageDataset;
42
+ /** The region set last asked to be attached, until the dataset stops naming it. */
43
+ private asked;
44
+ constructor(port: SpatialDataPort | undefined, target: DatasetRegionSetTarget);
45
+ /** Follow the port's dataset until `until$` emits. */
46
+ bind(until$: Observable<unknown>): void;
47
+ /** An image landed (its render settled): the dataset's own, perhaps. */
48
+ imageLanded(info: IImageInfo): void;
49
+ /**
50
+ * Whether the landed image may be the dataset's: by its id when the host gives one, else only when
51
+ * it landed under this dataset or under none (see the class's note).
52
+ */
53
+ private imageOf;
54
+ private sync;
55
+ }
@@ -122,6 +122,11 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
122
122
  private readonly consumedSliceHints;
123
123
  protected zIndex: number;
124
124
  protected maxIndex: number;
125
+ /**
126
+ * Planes of the spatial dataset's region set slicing the image, an image of one plane (see
127
+ * `IVisualizer.getDatasetPlanes$`): the slider then runs over them. 0 without.
128
+ */
129
+ protected datasetPlanes: number;
125
130
  contextMenu: ContextMenu;
126
131
  protected contextMenuItems: MenuItem[];
127
132
  /** The armed tool mode and the toolbar's tool settings. */
@@ -285,6 +290,8 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
285
290
  protected isoRange: number[];
286
291
  /** The spatial-omics dataset on offer and the gates it puts on the selector. */
287
292
  protected readonly spatial: SpatialDatasetBinder;
293
+ /** Attaches a spatial dataset's region set (a 3D segmentation's cells) to its image's regions. */
294
+ private readonly regionSetLink;
288
295
  /** Whether a spatial-omics dataset is published on `SPATIAL_DATA_PORT` — gates the
289
296
  * spatial plot types; the toolbar offers the plot modes for an image-less one too. */
290
297
  protected get hasSpatialDataset(): boolean;
@@ -298,6 +305,13 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
298
305
  /** Follow the spatial-omics dataset: a dataset appearing, switching or being cleared
299
306
  * re-gates the selector exactly as the image stream and the test-mode toggle do. */
300
307
  private watchSpatialDataset;
308
+ /**
309
+ * The slider over the dataset's planes, on an image of one plane: its bounds are the planes'
310
+ * (none left: back to the image's one), the slice kept within them.
311
+ */
312
+ private layOutPlanes;
313
+ /** The last slice index the dataset's planes give an image of one plane (0 without). */
314
+ private planeMaxIndex;
301
315
  /** Recompute the selector's entries for the current image, dataset and test mode
302
316
  * (see {@link computePlotTypeMenu}). */
303
317
  private computePlotTypeOptions;