@vitessce/launcher 4.0.0 → 4.0.2
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/dist/{GeometryAndMeshXR-CeAaq3ae.js → GeometryAndMeshXR-DsObDSMF.js} +2 -2
- package/dist/{ReactNeuroglancer-BLfUOvtO.js → ReactNeuroglancer-C2C-vEVu.js} +169 -57
- package/dist/{XREnterButton-vmEhdF4L.js → XREnterButton-B6j_tE1d.js} +1 -1
- package/dist/{XRSceneComponents-DnZLSAJz.js → XRSceneComponents-BgZ4J_JS.js} +3 -1
- package/dist/{XRWrapper-C94X82Mb.js → XRWrapper-BLKqjWwm.js} +3 -2
- package/dist/{deflate-nYfk3Mbe.js → deflate-38TS7div.js} +1 -1
- package/dist/{higlass-DPgS6S1h.js → higlass-CKuPDg4y.js} +1 -1
- package/dist/{index-C2U2CO2P.js → index-CA6Y_Dls.js} +18 -6
- package/dist/{index-DDD3apxS.js → index-D-cJewP-.js} +1017 -209
- package/dist/{index-DuFOjj6d.js → index-gStG4FEQ.js} +1 -1
- package/dist/index.js +3 -3
- package/dist/{jpeg-4XvdCEqV.js → jpeg-BGB-_EKG.js} +1 -1
- package/dist/{lerc-J5N91MJw.js → lerc-Db0ZEZ3c.js} +1 -1
- package/dist/{lzw-BlNLuocx.js → lzw-BmHVONBc.js} +1 -1
- package/dist/{packbits-D7jhgu7h.js → packbits-DKF2IGBX.js} +1 -1
- package/dist/{raw-Dcz65jWu.js → raw-DMNeLVd7.js} +1 -1
- package/dist/{webimage-CMXekglL.js → webimage-BTp31_-j.js} +1 -1
- package/dist/xrStore-CDyKy5UF.js +8 -0
- package/package.json +9 -9
- package/dist/xrStore-BymedRtx.js +0 -8
|
@@ -6375,12 +6375,12 @@ function baseIsEqual$3(value2, other, bitmask, customizer, stack2) {
|
|
|
6375
6375
|
var now$4 = function() {
|
|
6376
6376
|
return root$d.Date.now();
|
|
6377
6377
|
};
|
|
6378
|
-
var FUNC_ERROR_TEXT$
|
|
6378
|
+
var FUNC_ERROR_TEXT$3 = "Expected a function";
|
|
6379
6379
|
var nativeMax$3 = Math.max, nativeMin$1 = Math.min;
|
|
6380
6380
|
function debounce$5(func, wait2, options) {
|
|
6381
6381
|
var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true;
|
|
6382
6382
|
if (typeof func != "function") {
|
|
6383
|
-
throw new TypeError(FUNC_ERROR_TEXT$
|
|
6383
|
+
throw new TypeError(FUNC_ERROR_TEXT$3);
|
|
6384
6384
|
}
|
|
6385
6385
|
wait2 = toNumber$3(wait2) || 0;
|
|
6386
6386
|
if (isObject$f(options)) {
|
|
@@ -6538,6 +6538,22 @@ var range$e = createRange();
|
|
|
6538
6538
|
function sum$6(array2) {
|
|
6539
6539
|
return array2 && array2.length ? baseSum(array2, identity$h) : 0;
|
|
6540
6540
|
}
|
|
6541
|
+
var FUNC_ERROR_TEXT$2 = "Expected a function";
|
|
6542
|
+
function throttle$1(func, wait2, options) {
|
|
6543
|
+
var leading = true, trailing = true;
|
|
6544
|
+
if (typeof func != "function") {
|
|
6545
|
+
throw new TypeError(FUNC_ERROR_TEXT$2);
|
|
6546
|
+
}
|
|
6547
|
+
if (isObject$f(options)) {
|
|
6548
|
+
leading = "leading" in options ? !!options.leading : leading;
|
|
6549
|
+
trailing = "trailing" in options ? !!options.trailing : trailing;
|
|
6550
|
+
}
|
|
6551
|
+
return debounce$5(func, wait2, {
|
|
6552
|
+
"leading": leading,
|
|
6553
|
+
"maxWait": wait2,
|
|
6554
|
+
"trailing": trailing
|
|
6555
|
+
});
|
|
6556
|
+
}
|
|
6541
6557
|
var INFINITY = 1 / 0;
|
|
6542
6558
|
var createSet = !(Set$3 && 1 / setToArray$2(new Set$3([, -0]))[1] == INFINITY) ? noop$h : function(values3) {
|
|
6543
6559
|
return new Set$3(values3);
|
|
@@ -10382,6 +10398,7 @@ const CoordinationType$1 = {
|
|
|
10382
10398
|
SPATIAL_CHANNEL_LABELS_VISIBLE: "spatialChannelLabelsVisible",
|
|
10383
10399
|
SPATIAL_CHANNEL_LABELS_ORIENTATION: "spatialChannelLabelsOrientation",
|
|
10384
10400
|
SPATIAL_CHANNEL_LABEL_SIZE: "spatialChannelLabelSize",
|
|
10401
|
+
SPATIAL_CHANNELS_SORT_ORDER: "spatialChannelsSortOrder",
|
|
10385
10402
|
// Multi-sample / comparative
|
|
10386
10403
|
SAMPLE_TYPE: "sampleType",
|
|
10387
10404
|
SAMPLE_SELECTION: "sampleSelection",
|
|
@@ -10434,7 +10451,9 @@ const ViewHelpMapping = {
|
|
|
10434
10451
|
OBS_SET_COMPOSITION_BAR_PLOT: "The set composition bar plot displays the results of a compositional analysis conducted using the scCODA method (Büttner et al. 2021 Nature Communications).",
|
|
10435
10452
|
FEATURE_SET_ENRICHMENT_BAR_PLOT: "The feature set enrichment bar plot displays the results of a hypergeometric test applied to the differential expression test results to identify enriched pathway gene sets.",
|
|
10436
10453
|
SAMPLE_SET_PAIR_MANAGER: "Select pairs of sample groups.",
|
|
10437
|
-
FEATURE_STATS_TABLE: "This table displays per-feature statistics, for example, from a differential expression test."
|
|
10454
|
+
FEATURE_STATS_TABLE: "This table displays per-feature statistics, for example, from a differential expression test.",
|
|
10455
|
+
LAYER_CONTROLLER_BETA: "The spatial layer controller provides an interface for manipulating the visualization layers displayed in the spatial view.",
|
|
10456
|
+
SPATIAL_BETA: "The spatial view displays (potentially layered) spatially-resolved data including RGB or multiplexed images, segmentations of observations (bitmask- or polygon-based), and/or points (e.g., representing FISH transcripts)."
|
|
10438
10457
|
};
|
|
10439
10458
|
({
|
|
10440
10459
|
// For new file types
|
|
@@ -10985,6 +11004,7 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
10985
11004
|
CoordinationType$1.SPATIAL_CHANNEL_LABELS_VISIBLE,
|
|
10986
11005
|
CoordinationType$1.SPATIAL_CHANNEL_LABELS_ORIENTATION,
|
|
10987
11006
|
CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE,
|
|
11007
|
+
CoordinationType$1.SPATIAL_CHANNELS_SORT_ORDER,
|
|
10988
11008
|
CoordinationType$1.PHOTOMETRIC_INTERPRETATION
|
|
10989
11009
|
],
|
|
10990
11010
|
[ViewType$1.HEATMAP]: [
|
|
@@ -11166,7 +11186,8 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
11166
11186
|
CoordinationType$1.LEGEND_VISIBLE,
|
|
11167
11187
|
CoordinationType$1.SPATIAL_CHANNEL_LABELS_VISIBLE,
|
|
11168
11188
|
CoordinationType$1.SPATIAL_CHANNEL_LABELS_ORIENTATION,
|
|
11169
|
-
CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE
|
|
11189
|
+
CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE,
|
|
11190
|
+
CoordinationType$1.SPATIAL_CHANNELS_SORT_ORDER
|
|
11170
11191
|
],
|
|
11171
11192
|
[ViewType$1.GENOMIC_PROFILES]: [
|
|
11172
11193
|
CoordinationType$1.DATASET,
|
|
@@ -11877,7 +11898,18 @@ const ngPrecomputedMeshSchema = z.object({
|
|
|
11877
11898
|
const ngPointAnnotationSchema = z.object({
|
|
11878
11899
|
projectionAnnotationSpacing: z.number(),
|
|
11879
11900
|
featureIndexProp: z.string().optional().describe("The name of the Neuroglancer AnnotationProperty containing feature IDs. For example, specify 'gene' to use prop_gene() in the Neuroglancer shader code."),
|
|
11880
|
-
pointIndexProp: z.string().optional().describe("The name of the Neuroglancer AnnotationProperty containing point IDs. For example, specify 'point_id' to use prop_point_id() in the Neuroglancer shader code.")
|
|
11901
|
+
pointIndexProp: z.string().optional().describe("The name of the Neuroglancer AnnotationProperty containing point IDs. For example, specify 'point_id' to use prop_point_id() in the Neuroglancer shader code."),
|
|
11902
|
+
transform: z.object({
|
|
11903
|
+
matrix: z.array(z.array(z.number())),
|
|
11904
|
+
outputDimensions: z.record(z.tuple([z.number(), z.string()]))
|
|
11905
|
+
}).optional().describe("A coordinate transformation matrix to apply to the annotation layer source to map annotation coordinates to the global coordinate space."),
|
|
11906
|
+
// Note: See comments in neuroglancer-sorger.js
|
|
11907
|
+
// We may remove these in the future, pending clarification
|
|
11908
|
+
// to questions in the tissue-map-tools repo
|
|
11909
|
+
// - https://github.com/hms-dbmi/tissue-map-tools/issues/20
|
|
11910
|
+
// - https://github.com/hms-dbmi/tissue-map-tools/issues/38
|
|
11911
|
+
quantitativeColorProp: z.string().optional(),
|
|
11912
|
+
quantitativeColorMax: z.number().optional()
|
|
11881
11913
|
}).partial().nullable();
|
|
11882
11914
|
const obsEmbeddingAnndataSchema = annDataObsEmbedding;
|
|
11883
11915
|
const obsSpotsAnndataSchema = annDataObsLocations;
|
|
@@ -19290,7 +19322,7 @@ const { tss } = createTss({
|
|
|
19290
19322
|
},
|
|
19291
19323
|
"usePlugin": useMuiThemeStyleOverridesPlugin
|
|
19292
19324
|
});
|
|
19293
|
-
const useStyles$
|
|
19325
|
+
const useStyles$z = tss.create({});
|
|
19294
19326
|
function createChainedFunction$1(...funcs) {
|
|
19295
19327
|
return funcs.reduce((acc, func) => {
|
|
19296
19328
|
if (func == null) {
|
|
@@ -74100,7 +74132,7 @@ const Popper = React.forwardRef((props, ref2) => {
|
|
|
74100
74132
|
}, [handlePopperRef]);
|
|
74101
74133
|
React.useImperativeHandle(popperRefProp, () => popperRef.current, []);
|
|
74102
74134
|
const [exited, setExited] = React.useState(true);
|
|
74103
|
-
const { theme } = useStyles$
|
|
74135
|
+
const { theme } = useStyles$z();
|
|
74104
74136
|
const rtlPlacement = flipPlacement(initialPlacement, theme);
|
|
74105
74137
|
const [placement, setPlacement] = React.useState(rtlPlacement);
|
|
74106
74138
|
React.useEffect(() => {
|
|
@@ -74834,7 +74866,7 @@ var VariableSizeList$1 = /* @__PURE__ */ createListComponent({
|
|
|
74834
74866
|
});
|
|
74835
74867
|
const VariableSizeList = VariableSizeList$1;
|
|
74836
74868
|
const LIST_ROW_HEIGHT$1 = 48;
|
|
74837
|
-
const useStyles$
|
|
74869
|
+
const useStyles$y = makeStyles()(() => ({
|
|
74838
74870
|
searchInput: {
|
|
74839
74871
|
lineHeight: "initial",
|
|
74840
74872
|
height: "auto !important"
|
|
@@ -74874,7 +74906,7 @@ const ListboxComponent$1 = React__default.forwardRef((props, ref2) => {
|
|
|
74874
74906
|
});
|
|
74875
74907
|
function SimpleAutocomplete(props) {
|
|
74876
74908
|
const { getMatches, onChange, textInputLabel = "Enter a gene", getItemLabel = (option) => option.label } = props;
|
|
74877
|
-
const { classes: classes2 } = useStyles$
|
|
74909
|
+
const { classes: classes2 } = useStyles$y();
|
|
74878
74910
|
const [potentialItems, setPotentialItems] = useState([]);
|
|
74879
74911
|
const handleInputChange = async (_event, value2) => {
|
|
74880
74912
|
if (!value2) {
|
|
@@ -84424,7 +84456,7 @@ function defaultUrlTransform(value2) {
|
|
|
84424
84456
|
}
|
|
84425
84457
|
return "";
|
|
84426
84458
|
}
|
|
84427
|
-
const useStyles$
|
|
84459
|
+
const useStyles$x = makeStyles()((theme) => ({
|
|
84428
84460
|
description: {
|
|
84429
84461
|
"& p, details, table": {
|
|
84430
84462
|
fontSize: "80%",
|
|
@@ -84461,7 +84493,7 @@ const useStyles$w = makeStyles()((theme) => ({
|
|
|
84461
84493
|
}));
|
|
84462
84494
|
function Description(props) {
|
|
84463
84495
|
const { description: description2, metadata: metadata2, descriptionType } = props;
|
|
84464
|
-
const { classes: classes2 } = useStyles$
|
|
84496
|
+
const { classes: classes2 } = useStyles$x();
|
|
84465
84497
|
return jsxs("div", { className: classes2.description, children: [descriptionType && descriptionType === DescriptionType.MARKDOWN ? jsx$1(Markdown, { children: description2 }) : jsx$1("p", { children: description2 }), metadata2 && Array.from(metadata2.entries()).map(([layerIndex, { name: layerName, metadata: metadataRecord }]) => metadataRecord && Object.entries(metadataRecord).length > 0 ? jsxs("details", { children: [jsx$1("summary", { children: layerName }), jsx$1("div", { className: classes2.metadataContainer, children: jsx$1("table", { children: jsx$1("tbody", { children: Object.entries(metadataRecord).map(([key2, value2]) => jsxs("tr", { children: [jsx$1("th", { title: key2, children: key2 }), jsx$1("td", { title: value2, children: value2 })] }, key2)) }) }) })] }, layerIndex) : null)] });
|
|
84466
84498
|
}
|
|
84467
84499
|
function DescriptionSubscriber(props) {
|
|
@@ -92713,6 +92745,37 @@ function dataToCellSetsTree(data2, options) {
|
|
|
92713
92745
|
return cellSetsTree;
|
|
92714
92746
|
}
|
|
92715
92747
|
const schemeRdBu = [[103, 0, 31], [178, 24, 43], [214, 96, 77], [244, 165, 130], [253, 219, 199], [247, 247, 247], [209, 229, 240], [146, 197, 222], [67, 147, 195], [33, 102, 172], [5, 48, 97]];
|
|
92748
|
+
const schemePlasma = [[13, 8, 135], [16, 7, 136], [19, 7, 137], [22, 7, 138], [25, 6, 140], [27, 6, 141], [29, 6, 142], [32, 6, 143], [34, 6, 144], [36, 6, 145], [38, 5, 145], [40, 5, 146], [42, 5, 147], [44, 5, 148], [46, 5, 149], [47, 5, 150], [49, 5, 151], [51, 5, 151], [53, 4, 152], [55, 4, 153], [56, 4, 154], [58, 4, 154], [60, 4, 155], [62, 4, 156], [63, 4, 156], [65, 4, 157], [67, 3, 158], [68, 3, 158], [70, 3, 159], [72, 3, 159], [73, 3, 160], [75, 3, 161], [76, 2, 161], [78, 2, 162], [80, 2, 162], [81, 2, 163], [83, 2, 163], [85, 2, 164], [86, 1, 164], [88, 1, 164], [89, 1, 165], [91, 1, 165], [92, 1, 166], [94, 1, 166], [96, 1, 166], [97, 0, 167], [99, 0, 167], [100, 0, 167], [102, 0, 167], [103, 0, 168], [105, 0, 168], [106, 0, 168], [108, 0, 168], [110, 0, 168], [111, 0, 168], [113, 0, 168], [114, 1, 168], [116, 1, 168], [117, 1, 168], [119, 1, 168], [120, 1, 168], [122, 2, 168], [123, 2, 168], [125, 3, 168], [126, 3, 168], [128, 4, 168], [129, 4, 167], [131, 5, 167], [132, 5, 167], [134, 6, 166], [135, 7, 166], [136, 8, 166], [138, 9, 165], [139, 10, 165], [141, 11, 165], [142, 12, 164], [143, 13, 164], [145, 14, 163], [146, 15, 163], [148, 16, 162], [149, 17, 161], [150, 19, 161], [152, 20, 160], [153, 21, 159], [154, 22, 159], [156, 23, 158], [157, 24, 157], [158, 25, 157], [160, 26, 156], [161, 27, 155], [162, 29, 154], [163, 30, 154], [165, 31, 153], [166, 32, 152], [167, 33, 151], [168, 34, 150], [170, 35, 149], [171, 36, 148], [172, 38, 148], [173, 39, 147], [174, 40, 146], [176, 41, 145], [177, 42, 144], [178, 43, 143], [179, 44, 142], [180, 46, 141], [181, 47, 140], [182, 48, 139], [183, 49, 138], [184, 50, 137], [186, 51, 136], [187, 52, 136], [188, 53, 135], [189, 55, 134], [190, 56, 133], [191, 57, 132], [192, 58, 131], [193, 59, 130], [194, 60, 129], [195, 61, 128], [196, 62, 127], [197, 64, 126], [198, 65, 125], [199, 66, 124], [200, 67, 123], [201, 68, 122], [202, 69, 122], [203, 70, 121], [204, 71, 120], [204, 73, 119], [205, 74, 118], [206, 75, 117], [207, 76, 116], [208, 77, 115], [209, 78, 114], [210, 79, 113], [211, 81, 113], [212, 82, 112], [213, 83, 111], [213, 84, 110], [214, 85, 109], [215, 86, 108], [216, 87, 107], [217, 88, 106], [218, 90, 106], [218, 91, 105], [219, 92, 104], [220, 93, 103], [221, 94, 102], [222, 95, 101], [222, 97, 100], [223, 98, 99], [224, 99, 99], [225, 100, 98], [226, 101, 97], [226, 102, 96], [227, 104, 95], [228, 105, 94], [229, 106, 93], [229, 107, 93], [230, 108, 92], [231, 110, 91], [231, 111, 90], [232, 112, 89], [233, 113, 88], [233, 114, 87], [234, 116, 87], [235, 117, 86], [235, 118, 85], [236, 119, 84], [237, 121, 83], [237, 122, 82], [238, 123, 81], [239, 124, 81], [239, 126, 80], [240, 127, 79], [240, 128, 78], [241, 129, 77], [241, 131, 76], [242, 132, 75], [243, 133, 75], [243, 135, 74], [244, 136, 73], [244, 137, 72], [245, 139, 71], [245, 140, 70], [246, 141, 69], [246, 143, 68], [247, 144, 68], [247, 145, 67], [247, 147, 66], [248, 148, 65], [248, 149, 64], [249, 151, 63], [249, 152, 62], [249, 154, 62], [250, 155, 61], [250, 156, 60], [250, 158, 59], [251, 159, 58], [251, 161, 57], [251, 162, 56], [252, 163, 56], [252, 165, 55], [252, 166, 54], [252, 168, 53], [252, 169, 52], [253, 171, 51], [253, 172, 51], [253, 174, 50], [253, 175, 49], [253, 177, 48], [253, 178, 47], [253, 180, 47], [253, 181, 46], [254, 183, 45], [254, 184, 44], [254, 186, 44], [254, 187, 43], [254, 189, 42], [254, 190, 42], [254, 192, 41], [253, 194, 41], [253, 195, 40], [253, 197, 39], [253, 198, 39], [253, 200, 39], [253, 202, 38], [253, 203, 38], [252, 205, 37], [252, 206, 37], [252, 208, 37], [252, 210, 37], [251, 211, 36], [251, 213, 36], [251, 215, 36], [250, 216, 36], [250, 218, 36], [249, 220, 36], [249, 221, 37], [248, 223, 37], [248, 225, 37], [247, 226, 37], [247, 228, 37], [246, 230, 38], [246, 232, 38], [245, 233, 38], [245, 235, 39], [244, 237, 39], [243, 238, 39], [243, 240, 39], [242, 242, 39], [241, 244, 38], [241, 245, 37], [240, 247, 36], [240, 249, 33]];
|
|
92749
|
+
const schemeViridis = [[68, 1, 84], [68, 2, 86], [69, 4, 87], [69, 5, 89], [70, 7, 90], [70, 8, 92], [70, 10, 93], [70, 11, 94], [71, 13, 96], [71, 14, 97], [71, 16, 99], [71, 17, 100], [71, 19, 101], [72, 20, 103], [72, 22, 104], [72, 23, 105], [72, 24, 106], [72, 26, 108], [72, 27, 109], [72, 28, 110], [72, 30, 111], [72, 31, 112], [72, 32, 113], [72, 34, 115], [72, 35, 116], [72, 36, 117], [72, 38, 118], [72, 39, 119], [72, 40, 120], [72, 42, 121], [72, 43, 122], [72, 44, 123], [72, 46, 124], [72, 47, 125], [72, 48, 126], [72, 50, 127], [72, 51, 128], [72, 52, 129], [72, 53, 130], [72, 55, 131], [72, 56, 132], [72, 57, 133], [72, 59, 134], [72, 60, 135], [72, 61, 136], [72, 63, 137], [72, 64, 137], [72, 65, 138], [72, 67, 139], [72, 68, 140], [72, 69, 141], [72, 71, 142], [72, 72, 143], [72, 73, 144], [72, 75, 145], [72, 76, 146], [72, 77, 147], [72, 79, 148], [72, 80, 149], [72, 82, 150], [72, 83, 150], [72, 84, 151], [72, 86, 152], [72, 87, 153], [72, 88, 154], [72, 90, 155], [71, 91, 156], [71, 92, 157], [71, 94, 158], [71, 95, 158], [71, 97, 159], [71, 98, 160], [71, 99, 161], [71, 101, 162], [71, 102, 163], [71, 103, 164], [71, 105, 164], [71, 106, 165], [71, 108, 166], [71, 109, 167], [71, 110, 168], [71, 112, 169], [71, 113, 169], [71, 114, 170], [71, 116, 171], [71, 117, 172], [70, 119, 173], [70, 120, 174], [70, 121, 174], [70, 123, 175], [70, 124, 176], [70, 125, 177], [70, 127, 178], [70, 128, 178], [70, 130, 179], [70, 131, 180], [70, 132, 181], [70, 134, 182], [70, 135, 182], [70, 136, 183], [70, 138, 184], [70, 139, 185], [70, 141, 186], [70, 142, 186], [70, 143, 187], [70, 145, 188], [70, 146, 189], [70, 148, 189], [70, 149, 190], [70, 150, 191], [70, 152, 192], [70, 153, 192], [70, 155, 193], [70, 156, 194], [70, 157, 195], [70, 159, 195], [70, 160, 196], [70, 162, 197], [70, 163, 198], [70, 164, 198], [70, 166, 199], [70, 167, 200], [71, 169, 200], [71, 170, 201], [71, 171, 202], [71, 173, 203], [71, 174, 203], [71, 176, 204], [71, 177, 205], [71, 178, 205], [72, 180, 206], [72, 181, 207], [72, 183, 207], [72, 184, 208], [73, 185, 209], [73, 187, 209], [73, 188, 210], [74, 190, 211], [74, 191, 211], [74, 192, 212], [75, 194, 213], [75, 195, 213], [76, 197, 214], [76, 198, 214], [77, 199, 215], [77, 201, 216], [78, 202, 216], [78, 204, 217], [79, 205, 217], [79, 207, 218], [80, 208, 218], [81, 209, 219], [81, 211, 220], [82, 212, 220], [83, 214, 221], [83, 215, 221], [84, 216, 222], [85, 218, 222], [85, 219, 223], [86, 221, 223], [87, 222, 224], [88, 224, 224], [88, 225, 225], [89, 226, 225], [90, 228, 226], [91, 229, 226], [92, 231, 227], [92, 232, 227], [93, 234, 228], [94, 235, 228], [95, 236, 229], [96, 238, 229], [97, 239, 230], [97, 241, 230], [98, 242, 231], [99, 244, 231], [100, 245, 232], [101, 246, 232], [102, 248, 233], [103, 249, 233], [104, 251, 234], [105, 252, 234]];
|
|
92750
|
+
const schemeJet = Array.from({ length: 256 }, (_, i2) => {
|
|
92751
|
+
const t4 = i2 / 255;
|
|
92752
|
+
let r3;
|
|
92753
|
+
let g2;
|
|
92754
|
+
let b2;
|
|
92755
|
+
if (t4 < 0.125) {
|
|
92756
|
+
r3 = 0;
|
|
92757
|
+
g2 = 0;
|
|
92758
|
+
b2 = 0.5 + t4 * 4;
|
|
92759
|
+
} else if (t4 < 0.375) {
|
|
92760
|
+
r3 = 0;
|
|
92761
|
+
g2 = (t4 - 0.125) * 4;
|
|
92762
|
+
b2 = 1;
|
|
92763
|
+
} else if (t4 < 0.625) {
|
|
92764
|
+
r3 = (t4 - 0.375) * 4;
|
|
92765
|
+
g2 = 1;
|
|
92766
|
+
b2 = 1 - (t4 - 0.375) * 4;
|
|
92767
|
+
} else if (t4 < 0.875) {
|
|
92768
|
+
r3 = 1;
|
|
92769
|
+
g2 = 1 - (t4 - 0.625) * 4;
|
|
92770
|
+
b2 = 0;
|
|
92771
|
+
} else {
|
|
92772
|
+
r3 = 1 - (t4 - 0.875) * 4;
|
|
92773
|
+
g2 = 0;
|
|
92774
|
+
b2 = 0;
|
|
92775
|
+
}
|
|
92776
|
+
return [Math.round(r3 * 255), Math.round(g2 * 255), Math.round(b2 * 255)];
|
|
92777
|
+
});
|
|
92778
|
+
const schemeGreys = Array.from({ length: 256 }, (_, i2) => [i2, i2, i2]);
|
|
92716
92779
|
function rgbSpline$1(spline) {
|
|
92717
92780
|
return (colors2) => {
|
|
92718
92781
|
const n3 = colors2.length;
|
|
@@ -92750,7 +92813,15 @@ function basis$2(values3) {
|
|
|
92750
92813
|
};
|
|
92751
92814
|
}
|
|
92752
92815
|
const interpolateRgbBasis = rgbSpline$1(basis$2);
|
|
92816
|
+
function interpolateSequentialMulti(range2) {
|
|
92817
|
+
const n3 = range2.length;
|
|
92818
|
+
return (t4) => range2[Math.max(0, Math.min(n3 - 1, Math.floor(t4 * n3)))];
|
|
92819
|
+
}
|
|
92753
92820
|
interpolateRgbBasis(schemeRdBu);
|
|
92821
|
+
const interpolatePlasma = interpolateSequentialMulti(schemePlasma);
|
|
92822
|
+
const interpolateViridis = interpolateSequentialMulti(schemeViridis);
|
|
92823
|
+
const interpolateJet = interpolateSequentialMulti(schemeJet);
|
|
92824
|
+
const interpolateGreys = interpolateSequentialMulti(schemeGreys);
|
|
92754
92825
|
function getCellColors(params2) {
|
|
92755
92826
|
const { cellSets, cellSetSelection, cellSetColor, obsIndex, theme } = params2;
|
|
92756
92827
|
if (cellSetSelection && cellSets) {
|
|
@@ -99532,7 +99603,7 @@ const Tooltip$2 = /* @__PURE__ */ React.forwardRef((props, ref2) => {
|
|
|
99532
99603
|
}, extraProps), getChildren());
|
|
99533
99604
|
});
|
|
99534
99605
|
const nodeHeight = 32;
|
|
99535
|
-
const useStyles$
|
|
99606
|
+
const useStyles$w = makeStyles()((theme) => ({
|
|
99536
99607
|
setsManager: {
|
|
99537
99608
|
position: "relative",
|
|
99538
99609
|
width: "100%",
|
|
@@ -99699,7 +99770,7 @@ const useStyles$v = makeStyles()((theme) => ({
|
|
|
99699
99770
|
}));
|
|
99700
99771
|
function SetsManagerTreeGlobalStyles(props) {
|
|
99701
99772
|
const { classes: classes2 } = props;
|
|
99702
|
-
const { theme } = useStyles$
|
|
99773
|
+
const { theme } = useStyles$z();
|
|
99703
99774
|
return jsx$1(ScopedGlobalStyles, { parentClassName: classes2.setsManagerTree, styles: {
|
|
99704
99775
|
".rc-tree": {
|
|
99705
99776
|
paddingLeft: "0",
|
|
@@ -100040,7 +100111,7 @@ function HelpTooltipGlobalStyles(props) {
|
|
|
100040
100111
|
}
|
|
100041
100112
|
function PopoverGlobalStyles(props) {
|
|
100042
100113
|
const { classes: classes2 } = props;
|
|
100043
|
-
const { theme } = useStyles$
|
|
100114
|
+
const { theme } = useStyles$z();
|
|
100044
100115
|
return jsx$1(ScopedGlobalStyles, { parentClassName: classes2.popover, styles: {
|
|
100045
100116
|
".rc-tooltip-inner": {
|
|
100046
100117
|
boxSizing: "border-box",
|
|
@@ -104724,7 +104795,7 @@ function NamedSetNodeStatic(props) {
|
|
|
104724
104795
|
const onClick = level === 0 && !expanded ? () => onCheckLevel(nodeKey, nextLevelToCheck) : () => onNodeView(path2);
|
|
104725
104796
|
const tooltipProps = disableTooltip ? { visible: false } : {};
|
|
104726
104797
|
const popoverMenuConfig = makeNodeViewMenuConfig(props);
|
|
104727
|
-
const { classes: classes2 } = useStyles$
|
|
104798
|
+
const { classes: classes2 } = useStyles$w();
|
|
104728
104799
|
return jsxs("span", { children: [jsx$1(HelpTooltip, { title: tooltipText, ...tooltipProps, children: jsx$1("button", { type: "button", onClick, onKeyPress: (e3) => callbackOnKeyPress(e3, "v", () => onNodeView(path2)), className: classes2.titleButton, children: title2 }) }), popoverMenuConfig.length > 0 ? jsx$1(PopoverMenu, { menuConfig: makeNodeViewMenuConfig(props), color: level > 0 && editable ? color2 || getDefaultColor(theme) : null, setColor: (c2) => onNodeSetColor(path2, c2), children: jsx$1("span", { children: jsx$1(SvgMenu, { className: classes2.nodeMenuIcon, "aria-label": "Open Node View Menu" }) }) }) : null, level > 0 && isChecking ? checkbox2 : null, level > 0 && jsx$1("span", { className: classes2.nodeSizeLabel, children: niceSize })] });
|
|
104729
104800
|
}
|
|
104730
104801
|
function NamedSetNodeEditing(props) {
|
|
@@ -104736,7 +104807,7 @@ function NamedSetNodeEditing(props) {
|
|
|
104736
104807
|
onNodeSetName(path2, currentTitle, true);
|
|
104737
104808
|
}
|
|
104738
104809
|
}
|
|
104739
|
-
const { classes: classes2 } = useStyles$
|
|
104810
|
+
const { classes: classes2 } = useStyles$w();
|
|
104740
104811
|
return jsxs("span", { className: classes2.titleButtonWithInput, children: [jsx$1("input", {
|
|
104741
104812
|
// eslint-disable-next-line jsx-a11y/no-autofocus
|
|
104742
104813
|
autoFocus: true,
|
|
@@ -104762,7 +104833,7 @@ function LevelsButtons(props) {
|
|
|
104762
104833
|
onCheckLevel(nodeKey, newLevel);
|
|
104763
104834
|
}
|
|
104764
104835
|
}
|
|
104765
|
-
const { classes: classes2 } = useStyles$
|
|
104836
|
+
const { classes: classes2 } = useStyles$w();
|
|
104766
104837
|
return jsx$1("div", { className: classes2.levelButtonsContainer, children: range$e(1, height2 + 1).map((i2) => {
|
|
104767
104838
|
const isChecked = isEqual$3(path2, checkedLevelPath) && i2 === checkedLevelIndex;
|
|
104768
104839
|
return jsx$1("div", { children: jsx$1(HelpTooltip, { title: getLevelTooltipText(i2), children: jsx$1("input", { className: clsx(classes2.levelRadioButton, { [classes2.levelRadioButtonChecked]: isChecked && !hasColorEncoding }), type: "checkbox", value: i2, checked: isChecked && hasColorEncoding, onChange: onCheck }) }) }, i2);
|
|
@@ -104846,7 +104917,7 @@ let TreeNode$1 = class TreeNode extends TreeNode$2 {
|
|
|
104846
104917
|
};
|
|
104847
104918
|
function PlusButton(props) {
|
|
104848
104919
|
const { datatype, onError, onImportTree, onCreateLevelZeroNode, importable, editable } = props;
|
|
104849
|
-
const { classes: classes2 } = useStyles$
|
|
104920
|
+
const { classes: classes2 } = useStyles$w();
|
|
104850
104921
|
const onImport = useCallback((importHandler, mimeType) => () => {
|
|
104851
104922
|
const uploadInputNode = document.createElement("input");
|
|
104852
104923
|
uploadInputNode.setAttribute("type", "file");
|
|
@@ -104963,7 +105034,7 @@ function SetsManager(props) {
|
|
|
104963
105034
|
}, onNodeCheckNewName, onNodeSetIsEditing: setIsEditingNodeName, onNodeRemove, onExportLevelZeroNodeJSON, onExportLevelZeroNodeTabular, onExportSetJSON, disableTooltip: isDragging, onDragStart: () => setIsDragging(true), onDragEnd: () => setIsDragging(false), children: renderTreeNodes(node2.children, readOnly, newPath) }, pathToKey(newPath));
|
|
104964
105035
|
});
|
|
104965
105036
|
}
|
|
104966
|
-
const { classes: classes2 } = useStyles$
|
|
105037
|
+
const { classes: classes2 } = useStyles$w();
|
|
104967
105038
|
return jsxs("div", { className: classes2.setsManager, children: [jsx$1(SetsManagerTreeGlobalStyles, { classes: classes2 }), jsxs("div", { className: classes2.setsManagerTree, children: [jsx$1(Tree$1, { draggable: false, checkable, checkedKeys: setSelectionKeys, expandedKeys: setExpansionKeys, autoExpandParent, onCheck: (checkedKeys, info2) => onCheckNode(info2.node.props.nodeKey, info2.checked), onExpand: (expandedKeys, info2) => onExpandNode(expandedKeys, info2.node.props.nodeKey, info2.expanded), children: renderTreeNodes(processedSets.tree, true, []) }), jsx$1(Tree$1, { draggable: true, checkable, checkedKeys: additionalSetSelectionKeys, expandedKeys: additionalSetExpansionKeys, autoExpandParent, onCheck: (checkedKeys, info2) => onCheckNode(info2.node.props.nodeKey, info2.checked), onExpand: (expandedKeys, info2) => onExpandNode(expandedKeys, info2.node.props.nodeKey, info2.expanded), onDrop: (info2) => {
|
|
104968
105039
|
const { eventKey: dropKey } = info2.node.props;
|
|
104969
105040
|
const { eventKey: dragKey } = info2.dragNode.props;
|
|
@@ -210928,22 +210999,22 @@ async function getDecoder(fileDirectory) {
|
|
|
210928
210999
|
const Decoder = await importFn();
|
|
210929
211000
|
return new Decoder(fileDirectory);
|
|
210930
211001
|
}
|
|
210931
|
-
addDecoder([void 0, 1], () => import("./raw-
|
|
210932
|
-
addDecoder(5, () => import("./lzw-
|
|
211002
|
+
addDecoder([void 0, 1], () => import("./raw-DMNeLVd7.js").then((m2) => m2.default));
|
|
211003
|
+
addDecoder(5, () => import("./lzw-BmHVONBc.js").then((m2) => m2.default));
|
|
210933
211004
|
addDecoder(6, () => {
|
|
210934
211005
|
throw new Error("old style JPEG compression is not supported.");
|
|
210935
211006
|
});
|
|
210936
|
-
addDecoder(7, () => import("./jpeg-
|
|
210937
|
-
addDecoder([8, 32946], () => import("./deflate-
|
|
210938
|
-
addDecoder(32773, () => import("./packbits-
|
|
211007
|
+
addDecoder(7, () => import("./jpeg-BGB-_EKG.js").then((m2) => m2.default));
|
|
211008
|
+
addDecoder([8, 32946], () => import("./deflate-38TS7div.js").then((m2) => m2.default));
|
|
211009
|
+
addDecoder(32773, () => import("./packbits-DKF2IGBX.js").then((m2) => m2.default));
|
|
210939
211010
|
addDecoder(
|
|
210940
211011
|
34887,
|
|
210941
|
-
() => import("./lerc-
|
|
211012
|
+
() => import("./lerc-Db0ZEZ3c.js").then(async (m2) => {
|
|
210942
211013
|
await m2.zstd.init();
|
|
210943
211014
|
return m2;
|
|
210944
211015
|
}).then((m2) => m2.default)
|
|
210945
211016
|
);
|
|
210946
|
-
addDecoder(50001, () => import("./webimage-
|
|
211017
|
+
addDecoder(50001, () => import("./webimage-BTp31_-j.js").then((m2) => m2.default));
|
|
210947
211018
|
function copyNewSize(array2, width2, height2, samplesPerPixel = 1) {
|
|
210948
211019
|
return new (Object.getPrototypeOf(array2)).constructor(width2 * height2 * samplesPerPixel);
|
|
210949
211020
|
}
|
|
@@ -227717,7 +227788,7 @@ class ContourLayerWithText extends ContourLayer {
|
|
|
227717
227788
|
}
|
|
227718
227789
|
ContourLayerWithText.layerName = "ContourLayerWithText";
|
|
227719
227790
|
ContourLayerWithText.defaultProps = defaultProps;
|
|
227720
|
-
const useStyles$
|
|
227791
|
+
const useStyles$v = makeStyles()(() => ({
|
|
227721
227792
|
toolButton: {
|
|
227722
227793
|
display: "inline-flex",
|
|
227723
227794
|
"&:active": {
|
|
@@ -227779,12 +227850,12 @@ const useStyles$u = makeStyles()(() => ({
|
|
|
227779
227850
|
}));
|
|
227780
227851
|
function IconTool(props) {
|
|
227781
227852
|
const { alt, onClick, isActive: isActive2, children: children3 } = props;
|
|
227782
|
-
const { classes: classes2 } = useStyles$
|
|
227853
|
+
const { classes: classes2 } = useStyles$v();
|
|
227783
227854
|
return jsx$1("button", { className: clsx(classes2.toolIcon, { [classes2.toolActive]: isActive2 }), onClick, type: "button", title: alt, children: children3 });
|
|
227784
227855
|
}
|
|
227785
227856
|
function IconButton(props) {
|
|
227786
227857
|
const { alt, onClick, children: children3 } = props;
|
|
227787
|
-
const { classes: classes2 } = useStyles$
|
|
227858
|
+
const { classes: classes2 } = useStyles$v();
|
|
227788
227859
|
return jsx$1("button", { className: clsx(classes2.toolIcon, classes2.toolButton), onClick, type: "button", title: alt, children: children3 });
|
|
227789
227860
|
}
|
|
227790
227861
|
function ToolMenu(props) {
|
|
@@ -227792,14 +227863,14 @@ function ToolMenu(props) {
|
|
|
227792
227863
|
const lassoIconAltText = "Select lasso";
|
|
227793
227864
|
const { setActiveTool, activeTool, visibleTools = { pan: true, selectLasso: true, recenter: true }, recenterOnClick = () => {
|
|
227794
227865
|
} } = props;
|
|
227795
|
-
const { classes: classes2 } = useStyles$
|
|
227866
|
+
const { classes: classes2 } = useStyles$v();
|
|
227796
227867
|
const onRecenterButtonCLick = () => {
|
|
227797
227868
|
recenterOnClick();
|
|
227798
227869
|
};
|
|
227799
227870
|
return jsxs("div", { className: classes2.tool, children: [visibleTools.pan && jsx$1(IconTool, { alt: pointerIconAltText, onClick: () => setActiveTool(null), isActive: activeTool === null, children: jsx$1(SvgNearMe, {}) }), visibleTools.selectLasso ? jsx$1(IconTool, { alt: lassoIconAltText, onClick: () => setActiveTool(distEs6Exports$2.SELECTION_TYPE.POLYGON), isActive: activeTool === distEs6Exports$2.SELECTION_TYPE.POLYGON, children: jsx$1(SvgSelectionLasso, {}) }) : null, visibleTools.recenter ? jsx$1(IconButton, { alt: "click to recenter", onClick: () => onRecenterButtonCLick(), "aria-label": "Recenter scatterplot view", children: jsx$1(CenterFocusStrong, {}) }) : null] });
|
|
227800
227871
|
}
|
|
227801
227872
|
const getCursorWithTool = () => "crosshair";
|
|
227802
|
-
const getCursor = (interactionState) => interactionState.isDragging ? "grabbing" : "
|
|
227873
|
+
const getCursor = (interactionState) => interactionState.isDragging ? "grabbing" : "grab";
|
|
227803
227874
|
function getOnHoverCallback(obsIndex, setObsHighlight, setComponentHover) {
|
|
227804
227875
|
return (info2) => {
|
|
227805
227876
|
if (setComponentHover) {
|
|
@@ -228949,7 +229020,7 @@ function ScatterplotOptions(props) {
|
|
|
228949
229020
|
id: `feature-aggregation-strategy-${scatterplotOptionsId}`
|
|
228950
229021
|
}, children: FEATURE_AGGREGATION_STRATEGIES$2.map((opt) => jsx$1("option", { value: opt, children: capitalize$3(opt) }, opt)) }) })] }) : null] });
|
|
228951
229022
|
}
|
|
228952
|
-
const useStyles$
|
|
229023
|
+
const useStyles$u = makeStyles()((theme) => ({
|
|
228953
229024
|
tooltipAnchor: {
|
|
228954
229025
|
position: "relative",
|
|
228955
229026
|
width: "0px",
|
|
@@ -228980,7 +229051,7 @@ const useStyles$t = makeStyles()((theme) => ({
|
|
|
228980
229051
|
function Tooltip3(props) {
|
|
228981
229052
|
const { x: x2, y: y2, parentWidth, parentHeight, children: children3 } = props;
|
|
228982
229053
|
const ref2 = useRef();
|
|
228983
|
-
const { classes: classes2 } = useStyles$
|
|
229054
|
+
const { classes: classes2 } = useStyles$u();
|
|
228984
229055
|
const [placementX, setPlacementX] = useState("start");
|
|
228985
229056
|
const [placementY, setPlacementY] = useState("bottom");
|
|
228986
229057
|
const getTooltipContainer = useVitessceContainer(ref2);
|
|
@@ -228996,7 +229067,7 @@ function Tooltip3(props) {
|
|
|
228996
229067
|
}, [x2, y2, parentWidth, parentHeight]);
|
|
228997
229068
|
return jsx$1("div", { ref: ref2, className: classes2.tooltipAnchor, children: ref2 && ref2.current ? jsx$1(Popper, { open: true, anchorEl: ref2.current, container: getTooltipContainer, transition: true, placement: `${placementY}-${placementX}`, children: jsx$1(Paper, { elevation: 8, className: classes2.tooltipContent, children: children3 }) }) : null });
|
|
228998
229069
|
}
|
|
228999
|
-
const useStyles$
|
|
229070
|
+
const useStyles$t = makeStyles()((theme) => ({
|
|
229000
229071
|
cellEmphasisCrosshair: {
|
|
229001
229072
|
zIndex: 50,
|
|
229002
229073
|
position: "absolute",
|
|
@@ -229007,7 +229078,7 @@ const useStyles$s = makeStyles()((theme) => ({
|
|
|
229007
229078
|
}));
|
|
229008
229079
|
function Tooltip2D(props) {
|
|
229009
229080
|
const { parentUuid, sourceUuid, x: x2, y: y2, parentWidth, parentHeight, children: children3 } = props;
|
|
229010
|
-
const { classes: classes2 } = useStyles$
|
|
229081
|
+
const { classes: classes2 } = useStyles$t();
|
|
229011
229082
|
if (x2 < 0 || x2 > parentWidth || y2 < 0 || y2 > parentHeight) {
|
|
229012
229083
|
return null;
|
|
229013
229084
|
}
|
|
@@ -232919,7 +232990,7 @@ function getXlinkHref(cmap) {
|
|
|
232919
232990
|
const xlinkHref = ramp(color2.copy().domain(quantize$3(interpolate$1$1(0, 1), n3))).toDataURL();
|
|
232920
232991
|
return xlinkHref;
|
|
232921
232992
|
}
|
|
232922
|
-
const useStyles$
|
|
232993
|
+
const useStyles$s = makeStyles()(() => ({
|
|
232923
232994
|
legend: {
|
|
232924
232995
|
position: "relative",
|
|
232925
232996
|
// Needed for absolute positioning of slider overlay
|
|
@@ -233116,7 +233187,7 @@ function Legend(props) {
|
|
|
233116
233187
|
contourThresholds
|
|
233117
233188
|
} = props;
|
|
233118
233189
|
const svgRef = useRef(null);
|
|
233119
|
-
const { classes: classes2 } = useStyles$
|
|
233190
|
+
const { classes: classes2 } = useStyles$s();
|
|
233120
233191
|
const [localRange, setLocalRange] = useState(featureValueColormapRange);
|
|
233121
233192
|
useEffect(() => {
|
|
233122
233193
|
setLocalRange(featureValueColormapRange);
|
|
@@ -233450,7 +233521,7 @@ function Legend(props) {
|
|
|
233450
233521
|
}
|
|
233451
233522
|
} })] })] });
|
|
233452
233523
|
}
|
|
233453
|
-
const useStyles$
|
|
233524
|
+
const useStyles$r = makeStyles()(() => ({
|
|
233454
233525
|
multiLegend: {
|
|
233455
233526
|
position: "absolute",
|
|
233456
233527
|
top: "0px",
|
|
@@ -233477,7 +233548,7 @@ function MultiLegend(props) {
|
|
|
233477
233548
|
pointLayerCoordination,
|
|
233478
233549
|
pointMultiIndicesData
|
|
233479
233550
|
} = props;
|
|
233480
|
-
const { classes: classes2 } = useStyles$
|
|
233551
|
+
const { classes: classes2 } = useStyles$r();
|
|
233481
233552
|
const reversedSegmentationLayerScopes = useMemo$1(() => [...segmentationLayerScopes || []].reverse(), [segmentationLayerScopes]);
|
|
233482
233553
|
const reversedSpotLayerScopes = useMemo$1(() => [...spotLayerScopes || []].reverse(), [spotLayerScopes]);
|
|
233483
233554
|
const reversedPointLayerScopes = useMemo$1(() => [...pointLayerScopes || []].reverse(), [pointLayerScopes]);
|
|
@@ -233570,7 +233641,7 @@ function MultiLegend(props) {
|
|
|
233570
233641
|
}) : null;
|
|
233571
233642
|
}) : null] });
|
|
233572
233643
|
}
|
|
233573
|
-
const useStyles$
|
|
233644
|
+
const useStyles$q = makeStyles()(() => ({
|
|
233574
233645
|
channelNamesLegendContainer: {
|
|
233575
233646
|
position: "absolute",
|
|
233576
233647
|
bottom: "0px",
|
|
@@ -233593,7 +233664,7 @@ const useStyles$p = makeStyles()(() => ({
|
|
|
233593
233664
|
}));
|
|
233594
233665
|
function ChannelNamesLegend(props) {
|
|
233595
233666
|
const { images, imageLayerScopes, imageLayerCoordination, imageChannelScopesByLayer, imageChannelCoordination } = props;
|
|
233596
|
-
const { classes: classes2 } = useStyles$
|
|
233667
|
+
const { classes: classes2 } = useStyles$q();
|
|
233597
233668
|
const reversedImageLayerScopes = useMemo$1(() => [...imageLayerScopes || []].reverse(), [imageLayerScopes]);
|
|
233598
233669
|
return jsx$1("div", { className: classes2.channelNamesLegendContainer, children: imageLayerScopes ? reversedImageLayerScopes.map((layerScope) => {
|
|
233599
233670
|
const layerCoordination = imageLayerCoordination[0][layerScope];
|
|
@@ -255200,7 +255271,7 @@ class Spatial2 extends AbstractSpatialOrScatterplot {
|
|
|
255200
255271
|
this.viewInfoDidUpdate();
|
|
255201
255272
|
const shallowDiff2 = (propName) => prevProps[propName] !== this.props[propName];
|
|
255202
255273
|
const shallowDiffByLayer2 = (propName, scopeName) => prevProps?.[propName]?.[scopeName] !== this.props?.[propName]?.[scopeName];
|
|
255203
|
-
const
|
|
255274
|
+
const shallowDiffByChannel2 = (propName, firstName, secondName) => prevProps?.[propName]?.[firstName]?.[secondName] !== this.props?.[propName]?.[firstName]?.[secondName];
|
|
255204
255275
|
const shallowDiffByLayerCoordination = (propName, layerScope) => prevProps?.[propName]?.[0]?.[layerScope] !== this.props?.[propName]?.[0]?.[layerScope];
|
|
255205
255276
|
const shallowDiffByChannelCoordination = (propName, layerScope, channelScope) => prevProps?.[propName]?.[0]?.[layerScope]?.[channelScope] !== this.props?.[propName]?.[0]?.[layerScope]?.[channelScope];
|
|
255206
255277
|
let forceUpdate = false;
|
|
@@ -255221,7 +255292,7 @@ class Spatial2 extends AbstractSpatialOrScatterplot {
|
|
|
255221
255292
|
} else {
|
|
255222
255293
|
this.props.segmentationLayerScopes?.forEach((layerScope) => {
|
|
255223
255294
|
this.props.segmentationChannelScopesByLayer?.[layerScope]?.forEach((channelScope) => {
|
|
255224
|
-
if (
|
|
255295
|
+
if (shallowDiffByChannel2("obsSegmentationsLocations", layerScope, channelScope)) {
|
|
255225
255296
|
this.onUpdateSegmentationsLocationsData(layerScope, channelScope);
|
|
255226
255297
|
forceUpdate = true;
|
|
255227
255298
|
}
|
|
@@ -255234,7 +255305,7 @@ class Spatial2 extends AbstractSpatialOrScatterplot {
|
|
|
255234
255305
|
} else {
|
|
255235
255306
|
this.props.segmentationLayerScopes?.forEach((layerScope) => {
|
|
255236
255307
|
this.props.segmentationChannelScopesByLayer?.[layerScope]?.forEach((channelScope) => {
|
|
255237
|
-
if (
|
|
255308
|
+
if (shallowDiffByChannel2("obsSegmentationsSets", layerScope, channelScope) || shallowDiffByChannelCoordination("segmentationChannelCoordination", layerScope, channelScope)) {
|
|
255238
255309
|
this.onUpdateSegmentationsSetsData(layerScope, channelScope);
|
|
255239
255310
|
forceUpdate = true;
|
|
255240
255311
|
}
|
|
@@ -255247,7 +255318,7 @@ class Spatial2 extends AbstractSpatialOrScatterplot {
|
|
|
255247
255318
|
} else {
|
|
255248
255319
|
this.props.segmentationLayerScopes?.forEach((layerScope) => {
|
|
255249
255320
|
this.props.segmentationChannelScopesByLayer?.[layerScope]?.forEach((channelScope) => {
|
|
255250
|
-
if (
|
|
255321
|
+
if (shallowDiffByChannel2("segmentationMatrixIndices", layerScope, channelScope)) {
|
|
255251
255322
|
this.onUpdateSegmentationsIndexData(layerScope, channelScope);
|
|
255252
255323
|
forceUpdate = true;
|
|
255253
255324
|
}
|
|
@@ -255260,7 +255331,7 @@ class Spatial2 extends AbstractSpatialOrScatterplot {
|
|
|
255260
255331
|
} else {
|
|
255261
255332
|
this.props.segmentationLayerScopes.forEach((layerScope) => {
|
|
255262
255333
|
this.props.segmentationChannelScopesByLayer?.[layerScope]?.forEach((channelScope) => {
|
|
255263
|
-
if (
|
|
255334
|
+
if (shallowDiffByChannel2("segmentationMatrixIndices", layerScope, channelScope) || shallowDiffByChannel2("segmentationMultiExpressionData", layerScope, channelScope)) {
|
|
255264
255335
|
this.onUpdateSegmentationsExpressionData(layerScope, channelScope);
|
|
255265
255336
|
forceUpdate = true;
|
|
255266
255337
|
}
|
|
@@ -255514,12 +255585,12 @@ class ErrorBoundary extends React__default.Component {
|
|
|
255514
255585
|
}
|
|
255515
255586
|
}
|
|
255516
255587
|
const LazySpatialThree = React__default.lazy(async () => {
|
|
255517
|
-
const { SpatialWrapper: SpatialWrapper2 } = await import("./index-
|
|
255588
|
+
const { SpatialWrapper: SpatialWrapper2 } = await import("./index-CA6Y_Dls.js").then((n3) => n3.a);
|
|
255518
255589
|
return { default: SpatialWrapper2 };
|
|
255519
255590
|
});
|
|
255520
255591
|
const SpatialThreeAdapter = React__default.forwardRef((props, ref2) => jsx$1("div", { ref: ref2, style: { width: "100%", height: "100%" }, children: jsx$1(ErrorBoundary, { fallback: jsx$1("div", { children: "3D spatial view is not available in this environment." }), children: jsx$1(Suspense, { fallback: jsx$1("div", { children: "Loading..." }), children: jsx$1(LazySpatialThree, { ...props }) }) }) }));
|
|
255521
255592
|
const LazySpatialAccelerated = React__default.lazy(async () => {
|
|
255522
|
-
const { SpatialWrapper: SpatialWrapper2 } = await import("./index-
|
|
255593
|
+
const { SpatialWrapper: SpatialWrapper2 } = await import("./index-gStG4FEQ.js");
|
|
255523
255594
|
return { default: SpatialWrapper2 };
|
|
255524
255595
|
});
|
|
255525
255596
|
const SpatialAcceleratedAdapter = React__default.forwardRef((props, ref2) => jsx$1("div", { ref: ref2, style: { width: "100%", height: "100%" }, children: jsx$1(ErrorBoundary, { fallback: jsx$1("div", { children: "3D spatial view is not available in this environment." }), children: jsx$1(Suspense, { fallback: jsx$1("div", { children: "Loading..." }), children: jsx$1(LazySpatialAccelerated, { ...props }) }) }) }));
|
|
@@ -255696,7 +255767,8 @@ function SpatialSubscriber(props) {
|
|
|
255696
255767
|
bitmaskValueIsIndex = false,
|
|
255697
255768
|
// TODO: move to coordination type
|
|
255698
255769
|
three: threeFor3d = false,
|
|
255699
|
-
accelerated: acceleratedFor3d = false
|
|
255770
|
+
accelerated: acceleratedFor3d = false,
|
|
255771
|
+
helpText = ViewHelpMapping.SPATIAL_BETA
|
|
255700
255772
|
} = props;
|
|
255701
255773
|
const loaders = useLoaders();
|
|
255702
255774
|
const setComponentHover = useSetComponentHover();
|
|
@@ -256140,7 +256212,7 @@ function SpatialSubscriber(props) {
|
|
|
256140
256212
|
}
|
|
256141
256213
|
}
|
|
256142
256214
|
};
|
|
256143
|
-
return jsxs(TitleInfo, { title: title2, info: subtitle, isSpatial: true, urls: urls2, theme, closeButtonVisible, downloadButtonVisible, removeGridComponent, isReady, errors, children: [shouldUseThree ? acceleratedFor3d ? jsx$1(SpatialAcceleratedAdapter, { ref: threeRef, uuid: uuid2, width: width2, height: height2, theme, hideTools: !isSelectable, rotation: [rotationX, rotationY, rotationZ], setRotationX, setRotationY, setRotationZ, targetT, targetZ, viewState: isValidViewState ? {
|
|
256215
|
+
return jsxs(TitleInfo, { title: title2, info: subtitle, isSpatial: true, urls: urls2, theme, closeButtonVisible, downloadButtonVisible, removeGridComponent, isReady, errors, helpText, children: [shouldUseThree ? acceleratedFor3d ? jsx$1(SpatialAcceleratedAdapter, { ref: threeRef, uuid: uuid2, width: width2, height: height2, theme, hideTools: !isSelectable, rotation: [rotationX, rotationY, rotationZ], setRotationX, setRotationY, setRotationZ, targetT, targetZ, viewState: isValidViewState ? {
|
|
256144
256216
|
zoom: zoom2,
|
|
256145
256217
|
target: [targetX2, targetY2, targetZ],
|
|
256146
256218
|
rotationX,
|
|
@@ -263591,7 +263663,7 @@ _defineProperty$3(WindowScroller, "defaultProps", {
|
|
|
263591
263663
|
serverHeight: 0,
|
|
263592
263664
|
serverWidth: 0
|
|
263593
263665
|
});
|
|
263594
|
-
const useStyles$
|
|
263666
|
+
const useStyles$p = makeStyles()((theme) => ({
|
|
263595
263667
|
selectableTable: {
|
|
263596
263668
|
flex: "1 1 auto",
|
|
263597
263669
|
outline: "none"
|
|
@@ -263740,7 +263812,7 @@ function SelectableTable(props) {
|
|
|
263740
263812
|
onChange(null);
|
|
263741
263813
|
}
|
|
263742
263814
|
}, [selectedRows, allowMultiple]);
|
|
263743
|
-
const { classes: classes2 } = useStyles$
|
|
263815
|
+
const { classes: classes2 } = useStyles$p();
|
|
263744
263816
|
const inputUuid = v4$1();
|
|
263745
263817
|
const rowRenderer = ({ index: index2, style: style2 }) => (
|
|
263746
263818
|
// eslint-disable-next-line jsx-a11y/interactive-supports-focus
|
|
@@ -263765,7 +263837,7 @@ const FEATURELIST_SORT_OPTIONS = [
|
|
|
263765
263837
|
"original"
|
|
263766
263838
|
];
|
|
263767
263839
|
const ALT_COLNAME = "Alternate ID";
|
|
263768
|
-
const useStyles$
|
|
263840
|
+
const useStyles$o = makeStyles()(() => ({
|
|
263769
263841
|
searchBar: {
|
|
263770
263842
|
marginTop: "10px",
|
|
263771
263843
|
marginLeft: "10px",
|
|
@@ -263778,7 +263850,7 @@ const useStyles$n = makeStyles()(() => ({
|
|
|
263778
263850
|
}));
|
|
263779
263851
|
function FeatureList(props) {
|
|
263780
263852
|
const { width: width2, height: height2, hasColorEncoding, geneList = [], featureLabelsMap, geneSelection = [], geneFilter = null, setGeneSelection, enableMultiSelect, showFeatureTable, featureListSort, featureListSortKey, hasFeatureLabels, primaryColumnName } = props;
|
|
263781
|
-
const { classes: classes2 } = useStyles$
|
|
263853
|
+
const { classes: classes2 } = useStyles$o();
|
|
263782
263854
|
const [searchTerm, setSearchTerm] = useState("");
|
|
263783
263855
|
const selectableTableSortKey = featureListSortKey === "featureIndex" ? "key" : "name";
|
|
263784
263856
|
const searchResults = useMemo$1(() => geneList.filter((gene) => gene.toLowerCase().includes(searchTerm.toLowerCase()) || featureLabelsMap?.get(gene)?.toLowerCase().includes(searchTerm.toLowerCase()) || featureLabelsMap?.get(cleanFeatureId(gene))?.toLowerCase().includes(searchTerm.toLowerCase())), [geneList, searchTerm, featureLabelsMap]);
|
|
@@ -263843,7 +263915,7 @@ function FeatureListOptions(props) {
|
|
|
263843
263915
|
const { classes: classes2 } = usePlotOptionsStyles();
|
|
263844
263916
|
return jsxs(OptionsContainer, { children: [children3, jsxs(TableRow, { children: [jsx$1(TableCell, { className: classes2.labelCell, variant: "head", scope: "row", children: jsx$1("label", { htmlFor: `feature-list-sort-option-${featureListId}`, children: "Sort Ordering" }) }), jsx$1(TableCell, { variant: "body", children: jsx$1(OptionSelect, { className: classes2.select, value: featureListSort, onChange: handleFeatureListSortChange, inputProps: {
|
|
263845
263917
|
id: `feature-list-sort-option-${featureListId}`
|
|
263846
|
-
}, children: FEATURELIST_SORT_OPTIONS.map((option) => jsx$1("option", { value: option, children: option }, option)) }) })] }), hasFeatureLabels ? jsxs(Fragment, { children: [jsxs(TableRow, { children: [jsx$1(TableCell, { className: classes2.labelCell, variant: "head", scope: "row", children: jsx$1("label", { htmlFor: `feature-list-sort-key-${featureListId}`, children: "Sort Key" }) }), jsx$1(TableCell, { variant: "body", children: jsx$1(OptionSelect, { className: classes2.select, disabled: featureListSort === "original", value: featureListSortKey, onChange: handleFeatureListSortKeyChange, inputProps: {
|
|
263918
|
+
}, children: FEATURELIST_SORT_OPTIONS.map((option) => jsx$1("option", { value: option, children: capitalize$3(option) }, option)) }) })] }), hasFeatureLabels ? jsxs(Fragment, { children: [jsxs(TableRow, { children: [jsx$1(TableCell, { className: classes2.labelCell, variant: "head", scope: "row", children: jsx$1("label", { htmlFor: `feature-list-sort-key-${featureListId}`, children: "Sort Key" }) }), jsx$1(TableCell, { variant: "body", children: jsx$1(OptionSelect, { className: classes2.select, disabled: featureListSort === "original", value: featureListSortKey, onChange: handleFeatureListSortKeyChange, inputProps: {
|
|
263847
263919
|
"aria-label": "Select the feature list sort key",
|
|
263848
263920
|
id: `feature-list-sort-key-${featureListId}`
|
|
263849
263921
|
}, children: hasFeatureLabels ? jsxs(Fragment, { children: [jsx$1("option", { value: "featureLabels", children: primaryColumnName }), jsx$1("option", { value: "featureIndex", children: ALT_COLNAME })] }) : jsx$1("option", { value: "featureIndex", children: primaryColumnName }) }) })] }), jsxs(TableRow, { children: [jsx$1(TableCell, { className: classes2.labelCell, variant: "head", scope: "row", children: jsx$1("label", { htmlFor: `feature-list-show-alternative-ids-${featureListId}`, children: "Show Alternate IDs" }) }), jsx$1(TableCell, { className: classes2.inputCell, variant: "body", children: jsx$1(Checkbox$1, { className: classes2.tableCheckbox, checked: showFeatureTable, onChange: handleShowTableChange, name: "feature-list-show-table", color: "default", slotProps: { input: {
|
|
@@ -263851,7 +263923,7 @@ function FeatureListOptions(props) {
|
|
|
263851
263923
|
id: `feature-list-show-alternative-ids-${featureListId}`
|
|
263852
263924
|
} } }) })] })] }) : null] });
|
|
263853
263925
|
}
|
|
263854
|
-
const useStyles$
|
|
263926
|
+
const useStyles$n = makeStyles()((theme) => ({
|
|
263855
263927
|
featureListContainer: {
|
|
263856
263928
|
width: "100%",
|
|
263857
263929
|
height: "100%",
|
|
@@ -263866,7 +263938,7 @@ function FeatureListSubscriber(props) {
|
|
|
263866
263938
|
const loaders = useLoaders();
|
|
263867
263939
|
const coordinationScopes = useCoordinationScopes(coordinationScopesRaw);
|
|
263868
263940
|
const [width2, height2, containerRef] = useGridItemSize();
|
|
263869
|
-
const { classes: classes2 } = useStyles$
|
|
263941
|
+
const { classes: classes2 } = useStyles$n();
|
|
263870
263942
|
const [{ dataset, obsType, featureType, featureSelection: geneSelection, featureFilter: geneFilter, obsColorEncoding: cellColorEncoding }, { setFeatureSelection: setGeneSelection, setFeatureFilter: setGeneFilter, setFeatureHighlight: setGeneHighlight, setObsColorEncoding: setCellColorEncoding }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.FEATURE_LIST], coordinationScopes);
|
|
263871
263943
|
const variablesLabel = variablesLabelOverride || featureType;
|
|
263872
263944
|
const title2 = titleOverride || `${capitalize$3(variablesLabel)} List`;
|
|
@@ -264001,7 +264073,7 @@ const useSelectionSliderStyles = makeStyles()(() => ({
|
|
|
264001
264073
|
backgroundColor: "rgba(128, 128, 128, 0.7)"
|
|
264002
264074
|
}
|
|
264003
264075
|
}));
|
|
264004
|
-
const useStyles$
|
|
264076
|
+
const useStyles$m = makeStyles()((theme) => ({
|
|
264005
264077
|
paletteContainer: {
|
|
264006
264078
|
width: "70px",
|
|
264007
264079
|
height: "40px",
|
|
@@ -264022,10 +264094,10 @@ const useStyles$l = makeStyles()((theme) => ({
|
|
|
264022
264094
|
}
|
|
264023
264095
|
}));
|
|
264024
264096
|
const ColorPalette = ({ handleChange }) => {
|
|
264025
|
-
const { classes: classes2 } = useStyles$
|
|
264097
|
+
const { classes: classes2 } = useStyles$m();
|
|
264026
264098
|
return jsx$1("div", { className: classes2.paletteContainer, "aria-label": "Color swatch", children: VIEWER_PALETTE.map((color2) => jsx$1(IconButton$1, { className: classes2.button, onClick: () => handleChange(color2), "aria-label": `Change color to ${color2}`, children: jsx$1(LensIcon, { fontSize: "small", style: { color: `rgb(${color2})` }, className: classes2.icon }) }, color2)) });
|
|
264027
264099
|
};
|
|
264028
|
-
const useStyles$
|
|
264100
|
+
const useStyles$l = makeStyles()(() => ({
|
|
264029
264101
|
menuButton: {
|
|
264030
264102
|
backgroundColor: "transparent"
|
|
264031
264103
|
},
|
|
@@ -264044,7 +264116,7 @@ function MuiSpan(props) {
|
|
|
264044
264116
|
}
|
|
264045
264117
|
function ChannelOptions$1({ handlePropertyChange, handleChannelRemove, handleIQRUpdate }) {
|
|
264046
264118
|
const [open2, setOpen] = useState(false);
|
|
264047
|
-
const { classes: classes2 } = useStyles$
|
|
264119
|
+
const { classes: classes2 } = useStyles$l();
|
|
264048
264120
|
const handleColorSelect = (color2) => {
|
|
264049
264121
|
handlePropertyChange("color", color2);
|
|
264050
264122
|
};
|
|
@@ -264661,7 +264733,7 @@ function LayerController$1(props) {
|
|
|
264661
264733
|
minWidth: "50%"
|
|
264662
264734
|
} })] }), jsx$1(TabPanel, { value: tab2, index: 0, children: FullController }), jsx$1(TabPanel, { value: tab2, index: 1, style: { marginTop: 4 }, children: jsx$1(VolumeOptions, { loader: loader2, handleSlicerSetting, handleRenderingModeChange: setRenderingMode, renderingMode, xSlice, ySlice, zSlice, use3d, setViewState, spatialHeight, spatialWidth, modelMatrix: modelMatrix2 }) })] }) : FullController, shouldShowRemoveLayerButton ? jsx$1(Button, { onClick: handleLayerRemove, fullWidth: true, variant: "outlined", style: buttonStyles, size: "small", children: "Remove Image Layer" }) : null] })] });
|
|
264663
264735
|
}
|
|
264664
|
-
const useStyles$
|
|
264736
|
+
const useStyles$k = makeStyles()(() => ({
|
|
264665
264737
|
addButton: {
|
|
264666
264738
|
marginTop: "10px",
|
|
264667
264739
|
marginBottom: "10px",
|
|
@@ -264673,7 +264745,7 @@ function ImageAddIcon() {
|
|
|
264673
264745
|
}
|
|
264674
264746
|
function ImageAddButton({ imageOptions, handleImageAdd }) {
|
|
264675
264747
|
const [open2, setOpen] = useState(false);
|
|
264676
|
-
const { classes: classes2 } = useStyles$
|
|
264748
|
+
const { classes: classes2 } = useStyles$k();
|
|
264677
264749
|
const handleAdd = (imgData) => {
|
|
264678
264750
|
setOpen((prev2) => !prev2);
|
|
264679
264751
|
handleImageAdd(imgData);
|
|
@@ -265005,7 +265077,7 @@ const useEllipsisMenuStyles = makeStyles()(() => ({
|
|
|
265005
265077
|
padding: "4px"
|
|
265006
265078
|
}
|
|
265007
265079
|
}));
|
|
265008
|
-
const useStyles$
|
|
265080
|
+
const useStyles$j = makeStyles()(() => ({
|
|
265009
265081
|
colorPickerPaper: {
|
|
265010
265082
|
overflow: "hidden",
|
|
265011
265083
|
"& > ul": {
|
|
@@ -265063,7 +265135,7 @@ function ChannelColorPickerMenu(props) {
|
|
|
265063
265135
|
setColor2([rgb2.r, rgb2.g, rgb2.b]);
|
|
265064
265136
|
}
|
|
265065
265137
|
}
|
|
265066
|
-
const { classes: classes2 } = useStyles$
|
|
265138
|
+
const { classes: classes2 } = useStyles$j();
|
|
265067
265139
|
const currentColor = color2 ? colorArrayToString(color2) : colorArrayToString(getDefaultColor(theme));
|
|
265068
265140
|
const isWritable = typeof setColor2 === "function";
|
|
265069
265141
|
const derivedOpen = isWritable ? isStaticColor && visible ? open2 : false : false;
|
|
@@ -265071,7 +265143,7 @@ function ChannelColorPickerMenu(props) {
|
|
|
265071
265143
|
[classes2.colorIconOutline]: theme !== "dark" && isEqual$3(color2, [255, 255, 255])
|
|
265072
265144
|
}), style: { backgroundColor: currentColor } }) : isColormap && visible && featureValueColormap ? jsx$1("div", { className: classes2.colorIcon, children: jsx$1("svg", { width: "18", height: "18", children: jsx$1("image", { x: 0, y: 0, width: 18, height: 18, preserveAspectRatio: "none", href: getXlinkHref(featureValueColormap), clipPath: "inset(0% round 4px)" }) }) }) : jsx$1("div", { className: classes2.colorIcon }), buttonClassName: classes2.colorIconButton, withPaper: true, paperClassName: classes2.colorPickerPaper, "aria-label": "Open color picker menu", children: jsx$1(Twitter$1, { className: classes2.colorPicker, disableAlpha: true, width: 108, triangle: "hide", colors: defaultPalette, color: currentColor, onChangeComplete: handleColorChange }) });
|
|
265073
265145
|
}
|
|
265074
|
-
const useStyles$
|
|
265146
|
+
const useStyles$i = makeStyles()(() => ({
|
|
265075
265147
|
layerTypeSpotIcon: {
|
|
265076
265148
|
height: "100%",
|
|
265077
265149
|
marginLeft: "1px",
|
|
@@ -265084,7 +265156,7 @@ const useStyles$h = makeStyles()(() => ({
|
|
|
265084
265156
|
function SpotLayerEllipsisMenu(props) {
|
|
265085
265157
|
const { strokeWidth, setStrokeWidth, filled, setFilled, featureSelection, obsColorEncoding, setObsColorEncoding, featureValueColormap, setFeatureValueColormap, featureValueColormapRange, setFeatureValueColormapRange, tooltipsVisible, setTooltipsVisible, tooltipCrosshairsVisible, setTooltipCrosshairsVisible, legendVisible, setLegendVisible } = props;
|
|
265086
265158
|
const [open2, setOpen] = useState(false);
|
|
265087
|
-
const { classes: classes2 } = useStyles$
|
|
265159
|
+
const { classes: classes2 } = useStyles$i();
|
|
265088
265160
|
const { classes: selectClasses2 } = useSelectStyles();
|
|
265089
265161
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
265090
265162
|
const filledId = $bdb11010cef70236$export$f680877a34711e37();
|
|
@@ -265106,7 +265178,7 @@ function SpotLayerController(props) {
|
|
|
265106
265178
|
const Visibility = useMemo$1(() => visibleSetting ? VisibilityIcon : VisibilityOffIcon, [visibleSetting]);
|
|
265107
265179
|
const isStaticColor = obsColorEncoding === "spatialLayerColor";
|
|
265108
265180
|
const isColormap = obsColorEncoding === "geneSelection";
|
|
265109
|
-
const { classes: classes2 } = useStyles$
|
|
265181
|
+
const { classes: classes2 } = useStyles$i();
|
|
265110
265182
|
const { classes: lcClasses } = useControllerSectionStyles();
|
|
265111
265183
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
265112
265184
|
const handleVisibleChange = useCallback(() => {
|
|
@@ -265116,7 +265188,7 @@ function SpotLayerController(props) {
|
|
|
265116
265188
|
const handleOpacityChange = useCallback((e3, v) => setOpacity2(v), [setOpacity2]);
|
|
265117
265189
|
return jsx$1(Grid$1, { className: lcClasses.layerControllerGrid, children: jsx$1(Paper, { elevation: 4, className: lcClasses.layerControllerRoot, children: jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(Button, { onClick: handleVisibleChange, className: menuClasses.imageLayerVisibleButton, "aria-label": "Toggle spot layer visibility", children: jsx$1(Visibility, {}) }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelColorPickerMenu, { theme, color: color2, setColor: setColor2, palette, isStaticColor, isColormap, featureValueColormap, visible }) }), jsx$1(Grid$1, { size: 6, children: jsx$1(Typography, { className: menuClasses.imageLayerName, children: label2 }) }), jsx$1(Grid$1, { size: 2, children: jsx$1(Slider, { value: opacity2, min: 0, max: 1, step: 1e-3, onChange: handleOpacityChange, className: menuClasses.imageLayerOpacitySlider, orientation: "horizontal", "aria-label": `Adjust opacity for layer ${label2}` }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(SpotLayerEllipsisMenu, { filled, setFilled, strokeWidth, setStrokeWidth, featureSelection, obsColorEncoding, setObsColorEncoding, featureValueColormap, setFeatureValueColormap, featureValueColormapRange, setFeatureValueColormapRange, tooltipsVisible, setTooltipsVisible, tooltipCrosshairsVisible, setTooltipCrosshairsVisible, legendVisible, setLegendVisible }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(SvgSpots, { className: classes2.layerTypeSpotIcon }) })] }) }) });
|
|
265118
265190
|
}
|
|
265119
|
-
const useStyles$
|
|
265191
|
+
const useStyles$h = makeStyles()(() => ({
|
|
265120
265192
|
layerFeatureControllerGrid: {
|
|
265121
265193
|
padding: "0",
|
|
265122
265194
|
flexWrap: "nowrap"
|
|
@@ -265161,14 +265233,15 @@ function LayerPerFeatureController(props) {
|
|
|
265161
265233
|
]);
|
|
265162
265234
|
}
|
|
265163
265235
|
}, [featureName, featureColor, setFeatureColor, featureColorIndex]);
|
|
265164
|
-
const { classes: classes2 } = useStyles$
|
|
265236
|
+
const { classes: classes2 } = useStyles$h();
|
|
265165
265237
|
const { classes: lcClasses } = useControllerSectionStyles();
|
|
265166
265238
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
265167
265239
|
const [open2, setOpen] = useState(false);
|
|
265168
265240
|
const { colorPickerColor, colorPickerReadable, colorPickerWritable, colorPickerTooltip } = useMemo$1(() => {
|
|
265169
265241
|
if (obsColorEncoding === "geneSelection") {
|
|
265242
|
+
const storedColor = featureColor?.find((fc) => fc.name === featureName)?.color;
|
|
265170
265243
|
return {
|
|
265171
|
-
colorPickerColor:
|
|
265244
|
+
colorPickerColor: storedColor ?? randomByFeatureColor ?? spatialLayerColor,
|
|
265172
265245
|
colorPickerReadable: true,
|
|
265173
265246
|
colorPickerWritable: true,
|
|
265174
265247
|
colorPickerTooltip: null
|
|
@@ -265214,7 +265287,7 @@ function LayerPerFeatureController(props) {
|
|
|
265214
265287
|
]);
|
|
265215
265288
|
return jsx$1(Grid$1, { className: lcClasses.layerControllerGrid, children: jsxs(Paper, { elevation: 2, className: lcClasses.layerControllerSubRow, children: [jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(Button, { onClick: handleRemoveFeature, className: menuClasses.imageLayerVisibleButton, "aria-label": "Remove feature", children: jsx$1(ClearIcon, {}) }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(Tooltip$3, { title: colorPickerTooltip ?? "", disableHoverListener: !colorPickerTooltip, placement: "top", children: jsx$1("span", { children: jsx$1(ChannelColorPickerMenu, { theme, color: colorPickerColor, setColor: colorPickerWritable ? handleColorChange : null, palette, isStaticColor: colorPickerReadable, isColormap: false, featureValueColormap, visible: true }) }) }) }), jsx$1(Grid$1, { size: 6, children: jsx$1(Typography, { className: menuClasses.imageLayerName, children: featureName }) }), jsx$1(Grid$1, { size: 2, sx: { paddingRight: "12px", overflow: "visible" }, children: jsx$1(Slider, { value: opacity2, min: 0, max: 1, step: 1e-3, onChange: handleOpacityChange, className: menuClasses.imageLayerOpacitySlider, orientation: "horizontal", "aria-label": `Adjust opacity for layer ${featureName}` }) }), jsxs(Grid$1, { size: 1, container: true, direction: "row", children: [jsx$1(SvgPoints, { className: classes2.layerTypeFeatureIcon }), null] })] }), loadingDoneFraction < 1 ? jsx$1(Grid$1, { size: 12, container: true, direction: "column", justifyContent: "space-between", className: classes2.layerFeatureControllerGrid, children: jsx$1(LinearProgress, { variant: loadingDoneFraction === 0 ? "indeterminate" : "determinate", value: loadingDoneFraction * 100 }) }) : null] }) }, featureName);
|
|
265216
265289
|
}
|
|
265217
|
-
const useStyles$
|
|
265290
|
+
const useStyles$g = makeStyles()(() => ({
|
|
265218
265291
|
pointLayerButton: {
|
|
265219
265292
|
borderStyle: "dashed",
|
|
265220
265293
|
marginTop: "10px",
|
|
@@ -265243,7 +265316,7 @@ const useStyles$f = makeStyles()(() => ({
|
|
|
265243
265316
|
}
|
|
265244
265317
|
}));
|
|
265245
265318
|
function PointLayerEllipsisMenu(props) {
|
|
265246
|
-
const { featureSelection, featureFilterMode, setFeatureFilterMode, obsColorEncoding, setObsColorEncoding, featureValueColormapRange, setFeatureValueColormapRange, tooltipsVisible, setTooltipsVisible, tooltipCrosshairsVisible, setTooltipCrosshairsVisible, legendVisible, setLegendVisible } = props;
|
|
265319
|
+
const { featureSelection, featureFilterMode, setFeatureFilterMode, obsColorEncoding, setObsColorEncoding, featureValueColormap, setFeatureValueColormap, featureValueColormapRange, setFeatureValueColormapRange, tooltipsVisible, setTooltipsVisible, tooltipCrosshairsVisible, setTooltipCrosshairsVisible, legendVisible, setLegendVisible } = props;
|
|
265247
265320
|
const [open2, setOpen] = useState(false);
|
|
265248
265321
|
const { classes: selectClasses2 } = useSelectStyles();
|
|
265249
265322
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
@@ -265253,7 +265326,8 @@ function PointLayerEllipsisMenu(props) {
|
|
|
265253
265326
|
const crosshairsVisibleId = $bdb11010cef70236$export$f680877a34711e37();
|
|
265254
265327
|
const legendVisibleId = $bdb11010cef70236$export$f680877a34711e37();
|
|
265255
265328
|
const featureFilterModeId = $bdb11010cef70236$export$f680877a34711e37();
|
|
265256
|
-
|
|
265329
|
+
const colormapSelectorId = $bdb11010cef70236$export$f680877a34711e37();
|
|
265330
|
+
return jsxs(PopperMenu, { open: open2, setOpen, buttonIcon: jsx$1(MoreVertIcon, {}), buttonClassName: menuClasses.imageLayerMenuButton, containerClassName: menuClasses.imageLayerPopperContainer, withPaper: true, getAriaLabel: () => "Open point layer options menu", children: [jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: colormapSelectorId, children: "Colormap: " }), jsx$1(NativeSelect, { onChange: (e3) => setFeatureValueColormap(e3.target.value), value: featureValueColormap, inputProps: { id: colormapSelectorId, "aria-label": "Colormap selector" }, classes: { root: selectClasses2.selectRoot }, children: GLSL_COLORMAPS.map((cmap) => jsx$1("option", { value: cmap, children: cmap }, cmap)) })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: quantitativeColormapId, children: "Color Encoding: " }), jsxs(NativeSelect, { onChange: (e3) => setObsColorEncoding(e3.target.value), value: obsColorEncoding, inputProps: { id: quantitativeColormapId, "aria-label": "Color encoding selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { value: "spatialLayerColor", children: "Static Color" }), jsx$1("option", { value: "geneSelection", children: "Feature Color" }), jsx$1("option", { value: "randomByFeature", children: "Random Color per Feature" }), jsx$1("option", { value: "random", children: "Random Color per Point" })] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: featureFilterModeId, children: "Filter to Feature Selection: " }), jsx$1(Checkbox$1, { color: "primary", className: menuClasses.menuItemCheckbox, checked: featureFilterMode === "featureSelection", onChange: (e3, v) => setFeatureFilterMode(v ? "featureSelection" : null), slotProps: { input: { id: featureFilterModeId, "aria-label": "Toggle feature filter mode" } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: colormapRangeId, children: "Colormap Range: " }), jsx$1(Slider, { disabled: obsColorEncoding !== "geneSelection", value: featureValueColormapRange, min: 0, max: 1, step: 0.01, onChange: (e3, v) => setFeatureValueColormapRange(v), className: menuClasses.menuItemSlider, orientation: "horizontal", id: colormapRangeId, getAriaLabel: (index2) => index2 === 0 ? "Low value colormap range slider" : "High value colormap range slider" })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: tooltipsVisibleId, children: "Tooltips Visible: " }), jsx$1(Checkbox$1, { color: "primary", className: menuClasses.menuItemCheckbox, checked: tooltipsVisible, onChange: (e3, v) => setTooltipsVisible(v), slotProps: { input: { id: tooltipsVisibleId, "aria-label": "Toggle tooltip visibility" } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: crosshairsVisibleId, children: "Tooltip Crosshairs Visible: " }), jsx$1(Checkbox$1, { color: "primary", className: menuClasses.menuItemCheckbox, checked: tooltipCrosshairsVisible, onChange: (e3, v) => setTooltipCrosshairsVisible(v), slotProps: { input: { id: crosshairsVisibleId, "aria-label": "Toggle tooltip crosshair visibility" } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: legendVisibleId, children: "Legend Visible: " }), jsx$1(Checkbox$1, { color: "primary", className: menuClasses.menuItemCheckbox, checked: legendVisible, onChange: (e3, v) => setLegendVisible(v), slotProps: { input: { id: legendVisibleId, "aria-label": "Toggle legend visibility" } } })] })] });
|
|
265257
265331
|
}
|
|
265258
265332
|
function PointLayerController(props) {
|
|
265259
265333
|
const { theme, layerScope, layerCoordination, setLayerCoordination, palette = null, pointMatrixIndicesData, tiledPointsLoadingProgress, layerPerFeatureForPoints } = props;
|
|
@@ -265283,7 +265357,7 @@ function PointLayerController(props) {
|
|
|
265283
265357
|
}, [featureColor, featureSelection]);
|
|
265284
265358
|
const isStaticColor = obsColorEncoding === "spatialLayerColor" || obsColorEncoding === "geneSelection";
|
|
265285
265359
|
const showStaticColor = obsColorEncoding === "spatialLayerColor" || obsColorEncoding === "geneSelection" && hasUnspecifiedFeatureColors;
|
|
265286
|
-
const isColormap =
|
|
265360
|
+
const isColormap = obsColorEncoding === "geneSelection";
|
|
265287
265361
|
const hasSingleSelectedFeature = obsColorEncoding === "geneSelection" && Array.isArray(featureSelection) && featureSelection.length === 1;
|
|
265288
265362
|
const color2 = useMemo$1(() => {
|
|
265289
265363
|
if (showStaticColor) {
|
|
@@ -265330,7 +265404,7 @@ function PointLayerController(props) {
|
|
|
265330
265404
|
featureSelection,
|
|
265331
265405
|
showStaticColor
|
|
265332
265406
|
]);
|
|
265333
|
-
const { classes: classes2 } = useStyles$
|
|
265407
|
+
const { classes: classes2 } = useStyles$g();
|
|
265334
265408
|
const { classes: lcClasses } = useControllerSectionStyles();
|
|
265335
265409
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
265336
265410
|
const handleVisibleChange = useCallback(() => {
|
|
@@ -265342,9 +265416,24 @@ function PointLayerController(props) {
|
|
|
265342
265416
|
const [coloringTabIndex, setColoringTabIndex] = useState(0);
|
|
265343
265417
|
const { featureIndex } = pointMatrixIndicesData || {};
|
|
265344
265418
|
const hasSelectedFeatures = Array.isArray(featureSelection) && featureSelection.length > 0;
|
|
265345
|
-
|
|
265419
|
+
useEffect(() => {
|
|
265420
|
+
if (obsColorEncoding !== "geneSelection" || !Array.isArray(featureSelection))
|
|
265421
|
+
return;
|
|
265422
|
+
const cleanedFeatureColor = (featureColor ?? []).filter((fc) => featureSelection.includes(fc.name));
|
|
265423
|
+
const missingEntries = featureSelection.filter((featureName) => !cleanedFeatureColor.find((fc) => fc.name === featureName)).map((featureName) => {
|
|
265424
|
+
const varIdx = featureIndex?.indexOf(featureName) ?? -1;
|
|
265425
|
+
const fColor = varIdx >= 0 ? PALETTE[varIdx % PALETTE.length] : getDefaultColor(theme);
|
|
265426
|
+
return { name: featureName, color: fColor };
|
|
265427
|
+
});
|
|
265428
|
+
const nextFeatureColor = [...cleanedFeatureColor, ...missingEntries];
|
|
265429
|
+
const changed = nextFeatureColor.length !== featureColor?.length || missingEntries.length > 0;
|
|
265430
|
+
if (changed) {
|
|
265431
|
+
setFeatureColor(nextFeatureColor);
|
|
265432
|
+
}
|
|
265433
|
+
}, [featureSelection, obsColorEncoding, featureIndex, featureColor]);
|
|
265434
|
+
return jsxs(Grid$1, { className: lcClasses.layerControllerGrid, children: [jsxs(Paper, { elevation: 4, className: lcClasses.layerControllerRoot, children: [jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(Button, { onClick: handleVisibleChange, className: menuClasses.imageLayerVisibleButton, "aria-label": "Toggle layer visibility", children: jsx$1(Visibility, {}) }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelColorPickerMenu, { theme, color: color2, setColor: setColor2, palette, isStaticColor, isColormap, featureValueColormap, visible }) }), jsx$1(Grid$1, { size: 6, children: jsx$1(Typography, { className: menuClasses.imageLayerName, children: label2 }) }), jsx$1(Grid$1, { size: 2, children: jsx$1(Slider, { value: opacity2, min: 0, max: 1, step: 1e-3, onChange: handleOpacityChange, className: menuClasses.imageLayerOpacitySlider, orientation: "horizontal", "aria-label": `Adjust opacity for layer ${label2}` }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(PointLayerEllipsisMenu, { featureSelection, obsColorEncoding, setObsColorEncoding, featureValueColormapRange, setFeatureValueColormapRange, tooltipsVisible, setTooltipsVisible, tooltipCrosshairsVisible, setTooltipCrosshairsVisible, legendVisible, setLegendVisible, featureFilterMode, setFeatureFilterMode, featureValueColormap, setFeatureValueColormap }) }), jsxs(Grid$1, { size: 1, container: true, direction: "row", children: [jsx$1(SvgPoints, { className: classes2.layerTypePointIcon }), null] })] }), loadingDoneFraction < 1 ? jsx$1(Grid$1, { size: 12, container: true, direction: "column", justifyContent: "space-between", className: classes2.pointFeatureControllerGrid, children: jsx$1(LinearProgress, { variant: loadingDoneFraction === 0 ? "indeterminate" : "determinate", value: loadingDoneFraction * 100 }) }) : null, null] }), layerPerFeatureForPoints && hasSelectedFeatures ? jsxs(Fragment, { children: [featureSelection.map((featureName) => jsx$1(LayerPerFeatureController, { theme, featureName, featureColor, setFeatureColor, spatialLayerColor, featureIndex, featureValueColormap, featureSelection, setFeatureSelection, obsColorEncoding, loadingDoneFraction, opacity: opacity2, handleOpacityChange }, featureName)), jsx$1(Grid$1, { className: lcClasses.layerControllerGrid, children: jsx$1(Paper, { elevation: 2, className: lcClasses.layerControllerSubRow, children: jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(Button, { onClick: () => setFeatureFilterMode(featureFilterMode === "featureSelection" ? null : "featureSelection"), className: menuClasses.imageLayerVisibleButton, "aria-label": "Toggle visibility of unselected points", children: featureFilterMode === "featureSelection" ? jsx$1(VisibilityOffIcon, {}) : jsx$1(VisibilityIcon, {}) }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelColorPickerMenu, { theme, color: getDefaultColor("dark"), setColor: null, isStaticColor: true, isColormap: false, visible: true }) }), jsx$1(Grid$1, { size: 6, children: jsx$1(Typography, { className: menuClasses.imageLayerName, children: "Unselected" }) }), jsx$1(Grid$1, { size: 2, sx: { paddingRight: "12px", overflow: "visible" }, children: jsx$1(Slider, { value: opacity2, min: 0, max: 1, step: 1e-3, onChange: handleOpacityChange, className: menuClasses.imageLayerOpacitySlider, orientation: "horizontal", "aria-label": "Adjust opacity for unselected layer" }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(SvgPoints, { className: classes2.layerTypePointIcon }) })] }) }) })] }) : null] });
|
|
265346
265435
|
}
|
|
265347
|
-
const useStyles$
|
|
265436
|
+
const useStyles$f = makeStyles()(() => ({
|
|
265348
265437
|
layerTypeSegmentationIcon: {
|
|
265349
265438
|
height: "100%",
|
|
265350
265439
|
marginLeft: "1px",
|
|
@@ -265357,7 +265446,7 @@ const useStyles$e = makeStyles()(() => ({
|
|
|
265357
265446
|
function SegmentationChannelEllipsisMenu(props) {
|
|
265358
265447
|
const { obsType, featureType, featureValueType, strokeWidth, setStrokeWidth, filled, setFilled, featureSelection, obsColorEncoding, setObsColorEncoding, featureValueColormap, setFeatureValueColormap, featureValueColormapRange, setFeatureValueColormapRange, tooltipsVisible, setTooltipsVisible, tooltipCrosshairsVisible, setTooltipCrosshairsVisible, legendVisible, setLegendVisible } = props;
|
|
265359
265448
|
const [open2, setOpen] = useState(false);
|
|
265360
|
-
const { classes: classes2 } = useStyles$
|
|
265449
|
+
const { classes: classes2 } = useStyles$f();
|
|
265361
265450
|
const { classes: selectClasses2 } = useSelectStyles();
|
|
265362
265451
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
265363
265452
|
const filledId = $bdb11010cef70236$export$f680877a34711e37();
|
|
@@ -265376,7 +265465,7 @@ function SegmentationChannelController(props) {
|
|
|
265376
265465
|
const Visibility = useMemo$1(() => visibleSetting ? VisibilityIcon : VisibilityOffIcon, [visibleSetting]);
|
|
265377
265466
|
const isStaticColor = obsColorEncoding === "spatialChannelColor";
|
|
265378
265467
|
const isColormap = obsColorEncoding === "geneSelection";
|
|
265379
|
-
const { classes: classes2 } = useStyles$
|
|
265468
|
+
const { classes: classes2 } = useStyles$f();
|
|
265380
265469
|
const { classes: lcClasses } = useControllerSectionStyles();
|
|
265381
265470
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
265382
265471
|
const handleVisibleChange = useCallback(() => {
|
|
@@ -268094,7 +268183,7 @@ function useBaseQuery(options, Observer, queryClient) {
|
|
|
268094
268183
|
function useQuery(options, queryClient) {
|
|
268095
268184
|
return useBaseQuery(options, QueryObserver);
|
|
268096
268185
|
}
|
|
268097
|
-
const useStyles$
|
|
268186
|
+
const useStyles$e = makeStyles()(() => ({
|
|
268098
268187
|
channelMenuButton: {
|
|
268099
268188
|
backgroundColor: "transparent",
|
|
268100
268189
|
padding: "3px 0",
|
|
@@ -268108,7 +268197,7 @@ const useStyles$d = makeStyles()(() => ({
|
|
|
268108
268197
|
function ChannelOptions(props) {
|
|
268109
268198
|
const { onRemove: onRemove2, onResetWindowUsingIQR, showValueExtent, setShowValueExtent, numResolutions, spatialMaxResolution, setSpatialMaxResolution } = props;
|
|
268110
268199
|
const [open2, setOpen] = useState(false);
|
|
268111
|
-
const { classes: classes2 } = useStyles$
|
|
268200
|
+
const { classes: classes2 } = useStyles$e();
|
|
268112
268201
|
const { classes: selectClasses2 } = useSelectStyles();
|
|
268113
268202
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
268114
268203
|
function handleRemove() {
|
|
@@ -268121,7 +268210,7 @@ function ChannelOptions(props) {
|
|
|
268121
268210
|
const domainTypeId = $bdb11010cef70236$export$f680877a34711e37();
|
|
268122
268211
|
return jsxs(PopperMenu, { open: open2, setOpen, buttonIcon: jsx$1(MoreVertIcon, { fontSize: "small" }), buttonClassName: classes2.channelMenuButton, containerClassName: menuClasses.imageLayerPopperContainer, placement: "bottom-end", withPaper: true, "aria-label": "Open channel options menu", children: [jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: domainTypeId, children: "Best Resolution: " }), jsx$1(Slider, { value: spatialMaxResolution || 1, valueLabelDisplay: "auto", onChange: (e3, v) => setSpatialMaxResolution(v), min: 1, max: numResolutions - 1, step: 1, orientation: "horizontal" })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: domainTypeId, children: "Slider Extent: " }), jsxs(NativeSelect, { onChange: handleDomainTypeChange, value: showValueExtent ? "Value Min/Max" : "Dtype Min/Max", inputProps: { id: domainTypeId, "aria-label": "Slider extent selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { value: "Value Min/Max", children: "Value Min/Max" }), jsx$1("option", { value: "Dtype Min/Max", children: "Dtype Min/Max" })] })] }), jsx$1(MenuItem, { dense: true, disableGutters: true, component: "button", onClick: onResetWindowUsingIQR, className: classes2.menuItemButton, "aria-label": "Click to use IQR for channel", children: "Reset window using IQR" }), jsx$1(MenuItem, { dense: true, disableGutters: true, component: "button", onClick: handleRemove, className: classes2.menuItemButton, "aria-label": "Click to remove channel", children: "Remove channel" })] });
|
|
268123
268212
|
}
|
|
268124
|
-
const useStyles$
|
|
268213
|
+
const useStyles$d = makeStyles()(() => ({
|
|
268125
268214
|
channelSlider: {
|
|
268126
268215
|
marginTop: "7px"
|
|
268127
268216
|
}
|
|
@@ -268131,7 +268220,7 @@ function ChannelSlider(props) {
|
|
|
268131
268220
|
const rgbColor = toRgbUIString(colormapOn, color2, theme);
|
|
268132
268221
|
const dtype = image2?.getDtype();
|
|
268133
268222
|
const fullDomain = dtype ? DOMAINS[dtype] : [0, 0];
|
|
268134
|
-
const { classes: classes2 } = useStyles$
|
|
268223
|
+
const { classes: classes2 } = useStyles$d();
|
|
268135
268224
|
useEffect(() => {
|
|
268136
268225
|
if (!window2 && !disabled && Array.isArray(minMaxDomain)) {
|
|
268137
268226
|
setWindow2(minMaxDomain);
|
|
@@ -268146,7 +268235,7 @@ function ChannelSlider(props) {
|
|
|
268146
268235
|
return `${labelPrefix} for ${rgbColor} colormap channel`;
|
|
268147
268236
|
}, getAriaValueText: () => `Current colormap values: ${rgbColor}-${window2}`, min: min2, max: max2, step, orientation: "horizontal", className: classes2.channelSlider, style: { color: rgbColor }, disabled });
|
|
268148
268237
|
}
|
|
268149
|
-
const useStyles$
|
|
268238
|
+
const useStyles$c = makeStyles()(() => ({
|
|
268150
268239
|
visibilityCheckbox: {
|
|
268151
268240
|
padding: "10px 0"
|
|
268152
268241
|
}
|
|
@@ -268160,10 +268249,10 @@ function getCheckboxColor(colormapOn, color2, theme) {
|
|
|
268160
268249
|
function ChannelVisibilityCheckbox(props) {
|
|
268161
268250
|
const { color: color2, visible, setVisible, disabled, theme, colormapOn } = props;
|
|
268162
268251
|
const rgbColor = getCheckboxColor(colormapOn, color2, theme);
|
|
268163
|
-
const { classes: classes2 } = useStyles$
|
|
268252
|
+
const { classes: classes2 } = useStyles$c();
|
|
268164
268253
|
return jsx$1(Checkbox$1, { onChange: (e3, v) => setVisible(v), checked: visible, disabled, className: classes2.visibilityCheckbox, style: { color: rgbColor, "&$checked": { color: rgbColor } }, slotProps: { input: { "aria-label": "Toggle channel visibility" } } });
|
|
268165
268254
|
}
|
|
268166
|
-
const useStyles$
|
|
268255
|
+
const useStyles$b = makeStyles()(() => ({
|
|
268167
268256
|
oneLineChannelSelect: {
|
|
268168
268257
|
width: "90%",
|
|
268169
268258
|
marginLeft: "5%",
|
|
@@ -268171,17 +268260,23 @@ const useStyles$a = makeStyles()(() => ({
|
|
|
268171
268260
|
}
|
|
268172
268261
|
}));
|
|
268173
268262
|
function ChannelSelectionDropdown(props) {
|
|
268174
|
-
const { featureIndex, targetC, setTargetC, setWindow: setWindow2, disabled } = props;
|
|
268175
|
-
const { classes: classes2 } = useStyles$
|
|
268263
|
+
const { featureIndex, channelsSortOrder, targetC, setTargetC, setWindow: setWindow2, disabled } = props;
|
|
268264
|
+
const { classes: classes2 } = useStyles$b();
|
|
268176
268265
|
const { classes: selectClasses2 } = useSelectStyles();
|
|
268177
268266
|
function handleChange(event2) {
|
|
268178
268267
|
setTargetC(event2.target.value === "" ? null : Number(event2.target.value));
|
|
268179
268268
|
setWindow2(null);
|
|
268180
268269
|
}
|
|
268181
|
-
|
|
268182
|
-
|
|
268183
|
-
|
|
268184
|
-
|
|
268270
|
+
const sortedOptions = useMemo$1(() => {
|
|
268271
|
+
if (!Array.isArray(featureIndex))
|
|
268272
|
+
return [];
|
|
268273
|
+
const options = featureIndex.map((channelName, channelIndex) => ({ channelName, channelIndex }));
|
|
268274
|
+
if (channelsSortOrder === "alphabetical") {
|
|
268275
|
+
return options.sort((a2, b2) => a2.channelName.localeCompare(b2.channelName, void 0, { numeric: true, sensitivity: "base" }));
|
|
268276
|
+
}
|
|
268277
|
+
return options;
|
|
268278
|
+
}, [featureIndex, channelsSortOrder]);
|
|
268279
|
+
return Array.isArray(featureIndex) ? jsx$1(NativeSelect, { classes: { root: selectClasses2.selectRoot }, className: classes2.oneLineChannelSelect, value: targetC === null ? "" : targetC, onChange: handleChange, inputProps: { "aria-label": "Channel selector" }, children: sortedOptions.map(({ channelName, channelIndex }) => jsx$1("option", { disabled, value: channelIndex, children: channelName }, `${channelName}-${channelIndex}`)) }) : null;
|
|
268185
268280
|
}
|
|
268186
268281
|
function ImageChannelController(props) {
|
|
268187
268282
|
const {
|
|
@@ -268209,7 +268304,8 @@ function ImageChannelController(props) {
|
|
|
268209
268304
|
spatialRenderingMode,
|
|
268210
268305
|
numResolutions,
|
|
268211
268306
|
spatialMaxResolution,
|
|
268212
|
-
setSpatialMaxResolution
|
|
268307
|
+
setSpatialMaxResolution,
|
|
268308
|
+
channelsSortOrder
|
|
268213
268309
|
} = props;
|
|
268214
268310
|
const removeChannel = useRemoveImageChannelInMetaCoordinationScopes();
|
|
268215
268311
|
const [showValueExtent, setShowValueExtent] = useState(true);
|
|
@@ -268246,7 +268342,7 @@ function ImageChannelController(props) {
|
|
|
268246
268342
|
setWindow2(minMaxDomain);
|
|
268247
268343
|
}
|
|
268248
268344
|
}
|
|
268249
|
-
return jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelVisibilityCheckbox, { color: color2, setColor: setColor2, visible, setVisible, disabled: isLoading, theme, colormapOn }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelColorPickerMenu, { color: color2, setColor: setColor2, visible, setVisible, disabled: isLoading, theme, isStaticColor: !colormapOn, palette: VIEWER_PALETTE }) }), jsx$1(Grid$1, { size: 6, children: jsx$1(ChannelSelectionDropdown, { featureIndex, targetC, setTargetC, setWindow: setWindow2, disabled: isLoading }) }), jsx$1(Grid$1, { size: 3, children: jsx$1(ChannelSlider, { image: image2, targetT, targetZ, targetC, window: window2, setWindow: setWindow2, disabled, color: color2, theme, colormapOn, showValueExtent, minMaxDomain }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelOptions, { onRemove: onRemove2, showValueExtent, setShowValueExtent, onResetWindowUsingIQR: handleResetWindowUsingIQR, numResolutions, spatialMaxResolution, setSpatialMaxResolution }) })] });
|
|
268345
|
+
return jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelVisibilityCheckbox, { color: color2, setColor: setColor2, visible, setVisible, disabled: isLoading, theme, colormapOn }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelColorPickerMenu, { color: color2, setColor: setColor2, visible, setVisible, disabled: isLoading, theme, isStaticColor: !colormapOn, palette: VIEWER_PALETTE }) }), jsx$1(Grid$1, { size: 6, children: jsx$1(ChannelSelectionDropdown, { featureIndex, targetC, setTargetC, setWindow: setWindow2, disabled: isLoading, channelsSortOrder }) }), jsx$1(Grid$1, { size: 3, children: jsx$1(ChannelSlider, { image: image2, targetT, targetZ, targetC, window: window2, setWindow: setWindow2, disabled, color: color2, theme, colormapOn, showValueExtent, minMaxDomain }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelOptions, { onRemove: onRemove2, showValueExtent, setShowValueExtent, onResetWindowUsingIQR: handleResetWindowUsingIQR, numResolutions, spatialMaxResolution, setSpatialMaxResolution }) })] });
|
|
268250
268346
|
}
|
|
268251
268347
|
function DimensionSlider(props) {
|
|
268252
268348
|
const { boundingSlice, sliceValue, setSliceValue, label: label2 } = props;
|
|
@@ -268300,7 +268396,7 @@ function LoadingStatusIndicator(props) {
|
|
|
268300
268396
|
}
|
|
268301
268397
|
return jsxs(Grid$1, { container: true, px: 0.5, children: [jsx$1(Grid$1, { size: 6, alignItems: "start", children: jsx$1(Grid$1, { container: true, alignItems: "center", gap: 1, children: statusColor !== "success" ? jsx$1(StatusChip, { label: statusLabel, color: statusColor, size: "small" }) : null }) }), jsx$1(Grid$1, { size: 6, px: 1, my: 0.25, children: jsx$1(LoadingText, { bricksLoaded, currentRequestCount, totalBricksRequested, isLoading }) }), jsx$1(Grid$1, { size: 12, children: jsxs(Grid$1, { container: true, direction: "row", spacing: 2, alignItems: "center", wrap: "nowrap", children: [jsx$1(LoadingControlButton, { startIcon: jsx$1(Stop, {}), onClick: onStopLoading, disabled: noNewRequests, ariaLabel: "Stop loading data and render at highest resolution", children: "Stop Loading" }), jsx$1(LoadingControlButton, { startIcon: jsx$1(Replay, {}), onClick: onRestartLoading, disabled: !noNewRequests && !isLoading, ariaLabel: "Restart data loading", children: "Restart Loading" })] }) }), jsx$1(Grid$1, { size: 12, visibility: isLoading ? "visible" : "hidden", mt: 1, mb: 0.5, children: jsx$1(LinearProgress, { variant: "determinate", value: percentage }) })] });
|
|
268302
268398
|
}
|
|
268303
|
-
const useStyles$
|
|
268399
|
+
const useStyles$a = makeStyles()(() => ({
|
|
268304
268400
|
imageLayerButton: {
|
|
268305
268401
|
borderStyle: "dashed",
|
|
268306
268402
|
marginTop: "10px",
|
|
@@ -268345,7 +268441,7 @@ const lodSliderRangeConfig = {
|
|
|
268345
268441
|
step: 1
|
|
268346
268442
|
};
|
|
268347
268443
|
function ImageLayerEllipsisMenu(props) {
|
|
268348
|
-
const { colormap, setColormap, photometricInterpretation, setPhotometricInterpretation, spatialTargetResolution, setSpatialTargetResolution, spatialLodFactor, setSpatialLodFactor, volumetricRenderingAlgorithm, setVolumetricRenderingAlgorithm, spatialLayerTransparentColor, setSpatialLayerTransparentColor, spatialRenderingMode, image: image2, channelScopes, tooltipsVisible, setTooltipsVisible, channelLabelsVisible, setChannelLabelsVisible, channelLabelsOrientation, setChannelLabelsOrientation, channelLabelSize, setChannelLabelSize } = props;
|
|
268444
|
+
const { colormap, setColormap, photometricInterpretation, setPhotometricInterpretation, spatialTargetResolution, setSpatialTargetResolution, spatialLodFactor, setSpatialLodFactor, volumetricRenderingAlgorithm, setVolumetricRenderingAlgorithm, spatialLayerTransparentColor, setSpatialLayerTransparentColor, spatialRenderingMode, image: image2, channelScopes, tooltipsVisible, setTooltipsVisible, channelLabelsVisible, setChannelLabelsVisible, channelLabelsOrientation, setChannelLabelsOrientation, channelLabelSize, setChannelLabelSize, channelsSortOrder, setChannelsSortOrder } = props;
|
|
268349
268445
|
const [open2, setOpen] = useState(false);
|
|
268350
268446
|
const { classes: selectClasses2 } = useSelectStyles();
|
|
268351
268447
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
@@ -268371,6 +268467,9 @@ function ImageLayerEllipsisMenu(props) {
|
|
|
268371
268467
|
function handleChannelLabelsOrientationChange(event2) {
|
|
268372
268468
|
setChannelLabelsOrientation(event2.target.value);
|
|
268373
268469
|
}
|
|
268470
|
+
function handleChannelsSortOrderChange(event2) {
|
|
268471
|
+
setChannelsSortOrder(event2.target.value);
|
|
268472
|
+
}
|
|
268374
268473
|
function handleLodFactorChange(event2, value2) {
|
|
268375
268474
|
setLocalLodSliderValue(value2);
|
|
268376
268475
|
}
|
|
@@ -268392,11 +268491,12 @@ function ImageLayerEllipsisMenu(props) {
|
|
|
268392
268491
|
const channelLabelsOrientationId = $bdb11010cef70236$export$f680877a34711e37();
|
|
268393
268492
|
const channelLabelSizeId = $bdb11010cef70236$export$f680877a34711e37();
|
|
268394
268493
|
const lodFactorId = $bdb11010cef70236$export$f680877a34711e37();
|
|
268494
|
+
const channelsSortOrderId = $bdb11010cef70236$export$f680877a34711e37();
|
|
268395
268495
|
return jsxs(PopperMenu, { open: open2, setOpen, buttonIcon: jsx$1(MoreVertIcon, {}), buttonClassName: menuClasses.imageLayerMenuButton, containerClassName: menuClasses.imageLayerPopperContainer, withPaper: true, "aria-label": "Open image layer options menu", children: [is3dMode && jsxs(MenuItem, { dense: true, disableGutters: true, className: menuClasses.menuItem, children: [jsx$1("label", { id: `${lodFactorId}-label`, className: menuClasses.imageLayerMenuLabel, htmlFor: lodFactorId, children: "LOD Factor: " }), jsx$1(Slider, { disabled: !is3dMode, value: localLodSliderValue, onChange: handleLodFactorChange, onChangeCommitted: handleLodFactorChangeCommitted, className: menuClasses.menuItemSlider, orientation: "horizontal", id: lodFactorId, "aria-label": "Level of detail factor slider", valueLabelDisplay: "off", ...lodSliderRangeConfig }), jsx$1(Box, { px: 1 }), jsx$1(Input$1, { value: localLodSliderValue, onChange: handleLodFactorInputChange, onBlur: handleLodFactorInputChange, "aria-labelledby": `${lodFactorId}-label`, size: "small", sx: { width: "6ch", flexShrink: 0, fontVariantNumeric: "tabular-nums" }, endAdornment: jsx$1(InputAdornment$1, { position: "end", variant: "standard", sx: { "& > p": { marginBottom: 0 } }, children: "%" }), inputProps: {
|
|
268396
268496
|
...lodSliderRangeConfig,
|
|
268397
268497
|
inputMode: "numeric",
|
|
268398
268498
|
pattern: "[0-9]*"
|
|
268399
|
-
} })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: colormapId, children: "Colormap: " }), jsxs(NativeSelect, { disabled: photometricInterpretation === "RGB", onChange: handleColormapChange, value: colormap === null ? "" : colormap, inputProps: { id: colormapId, "aria-label": "Colormap selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { "aria-label": "None", value: "", children: "None" }), COLORMAP_OPTIONS.map((name2) => jsx$1("option", { value: name2, children: name2 }, name2))] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: interpretationId, children: "Photometric Interpretation: " }), jsxs(NativeSelect, { onChange: handleInterpretationChange, value: photometricInterpretation, inputProps: { id: interpretationId, "aria-label": "Photometric interpretation selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { "aria-label": "RGB", value: "RGB", children: "RGB" }), channelScopes.length > 0 ? jsx$1("option", { "aria-label": "BlackIsZero", value: "BlackIsZero", children: "BlackIsZero" }) : null] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: transparentId, children: "Zero Transparent: " }), jsx$1(Checkbox$1, { color: "primary", checked: spatialLayerTransparentColor !== null, onChange: (e3, v) => setSpatialLayerTransparentColor(v ? [0, 0, 0] : null), slotProps: { input: { id: transparentId, "aria-label": "Render zero-value pixels as transparent" } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: volumetricId, children: "Volumetric Rendering: " }), jsxs(NativeSelect, { onChange: handleVolumetricChange, value: volumetricRenderingAlgorithm, inputProps: { id: volumetricId, "aria-label": "Volumetric rendering algorithm selector" }, classes: { root: selectClasses2.selectRoot }, disabled: !is3dMode, children: [jsx$1("option", { "aria-label": "Additive", value: "additive", children: "Additive" }), jsx$1("option", { "aria-label": "Maximum Intensity Projection", value: "maximumIntensityProjection", children: "Maximum Intensity Projection" })] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: resolutionId, children: "Volume Resolution: " }), jsxs(NativeSelect, { disabled: !is3dMode || !isMultiResolution, onChange: handleResolutionChange, value: spatialTargetResolution === null ? "auto" : spatialTargetResolution, inputProps: { id: resolutionId, "aria-label": "Volumetric resolution selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { value: "auto", children: "Auto" }), Array.isArray(multiResolutionStats) ? multiResolutionStats.map((stats, resolution) => stats.canLoad ? jsx$1("option", { value: resolution, children: `3D: ${resolution}x Downsampled, ~${formatBytes(stats.totalBytes)} per channel, (${stats.height}, ${stats.width}, ${stats.depthDownsampled})` }, `(${stats.height}, ${stats.width}, ${stats.depthDownsampled})`) : null) : null] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: tooltipsVisibleId, children: "Tooltips Visible: " }), jsx$1(Checkbox$1, { color: "primary", checked: tooltipsVisible, onChange: (e3, v) => setTooltipsVisible(v), slotProps: { input: { id: tooltipsVisibleId, "aria-label": "Render pixel value tooltips" } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: channelLabelsVisibleId, children: "Channel Labels Visible: " }), jsx$1(Checkbox$1, { disabled: photometricInterpretation === "RGB", color: "primary", checked: channelLabelsVisible, onChange: (e3, v) => setChannelLabelsVisible(v), slotProps: { input: { id: channelLabelsVisibleId, "aria-label": "Render channel labels" } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: channelLabelsOrientationId, children: "Channel Labels Orientation: " }), jsxs(NativeSelect, { disabled: photometricInterpretation === "RGB", onChange: handleChannelLabelsOrientationChange, value: channelLabelsOrientation, inputProps: { id: channelLabelsOrientationId, "aria-label": "Channel labels orientation selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { "aria-label": "Vertical", value: "vertical", children: "Vertical" }), jsx$1("option", { "aria-label": "Horizontal", value: "horizontal", children: "Horizontal" })] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: channelLabelSizeId, children: "Channel Labels Size: " }), jsx$1(Slider, { disabled: photometricInterpretation === "RGB", value: channelLabelSize, min: 8, max: 36, step: 1, onChange: (e3, v) => setChannelLabelSize(v), className: menuClasses.menuItemSlider, orientation: "horizontal", id: channelLabelSizeId, "aria-label": "Channel labels text size slider" })] })] });
|
|
268499
|
+
} })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: colormapId, children: "Colormap: " }), jsxs(NativeSelect, { disabled: photometricInterpretation === "RGB", onChange: handleColormapChange, value: colormap === null ? "" : colormap, inputProps: { id: colormapId, "aria-label": "Colormap selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { "aria-label": "None", value: "", children: "None" }), COLORMAP_OPTIONS.map((name2) => jsx$1("option", { value: name2, children: name2 }, name2))] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: interpretationId, children: "Photometric Interpretation: " }), jsxs(NativeSelect, { onChange: handleInterpretationChange, value: photometricInterpretation, inputProps: { id: interpretationId, "aria-label": "Photometric interpretation selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { "aria-label": "RGB", value: "RGB", children: "RGB" }), channelScopes.length > 0 ? jsx$1("option", { "aria-label": "BlackIsZero", value: "BlackIsZero", children: "BlackIsZero" }) : null] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: transparentId, children: "Zero Transparent: " }), jsx$1(Checkbox$1, { color: "primary", checked: spatialLayerTransparentColor !== null, onChange: (e3, v) => setSpatialLayerTransparentColor(v ? [0, 0, 0] : null), slotProps: { input: { id: transparentId, "aria-label": "Render zero-value pixels as transparent" } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: volumetricId, children: "Volumetric Rendering: " }), jsxs(NativeSelect, { onChange: handleVolumetricChange, value: volumetricRenderingAlgorithm, inputProps: { id: volumetricId, "aria-label": "Volumetric rendering algorithm selector" }, classes: { root: selectClasses2.selectRoot }, disabled: !is3dMode, children: [jsx$1("option", { "aria-label": "Additive", value: "additive", children: "Additive" }), jsx$1("option", { "aria-label": "Maximum Intensity Projection", value: "maximumIntensityProjection", children: "Maximum Intensity Projection" })] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: resolutionId, children: "Volume Resolution: " }), jsxs(NativeSelect, { disabled: !is3dMode || !isMultiResolution, onChange: handleResolutionChange, value: spatialTargetResolution === null ? "auto" : spatialTargetResolution, inputProps: { id: resolutionId, "aria-label": "Volumetric resolution selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { value: "auto", children: "Auto" }), Array.isArray(multiResolutionStats) ? multiResolutionStats.map((stats, resolution) => stats.canLoad ? jsx$1("option", { value: resolution, children: `3D: ${resolution}x Downsampled, ~${formatBytes(stats.totalBytes)} per channel, (${stats.height}, ${stats.width}, ${stats.depthDownsampled})` }, `(${stats.height}, ${stats.width}, ${stats.depthDownsampled})`) : null) : null] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: tooltipsVisibleId, children: "Tooltips Visible: " }), jsx$1(Checkbox$1, { color: "primary", checked: tooltipsVisible, onChange: (e3, v) => setTooltipsVisible(v), slotProps: { input: { id: tooltipsVisibleId, "aria-label": "Render pixel value tooltips" } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: channelLabelsVisibleId, children: "Channel Labels Visible: " }), jsx$1(Checkbox$1, { disabled: photometricInterpretation === "RGB", color: "primary", checked: channelLabelsVisible, onChange: (e3, v) => setChannelLabelsVisible(v), slotProps: { input: { id: channelLabelsVisibleId, "aria-label": "Render channel labels" } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: channelLabelsOrientationId, children: "Channel Labels Orientation: " }), jsxs(NativeSelect, { disabled: photometricInterpretation === "RGB", onChange: handleChannelLabelsOrientationChange, value: channelLabelsOrientation, inputProps: { id: channelLabelsOrientationId, "aria-label": "Channel labels orientation selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { "aria-label": "Vertical", value: "vertical", children: "Vertical" }), jsx$1("option", { "aria-label": "Horizontal", value: "horizontal", children: "Horizontal" })] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: channelLabelSizeId, children: "Channel Labels Size: " }), jsx$1(Slider, { disabled: photometricInterpretation === "RGB", value: channelLabelSize, min: 8, max: 36, step: 1, onChange: (e3, v) => setChannelLabelSize(v), className: menuClasses.menuItemSlider, orientation: "horizontal", id: channelLabelSizeId, "aria-label": "Channel labels text size slider" })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: channelsSortOrderId, children: "Channel Ordering: " }), jsxs(NativeSelect, { onChange: handleChannelsSortOrderChange, value: channelsSortOrder, inputProps: { id: channelsSortOrderId, "aria-label": "Channel sort order selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { "aria-label": "Original", value: "original", children: "Original" }), jsx$1("option", { "aria-label": "Alphabetical", value: "alphabetical", children: "Alphabetical" })] })] })] });
|
|
268400
268500
|
}
|
|
268401
268501
|
function ImageLayerController(props) {
|
|
268402
268502
|
const {
|
|
@@ -268422,8 +268522,8 @@ function ImageLayerController(props) {
|
|
|
268422
268522
|
volumeStillRef = null
|
|
268423
268523
|
} = props;
|
|
268424
268524
|
const [open2, setOpen] = useState(true);
|
|
268425
|
-
const { spatialLayerVisible: visible, spatialLayerOpacity: opacity2, spatialLayerColormap: colormap, photometricInterpretation, spatialTargetResolution, spatialLodFactor, volumetricRenderingAlgorithm, spatialLayerTransparentColor, spatialSliceX, spatialSliceY, spatialSliceZ, tooltipsVisible, spatialChannelLabelsVisible: channelLabelsVisible, spatialChannelLabelsOrientation: channelLabelsOrientation, spatialChannelLabelSize: channelLabelSize } = layerCoordination;
|
|
268426
|
-
const { setSpatialLayerVisible: setVisible, setSpatialLayerOpacity: setOpacity2, setSpatialLayerColormap: setColormap, setPhotometricInterpretation, setSpatialTargetResolution, setSpatialLodFactor, setVolumetricRenderingAlgorithm, setSpatialLayerTransparentColor, setSpatialSliceX, setSpatialSliceY, setSpatialSliceZ, setTooltipsVisible, setSpatialChannelLabelsVisible: setChannelLabelsVisible, setSpatialChannelLabelsOrientation: setChannelLabelsOrientation, setSpatialChannelLabelSize: setChannelLabelSize } = setLayerCoordination;
|
|
268525
|
+
const { spatialLayerVisible: visible, spatialLayerOpacity: opacity2, spatialLayerColormap: colormap, photometricInterpretation, spatialTargetResolution, spatialLodFactor, volumetricRenderingAlgorithm, spatialLayerTransparentColor, spatialSliceX, spatialSliceY, spatialSliceZ, tooltipsVisible, spatialChannelLabelsVisible: channelLabelsVisible, spatialChannelLabelsOrientation: channelLabelsOrientation, spatialChannelLabelSize: channelLabelSize, spatialChannelsSortOrder: channelsSortOrder } = layerCoordination;
|
|
268526
|
+
const { setSpatialLayerVisible: setVisible, setSpatialLayerOpacity: setOpacity2, setSpatialLayerColormap: setColormap, setPhotometricInterpretation, setSpatialTargetResolution, setSpatialLodFactor, setVolumetricRenderingAlgorithm, setSpatialLayerTransparentColor, setSpatialSliceX, setSpatialSliceY, setSpatialSliceZ, setTooltipsVisible, setSpatialChannelLabelsVisible: setChannelLabelsVisible, setSpatialChannelLabelsOrientation: setChannelLabelsOrientation, setSpatialChannelLabelSize: setChannelLabelSize, setSpatialChannelsSortOrder: setChannelsSortOrder } = setLayerCoordination;
|
|
268427
268527
|
const addChannel = useAddImageChannelInMetaCoordinationScopes();
|
|
268428
268528
|
const visibleSetting = typeof visible === "boolean" ? visible : true;
|
|
268429
268529
|
const Visibility = useMemo$1(() => visibleSetting ? VisibilityIcon : VisibilityOffIcon, [visibleSetting]);
|
|
@@ -268439,19 +268539,19 @@ function ImageLayerController(props) {
|
|
|
268439
268539
|
}, [visible, setVisible]);
|
|
268440
268540
|
const handleOpacityChange = useCallback((e3, v) => setOpacity2(v), [setOpacity2]);
|
|
268441
268541
|
const handleOpenChange = useCallback(() => setOpen((prev2) => !prev2), []);
|
|
268442
|
-
const { classes: classes2 } = useStyles$
|
|
268542
|
+
const { classes: classes2 } = useStyles$a();
|
|
268443
268543
|
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
268444
268544
|
const { classes: controllerSectionClasses } = useControllerSectionStyles();
|
|
268445
268545
|
const isMultiChannel = photometricInterpretation !== "RGB";
|
|
268446
|
-
return jsx$1(Grid$1, { className: controllerSectionClasses.layerControllerGrid, children: jsxs(Paper, { elevation: 4, className: controllerSectionClasses.layerControllerRoot, children: [jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(Button, { className: menuClasses.imageLayerVisibleButton, onClick: handleVisibleChange, "aria-label": "Toggle layer visibility", children: jsx$1(Visibility, {}) }) }), jsx$1(Grid$1, { size: 1 }), jsx$1(Grid$1, { size: 6, children: jsx$1(Typography, { className: menuClasses.imageLayerName, children: label2 }) }), jsx$1(Grid$1, { size: 2, children: jsx$1(Slider, { value: opacity2, min: 0, max: 1, step: 1e-3, onChange: handleOpacityChange, className: menuClasses.imageLayerOpacitySlider, orientation: "horizontal", "aria-label": `Adjust opacity for layer ${label2}` }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ImageLayerEllipsisMenu, { colormap, setColormap, photometricInterpretation, setPhotometricInterpretation, spatialTargetResolution, setSpatialTargetResolution, spatialLodFactor, setSpatialLodFactor, volumetricRenderingAlgorithm, setVolumetricRenderingAlgorithm, spatialLayerTransparentColor, setSpatialLayerTransparentColor, spatialRenderingMode, image: image2, channelScopes, tooltipsVisible, setTooltipsVisible, channelLabelsVisible, setChannelLabelsVisible, channelLabelsOrientation, setChannelLabelsOrientation, channelLabelSize, setChannelLabelSize }) }), jsxs(Grid$1, { size: 1, container: true, direction: "row", children: [jsx$1(ImageIcon, { className: classes2.layerTypeImageIcon }), isMultiChannel ? jsx$1(Button, { onClick: handleOpenChange, className: classes2.channelExpansionButton, "aria-label": "Expand or collapse channel controls", children: open2 ? jsx$1(ExpandLess, {}) : jsx$1(ExpandMore, {}) }) : null] })] }), isMultiChannel && open2 ? jsxs(Grid$1, { container: true, direction: "column", justifyContent: "space-between", className: classes2.imageChannelControllerGrid, children: [channelScopes.map((cScope) => {
|
|
268546
|
+
return jsx$1(Grid$1, { className: controllerSectionClasses.layerControllerGrid, children: jsxs(Paper, { elevation: 4, className: controllerSectionClasses.layerControllerRoot, children: [jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(Button, { className: menuClasses.imageLayerVisibleButton, onClick: handleVisibleChange, "aria-label": "Toggle layer visibility", children: jsx$1(Visibility, {}) }) }), jsx$1(Grid$1, { size: 1 }), jsx$1(Grid$1, { size: 6, children: jsx$1(Typography, { className: menuClasses.imageLayerName, children: label2 }) }), jsx$1(Grid$1, { size: 2, children: jsx$1(Slider, { value: opacity2, min: 0, max: 1, step: 1e-3, onChange: handleOpacityChange, className: menuClasses.imageLayerOpacitySlider, orientation: "horizontal", "aria-label": `Adjust opacity for layer ${label2}` }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ImageLayerEllipsisMenu, { colormap, setColormap, photometricInterpretation, setPhotometricInterpretation, spatialTargetResolution, setSpatialTargetResolution, spatialLodFactor, setSpatialLodFactor, volumetricRenderingAlgorithm, setVolumetricRenderingAlgorithm, spatialLayerTransparentColor, setSpatialLayerTransparentColor, spatialRenderingMode, image: image2, channelScopes, tooltipsVisible, setTooltipsVisible, channelLabelsVisible, setChannelLabelsVisible, channelLabelsOrientation, setChannelLabelsOrientation, channelLabelSize, setChannelLabelSize, channelsSortOrder, setChannelsSortOrder }) }), jsxs(Grid$1, { size: 1, container: true, direction: "row", children: [jsx$1(ImageIcon, { className: classes2.layerTypeImageIcon }), isMultiChannel ? jsx$1(Button, { onClick: handleOpenChange, className: classes2.channelExpansionButton, "aria-label": "Expand or collapse channel controls", children: open2 ? jsx$1(ExpandLess, {}) : jsx$1(ExpandMore, {}) }) : null] })] }), isMultiChannel && open2 ? jsxs(Grid$1, { container: true, direction: "column", justifyContent: "space-between", className: classes2.imageChannelControllerGrid, children: [channelScopes.map((cScope) => {
|
|
268447
268547
|
const { spatialTargetC, spatialChannelVisible, spatialChannelOpacity, spatialChannelColor, spatialChannelWindow, spatialMaxResolution } = channelCoordination[cScope];
|
|
268448
268548
|
const { setSpatialTargetC, setSpatialChannelVisible, setSpatialChannelOpacity, setSpatialChannelColor, setSpatialChannelWindow, setSpatialMaxResolution } = setChannelCoordination[cScope];
|
|
268449
268549
|
const channelIndex = image2?.getChannelIndex(spatialTargetC);
|
|
268450
268550
|
const numResolutions = image2?.getNumResolutions();
|
|
268451
|
-
return jsx$1(ImageChannelController, { theme, coordinationScopesRaw, layerScope, channelScope: cScope, targetT, targetZ, targetC: channelIndex, setTargetC: setSpatialTargetC, visible: spatialChannelVisible, setVisible: setSpatialChannelVisible, opacity: spatialChannelOpacity, setOpacity: setSpatialChannelOpacity, color: spatialChannelColor, setColor: setSpatialChannelColor, window: spatialChannelWindow, setWindow: setSpatialChannelWindow, colormapOn: colormap !== null, featureIndex, image: image2, spatialRenderingMode, numResolutions, spatialMaxResolution, setSpatialMaxResolution }, cScope);
|
|
268551
|
+
return jsx$1(ImageChannelController, { theme, coordinationScopesRaw, layerScope, channelScope: cScope, targetT, targetZ, targetC: channelIndex, setTargetC: setSpatialTargetC, visible: spatialChannelVisible, setVisible: setSpatialChannelVisible, opacity: spatialChannelOpacity, setOpacity: setSpatialChannelOpacity, color: spatialChannelColor, setColor: setSpatialChannelColor, window: spatialChannelWindow, setWindow: setSpatialChannelWindow, colormapOn: colormap !== null, featureIndex, image: image2, channelsSortOrder, spatialRenderingMode, numResolutions, spatialMaxResolution, setSpatialMaxResolution }, cScope);
|
|
268452
268552
|
}), jsx$1(Button, { disabled: channelScopes.length === MAX_CHANNELS$1 || channelScopes.length === imageNumChannels, onClick: handleChannelAdd, fullWidth: true, variant: "outlined", className: classes2.imageLayerButton, startIcon: jsx$1(AddIcon, {}), size: "small", "aria-label": "Add a channel to this layer", children: "Add Channel" })] }) : null, is3dMode && image2 ? jsxs(Grid$1, { container: true, direction: "column", justifyContent: "space-between", className: classes2.imageChannelControllerGrid, children: [jsx$1(Typography, { className: classes2.clippingPanesLabel, children: "Clipping planes:" }), jsx$1(Grid$1, { size: 12, className: classes2.clippingSliders, children: jsx$1(ClippingSliders, { image: image2, spatialSliceX, spatialSliceY, spatialSliceZ, setSpatialSliceX, setSpatialSliceY, setSpatialSliceZ }) }), jsx$1(LoadingStatusIndicator, { loadingProgress: volumeLoadingProgress, onStopLoading: onStopVolumeLoading, onRestartLoading: onRestartVolumeLoading, stillRef: volumeStillRef, spatialRenderingMode })] }) : null] }) });
|
|
268453
268553
|
}
|
|
268454
|
-
const useStyles$
|
|
268554
|
+
const useStyles$9 = makeStyles()((theme) => ({
|
|
268455
268555
|
dimensionsIcon: {
|
|
268456
268556
|
height: "40px",
|
|
268457
268557
|
width: "40px",
|
|
@@ -268475,7 +268575,7 @@ const useStyles$8 = makeStyles()((theme) => ({
|
|
|
268475
268575
|
function GlobalDimensionSlider(props) {
|
|
268476
268576
|
const { label: label2, targetValue, setTargetValue, min: min2 = 0, max: max2 = 0, spatialRenderingMode = null, setSpatialRenderingMode = null } = props;
|
|
268477
268577
|
const { classes: lcClasses } = useControllerSectionStyles();
|
|
268478
|
-
const { classes: classes2 } = useStyles$
|
|
268578
|
+
const { classes: classes2 } = useStyles$9();
|
|
268479
268579
|
const isForZ = spatialRenderingMode !== null;
|
|
268480
268580
|
const is3dMode = spatialRenderingMode === "3D";
|
|
268481
268581
|
function handleRenderingModeChange(event2) {
|
|
@@ -268486,20 +268586,115 @@ function GlobalDimensionSlider(props) {
|
|
|
268486
268586
|
}
|
|
268487
268587
|
return jsx$1(Grid$1, { className: lcClasses.layerControllerGrid, children: jsx$1(Paper, { elevation: 4, className: lcClasses.layerControllerRoot, children: jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(SvgDimensions, { className: classes2.dimensionsIcon }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(Typography, { className: classes2.dimensionLabel, children: label2 }) }), jsx$1(Grid$1, { size: 8, children: !is3dMode ? jsx$1(Slider, { value: targetValue, min: min2, max: max2, step: 1, onChange: (e3, v) => setTargetValue(v), className: classes2.dimensionSlider, valueLabelDisplay: "auto", orientation: "horizontal", disabled: spatialRenderingMode === "3D", "aria-label": `${label2}-slice slider` }) : null }), jsx$1(Grid$1, { size: 2, children: isForZ ? jsx$1(FormGroup, { row: true, className: classes2.switchFormGroup, children: jsx$1(FormControlLabel$1, { control: jsx$1(Switch, { color: "primary", checked: spatialRenderingMode === "3D", onChange: handleRenderingModeChange, name: "is3dMode" }), label: "3D" }) }) : null })] }) }) });
|
|
268488
268588
|
}
|
|
268589
|
+
const useStyles$8 = makeStyles()(() => ({
|
|
268590
|
+
layerTypeCentroidSegmentationIcon: {
|
|
268591
|
+
height: "100%",
|
|
268592
|
+
marginLeft: "1px",
|
|
268593
|
+
fill: "currentColor",
|
|
268594
|
+
fontSize: "24px",
|
|
268595
|
+
width: "50%",
|
|
268596
|
+
maxWidth: "24px"
|
|
268597
|
+
},
|
|
268598
|
+
divider: {
|
|
268599
|
+
width: "1px",
|
|
268600
|
+
height: "20px",
|
|
268601
|
+
background: "currentColor",
|
|
268602
|
+
flexShrink: 0,
|
|
268603
|
+
margin: "0 10px"
|
|
268604
|
+
},
|
|
268605
|
+
inlineLabel: {
|
|
268606
|
+
margin: "0px !important",
|
|
268607
|
+
lineHeight: 1,
|
|
268608
|
+
alignSelf: "center"
|
|
268609
|
+
},
|
|
268610
|
+
iconCell: {
|
|
268611
|
+
display: "flex",
|
|
268612
|
+
alignItems: "center",
|
|
268613
|
+
justifyContent: "center"
|
|
268614
|
+
}
|
|
268615
|
+
}));
|
|
268616
|
+
function CombinedEllipsisMenu(props) {
|
|
268617
|
+
const { obsType, featureType, featureValueType, filled, setFilled, strokeWidth, setStrokeWidth, obsColorEncoding, setObsColorEncoding, featureValueColormap, setFeatureValueColormap, featureValueColormapRange, setFeatureValueColormapRange, tooltipsVisible, setTooltipsVisible, tooltipCrosshairsVisible, setTooltipCrosshairsVisible, legendVisible, setLegendVisible, setPointObsColorEncoding, setPointFeatureValueColormap, setPointFeatureValueColormapRange, onColorEncodingChange } = props;
|
|
268618
|
+
const [open2, setOpen] = useState(false);
|
|
268619
|
+
const { classes: selectClasses2 } = useSelectStyles();
|
|
268620
|
+
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
268621
|
+
const filledId = $bdb11010cef70236$export$f680877a34711e37();
|
|
268622
|
+
const strokeWidthId = $bdb11010cef70236$export$f680877a34711e37();
|
|
268623
|
+
const colorEncodingId = $bdb11010cef70236$export$f680877a34711e37();
|
|
268624
|
+
const colormapId = $bdb11010cef70236$export$f680877a34711e37();
|
|
268625
|
+
const colormapRangeId = $bdb11010cef70236$export$f680877a34711e37();
|
|
268626
|
+
const tooltipsId = $bdb11010cef70236$export$f680877a34711e37();
|
|
268627
|
+
const crosshairsId = $bdb11010cef70236$export$f680877a34711e37();
|
|
268628
|
+
const legendId = $bdb11010cef70236$export$f680877a34711e37();
|
|
268629
|
+
return jsxs(PopperMenu, { open: open2, setOpen, buttonIcon: jsx$1(MoreVertIcon, {}), buttonClassName: menuClasses.imageLayerMenuButton, containerClassName: menuClasses.imageLayerPopperContainer, withPaper: true, getAriaLabel: () => "Open combined centroid and segmentation layer options menu", children: [jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: filledId, children: "Filled: " }), jsx$1(Checkbox$1, { color: "primary", className: menuClasses.menuItemCheckbox, checked: filled, onChange: (e3, v) => setFilled(v), slotProps: { input: { id: filledId } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: strokeWidthId, children: "Stroke width:" }), jsx$1(Slider, { disabled: filled, value: strokeWidth, min: 0.01, max: 5, step: 0.01, onChange: (e3, v) => setStrokeWidth(v), className: menuClasses.menuItemSlider, orientation: "horizontal", id: strokeWidthId, getAriaLabel: () => "Stroke width" })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: colorEncodingId, children: "Color encoding: " }), jsxs(NativeSelect, { onChange: onColorEncodingChange, value: obsColorEncoding, inputProps: { id: colorEncodingId }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { value: "spatialChannelColor", children: "Static Color" }), jsx$1("option", { value: "geneSelection", children: "Feature Value" }), jsx$1("option", { value: "cellSetSelection", children: "Set Selection" })] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: colormapId, children: "Colormap: " }), jsx$1(NativeSelect, { onChange: (e3) => {
|
|
268630
|
+
setFeatureValueColormap(e3.target.value);
|
|
268631
|
+
setPointFeatureValueColormap?.(e3.target.value);
|
|
268632
|
+
}, value: featureValueColormap, inputProps: { id: colormapId }, classes: { root: selectClasses2.selectRoot }, children: GLSL_COLORMAPS.map((cmap) => jsx$1("option", { value: cmap, children: cmap }, cmap)) })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: colormapRangeId, children: "Colormap range: " }), jsx$1(Slider, { disabled: obsColorEncoding !== "geneSelection", value: featureValueColormapRange, min: 0, max: 1, step: 0.01, onChange: (e3, v) => {
|
|
268633
|
+
setFeatureValueColormapRange(v);
|
|
268634
|
+
setPointFeatureValueColormapRange?.(v);
|
|
268635
|
+
}, className: menuClasses.menuItemSlider, orientation: "horizontal", id: colormapRangeId, getAriaLabel: (i2) => i2 === 0 ? "Low colormap range" : "High colormap range" })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: tooltipsId, children: "Tooltips visible: " }), jsx$1(Checkbox$1, { color: "primary", className: menuClasses.menuItemCheckbox, checked: tooltipsVisible, onChange: (e3, v) => setTooltipsVisible(v), slotProps: { input: { id: tooltipsId } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: crosshairsId, children: "Crosshairs visible: " }), jsx$1(Checkbox$1, { color: "primary", className: menuClasses.menuItemCheckbox, checked: tooltipCrosshairsVisible, onChange: (e3, v) => setTooltipCrosshairsVisible(v), slotProps: { input: { id: crosshairsId } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: legendId, children: "Legend visible: " }), jsx$1(Checkbox$1, { color: "primary", className: menuClasses.menuItemCheckbox, checked: legendVisible, onChange: (e3, v) => setLegendVisible(v), slotProps: { input: { id: legendId } } })] })] });
|
|
268636
|
+
}
|
|
268637
|
+
function SegmentationCentroidsController(props) {
|
|
268638
|
+
const { theme, segScope, segLayerCoordination, segChannelScopesByLayer, segChannelCoordination, pointScope, pointLayerCoordination } = props;
|
|
268639
|
+
const { classes: classes2 } = useStyles$8();
|
|
268640
|
+
const { classes: lcClasses } = useControllerSectionStyles();
|
|
268641
|
+
const { classes: menuClasses } = useEllipsisMenuStyles();
|
|
268642
|
+
const channelScopes = segChannelScopesByLayer?.[segScope] ?? [];
|
|
268643
|
+
const primaryChanScope = channelScopes[0];
|
|
268644
|
+
const chanValues = segChannelCoordination[0]?.[segScope]?.[primaryChanScope] ?? {};
|
|
268645
|
+
const chanSetters = segChannelCoordination[1]?.[segScope]?.[primaryChanScope] ?? {};
|
|
268646
|
+
const { obsType, featureType, featureValueType, spatialChannelVisible: segVisible, spatialChannelOpacity: segOpacity, spatialChannelColor: segColor, spatialSegmentationFilled: filled, spatialSegmentationStrokeWidth: strokeWidth, obsColorEncoding, featureSelection, featureValueColormap, featureValueColormapRange, tooltipsVisible, tooltipCrosshairsVisible, legendVisible } = chanValues;
|
|
268647
|
+
const { setSpatialChannelVisible: setSegVisible, setSpatialChannelOpacity: setSegOpacity, setSpatialChannelColor: setSegColor, setSpatialSegmentationFilled: setFilled, setSpatialSegmentationStrokeWidth: setStrokeWidth, setObsColorEncoding, setFeatureValueColormap, setFeatureValueColormapRange, setTooltipsVisible, setTooltipCrosshairsVisible, setLegendVisible } = chanSetters;
|
|
268648
|
+
const pointValues = pointLayerCoordination[0]?.[pointScope] ?? {};
|
|
268649
|
+
const pointSetters = pointLayerCoordination[1]?.[pointScope] ?? {};
|
|
268650
|
+
const { spatialLayerVisible: pointVisible, spatialLayerOpacity: pointOpacity, spatialLayerColor: pointColor, obsColorEncoding: pointObsColorEncoding, featureValueColormap: pointFeatureValueColormap } = pointValues;
|
|
268651
|
+
const { setSpatialLayerVisible: setPointVisible, setSpatialLayerOpacity: setPointOpacity, setSpatialLayerColor: setPointColor, setObsColorEncoding: setPointObsColorEncoding, setFeatureValueColormap: setPointFeatureValueColormap, setFeatureValueColormapRange: setPointFeatureValueColormapRange } = pointSetters;
|
|
268652
|
+
const sharedOpacity = segOpacity ?? 1;
|
|
268653
|
+
const handleOpacityChange = useCallback((e3, v) => {
|
|
268654
|
+
setSegOpacity?.(v);
|
|
268655
|
+
setPointOpacity?.(v);
|
|
268656
|
+
}, [setSegOpacity, setPointOpacity]);
|
|
268657
|
+
const handleSegVisibleChange = useCallback(() => {
|
|
268658
|
+
setSegVisible?.(typeof segVisible === "boolean" ? !segVisible : false);
|
|
268659
|
+
}, [segVisible, setSegVisible]);
|
|
268660
|
+
const handlePointVisibleChange = useCallback(() => {
|
|
268661
|
+
setPointVisible?.(typeof pointVisible === "boolean" ? !pointVisible : false);
|
|
268662
|
+
}, [pointVisible, setPointVisible]);
|
|
268663
|
+
const handleColorEncodingChange = useCallback((e3) => {
|
|
268664
|
+
const val = e3.target.value;
|
|
268665
|
+
setObsColorEncoding(val);
|
|
268666
|
+
if (val === "geneSelection") {
|
|
268667
|
+
setPointObsColorEncoding?.("geneSelection");
|
|
268668
|
+
} else if (val === "cellSetSelection") {
|
|
268669
|
+
setPointObsColorEncoding?.("cellSetSelection");
|
|
268670
|
+
} else {
|
|
268671
|
+
setPointObsColorEncoding?.("spatialChannelColor");
|
|
268672
|
+
}
|
|
268673
|
+
}, [setObsColorEncoding, setPointObsColorEncoding]);
|
|
268674
|
+
const segVisibleSetting = typeof segVisible === "boolean" ? segVisible : true;
|
|
268675
|
+
const pointVisibleSetting = typeof pointVisible === "boolean" ? pointVisible : true;
|
|
268676
|
+
const SegVisibility = segVisibleSetting ? VisibilityIcon : VisibilityOffIcon;
|
|
268677
|
+
const PointVisibility = pointVisibleSetting ? VisibilityIcon : VisibilityOffIcon;
|
|
268678
|
+
const isStaticColor = obsColorEncoding === "spatialChannelColor";
|
|
268679
|
+
const isColormap = obsColorEncoding === "geneSelection";
|
|
268680
|
+
const pointIsStaticColor = pointObsColorEncoding === "spatialChannelColor";
|
|
268681
|
+
const pointIsColormap = pointObsColorEncoding === "geneSelection";
|
|
268682
|
+
return jsx$1(Grid$1, { className: lcClasses.layerControllerGrid, children: jsx$1(Paper, { elevation: 4, className: lcClasses.layerControllerRoot, children: jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", alignItems: "center", children: [jsxs(Grid$1, { size: "grow", style: { display: "flex", alignItems: "center", minWidth: 0 }, children: [jsx$1(Button, { onClick: handleSegVisibleChange, className: menuClasses.imageLayerVisibleButton, getAriaLabel: () => "Toggle mesh visibility", children: jsx$1(SegVisibility, {}) }), jsx$1(ChannelColorPickerMenu, { theme, color: segColor, setColor: setSegColor, isStaticColor, isColormap, featureValueColormap, visible: segVisibleSetting }), jsx$1(Typography, { className: `${menuClasses.imageLayerName} ${classes2.inlineLabel}`, children: "Cell" }), jsx$1("div", { className: classes2.divider }), jsx$1(Button, { onClick: handlePointVisibleChange, className: menuClasses.imageLayerVisibleButton, getAriaLabel: () => "Toggle centroid visibility", children: jsx$1(PointVisibility, {}) }), jsx$1(ChannelColorPickerMenu, { theme, color: pointColor, setColor: setPointColor, isStaticColor: pointIsStaticColor, isColormap: pointIsColormap, featureValueColormap: pointFeatureValueColormap, visible: pointVisibleSetting }), jsx$1(Typography, { className: `${menuClasses.imageLayerName} ${classes2.inlineLabel}`, children: "Point" })] }), jsx$1(Grid$1, { size: 2, children: jsx$1(Slider, { value: sharedOpacity, min: 0, max: 1, step: 1e-3, onChange: handleOpacityChange, className: menuClasses.imageLayerOpacitySlider, orientation: "horizontal", getAriaLabel: () => "Adjust shared opacity" }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(CombinedEllipsisMenu, { obsType, featureType, featureValueType, filled, setFilled, strokeWidth, setStrokeWidth, obsColorEncoding, setObsColorEncoding, featureValueColormap, setFeatureValueColormap, featureValueColormapRange, setFeatureValueColormapRange, tooltipsVisible, setTooltipsVisible, tooltipCrosshairsVisible, setTooltipCrosshairsVisible, legendVisible, setLegendVisible, setPointObsColorEncoding, setPointFeatureValueColormap, setPointFeatureValueColormapRange, onColorEncodingChange: handleColorEncodingChange }) }), jsx$1(Grid$1, { size: 1, className: classes2.iconCell, children: jsx$1(SvgVector, { className: classes2.layerTypeCentroidSegmentationIcon }) })] }) }) });
|
|
268683
|
+
}
|
|
268489
268684
|
function LayerController(props) {
|
|
268490
|
-
const { theme, coordinationScopesRaw, segmentationLayerScopes, segmentationLayerCoordination, segmentationChannelScopesByLayer, segmentationChannelCoordination, images, imageLayerScopes, imageLayerCoordination, targetT, targetZ, setTargetT, setTargetZ, spatialRenderingMode, setSpatialRenderingMode, imageChannelScopesByLayer, imageChannelCoordination, spotLayerScopes, spotLayerCoordination, pointLayerScopes, pointLayerCoordination, pointMultiIndicesData, volumeLoadingStatus, tiledPointsLoadingProgress, layerPerFeatureForPoints } = props;
|
|
268685
|
+
const { theme, coordinationScopesRaw, segmentationLayerScopes, segmentationLayerCoordination, segmentationChannelScopesByLayer, segmentationChannelCoordination, images, imageLayerScopes, imageLayerCoordination, targetT, targetZ, setTargetT, setTargetZ, spatialRenderingMode, setSpatialRenderingMode, imageChannelScopesByLayer, imageChannelCoordination, spotLayerScopes, spotLayerCoordination, pointLayerScopes, pointLayerCoordination, pointMultiIndicesData, volumeLoadingStatus, tiledPointsLoadingProgress, layerPerFeatureForPoints, centroidSegmentationPairs = [], pairedSegScopes = /* @__PURE__ */ new Set(), pairedPointScopes = /* @__PURE__ */ new Set() } = props;
|
|
268491
268686
|
const anyLayerHasT = Object.values(images || {}).some((image2) => image2?.image?.instance.hasTStack());
|
|
268492
268687
|
const anyLayerHasZ = Object.values(images || {}).some((image2) => image2?.image?.instance.hasZStack());
|
|
268493
268688
|
const maxT = Object.values(images || {}).reduce((a2, h2) => Math.max(a2, h2?.image?.instance.getNumT()), 1) - 1;
|
|
268494
268689
|
const maxZ = Object.values(images || {}).reduce((a2, h2) => Math.max(a2, h2?.image?.instance.getNumZ()), 1) - 1;
|
|
268495
268690
|
const reversedImageLayerScopes = useMemo$1(() => [...imageLayerScopes || []].reverse(), [imageLayerScopes]);
|
|
268496
|
-
const reversedSegmentationLayerScopes = useMemo$1(() => [...segmentationLayerScopes || []].reverse(), [segmentationLayerScopes]);
|
|
268497
268691
|
const reversedSpotLayerScopes = useMemo$1(() => [...spotLayerScopes || []].reverse(), [spotLayerScopes]);
|
|
268498
|
-
const reversedPointLayerScopes = useMemo$1(() => [...pointLayerScopes || []].reverse(), [pointLayerScopes]);
|
|
268499
|
-
|
|
268692
|
+
const reversedPointLayerScopes = useMemo$1(() => [...pointLayerScopes || []].filter((scope) => !pairedPointScopes.has(scope)).reverse(), [pointLayerScopes, pairedPointScopes]);
|
|
268693
|
+
const reversedSegmentationLayerScopes = useMemo$1(() => [...segmentationLayerScopes || []].filter((scope) => !pairedSegScopes.has(scope)).reverse(), [segmentationLayerScopes, pairedSegScopes]);
|
|
268694
|
+
return jsxs("div", { children: [anyLayerHasZ ? jsx$1(GlobalDimensionSlider, { label: "Z", targetValue: targetZ, setTargetValue: setTargetZ, max: maxZ, spatialRenderingMode, setSpatialRenderingMode }) : null, anyLayerHasT ? jsx$1(GlobalDimensionSlider, { label: "T", targetValue: targetT, setTargetValue: setTargetT, max: maxT }) : null, centroidSegmentationPairs.map(({ pointScope, segScope }) => jsx$1(SegmentationCentroidsController, { theme, segScope, segLayerCoordination: segmentationLayerCoordination, segChannelScopesByLayer: segmentationChannelScopesByLayer, segChannelCoordination: segmentationChannelCoordination, pointScope, pointLayerCoordination }, `combined-${segScope}-${pointScope}`)), pointLayerScopes && reversedPointLayerScopes.map((layerScope) => jsx$1(PointLayerController, { theme, layerScope, layerCoordination: pointLayerCoordination[0][layerScope], setLayerCoordination: pointLayerCoordination[1][layerScope], pointMatrixIndicesData: pointMultiIndicesData?.[layerScope], tiledPointsLoadingProgress, layerPerFeatureForPoints }, layerScope)), spotLayerScopes && reversedSpotLayerScopes.map((layerScope) => jsx$1(SpotLayerController, { theme, layerScope, layerCoordination: spotLayerCoordination[0][layerScope], setLayerCoordination: spotLayerCoordination[1][layerScope] }, layerScope)), segmentationLayerScopes && reversedSegmentationLayerScopes.map((layerScope) => jsx$1(SegmentationLayerController, { theme, layerScope, layerCoordination: segmentationLayerCoordination[0][layerScope], setLayerCoordination: segmentationLayerCoordination[1][layerScope], channelScopes: segmentationChannelScopesByLayer[layerScope], channelCoordination: segmentationChannelCoordination[0][layerScope], setChannelCoordination: segmentationChannelCoordination[1][layerScope] }, layerScope)), imageLayerScopes && reversedImageLayerScopes.map((layerScope) => jsx$1(ImageLayerController, { theme, coordinationScopesRaw, layerScope, layerCoordination: imageLayerCoordination[0][layerScope], setLayerCoordination: imageLayerCoordination[1][layerScope], channelScopes: imageChannelScopesByLayer[layerScope], channelCoordination: imageChannelCoordination[0][layerScope], setChannelCoordination: imageChannelCoordination[1][layerScope], image: images[layerScope]?.image?.instance, featureIndex: images[layerScope]?.featureIndex, targetT, targetZ, spatialRenderingMode, volumeLoadingProgress: volumeLoadingStatus?.loadingProgress, onStopVolumeLoading: volumeLoadingStatus?.onStopLoading, onRestartVolumeLoading: volumeLoadingStatus?.onRestartLoading, volumeStillRef: volumeLoadingStatus?.stillRef }, layerScope))] });
|
|
268500
268695
|
}
|
|
268501
268696
|
function LayerControllerSubscriber(props) {
|
|
268502
|
-
const { coordinationScopes: coordinationScopesRaw, coordinationScopesBy: coordinationScopesByRaw, closeButtonVisible, downloadButtonVisible, removeGridComponent, theme, title: title2 = "Spatial Layers", uuid: uuid2, layerPerFeatureForPoints = false, cameraPresets } = props;
|
|
268697
|
+
const { coordinationScopes: coordinationScopesRaw, coordinationScopesBy: coordinationScopesByRaw, closeButtonVisible, downloadButtonVisible, removeGridComponent, theme, title: title2 = "Spatial Layers", uuid: uuid2, layerPerFeatureForPoints = false, cameraPresets, helpText = ViewHelpMapping.LAYER_CONTROLLER_BETA } = props;
|
|
268503
268698
|
const loaders = useLoaders();
|
|
268504
268699
|
const mergeCoordination = useMergeCoordination();
|
|
268505
268700
|
const coordinationScopes = useCoordinationScopes(coordinationScopesRaw);
|
|
@@ -268587,7 +268782,8 @@ function LayerControllerSubscriber(props) {
|
|
|
268587
268782
|
CoordinationType$1.TOOLTIPS_VISIBLE,
|
|
268588
268783
|
CoordinationType$1.SPATIAL_CHANNEL_LABELS_VISIBLE,
|
|
268589
268784
|
CoordinationType$1.SPATIAL_CHANNEL_LABELS_ORIENTATION,
|
|
268590
|
-
CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE
|
|
268785
|
+
CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE,
|
|
268786
|
+
CoordinationType$1.SPATIAL_CHANNELS_SORT_ORDER
|
|
268591
268787
|
], coordinationScopes, coordinationScopesBy, CoordinationType$1.IMAGE_LAYER);
|
|
268592
268788
|
const imageChannelCoordination = useComplexCoordinationSecondary([
|
|
268593
268789
|
CoordinationType$1.SPATIAL_TARGET_C,
|
|
@@ -268628,6 +268824,40 @@ function LayerControllerSubscriber(props) {
|
|
|
268628
268824
|
CoordinationType$1.TOOLTIP_CROSSHAIRS_VISIBLE,
|
|
268629
268825
|
CoordinationType$1.LEGEND_VISIBLE
|
|
268630
268826
|
], coordinationScopes, coordinationScopesBy, CoordinationType$1.POINT_LAYER);
|
|
268827
|
+
const centroidSegmentationPairs = React__default.useMemo(() => {
|
|
268828
|
+
const pairs = [];
|
|
268829
|
+
const pairedSegScopes = /* @__PURE__ */ new Set();
|
|
268830
|
+
const pairedPointScopes = /* @__PURE__ */ new Set();
|
|
268831
|
+
pointLayerScopes.forEach((pointScope) => {
|
|
268832
|
+
const pointCoord = pointLayerCoordination[0][pointScope];
|
|
268833
|
+
if (!pointCoord)
|
|
268834
|
+
return;
|
|
268835
|
+
const pointObsType = pointCoord[CoordinationType$1.OBS_TYPE];
|
|
268836
|
+
if (!pointObsType)
|
|
268837
|
+
return;
|
|
268838
|
+
const matchingSegScope = segmentationLayerScopes.find((segScope) => {
|
|
268839
|
+
if (pairedSegScopes.has(segScope))
|
|
268840
|
+
return false;
|
|
268841
|
+
const channelScopes = segmentationChannelScopesByLayer[segScope] || [];
|
|
268842
|
+
return channelScopes.some((chanScope) => {
|
|
268843
|
+
const chanCoord = segmentationChannelCoordination[0]?.[segScope]?.[chanScope];
|
|
268844
|
+
return chanCoord?.[CoordinationType$1.OBS_TYPE] === pointObsType;
|
|
268845
|
+
});
|
|
268846
|
+
});
|
|
268847
|
+
if (matchingSegScope) {
|
|
268848
|
+
pairs.push({ pointScope, segScope: matchingSegScope });
|
|
268849
|
+
pairedSegScopes.add(matchingSegScope);
|
|
268850
|
+
pairedPointScopes.add(pointScope);
|
|
268851
|
+
}
|
|
268852
|
+
});
|
|
268853
|
+
return { pairs, pairedSegScopes, pairedPointScopes };
|
|
268854
|
+
}, [
|
|
268855
|
+
pointLayerScopes,
|
|
268856
|
+
pointLayerCoordination,
|
|
268857
|
+
segmentationLayerScopes,
|
|
268858
|
+
segmentationChannelScopesByLayer,
|
|
268859
|
+
segmentationChannelCoordination
|
|
268860
|
+
]);
|
|
268631
268861
|
const [{ volumeLoadingProgress: volumeLoadingStatus, tiledPointsLoadingProgress }] = useAuxiliaryCoordination([
|
|
268632
268862
|
"spatialAcceleratedVolumeLoadingProgress",
|
|
268633
268863
|
"spatialTiledPointsLoadingProgress"
|
|
@@ -268655,7 +268885,7 @@ function LayerControllerSubscriber(props) {
|
|
|
268655
268885
|
imageDataStatus,
|
|
268656
268886
|
pointMultiIndicesDataStatus
|
|
268657
268887
|
]);
|
|
268658
|
-
return jsx$1(TitleInfo, { title: title2, isScroll: true, closeButtonVisible, downloadButtonVisible, removeGridComponent, theme, isReady, errors, children: jsx$1(LayerController, { theme, coordinationScopesRaw, segmentationLayerScopes, segmentationLayerCoordination, segmentationChannelScopesByLayer, segmentationChannelCoordination, images: imageData, imageLayerScopes, imageLayerCoordination, targetT, targetZ, setTargetT, setTargetZ, spatialRenderingMode, setSpatialRenderingMode, imageChannelScopesByLayer, imageChannelCoordination, spotLayerScopes, spotLayerCoordination, pointLayerScopes, pointLayerCoordination, pointMultiIndicesData, layerPerFeatureForPoints, volumeLoadingStatus, tiledPointsLoadingProgress }) });
|
|
268888
|
+
return jsx$1(TitleInfo, { title: title2, isScroll: true, closeButtonVisible, downloadButtonVisible, removeGridComponent, theme, isReady, errors, helpText, children: jsx$1(LayerController, { theme, coordinationScopesRaw, segmentationLayerScopes, segmentationLayerCoordination, segmentationChannelScopesByLayer, segmentationChannelCoordination, images: imageData, imageLayerScopes, imageLayerCoordination, targetT, targetZ, setTargetT, setTargetZ, spatialRenderingMode, setSpatialRenderingMode, imageChannelScopesByLayer, imageChannelCoordination, spotLayerScopes, spotLayerCoordination, pointLayerScopes, pointLayerCoordination, pointMultiIndicesData, layerPerFeatureForPoints, volumeLoadingStatus, tiledPointsLoadingProgress, centroidSegmentationPairs: centroidSegmentationPairs.pairs, pairedSegScopes: centroidSegmentationPairs.pairedSegScopes, pairedPointScopes: centroidSegmentationPairs.pairedPointScopes }) });
|
|
268659
268889
|
}
|
|
268660
268890
|
const isIterable$2 = (obj) => Symbol.iterator in obj;
|
|
268661
268891
|
const hasIterableEntries = (value2) => (
|
|
@@ -270570,7 +270800,7 @@ function HiglassGlobalStyles(props) {
|
|
|
270570
270800
|
}
|
|
270571
270801
|
register({ dataFetcher: ZarrMultivecDataFetcher_default, config: ZarrMultivecDataFetcher_default.config }, { pluginType: "dataFetcher" });
|
|
270572
270802
|
const LazyHiGlassComponent = React__default.lazy(async () => {
|
|
270573
|
-
const { HiGlassComponent } = await import("./higlass-
|
|
270803
|
+
const { HiGlassComponent } = await import("./higlass-CKuPDg4y.js");
|
|
270574
270804
|
return { default: HiGlassComponent };
|
|
270575
270805
|
});
|
|
270576
270806
|
const HG_SIZE = 800;
|
|
@@ -270908,6 +271138,12 @@ const useStyles$5 = makeStyles()(() => ({
|
|
|
270908
271138
|
neuroglancerWrapper: {
|
|
270909
271139
|
position: "relative",
|
|
270910
271140
|
height: "100%"
|
|
271141
|
+
},
|
|
271142
|
+
meshLoadingIndicator: {
|
|
271143
|
+
position: "absolute",
|
|
271144
|
+
bottom: 8,
|
|
271145
|
+
left: 8,
|
|
271146
|
+
zIndex: 50
|
|
270911
271147
|
}
|
|
270912
271148
|
}));
|
|
270913
271149
|
const globalNeuroglancerCss = `
|
|
@@ -272159,13 +272395,16 @@ const globalNeuroglancerStyles = {
|
|
|
272159
272395
|
},
|
|
272160
272396
|
"input.perspective-panel-show-slice-views": { pointerEvents: "all" },
|
|
272161
272397
|
".neuroglancer-rendered-data-panel": {
|
|
272162
|
-
cursor: "
|
|
272398
|
+
cursor: "grab",
|
|
272163
272399
|
position: "relative",
|
|
272164
272400
|
outline: "0",
|
|
272165
272401
|
touchAction: "none",
|
|
272166
272402
|
color: "#fff",
|
|
272167
272403
|
textAlign: "left"
|
|
272168
272404
|
},
|
|
272405
|
+
".neuroglancer-rendered-data-panel:active": {
|
|
272406
|
+
cursor: "grabbing"
|
|
272407
|
+
},
|
|
272169
272408
|
".neuroglancer-display-dimensions-widget": {
|
|
272170
272409
|
position: "absolute",
|
|
272171
272410
|
cursor: "default",
|
|
@@ -273518,7 +273757,7 @@ function NeuroglancerGlobalStyles(props) {
|
|
|
273518
273757
|
const { classes: classes2 } = props;
|
|
273519
273758
|
return jsxs(Fragment, { children: [jsx$1(GlobalStyles$3, { styles: globalNeuroglancerCss }), jsx$1(ScopedGlobalStyles, { styles: globalNeuroglancerStyles, parentClassName: classes2.neuroglancerWrapper })] });
|
|
273520
273759
|
}
|
|
273521
|
-
const LazyReactNeuroglancer = React__default.lazy(() => import("./ReactNeuroglancer-
|
|
273760
|
+
const LazyReactNeuroglancer = React__default.lazy(() => import("./ReactNeuroglancer-C2C-vEVu.js"));
|
|
273522
273761
|
function createWorker() {
|
|
273523
273762
|
const worker = new WorkerFactory$1();
|
|
273524
273763
|
worker.AsyncComputationWorker = WorkerFactory;
|
|
@@ -273563,12 +273802,31 @@ class NeuroglancerComp extends PureComponent {
|
|
|
273563
273802
|
}
|
|
273564
273803
|
};
|
|
273565
273804
|
remapWheelToZoom(viewer.inputEventBindings.perspectiveView);
|
|
273805
|
+
const { getMeshIdToCellId, onViewerReady, cellsUrl } = this.props;
|
|
273566
273806
|
this.prevHoverHandler = () => {
|
|
273567
|
-
|
|
273568
|
-
|
|
273569
|
-
|
|
273807
|
+
const ms = viewer.mouseState;
|
|
273808
|
+
if (ms.pickedAnnotationId != null) {
|
|
273809
|
+
const byIdKey = String(ms.pickedAnnotationId);
|
|
273810
|
+
fetch(`${cellsUrl}/by_id/${byIdKey}`).then((r3) => r3.arrayBuffer()).then((buf) => {
|
|
273811
|
+
const dv = new DataView(buf);
|
|
273812
|
+
const actualMeshId = String(dv.getInt32(12, true));
|
|
273813
|
+
const cellId = getMeshIdToCellId?.(actualMeshId) ?? actualMeshId;
|
|
273814
|
+
this.latestOnSelectHoveredCoords?.(cellId);
|
|
273815
|
+
});
|
|
273816
|
+
return;
|
|
273570
273817
|
}
|
|
273818
|
+
if (ms.pickedValue !== void 0 && ms.pickedValue !== null) {
|
|
273819
|
+
const meshId = String(ms.pickedValue?.low);
|
|
273820
|
+
const cellId = getMeshIdToCellId?.(meshId) ?? meshId;
|
|
273821
|
+
this.latestOnSelectHoveredCoords?.(cellId);
|
|
273822
|
+
return;
|
|
273823
|
+
}
|
|
273824
|
+
this.latestOnSelectHoveredCoords?.(null);
|
|
273571
273825
|
};
|
|
273826
|
+
onViewerReady?.(() => {
|
|
273827
|
+
const panel = [...viewer.display.panels][0];
|
|
273828
|
+
return panel?.projectionParameters?.value_?.viewProjectionMat;
|
|
273829
|
+
});
|
|
273572
273830
|
viewer.mouseState.changed.add(this.prevHoverHandler);
|
|
273573
273831
|
} else {
|
|
273574
273832
|
if (this.prevMouseStateChanged && this.prevHoverHandler) {
|
|
@@ -273589,8 +273847,8 @@ class NeuroglancerComp extends PureComponent {
|
|
|
273589
273847
|
}
|
|
273590
273848
|
}
|
|
273591
273849
|
render() {
|
|
273592
|
-
const { classes: classes2, viewerState, cellColorMapping, onLayerLoadingChange } = this.props;
|
|
273593
|
-
return jsxs(Fragment, { children: [jsx$1(NeuroglancerGlobalStyles, { classes: classes2 }), jsx$1("div", { className: classes2.neuroglancerWrapper, children: jsx$1(Suspense, { fallback: jsx$1("div", { children: "Loading..." }), children: jsx$1(LazyReactNeuroglancer, { brainMapsClientId: "NOT_A_VALID_ID", viewerState, onViewerStateChanged: this.onViewerStateChanged, onLayerLoadingChange, bundleRoot: this.bundleRoot, cellColorMapping, ref: this.onRef }) }) })] });
|
|
273850
|
+
const { classes: classes2, viewerState, cellColorMapping, onLayerLoadingChange, onAnnotationSourceReady, onViewerReady, meshOpacity } = this.props;
|
|
273851
|
+
return jsxs(Fragment, { children: [jsx$1(NeuroglancerGlobalStyles, { classes: classes2 }), jsx$1("div", { className: classes2.neuroglancerWrapper, children: jsx$1(Suspense, { fallback: jsx$1("div", { children: "Loading..." }), children: jsx$1(LazyReactNeuroglancer, { brainMapsClientId: "NOT_A_VALID_ID", viewerState, onViewerStateChanged: this.onViewerStateChanged, onLayerLoadingChange, bundleRoot: this.bundleRoot, cellColorMapping, ref: this.onRef, onAnnotationSourceReady, onViewerReady, meshOpacity }) }) })] });
|
|
273594
273852
|
}
|
|
273595
273853
|
}
|
|
273596
273854
|
function useMemoCustomComparison(factory2, dependencies2, customIsEqual) {
|
|
@@ -273605,17 +273863,22 @@ function useMemoCustomComparison(factory2, dependencies2, customIsEqual) {
|
|
|
273605
273863
|
}
|
|
273606
273864
|
const shallowDiff = (prevDeps, nextDeps, depName) => prevDeps[depName] !== nextDeps[depName];
|
|
273607
273865
|
const shallowDiffByLayer = (prevDeps, nextDeps, depName, scopeName) => prevDeps?.[depName]?.[scopeName] !== nextDeps?.[depName]?.[scopeName];
|
|
273866
|
+
const shallowDiffByChannel = (prevDeps, nextDeps, depName, firstName, secondName) => prevDeps?.[depName]?.[firstName]?.[secondName] !== nextDeps?.[depName]?.[firstName]?.[secondName];
|
|
273608
273867
|
const shallowDiffByChannelWithKeys = (prevDeps, nextDeps, depName, firstName, secondName, keys2) => keys2.some((k) => prevDeps?.[depName]?.[firstName]?.[secondName]?.[k] !== nextDeps?.[depName]?.[firstName]?.[secondName]?.[k]);
|
|
273609
273868
|
const shallowDiffByLayerCoordinationWithKeys = (prevDeps, nextDeps, depName, layerScope, keys2) => keys2.some((k) => prevDeps?.[depName]?.[0]?.[layerScope]?.[k] !== nextDeps?.[depName]?.[0]?.[layerScope]?.[k]);
|
|
273610
273869
|
const shallowDiffByChannelCoordinationWithKeys = (prevDeps, nextDeps, depName, layerScope, channelScope, keys2) => keys2.some((k) => prevDeps?.[depName]?.[0]?.[layerScope]?.[channelScope]?.[k] !== nextDeps?.[depName]?.[0]?.[layerScope]?.[channelScope]?.[k]);
|
|
273611
273870
|
function customIsEqualForCellColors(prevDeps, nextDeps) {
|
|
273612
273871
|
let forceUpdate = false;
|
|
273613
273872
|
const curriedShallowDiff = (depName) => shallowDiff(prevDeps, nextDeps, depName);
|
|
273873
|
+
const curriedShallowDiffByChannel = (depName, firstName, secondName) => shallowDiffByChannel(prevDeps, nextDeps, depName, firstName, secondName);
|
|
273614
273874
|
const curriedShallowDiffByChannelWithKeys = (depName, firstName, secondName, keys2) => shallowDiffByChannelWithKeys(prevDeps, nextDeps, depName, firstName, secondName, keys2);
|
|
273615
273875
|
const curriedShallowDiffByChannelCoordinationWithKeys = (depName, layerScope, channelScope, keys2) => shallowDiffByChannelCoordinationWithKeys(prevDeps, nextDeps, depName, layerScope, channelScope, keys2);
|
|
273616
273876
|
if (curriedShallowDiff("theme")) {
|
|
273617
273877
|
forceUpdate = true;
|
|
273618
273878
|
}
|
|
273879
|
+
if (curriedShallowDiff("csvLoaded")) {
|
|
273880
|
+
forceUpdate = true;
|
|
273881
|
+
}
|
|
273619
273882
|
if (["segmentationLayerScopes", "segmentationChannelScopesByLayer"].some(curriedShallowDiff)) {
|
|
273620
273883
|
forceUpdate = true;
|
|
273621
273884
|
} else {
|
|
@@ -273630,8 +273893,11 @@ function customIsEqualForCellColors(prevDeps, nextDeps) {
|
|
|
273630
273893
|
"obsSetSelection",
|
|
273631
273894
|
"additionalObsSets",
|
|
273632
273895
|
"spatialChannelColor",
|
|
273633
|
-
"spatialChannelOpacity"
|
|
273634
|
-
|
|
273896
|
+
"spatialChannelOpacity",
|
|
273897
|
+
"featureValueColormap",
|
|
273898
|
+
"featureValueColormapRange",
|
|
273899
|
+
"featureSelection"
|
|
273900
|
+
]) || curriedShallowDiffByChannel("segmentationMultiIndicesData", layerScope, channelScope) || curriedShallowDiffByChannel("segmentationMultiExpressionNormData", layerScope, channelScope)) {
|
|
273635
273901
|
forceUpdate = true;
|
|
273636
273902
|
}
|
|
273637
273903
|
});
|
|
@@ -273677,7 +273943,13 @@ function customIsEqualForInitialViewerState(prevDeps, nextDeps) {
|
|
|
273677
273943
|
"featureSelection",
|
|
273678
273944
|
"featureFilterMode",
|
|
273679
273945
|
"featureColor",
|
|
273680
|
-
"spatialPointStrokeWidth"
|
|
273946
|
+
"spatialPointStrokeWidth",
|
|
273947
|
+
"featureValueColormap",
|
|
273948
|
+
"featureValueColormapRange",
|
|
273949
|
+
"featureSelection",
|
|
273950
|
+
"obsSetColor",
|
|
273951
|
+
"obsSetSelection",
|
|
273952
|
+
"additionalObsSets"
|
|
273681
273953
|
]) || Math.abs(prevDeps?.pointLayerCoordination?.[0]?.[layerScope]?.spatialLayerOpacity - nextDeps?.pointLayerCoordination?.[0]?.[layerScope]?.spatialLayerOpacity) >= 0.05) {
|
|
273682
273954
|
forceUpdate = true;
|
|
273683
273955
|
}
|
|
@@ -273731,6 +274003,35 @@ function getSpatialLayerColorWithSelectionShader(staticColor, opacity2, featureI
|
|
|
273731
274003
|
}
|
|
273732
274004
|
`;
|
|
273733
274005
|
}
|
|
274006
|
+
function getObsSetSelectionFilteredShader(phenotypeColors, selectedIndices, opacity2, borderWidth = 0) {
|
|
274007
|
+
const numColors = phenotypeColors.length;
|
|
274008
|
+
const numSelected = selectedIndices.length;
|
|
274009
|
+
const normColors = phenotypeColors.map((c2) => normalizeColor(c2));
|
|
274010
|
+
const colorsDecl = `vec3 phenotypeColors[${numColors}] = vec3[${numColors}](${normColors.map((c2) => toVec3(c2)).join(", ")});`;
|
|
274011
|
+
const selectedDecl = `int selectedIndices[${numSelected}] = int[${numSelected}](${selectedIndices.join(", ")});`;
|
|
274012
|
+
return `
|
|
274013
|
+
void main() {
|
|
274014
|
+
int phenotype = prop_phenotype();
|
|
274015
|
+
${colorsDecl}
|
|
274016
|
+
${selectedDecl}
|
|
274017
|
+
bool isSelected = false;
|
|
274018
|
+
for (int i = 0; i < ${numSelected}; ++i) {
|
|
274019
|
+
if (phenotype == selectedIndices[i]) {
|
|
274020
|
+
isSelected = true;
|
|
274021
|
+
}
|
|
274022
|
+
}
|
|
274023
|
+
if (!isSelected) {
|
|
274024
|
+
discard;
|
|
274025
|
+
}
|
|
274026
|
+
vec3 color = vec3(0.5, 0.5, 0.5);
|
|
274027
|
+
if (phenotype >= 0 && phenotype < ${numColors}) {
|
|
274028
|
+
color = phenotypeColors[phenotype];
|
|
274029
|
+
}
|
|
274030
|
+
setColor(vec4(color, ${opacity2.toFixed(4)}));
|
|
274031
|
+
${borderWidthGlsl(borderWidth)}
|
|
274032
|
+
}
|
|
274033
|
+
`;
|
|
274034
|
+
}
|
|
273734
274035
|
function getSpatialLayerColorFilteredShader(staticColor, opacity2, featureIndices, featureIndexProp, borderWidth = 0) {
|
|
273735
274036
|
const normStatic = normalizeColor(staticColor);
|
|
273736
274037
|
const numFeatures = featureIndices.length;
|
|
@@ -273912,6 +274213,23 @@ function getRandomPerPointShader(opacity2, featureIndexProp, pointIndexProp, bor
|
|
|
273912
274213
|
}
|
|
273913
274214
|
`;
|
|
273914
274215
|
}
|
|
274216
|
+
function getQuantitativeColormapShader(quantitativeColorProp, opacity2, colormap = GLSL_COLORMAP_DEFAULT, colormapRange = [0, 1], borderWidth = 0, quantitativeColorMax = 1) {
|
|
274217
|
+
const [low, high] = colormapRange;
|
|
274218
|
+
const resolvedColormap = GLSL_COLORMAPS.includes(colormap) ? colormap : GLSL_COLORMAP_DEFAULT;
|
|
274219
|
+
return `
|
|
274220
|
+
#define COLORMAP_FUNC ${resolvedColormap}
|
|
274221
|
+
${colormaps$1}
|
|
274222
|
+
void main() {
|
|
274223
|
+
float rawVal = float(prop_${quantitativeColorProp}());
|
|
274224
|
+
float normalizedVal = rawVal / ${quantitativeColorMax.toFixed(4)};
|
|
274225
|
+
float t = (normalizedVal - ${low.toFixed(4)}) / max(${(high - low).toFixed(4)}, 0.0001);
|
|
274226
|
+
t = clamp(t, 0.0, 1.0);
|
|
274227
|
+
vec4 col = COLORMAP_FUNC(t);
|
|
274228
|
+
setColor(vec4(col.rgb, ${opacity2.toFixed(4)}));
|
|
274229
|
+
${borderWidthGlsl(borderWidth)}
|
|
274230
|
+
}
|
|
274231
|
+
`;
|
|
274232
|
+
}
|
|
273915
274233
|
function getRandomPerPointWithSelectionShader(featureIndices, defaultColor, opacity2, featureIndexProp, pointIndexProp, borderWidth = 0) {
|
|
273916
274234
|
const normDefault = normalizeColor(defaultColor);
|
|
273917
274235
|
const numFeatures = featureIndices.length;
|
|
@@ -273967,8 +274285,25 @@ function getRandomPerPointFilteredShader(featureIndices, opacity2, featureIndexP
|
|
|
273967
274285
|
}
|
|
273968
274286
|
`;
|
|
273969
274287
|
}
|
|
274288
|
+
function getObsSetSelectionShader(phenotypeColors, opacity2, borderWidth = 0) {
|
|
274289
|
+
const numColors = phenotypeColors.length;
|
|
274290
|
+
const normColors = phenotypeColors.map((c2) => normalizeColor(c2));
|
|
274291
|
+
const colorsDecl = `vec3 phenotypeColors[${numColors}] = vec3[${numColors}](${normColors.map((c2) => toVec3(c2)).join(", ")});`;
|
|
274292
|
+
return `
|
|
274293
|
+
void main() {
|
|
274294
|
+
int phenotype = prop_phenotype();
|
|
274295
|
+
${colorsDecl}
|
|
274296
|
+
vec3 color = ${toVec3(normalizeColor([128, 128, 128]))};
|
|
274297
|
+
if (phenotype >= 0 && phenotype < ${numColors}) {
|
|
274298
|
+
color = phenotypeColors[phenotype];
|
|
274299
|
+
}
|
|
274300
|
+
setColor(vec4(color, ${opacity2.toFixed(4)}));
|
|
274301
|
+
${borderWidthGlsl(borderWidth)}
|
|
274302
|
+
}
|
|
274303
|
+
`;
|
|
274304
|
+
}
|
|
273970
274305
|
function getPointsShader(layerCoordination) {
|
|
273971
|
-
const { theme, featureIndex, spatialLayerOpacity, obsColorEncoding, spatialLayerColor, featureSelection, featureFilterMode, featureColor, pointMarkerBorderWidth = 0, featureIndexProp, pointIndexProp } = layerCoordination;
|
|
274306
|
+
const { theme, featureIndex, spatialLayerOpacity, obsColorEncoding, spatialLayerColor, featureSelection, featureFilterMode, featureColor, pointMarkerBorderWidth = 0, featureIndexProp, pointIndexProp, quantitativeColorProp, featureValueColormap, featureValueColormapRange, obsSetColor, obsSetSelection, quantitativeColorMax, pointsAreSegmentationCentroids } = layerCoordination;
|
|
273972
274307
|
const defaultColor = getDefaultColor(theme);
|
|
273973
274308
|
const opacity2 = spatialLayerOpacity ?? 1;
|
|
273974
274309
|
const staticColor = Array.isArray(spatialLayerColor) && spatialLayerColor.length === 3 ? spatialLayerColor : defaultColor;
|
|
@@ -273992,7 +274327,7 @@ function getPointsShader(layerCoordination) {
|
|
|
273992
274327
|
}
|
|
273993
274328
|
return getSpatialLayerColorWithSelectionShader(staticColor, opacity2, featureIndices, defaultColor, featureIndexProp, pointMarkerBorderWidth);
|
|
273994
274329
|
}
|
|
273995
|
-
if (obsColorEncoding === "geneSelection") {
|
|
274330
|
+
if (obsColorEncoding === "geneSelection" && !pointsAreSegmentationCentroids) {
|
|
273996
274331
|
if (!featureIndexProp) {
|
|
273997
274332
|
throw new Error("In order to use gene-based color encoding for Neuroglancer Points, options.featureIndexProp must be specified for the obsPoints.ng-annotations fileType in the Vitessce configuration.");
|
|
273998
274333
|
}
|
|
@@ -274028,19 +274363,49 @@ function getPointsShader(layerCoordination) {
|
|
|
274028
274363
|
}
|
|
274029
274364
|
return getRandomPerPointWithSelectionShader(featureIndices, defaultColor, opacity2, featureIndexProp, pointIndexProp, pointMarkerBorderWidth);
|
|
274030
274365
|
}
|
|
274366
|
+
if (obsColorEncoding === "geneSelection" && pointsAreSegmentationCentroids) {
|
|
274367
|
+
if (!quantitativeColorProp) {
|
|
274368
|
+
console.warn("In order to use quantitative colormap encoding for Neuroglancer Points, options.quantitativeColorProp must be specified for the obsPoints.ng-annotations fileType in the Vitessce configuration. Falling back to static color.");
|
|
274369
|
+
return getSpatialLayerColorShader(staticColor, opacity2, pointMarkerBorderWidth);
|
|
274370
|
+
}
|
|
274371
|
+
return getQuantitativeColormapShader(quantitativeColorProp, opacity2, featureValueColormap, featureValueColormapRange, pointMarkerBorderWidth, quantitativeColorMax);
|
|
274372
|
+
}
|
|
274373
|
+
if (obsColorEncoding === "cellSetSelection") {
|
|
274374
|
+
if (!obsSetColor || !obsSetSelection) {
|
|
274375
|
+
return getSpatialLayerColorShader(staticColor, opacity2, pointMarkerBorderWidth);
|
|
274376
|
+
}
|
|
274377
|
+
const colorByName = {};
|
|
274378
|
+
obsSetColor?.forEach(({ path: path2, color: color2 }) => {
|
|
274379
|
+
if (path2?.length > 1) {
|
|
274380
|
+
colorByName[path2[path2.length - 1]] = color2;
|
|
274381
|
+
}
|
|
274382
|
+
});
|
|
274383
|
+
const uniqueNames = Object.keys(colorByName).sort();
|
|
274384
|
+
const phenotypeColors = uniqueNames.map((name2) => colorByName[name2] ?? defaultColor);
|
|
274385
|
+
if (isFiltered) {
|
|
274386
|
+
const selectedNames = new Set(obsSetSelection?.map((path2) => path2[path2.length - 1]) ?? []);
|
|
274387
|
+
const selectedIndices = uniqueNames.map((name2, idx) => selectedNames.has(name2) ? idx : -1).filter((idx) => idx >= 0);
|
|
274388
|
+
if (selectedIndices.length === 0) {
|
|
274389
|
+
return "void main() { discard; }";
|
|
274390
|
+
}
|
|
274391
|
+
return getObsSetSelectionFilteredShader(phenotypeColors, selectedIndices, opacity2, pointMarkerBorderWidth);
|
|
274392
|
+
}
|
|
274393
|
+
return getObsSetSelectionShader(phenotypeColors, opacity2, pointMarkerBorderWidth);
|
|
274394
|
+
}
|
|
274031
274395
|
return getSpatialLayerColorShader(staticColor, opacity2, pointMarkerBorderWidth);
|
|
274032
274396
|
}
|
|
274397
|
+
const DEFAULT_NG_DIMENSIONS = {
|
|
274398
|
+
x: [1, "nm"],
|
|
274399
|
+
y: [1, "nm"],
|
|
274400
|
+
z: [1, "nm"]
|
|
274401
|
+
};
|
|
274033
274402
|
const DEFAULT_NG_PROPS = {
|
|
274034
274403
|
layout: "3d",
|
|
274035
274404
|
position: [0, 0, 0],
|
|
274036
274405
|
projectionOrientation: [0, 0, 0, 1],
|
|
274037
274406
|
projectionScale: 1024,
|
|
274038
274407
|
crossSectionScale: 1,
|
|
274039
|
-
dimensions:
|
|
274040
|
-
x: [1, "nm"],
|
|
274041
|
-
y: [1, "nm"],
|
|
274042
|
-
z: [1, "nm"]
|
|
274043
|
-
},
|
|
274408
|
+
dimensions: DEFAULT_NG_DIMENSIONS,
|
|
274044
274409
|
layers: []
|
|
274045
274410
|
};
|
|
274046
274411
|
function toPrecomputedSource(url) {
|
|
@@ -274058,6 +274423,15 @@ function toNgLayerName(dataType, layerScope, channelScope = null) {
|
|
|
274058
274423
|
}
|
|
274059
274424
|
throw new Error(`Unsupported data type: ${dataType}`);
|
|
274060
274425
|
}
|
|
274426
|
+
function pointsHaveMatchingSegmentation({ pointObsType, segmentationLayerScopes, segmentationChannelScopesByLayer, segmentationChannelCoordination }) {
|
|
274427
|
+
return segmentationLayerScopes.some((segmentationLayerScope) => {
|
|
274428
|
+
const segmentationChannelScopes = segmentationChannelScopesByLayer?.[segmentationLayerScope] || [];
|
|
274429
|
+
return segmentationChannelScopes.some((segmentationChannelScope) => {
|
|
274430
|
+
const segmentationObsType = segmentationChannelCoordination?.[0]?.[segmentationLayerScope]?.[segmentationChannelScope]?.obsType;
|
|
274431
|
+
return segmentationObsType && pointObsType && segmentationObsType === pointObsType;
|
|
274432
|
+
});
|
|
274433
|
+
});
|
|
274434
|
+
}
|
|
274061
274435
|
function useNeuroglancerViewerState(theme, showAxisLines, segmentationLayerScopes, segmentationChannelScopesByLayer, segmentationLayerCoordination, segmentationChannelCoordination, obsSegmentationsUrls, obsSegmentationsData, pointLayerScopes, pointLayerCoordination, obsPointsUrls, obsPointsData, pointMultiIndicesData) {
|
|
274062
274436
|
const viewerState = useMemoCustomComparison(() => {
|
|
274063
274437
|
let result = cloneDeep$1(DEFAULT_NG_PROPS);
|
|
@@ -274080,6 +274454,9 @@ function useNeuroglancerViewerState(theme, showAxisLines, segmentationLayerScope
|
|
|
274080
274454
|
} : toPrecomputedSource(layerUrl);
|
|
274081
274455
|
result = {
|
|
274082
274456
|
...result,
|
|
274457
|
+
showAxisLines,
|
|
274458
|
+
showDefaultAnnotations: false,
|
|
274459
|
+
// this removes the yellow box around pointsLayer
|
|
274083
274460
|
layers: [
|
|
274084
274461
|
...result.layers,
|
|
274085
274462
|
{
|
|
@@ -274103,9 +274480,27 @@ function useNeuroglancerViewerState(theme, showAxisLines, segmentationLayerScope
|
|
|
274103
274480
|
const layerCoordination = pointLayerCoordination[0][layerScope];
|
|
274104
274481
|
const layerData = obsPointsData[layerScope];
|
|
274105
274482
|
const layerUrl = obsPointsUrls[layerScope]?.[0]?.url;
|
|
274483
|
+
const ngOptions = layerData?.neuroglancerOptions;
|
|
274484
|
+
if (ngOptions?.transform?.matrix && ngOptions?.transform?.outputDimensions) {
|
|
274485
|
+
result = {
|
|
274486
|
+
...result,
|
|
274487
|
+
dimensions: ngOptions.transform.outputDimensions ?? DEFAULT_NG_DIMENSIONS
|
|
274488
|
+
};
|
|
274489
|
+
}
|
|
274490
|
+
const pointsAreSegmentationCentroids = pointsHaveMatchingSegmentation({
|
|
274491
|
+
pointObsType: layerCoordination?.obsType,
|
|
274492
|
+
segmentationLayerScopes,
|
|
274493
|
+
segmentationChannelScopesByLayer,
|
|
274494
|
+
segmentationChannelCoordination
|
|
274495
|
+
});
|
|
274106
274496
|
const featureIndex = pointMultiIndicesData[layerScope]?.featureIndex;
|
|
274107
274497
|
if (layerUrl && layerData) {
|
|
274108
|
-
const { spatialLayerVisible, spatialLayerOpacity, obsColorEncoding, spatialLayerColor, featureSelection, featureFilterMode, featureColor, spatialPointStrokeWidth } = layerCoordination || {};
|
|
274498
|
+
const { spatialLayerVisible, spatialLayerOpacity, obsColorEncoding, spatialLayerColor, featureSelection, featureFilterMode, featureColor, spatialPointStrokeWidth, featureValueColormap, featureValueColormapRange } = layerCoordination || {};
|
|
274499
|
+
const quantitativeColorMax = layerData.neuroglancerOptions?.quantitativeColorMax;
|
|
274500
|
+
if (!quantitativeColorMax && obsColorEncoding === "geneSelection") {
|
|
274501
|
+
console.warn("quantitativeColorMax not specified in options — defaulting to 1.0 (no normalization)");
|
|
274502
|
+
}
|
|
274503
|
+
const quantitativeColorMaxSelected = quantitativeColorMax ?? 1;
|
|
274109
274504
|
const shader = getPointsShader({
|
|
274110
274505
|
theme,
|
|
274111
274506
|
featureIndex,
|
|
@@ -274115,9 +274510,18 @@ function useNeuroglancerViewerState(theme, showAxisLines, segmentationLayerScope
|
|
|
274115
274510
|
featureSelection,
|
|
274116
274511
|
featureFilterMode,
|
|
274117
274512
|
featureColor,
|
|
274513
|
+
featureValueColormap,
|
|
274514
|
+
featureValueColormapRange,
|
|
274118
274515
|
featureIndexProp: layerData.neuroglancerOptions?.featureIndexProp,
|
|
274119
274516
|
pointIndexProp: layerData.neuroglancerOptions?.pointIndexProp,
|
|
274120
|
-
|
|
274517
|
+
quantitativeColorProp: layerData.neuroglancerOptions?.quantitativeColorProp,
|
|
274518
|
+
pointMarkerBorderWidth: spatialPointStrokeWidth ?? 0,
|
|
274519
|
+
obsSets: layerCoordination.obsSets,
|
|
274520
|
+
obsSetColor: layerCoordination.obsSetColor,
|
|
274521
|
+
obsSetSelection: layerCoordination.obsSetSelection,
|
|
274522
|
+
additionalObsSets: layerCoordination.additionalObsSets,
|
|
274523
|
+
quantitativeColorMax: quantitativeColorMaxSelected,
|
|
274524
|
+
pointsAreSegmentationCentroids
|
|
274121
274525
|
});
|
|
274122
274526
|
result = {
|
|
274123
274527
|
...result,
|
|
@@ -274130,7 +274534,13 @@ function useNeuroglancerViewerState(theme, showAxisLines, segmentationLayerScope
|
|
|
274130
274534
|
subsources: {
|
|
274131
274535
|
default: true
|
|
274132
274536
|
},
|
|
274133
|
-
enableDefaultSubsources: false
|
|
274537
|
+
enableDefaultSubsources: false,
|
|
274538
|
+
...ngOptions?.transform?.matrix ? {
|
|
274539
|
+
transform: {
|
|
274540
|
+
matrix: ngOptions.transform.matrix,
|
|
274541
|
+
outputDimensions: ngOptions.transform?.outputDimensions ?? result.dimensions
|
|
274542
|
+
}
|
|
274543
|
+
} : {}
|
|
274134
274544
|
},
|
|
274135
274545
|
tab: "annotations",
|
|
274136
274546
|
shader,
|
|
@@ -274138,7 +274548,7 @@ function useNeuroglancerViewerState(theme, showAxisLines, segmentationLayerScope
|
|
|
274138
274548
|
visible: spatialLayerVisible,
|
|
274139
274549
|
// Options from layerData.neuroglancerOptions
|
|
274140
274550
|
// like projectionAnnotationSpacing:
|
|
274141
|
-
projectionAnnotationSpacing:
|
|
274551
|
+
projectionAnnotationSpacing: ngOptions?.projectionAnnotationSpacing ?? 1
|
|
274142
274552
|
}
|
|
274143
274553
|
],
|
|
274144
274554
|
// TODO: is this needed?
|
|
@@ -274169,6 +274579,8 @@ function useNeuroglancerViewerState(theme, showAxisLines, segmentationLayerScope
|
|
|
274169
274579
|
}, customIsEqualForInitialViewerState);
|
|
274170
274580
|
return viewerState;
|
|
274171
274581
|
}
|
|
274582
|
+
const ANNOTATION_HEADER_OFFSET = 8;
|
|
274583
|
+
const GREY_HEX = "#323232";
|
|
274172
274584
|
const EPSILON_KEYS_MAPPING_NG = {
|
|
274173
274585
|
projectionScale: 100,
|
|
274174
274586
|
projectionOrientation: 0.02,
|
|
@@ -274189,6 +274601,17 @@ const multiplyQuat = (a2, b2) => {
|
|
|
274189
274601
|
const conjQuat = (q) => [-q[0], -q[1], -q[2], q[3]];
|
|
274190
274602
|
const rad2deg = (r3) => r3 * 180 / Math.PI;
|
|
274191
274603
|
const deg2rad = (d) => d * Math.PI / 180;
|
|
274604
|
+
function applyColormap(colormap, t4) {
|
|
274605
|
+
const tClamped = Math.max(0, Math.min(1, t4));
|
|
274606
|
+
const interpolators = {
|
|
274607
|
+
plasma: interpolatePlasma,
|
|
274608
|
+
viridis: interpolateViridis,
|
|
274609
|
+
jet: interpolateJet,
|
|
274610
|
+
greys: interpolateGreys
|
|
274611
|
+
};
|
|
274612
|
+
const fn2 = interpolators[colormap] ?? interpolateViridis;
|
|
274613
|
+
return fn2(tClamped);
|
|
274614
|
+
}
|
|
274192
274615
|
function valueGreaterThanEpsilon(a2, b2, epsilon3) {
|
|
274193
274616
|
if (Array.isArray(a2) && Array.isArray(b2) && a2.length === b2.length) {
|
|
274194
274617
|
return a2.some((val, i2) => Math.abs(val - b2[i2]) > epsilon3);
|
|
@@ -274255,13 +274678,57 @@ function makeVitNgZoomCalibrator(initialNgProjectionScale, initialDeckZoom = 0)
|
|
|
274255
274678
|
}
|
|
274256
274679
|
};
|
|
274257
274680
|
}
|
|
274681
|
+
function parseAnnotationChunkSegmentsWithPositions(buffer2, serializer2) {
|
|
274682
|
+
const dv = new DataView(buffer2);
|
|
274683
|
+
if (buffer2.byteLength <= 8)
|
|
274684
|
+
return [];
|
|
274685
|
+
const count2 = dv.getUint32(0, true);
|
|
274686
|
+
if (count2 === 0)
|
|
274687
|
+
return [];
|
|
274688
|
+
const numBytes = serializer2.serializedBytes;
|
|
274689
|
+
const properties2 = [null, null, null, null, null];
|
|
274690
|
+
const results = [];
|
|
274691
|
+
for (let i2 = 0; i2 < count2; i2++) {
|
|
274692
|
+
serializer2.deserialize(dv, ANNOTATION_HEADER_OFFSET, i2, count2, true, properties2);
|
|
274693
|
+
const phenotype = properties2[0];
|
|
274694
|
+
const segId = properties2[1];
|
|
274695
|
+
if (segId > 0) {
|
|
274696
|
+
const propBase = ANNOTATION_HEADER_OFFSET + i2 * numBytes;
|
|
274697
|
+
const x2 = dv.getFloat32(propBase + 0, true);
|
|
274698
|
+
const y2 = dv.getFloat32(propBase + 4, true);
|
|
274699
|
+
const z2 = dv.getFloat32(propBase + 8, true);
|
|
274700
|
+
if (x2 !== 0 || y2 !== 0 || z2 !== 0) {
|
|
274701
|
+
results.push({
|
|
274702
|
+
id: String(segId),
|
|
274703
|
+
// mesh segment ID - use for segments array
|
|
274704
|
+
phenotype: Number(phenotype),
|
|
274705
|
+
x: x2,
|
|
274706
|
+
y: y2,
|
|
274707
|
+
z: z2
|
|
274708
|
+
});
|
|
274709
|
+
}
|
|
274710
|
+
}
|
|
274711
|
+
}
|
|
274712
|
+
return results;
|
|
274713
|
+
}
|
|
274714
|
+
const remapCellColors = (ngCellColors, cellIdToMeshIdRef) => {
|
|
274715
|
+
const remapped = {};
|
|
274716
|
+
Object.entries(ngCellColors).forEach(([cellId, color2]) => {
|
|
274717
|
+
const meshId = cellIdToMeshIdRef.current[cellId] ?? cellId;
|
|
274718
|
+
remapped[meshId] = color2;
|
|
274719
|
+
});
|
|
274720
|
+
return remapped;
|
|
274721
|
+
};
|
|
274258
274722
|
const VITESSCE_INTERACTION_DELAY = 50;
|
|
274259
274723
|
const INIT_VIT_ZOOM = -3.6;
|
|
274260
274724
|
const ZOOM_EPS = 0.01;
|
|
274261
274725
|
const ROTATION_EPS = 1e-3;
|
|
274262
274726
|
const TARGET_EPS = 0.5;
|
|
274263
274727
|
const NG_ROT_COOLDOWN_MS = 120;
|
|
274728
|
+
const MESH_LOAD_THRESHOLD = 100;
|
|
274729
|
+
const MESH_LOADING_OVERLAY_TIMEOUT = 1500;
|
|
274264
274730
|
const GUIDE_URL = "https://vitessce.io/docs/ng-guide/";
|
|
274731
|
+
const MESH_OPACITY = 0.6;
|
|
274265
274732
|
const LAST_INTERACTION_SOURCE = {
|
|
274266
274733
|
vitessce: "vitessce",
|
|
274267
274734
|
neuroglancer: "neuroglancer"
|
|
@@ -274278,10 +274745,11 @@ function NeuroglancerSubscriber(props) {
|
|
|
274278
274745
|
downloadButtonVisible,
|
|
274279
274746
|
removeGridComponent,
|
|
274280
274747
|
theme,
|
|
274281
|
-
showAxisLines =
|
|
274748
|
+
showAxisLines = true,
|
|
274282
274749
|
title: title2 = "Spatial",
|
|
274283
274750
|
subtitle = "Powered by Neuroglancer",
|
|
274284
274751
|
helpText = ViewHelpMapping.NEUROGLANCER,
|
|
274752
|
+
meshLoadProjectionScaleThreshold,
|
|
274285
274753
|
// Note: this is a temporary mechanism
|
|
274286
274754
|
// to pass an initial NG camera state.
|
|
274287
274755
|
// Ideally, all camera state should be passed via
|
|
@@ -274292,6 +274760,32 @@ function NeuroglancerSubscriber(props) {
|
|
|
274292
274760
|
} = props;
|
|
274293
274761
|
const loaders = useLoaders();
|
|
274294
274762
|
const mergeCoordination = useMergeCoordination();
|
|
274763
|
+
const { classes: classes2 } = useStyles$5();
|
|
274764
|
+
const initialRotationPushedRef = useRef(false);
|
|
274765
|
+
const getViewProjectionMatRef = useRef(null);
|
|
274766
|
+
const obsIdToMeshIdRef = useRef({});
|
|
274767
|
+
const meshIdToCellIdRef = useRef({});
|
|
274768
|
+
const cellIdToMeshIdRef = useRef({});
|
|
274769
|
+
const ngRotPushAtRef = useRef(0);
|
|
274770
|
+
const lastInteractionSource = useRef(null);
|
|
274771
|
+
const applyNgUpdateTimeoutRef = useRef(null);
|
|
274772
|
+
const lastNgPushOrientationRef = useRef(null);
|
|
274773
|
+
const initialRenderCalibratorRef = useRef(null);
|
|
274774
|
+
const translationOffsetRef = useRef([0, 0, 0]);
|
|
274775
|
+
const zoomRafRef = useRef(null);
|
|
274776
|
+
const lastNgQuatRef = useRef([0, 0, 0, 1]);
|
|
274777
|
+
const lastNgScaleRef = useRef(null);
|
|
274778
|
+
const annotationInfoRef = useRef(null);
|
|
274779
|
+
const annotationTransformRef = useRef(null);
|
|
274780
|
+
const visibleSegmentIdsRef = useRef(null);
|
|
274781
|
+
const chunkCacheRef = useRef(/* @__PURE__ */ new Map());
|
|
274782
|
+
const resizeObserverRef = useRef(null);
|
|
274783
|
+
const [isLayersLoaded, setIsLayersLoaded] = useState(false);
|
|
274784
|
+
const [isMeshLoading, setIsMeshLoading] = useState(false);
|
|
274785
|
+
const [annotationReady, setAnnotationReady] = useState(false);
|
|
274786
|
+
const [csvLoaded, setCsvLoaded] = useState(false);
|
|
274787
|
+
const updateVisibleSegmentsThrottledRef = useRef(null);
|
|
274788
|
+
const viewportSizeRef = useRef({ width: 0, height: 0 });
|
|
274295
274789
|
const coordinationScopes = useCoordinationScopes(coordinationScopesRaw);
|
|
274296
274790
|
const coordinationScopesBy = useCoordinationScopesBy(coordinationScopes, coordinationScopesByRaw);
|
|
274297
274791
|
const [{
|
|
@@ -274323,6 +274817,19 @@ function NeuroglancerSubscriber(props) {
|
|
|
274323
274817
|
setSpatialRotationOrbit: setRotationOrbit,
|
|
274324
274818
|
setSpatialZoom: setZoom
|
|
274325
274819
|
}] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.NEUROGLANCER], coordinationScopes);
|
|
274820
|
+
const csvUrlRef = useRef(null);
|
|
274821
|
+
const csvUrl = useMemo$1(() => {
|
|
274822
|
+
if (csvUrlRef.current)
|
|
274823
|
+
return csvUrlRef.current;
|
|
274824
|
+
const obsSetsMap = loaders?.[dataset]?.loaders?.obsSets;
|
|
274825
|
+
if (!obsSetsMap)
|
|
274826
|
+
return null;
|
|
274827
|
+
const firstLoader = obsSetsMap.values().next().value;
|
|
274828
|
+
const url = firstLoader?.url ?? null;
|
|
274829
|
+
if (url)
|
|
274830
|
+
csvUrlRef.current = url;
|
|
274831
|
+
return url;
|
|
274832
|
+
}, [loaders, dataset]);
|
|
274326
274833
|
const [ngWidth, ngHeight, containerRef] = useGridItemSize();
|
|
274327
274834
|
const [segmentationLayerScopes, segmentationChannelScopesByLayer] = useMultiCoordinationScopesSecondaryNonNull(CoordinationType$1.SEGMENTATION_CHANNEL, CoordinationType$1.SEGMENTATION_LAYER, coordinationScopes, coordinationScopesBy);
|
|
274328
274835
|
const pointLayerScopes = useMultiCoordinationScopesNonNull(CoordinationType$1.POINT_LAYER, coordinationScopes);
|
|
@@ -274351,7 +274858,9 @@ function NeuroglancerSubscriber(props) {
|
|
|
274351
274858
|
CoordinationType$1.OBS_HIGHLIGHT,
|
|
274352
274859
|
CoordinationType$1.TOOLTIPS_VISIBLE,
|
|
274353
274860
|
CoordinationType$1.TOOLTIP_CROSSHAIRS_VISIBLE,
|
|
274354
|
-
CoordinationType$1.LEGEND_VISIBLE
|
|
274861
|
+
CoordinationType$1.LEGEND_VISIBLE,
|
|
274862
|
+
CoordinationType$1.FEATURE_TYPE,
|
|
274863
|
+
CoordinationType$1.FEATURE_VALUE_TYPE
|
|
274355
274864
|
], coordinationScopes, coordinationScopesBy, CoordinationType$1.SEGMENTATION_LAYER, CoordinationType$1.SEGMENTATION_CHANNEL);
|
|
274356
274865
|
const pointLayerCoordination = useComplexCoordination([
|
|
274357
274866
|
CoordinationType$1.OBS_TYPE,
|
|
@@ -274368,7 +274877,10 @@ function NeuroglancerSubscriber(props) {
|
|
|
274368
274877
|
CoordinationType$1.TOOLTIPS_VISIBLE,
|
|
274369
274878
|
CoordinationType$1.TOOLTIP_CROSSHAIRS_VISIBLE,
|
|
274370
274879
|
CoordinationType$1.LEGEND_VISIBLE,
|
|
274371
|
-
CoordinationType$1.SPATIAL_POINT_STROKE_WIDTH
|
|
274880
|
+
CoordinationType$1.SPATIAL_POINT_STROKE_WIDTH,
|
|
274881
|
+
CoordinationType$1.OBS_SET_COLOR,
|
|
274882
|
+
CoordinationType$1.OBS_SET_SELECTION,
|
|
274883
|
+
CoordinationType$1.ADDITIONAL_OBS_SETS
|
|
274372
274884
|
], coordinationScopes, coordinationScopesBy, CoordinationType$1.POINT_LAYER);
|
|
274373
274885
|
const [obsPointsData, obsPointsDataStatus, obsPointsUrls, obsPointsErrors] = useMultiObsPoints(coordinationScopes, coordinationScopesBy, loaders, dataset, mergeCoordination, uuid2);
|
|
274374
274886
|
const [pointMultiIndicesData, pointMultiIndicesDataStatus, pointMultiIndicesDataErrors] = usePointMultiObsFeatureMatrixIndices(coordinationScopes, coordinationScopesBy, loaders, dataset);
|
|
@@ -274394,34 +274906,89 @@ function NeuroglancerSubscriber(props) {
|
|
|
274394
274906
|
segmentationMultiFeatureSelectionStatus,
|
|
274395
274907
|
segmentationMultiIndicesDataStatus
|
|
274396
274908
|
]);
|
|
274397
|
-
const
|
|
274909
|
+
const lastVitessceRotationRef = useRef({
|
|
274910
|
+
x: spatialRotationX,
|
|
274911
|
+
y: spatialRotationY,
|
|
274912
|
+
z: spatialRotationZ,
|
|
274913
|
+
orbit: spatialRotationOrbit
|
|
274914
|
+
});
|
|
274915
|
+
const prevCoordsRef = useRef({
|
|
274916
|
+
zoom: spatialZoom,
|
|
274917
|
+
rx: spatialRotationX,
|
|
274918
|
+
ry: spatialRotationY,
|
|
274919
|
+
rz: spatialRotationZ,
|
|
274920
|
+
orbit: spatialRotationOrbit,
|
|
274921
|
+
tx: spatialTargetX,
|
|
274922
|
+
ty: spatialTargetY
|
|
274923
|
+
});
|
|
274398
274924
|
const segmentationColorMapping = useMemoCustomComparison(() => {
|
|
274399
274925
|
const result = {};
|
|
274400
274926
|
segmentationLayerScopes?.forEach((layerScope) => {
|
|
274401
274927
|
result[layerScope] = {};
|
|
274402
274928
|
segmentationChannelScopesByLayer?.[layerScope]?.forEach((channelScope) => {
|
|
274403
|
-
const { obsSets: layerSets, obsIndex:
|
|
274404
|
-
const
|
|
274929
|
+
const { obsSets: layerSets, obsIndex: layerIndexFromSets } = obsSegmentationsSetsData?.[layerScope]?.[channelScope] || {};
|
|
274930
|
+
const layerIndex = layerIndexFromSets ?? null;
|
|
274931
|
+
const { obsSetColor, obsColorEncoding, obsSetSelection, additionalObsSets, spatialChannelColor, spatialChannelOpacity, featureValueColormap, featureValueColormapRange } = segmentationChannelCoordination[0][layerScope][channelScope];
|
|
274405
274932
|
if (obsColorEncoding === "spatialChannelColor") {
|
|
274406
|
-
if (
|
|
274933
|
+
if (spatialChannelColor) {
|
|
274407
274934
|
const hex2 = rgbToHex$1(spatialChannelColor);
|
|
274408
274935
|
const ngCellColors = {};
|
|
274409
|
-
if (
|
|
274410
|
-
|
|
274411
|
-
|
|
274412
|
-
|
|
274413
|
-
|
|
274414
|
-
|
|
274415
|
-
|
|
274416
|
-
|
|
274417
|
-
|
|
274418
|
-
|
|
274936
|
+
if (layerIndex) {
|
|
274937
|
+
if (obsSetSelection?.length > 0) {
|
|
274938
|
+
const mergedCellSets = mergeObsSets(layerSets, additionalObsSets);
|
|
274939
|
+
const selectedIds = /* @__PURE__ */ new Set();
|
|
274940
|
+
obsSetSelection.forEach((setPath) => {
|
|
274941
|
+
const rootNode = mergedCellSets?.tree?.find((n3) => n3.name === setPath[0]);
|
|
274942
|
+
const leafNode = setPath.length > 1 ? rootNode?.children?.find((n3) => n3.name === setPath[1]) : rootNode;
|
|
274943
|
+
leafNode?.set?.forEach(([id2]) => selectedIds.add(String(id2)));
|
|
274944
|
+
});
|
|
274945
|
+
layerIndex.forEach((id2) => {
|
|
274946
|
+
if (selectedIds.has(String(id2))) {
|
|
274947
|
+
ngCellColors[id2] = hex2;
|
|
274948
|
+
}
|
|
274949
|
+
});
|
|
274950
|
+
} else {
|
|
274951
|
+
layerIndex.forEach((id2) => {
|
|
274419
274952
|
ngCellColors[id2] = hex2;
|
|
274420
|
-
}
|
|
274421
|
-
}
|
|
274953
|
+
});
|
|
274954
|
+
}
|
|
274422
274955
|
}
|
|
274423
|
-
result[layerScope][channelScope] = ngCellColors;
|
|
274956
|
+
result[layerScope][channelScope] = remapCellColors(ngCellColors, cellIdToMeshIdRef);
|
|
274957
|
+
result[layerScope].opacity = spatialChannelOpacity ?? 1;
|
|
274958
|
+
result[layerScope].defaultColor = hex2;
|
|
274959
|
+
}
|
|
274960
|
+
} else if (obsColorEncoding === "geneSelection") {
|
|
274961
|
+
const instanceObsIndex = obsSegmentationsSetsData?.[layerScope]?.[channelScope]?.obsIndex;
|
|
274962
|
+
const matrixObsIndex = segmentationMultiIndicesData?.[layerScope]?.[channelScope]?.obsIndex;
|
|
274963
|
+
const expressionData = segmentationMultiExpressionNormData?.[layerScope]?.[channelScope];
|
|
274964
|
+
if (instanceObsIndex && matrixObsIndex && expressionData?.[0]) {
|
|
274965
|
+
const matrixIndexMap = new Map(matrixObsIndex.map((key2, i2) => {
|
|
274966
|
+
const normalizedKey = key2.replace(/^.*_/, "");
|
|
274967
|
+
return [normalizedKey, i2];
|
|
274968
|
+
}));
|
|
274969
|
+
const toMatrixIndex = instanceObsIndex.map((key2) => matrixIndexMap.get(String(key2)));
|
|
274970
|
+
const [low, high] = featureValueColormapRange ?? [0, 1];
|
|
274971
|
+
const ngCellColors = {};
|
|
274972
|
+
instanceObsIndex.forEach((id2, i2) => {
|
|
274973
|
+
const rowIndex = toMatrixIndex[i2];
|
|
274974
|
+
const rawVal = expressionData[0][rowIndex] ?? 0;
|
|
274975
|
+
const t4 = rawVal / 255;
|
|
274976
|
+
const tScaled = (t4 - low) / Math.max(high - low, 1e-4);
|
|
274977
|
+
const tClamped = Math.max(0, Math.min(1, tScaled));
|
|
274978
|
+
const color2 = applyColormap(featureValueColormap ?? "viridis", tClamped);
|
|
274979
|
+
ngCellColors[id2] = rgbToHex$1(color2);
|
|
274980
|
+
});
|
|
274981
|
+
result[layerScope][channelScope] = remapCellColors(ngCellColors, cellIdToMeshIdRef);
|
|
274982
|
+
result[layerScope].opacity = spatialChannelOpacity ?? 1;
|
|
274983
|
+
} else if (instanceObsIndex) {
|
|
274984
|
+
const fallbackColor = spatialChannelColor ? rgbToHex$1(spatialChannelColor) : GREY_HEX;
|
|
274985
|
+
const ngCellColors = {};
|
|
274986
|
+
instanceObsIndex.forEach((id2) => {
|
|
274987
|
+
ngCellColors[id2] = fallbackColor;
|
|
274988
|
+
});
|
|
274989
|
+
result[layerScope][channelScope] = remapCellColors(ngCellColors, cellIdToMeshIdRef);
|
|
274424
274990
|
result[layerScope].opacity = spatialChannelOpacity ?? 1;
|
|
274991
|
+
result[layerScope].defaultColor = fallbackColor;
|
|
274425
274992
|
}
|
|
274426
274993
|
} else if (layerSets && layerIndex) {
|
|
274427
274994
|
const mergedCellSets = mergeObsSets(layerSets, additionalObsSets);
|
|
@@ -274433,10 +275000,10 @@ function NeuroglancerSubscriber(props) {
|
|
|
274433
275000
|
theme
|
|
274434
275001
|
});
|
|
274435
275002
|
const ngCellColors = {};
|
|
274436
|
-
cellColors.forEach((color2,
|
|
274437
|
-
ngCellColors[
|
|
275003
|
+
cellColors.forEach((color2, id2) => {
|
|
275004
|
+
ngCellColors[id2] = rgbToHex$1(color2);
|
|
274438
275005
|
});
|
|
274439
|
-
result[layerScope][channelScope] = ngCellColors;
|
|
275006
|
+
result[layerScope][channelScope] = remapCellColors(ngCellColors, cellIdToMeshIdRef);
|
|
274440
275007
|
result[layerScope].opacity = spatialChannelOpacity ?? 1;
|
|
274441
275008
|
}
|
|
274442
275009
|
});
|
|
@@ -274449,14 +275016,201 @@ function NeuroglancerSubscriber(props) {
|
|
|
274449
275016
|
segmentationChannelScopesByLayer,
|
|
274450
275017
|
obsSegmentationsSetsData,
|
|
274451
275018
|
segmentationChannelCoordination,
|
|
274452
|
-
theme
|
|
275019
|
+
theme,
|
|
275020
|
+
segmentationMultiExpressionNormData,
|
|
275021
|
+
segmentationMultiIndicesData,
|
|
275022
|
+
csvLoaded
|
|
274453
275023
|
}, customIsEqualForCellColors);
|
|
274454
|
-
const
|
|
275024
|
+
const initialViewerState = useNeuroglancerViewerState(theme, showAxisLines, segmentationLayerScopes, segmentationChannelScopesByLayer, segmentationLayerCoordination, segmentationChannelCoordination, obsSegmentationsUrls, obsSegmentationsData, pointLayerScopes, pointLayerCoordination, obsPointsUrls, obsPointsData, pointMultiIndicesData);
|
|
274455
275025
|
const [latestViewerStateIteration, incrementLatestViewerStateIteration] = useReducer((x2) => x2 + 1, 0);
|
|
274456
275026
|
const latestViewerStateRef = useRef({
|
|
274457
|
-
...
|
|
275027
|
+
...initialViewerState,
|
|
274458
275028
|
...initialNgCameraState ?? {}
|
|
274459
275029
|
});
|
|
275030
|
+
useEffect(() => {
|
|
275031
|
+
if (!csvUrl)
|
|
275032
|
+
return;
|
|
275033
|
+
fetch(csvUrl).then((r3) => r3.text()).then((text2) => {
|
|
275034
|
+
const lines = text2.split("\n");
|
|
275035
|
+
const header = lines[0].split(",");
|
|
275036
|
+
const meshIdIdx = header.indexOf("MeshID");
|
|
275037
|
+
const cellIdIdx = header.indexOf("CellID");
|
|
275038
|
+
const meshMap = {};
|
|
275039
|
+
const cellMap = {};
|
|
275040
|
+
lines.slice(1).forEach((l2) => {
|
|
275041
|
+
const cols = l2.split(",");
|
|
275042
|
+
const meshId = cols[meshIdIdx]?.trim();
|
|
275043
|
+
const cellId = cols[cellIdIdx]?.trim();
|
|
275044
|
+
if (meshId && cellId) {
|
|
275045
|
+
meshMap[meshId] = cellId;
|
|
275046
|
+
cellMap[cellId] = meshId;
|
|
275047
|
+
}
|
|
275048
|
+
});
|
|
275049
|
+
meshIdToCellIdRef.current = meshMap;
|
|
275050
|
+
cellIdToMeshIdRef.current = cellMap;
|
|
275051
|
+
setCsvLoaded(true);
|
|
275052
|
+
});
|
|
275053
|
+
}, [csvUrl]);
|
|
275054
|
+
useEffect(() => {
|
|
275055
|
+
chunkCacheRef.current.clear();
|
|
275056
|
+
}, [obsPointsData]);
|
|
275057
|
+
useEffect(() => {
|
|
275058
|
+
if (ngWidth && ngHeight) {
|
|
275059
|
+
viewportSizeRef.current = { width: ngWidth, height: ngHeight };
|
|
275060
|
+
}
|
|
275061
|
+
}, [ngWidth, ngHeight]);
|
|
275062
|
+
const setContainerNode = useCallback((node2) => {
|
|
275063
|
+
containerRef.current = node2;
|
|
275064
|
+
if (resizeObserverRef.current) {
|
|
275065
|
+
resizeObserverRef.current.disconnect();
|
|
275066
|
+
resizeObserverRef.current = null;
|
|
275067
|
+
}
|
|
275068
|
+
if (node2) {
|
|
275069
|
+
const rect2 = node2.getBoundingClientRect();
|
|
275070
|
+
if (rect2.width && rect2.height) {
|
|
275071
|
+
viewportSizeRef.current = { width: rect2.width, height: rect2.height };
|
|
275072
|
+
}
|
|
275073
|
+
const observer2 = new ResizeObserver((entries2) => {
|
|
275074
|
+
const entry2 = entries2[0];
|
|
275075
|
+
if (!entry2)
|
|
275076
|
+
return;
|
|
275077
|
+
const { width: width2, height: height2 } = entry2.contentRect;
|
|
275078
|
+
if (width2 && height2) {
|
|
275079
|
+
viewportSizeRef.current = { width: width2, height: height2 };
|
|
275080
|
+
}
|
|
275081
|
+
});
|
|
275082
|
+
observer2.observe(node2);
|
|
275083
|
+
resizeObserverRef.current = observer2;
|
|
275084
|
+
}
|
|
275085
|
+
}, []);
|
|
275086
|
+
const updateVisibleSegments = useCallback(async () => {
|
|
275087
|
+
if (!annotationInfoRef.current)
|
|
275088
|
+
return;
|
|
275089
|
+
if (!annotationTransformRef.current)
|
|
275090
|
+
return;
|
|
275091
|
+
if (!segmentationLayerScopes?.length)
|
|
275092
|
+
return;
|
|
275093
|
+
if (!pointLayerScopes?.length)
|
|
275094
|
+
return;
|
|
275095
|
+
const { position: position2, projectionScale } = latestViewerStateRef.current;
|
|
275096
|
+
if (!position2 || !projectionScale)
|
|
275097
|
+
return;
|
|
275098
|
+
const maxProjectionScale = meshLoadProjectionScaleThreshold ?? MESH_LOAD_THRESHOLD;
|
|
275099
|
+
if (projectionScale > maxProjectionScale) {
|
|
275100
|
+
if (visibleSegmentIdsRef.current?.length !== 0) {
|
|
275101
|
+
visibleSegmentIdsRef.current = [];
|
|
275102
|
+
incrementLatestViewerStateIteration();
|
|
275103
|
+
setIsMeshLoading(false);
|
|
275104
|
+
}
|
|
275105
|
+
return;
|
|
275106
|
+
}
|
|
275107
|
+
const { width: width2, height: height2 } = viewportSizeRef.current;
|
|
275108
|
+
if (!width2 || !height2)
|
|
275109
|
+
return;
|
|
275110
|
+
const transform3 = annotationTransformRef.current;
|
|
275111
|
+
const info2 = annotationInfoRef.current;
|
|
275112
|
+
const cellsUrl2 = info2.url;
|
|
275113
|
+
const allLevelCoords = info2.spatial.flatMap((level) => {
|
|
275114
|
+
const [gx, gy, gz] = level.grid_shape;
|
|
275115
|
+
const coords = [];
|
|
275116
|
+
for (let cx = 0; cx < gx; cx++) {
|
|
275117
|
+
for (let cy = 0; cy < gy; cy++) {
|
|
275118
|
+
for (let cz = 0; cz < gz; cz++) {
|
|
275119
|
+
coords.push({ level: level.key, cx, cy, cz });
|
|
275120
|
+
}
|
|
275121
|
+
}
|
|
275122
|
+
}
|
|
275123
|
+
return coords;
|
|
275124
|
+
});
|
|
275125
|
+
const fetchChunkWithPositions = async ({ level, cx, cy, cz }) => {
|
|
275126
|
+
const { serializers, serializer: defaultSerializer } = annotationTransformRef.current;
|
|
275127
|
+
const serializer2 = serializers?.[0] ?? defaultSerializer;
|
|
275128
|
+
if (!serializer2)
|
|
275129
|
+
return [];
|
|
275130
|
+
const cacheKey = `${cellsUrl2}/${level}/${cx}_${cy}_${cz}`;
|
|
275131
|
+
if (chunkCacheRef.current.has(cacheKey)) {
|
|
275132
|
+
return chunkCacheRef.current.get(cacheKey);
|
|
275133
|
+
}
|
|
275134
|
+
try {
|
|
275135
|
+
const res = await fetch(cacheKey);
|
|
275136
|
+
if (!res.ok) {
|
|
275137
|
+
chunkCacheRef.current.set(cacheKey, []);
|
|
275138
|
+
return [];
|
|
275139
|
+
}
|
|
275140
|
+
const buffer2 = await res.arrayBuffer();
|
|
275141
|
+
const entries2 = parseAnnotationChunkSegmentsWithPositions(buffer2, serializer2);
|
|
275142
|
+
chunkCacheRef.current.set(cacheKey, entries2);
|
|
275143
|
+
return entries2;
|
|
275144
|
+
} catch (e3) {
|
|
275145
|
+
chunkCacheRef.current.set(cacheKey, []);
|
|
275146
|
+
return [];
|
|
275147
|
+
}
|
|
275148
|
+
};
|
|
275149
|
+
try {
|
|
275150
|
+
const results = await Promise.all(allLevelCoords.map(fetchChunkWithPositions));
|
|
275151
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
275152
|
+
const allEntries = results.flat().filter(({ id: id2 }) => {
|
|
275153
|
+
if (seenIds.has(id2))
|
|
275154
|
+
return false;
|
|
275155
|
+
seenIds.add(id2);
|
|
275156
|
+
return true;
|
|
275157
|
+
});
|
|
275158
|
+
const obsIdToMeshId = {};
|
|
275159
|
+
allEntries.forEach(({ id: id2, obsId }) => {
|
|
275160
|
+
obsIdToMeshId[obsId] = id2;
|
|
275161
|
+
});
|
|
275162
|
+
obsIdToMeshIdRef.current = obsIdToMeshId;
|
|
275163
|
+
const mat = getViewProjectionMatRef.current?.();
|
|
275164
|
+
let visibleIds;
|
|
275165
|
+
if (!mat) {
|
|
275166
|
+
console.warn("No viewProjectionMatrix, loading all");
|
|
275167
|
+
visibleIds = [...new Set(allEntries.map(({ id: id2 }) => id2))];
|
|
275168
|
+
} else {
|
|
275169
|
+
const margin2 = Math.max(width2, height2) * 0.5;
|
|
275170
|
+
visibleIds = [...new Set(allEntries.filter(({ x: x2, y: y2, z: z2 }) => {
|
|
275171
|
+
const vx = x2 / transform3.x;
|
|
275172
|
+
const vy = y2 / transform3.y;
|
|
275173
|
+
const vz = (z2 || 0) / transform3.z;
|
|
275174
|
+
const cx = mat[0] * vx + mat[4] * vy + mat[8] * vz + mat[12];
|
|
275175
|
+
const cy = mat[1] * vx + mat[5] * vy + mat[9] * vz + mat[13];
|
|
275176
|
+
const cw2 = mat[3] * vx + mat[7] * vy + mat[11] * vz + mat[15];
|
|
275177
|
+
const screenX = (cx / cw2 + 1) * 0.5 * width2;
|
|
275178
|
+
const screenY = (1 - cy / cw2) * 0.5 * height2;
|
|
275179
|
+
return screenX >= -margin2 && screenX <= width2 + margin2 && screenY >= -margin2 && screenY <= height2 + margin2;
|
|
275180
|
+
}).map(({ id: id2 }) => id2))];
|
|
275181
|
+
}
|
|
275182
|
+
if (visibleIds.length === 0) {
|
|
275183
|
+
if (visibleSegmentIdsRef.current?.length !== 0) {
|
|
275184
|
+
visibleSegmentIdsRef.current = [];
|
|
275185
|
+
incrementLatestViewerStateIteration();
|
|
275186
|
+
}
|
|
275187
|
+
setIsMeshLoading(false);
|
|
275188
|
+
return;
|
|
275189
|
+
}
|
|
275190
|
+
const prevIds = new Set(visibleSegmentIdsRef.current ?? []);
|
|
275191
|
+
const addedIdsCount = visibleIds.filter((id2) => !prevIds.has(id2)).length;
|
|
275192
|
+
const hasSignificantChange = addedIdsCount > 20;
|
|
275193
|
+
if (hasSignificantChange && visibleIds.length > 0) {
|
|
275194
|
+
setIsMeshLoading(true);
|
|
275195
|
+
}
|
|
275196
|
+
const prevSorted = [...visibleSegmentIdsRef.current ?? []].sort().join(",");
|
|
275197
|
+
const nextSorted = [...visibleIds].sort().join(",");
|
|
275198
|
+
if (prevSorted !== nextSorted) {
|
|
275199
|
+
visibleSegmentIdsRef.current = visibleIds;
|
|
275200
|
+
incrementLatestViewerStateIteration();
|
|
275201
|
+
}
|
|
275202
|
+
if (hasSignificantChange) {
|
|
275203
|
+
setTimeout(() => setIsMeshLoading(false), MESH_LOADING_OVERLAY_TIMEOUT);
|
|
275204
|
+
}
|
|
275205
|
+
} catch (e3) {
|
|
275206
|
+
console.warn("[updateVisibleSegments] error:", e3);
|
|
275207
|
+
setIsMeshLoading(false);
|
|
275208
|
+
}
|
|
275209
|
+
}, [segmentationLayerScopes, pointLayerScopes, obsPointsData, meshLoadProjectionScaleThreshold]);
|
|
275210
|
+
useEffect(() => {
|
|
275211
|
+
updateVisibleSegmentsThrottledRef.current = throttle$1(updateVisibleSegments, 500);
|
|
275212
|
+
return () => updateVisibleSegmentsThrottledRef.current?.cancel();
|
|
275213
|
+
}, [updateVisibleSegments]);
|
|
274460
275214
|
useEffect(() => {
|
|
274461
275215
|
const prevNgCameraState = {
|
|
274462
275216
|
position: latestViewerStateRef.current.position,
|
|
@@ -274464,37 +275218,50 @@ function NeuroglancerSubscriber(props) {
|
|
|
274464
275218
|
projectionScale: latestViewerStateRef.current.projectionScale
|
|
274465
275219
|
};
|
|
274466
275220
|
latestViewerStateRef.current = {
|
|
274467
|
-
...
|
|
275221
|
+
...initialViewerState,
|
|
274468
275222
|
...prevNgCameraState
|
|
274469
275223
|
};
|
|
274470
275224
|
incrementLatestViewerStateIteration();
|
|
274471
|
-
}, [
|
|
274472
|
-
const
|
|
274473
|
-
|
|
274474
|
-
|
|
274475
|
-
|
|
274476
|
-
const
|
|
274477
|
-
|
|
274478
|
-
|
|
274479
|
-
|
|
274480
|
-
|
|
274481
|
-
|
|
274482
|
-
|
|
274483
|
-
|
|
274484
|
-
|
|
274485
|
-
|
|
274486
|
-
|
|
274487
|
-
|
|
274488
|
-
|
|
274489
|
-
|
|
274490
|
-
|
|
274491
|
-
|
|
274492
|
-
|
|
274493
|
-
|
|
274494
|
-
|
|
274495
|
-
|
|
274496
|
-
|
|
274497
|
-
|
|
275225
|
+
}, [initialViewerState]);
|
|
275226
|
+
const cellsUrl = useMemo$1(() => {
|
|
275227
|
+
const firstScope = pointLayerScopes?.[0];
|
|
275228
|
+
return obsPointsUrls?.[firstScope]?.[0]?.url ?? null;
|
|
275229
|
+
}, [pointLayerScopes, obsPointsUrls]);
|
|
275230
|
+
const hasMatchingAnnotationSource = useMemo$1(() => {
|
|
275231
|
+
if (!cellsUrl)
|
|
275232
|
+
return false;
|
|
275233
|
+
const firstPointScope = pointLayerScopes?.[0];
|
|
275234
|
+
return pointsHaveMatchingSegmentation({
|
|
275235
|
+
pointObsType: pointLayerCoordination[0]?.[firstPointScope]?.obsType,
|
|
275236
|
+
segmentationLayerScopes,
|
|
275237
|
+
segmentationChannelScopesByLayer,
|
|
275238
|
+
segmentationChannelCoordination
|
|
275239
|
+
});
|
|
275240
|
+
}, [cellsUrl, pointLayerScopes, segmentationLayerScopes, segmentationChannelScopesByLayer]);
|
|
275241
|
+
useEffect(() => {
|
|
275242
|
+
if (!cellsUrl)
|
|
275243
|
+
return;
|
|
275244
|
+
fetch(`${cellsUrl}/info`).then((r3) => r3.json()).then((info2) => {
|
|
275245
|
+
const infoWithUrl = {
|
|
275246
|
+
...info2,
|
|
275247
|
+
url: cellsUrl
|
|
275248
|
+
};
|
|
275249
|
+
annotationInfoRef.current = infoWithUrl;
|
|
275250
|
+
if (annotationTransformRef.current)
|
|
275251
|
+
setAnnotationReady(true);
|
|
275252
|
+
}).catch((err2) => console.error("failed to fetch annotation info:", err2));
|
|
275253
|
+
}, [cellsUrl]);
|
|
275254
|
+
useEffect(() => {
|
|
275255
|
+
if (annotationReady) {
|
|
275256
|
+
setIsLayersLoaded(true);
|
|
275257
|
+
updateVisibleSegments();
|
|
275258
|
+
}
|
|
275259
|
+
}, [annotationReady]);
|
|
275260
|
+
const onAnnotationSourceReady = useCallback((transform3) => {
|
|
275261
|
+
annotationTransformRef.current = transform3;
|
|
275262
|
+
if (annotationInfoRef.current)
|
|
275263
|
+
setAnnotationReady(true);
|
|
275264
|
+
}, []);
|
|
274498
275265
|
const handleStateUpdate = useCallback((newState) => {
|
|
274499
275266
|
lastInteractionSource.current = LAST_INTERACTION_SOURCE.neuroglancer;
|
|
274500
275267
|
const { projectionScale, projectionOrientation, position: position2 } = newState;
|
|
@@ -274527,6 +275294,7 @@ function NeuroglancerSubscriber(props) {
|
|
|
274527
275294
|
setZoom(vitZoomFromNg);
|
|
274528
275295
|
zoomRafRef.current = null;
|
|
274529
275296
|
});
|
|
275297
|
+
updateVisibleSegments();
|
|
274530
275298
|
}
|
|
274531
275299
|
lastNgScaleRef.current = projectionScale;
|
|
274532
275300
|
}
|
|
@@ -274567,7 +275335,8 @@ function NeuroglancerSubscriber(props) {
|
|
|
274567
275335
|
projectionScale,
|
|
274568
275336
|
position: position2
|
|
274569
275337
|
};
|
|
274570
|
-
|
|
275338
|
+
updateVisibleSegmentsThrottledRef.current?.();
|
|
275339
|
+
}, [updateVisibleSegmentsThrottledRef]);
|
|
274571
275340
|
const onSegmentClick = useCallback((value2) => {
|
|
274572
275341
|
if (value2) {
|
|
274573
275342
|
const id2 = String(value2);
|
|
@@ -274592,11 +275361,18 @@ function NeuroglancerSubscriber(props) {
|
|
|
274592
275361
|
const channelScope = segmentationChannelScopesByLayer?.[layerScope]?.[0];
|
|
274593
275362
|
result[layerScope] = {
|
|
274594
275363
|
colors: segmentationColorMapping?.[layerScope]?.[channelScope] ?? {},
|
|
274595
|
-
opacity: segmentationColorMapping?.[layerScope]?.opacity ?? 1
|
|
275364
|
+
opacity: segmentationColorMapping?.[layerScope]?.opacity ?? 1,
|
|
275365
|
+
defaultColor: segmentationColorMapping?.[layerScope]?.defaultColor ?? null
|
|
274596
275366
|
};
|
|
274597
275367
|
});
|
|
274598
275368
|
return result;
|
|
274599
275369
|
}, [segmentationColorMapping, segmentationLayerScopes, segmentationChannelScopesByLayer]);
|
|
275370
|
+
useEffect(() => {
|
|
275371
|
+
if (!hasMatchingAnnotationSource && isReady && !segmentationLayerScopes?.length) {
|
|
275372
|
+
setIsLayersLoaded(true);
|
|
275373
|
+
}
|
|
275374
|
+
}, [hasMatchingAnnotationSource, isReady, segmentationLayerScopes]);
|
|
275375
|
+
const meshOpacity = hasMatchingAnnotationSource ? MESH_OPACITY : void 0;
|
|
274600
275376
|
const derivedViewerState = useMemo$1(() => {
|
|
274601
275377
|
const { current: current2 } = latestViewerStateRef;
|
|
274602
275378
|
if (current2.layers.length <= 0) {
|
|
@@ -274655,13 +275431,33 @@ function NeuroglancerSubscriber(props) {
|
|
|
274655
275431
|
lastInteractionSource.current = null;
|
|
274656
275432
|
}
|
|
274657
275433
|
const updatedLayers = current2?.layers?.map((layer, idx) => {
|
|
274658
|
-
|
|
275434
|
+
if (layer.type !== "segmentation")
|
|
275435
|
+
return layer;
|
|
275436
|
+
const layerScope = segmentationLayerScopes?.find((scope) => layer.name?.includes(scope));
|
|
275437
|
+
if (!layerScope)
|
|
275438
|
+
return layer;
|
|
274659
275439
|
const layerColorMapping = cellColorMappingByLayer?.[layerScope]?.colors ?? {};
|
|
274660
|
-
const
|
|
275440
|
+
const defaultColor = cellColorMappingByLayer?.[layerScope]?.defaultColor;
|
|
275441
|
+
let segments2 = [];
|
|
275442
|
+
if (hasMatchingAnnotationSource) {
|
|
275443
|
+
segments2 = visibleSegmentIdsRef.current ?? [];
|
|
275444
|
+
} else if (Object.keys(layerColorMapping).length > 0) {
|
|
275445
|
+
segments2 = Object.keys(layerColorMapping);
|
|
275446
|
+
}
|
|
275447
|
+
let derivedSegmentColors = {};
|
|
275448
|
+
if (hasMatchingAnnotationSource && segments2.length > 0) {
|
|
275449
|
+
segments2.forEach((meshId) => {
|
|
275450
|
+
const color2 = layerColorMapping[meshId] || defaultColor;
|
|
275451
|
+
if (color2)
|
|
275452
|
+
derivedSegmentColors[meshId] = color2;
|
|
275453
|
+
});
|
|
275454
|
+
} else if (!hasMatchingAnnotationSource) {
|
|
275455
|
+
derivedSegmentColors = layerColorMapping;
|
|
275456
|
+
}
|
|
274661
275457
|
return {
|
|
274662
275458
|
...layer,
|
|
274663
|
-
segments:
|
|
274664
|
-
segmentColors:
|
|
275459
|
+
segments: segments2,
|
|
275460
|
+
segmentColors: derivedSegmentColors,
|
|
274665
275461
|
objectAlpha: cellColorMappingByLayer?.[layerScope]?.opacity ?? 1
|
|
274666
275462
|
};
|
|
274667
275463
|
}) ?? [];
|
|
@@ -274691,17 +275487,21 @@ function NeuroglancerSubscriber(props) {
|
|
|
274691
275487
|
spatialRotationZ,
|
|
274692
275488
|
spatialTargetX,
|
|
274693
275489
|
spatialTargetY,
|
|
274694
|
-
|
|
274695
|
-
latestViewerStateIteration
|
|
275490
|
+
initialViewerState,
|
|
275491
|
+
latestViewerStateIteration,
|
|
275492
|
+
hasMatchingAnnotationSource
|
|
274696
275493
|
]);
|
|
274697
275494
|
const onSegmentHighlight = useCallback((obsId) => {
|
|
274698
275495
|
setCellHighlight(String(obsId));
|
|
274699
275496
|
}, [setCellHighlight]);
|
|
274700
275497
|
const handleLayerLoadingChange = useCallback((isLoaded) => {
|
|
274701
|
-
|
|
274702
|
-
|
|
275498
|
+
if (!isLayersLoaded && isLoaded) {
|
|
275499
|
+
setIsLayersLoaded(true);
|
|
275500
|
+
}
|
|
275501
|
+
}, [isLayersLoaded]);
|
|
274703
275502
|
const hasLayers = derivedViewerState?.layers?.length > 0;
|
|
274704
|
-
|
|
275503
|
+
const showPointsLegend = !hasMatchingAnnotationSource;
|
|
275504
|
+
return jsx$1(TitleInfo, { title: title2, info: subtitle, helpText, isSpatial: true, theme, closeButtonVisible, downloadButtonVisible, removeGridComponent, isReady: isReady && isLayersLoaded, errors, withPadding: false, guideUrl: GUIDE_URL, children: hasLayers ? jsxs("div", { style: { position: "relative", width: "100%", height: "100%" }, ref: setContainerNode, children: [jsx$1("div", { style: { position: "absolute", top: 0, right: 0, zIndex: 50 }, children: jsx$1(MultiLegend, {
|
|
274705
275505
|
theme: "dark",
|
|
274706
275506
|
maxHeight: ngHeight,
|
|
274707
275507
|
// Segmentations
|
|
@@ -274710,10 +275510,12 @@ function NeuroglancerSubscriber(props) {
|
|
|
274710
275510
|
segmentationChannelScopesByLayer,
|
|
274711
275511
|
segmentationChannelCoordination,
|
|
274712
275512
|
// Points
|
|
274713
|
-
pointLayerScopes,
|
|
275513
|
+
pointLayerScopes: showPointsLegend ? pointLayerScopes : void 0,
|
|
274714
275514
|
pointLayerCoordination,
|
|
274715
275515
|
pointMultiIndicesData
|
|
274716
|
-
}) }), jsx$1(NeuroglancerComp, { classes: classes2, onSegmentClick, onSelectHoveredCoords: onSegmentHighlight, viewerState: derivedViewerState, cellColorMapping: cellColorMappingByLayer, setViewerState: handleStateUpdate, onLayerLoadingChange: handleLayerLoadingChange
|
|
275516
|
+
}) }), isMeshLoading ? jsx$1(Chip, { label: "Loading meshes...", size: "small", color: "primary", className: classes2.meshLoadingIndicator }) : null, jsx$1(NeuroglancerComp, { classes: classes2, onSegmentClick, onSelectHoveredCoords: onSegmentHighlight, viewerState: derivedViewerState, cellColorMapping: cellColorMappingByLayer, setViewerState: handleStateUpdate, onLayerLoadingChange: handleLayerLoadingChange, onAnnotationSourceReady, onViewerReady: (getFn) => {
|
|
275517
|
+
getViewProjectionMatRef.current = getFn;
|
|
275518
|
+
}, getMeshIdToCellId: (meshId) => meshIdToCellIdRef.current[meshId], cellsUrl, meshOpacity })] }) : null });
|
|
274717
275519
|
}
|
|
274718
275520
|
const FEATURE_AGGREGATION_STRATEGIES = ["first", "last", "sum", "mean"];
|
|
274719
275521
|
function CellSetExpressionPlotOptions(props) {
|
|
@@ -276552,7 +277354,7 @@ function useFilteredVolcanoData(props) {
|
|
|
276552
277354
|
const rawSampleSetPathB = coordinationValues.sampleSetFilter[1];
|
|
276553
277355
|
const sampleSetPathB = [...rawSampleSetPathB];
|
|
276554
277356
|
sampleSetPathB[0] = sampleSetsColumnNameMappingReversed[rawSampleSetPathB[0]];
|
|
276555
|
-
if (isEqual$3(sampleSetPathA, sampleSetSelection[
|
|
277357
|
+
if (isEqual$3(sampleSetPathA, sampleSetSelection[0]) && isEqual$3(sampleSetPathB, sampleSetSelection[1])) {
|
|
276556
277358
|
shouldSwapFoldChangeDirection = true;
|
|
276557
277359
|
}
|
|
276558
277360
|
}
|
|
@@ -327211,7 +328013,7 @@ const VEGA_THEMES = {
|
|
|
327211
328013
|
};
|
|
327212
328014
|
const DATASET_NAME = "table";
|
|
327213
328015
|
function VegaGlobalStyles() {
|
|
327214
|
-
const { theme } = useStyles$
|
|
328016
|
+
const { theme } = useStyles$z();
|
|
327215
328017
|
return jsx$1(GlobalStyles$3, { styles: {
|
|
327216
328018
|
"#vg-tooltip-element.vg-tooltip.custom-theme": {
|
|
327217
328019
|
boxShadow: "0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)",
|
|
@@ -327245,7 +328047,7 @@ function renderTooltipContents(tooltipText) {
|
|
|
327245
328047
|
}
|
|
327246
328048
|
function VegaPlot(props) {
|
|
327247
328049
|
const { spec: partialSpec, data: data2, getTooltipText, signalListeners, renderer = "svg", onNewView } = props;
|
|
327248
|
-
const { classes: tooltipClasses2 } = useStyles$
|
|
328050
|
+
const { classes: tooltipClasses2 } = useStyles$u();
|
|
327249
328051
|
const tooltipHandler = useMemo$1(() => {
|
|
327250
328052
|
if (typeof getTooltipText === "function") {
|
|
327251
328053
|
const tooltipConfig = {
|
|
@@ -328306,6 +329108,10 @@ function TreemapSubscriber(props) {
|
|
|
328306
329108
|
}, [setObsSetSelection]);
|
|
328307
329109
|
return jsxs(TitleInfo, { title: `Treemap of ${capitalize$3(pluralize(obsType, 2))}`, info: `${commaNumber(selectedObsCount)} ${pluralize(obsType, selectedObsCount)} from ${commaNumber(selectedSampleCount)} ${pluralize(sampleType, selectedSampleCount)}`, removeGridComponent, urls: urls2, theme, isReady, helpText, errors, withPadding: false, options: jsx$1(TreemapOptions, { obsType, sampleType, obsColorEncoding, setObsColorEncoding, hierarchyLevels: hierarchyLevels || DEFAULT_HIERARCHY_LEVELS, setHierarchyLevels }), children: [jsx$1("div", { ref: containerRef, className: classes2.vegaContainer, children: jsx$1(Treemap, { obsCounts, sampleCounts, obsColorEncoding, hierarchyLevels: hierarchyLevels || DEFAULT_HIERARCHY_LEVELS, theme, width: width2, height: Math.max(height2 * (selectedObsCount / totalObsCount), 40), obsType, sampleType, obsSetColor, sampleSetColor, obsSetSelection, sampleSetSelection, onNodeClick }) }), jsx$1("div", { style: { position: "absolute", right: "2px", bottom: "2px", fontSize: "10px" }, children: unselectedObsCount > 0 ? jsx$1("span", { children: `${commaNumber(unselectedObsCount)} ${pluralize(obsType, unselectedObsCount)} from ${commaNumber(unselectedSampleCount)} ${pluralize(sampleType, unselectedSampleCount)} currently omitted` }) : null })] });
|
|
328308
329110
|
}
|
|
329111
|
+
const GOLDEN_RATIO = 0.6180339887498948;
|
|
329112
|
+
function topJitter(index2, rangePixels) {
|
|
329113
|
+
return index2 * GOLDEN_RATIO % 1 * rangePixels;
|
|
329114
|
+
}
|
|
328309
329115
|
function VolcanoPlot(props) {
|
|
328310
329116
|
const { theme, width: width2, height: height2, obsType, featureType, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMappingReversed, sampleSetSelection, obsSetSelection, obsSetColor, sampleSetColor, data: data2, marginTop = 5, marginRight = 5, marginLeft = 50, marginBottom = 50, onFeatureClick, featurePointSignificanceThreshold, featurePointFoldChangeThreshold, featureLabelSignificanceThreshold, featureLabelFoldChangeThreshold } = props;
|
|
328311
329117
|
const svgRef = useRef();
|
|
@@ -328367,10 +329173,10 @@ function VolcanoPlot(props) {
|
|
|
328367
329173
|
const obsSetPath2 = [...rawObsSetPath];
|
|
328368
329174
|
obsSetPath2[0] = obsSetsColumnNameMappingReversed[rawObsSetPath[0]];
|
|
328369
329175
|
const color2 = obsSetColorScale(obsSetPath2);
|
|
328370
|
-
obsSetG.append("g").selectAll("circle").data(filteredDf).join("circle").attr("cx", (d) => xScale(d.logFoldChange)).attr("cy", (d) => yScale(d.minusLog10p)).attr("r", 3).attr("opacity", 0.5).attr("fill", color2).on("click", (event2, d) => {
|
|
329176
|
+
obsSetG.append("g").selectAll("circle").data(filteredDf).join("circle").attr("cx", (d) => xScale(d.logFoldChange)).attr("cy", (d, i2) => yScale(d.minusLog10p) + (!Number.isFinite(d.minusLog10p) ? topJitter(i2, 20) : 0)).attr("r", 3).attr("opacity", 0.5).attr("fill", color2).on("click", (event2, d) => {
|
|
328371
329177
|
onFeatureClick(d.featureId);
|
|
328372
329178
|
});
|
|
328373
|
-
const textElements = obsSetG.append("g").selectAll("text").data(filteredDf).join("text").text((d) => d.featureId).attr("text-anchor", (d) => d.logFoldChange < 0 ? "end" : "start").attr("x", (d) => xScale(d.logFoldChange)).attr("y", (d) => yScale(d.minusLog10p)).style("display", (d) => Math.abs(d.logFoldChange) < (featureLabelFoldChangeThreshold ?? 5) || d.featureSignificance >= (featureLabelSignificanceThreshold ?? 0.01) ? "none" : void 0).attr("fill", color2).on("click", (event2, d) => {
|
|
329179
|
+
const textElements = obsSetG.append("g").selectAll("text").data(filteredDf).join("text").text((d) => d.featureId).attr("text-anchor", (d) => d.logFoldChange < 0 ? "end" : "start").attr("x", (d) => xScale(d.logFoldChange)).attr("y", (d, i2) => yScale(d.minusLog10p) + (!Number.isFinite(d.minusLog10p) ? topJitter(i2, 20) : 0)).style("display", (d) => Math.abs(d.logFoldChange) < (featureLabelFoldChangeThreshold ?? 5) || d.featureSignificance >= (featureLabelSignificanceThreshold ?? 0.01) ? "none" : void 0).attr("fill", color2).on("click", (event2, d) => {
|
|
328374
329180
|
onFeatureClick(d.featureId);
|
|
328375
329181
|
});
|
|
328376
329182
|
textElements.append("title").text((d) => `${featureType}: ${d.featureId}
|
|
@@ -353180,6 +353986,7 @@ const baseCoordinationTypes = [
|
|
|
353180
353986
|
new PluginCoordinationType(CoordinationType$1.SPATIAL_CHANNEL_LABELS_VISIBLE, true, z.boolean()),
|
|
353181
353987
|
new PluginCoordinationType(CoordinationType$1.SPATIAL_CHANNEL_LABELS_ORIENTATION, "vertical", z.enum(["vertical", "horizontal"])),
|
|
353182
353988
|
new PluginCoordinationType(CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE, 14, z.number()),
|
|
353989
|
+
new PluginCoordinationType(CoordinationType$1.SPATIAL_CHANNELS_SORT_ORDER, "original", z.enum(["original", "alphabetical"])),
|
|
353183
353990
|
new PluginCoordinationType(CoordinationType$1.SAMPLE_TYPE, "sample", z.string().nullable()),
|
|
353184
353991
|
// TODO: remove one array level and use multi-coordination for sampleSetSelection?
|
|
353185
353992
|
new PluginCoordinationType(CoordinationType$1.SAMPLE_FILTER, null, z.array(z.string()).nullable()),
|
|
@@ -353734,7 +354541,7 @@ function UncontrolledLauncher(props) {
|
|
|
353734
354541
|
));
|
|
353735
354542
|
}
|
|
353736
354543
|
export {
|
|
353737
|
-
|
|
354544
|
+
GREY_HEX as $,
|
|
353738
354545
|
require_descriptors as A,
|
|
353739
354546
|
BaseDecoder as B,
|
|
353740
354547
|
CoordinationType$1 as C,
|
|
@@ -353763,8 +354570,9 @@ export {
|
|
|
353763
354570
|
require_redefine as Z,
|
|
353764
354571
|
require_objectAssign as _,
|
|
353765
354572
|
getDefaultExportFromCjs$1 as a,
|
|
353766
|
-
|
|
353767
|
-
|
|
354573
|
+
diffCameraState as a0,
|
|
354574
|
+
UncontrolledLauncher as a1,
|
|
354575
|
+
ControlledLauncher as a2,
|
|
353768
354576
|
LercAddCompression as b,
|
|
353769
354577
|
commonjsGlobal$1 as c,
|
|
353770
354578
|
requireAssign as d,
|