@vitessce/scatterplot-embedding 3.5.10 → 3.5.11
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-7f3bb131.js} +1 -1
- package/dist/{index-a37f30c8.js → index-ab73546f.js} +170 -44
- package/dist/index.js +1 -1
- package/dist/{jpeg-5927a952.js → jpeg-6b5f0200.js} +1 -1
- package/dist/{lerc-7a4fca51.js → lerc-6a84a90d.js} +1 -1
- package/dist/{lzw-ce001eff.js → lzw-ec516fe1.js} +1 -1
- package/dist/{packbits-075c055a.js → packbits-28d4e412.js} +1 -1
- package/dist/{raw-b648d255.js → raw-140846a5.js} +1 -1
- package/dist/{webimage-dec5407e.js → webimage-5e317232.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,6 +11984,7 @@ 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,
|
|
@@ -12018,6 +12022,7 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
12018
12022
|
CoordinationType$1.FEATURE_SELECTION,
|
|
12019
12023
|
CoordinationType$1.FEATURE_VALUE_COLORMAP,
|
|
12020
12024
|
CoordinationType$1.FEATURE_VALUE_COLORMAP_RANGE,
|
|
12025
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
12021
12026
|
CoordinationType$1.OBS_COLOR_ENCODING,
|
|
12022
12027
|
CoordinationType$1.ADDITIONAL_OBS_SETS,
|
|
12023
12028
|
CoordinationType$1.MOLECULE_HIGHLIGHT,
|
|
@@ -12131,6 +12136,7 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
12131
12136
|
CoordinationType$1.FEATURE_SELECTION,
|
|
12132
12137
|
CoordinationType$1.FEATURE_VALUE_TRANSFORM,
|
|
12133
12138
|
CoordinationType$1.FEATURE_VALUE_TRANSFORM_COEFFICIENT,
|
|
12139
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
12134
12140
|
CoordinationType$1.OBS_SET_SELECTION,
|
|
12135
12141
|
CoordinationType$1.OBS_SET_FILTER,
|
|
12136
12142
|
CoordinationType$1.OBS_SET_HIGHLIGHT,
|
|
@@ -12146,6 +12152,7 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
12146
12152
|
CoordinationType$1.FEATURE_TYPE,
|
|
12147
12153
|
CoordinationType$1.FEATURE_VALUE_TYPE,
|
|
12148
12154
|
CoordinationType$1.FEATURE_SELECTION,
|
|
12155
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
12149
12156
|
CoordinationType$1.ADDITIONAL_OBS_SETS,
|
|
12150
12157
|
CoordinationType$1.OBS_SET_COLOR,
|
|
12151
12158
|
CoordinationType$1.OBS_COLOR_ENCODING,
|
|
@@ -12224,6 +12231,7 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
12224
12231
|
CoordinationType$1.FEATURE_VALUE_COLORMAP,
|
|
12225
12232
|
CoordinationType$1.FEATURE_VALUE_COLORMAP_RANGE,
|
|
12226
12233
|
CoordinationType$1.FEATURE_SELECTION,
|
|
12234
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
12227
12235
|
CoordinationType$1.TOOLTIPS_VISIBLE,
|
|
12228
12236
|
CoordinationType$1.TOOLTIP_CROSSHAIRS_VISIBLE,
|
|
12229
12237
|
CoordinationType$1.LEGEND_VISIBLE,
|
|
@@ -12264,6 +12272,7 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
12264
12272
|
CoordinationType$1.FEATURE_VALUE_TRANSFORM_COEFFICIENT,
|
|
12265
12273
|
CoordinationType$1.FEATURE_VALUE_POSITIVITY_THRESHOLD,
|
|
12266
12274
|
CoordinationType$1.FEATURE_VALUE_COLORMAP,
|
|
12275
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
12267
12276
|
CoordinationType$1.OBS_SET_SELECTION,
|
|
12268
12277
|
CoordinationType$1.OBS_SET_FILTER,
|
|
12269
12278
|
CoordinationType$1.OBS_SET_HIGHLIGHT,
|
|
@@ -12292,6 +12301,7 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
12292
12301
|
CoordinationType$1.FEATURE_SELECTION,
|
|
12293
12302
|
CoordinationType$1.FEATURE_VALUE_TRANSFORM,
|
|
12294
12303
|
CoordinationType$1.FEATURE_VALUE_TRANSFORM_COEFFICIENT,
|
|
12304
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
12295
12305
|
CoordinationType$1.OBS_SET_SELECTION,
|
|
12296
12306
|
CoordinationType$1.OBS_SET_HIGHLIGHT,
|
|
12297
12307
|
CoordinationType$1.OBS_HIGHLIGHT,
|
|
@@ -12396,6 +12406,7 @@ const COMPONENT_COORDINATION_TYPES = {
|
|
|
12396
12406
|
CoordinationType$1.OBS_TYPE,
|
|
12397
12407
|
CoordinationType$1.SAMPLE_TYPE,
|
|
12398
12408
|
CoordinationType$1.FEATURE_SELECTION,
|
|
12409
|
+
CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
|
|
12399
12410
|
CoordinationType$1.SAMPLE_SET_SELECTION,
|
|
12400
12411
|
CoordinationType$1.SAMPLE_SET_FILTER,
|
|
12401
12412
|
CoordinationType$1.OBS_SET_SELECTION,
|
|
@@ -12703,6 +12714,7 @@ z.object({
|
|
|
12703
12714
|
termColumn: z.string().optional(),
|
|
12704
12715
|
pValueColumn: z.string(),
|
|
12705
12716
|
pValueAdjusted: z.boolean().optional(),
|
|
12717
|
+
featureSetLibrary: z.string().optional().describe("Optionally, provide a feature set library name. By default, Reactome_2022."),
|
|
12706
12718
|
analysisType: z.string().optional().describe("Optionally, provide an analysis_type name. By default, pertpy_hypergeometric.")
|
|
12707
12719
|
});
|
|
12708
12720
|
z.object({
|
|
@@ -12713,7 +12725,6 @@ z.object({
|
|
|
12713
12725
|
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
12726
|
foldChangeTransformation: z.enum(["log2"]).optional(),
|
|
12715
12727
|
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
12728
|
analysisType: z.string().optional().describe("Optionally, provide an analysis_type name. By default, sccoda_df.")
|
|
12718
12729
|
});
|
|
12719
12730
|
const annDataObsLabels = annDataObs;
|
|
@@ -19717,7 +19728,7 @@ function getCellColors(params) {
|
|
|
19717
19728
|
}
|
|
19718
19729
|
return /* @__PURE__ */ new Map();
|
|
19719
19730
|
}
|
|
19720
|
-
function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetSelection, obsIndex, mergedCellSets, cellSetSelection, arraysToStratify) {
|
|
19731
|
+
function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetSelection, obsIndex, mergedCellSets, cellSetSelection, arraysToStratify, featureAggregationStrategy) {
|
|
19721
19732
|
const result = new InternMap([], JSON.stringify);
|
|
19722
19733
|
const hasSampleSetSelection = Array.isArray(sampleSetSelection) && sampleSetSelection.length > 0;
|
|
19723
19734
|
const hasCellSetSelection = Array.isArray(cellSetSelection) && cellSetSelection.length > 0;
|
|
@@ -19727,9 +19738,13 @@ function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetS
|
|
|
19727
19738
|
if (arrKeys.includes("obsIndex") || arrKeys.includes("i")) {
|
|
19728
19739
|
throw new Error('The keys "obsIndex" and "i" are reserved for internal use.');
|
|
19729
19740
|
}
|
|
19730
|
-
if (Object.
|
|
19731
|
-
|
|
19732
|
-
|
|
19741
|
+
if (Object.entries(arraysToStratify).some(([arrKey, arr]) => {
|
|
19742
|
+
if (arrKey === "featureValue") {
|
|
19743
|
+
return arr.some((a2) => a2.length !== obsIndex.length);
|
|
19744
|
+
}
|
|
19745
|
+
return arr.length !== obsIndex.length;
|
|
19746
|
+
}))
|
|
19747
|
+
;
|
|
19733
19748
|
const sampleSetInfo = sampleSets && sampleSetSelection ? treeToObsIdsBySetNames(sampleSets, sampleSetSelection) : null;
|
|
19734
19749
|
const cellSetInfo = mergedCellSets && cellSetSelection ? treeToObsIdsBySetNames(mergedCellSets, cellSetSelection) : null;
|
|
19735
19750
|
cellSetKeys.forEach((cellSetKey) => {
|
|
@@ -19759,6 +19774,7 @@ function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetS
|
|
|
19759
19774
|
});
|
|
19760
19775
|
const sampleIdToSetMap = sampleSets && sampleSetSelection ? treeToSelectedSetMap(sampleSets, sampleSetSelection) : null;
|
|
19761
19776
|
const cellIdToSetMap = mergedCellSets && cellSetSelection ? treeToSelectedSetMap(mergedCellSets, cellSetSelection) : null;
|
|
19777
|
+
let cellCount = 0;
|
|
19762
19778
|
for (let i2 = 0; i2 < obsIndex.length; i2 += 1) {
|
|
19763
19779
|
const obsId = obsIndex[i2];
|
|
19764
19780
|
const cellSet = (cellIdToSetMap == null ? void 0 : cellIdToSetMap.get(obsId)) || null;
|
|
@@ -19769,10 +19785,28 @@ function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetS
|
|
|
19769
19785
|
}
|
|
19770
19786
|
const insertionIndex = result.get(cellSet).get(sampleSet).get("i");
|
|
19771
19787
|
arrKeys.forEach((arrKey) => {
|
|
19772
|
-
|
|
19788
|
+
let value;
|
|
19789
|
+
if (arrKey === "featureValue") {
|
|
19790
|
+
if (featureAggregationStrategy === "first") {
|
|
19791
|
+
value = arraysToStratify[arrKey][0][i2];
|
|
19792
|
+
} else if (featureAggregationStrategy === "last") {
|
|
19793
|
+
value = arraysToStratify[arrKey].at(-1)[i2];
|
|
19794
|
+
} else if (typeof featureAggregationStrategy === "number") {
|
|
19795
|
+
const j = featureAggregationStrategy;
|
|
19796
|
+
value = arraysToStratify[arrKey][j][i2];
|
|
19797
|
+
} else if (featureAggregationStrategy === "sum" || featureAggregationStrategy === "mean") {
|
|
19798
|
+
value = arraysToStratify[arrKey].reduce((a2, h) => a2 + h[i2], 0);
|
|
19799
|
+
if (featureAggregationStrategy === "mean") {
|
|
19800
|
+
value /= arraysToStratify[arrKey].length;
|
|
19801
|
+
}
|
|
19802
|
+
}
|
|
19803
|
+
} else {
|
|
19804
|
+
value = arraysToStratify[arrKey][i2];
|
|
19805
|
+
}
|
|
19773
19806
|
result.get(cellSet).get(sampleSet).get(arrKey)[insertionIndex] = value;
|
|
19774
19807
|
});
|
|
19775
19808
|
result.get(cellSet).get(sampleSet).set("i", insertionIndex + 1);
|
|
19809
|
+
cellCount += 1;
|
|
19776
19810
|
}
|
|
19777
19811
|
cellSetKeys.forEach((cellSetKey) => {
|
|
19778
19812
|
sampleSetKeys.forEach((sampleSetKey) => {
|
|
@@ -19783,7 +19817,7 @@ function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetS
|
|
|
19783
19817
|
result.get(cellSetKey).get(sampleSetKey).delete("i");
|
|
19784
19818
|
});
|
|
19785
19819
|
});
|
|
19786
|
-
return result;
|
|
19820
|
+
return [result, cellCount];
|
|
19787
19821
|
}
|
|
19788
19822
|
function tree_add(d) {
|
|
19789
19823
|
var x2 = +this._x.call(null, d), y2 = +this._y.call(null, d);
|
|
@@ -127455,8 +127489,15 @@ class SelectionLayer extends CompositeLayer {
|
|
|
127455
127489
|
if (!nodePolygonContainsSelectedPolygon && !nodePolygonWithinSelectedPolygon && !nodePolygonOverlapsSelectedPolgyon) {
|
|
127456
127490
|
return true;
|
|
127457
127491
|
}
|
|
127458
|
-
if (node.data
|
|
127459
|
-
|
|
127492
|
+
if (node.data) {
|
|
127493
|
+
let current = node;
|
|
127494
|
+
while (current) {
|
|
127495
|
+
const pointCoords = [].slice.call(getObsCoords(current.data));
|
|
127496
|
+
if (booleanPointInPolygon$1(point$1(pointCoords), selectedPolygon)) {
|
|
127497
|
+
pickingInfos.push(current.data);
|
|
127498
|
+
}
|
|
127499
|
+
current = current.next;
|
|
127500
|
+
}
|
|
127460
127501
|
}
|
|
127461
127502
|
return false;
|
|
127462
127503
|
});
|
|
@@ -128668,16 +128709,16 @@ function addDecoder(cases, importFn) {
|
|
|
128668
128709
|
}
|
|
128669
128710
|
cases.forEach((c2) => registry$1.set(c2, importFn));
|
|
128670
128711
|
}
|
|
128671
|
-
addDecoder([void 0, 1], () => import("./raw-
|
|
128672
|
-
addDecoder(5, () => import("./lzw-
|
|
128712
|
+
addDecoder([void 0, 1], () => import("./raw-140846a5.js").then((m2) => m2.default));
|
|
128713
|
+
addDecoder(5, () => import("./lzw-ec516fe1.js").then((m2) => m2.default));
|
|
128673
128714
|
addDecoder(6, () => {
|
|
128674
128715
|
throw new Error("old style JPEG compression is not supported.");
|
|
128675
128716
|
});
|
|
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-
|
|
128717
|
+
addDecoder(7, () => import("./jpeg-6b5f0200.js").then((m2) => m2.default));
|
|
128718
|
+
addDecoder([8, 32946], () => import("./deflate-7f3bb131.js").then((m2) => m2.default));
|
|
128719
|
+
addDecoder(32773, () => import("./packbits-28d4e412.js").then((m2) => m2.default));
|
|
128720
|
+
addDecoder(34887, () => import("./lerc-6a84a90d.js").then((m2) => m2.default));
|
|
128721
|
+
addDecoder(50001, () => import("./webimage-5e317232.js").then((m2) => m2.default));
|
|
128681
128722
|
function decodeRowAcc(row, stride) {
|
|
128682
128723
|
let length2 = row.length - stride;
|
|
128683
128724
|
let offset5 = 0;
|
|
@@ -149712,7 +149753,10 @@ const getPosition = (object2, { index: index2, data, target }) => {
|
|
|
149712
149753
|
target[2] = POINT_LAYER_Z_INDEX;
|
|
149713
149754
|
return target;
|
|
149714
149755
|
};
|
|
149715
|
-
const contourGetWeight = (object2, { index: index2, data }) =>
|
|
149756
|
+
const contourGetWeight = (object2, { index: index2, data }) => {
|
|
149757
|
+
var _a3;
|
|
149758
|
+
return (_a3 = data.src.featureValues) == null ? void 0 : _a3[index2];
|
|
149759
|
+
};
|
|
149716
149760
|
const contourGetPosition = (object2, { index: index2, data, target }) => {
|
|
149717
149761
|
target[0] = data.src.embeddingX[index2];
|
|
149718
149762
|
target[1] = -data.src.embeddingY[index2];
|
|
@@ -150009,6 +150053,16 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
150009
150053
|
const { obsEmbeddingIndex, obsEmbedding } = this.props;
|
|
150010
150054
|
super.viewInfoDidUpdate(obsEmbeddingIndex, obsEmbedding, makeFlippedGetObsCoords);
|
|
150011
150055
|
}
|
|
150056
|
+
componentWillUnmount() {
|
|
150057
|
+
delete this.cellsQuadTree;
|
|
150058
|
+
delete this.cellsLayer;
|
|
150059
|
+
delete this.cellsData;
|
|
150060
|
+
delete this.stratifiedData;
|
|
150061
|
+
delete this.cellSetsForceSimulation;
|
|
150062
|
+
delete this.cellSetsLabelPrevZoom;
|
|
150063
|
+
delete this.cellSetsLayers;
|
|
150064
|
+
delete this.contourLayers;
|
|
150065
|
+
}
|
|
150012
150066
|
/**
|
|
150013
150067
|
* Here, asynchronously check whether props have
|
|
150014
150068
|
* updated which require re-computing memoized variables,
|
|
@@ -150215,8 +150269,9 @@ if (typeof document !== "undefined") {
|
|
|
150215
150269
|
else
|
|
150216
150270
|
document.addEventListener("DOMContentLoaded", $bbed8b41f857bcc0$var$setupGlobalEvents);
|
|
150217
150271
|
}
|
|
150272
|
+
const FEATURE_AGGREGATION_STRATEGIES = ["first", "last", "sum", "mean"];
|
|
150218
150273
|
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;
|
|
150274
|
+
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
150275
|
const scatterplotOptionsId = $bdb11010cef70236$export$f680877a34711e37();
|
|
150221
150276
|
const observationsLabelNice = capitalize$1(observationsLabel);
|
|
150222
150277
|
const classes = usePlotOptionsStyles();
|
|
@@ -150267,6 +150322,9 @@ function ScatterplotOptions(props) {
|
|
|
150267
150322
|
setContourPercentiles(values2);
|
|
150268
150323
|
}
|
|
150269
150324
|
const handlePercentilesChangeDebounced = useCallback(debounce$2(handlePercentilesChange, 5, { trailing: true }), [handlePercentilesChange]);
|
|
150325
|
+
function handleFeatureAggregationStrategyChange(event) {
|
|
150326
|
+
setFeatureAggregationStrategy(event.target.value);
|
|
150327
|
+
}
|
|
150270
150328
|
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
150329
|
"aria-label": "Show or hide set labels",
|
|
150272
150330
|
id: `scatterplot-set-labels-visible-${scatterplotOptionsId}`
|
|
@@ -150308,7 +150366,9 @@ function ScatterplotOptions(props) {
|
|
|
150308
150366
|
id: `scatterplot-contours-filled-${scatterplotOptionsId}`
|
|
150309
150367
|
} }) })] }), 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
150368
|
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 }) })] })
|
|
150369
|
+
}, 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: {
|
|
150370
|
+
id: `feature-aggregation-strategy-${scatterplotOptionsId}`
|
|
150371
|
+
}, children: FEATURE_AGGREGATION_STRATEGIES.map((opt) => jsxRuntimeExports.jsx("option", { value: opt, children: capitalize$1(opt) }, opt)) }) })] }) : null] });
|
|
150312
150372
|
}
|
|
150313
150373
|
const styles10 = makeStyles((theme) => ({
|
|
150314
150374
|
tooltipAnchor: {
|
|
@@ -152819,8 +152879,50 @@ const titleHeight = 10;
|
|
|
152819
152879
|
const rectHeight = 8;
|
|
152820
152880
|
const rectMarginY = 2;
|
|
152821
152881
|
const rectMarginX = 2;
|
|
152882
|
+
function combineExtents(extents, featureAggregationStrategy) {
|
|
152883
|
+
if (Array.isArray(extents)) {
|
|
152884
|
+
if (featureAggregationStrategy === "first") {
|
|
152885
|
+
return extents[0];
|
|
152886
|
+
}
|
|
152887
|
+
if (featureAggregationStrategy === "last") {
|
|
152888
|
+
return extents.at(-1);
|
|
152889
|
+
}
|
|
152890
|
+
if (typeof featureAggregationStrategy === "number") {
|
|
152891
|
+
const i2 = featureAggregationStrategy;
|
|
152892
|
+
return extents[i2];
|
|
152893
|
+
}
|
|
152894
|
+
if (featureAggregationStrategy === "sum") {
|
|
152895
|
+
return extents.reduce((a2, h) => [a2[0] + h[0], a2[1] + h[1]]);
|
|
152896
|
+
}
|
|
152897
|
+
if (featureAggregationStrategy === "mean") {
|
|
152898
|
+
return extents.reduce((a2, h) => [a2[0] + h[0], a2[1] + h[1]]).map((v) => v / extents.length);
|
|
152899
|
+
}
|
|
152900
|
+
}
|
|
152901
|
+
return null;
|
|
152902
|
+
}
|
|
152903
|
+
function combineMissings(missings, featureAggregationStrategy) {
|
|
152904
|
+
if (Array.isArray(missings)) {
|
|
152905
|
+
if (featureAggregationStrategy === "first") {
|
|
152906
|
+
return missings[0];
|
|
152907
|
+
}
|
|
152908
|
+
if (featureAggregationStrategy === "last") {
|
|
152909
|
+
return missings.at(-1);
|
|
152910
|
+
}
|
|
152911
|
+
if (typeof featureAggregationStrategy === "number") {
|
|
152912
|
+
const i2 = featureAggregationStrategy;
|
|
152913
|
+
return missings[i2];
|
|
152914
|
+
}
|
|
152915
|
+
if (featureAggregationStrategy === "sum") {
|
|
152916
|
+
return missings.reduce((a2, h) => a2 + h, 0);
|
|
152917
|
+
}
|
|
152918
|
+
if (featureAggregationStrategy === "mean") {
|
|
152919
|
+
return missings.reduce((a2, h) => a2 + h / missings.length, 0);
|
|
152920
|
+
}
|
|
152921
|
+
}
|
|
152922
|
+
return null;
|
|
152923
|
+
}
|
|
152822
152924
|
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;
|
|
152925
|
+
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
152926
|
const svgRef = useRef();
|
|
152825
152927
|
const classes = useStyles();
|
|
152826
152928
|
const isDarkTheme = theme === "dark";
|
|
@@ -152829,9 +152931,9 @@ function Legend(props) {
|
|
|
152829
152931
|
const layerColor = Array.isArray(spatialLayerColor) && spatialLayerColor.length === 3 ? spatialLayerColor : getDefaultColor(theme);
|
|
152830
152932
|
const channelColor = Array.isArray(spatialChannelColor) && spatialChannelColor.length === 3 ? spatialChannelColor : getDefaultColor(theme);
|
|
152831
152933
|
const staticColor = obsColorEncoding === "spatialChannelColor" ? channelColor : layerColor;
|
|
152832
|
-
const visible = visibleProp && (!considerSelections || obsColorEncoding === "geneSelection" && featureSelection && Array.isArray(featureSelection) && featureSelection.length
|
|
152934
|
+
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
152935
|
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);
|
|
152936
|
+
const dynamicHeight = isSetColor && obsSetSelection ? levelZeroNames.length * titleHeight + (obsSetSelection == null ? void 0 : obsSetSelection.length) * (rectHeight + rectMarginY) : height + (!pointsVisible && contoursVisible ? 25 : 0);
|
|
152835
152937
|
useEffect(() => {
|
|
152836
152938
|
const domElement = svgRef.current;
|
|
152837
152939
|
const foregroundColor = highContrast ? "black" : isDarkTheme ? "white" : "black";
|
|
@@ -152840,7 +152942,7 @@ function Legend(props) {
|
|
|
152840
152942
|
svg.attr("width", width).attr("height", dynamicHeight);
|
|
152841
152943
|
const g2 = svg.append("g").attr("width", width).attr("height", dynamicHeight);
|
|
152842
152944
|
if (!considerSelections || obsColorEncoding === "geneSelection") {
|
|
152843
|
-
const [xMin, xMax] = extent2 || [0, 1];
|
|
152945
|
+
const [xMin, xMax] = combineExtents(extent2, featureAggregationStrategy) || [0, 1];
|
|
152844
152946
|
if (featureValueColormap && pointsVisible) {
|
|
152845
152947
|
const xlinkHref = getXlinkHref(featureValueColormap);
|
|
152846
152948
|
g2.append("image").attr("x", 0).attr("y", titleHeight).attr("width", width).attr("height", rectHeight).attr("preserveAspectRatio", "none").attr("href", xlinkHref);
|
|
@@ -152904,8 +153006,19 @@ function Legend(props) {
|
|
|
152904
153006
|
});
|
|
152905
153007
|
});
|
|
152906
153008
|
}
|
|
152907
|
-
const featureSelectionLabelRaw = featureSelection && featureSelection.length >= 1 && !isStaticColor ? (featureLabelsMap == null ? void 0 : featureLabelsMap.get(
|
|
152908
|
-
|
|
153009
|
+
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;
|
|
153010
|
+
let featureSelectionLabelRawStr = "";
|
|
153011
|
+
if (featureAggregationStrategy === "first") {
|
|
153012
|
+
featureSelectionLabelRawStr = featureSelectionLabelRaw == null ? void 0 : featureSelectionLabelRaw[0];
|
|
153013
|
+
} else if (featureAggregationStrategy === "last") {
|
|
153014
|
+
featureSelectionLabelRawStr = featureSelectionLabelRaw == null ? void 0 : featureSelectionLabelRaw.at(-1);
|
|
153015
|
+
} else if (featureAggregationStrategy === "sum") {
|
|
153016
|
+
featureSelectionLabelRawStr = "Sum of features";
|
|
153017
|
+
} else if (featureAggregationStrategy === "mean") {
|
|
153018
|
+
featureSelectionLabelRawStr = "Mean of features";
|
|
153019
|
+
}
|
|
153020
|
+
const combinedMissing = combineMissings(missing, featureAggregationStrategy);
|
|
153021
|
+
const featureSelectionLabel = combinedMissing ? `${featureSelectionLabelRawStr} (${Math.round(combinedMissing * 100)}% NaN)` : featureSelectionLabelRawStr;
|
|
152909
153022
|
const obsLabel = capitalize$1(obsType);
|
|
152910
153023
|
const featureLabel = considerSelections ? featureSelectionLabel || capitalize$1(featureValueType) : capitalize$1(featureValueType);
|
|
152911
153024
|
const mainLabel = showObsLabel ? obsLabel : featureLabel;
|
|
@@ -152939,7 +153052,8 @@ function Legend(props) {
|
|
|
152939
153052
|
contourThresholds,
|
|
152940
153053
|
contoursFilled,
|
|
152941
153054
|
contoursVisible,
|
|
152942
|
-
pointsVisible
|
|
153055
|
+
pointsVisible,
|
|
153056
|
+
featureAggregationStrategy
|
|
152943
153057
|
]);
|
|
152944
153058
|
return jsxRuntimeExports.jsx("div", { className: clsx(classes.legend, {
|
|
152945
153059
|
[classes.legendRelative]: positionRelative,
|
|
@@ -152981,6 +153095,7 @@ makeStyles(() => ({
|
|
|
152981
153095
|
}
|
|
152982
153096
|
}));
|
|
152983
153097
|
const DEFAULT_CONTOUR_PERCENTILES = [0.09, 0.9, 0.99];
|
|
153098
|
+
const DEFAULT_FEATURE_AGGREGATION_STRATEGY = "first";
|
|
152984
153099
|
function EmbeddingScatterplotSubscriber(props) {
|
|
152985
153100
|
const {
|
|
152986
153101
|
uuid,
|
|
@@ -153035,7 +153150,8 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153035
153150
|
embeddingContoursFilled,
|
|
153036
153151
|
embeddingContourPercentiles: contourPercentiles,
|
|
153037
153152
|
contourColorEncoding,
|
|
153038
|
-
contourColor
|
|
153153
|
+
contourColor,
|
|
153154
|
+
featureAggregationStrategy
|
|
153039
153155
|
}, {
|
|
153040
153156
|
setEmbeddingZoom: setZoom,
|
|
153041
153157
|
setEmbeddingTargetX: setTargetX,
|
|
@@ -153061,7 +153177,8 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153061
153177
|
setEmbeddingContoursVisible,
|
|
153062
153178
|
setEmbeddingContoursFilled,
|
|
153063
153179
|
setEmbeddingContourPercentiles: setContourPercentiles,
|
|
153064
|
-
setContourColorEncoding
|
|
153180
|
+
setContourColorEncoding,
|
|
153181
|
+
setFeatureAggregationStrategy
|
|
153065
153182
|
}] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SCATTERPLOT], coordinationScopes);
|
|
153066
153183
|
const {
|
|
153067
153184
|
embeddingZoom: initialZoom,
|
|
@@ -153073,6 +153190,7 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153073
153190
|
);
|
|
153074
153191
|
const observationsLabel = observationsLabelOverride || obsType;
|
|
153075
153192
|
const sampleSetSelection = sampleSetSelectionFromProps || sampleSetSelectionFromCoordination;
|
|
153193
|
+
const featureAggregationStrategyToUse = featureAggregationStrategy ?? DEFAULT_FEATURE_AGGREGATION_STRATEGY;
|
|
153076
153194
|
const [width, height, deckRef] = useDeckCanvasSize();
|
|
153077
153195
|
const title = titleOverride || `Scatterplot (${mapping})`;
|
|
153078
153196
|
const [obsLabelsTypes, obsLabelsData] = useMultiObsLabels(
|
|
@@ -153249,7 +153367,7 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153249
153367
|
return [null, null, null, null, null];
|
|
153250
153368
|
}, [obsEmbedding]);
|
|
153251
153369
|
useEffect(() => {
|
|
153252
|
-
if (xRange && yRange) {
|
|
153370
|
+
if (xRange && yRange && width && height) {
|
|
153253
153371
|
const pointSizeDevicePixels = getPointSizeDevicePixels(
|
|
153254
153372
|
window.devicePixelRatio,
|
|
153255
153373
|
zoom,
|
|
@@ -153342,6 +153460,9 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153342
153460
|
originalViewState.target[1]
|
|
153343
153461
|
];
|
|
153344
153462
|
const scaleFactor = 2 ** originalViewState.zoom;
|
|
153463
|
+
if (!(typeof scaleFactor === "number" && typeof center2[0] === "number" && typeof center2[1] === "number") || Number.isNaN(scaleFactor)) {
|
|
153464
|
+
return null;
|
|
153465
|
+
}
|
|
153345
153466
|
const radius = Math.min(width, height) / 2 / scaleFactor;
|
|
153346
153467
|
const numPoints = 96;
|
|
153347
153468
|
const options = { steps: numPoints, units: "degrees" };
|
|
@@ -153386,9 +153507,9 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153386
153507
|
}
|
|
153387
153508
|
return null;
|
|
153388
153509
|
}, [sampleEdges]);
|
|
153389
|
-
const stratifiedData = useMemo(() => {
|
|
153510
|
+
const [stratifiedData, stratifiedDataCount] = useMemo(() => {
|
|
153390
153511
|
if (alignedEmbeddingData == null ? void 0 : alignedEmbeddingData.data) {
|
|
153391
|
-
const result = stratifyArrays(
|
|
153512
|
+
const [result, cellCountResult] = stratifyArrays(
|
|
153392
153513
|
sampleEdges,
|
|
153393
153514
|
sampleIdToObsIdsMap,
|
|
153394
153515
|
sampleSets,
|
|
@@ -153399,13 +153520,13 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153399
153520
|
{
|
|
153400
153521
|
obsEmbeddingX: alignedEmbeddingData.data[0],
|
|
153401
153522
|
obsEmbeddingY: alignedEmbeddingData.data[1],
|
|
153402
|
-
|
|
153403
|
-
|
|
153404
|
-
|
|
153523
|
+
...(uint8ExpressionData == null ? void 0 : uint8ExpressionData[0]) ? { featureValue: uint8ExpressionData } : {}
|
|
153524
|
+
},
|
|
153525
|
+
featureAggregationStrategyToUse
|
|
153405
153526
|
);
|
|
153406
|
-
return result;
|
|
153527
|
+
return [result, cellCountResult];
|
|
153407
153528
|
}
|
|
153408
|
-
return null;
|
|
153529
|
+
return [null, null];
|
|
153409
153530
|
}, [
|
|
153410
153531
|
alignedEmbeddingIndex,
|
|
153411
153532
|
alignedEmbeddingData,
|
|
@@ -153415,7 +153536,8 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153415
153536
|
sampleSets,
|
|
153416
153537
|
sampleSetSelection,
|
|
153417
153538
|
cellSetSelection,
|
|
153418
|
-
mergedCellSets
|
|
153539
|
+
mergedCellSets,
|
|
153540
|
+
featureAggregationStrategyToUse
|
|
153419
153541
|
]);
|
|
153420
153542
|
const setViewState = ({ zoom: newZoom, target }) => {
|
|
153421
153543
|
setZoom(newZoom);
|
|
@@ -153423,11 +153545,12 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153423
153545
|
setTargetY(target[1]);
|
|
153424
153546
|
setTargetZ(target[2] || 0);
|
|
153425
153547
|
};
|
|
153548
|
+
const cellCountToUse = embeddingPointsVisible ? cellsCount : stratifiedDataCount ?? cellsCount;
|
|
153426
153549
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
153427
153550
|
TitleInfo,
|
|
153428
153551
|
{
|
|
153429
153552
|
title,
|
|
153430
|
-
info: `${commaNumber(
|
|
153553
|
+
info: `${commaNumber(cellCountToUse)} ${pluralize(observationsLabel, cellCountToUse)}`,
|
|
153431
153554
|
closeButtonVisible,
|
|
153432
153555
|
downloadButtonVisible,
|
|
153433
153556
|
removeGridComponent,
|
|
@@ -153471,7 +153594,9 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153471
153594
|
setContourPercentiles,
|
|
153472
153595
|
defaultContourPercentiles: DEFAULT_CONTOUR_PERCENTILES,
|
|
153473
153596
|
contourColorEncoding,
|
|
153474
|
-
setContourColorEncoding
|
|
153597
|
+
setContourColorEncoding,
|
|
153598
|
+
featureAggregationStrategy,
|
|
153599
|
+
setFeatureAggregationStrategy
|
|
153475
153600
|
}
|
|
153476
153601
|
),
|
|
153477
153602
|
children: [
|
|
@@ -153523,7 +153648,7 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153523
153648
|
featureSelection: geneSelection
|
|
153524
153649
|
}
|
|
153525
153650
|
),
|
|
153526
|
-
tooltipsVisible && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
153651
|
+
tooltipsVisible && width && height ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
153527
153652
|
ScatterplotTooltipSubscriber,
|
|
153528
153653
|
{
|
|
153529
153654
|
parentUuid: uuid,
|
|
@@ -153534,7 +153659,7 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153534
153659
|
featureType,
|
|
153535
153660
|
featureLabelsMap
|
|
153536
153661
|
}
|
|
153537
|
-
),
|
|
153662
|
+
) : null,
|
|
153538
153663
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
153539
153664
|
Legend,
|
|
153540
153665
|
{
|
|
@@ -153548,13 +153673,14 @@ function EmbeddingScatterplotSubscriber(props) {
|
|
|
153548
153673
|
featureValueColormap: geneExpressionColormap,
|
|
153549
153674
|
featureValueColormapRange: geneExpressionColormapRange,
|
|
153550
153675
|
obsSetSelection: cellSetSelection,
|
|
153551
|
-
extent: expressionExtents
|
|
153552
|
-
missing: expressionMissing
|
|
153676
|
+
extent: expressionExtents,
|
|
153677
|
+
missing: expressionMissing,
|
|
153553
153678
|
pointsVisible: embeddingPointsVisible,
|
|
153554
153679
|
contoursVisible: embeddingContoursVisible,
|
|
153555
153680
|
contoursFilled: embeddingContoursFilled,
|
|
153556
153681
|
contourPercentiles: contourPercentiles || DEFAULT_CONTOUR_PERCENTILES,
|
|
153557
|
-
contourThresholds
|
|
153682
|
+
contourThresholds,
|
|
153683
|
+
featureAggregationStrategy: featureAggregationStrategyToUse
|
|
153558
153684
|
}
|
|
153559
153685
|
)
|
|
153560
153686
|
]
|
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-ab73546f.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.11",
|
|
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.11",
|
|
25
|
+
"@vitessce/legend": "3.5.11",
|
|
26
|
+
"@vitessce/scatterplot": "3.5.11",
|
|
27
|
+
"@vitessce/sets-utils": "3.5.11",
|
|
28
|
+
"@vitessce/utils": "3.5.11",
|
|
29
|
+
"@vitessce/vit-s": "3.5.11"
|
|
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
|
);
|