@jax-data-science/sci-image-visualizer 0.12.1 → 0.14.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 (78) hide show
  1. package/esm2022/lib/contracts/channel-histogram-api.contract.mjs +19 -1
  2. package/esm2022/lib/contracts/display-types.mjs +7 -1
  3. package/esm2022/lib/contracts/image.contract.mjs +1 -1
  4. package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
  5. package/esm2022/lib/contracts/spatial-dataset.contract.mjs +1 -1
  6. package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
  7. package/esm2022/lib/geometry/reconstruct.mjs +11 -1
  8. package/esm2022/lib/implementations/napari-js/napari-image-2d-scene.mjs +17 -2
  9. package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +88 -10
  10. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +62 -13
  11. package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +21 -1
  12. package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +5 -1
  13. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +9 -1
  14. package/esm2022/lib/implementations/napari-js/spatial-tiles/categorical-lookup.mjs +26 -3
  15. package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +3 -2
  16. package/esm2022/lib/implementations/napari-js/spatial-tiles/density-layer.mjs +20 -4
  17. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-hover.mjs +4 -2
  18. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-jobs.mjs +4 -2
  19. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +42 -15
  20. package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +3 -1
  21. package/esm2022/lib/region-editor/region-editor.component.mjs +13 -1
  22. package/esm2022/lib/routing-visualizer.service.mjs +4 -1
  23. package/esm2022/lib/spatial/lod.mjs +6 -3
  24. package/esm2022/lib/spatial/spatial-controls.facade.mjs +78 -23
  25. package/esm2022/lib/spatial/spatial-gene-filter.mjs +138 -0
  26. package/esm2022/lib/spatial/spatial-selection.mjs +70 -1
  27. package/esm2022/lib/spatial/spatial-tile-merge.mjs +42 -1
  28. package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +3 -3
  29. package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +54 -11
  30. package/esm2022/lib/spatial-controls/spatial-gene-style/spatial-gene-style.component.mjs +66 -0
  31. package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +106 -26
  32. package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +3 -3
  33. package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +3 -3
  34. package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +3 -3
  35. package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +110 -8
  36. package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +41 -9
  37. package/esm2022/lib/store/region-selection.mjs +21 -4
  38. package/esm2022/lib/store/region-store.service.mjs +22 -3
  39. package/esm2022/lib/store/spatial-selection.service.mjs +13 -1
  40. package/esm2022/lib/store/visualizer-store.service.mjs +50 -1
  41. package/esm2022/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.mjs +3 -3
  42. package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DnPlIP2F.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DvFp1jNH.mjs} +1777 -793
  43. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DvFp1jNH.mjs.map +1 -0
  44. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bs987_-E.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-D7lSUAM1.mjs} +2 -2
  45. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bs987_-E.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-D7lSUAM1.mjs.map} +1 -1
  46. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +2 -2
  47. package/lib/contracts/channel-histogram-api.contract.d.ts +14 -0
  48. package/lib/contracts/display-types.d.ts +27 -0
  49. package/lib/contracts/image.contract.d.ts +2 -0
  50. package/lib/contracts/region-editor-api.contract.d.ts +3 -0
  51. package/lib/contracts/spatial-dataset.contract.d.ts +7 -0
  52. package/lib/contracts/visualizer.contract.d.ts +28 -2
  53. package/lib/geometry/reconstruct.d.ts +6 -0
  54. package/lib/implementations/napari-js/napari-image-2d-scene.d.ts +7 -0
  55. package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +13 -2
  56. package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +5 -0
  57. package/lib/implementations/napari-js/napari-spatial-scene.d.ts +4 -0
  58. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +5 -0
  59. package/lib/implementations/napari-js/spatial-tiles/categorical-lookup.d.ts +6 -1
  60. package/lib/implementations/napari-js/spatial-tiles/transcript-hover.d.ts +4 -0
  61. package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +3 -1
  62. package/lib/routing-visualizer.service.d.ts +1 -0
  63. package/lib/spatial/lod.d.ts +3 -1
  64. package/lib/spatial/spatial-controls.facade.d.ts +19 -2
  65. package/lib/spatial/spatial-gene-filter.d.ts +44 -0
  66. package/lib/spatial/spatial-selection.d.ts +16 -1
  67. package/lib/spatial/spatial-tile-merge.d.ts +17 -0
  68. package/lib/spatial-controls/spatial-controls.component.d.ts +14 -3
  69. package/lib/spatial-controls/spatial-gene-style/spatial-gene-style.component.d.ts +30 -0
  70. package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +39 -7
  71. package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +33 -1
  72. package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +13 -1
  73. package/lib/store/region-selection.d.ts +14 -3
  74. package/lib/store/region-store.service.d.ts +14 -1
  75. package/lib/store/spatial-selection.service.d.ts +8 -0
  76. package/lib/store/visualizer-store.service.d.ts +13 -0
  77. package/package.json +1 -1
  78. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DnPlIP2F.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { EventEmitter, NgZone, OnInit } from '@angular/core';
