@vitessce/scatterplot-embedding 3.5.10 → 3.5.12
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/{deflate-f550f6c6.js → deflate-94dfdd6c.js} +1 -1
- package/dist/{index-a37f30c8.js → index-de0a204e.js} +176 -47
- package/dist/index.js +1 -1
- package/dist/{jpeg-5927a952.js → jpeg-ea5d6166.js} +1 -1
- package/dist/{lerc-7a4fca51.js → lerc-7e5d53ac.js} +1 -1
- package/dist/{lzw-ce001eff.js → lzw-cecbc3f4.js} +1 -1
- package/dist/{packbits-075c055a.js → packbits-04a500da.js} +1 -1
- package/dist/{raw-b648d255.js → raw-5d0a1d41.js} +1 -1
- package/dist/{webimage-dec5407e.js → webimage-67a3c5bf.js} +1 -1
- package/dist-tsc/EmbeddingScatterplotSubscriber.d.ts.map +1 -1
- package/dist-tsc/EmbeddingScatterplotSubscriber.js +22 -13
- package/package.json +7 -7
- package/src/EmbeddingScatterplotSubscriber.js +39 -23
|
@@ -11717,6 +11717,7 @@ const CoordinationType$1 = {
|
|
|
11717
11717
|
FEATURE_VALUE_COLORMAP: "featureValueColormap",
|
|
11718
11718
|
FEATURE_VALUE_TRANSFORM: "featureValueTransform",
|
|
11719
11719
|
FEATURE_VALUE_COLORMAP_RANGE: "featureValueColormapRange",
|
|
11720
|
+
FEATURE_AGGREGATION_STRATEGY: "featureAggregationStrategy",
|
|
11720
11721
|
OBS_COLOR_ENCODING: "obsColorEncoding",
|
|
11721
11722
|
SPATIAL_IMAGE_LAYER: "spatialImageLayer",
|
|
11722
11723
|
SPATIAL_SEGMENTATION_LAYER: "spatialSegmentationLayer",
|
|
@@ -11859,6 +11860,7 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
11859
11860
|
CoordinationType$1.FEATURE_SELECTION,
|
|
11860
11861
|
CoordinationType$1.FEATURE_VALUE_COLORMAP,
|
|
11861
11862
|
CoordinationType$1.FEATURE_VALUE_COLORMAP_RANGE,
|
|
11863
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
11862
11864
|
CoordinationType$1.OBS_COLOR_ENCODING,
|
|
11863
11865
|
CoordinationType$1.ADDITIONAL_OBS_SETS,
|
|
11864
11866
|
CoordinationType$1.TOOLTIPS_VISIBLE,
|
|
@@ -11902,6 +11904,7 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
11902
11904
|
CoordinationType$1.FEATURE_SELECTION,
|
|
11903
11905
|
CoordinationType$1.FEATURE_VALUE_COLORMAP,
|
|
11904
11906
|
CoordinationType$1.FEATURE_VALUE_COLORMAP_RANGE,
|
|
11907
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
11905
11908
|
CoordinationType$1.OBS_COLOR_ENCODING,
|
|
11906
11909
|
CoordinationType$1.ADDITIONAL_OBS_SETS,
|
|
11907
11910
|
CoordinationType$1.TOOLTIPS_VISIBLE,
|
|
@@ -11981,10 +11984,12 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
11981
11984
|
CoordinationType$1.FEATURE_SELECTION,
|
|
11982
11985
|
CoordinationType$1.FEATURE_VALUE_COLORMAP,
|
|
11983
11986
|
CoordinationType$1.FEATURE_VALUE_COLORMAP_RANGE,
|
|
11987
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
11984
11988
|
CoordinationType$1.OBS_COLOR_ENCODING,
|
|
11985
11989
|
CoordinationType$1.ADDITIONAL_OBS_SETS,
|
|
11986
11990
|
CoordinationType$1.MOLECULE_HIGHLIGHT,
|
|
11987
|
-
CoordinationType$1.TOOLTIPS_VISIBLE
|
|
11991
|
+
CoordinationType$1.TOOLTIPS_VISIBLE,
|
|
11992
|
+
CoordinationType$1.PHOTOMETRIC_INTERPRETATION
|
|
11988
11993
|
],
|
|
11989
11994
|
[ViewType$1.SPATIAL_BETA]: [
|
|
11990
11995
|
CoordinationType$1.META_COORDINATION_SCOPES,
|
|
@@ -12018,6 +12023,7 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
12018
12023
|
CoordinationType$1.FEATURE_SELECTION,
|
|
12019
12024
|
CoordinationType$1.FEATURE_VALUE_COLORMAP,
|
|
12020
12025
|
CoordinationType$1.FEATURE_VALUE_COLORMAP_RANGE,
|
|
12026
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
12021
12027
|
CoordinationType$1.OBS_COLOR_ENCODING,
|
|
12022
12028
|
CoordinationType$1.ADDITIONAL_OBS_SETS,
|
|
12023
12029
|
CoordinationType$1.MOLECULE_HIGHLIGHT,
|
|
@@ -12056,7 +12062,8 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
12056
12062
|
CoordinationType$1.LEGEND_VISIBLE,
|
|
12057
12063
|
CoordinationType$1.SPATIAL_CHANNEL_LABELS_VISIBLE,
|
|
12058
12064
|
CoordinationType$1.SPATIAL_CHANNEL_LABELS_ORIENTATION,
|
|
12059
|
-
CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE
|
|
12065
|
+
CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE,
|
|
12066
|
+
CoordinationType$1.PHOTOMETRIC_INTERPRETATION
|
|
12060
12067
|
],
|
|
12061
12068
|
[ViewType$1.HEATMAP]: [
|
|
12062
12069
|
CoordinationType$1.DATASET,
|
|
@@ -12131,6 +12138,7 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
12131
12138
|
CoordinationType$1.FEATURE_SELECTION,
|
|
12132
12139
|
CoordinationType$1.FEATURE_VALUE_TRANSFORM,
|
|
12133
12140
|
CoordinationType$1.FEATURE_VALUE_TRANSFORM_COEFFICIENT,
|
|
12141
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
12134
12142
|
CoordinationType$1.OBS_SET_SELECTION,
|
|
12135
12143
|
CoordinationType$1.OBS_SET_FILTER,
|
|
12136
12144
|
CoordinationType$1.OBS_SET_HIGHLIGHT,
|
|
@@ -12146,6 +12154,7 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
12146
12154
|
CoordinationType$1.FEATURE_TYPE,
|
|
12147
12155
|
CoordinationType$1.FEATURE_VALUE_TYPE,
|
|
12148
12156
|
CoordinationType$1.FEATURE_SELECTION,
|
|
12157
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
12149
12158
|
CoordinationType$1.ADDITIONAL_OBS_SETS,
|
|
12150
12159
|
CoordinationType$1.OBS_SET_COLOR,
|
|
12151
12160
|
CoordinationType$1.OBS_COLOR_ENCODING,
|
|
@@ -12169,7 +12178,8 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
12169
12178
|
CoordinationType$1.SPATIAL_ROTATION_Y,
|
|
12170
12179
|
CoordinationType$1.SPATIAL_ROTATION_Z,
|
|
12171
12180
|
CoordinationType$1.SPATIAL_ROTATION_ORBIT,
|
|
12172
|
-
CoordinationType$1.SPATIAL_ORBIT_AXIS
|
|
12181
|
+
CoordinationType$1.SPATIAL_ORBIT_AXIS,
|
|
12182
|
+
CoordinationType$1.PHOTOMETRIC_INTERPRETATION
|
|
12173
12183
|
],
|
|
12174
12184
|
[ViewType$1.LAYER_CONTROLLER_BETA]: [
|
|
12175
12185
|
CoordinationType$1.META_COORDINATION_SCOPES,
|
|
@@ -12224,6 +12234,7 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
12224
12234
|
CoordinationType$1.FEATURE_VALUE_COLORMAP,
|
|
12225
12235
|
CoordinationType$1.FEATURE_VALUE_COLORMAP_RANGE,
|
|
12226
12236
|
CoordinationType$1.FEATURE_SELECTION,
|
|
12237
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
12227
12238
|
CoordinationType$1.TOOLTIPS_VISIBLE,
|
|
12228
12239
|
CoordinationType$1.TOOLTIP_CROSSHAIRS_VISIBLE,
|
|
12229
12240
|
CoordinationType$1.LEGEND_VISIBLE,
|
|
@@ -12264,6 +12275,7 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
12264
12275
|
CoordinationType$1.FEATURE_VALUE_TRANSFORM_COEFFICIENT,
|
|
12265
12276
|
CoordinationType$1.FEATURE_VALUE_POSITIVITY_THRESHOLD,
|
|
12266
12277
|
CoordinationType$1.FEATURE_VALUE_COLORMAP,
|
|
12278
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
12267
12279
|
CoordinationType$1.OBS_SET_SELECTION,
|
|
12268
12280
|
CoordinationType$1.OBS_SET_FILTER,
|
|
12269
12281
|
CoordinationType$1.OBS_SET_HIGHLIGHT,
|
|
@@ -12292,6 +12304,7 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
12292
12304
|
CoordinationType$1.FEATURE_SELECTION,
|
|
12293
12305
|
CoordinationType$1.FEATURE_VALUE_TRANSFORM,
|
|
12294
12306
|
CoordinationType$1.FEATURE_VALUE_TRANSFORM_COEFFICIENT,
|
|
12307
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
12295
12308
|
CoordinationType$1.OBS_SET_SELECTION,
|
|
12296
12309
|
CoordinationType$1.OBS_SET_HIGHLIGHT,
|
|
12297
12310
|
CoordinationType$1.OBS_HIGHLIGHT,
|
|
@@ -12396,6 +12409,7 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
12396
12409
|
CoordinationType$1.OBS_TYPE,
|
|
12397
12410
|
CoordinationType$1.SAMPLE_TYPE,
|
|
12398
12411
|
CoordinationType$1.FEATURE_SELECTION,
|
|
12412
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
12399
12413
|
CoordinationType$1.SAMPLE_SET_SELECTION,
|
|
12400
12414
|
CoordinationType$1.SAMPLE_SET_FILTER,
|
|
12401
12415
|
CoordinationType$1.OBS_SET_SELECTION,
|
|
@@ -12703,6 +12717,7 @@ z.object({
|
|
|
12703
12717
|
termColumn: z.string().optional(),
|
|
12704
12718
|
pValueColumn: z.string(),
|
|
12705
12719
|
pValueAdjusted: z.boolean().optional(),
|
|
12720
|
+
featureSetLibrary: z.string().optional().describe("Optionally, provide a feature set library name. By default, Reactome_2022."),
|
|
12706
12721
|
analysisType: z.string().optional().describe("Optionally, provide an analysis_type name. By default, pertpy_hypergeometric.")
|
|
12707
12722
|
});
|
|
12708
12723
|
z.object({
|
|
@@ -12713,7 +12728,6 @@ z.object({
|
|
|
12713
12728
|
foldChangeColumn: z.string().describe("The log-fold change is then calculated between this expected sample and the expected sample with no active covariates from the intercept section."),
|
|
12714
12729
|
foldChangeTransformation: z.enum(["log2"]).optional(),
|
|
12715
12730
|
isCredibleEffectColumn: z.string().describe("Column which annotates effects as being credible or not (boolean)."),
|
|
12716
|
-
covariateColumn: z.string().describe("Column which defines the covariate used in the analysis."),
|
|
12717
12731
|
analysisType: z.string().optional().describe("Optionally, provide an analysis_type name. By default, sccoda_df.")
|
|
12718
12732
|
});
|
|
12719
12733
|
const annDataObsLabels = annDataObs;
|
|
@@ -19717,7 +19731,7 @@ function getCellColors(params) {
|
|
|
19717
19731
|
}
|
|
19718
19732
|
return /* @__PURE__ */ new Map();
|
|
19719
19733
|
}
|
|
19720
|
-
function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetSelection, obsIndex, mergedCellSets, cellSetSelection, arraysToStratify) {
|
|
19734
|
+
function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetSelection, obsIndex, mergedCellSets, cellSetSelection, arraysToStratify, featureAggregationStrategy) {
|
|
19721
19735
|
const result = new InternMap([], JSON.stringify);
|
|
19722
19736
|
const hasSampleSetSelection = Array.isArray(sampleSetSelection) && sampleSetSelection.length > 0;
|
|
19723
19737
|
const hasCellSetSelection = Array.isArray(cellSetSelection) && cellSetSelection.length > 0;
|
|
@@ -19727,9 +19741,13 @@ function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetS
|
|
|
19727
19741
|
if (arrKeys.includes("obsIndex") || arrKeys.includes("i")) {
|
|
19728
19742
|
throw new Error('The keys "obsIndex" and "i" are reserved for internal use.');
|
|
19729
19743
|
}
|
|
19730
|
-
if (Object.
|
|
19731
|
-
|
|
19732
|
-
|
|
19744
|
+
if (Object.entries(arraysToStratify).some(([arrKey, arr]) => {
|
|
19745
|
+
if (arrKey === "featureValue") {
|
|
19746
|
+
return arr.some((a2) => a2.length !== obsIndex.length);
|
|
19747
|
+
}
|
|
19748
|
+
return arr.length !== obsIndex.length;
|
|
19749
|
+
}))
|
|
19750
|
+
;
|
|
19733
19751
|
const sampleSetInfo = sampleSets && sampleSetSelection ? treeToObsIdsBySetNames(sampleSets, sampleSetSelection) : null;
|
|
19734
19752
|
const cellSetInfo = mergedCellSets && cellSetSelection ? treeToObsIdsBySetNames(mergedCellSets, cellSetSelection) : null;
|
|
19735
19753
|
cellSetKeys.forEach((cellSetKey) => {
|
|
@@ -19759,6 +19777,7 @@ function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetS
|
|
|
19759
19777
|
});
|
|
19760
19778
|
const sampleIdToSetMap = sampleSets && sampleSetSelection ? treeToSelectedSetMap(sampleSets, sampleSetSelection) : null;
|
|
19761
19779
|
const cellIdToSetMap = mergedCellSets && cellSetSelection ? treeToSelectedSetMap(mergedCellSets, cellSetSelection) : null;
|
|
19780
|
+
let cellCount = 0;
|
|
19762
19781
|
for (let i2 = 0; i2 < obsIndex.length; i2 += 1) {
|
|
19763
19782
|
const obsId = obsIndex[i2];
|
|
19764
19783
|
const cellSet = (cellIdToSetMap == null ? void 0 : cellIdToSetMap.get(obsId)) || null;
|
|
@@ -19769,10 +19788,28 @@ function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetS
|
|
|
19769
19788
|
}
|
|
19770
19789
|
const insertionIndex = result.get(cellSet).get(sampleSet).get("i");
|
|
19771
19790
|
arrKeys.forEach((arrKey) => {
|
|
19772
|
-
|
|
19791
|
+
let value;
|
|
19792
|
+
if (arrKey === "featureValue") {
|
|
19793
|
+
if (featureAggregationStrategy === "first") {
|
|
19794
|
+
value = arraysToStratify[arrKey][0][i2];
|
|
19795
|
+
} else if (featureAggregationStrategy === "last") {
|
|
19796
|
+
value = arraysToStratify[arrKey].at(-1)[i2];
|
|
19797
|
+
} else if (typeof featureAggregationStrategy === "number") {
|
|
19798
|
+
const j = featureAggregationStrategy;
|
|
19799
|
+
value = arraysToStratify[arrKey][j][i2];
|
|
19800
|
+
} else if (featureAggregationStrategy === "sum" || featureAggregationStrategy === "mean") {
|
|
19801
|
+
value = arraysToStratify[arrKey].reduce((a2, h) => a2 + h[i2], 0);
|
|
19802
|
+
if (featureAggregationStrategy === "mean") {
|
|
19803
|
+
value /= arraysToStratify[arrKey].length;
|
|
19804
|
+
}
|
|
19805
|
+
}
|
|
19806
|
+
} else {
|
|
19807
|
+
value = arraysToStratify[arrKey][i2];
|
|
19808
|
+
}
|
|
19773
19809
|
result.get(cellSet).get(sampleSet).get(arrKey)[insertionIndex] = value;
|
|
19774
19810
|
});
|
|
19775
19811
|
result.get(cellSet).get(sampleSet).set("i", insertionIndex + 1);
|
|
19812
|
+
cellCount += 1;
|
|
19776
19813
|
}
|
|
19777
19814
|
cellSetKeys.forEach((cellSetKey) => {
|
|
19778
19815
|
sampleSetKeys.forEach((sampleSetKey) => {
|
|
@@ -19783,7 +19820,7 @@ function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetS
|
|
|
19783
19820
|
result.get(cellSetKey).get(sampleSetKey).delete("i");
|
|
19784
19821
|
});
|
|
19785
19822
|
});
|
|
19786
|
-
return result;
|
|
19823
|
+
return [result, cellCount];
|
|
19787
19824
|
}
|
|
19788
19825
|
function tree_add(d) {
|
|
19789
19826
|
var x2 = +this._x.call(null, d), y2 = +this._y.call(null, d);
|
|
@@ -127455,8 +127492,15 @@ class SelectionLayer extends CompositeLayer {
|
|
|
127455
127492
|
if (!nodePolygonContainsSelectedPolygon && !nodePolygonWithinSelectedPolygon && !nodePolygonOverlapsSelectedPolgyon) {
|
|
127456
127493
|
return true;
|
|
127457
127494
|
}
|
|
127458
|
-
if (node.data
|
|
127459
|
-
|
|
127495
|
+
if (node.data) {
|
|
127496
|
+
let current = node;
|
|
127497
|
+
while (current) {
|
|
127498
|
+
const pointCoords = [].slice.call(getObsCoords(current.data));
|
|
127499
|
+
if (booleanPointInPolygon$1(point$1(pointCoords), selectedPolygon)) {
|
|
127500
|
+
pickingInfos.push(current.data);
|
|
127501
|
+
}
|
|
127502
|
+
current = current.next;
|
|
127503
|
+
}
|
|
127460
127504
|
}
|
|
127461
127505
|
return false;
|
|
127462
127506
|
});
|
|
@@ -128668,16 +128712,16 @@ function addDecoder(cases, importFn) {
|
|
|
128668
128712
|
}
|
|
128669
128713
|
cases.forEach((c2) => registry$1.set(c2, importFn));
|
|
128670
128714
|
}
|
|
128671
|
-
addDecoder([void 0, 1], () => import("./raw-
|
|
128672
|
-
addDecoder(5, () => import("./lzw-
|
|
128715
|
+
addDecoder([void 0, 1], () => import("./raw-5d0a1d41.js").then((m2) => m2.default));
|
|
128716
|
+
addDecoder(5, () => import("./lzw-cecbc3f4.js").then((m2) => m2.default));
|
|
128673
128717
|
addDecoder(6, () => {
|
|
128674
128718
|
throw new Error("old style JPEG compression is not supported.");
|
|
128675
128719
|
});
|
|
128676
|
-
addDecoder(7, () => import("./jpeg-
|
|
128677
|
-
addDecoder([8, 32946], () => import("./deflate-
|
|
128678
|
-
addDecoder(32773, () => import("./packbits-
|
|
128679
|
-
addDecoder(34887, () => import("./lerc-
|
|
128680
|
-
addDecoder(50001, () => import("./webimage-
|
|
128720
|
+
addDecoder(7, () => import("./jpeg-ea5d6166.js").then((m2) => m2.default));
|
|
128721
|
+
addDecoder([8, 32946], () => import("./deflate-94dfdd6c.js").then((m2) => m2.default));
|
|
128722
|
+
addDecoder(32773, () => import("./packbits-04a500da.js").then((m2) => m2.default));
|
|
128723
|
+
addDecoder(34887, () => import("./lerc-7e5d53ac.js").then((m2) => m2.default));
|
|
128724
|
+
addDecoder(50001, () => import("./webimage-67a3c5bf.js").then((m2) => m2.default));
|
|
128681
128725
|
function decodeRowAcc(row, stride) {
|
|
128682
128726
|
let length2 = row.length - stride;
|
|
128683
128727
|
let offset5 = 0;
|
|
@@ -149712,7 +149756,10 @@ const getPosition = (object2, { index: index2, data, target }) => {
|
|
|
149712
149756
|
target[2] = POINT_LAYER_Z_INDEX;
|
|
149713
149757
|
return target;
|
|
149714
149758
|
};
|
|
149715
|
-
const contourGetWeight = (object2, { index: index2, data }) =>
|
|
149759
|
+
const contourGetWeight = (object2, { index: index2, data }) => {
|
|
149760
|
+
var _a3;
|
|
149761
|
+
return (_a3 = data.src.featureValues) == null ? void 0 : _a3[index2];
|
|
149762
|
+
};
|
|
149716
149763
|
const contourGetPosition = (object2, { index: index2, data, target }) => {
|
|
149717
149764
|
target[0] = data.src.embeddingX[index2];
|
|
149718
149765
|
target[1] = -data.src.embeddingY[index2];
|
|
@@ -150009,6 +150056,16 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
150009
150056
|
const { obsEmbeddingIndex, obsEmbedding } = this.props;
|
|
150010
150057
|
super.viewInfoDidUpdate(obsEmbeddingIndex, obsEmbedding, makeFlippedGetObsCoords);
|
|
150011
150058
|
}
|
|
150059
|
+
componentWillUnmount() {
|
|
150060
|
+
delete this.cellsQuadTree;
|
|
150061
|
+
delete this.cellsLayer;
|
|
150062
|
+
delete this.cellsData;
|
|
150063
|
+
delete this.stratifiedData;
|
|
150064
|
+
delete this.cellSetsForceSimulation;
|
|
150065
|
+
delete this.cellSetsLabelPrevZoom;
|
|
150066
|
+
delete this.cellSetsLayers;
|
|
150067
|
+
delete this.contourLayers;
|
|
150068
|
+
}
|
|
150012
150069
|
/**
|
|
150013
150070
|
* Here, asynchronously check whether props have
|
|
150014
150071
|
* updated which require re-computing memoized variables,
|
|
@@ -150215,8 +150272,9 @@ if (typeof document !== "undefined") {
|
|
|
150215
150272
|
else
|
|
150216
150273
|
document.addEventListener("DOMContentLoaded", $bbed8b41f857bcc0$var$setupGlobalEvents);
|
|
150217
150274
|
}
|
|
150275
|
+
const FEATURE_AGGREGATION_STRATEGIES = ["first", "last", "sum", "mean"];
|
|
150218
150276
|
function ScatterplotOptions(props) {
|
|
150219
|
-
const { children: children2, observationsLabel, cellRadius, setCellRadius, cellRadiusMode, setCellRadiusMode, cellOpacity, setCellOpacity, cellOpacityMode, setCellOpacityMode, cellSetLabelsVisible, setCellSetLabelsVisible, tooltipsVisible, setTooltipsVisible, cellSetLabelSize, setCellSetLabelSize, cellSetPolygonsVisible, setCellSetPolygonsVisible, cellColorEncoding, setCellColorEncoding, geneExpressionColormap, setGeneExpressionColormap, geneExpressionColormapRange, setGeneExpressionColormapRange, embeddingPointsVisible, setEmbeddingPointsVisible, embeddingContoursVisible, setEmbeddingContoursVisible, embeddingContoursFilled, setEmbeddingContoursFilled, contourPercentiles, setContourPercentiles, defaultContourPercentiles, contourColorEncoding, setContourColorEncoding } = props;
|
|
150277
|
+
const { children: children2, observationsLabel, cellRadius, setCellRadius, cellRadiusMode, setCellRadiusMode, cellOpacity, setCellOpacity, cellOpacityMode, setCellOpacityMode, cellSetLabelsVisible, setCellSetLabelsVisible, tooltipsVisible, setTooltipsVisible, cellSetLabelSize, setCellSetLabelSize, cellSetPolygonsVisible, setCellSetPolygonsVisible, cellColorEncoding, setCellColorEncoding, geneExpressionColormap, setGeneExpressionColormap, geneExpressionColormapRange, setGeneExpressionColormapRange, embeddingPointsVisible, setEmbeddingPointsVisible, embeddingContoursVisible, setEmbeddingContoursVisible, embeddingContoursFilled, setEmbeddingContoursFilled, contourPercentiles, setContourPercentiles, defaultContourPercentiles, contourColorEncoding, setContourColorEncoding, featureAggregationStrategy, setFeatureAggregationStrategy } = props;
|
|
150220
150278
|
const scatterplotOptionsId = $bdb11010cef70236$export$f680877a34711e37();
|
|
150221
150279
|
const observationsLabelNice = capitalize$1(observationsLabel);
|
|
150222
150280
|
const classes = usePlotOptionsStyles();
|
|
@@ -150267,6 +150325,9 @@ function ScatterplotOptions(props) {
|
|
|
150267
150325
|
setContourPercentiles(values2);
|
|
150268
150326
|
}
|
|
150269
150327
|
const handlePercentilesChangeDebounced = useCallback(debounce$2(handlePercentilesChange, 5, { trailing: true }), [handlePercentilesChange]);
|
|
150328
|
+
function handleFeatureAggregationStrategyChange(event) {
|
|
150329
|
+
setFeatureAggregationStrategy(event.target.value);
|
|
150330
|
+
}
|
|
150270
150331
|
return jsxRuntimeExports.jsxs(OptionsContainer, { children: [children2, jsxRuntimeExports.jsx(CellColorEncodingOption, { observationsLabel, cellColorEncoding, setCellColorEncoding }), jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, variant: "head", scope: "row", children: jsxRuntimeExports.jsxs("label", { htmlFor: `scatterplot-set-labels-visible-${scatterplotOptionsId}`, children: [observationsLabelNice, " Set Labels Visible"] }) }), jsxRuntimeExports.jsx(TableCell$1, { className: classes.inputCell, variant: "body", children: jsxRuntimeExports.jsx(Checkbox$1, { className: classes.checkbox, checked: cellSetLabelsVisible, onChange: handleLabelVisibilityChange, name: "scatterplot-option-cell-set-labels", color: "default", inputProps: {
|
|
150271
150332
|
"aria-label": "Show or hide set labels",
|
|
150272
150333
|
id: `scatterplot-set-labels-visible-${scatterplotOptionsId}`
|
|
@@ -150308,7 +150369,9 @@ function ScatterplotOptions(props) {
|
|
|
150308
150369
|
id: `scatterplot-contours-filled-${scatterplotOptionsId}`
|
|
150309
150370
|
} }) })] }), jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, variant: "head", scope: "row", children: jsxRuntimeExports.jsx("label", { htmlFor: `scatterplot-contour-color-encoding-${scatterplotOptionsId}`, children: "Contour Color Encoding" }) }), jsxRuntimeExports.jsx(TableCell$1, { className: classes.inputCell, variant: "body", children: jsxRuntimeExports.jsxs(OptionSelect, { className: classes.select, value: contourColorEncoding, onChange: handleContourColorEncodingChange, inputProps: {
|
|
150310
150371
|
id: `scatterplot-contour-color-encoding-${scatterplotOptionsId}`
|
|
150311
|
-
}, children: [jsxRuntimeExports.jsx("option", { value: "sampleSetSelection", children: "Sample Sets" }), jsxRuntimeExports.jsxs("option", { value: "cellSetSelection", children: [observationsLabelNice, " Sets"] }), jsxRuntimeExports.jsx("option", { value: "staticColor", children: "Static Color" })] }) })] }), jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, variant: "head", scope: "row", children: jsxRuntimeExports.jsx("label", { htmlFor: `scatterplot-contour-percentiles-${scatterplotOptionsId}`, children: "Contour Percentiles" }) }), jsxRuntimeExports.jsx(TableCell$1, { className: classes.inputCell, variant: "body", children: jsxRuntimeExports.jsx(Slider$1, { classes: { root: classes.slider, valueLabel: classes.sliderValueLabel }, value: contourPercentiles || defaultContourPercentiles, onChange: handlePercentilesChangeDebounced, "aria-label": "Scatterplot sliders for contour percentile thresholds", id: `scatterplot-contour-percentiles-${scatterplotOptionsId}`, valueLabelDisplay: "auto", step: 5e-3, min: 9e-3, max: 0.999 }) })] })
|
|
150372
|
+
}, children: [jsxRuntimeExports.jsx("option", { value: "sampleSetSelection", children: "Sample Sets" }), jsxRuntimeExports.jsxs("option", { value: "cellSetSelection", children: [observationsLabelNice, " Sets"] }), jsxRuntimeExports.jsx("option", { value: "staticColor", children: "Static Color" })] }) })] }), jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, variant: "head", scope: "row", children: jsxRuntimeExports.jsx("label", { htmlFor: `scatterplot-contour-percentiles-${scatterplotOptionsId}`, children: "Contour Percentiles" }) }), jsxRuntimeExports.jsx(TableCell$1, { className: classes.inputCell, variant: "body", children: jsxRuntimeExports.jsx(Slider$1, { classes: { root: classes.slider, valueLabel: classes.sliderValueLabel }, value: contourPercentiles || defaultContourPercentiles, onChange: handlePercentilesChangeDebounced, "aria-label": "Scatterplot sliders for contour percentile thresholds", id: `scatterplot-contour-percentiles-${scatterplotOptionsId}`, valueLabelDisplay: "auto", step: 5e-3, min: 9e-3, max: 0.999 }) })] }), setFeatureAggregationStrategy ? jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, variant: "head", scope: "row", children: jsxRuntimeExports.jsx("label", { htmlFor: `feature-aggregation-strategy-${scatterplotOptionsId}`, children: "Feature Aggregation Strategy" }) }), jsxRuntimeExports.jsx(TableCell$1, { className: classes.inputCell, variant: "body", children: jsxRuntimeExports.jsx(OptionSelect, { className: classes.select, value: featureAggregationStrategy ?? "first", onChange: handleFeatureAggregationStrategyChange, inputProps: {
|
|
150373
|
+
id: `feature-aggregation-strategy-${scatterplotOptionsId}`
|
|
150374
|
+
}, children: FEATURE_AGGREGATION_STRATEGIES.map((opt) => jsxRuntimeExports.jsx("option", { value: opt, children: capitalize$1(opt) }, opt)) }) })] }) : null] });
|
|
150312
150375
|
}
|
|
150313
150376
|
const styles10 = makeStyles((theme) => ({
|
|
150314
150377
|
tooltipAnchor: {
|
|
@@ -152819,8 +152882,50 @@ const titleHeight = 10;
|
|
|
152819
152882
|
const rectHeight = 8;
|
|
152820
152883
|
const rectMarginY = 2;
|
|
152821
152884
|
const rectMarginX = 2;
|
|
152885
|
+
function combineExtents(extents, featureAggregationStrategy) {
|
|
152886
|
+
if (Array.isArray(extents)) {
|
|
152887
|
+
if (featureAggregationStrategy === "first") {
|
|
152888
|
+
return extents[0];
|
|
152889
|
+
}
|
|
152890
|
+
if (featureAggregationStrategy === "last") {
|
|
152891
|
+
return extents.at(-1);
|
|
152892
|
+
}
|
|
152893
|
+
if (typeof featureAggregationStrategy === "number") {
|
|
152894
|
+
const i2 = featureAggregationStrategy;
|
|
152895
|
+
return extents[i2];
|
|
152896
|
+
}
|
|
152897
|
+
if (featureAggregationStrategy === "sum") {
|
|
152898
|
+
return extents.reduce((a2, h) => [a2[0] + h[0], a2[1] + h[1]]);
|
|
152899
|
+
}
|
|
152900
|
+
if (featureAggregationStrategy === "mean") {
|
|
152901
|
+
return extents.reduce((a2, h) => [a2[0] + h[0], a2[1] + h[1]]).map((v) => v / extents.length);
|
|
152902
|
+
}
|
|
152903
|
+
}
|
|
152904
|
+
return null;
|
|
152905
|
+
}
|
|
152906
|
+
function combineMissings(missings, featureAggregationStrategy) {
|
|
152907
|
+
if (Array.isArray(missings)) {
|
|
152908
|
+
if (featureAggregationStrategy === "first") {
|
|
152909
|
+
return missings[0];
|
|
152910
|
+
}
|
|
152911
|
+
if (featureAggregationStrategy === "last") {
|
|
152912
|
+
return missings.at(-1);
|
|
152913
|
+
}
|
|
152914
|
+
if (typeof featureAggregationStrategy === "number") {
|
|
152915
|
+
const i2 = featureAggregationStrategy;
|
|
152916
|
+
return missings[i2];
|
|
152917
|
+
}
|
|
152918
|
+
if (featureAggregationStrategy === "sum") {
|
|
152919
|
+
return missings.reduce((a2, h) => a2 + h, 0);
|
|
152920
|
+
}
|
|
152921
|
+
if (featureAggregationStrategy === "mean") {
|
|
152922
|
+
return missings.reduce((a2, h) => a2 + h / missings.length, 0);
|
|
152923
|
+
}
|
|
152924
|
+
}
|
|
152925
|
+
return null;
|
|
152926
|
+
}
|
|
152822
152927
|
function Legend(props) {
|
|
152823
|
-
const { visible: visibleProp, positionRelative = false, highContrast = false, obsType, featureValueType, considerSelections = true, obsColorEncoding, featureSelection, featureLabelsMap, featureValueColormap, featureValueColormapRange, spatialChannelColor, spatialLayerColor, obsSetSelection, obsSetColor, extent: extent2, missing, width = 100, height = 36, theme, showObsLabel = false, pointsVisible = true, contoursVisible = false, contoursFilled, contourPercentiles, contourThresholds } = props;
|
|
152928
|
+
const { visible: visibleProp, positionRelative = false, highContrast = false, obsType, featureValueType, considerSelections = true, obsColorEncoding, featureSelection, featureLabelsMap, featureValueColormap, featureValueColormapRange, spatialChannelColor, spatialLayerColor, obsSetSelection, obsSetColor, featureAggregationStrategy, extent: extent2, missing, width = 100, height = 36, theme, showObsLabel = false, pointsVisible = true, contoursVisible = false, contoursFilled, contourPercentiles, contourThresholds } = props;
|
|
152824
152929
|
const svgRef = useRef();
|
|
152825
152930
|
const classes = useStyles();
|
|
152826
152931
|
const isDarkTheme = theme === "dark";
|
|
@@ -152829,9 +152934,9 @@ function Legend(props) {
|
|
|
152829
152934
|
const layerColor = Array.isArray(spatialLayerColor) && spatialLayerColor.length === 3 ? spatialLayerColor : getDefaultColor(theme);
|
|
152830
152935
|
const channelColor = Array.isArray(spatialChannelColor) && spatialChannelColor.length === 3 ? spatialChannelColor : getDefaultColor(theme);
|
|
152831
152936
|
const staticColor = obsColorEncoding === "spatialChannelColor" ? channelColor : layerColor;
|
|
152832
|
-
const visible = visibleProp && (!considerSelections || obsColorEncoding === "geneSelection" && featureSelection && Array.isArray(featureSelection) && featureSelection.length
|
|
152937
|
+
const visible = visibleProp && (!considerSelections || obsColorEncoding === "geneSelection" && featureSelection && Array.isArray(featureSelection) && featureSelection.length >= 1 || isSetColor && (obsSetSelection == null ? void 0 : obsSetSelection.length) > 0 && (obsSetColor == null ? void 0 : obsSetColor.length) > 0 || isStaticColor);
|
|
152833
152938
|
const levelZeroNames = useMemo(() => Array.from(new Set((obsSetSelection == null ? void 0 : obsSetSelection.map((setPath) => setPath[0])) || [])), [obsSetSelection]);
|
|
152834
|
-
const dynamicHeight = isSetColor ? levelZeroNames.length * titleHeight + (obsSetSelection == null ? void 0 : obsSetSelection.length) * (rectHeight + rectMarginY) : height + (!pointsVisible && contoursVisible ? 25 : 0);
|
|
152939
|
+
const dynamicHeight = isSetColor && obsSetSelection ? levelZeroNames.length * titleHeight + (obsSetSelection == null ? void 0 : obsSetSelection.length) * (rectHeight + rectMarginY) : height + (!pointsVisible && contoursVisible ? 25 : 0);
|
|
152835
152940
|
useEffect(() => {
|
|
152836
152941
|
const domElement = svgRef.current;
|
|
152837
152942
|
const foregroundColor = highContrast ? "black" : isDarkTheme ? "white" : "black";
|
|
@@ -152840,7 +152945,7 @@ function Legend(props) {
|
|
|
152840
152945
|
svg.attr("width", width).attr("height", dynamicHeight);
|
|
152841
152946
|
const g2 = svg.append("g").attr("width", width).attr("height", dynamicHeight);
|
|
152842
152947
|
if (!considerSelections || obsColorEncoding === "geneSelection") {
|
|
152843
|
-
const [xMin, xMax] = extent2 || [0, 1];
|
|
152948
|
+
const [xMin, xMax] = combineExtents(extent2, featureAggregationStrategy) || [0, 1];
|
|
152844
152949
|
if (featureValueColormap && pointsVisible) {
|
|
152845
152950
|
const xlinkHref = getXlinkHref(featureValueColormap);
|
|
152846
152951
|
g2.append("image").attr("x", 0).attr("y", titleHeight).attr("width", width).attr("height", rectHeight).attr("preserveAspectRatio", "none").attr("href", xlinkHref);
|
|
@@ -152904,8 +153009,19 @@ function Legend(props) {
|
|
|
152904
153009
|
});
|
|
152905
153010
|
});
|
|
152906
153011
|
}
|
|
152907
|
-
const featureSelectionLabelRaw = featureSelection && featureSelection.length >= 1 && !isStaticColor ? (featureLabelsMap == null ? void 0 : featureLabelsMap.get(
|
|
152908
|
-
|
|
153012
|
+
const featureSelectionLabelRaw = featureSelection && featureSelection.length >= 1 && !isStaticColor ? featureSelection.map((geneName) => (featureLabelsMap == null ? void 0 : featureLabelsMap.get(geneName)) || (featureLabelsMap == null ? void 0 : featureLabelsMap.get(cleanFeatureId(geneName))) || geneName) : null;
|
|
153013
|
+
let featureSelectionLabelRawStr = "";
|
|
153014
|
+
if (featureAggregationStrategy === "first") {
|
|
153015
|
+
featureSelectionLabelRawStr = featureSelectionLabelRaw == null ? void 0 : featureSelectionLabelRaw[0];
|
|
153016
|
+
} else if (featureAggregationStrategy === "last") {
|
|
153017
|
+
featureSelectionLabelRawStr = featureSelectionLabelRaw == null ? void 0 : featureSelectionLabelRaw.at(-1);
|
|
153018
|
+
} else if (featureAggregationStrategy === "sum") {
|
|
153019
|
+
featureSelectionLabelRawStr = "Sum of features";
|
|
153020
|
+
} else if (featureAggregationStrategy === "mean") {
|
|
153021
|
+
featureSelectionLabelRawStr = "Mean of features";
|
|
153022
|
+
}
|
|
153023
|
+
const combinedMissing = combineMissings(missing, featureAggregationStrategy);
|
|
153024
|
+
const featureSelectionLabel = combinedMissing ? `${featureSelectionLabelRawStr} (${Math.round(combinedMissing * 100)}% NaN)` : featureSelectionLabelRawStr;
|
|
152909
153025
|
const obsLabel = capitalize$1(obsType);
|
|
152910
153026
|
const featureLabel = considerSelections ? featureSelectionLabel || capitalize$1(featureValueType) : capitalize$1(featureValueType);
|
|
152911
153027
|
const mainLabel = showObsLabel ? obsLabel : featureLabel;
|
|
@@ -152939,7 +153055,8 @@ function Legend(props) {
|
|
|
152939
153055
|
contourThresholds,
|
|
152940
153056
|
contoursFilled,
|
|
152941
153057
|
contoursVisible,
|
|
152942
|
-
pointsVisible
|
|
153058
|
+
pointsVisible,
|
|
153059
|
+
featureAggregationStrategy
|
|
152943
153060
|
]);
|
|
152944
153061
|
return jsxRuntimeExports.jsx("div", { className: clsx(classes.legend, {
|
|
152945
153062
|
[classes.legendRelative]: positionRelative,
|
|
@@ -152981,6 +153098,7 @@ makeStyles(() => ({
|
|
|
152981
153098
|
}
|
|
152982
153099
|
}));
|
|
152983
153100
|
const DEFAULT_CONTOUR_PERCENTILES = [0.09, 0.9, 0.99];
|
|
153101
|
+
const DEFAULT_FEATURE_AGGREGATION_STRATEGY = "first";
|
|
152984
153102
|
function EmbeddingScatterplotSubscriber(props) {
|
|
152985
153103
|
const {
|
|
152986
153104
|
uuid,
|
|
@@ -153035,7 +153153,8 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153035
153153
|
embeddingContoursFilled,
|
|
153036
153154
|
embeddingContourPercentiles: contourPercentiles,
|
|
153037
153155
|
contourColorEncoding,
|
|
153038
|
-
contourColor
|
|
153156
|
+
contourColor,
|
|
153157
|
+
featureAggregationStrategy
|
|
153039
153158
|
}, {
|
|
153040
153159
|
setEmbeddingZoom: setZoom,
|
|
153041
153160
|
setEmbeddingTargetX: setTargetX,
|
|
@@ -153061,7 +153180,8 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153061
153180
|
setEmbeddingContoursVisible,
|
|
153062
153181
|
setEmbeddingContoursFilled,
|
|
153063
153182
|
setEmbeddingContourPercentiles: setContourPercentiles,
|
|
153064
|
-
setContourColorEncoding
|
|
153183
|
+
setContourColorEncoding,
|
|
153184
|
+
setFeatureAggregationStrategy
|
|
153065
153185
|
}] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SCATTERPLOT], coordinationScopes);
|
|
153066
153186
|
const {
|
|
153067
153187
|
embeddingZoom: initialZoom,
|
|
@@ -153073,6 +153193,7 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153073
153193
|
);
|
|
153074
153194
|
const observationsLabel = observationsLabelOverride || obsType;
|
|
153075
153195
|
const sampleSetSelection = sampleSetSelectionFromProps || sampleSetSelectionFromCoordination;
|
|
153196
|
+
const featureAggregationStrategyToUse = featureAggregationStrategy ?? DEFAULT_FEATURE_AGGREGATION_STRATEGY;
|
|
153076
153197
|
const [width, height, deckRef] = useDeckCanvasSize();
|
|
153077
153198
|
const title = titleOverride || `Scatterplot (${mapping})`;
|
|
153078
153199
|
const [obsLabelsTypes, obsLabelsData] = useMultiObsLabels(
|
|
@@ -153249,7 +153370,7 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153249
153370
|
return [null, null, null, null, null];
|
|
153250
153371
|
}, [obsEmbedding]);
|
|
153251
153372
|
useEffect(() => {
|
|
153252
|
-
if (xRange && yRange) {
|
|
153373
|
+
if (xRange && yRange && width && height) {
|
|
153253
153374
|
const pointSizeDevicePixels = getPointSizeDevicePixels(
|
|
153254
153375
|
window.devicePixelRatio,
|
|
153255
153376
|
zoom,
|
|
@@ -153342,6 +153463,9 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153342
153463
|
originalViewState.target[1]
|
|
153343
153464
|
];
|
|
153344
153465
|
const scaleFactor = 2 ** originalViewState.zoom;
|
|
153466
|
+
if (!(typeof scaleFactor === "number" && typeof center2[0] === "number" && typeof center2[1] === "number") || Number.isNaN(scaleFactor)) {
|
|
153467
|
+
return null;
|
|
153468
|
+
}
|
|
153345
153469
|
const radius = Math.min(width, height) / 2 / scaleFactor;
|
|
153346
153470
|
const numPoints = 96;
|
|
153347
153471
|
const options = { steps: numPoints, units: "degrees" };
|
|
@@ -153386,9 +153510,9 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153386
153510
|
}
|
|
153387
153511
|
return null;
|
|
153388
153512
|
}, [sampleEdges]);
|
|
153389
|
-
const stratifiedData = useMemo(() => {
|
|
153513
|
+
const [stratifiedData, stratifiedDataCount] = useMemo(() => {
|
|
153390
153514
|
if (alignedEmbeddingData == null ? void 0 : alignedEmbeddingData.data) {
|
|
153391
|
-
const result = stratifyArrays(
|
|
153515
|
+
const [result, cellCountResult] = stratifyArrays(
|
|
153392
153516
|
sampleEdges,
|
|
153393
153517
|
sampleIdToObsIdsMap,
|
|
153394
153518
|
sampleSets,
|
|
@@ -153399,13 +153523,13 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153399
153523
|
{
|
|
153400
153524
|
obsEmbeddingX: alignedEmbeddingData.data[0],
|
|
153401
153525
|
obsEmbeddingY: alignedEmbeddingData.data[1],
|
|
153402
|
-
|
|
153403
|
-
|
|
153404
|
-
|
|
153526
|
+
...(uint8ExpressionData == null ? void 0 : uint8ExpressionData[0]) ? { featureValue: uint8ExpressionData } : {}
|
|
153527
|
+
},
|
|
153528
|
+
featureAggregationStrategyToUse
|
|
153405
153529
|
);
|
|
153406
|
-
return result;
|
|
153530
|
+
return [result, cellCountResult];
|
|
153407
153531
|
}
|
|
153408
|
-
return null;
|
|
153532
|
+
return [null, null];
|
|
153409
153533
|
}, [
|
|
153410
153534
|
alignedEmbeddingIndex,
|
|
153411
153535
|
alignedEmbeddingData,
|
|
@@ -153415,7 +153539,8 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153415
153539
|
sampleSets,
|
|
153416
153540
|
sampleSetSelection,
|
|
153417
153541
|
cellSetSelection,
|
|
153418
|
-
mergedCellSets
|
|
153542
|
+
mergedCellSets,
|
|
153543
|
+
featureAggregationStrategyToUse
|
|
153419
153544
|
]);
|
|
153420
153545
|
const setViewState = ({ zoom: newZoom, target }) => {
|
|
153421
153546
|
setZoom(newZoom);
|
|
@@ -153423,11 +153548,12 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153423
153548
|
setTargetY(target[1]);
|
|
153424
153549
|
setTargetZ(target[2] || 0);
|
|
153425
153550
|
};
|
|
153551
|
+
const cellCountToUse = embeddingPointsVisible ? cellsCount : stratifiedDataCount ?? cellsCount;
|
|
153426
153552
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
153427
153553
|
TitleInfo,
|
|
153428
153554
|
{
|
|
153429
153555
|
title,
|
|
153430
|
-
info: `${commaNumber(
|
|
153556
|
+
info: `${commaNumber(cellCountToUse)} ${pluralize(observationsLabel, cellCountToUse)}`,
|
|
153431
153557
|
closeButtonVisible,
|
|
153432
153558
|
downloadButtonVisible,
|
|
153433
153559
|
removeGridComponent,
|
|
@@ -153471,7 +153597,9 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153471
153597
|
setContourPercentiles,
|
|
153472
153598
|
defaultContourPercentiles: DEFAULT_CONTOUR_PERCENTILES,
|
|
153473
153599
|
contourColorEncoding,
|
|
153474
|
-
setContourColorEncoding
|
|
153600
|
+
setContourColorEncoding,
|
|
153601
|
+
featureAggregationStrategy,
|
|
153602
|
+
setFeatureAggregationStrategy
|
|
153475
153603
|
}
|
|
153476
153604
|
),
|
|
153477
153605
|
children: [
|
|
@@ -153523,7 +153651,7 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153523
153651
|
featureSelection: geneSelection
|
|
153524
153652
|
}
|
|
153525
153653
|
),
|
|
153526
|
-
tooltipsVisible && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
153654
|
+
tooltipsVisible && width && height ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
153527
153655
|
ScatterplotTooltipSubscriber,
|
|
153528
153656
|
{
|
|
153529
153657
|
parentUuid: uuid,
|
|
@@ -153534,7 +153662,7 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153534
153662
|
featureType,
|
|
153535
153663
|
featureLabelsMap
|
|
153536
153664
|
}
|
|
153537
|
-
),
|
|
153665
|
+
) : null,
|
|
153538
153666
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
153539
153667
|
Legend,
|
|
153540
153668
|
{
|
|
@@ -153548,13 +153676,14 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153548
153676
|
featureValueColormap: geneExpressionColormap,
|
|
153549
153677
|
featureValueColormapRange: geneExpressionColormapRange,
|
|
153550
153678
|
obsSetSelection: cellSetSelection,
|
|
153551
|
-
extent: expressionExtents
|
|
153552
|
-
missing: expressionMissing
|
|
153679
|
+
extent: expressionExtents,
|
|
153680
|
+
missing: expressionMissing,
|
|
153553
153681
|
pointsVisible: embeddingPointsVisible,
|
|
153554
153682
|
contoursVisible: embeddingContoursVisible,
|
|
153555
153683
|
contoursFilled: embeddingContoursFilled,
|
|
153556
153684
|
contourPercentiles: contourPercentiles || DEFAULT_CONTOUR_PERCENTILES,
|
|
153557
|
-
contourThresholds
|
|
153685
|
+
contourThresholds,
|
|
153686
|
+
featureAggregationStrategy: featureAggregationStrategyToUse
|
|
153558
153687
|
}
|
|
153559
153688
|
)
|
|
153560
153689
|
]
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as inflate_1 } from "./pako.esm-68f84e2a.js";
|
|
2
|
-
import { g as getDefaultExportFromCjs, B as BaseDecoder } from "./index-
|
|
2
|
+
import { g as getDefaultExportFromCjs, B as BaseDecoder } from "./index-de0a204e.js";
|
|
3
3
|
import "react";
|
|
4
4
|
import "@vitessce/vit-s";
|
|
5
5
|
import "react-dom";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmbeddingScatterplotSubscriber.d.ts","sourceRoot":"","sources":["../src/EmbeddingScatterplotSubscriber.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"EmbeddingScatterplotSubscriber.d.ts","sourceRoot":"","sources":["../src/EmbeddingScatterplotSubscriber.js"],"names":[],"mappings":"AA4CA;;;;;;;;;;;;GAYG;AACH,sDAVG;IAAsB,IAAI,EAAlB,MAAM;IACQ,KAAK,EAAnB,MAAM;IACQ,kBAAkB,EAAhC,MAAM;IAEU,mBAAmB;IAErB,KAAK,EAAnB,MAAM;IACQ,kBAAkB,EAAhC,MAAM;CAEhB,eAkkBA"}
|
|
@@ -10,6 +10,7 @@ import { Scatterplot, ScatterplotTooltipSubscriber, ScatterplotOptions, getPoint
|
|
|
10
10
|
import { Legend } from '@vitessce/legend';
|
|
11
11
|
import { ViewType, COMPONENT_COORDINATION_TYPES, ViewHelpMapping } from '@vitessce/constants-internal';
|
|
12
12
|
import { DEFAULT_CONTOUR_PERCENTILES } from './constants.js';
|
|
13
|
+
const DEFAULT_FEATURE_AGGREGATION_STRATEGY = 'first';
|
|
13
14
|
/**
|
|
14
15
|
* A subscriber component for the scatterplot.
|
|
15
16
|
* @param {object} props
|
|
@@ -33,11 +34,13 @@ export function EmbeddingScatterplotSubscriber(props) {
|
|
|
33
34
|
const setComponentHover = useSetComponentHover();
|
|
34
35
|
const setComponentViewInfo = useSetComponentViewInfo(uuid);
|
|
35
36
|
// Get "props" from the coordination space.
|
|
36
|
-
const [{ dataset, obsType, featureType, featureValueType, sampleType, embeddingZoom: zoom, embeddingTargetX: targetX, embeddingTargetY: targetY, embeddingTargetZ: targetZ, embeddingType: mapping, obsFilter: cellFilter, obsHighlight: cellHighlight, featureSelection: geneSelection, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, obsColorEncoding: cellColorEncoding, additionalObsSets: additionalCellSets, embeddingObsSetPolygonsVisible: cellSetPolygonsVisible, embeddingObsSetLabelsVisible: cellSetLabelsVisible, embeddingObsSetLabelSize: cellSetLabelSize, embeddingObsRadius: cellRadiusFixed, embeddingObsRadiusMode: cellRadiusMode, embeddingObsOpacity: cellOpacityFixed, embeddingObsOpacityMode: cellOpacityMode, featureValueColormap: geneExpressionColormap, featureValueColormapRange: geneExpressionColormapRange, tooltipsVisible, sampleSetSelection: sampleSetSelectionFromCoordination, sampleSetColor, embeddingPointsVisible, embeddingContoursVisible, embeddingContoursFilled, embeddingContourPercentiles: contourPercentiles, contourColorEncoding, contourColor, }, { setEmbeddingZoom: setZoom, setEmbeddingTargetX: setTargetX, setEmbeddingTargetY: setTargetY, setEmbeddingTargetZ: setTargetZ, setObsFilter: setCellFilter, setObsSetSelection: setCellSetSelection, setObsHighlight: setCellHighlight, setObsSetColor: setCellSetColor, setObsColorEncoding: setCellColorEncoding, setAdditionalObsSets: setAdditionalCellSets, setEmbeddingObsSetPolygonsVisible: setCellSetPolygonsVisible, setEmbeddingObsSetLabelsVisible: setCellSetLabelsVisible, setEmbeddingObsSetLabelSize: setCellSetLabelSize, setEmbeddingObsRadius: setCellRadiusFixed, setEmbeddingObsRadiusMode: setCellRadiusMode, setEmbeddingObsOpacity: setCellOpacityFixed, setEmbeddingObsOpacityMode: setCellOpacityMode, setFeatureValueColormap: setGeneExpressionColormap, setFeatureValueColormapRange: setGeneExpressionColormapRange, setTooltipsVisible, setEmbeddingPointsVisible, setEmbeddingContoursVisible, setEmbeddingContoursFilled, setEmbeddingContourPercentiles: setContourPercentiles, setContourColorEncoding, }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType.SCATTERPLOT], coordinationScopes);
|
|
37
|
+
const [{ dataset, obsType, featureType, featureValueType, sampleType, embeddingZoom: zoom, embeddingTargetX: targetX, embeddingTargetY: targetY, embeddingTargetZ: targetZ, embeddingType: mapping, obsFilter: cellFilter, obsHighlight: cellHighlight, featureSelection: geneSelection, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, obsColorEncoding: cellColorEncoding, additionalObsSets: additionalCellSets, embeddingObsSetPolygonsVisible: cellSetPolygonsVisible, embeddingObsSetLabelsVisible: cellSetLabelsVisible, embeddingObsSetLabelSize: cellSetLabelSize, embeddingObsRadius: cellRadiusFixed, embeddingObsRadiusMode: cellRadiusMode, embeddingObsOpacity: cellOpacityFixed, embeddingObsOpacityMode: cellOpacityMode, featureValueColormap: geneExpressionColormap, featureValueColormapRange: geneExpressionColormapRange, tooltipsVisible, sampleSetSelection: sampleSetSelectionFromCoordination, sampleSetColor, embeddingPointsVisible, embeddingContoursVisible, embeddingContoursFilled, embeddingContourPercentiles: contourPercentiles, contourColorEncoding, contourColor, featureAggregationStrategy, }, { setEmbeddingZoom: setZoom, setEmbeddingTargetX: setTargetX, setEmbeddingTargetY: setTargetY, setEmbeddingTargetZ: setTargetZ, setObsFilter: setCellFilter, setObsSetSelection: setCellSetSelection, setObsHighlight: setCellHighlight, setObsSetColor: setCellSetColor, setObsColorEncoding: setCellColorEncoding, setAdditionalObsSets: setAdditionalCellSets, setEmbeddingObsSetPolygonsVisible: setCellSetPolygonsVisible, setEmbeddingObsSetLabelsVisible: setCellSetLabelsVisible, setEmbeddingObsSetLabelSize: setCellSetLabelSize, setEmbeddingObsRadius: setCellRadiusFixed, setEmbeddingObsRadiusMode: setCellRadiusMode, setEmbeddingObsOpacity: setCellOpacityFixed, setEmbeddingObsOpacityMode: setCellOpacityMode, setFeatureValueColormap: setGeneExpressionColormap, setFeatureValueColormapRange: setGeneExpressionColormapRange, setTooltipsVisible, setEmbeddingPointsVisible, setEmbeddingContoursVisible, setEmbeddingContoursFilled, setEmbeddingContourPercentiles: setContourPercentiles, setContourColorEncoding, setFeatureAggregationStrategy, }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType.SCATTERPLOT], coordinationScopes);
|
|
37
38
|
const { embeddingZoom: initialZoom, embeddingTargetX: initialTargetX, embeddingTargetY: initialTargetY, } = useInitialCoordination(COMPONENT_COORDINATION_TYPES[ViewType.SCATTERPLOT], coordinationScopes);
|
|
38
39
|
const observationsLabel = observationsLabelOverride || obsType;
|
|
39
40
|
const sampleSetSelection = (sampleSetSelectionFromProps
|
|
40
41
|
|| sampleSetSelectionFromCoordination);
|
|
42
|
+
const featureAggregationStrategyToUse = featureAggregationStrategy
|
|
43
|
+
?? DEFAULT_FEATURE_AGGREGATION_STRATEGY;
|
|
41
44
|
const [width, height, deckRef] = useDeckCanvasSize();
|
|
42
45
|
const title = titleOverride || `Scatterplot (${mapping})`;
|
|
43
46
|
const [obsLabelsTypes, obsLabelsData] = useMultiObsLabels(coordinationScopes, obsType, loaders, dataset);
|
|
@@ -129,7 +132,7 @@ export function EmbeddingScatterplotSubscriber(props) {
|
|
|
129
132
|
// compute the cell radius scale based on the
|
|
130
133
|
// extents of the cell coordinates on the x/y axes.
|
|
131
134
|
useEffect(() => {
|
|
132
|
-
if (xRange && yRange) {
|
|
135
|
+
if (xRange && yRange && width && height) {
|
|
133
136
|
const pointSizeDevicePixels = getPointSizeDevicePixels(window.devicePixelRatio, zoom, xRange, yRange, width, height);
|
|
134
137
|
setDynamicCellRadius(pointSizeDevicePixels);
|
|
135
138
|
const nextCellOpacityScale = getPointOpacity(zoom, xRange, yRange, width, height, numCells, averageFillDensity);
|
|
@@ -204,6 +207,9 @@ export function EmbeddingScatterplotSubscriber(props) {
|
|
|
204
207
|
originalViewState.target[1],
|
|
205
208
|
];
|
|
206
209
|
const scaleFactor = (2 ** originalViewState.zoom);
|
|
210
|
+
if (!(typeof scaleFactor === 'number' && typeof center[0] === 'number' && typeof center[1] === 'number') || Number.isNaN(scaleFactor)) {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
207
213
|
const radius = Math.min(width, height) / 2 / scaleFactor;
|
|
208
214
|
const numPoints = 96;
|
|
209
215
|
const options = { steps: numPoints, units: 'degrees' };
|
|
@@ -263,20 +269,19 @@ export function EmbeddingScatterplotSubscriber(props) {
|
|
|
263
269
|
return null;
|
|
264
270
|
}, [sampleEdges]);
|
|
265
271
|
// Stratify multiple arrays: per-cellSet and per-sampleSet.
|
|
266
|
-
const stratifiedData = useMemo(() => {
|
|
272
|
+
const [stratifiedData, stratifiedDataCount] = useMemo(() => {
|
|
267
273
|
if (alignedEmbeddingData?.data) {
|
|
268
|
-
const result = stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetSelection, alignedEmbeddingIndex, mergedCellSets, cellSetSelection, {
|
|
274
|
+
const [result, cellCountResult] = stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetSelection, alignedEmbeddingIndex, mergedCellSets, cellSetSelection, {
|
|
269
275
|
obsEmbeddingX: alignedEmbeddingData.data[0],
|
|
270
276
|
obsEmbeddingY: alignedEmbeddingData.data[1],
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
return result;
|
|
277
|
+
...(uint8ExpressionData?.[0] ? { featureValue: uint8ExpressionData } : {}),
|
|
278
|
+
}, featureAggregationStrategyToUse);
|
|
279
|
+
return [result, cellCountResult];
|
|
275
280
|
}
|
|
276
|
-
return null;
|
|
281
|
+
return [null, null];
|
|
277
282
|
}, [alignedEmbeddingIndex, alignedEmbeddingData, uint8ExpressionData,
|
|
278
283
|
sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetSelection,
|
|
279
|
-
cellSetSelection, mergedCellSets,
|
|
284
|
+
cellSetSelection, mergedCellSets, featureAggregationStrategyToUse,
|
|
280
285
|
]);
|
|
281
286
|
const setViewState = ({ zoom: newZoom, target }) => {
|
|
282
287
|
setZoom(newZoom);
|
|
@@ -284,12 +289,16 @@ export function EmbeddingScatterplotSubscriber(props) {
|
|
|
284
289
|
setTargetY(target[1]);
|
|
285
290
|
setTargetZ(target[2] || 0);
|
|
286
291
|
};
|
|
287
|
-
|
|
292
|
+
// TODO: Update this once the rendered points reflects the selection/filtering.
|
|
293
|
+
const cellCountToUse = embeddingPointsVisible
|
|
294
|
+
? cellsCount
|
|
295
|
+
: (stratifiedDataCount ?? cellsCount);
|
|
296
|
+
return (_jsxs(TitleInfo, { title: title, info: `${commaNumber(cellCountToUse)} ${plur(observationsLabel, cellCountToUse)}`, closeButtonVisible: closeButtonVisible, downloadButtonVisible: downloadButtonVisible, removeGridComponent: removeGridComponent, urls: urls, theme: theme, isReady: isReady, helpText: helpText, options: (_jsx(ScatterplotOptions, { observationsLabel: observationsLabel, cellRadius: cellRadiusFixed, setCellRadius: setCellRadiusFixed, cellRadiusMode: cellRadiusMode, setCellRadiusMode: setCellRadiusMode, cellOpacity: cellOpacityFixed, setCellOpacity: setCellOpacityFixed, cellOpacityMode: cellOpacityMode, setCellOpacityMode: setCellOpacityMode, cellSetLabelsVisible: cellSetLabelsVisible, setCellSetLabelsVisible: setCellSetLabelsVisible, tooltipsVisible: tooltipsVisible, setTooltipsVisible: setTooltipsVisible, cellSetLabelSize: cellSetLabelSize, setCellSetLabelSize: setCellSetLabelSize, cellSetPolygonsVisible: cellSetPolygonsVisible, setCellSetPolygonsVisible: setCellSetPolygonsVisible, cellColorEncoding: cellColorEncoding, setCellColorEncoding: setCellColorEncoding, geneExpressionColormap: geneExpressionColormap, setGeneExpressionColormap: setGeneExpressionColormap, geneExpressionColormapRange: geneExpressionColormapRange, setGeneExpressionColormapRange: setGeneExpressionColormapRange, embeddingPointsVisible: embeddingPointsVisible, setEmbeddingPointsVisible: setEmbeddingPointsVisible, embeddingContoursVisible: embeddingContoursVisible, setEmbeddingContoursVisible: setEmbeddingContoursVisible, embeddingContoursFilled: embeddingContoursFilled, setEmbeddingContoursFilled: setEmbeddingContoursFilled, contourPercentiles: contourPercentiles, setContourPercentiles: setContourPercentiles, defaultContourPercentiles: DEFAULT_CONTOUR_PERCENTILES, contourColorEncoding: contourColorEncoding, setContourColorEncoding: setContourColorEncoding, featureAggregationStrategy: featureAggregationStrategy, setFeatureAggregationStrategy: setFeatureAggregationStrategy })), children: [_jsx(Scatterplot, { ref: deckRef, uuid: uuid, theme: theme, viewState: { zoom, target: [targetX, targetY, targetZ] }, setViewState: setViewState, originalViewState: originalViewState, obsEmbeddingIndex: obsEmbeddingIndex, obsEmbedding: obsEmbedding, cellFilter: cellFilter, cellSelection: cellSelection, cellHighlight: cellHighlight, cellColors: cellColors, cellSetPolygons: cellSetPolygons, cellSetLabelSize: cellSetLabelSize, cellSetLabelsVisible: cellSetLabelsVisible, cellSetPolygonsVisible: cellSetPolygonsVisible, setCellFilter: setCellFilter, setCellSelection: setCellSelectionProp, setCellHighlight: setCellHighlight, cellRadius: cellRadius, cellOpacity: cellOpacity, cellColorEncoding: cellColorEncoding, geneExpressionColormap: geneExpressionColormap, geneExpressionColormapRange: geneExpressionColormapRange, setComponentHover: () => {
|
|
288
297
|
setComponentHover(uuid);
|
|
289
298
|
}, updateViewInfo: setComponentViewInfo, getExpressionValue: getExpressionValue, getCellIsSelected: getCellIsSelected, obsSetSelection: cellSetSelection, sampleSetSelection: sampleSetSelection,
|
|
290
299
|
// InternMap data structures where keys are
|
|
291
300
|
// obsSet -> sampleSet -> arrayKey -> [].
|
|
292
|
-
stratifiedData: stratifiedData, obsSetColor: cellSetColor, sampleSetColor: sampleSetColor, contourThresholds: contourThresholds, contourColorEncoding: contourColorEncoding, contourColor: contourColor, contoursFilled: embeddingContoursFilled, embeddingPointsVisible: embeddingPointsVisible, embeddingContoursVisible: embeddingContoursVisible, circleInfo: circleInfo, featureSelection: geneSelection }), tooltipsVisible && (_jsx(ScatterplotTooltipSubscriber, { parentUuid: uuid, obsHighlight: cellHighlight, width: width, height: height, getObsInfo: getObsInfo, featureType: featureType, featureLabelsMap: featureLabelsMap })), _jsx(Legend, { visible: true, theme: theme, featureType: featureType, featureValueType: featureValueType, obsColorEncoding: cellColorEncoding, featureSelection: geneSelection, featureLabelsMap: featureLabelsMap, featureValueColormap: geneExpressionColormap, featureValueColormapRange: geneExpressionColormapRange, obsSetSelection: cellSetSelection, extent: expressionExtents
|
|
301
|
+
stratifiedData: stratifiedData, obsSetColor: cellSetColor, sampleSetColor: sampleSetColor, contourThresholds: contourThresholds, contourColorEncoding: contourColorEncoding, contourColor: contourColor, contoursFilled: embeddingContoursFilled, embeddingPointsVisible: embeddingPointsVisible, embeddingContoursVisible: embeddingContoursVisible, circleInfo: circleInfo, featureSelection: geneSelection }), tooltipsVisible && width && height ? (_jsx(ScatterplotTooltipSubscriber, { parentUuid: uuid, obsHighlight: cellHighlight, width: width, height: height, getObsInfo: getObsInfo, featureType: featureType, featureLabelsMap: featureLabelsMap })) : null, _jsx(Legend, { visible: true, theme: theme, featureType: featureType, featureValueType: featureValueType, obsColorEncoding: cellColorEncoding, featureSelection: geneSelection, featureLabelsMap: featureLabelsMap, featureValueColormap: geneExpressionColormap, featureValueColormapRange: geneExpressionColormapRange, obsSetSelection: cellSetSelection, extent: expressionExtents, missing: expressionMissing,
|
|
293
302
|
// Contour percentile legend
|
|
294
|
-
pointsVisible: embeddingPointsVisible, contoursVisible: embeddingContoursVisible, contoursFilled: embeddingContoursFilled, contourPercentiles: contourPercentiles || DEFAULT_CONTOUR_PERCENTILES, contourThresholds: contourThresholds })] }));
|
|
303
|
+
pointsVisible: embeddingPointsVisible, contoursVisible: embeddingContoursVisible, contoursFilled: embeddingContoursFilled, contourPercentiles: contourPercentiles || DEFAULT_CONTOUR_PERCENTILES, contourThresholds: contourThresholds, featureAggregationStrategy: featureAggregationStrategyToUse })] }));
|
|
295
304
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitessce/scatterplot-embedding",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.12",
|
|
4
4
|
"author": "HIDIVE Lab at HMS",
|
|
5
5
|
"homepage": "http://vitessce.io",
|
|
6
6
|
"repository": {
|
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
"lodash-es": "^4.17.21",
|
|
22
22
|
"react-aria": "^3.28.0",
|
|
23
23
|
"@turf/circle": "^7.2.0",
|
|
24
|
-
"@vitessce/constants-internal": "3.5.
|
|
25
|
-
"@vitessce/legend": "3.5.
|
|
26
|
-
"@vitessce/scatterplot": "3.5.
|
|
27
|
-
"@vitessce/sets-utils": "3.5.
|
|
28
|
-
"@vitessce/utils": "3.5.
|
|
29
|
-
"@vitessce/vit-s": "3.5.
|
|
24
|
+
"@vitessce/constants-internal": "3.5.12",
|
|
25
|
+
"@vitessce/legend": "3.5.12",
|
|
26
|
+
"@vitessce/scatterplot": "3.5.12",
|
|
27
|
+
"@vitessce/sets-utils": "3.5.12",
|
|
28
|
+
"@vitessce/utils": "3.5.12",
|
|
29
|
+
"@vitessce/vit-s": "3.5.12"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"react": "^18.0.0",
|
|
@@ -40,6 +40,7 @@ import { Legend } from '@vitessce/legend';
|
|
|
40
40
|
import { ViewType, COMPONENT_COORDINATION_TYPES, ViewHelpMapping } from '@vitessce/constants-internal';
|
|
41
41
|
import { DEFAULT_CONTOUR_PERCENTILES } from './constants.js';
|
|
42
42
|
|
|
43
|
+
const DEFAULT_FEATURE_AGGREGATION_STRATEGY = 'first';
|
|
43
44
|
|
|
44
45
|
/**
|
|
45
46
|
* A subscriber component for the scatterplot.
|
|
@@ -113,6 +114,7 @@ export function EmbeddingScatterplotSubscriber(props) {
|
|
|
113
114
|
embeddingContourPercentiles: contourPercentiles,
|
|
114
115
|
contourColorEncoding,
|
|
115
116
|
contourColor,
|
|
117
|
+
featureAggregationStrategy,
|
|
116
118
|
}, {
|
|
117
119
|
setEmbeddingZoom: setZoom,
|
|
118
120
|
setEmbeddingTargetX: setTargetX,
|
|
@@ -139,6 +141,7 @@ export function EmbeddingScatterplotSubscriber(props) {
|
|
|
139
141
|
setEmbeddingContoursFilled,
|
|
140
142
|
setEmbeddingContourPercentiles: setContourPercentiles,
|
|
141
143
|
setContourColorEncoding,
|
|
144
|
+
setFeatureAggregationStrategy,
|
|
142
145
|
}] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType.SCATTERPLOT], coordinationScopes);
|
|
143
146
|
|
|
144
147
|
const {
|
|
@@ -155,6 +158,9 @@ export function EmbeddingScatterplotSubscriber(props) {
|
|
|
155
158
|
|| sampleSetSelectionFromCoordination
|
|
156
159
|
);
|
|
157
160
|
|
|
161
|
+
const featureAggregationStrategyToUse = featureAggregationStrategy
|
|
162
|
+
?? DEFAULT_FEATURE_AGGREGATION_STRATEGY;
|
|
163
|
+
|
|
158
164
|
const [width, height, deckRef] = useDeckCanvasSize();
|
|
159
165
|
|
|
160
166
|
const title = titleOverride || `Scatterplot (${mapping})`;
|
|
@@ -299,7 +305,7 @@ export function EmbeddingScatterplotSubscriber(props) {
|
|
|
299
305
|
// compute the cell radius scale based on the
|
|
300
306
|
// extents of the cell coordinates on the x/y axes.
|
|
301
307
|
useEffect(() => {
|
|
302
|
-
if (xRange && yRange) {
|
|
308
|
+
if (xRange && yRange && width && height) {
|
|
303
309
|
const pointSizeDevicePixels = getPointSizeDevicePixels(
|
|
304
310
|
window.devicePixelRatio, zoom, xRange, yRange, width, height,
|
|
305
311
|
);
|
|
@@ -395,6 +401,9 @@ export function EmbeddingScatterplotSubscriber(props) {
|
|
|
395
401
|
originalViewState.target[1],
|
|
396
402
|
];
|
|
397
403
|
const scaleFactor = (2 ** originalViewState.zoom);
|
|
404
|
+
if (!(typeof scaleFactor === 'number' && typeof center[0] === 'number' && typeof center[1] === 'number') || Number.isNaN(scaleFactor)) {
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
398
407
|
const radius = Math.min(width, height) / 2 / scaleFactor;
|
|
399
408
|
const numPoints = 96;
|
|
400
409
|
const options = { steps: numPoints, units: 'degrees' };
|
|
@@ -457,24 +466,23 @@ export function EmbeddingScatterplotSubscriber(props) {
|
|
|
457
466
|
}, [sampleEdges]);
|
|
458
467
|
|
|
459
468
|
// Stratify multiple arrays: per-cellSet and per-sampleSet.
|
|
460
|
-
const stratifiedData = useMemo(() => {
|
|
469
|
+
const [stratifiedData, stratifiedDataCount] = useMemo(() => {
|
|
461
470
|
if (alignedEmbeddingData?.data) {
|
|
462
|
-
const result = stratifyArrays(
|
|
471
|
+
const [result, cellCountResult] = stratifyArrays(
|
|
463
472
|
sampleEdges, sampleIdToObsIdsMap,
|
|
464
473
|
sampleSets, sampleSetSelection,
|
|
465
474
|
alignedEmbeddingIndex, mergedCellSets, cellSetSelection, {
|
|
466
475
|
obsEmbeddingX: alignedEmbeddingData.data[0],
|
|
467
476
|
obsEmbeddingY: alignedEmbeddingData.data[1],
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
},
|
|
477
|
+
...(uint8ExpressionData?.[0] ? { featureValue: uint8ExpressionData } : {}),
|
|
478
|
+
}, featureAggregationStrategyToUse,
|
|
471
479
|
);
|
|
472
|
-
return result;
|
|
480
|
+
return [result, cellCountResult];
|
|
473
481
|
}
|
|
474
|
-
return null;
|
|
482
|
+
return [null, null];
|
|
475
483
|
}, [alignedEmbeddingIndex, alignedEmbeddingData, uint8ExpressionData,
|
|
476
484
|
sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetSelection,
|
|
477
|
-
cellSetSelection, mergedCellSets,
|
|
485
|
+
cellSetSelection, mergedCellSets, featureAggregationStrategyToUse,
|
|
478
486
|
]);
|
|
479
487
|
|
|
480
488
|
const setViewState = ({ zoom: newZoom, target }) => {
|
|
@@ -484,10 +492,15 @@ export function EmbeddingScatterplotSubscriber(props) {
|
|
|
484
492
|
setTargetZ(target[2] || 0);
|
|
485
493
|
};
|
|
486
494
|
|
|
495
|
+
// TODO: Update this once the rendered points reflects the selection/filtering.
|
|
496
|
+
const cellCountToUse = embeddingPointsVisible
|
|
497
|
+
? cellsCount
|
|
498
|
+
: (stratifiedDataCount ?? cellsCount);
|
|
499
|
+
|
|
487
500
|
return (
|
|
488
501
|
<TitleInfo
|
|
489
502
|
title={title}
|
|
490
|
-
info={`${commaNumber(
|
|
503
|
+
info={`${commaNumber(cellCountToUse)} ${plur(observationsLabel, cellCountToUse)}`}
|
|
491
504
|
closeButtonVisible={closeButtonVisible}
|
|
492
505
|
downloadButtonVisible={downloadButtonVisible}
|
|
493
506
|
removeGridComponent={removeGridComponent}
|
|
@@ -531,6 +544,8 @@ export function EmbeddingScatterplotSubscriber(props) {
|
|
|
531
544
|
defaultContourPercentiles={DEFAULT_CONTOUR_PERCENTILES}
|
|
532
545
|
contourColorEncoding={contourColorEncoding}
|
|
533
546
|
setContourColorEncoding={setContourColorEncoding}
|
|
547
|
+
featureAggregationStrategy={featureAggregationStrategy}
|
|
548
|
+
setFeatureAggregationStrategy={setFeatureAggregationStrategy}
|
|
534
549
|
/>
|
|
535
550
|
)}
|
|
536
551
|
>
|
|
@@ -583,17 +598,17 @@ export function EmbeddingScatterplotSubscriber(props) {
|
|
|
583
598
|
circleInfo={circleInfo}
|
|
584
599
|
featureSelection={geneSelection}
|
|
585
600
|
/>
|
|
586
|
-
{tooltipsVisible && (
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
)}
|
|
601
|
+
{tooltipsVisible && width && height ? (
|
|
602
|
+
<ScatterplotTooltipSubscriber
|
|
603
|
+
parentUuid={uuid}
|
|
604
|
+
obsHighlight={cellHighlight}
|
|
605
|
+
width={width}
|
|
606
|
+
height={height}
|
|
607
|
+
getObsInfo={getObsInfo}
|
|
608
|
+
featureType={featureType}
|
|
609
|
+
featureLabelsMap={featureLabelsMap}
|
|
610
|
+
/>
|
|
611
|
+
) : null}
|
|
597
612
|
<Legend
|
|
598
613
|
visible
|
|
599
614
|
theme={theme}
|
|
@@ -605,14 +620,15 @@ export function EmbeddingScatterplotSubscriber(props) {
|
|
|
605
620
|
featureValueColormap={geneExpressionColormap}
|
|
606
621
|
featureValueColormapRange={geneExpressionColormapRange}
|
|
607
622
|
obsSetSelection={cellSetSelection}
|
|
608
|
-
extent={expressionExtents
|
|
609
|
-
missing={expressionMissing
|
|
623
|
+
extent={expressionExtents}
|
|
624
|
+
missing={expressionMissing}
|
|
610
625
|
// Contour percentile legend
|
|
611
626
|
pointsVisible={embeddingPointsVisible}
|
|
612
627
|
contoursVisible={embeddingContoursVisible}
|
|
613
628
|
contoursFilled={embeddingContoursFilled}
|
|
614
629
|
contourPercentiles={contourPercentiles || DEFAULT_CONTOUR_PERCENTILES}
|
|
615
630
|
contourThresholds={contourThresholds}
|
|
631
|
+
featureAggregationStrategy={featureAggregationStrategyToUse}
|
|
616
632
|
/>
|
|
617
633
|
</TitleInfo>
|
|
618
634
|
);
|