2
- import { IVisualizer, ISpatialControls } from '../contracts/visualizer.contract';
2
+ import { IVisualizer, ISpatialControls, RoiSelectionMode } from '../contracts/visualizer.contract';
3
3
  import { SpatialDataset } from '../contracts/spatial-dataset.contract';
4
4
  import { ColormapNode, SpatialViewState } from '../contracts/display-types';
5
5
  import { PanelOption, parseGeneGroups } from '../spatial/spatial-panel-model';
@@ -81,6 +81,12 @@ export declare class SpatialControlsComponent implements OnInit {
81
81
  /** An ROI selection that matched nothing, so the UI can say so rather than
82
82
  * looking like the button did nothing. */
83
83
  protected selectionMissed: boolean;
84
+ /** The mode of the selection that {@link selectionMissed}: what it found nothing inside. */
85
+ protected missedMode: RoiSelectionMode;
86
+ /** The region classes picked in the Region Editor: in 3D, "Select from ROIs" selects inside them. */
87
+ protected pickedClasses: readonly string[];
88
+ /** While "Select from ROIs" reads the picked classes' outlines. */
89
+ protected selectingFromRegions: boolean;
84
90
  /**
85
91
  * Whether the Distribution section is expanded. Collapsed by default: the
86
92
  * panel's primary job is the colour controls, and the chart roughly doubles
@@ -106,8 +112,13 @@ export declare class SpatialControlsComponent implements OnInit {
106
112
  onGeneFilter(query: string): Promise<void>;
107
113
  /** A gene dropdown opened — see {@link GenePickerModel.ensureList}. */
108
114
  ensureGeneList(): Promise<void>;
109
- /** Select every observation inside the drawn regions (their union). */
110
- protected selectFromRegions(): void;
115
+ /** Select every observation inside the drawn regions (their union) — in 3D, inside the
116
+ * picked classes' volumes. */
117
+ protected selectFromRegions(): Promise<void>;
118
+ /** In 3D with classes picked, "Select from ROIs" selects inside their volumes. */
119
+ protected get selectsClassVolumes(): boolean;
120
+ /** How "Select from ROIs" selects now: the controls' own rule, the one the selection runs by. */
121
+ private get roiSelectionMode();
111
122
  /** Legend click: select one category. Clicking the active row clears it, so a
112
123
  * second click is an undo rather than a no-op. */
113
124
  protected selectCategory(index: number): Promise<void>;
@@ -0,0 +1,30 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import { TranscriptGlyphName } from '../../contracts/display-types';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * One gene's icon and colour: the icon grid, a colour picker with its hex value, presets, and
6
+ * a reset — the content of a popover its host opens on the gene's swatch. Writes nothing itself:
7
+ * it reports the choice, and the host stores it where it belongs.
8
+ */
9
+ export declare class SpatialGeneStyleComponent {
10
+ /** The gene, for the controls' labels. */
11
+ gene: string;
12
+ /** What the icons and colour are of ("Observation", "Transcript"), for the titles. */
13
+ what: string;
14
+ /** The gene's colour, `#rrggbb`. */
15
+ color: string;
16
+ /** The gene's icon. */
17
+ glyph: TranscriptGlyphName;
18
+ /** A note under the icons, e.g. where they show; none when null. */
19
+ iconHint: string | null;
20
+ readonly colorChange: EventEmitter<string>;
21
+ readonly glyphChange: EventEmitter<TranscriptGlyphName>;
22
+ /** Back to the gene's default icon and colour. */
23
+ readonly resetStyle: EventEmitter<void>;
24
+ protected readonly glyphOptions: import("../../spatial/spatial-panel-model").GlyphOption[];
25
+ protected readonly colorPresets: string[];
26
+ /** A typed hex colour, accepted as `#rrggbb` or `rrggbb`; anything else is ignored. */
27
+ protected onHex(text: string): void;
28
+ 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>;
30
+ }
@@ -13,11 +13,21 @@ interface GeneRowView {
13
13
  /** Transcripts in view, or null before the renderer reports any. */
14
14
  count: number | null;
15
15
  }
16
+ /** One row of the all-genes list. */
17
+ interface AllGeneRowView {
18
+ gene: string;
19
+ shown: boolean;
20
+ /** Its colour when coloured by gene, or null when the dataset's code order is unknown. */
21
+ swatch: string | null;
22
+ count: number | null;
23
+ }
16
24
  /**
17
25
  * The selected transcript genes as Xenium Explorer's tree: the gene groups, then the
18
26
  * ungrouped genes, each row with an eye that hides it without deselecting it, its marker
19
27
  * in its colour (opening one icon-and-colour picker per gene), and its transcript count in
20
- * view.
28
+ * view. With "All genes" on, the root eye hides or shows every transcript and the root
29
+ * expands to every gene of the dataset, each with its eye when the dataset lists its genes
30
+ * in code order (`transcriptTiles.genes`), filtered by name past a few hundred.
21
31
  *
22
32
  * Writes only through `controls.setViewState`.
23
33
  */
@@ -34,9 +44,7 @@ export declare class SpatialGeneTreeComponent implements OnChanges {
34
44
  geneCounts: Record<string, number> | null;
35
45
  /** Real genes in the panel — the tree's denominator. */
36
46
  geneTotal: number;
37
- protected readonly glyphOptions: import("../../spatial/spatial-panel-model").GlyphOption[];
38
47
  /** Swatches in the picker: the categorical palette genes are coloured from by default. */
39
- protected readonly colorPresets: string[];
40
48
  /** The tree, rebuilt when the view changes — never per change-detection pass. */
41
49
  protected geneTree: GeneTreeNode[];
42
50
  /** Per gene: its eye, swatch, glyph and count — rebuilt with the inputs (and when the
@@ -47,6 +55,18 @@ export declare class SpatialGeneTreeComponent implements OnChanges {
47
55
  protected rootShown: boolean;
48
56
  protected collapsedGeneGroups: Set<string>;
49
57
  protected geneTreeOpen: boolean;
58
+ /** The all-genes list starts closed: it can run to thousands of genes. */
59
+ protected allGenesOpen: boolean;
60
+ /** The genes "All genes" lists, or null when the dataset names none. */
61
+ protected allGeneList: readonly string[] | null;
62
+ /** Whether a gene of "All genes" can be hidden: the dataset lists its genes in code order. */
63
+ protected canHideAllGenes: boolean;
64
+ protected allGenesFilter: string;
65
+ /** The list's rows matching the filter, at most {@link ALL_GENES_ROWS}. */
66
+ protected allRows: AllGeneRowView[];
67
+ /** How many genes match the filter, for the "showing n of m" line. */
68
+ protected allGenesMatched: number;
69
+ protected readonly allGenesRowCap = 200;
50
70
  /** The gene the open picker edits. */
51
71
  protected styleGene: string | null;
52
72
  /** Colours of the cells' groups, by name — what a cluster of the same name is drawn in. */
@@ -58,13 +78,26 @@ export declare class SpatialGeneTreeComponent implements OnChanges {
58
78
  constructor(zone: NgZone, cdr: ChangeDetectorRef);
59
79
  ngOnChanges(changes: SimpleChanges): void;
60
80
  private rebuildRows;
81
+ /**
82
+ * The all-genes list's rows: the genes matching the filter, up to the cap. Built only while
83
+ * the list is open: the counts in view change with every pan, and the list can be thousands.
84
+ */
85
+ private rebuildAllRows;
86
+ /** Whether "All genes" draws anything: not switched off whole, nor every listed gene hidden. */
87
+ private anyOfAllGenesShown;
88
+ /** A gene of "All genes" in its colour by gene: its chosen one, else the palette's by code. */
89
+ private allGeneColorOf;
90
+ protected toggleAllGenesOpen(): void;
91
+ protected onAllGenesFilter(text: string): void;
61
92
  protected toggleGeneGroup(name: string): void;
62
93
  protected isGeneShown(gene: string): boolean;
63
94
  protected areGenesShown(genes: string[]): boolean;
64
95
  /** The eye toggle: hide or show genes without removing them from the selection. */
65
96
  protected onGenesShown(genes: string[], on: boolean): void;
66
- /** The root eye while every gene is shown: back to the chosen list. */
67
- protected onToggleAllGenes(): void;
97
+ /** The root eye while every gene is drawn: hide or show them all (the '±' leaves "All genes"). */
98
+ protected onAllGenesShown(on: boolean): void;
99
+ /** One gene's eye in the all-genes list. Showing one while all are off shows it alone. */
100
+ protected onAllGeneShown(gene: string, on: boolean): void;
68
101
  protected onGeneColor(gene: string, hex: string): void;
69
102
  protected openGeneStyle(event: Event, gene: string, panel: {
70
103
  toggle(e: Event): void;
@@ -75,8 +108,6 @@ export declare class SpatialGeneTreeComponent implements OnChanges {
75
108
  protected glyphPoints(glyph: TranscriptGlyphName): string;
76
109
  protected glyphOf(gene: string, slot: number): TranscriptGlyphName;
77
110
  protected onGlyph(gene: string, glyph: TranscriptGlyphName): void;
78
- /** A typed hex colour, accepted as `#rrggbb` or `rrggbb`; anything else is ignored. */
79
- protected onGeneHex(gene: string, text: string): void;
80
111
  /** Back to the gene's default icon and colour (by its position in the list). */
81
112
  protected resetGeneStyle(gene: string): void;
82
113
  /** The colour gene `slot` is drawn in when transcripts are coloured by gene. */
@@ -89,6 +120,7 @@ export declare class SpatialGeneTreeComponent implements OnChanges {
89
120
  name: string | null;
90
121
  }) => string;
91
122
  protected trackByLabelString: (_i: number, s: string) => string;
123
+ protected trackByAllRow: (_i: number, row: AllGeneRowView) => string;
92
124
  /**
93
125
  * The cluster colours, rebuilt only when what they come from changes. The template asks
94
126
  * once per gene row per change-detection pass, and rebuilding per call made that O(G²).
@@ -1,7 +1,8 @@
1
1
  import { EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
2
+ import { Observable } from 'rxjs';
2
3
  import type { ISpatialControls } from '../../contracts/visualizer.contract';
3
4
  import type { SpatialDataset } from '../../contracts/spatial-dataset.contract';
4
- import { ColormapNode, SpatialViewState } from '../../contracts/display-types';
5
+ import { ColormapNode, SpatialViewState, TranscriptGlyphName } from '../../contracts/display-types';
5
6
  import { SpatialSelectionMask } from '../../spatial/spatial-selection';
6
7
  import { PanelOption } from '../../spatial/spatial-panel-model';
7
8
  import type { GenePickerModel } from '../spatial-gene-picker';
@@ -45,6 +46,8 @@ export declare class SpatialObservationsPanelComponent implements OnChanges {
45
46
  /** A legend row was clicked (see the key). */
46
47
  readonly categoryClicked: EventEmitter<number>;
47
48
  protected readonly clipOptions: PanelOption<[number, number]>[];
49
+ /** How several genes of the observation filter combine. */
50
+ protected readonly matchOptions: PanelOption<SpatialViewState['observationGenesMatch']>[];
48
51
  /** Virtual-scrolled only past this many options (see the cells panel's gene dropdown). */
49
52
  protected readonly geneVirtualScrollFrom = 200;
50
53
  /** Colour-by column choices — "None" plus every column the dataset declares. */
@@ -62,6 +65,35 @@ export declare class SpatialObservationsPanelComponent implements OnChanges {
62
65
  protected onColumn(name: string | null): void;
63
66
  /** A gene was picked; it supersedes any column selection. */
64
67
  protected onGene(name: string | null): void;
68
+ /** Genes picked for the observation filter; none draws every observation. */
69
+ protected onObservationGenes(genes: string[] | null): void;
70
+ protected onObservationGenesMatch(match: SpatialViewState['observationGenesMatch'] | null): void;
71
+ /** Whether the gene filter could not be applied (an expression read failed); one stream per
72
+ * `controls`, so the template's async pipe keeps its subscription. */
73
+ protected geneFilterFailed$: Observable<boolean>;
74
+ /** Ask for the picked genes' expression again (a failed read is not cached). */
75
+ protected retryGeneFilter(): void;
76
+ protected onObservationGenesColorBy(on: boolean): void;
77
+ protected removeObservationGene(gene: string): void;
78
+ protected isObservationGene(gene: string): boolean;
79
+ protected trackByGene(_i: number, gene: string): string;
80
+ /** The gene the icon and colour picker is open for. */
81
+ protected styleGene: string | null;
82
+ protected geneColorOf(gene: string): string;
83
+ protected geneGlyphOf(gene: string): TranscriptGlyphName;
84
+ protected glyphPointsOf(gene: string): string;
85
+ /** Open the picker on the gene's swatch. Inside the genes dropdown the click must not also
86
+ * reach the option, which would unpick the gene. */
87
+ protected openGeneStyle(event: Event, gene: string, panel: {
88
+ toggle(e: Event): void;
89
+ hide(): void;
90
+ }): void;
91
+ protected onGeneColor(gene: string, hex: string): void;
92
+ protected onGeneGlyph(gene: string, glyph: TranscriptGlyphName): void;
93
+ /** Back to the gene's default colour (its place in the list) and icon (a circle). */
94
+ protected resetGeneStyle(gene: string): void;
95
+ /** What the filter hides, in words. */
96
+ protected get geneFilterHint(): string;
65
97
  /** Cell outlines on offer, which changes what the circles mean. */
66
98
  protected get hasCells(): boolean;
67
99
  /** True while a selection is active — everything else renders muted. */
@@ -54,7 +54,13 @@ export declare class SpatialTranscriptsPanelComponent implements OnChanges {
54
54
  readonly openChange: EventEmitter<boolean>;
55
55
  /** Virtual-scrolled only past this many options (see the cells panel's gene dropdown). */
56
56
  protected readonly geneVirtualScrollFrom = 200;
57
- protected readonly transcriptColorOptions: PanelOption<SpatialViewState['transcriptColorBy']>[];
57
+ /**
58
+ * Colourings on offer: "Cell type" only for a dataset with cell types. Rebuilt only when that
59
+ * changes, for the same reason as {@link transcriptModeOptions}.
60
+ */
61
+ protected transcriptColorOptions: PanelOption<SpatialViewState['transcriptColorBy']>[];
62
+ /** Whether the dataset has a column naming each cell's type (see `cellTypeColumnFor`). */
63
+ protected hasCellTypes: boolean;
58
64
  protected readonly glyphOptions: import("../../spatial/spatial-panel-model").GlyphOption[];
59
65
  protected readonly budgetOptions: {
60
66
  label: string;
@@ -117,8 +123,14 @@ export declare class SpatialTranscriptsPanelComponent implements OnChanges {
117
123
  */
118
124
  protected onImportGeneGroups(input: HTMLInputElement): Promise<void>;
119
125
  protected get estimatePercent(): number;
126
+ /** Whether the Observations gene filter is on, which limits the transcripts drawn. */
127
+ protected get observationsFiltered(): boolean;
120
128
  protected get estimateOverMax(): boolean;
121
129
  protected onTranscriptBudget(n: number): void;
130
+ /** The colouring in use: "Cell type" without cell types colours by gene (as the markers do). */
131
+ protected get transcriptColorShown(): SpatialViewState['transcriptColorBy'];
132
+ /** Genes of "All genes" hidden one by one (not the whole set switched off). */
133
+ protected get allGenesSomeHidden(): boolean;
122
134
  protected onTranscriptColorBy(by: SpatialViewState['transcriptColorBy']): void;
123
135
  protected onTranscriptScale(value: number | undefined): void;
124
136
  protected onTranscriptOpacity(value: number | undefined): void;
@@ -10,18 +10,29 @@ interface HasId {
10
10
  * owner calls {@link sync} once the region array it projects onto is final,
11
11
  * which prunes ids that no longer exist and emits {@link indices$} only when
12
12
  * the index set changed.
13
+ *
14
+ * A selection made by picking classes (the class tree, a surface in 3D) also
15
+ * holds those classes: a class is a volume through the whole stack, whether or
16
+ * not it has a region on the slice. Any other selection drops them; an edit
17
+ * ({@link retain}, {@link sync}) keeps them.
13
18
  */
14
19
  export declare class RegionSelection {
15
20
  private selected;
21
+ private picked;
16
22
  private readonly indicesSubject;
23
+ private readonly classesSubject;
17
24
  /** The selected regions' current array indices (emits on change only). */
18
25
  readonly indices$: Observable<number[]>;
26
+ /** The classes the selection was picked as ([] for any other selection; emits on change only). */
27
+ readonly classes$: Observable<readonly string[]>;
28
+ /** The classes the selection was picked as, as last emitted by {@link sync}. */
29
+ get classes(): readonly string[];
19
30
  /** The selected indices as last projected by {@link sync}. */
20
31
  get indices(): number[];
21
32
  /** The selected ids, in selection order. */
22
33
  get ids(): readonly number[];
23
- /** Replace the selected ids (no emit until {@link sync}). */
24
- replace(ids: number[]): void;
34
+ /** Replace the selected ids, picked as `classes` if they were (no emit until {@link sync}). */
35
+ replace(ids: number[], classes?: readonly string[]): void;
25
36
  /** Keep only the ids `keep` accepts (no emit until {@link sync}). */
26
37
  retain(keep: (id: number) => boolean): void;
27
38
  /**
@@ -30,7 +41,7 @@ export declare class RegionSelection {
30
41
  */
31
42
  selectIndices(indices: number[], regions: readonly HasId[]): void;
32
43
  /** Project the selected ids onto `regions`, pruning ids it no longer holds,
33
- * and emit if the index set changed. */
44
+ * and emit if the index set (or the picked classes) changed. */
34
45
  sync(regions: readonly HasId[]): void;
35
46
  }
36
47
  export {};
@@ -377,9 +377,22 @@ export declare class RegionStore implements IRegionStore, IRegionEditApi, IRegio
377
377
  /**
378
378
  * Select every region of these classes on the slice — the regions', and the region source's,
379
379
  * which are taken into the regions (at most {@link SELECT_CLASSES_LIMIT} of them). Added to the
380
- * selection with `additive`. Resolves the selected region ids.
380
+ * selection with `additive`. The selection holds the classes too (see {@link getPickedClasses}).
381
+ * Resolves the selected region ids.
381
382
  */
382
383
  selectClasses(classes: readonly string[], additive?: boolean): Promise<number[]>;
384
+ /**
385
+ * The classes the selection was picked as by {@link selectClasses} (a class tree node with its
386
+ * subclasses, a surface clicked in 3D); [] once anything else selected. Each is a volume through
387
+ * the whole stack, whether or not it has a region on the slice.
388
+ */
389
+ getPickedClasses(): readonly string[];
390
+ getPickedClasses$(): Observable<readonly string[]>;
391
+ /**
392
+ * Every slice's exact outlines of these classes, the region sources' and the regions' (as the
393
+ * 3D reconstruction reads them at the stack's own resolution): what is inside their volume.
394
+ */
395
+ classSliceOutlines(classes: readonly string[]): Promise<SliceOutlines[]>;
383
396
  /**
384
397
  * The 3D reconstruction of each group of classes over every slice of the stack (an atlas
385
398
  * structure with its substructures, say): the outlines of the regions of those classes on every
@@ -11,6 +11,14 @@ import * as i0 from "@angular/core";
11
11
  */
12
12
  export declare class SpatialSelectionStore {
13
13
  private readonly selection$;
14
+ /** Bumped by every write, a clear of nothing included (see {@link revision}). */
15
+ private writes;
16
+ /**
17
+ * How many times the selection was written (set or cleared, by any writer). A selection
18
+ * computed asynchronously compares it before publishing: a newer write — a Clear, a legend
19
+ * click, a linked chart's brush — supersedes it.
20
+ */
21
+ revision(): number;
14
22
  /** Emits on every change, including a clear. */
15
23
  getSelection$(): Observable<SpatialSelectionMask>;
16
24
  /** Synchronous read, for a renderer building its first frame. */
@@ -76,6 +76,18 @@ export declare class VisualizerStore {
76
76
  * Editor) show µm²/mm² instead of px². No-op when neither axis is positive.
77
77
  */
78
78
  setPhysicalPixelSize(mppX?: number, mppY?: number): void;
79
+ /**
80
+ * Fill in the channel names and tints the host's image meta left out, from the image's tile
81
+ * descriptor: the server reads them from the file (an OME-TIFF's channel names, such as Cytos's
82
+ * "Actin" or "Cell-Membrane"), where a host's metadata (jit-ui's `/metadata`) carries none, so
83
+ * the Channels pane showed "Channel 1", "Channel 2"… The host's own names and tints win; only a
84
+ * channel still showing its derived default takes the descriptor's, so an edit made in the pane
85
+ * stays. A no-op when the channel counts differ, or for RGB.
86
+ */
87
+ adoptChannelInfo(info: ReadonlyArray<{
88
+ name?: string;
89
+ color?: string;
90
+ }> | null | undefined): void;
79
91
  /**
80
92
  * Publish the current image's metadata and derive its channels.
81
93
  *
@@ -90,6 +102,7 @@ export declare class VisualizerStore {
90
102
  * - RGB (rgbChannels ≥ 3) → Red/Green/Blue;
91
103
  * - multichannel fluorescence (channelCount > 1) → one channel per band,
92
104
  * named/tinted from the server `channelInfo` when present, else a palette;
105
+ * only the first `DEFAULT_VISIBLE_CHANNELS` start visible (see `defaultChannelVisible`);
93
106
  * - otherwise a single grayscale "Intensity" channel. */
94
107
  private deriveChannels;
95
108
  getChannelStates(): Observable<IChannelState[]>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jax-data-science/sci-image-visualizer",
3
- "version": "0.12.1",
3
+ "version": "0.14.0",
4
4
  "engines": {
5
5
  "node": ">=20.9.0"
6
6
  },