@vitessce/scatterplot 3.1.2 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{deflate-ac65438c.js → deflate-9071f9f0.js} +1 -1
- package/dist/{index-8a1f373a.js → index-2c270a1e.js} +768 -99
- package/dist/index.js +1 -1
- package/dist/{jpeg-09198c7a.js → jpeg-46e4967f.js} +1 -1
- package/dist/{lerc-a1ea16ed.js → lerc-f7e82495.js} +1 -1
- package/dist/{lzw-6ec4deb9.js → lzw-91120d0e.js} +1 -1
- package/dist/{packbits-26db2d36.js → packbits-ad7c6a7a.js} +1 -1
- package/dist/{raw-2ee0835f.js → raw-b9a1aa09.js} +1 -1
- package/dist/{webimage-2075fc27.js → webimage-0722f414.js} +1 -1
- package/dist-tsc/Scatterplot.d.ts.map +1 -1
- package/dist-tsc/Scatterplot.js +13 -4
- package/dist-tsc/shared-spatial-scatterplot/AbstractSpatialOrScatterplot.d.ts.map +1 -1
- package/dist-tsc/shared-spatial-scatterplot/AbstractSpatialOrScatterplot.js +6 -4
- package/package.json +7 -7
- package/src/Scatterplot.js +14 -8
- package/src/shared-spatial-scatterplot/AbstractSpatialOrScatterplot.js +6 -4
|
@@ -2976,17 +2976,17 @@ let COLOR;
|
|
|
2976
2976
|
COLOR2[COLOR2["BRIGHT_CYAN"] = 96] = "BRIGHT_CYAN";
|
|
2977
2977
|
COLOR2[COLOR2["BRIGHT_WHITE"] = 97] = "BRIGHT_WHITE";
|
|
2978
2978
|
})(COLOR || (COLOR = {}));
|
|
2979
|
-
function getColor(color) {
|
|
2979
|
+
function getColor$1(color) {
|
|
2980
2980
|
return typeof color === "string" ? COLOR[color.toUpperCase()] || COLOR.WHITE : color;
|
|
2981
2981
|
}
|
|
2982
2982
|
function addColor(string, color, background) {
|
|
2983
2983
|
if (!isBrowser$3 && typeof string === "string") {
|
|
2984
2984
|
if (color) {
|
|
2985
|
-
color = getColor(color);
|
|
2985
|
+
color = getColor$1(color);
|
|
2986
2986
|
string = "\x1B[".concat(color, "m").concat(string, "\x1B[39m");
|
|
2987
2987
|
}
|
|
2988
2988
|
if (background) {
|
|
2989
|
-
color = getColor(background);
|
|
2989
|
+
color = getColor$1(background);
|
|
2990
2990
|
string = "\x1B[".concat(background + 10, "m").concat(string, "\x1B[49m");
|
|
2991
2991
|
}
|
|
2992
2992
|
}
|
|
@@ -13010,7 +13010,7 @@ function negate(out, a2) {
|
|
|
13010
13010
|
out[2] = -a2[2];
|
|
13011
13011
|
return out;
|
|
13012
13012
|
}
|
|
13013
|
-
function normalize$
|
|
13013
|
+
function normalize$4(out, a2) {
|
|
13014
13014
|
var x2 = a2[0];
|
|
13015
13015
|
var y2 = a2[1];
|
|
13016
13016
|
var z2 = a2[2];
|
|
@@ -14319,7 +14319,7 @@ function squaredLength$1(a2) {
|
|
|
14319
14319
|
var w2 = a2[3];
|
|
14320
14320
|
return x2 * x2 + y2 * y2 + z2 * z2 + w2 * w2;
|
|
14321
14321
|
}
|
|
14322
|
-
function normalize$
|
|
14322
|
+
function normalize$3(out, a2) {
|
|
14323
14323
|
var x2 = a2[0];
|
|
14324
14324
|
var y2 = a2[1];
|
|
14325
14325
|
var z2 = a2[2];
|
|
@@ -14956,7 +14956,7 @@ var dot$1 = dot$2;
|
|
|
14956
14956
|
var lerp$1 = lerp$2;
|
|
14957
14957
|
var length$2 = length$3;
|
|
14958
14958
|
var squaredLength = squaredLength$1;
|
|
14959
|
-
var normalize$
|
|
14959
|
+
var normalize$2 = normalize$3;
|
|
14960
14960
|
var rotationTo = function() {
|
|
14961
14961
|
var tmpvec3 = create$3();
|
|
14962
14962
|
var xUnitVec3 = fromValues(1, 0, 0);
|
|
@@ -14967,7 +14967,7 @@ var rotationTo = function() {
|
|
|
14967
14967
|
cross$1(tmpvec3, xUnitVec3, a2);
|
|
14968
14968
|
if (len(tmpvec3) < 1e-6)
|
|
14969
14969
|
cross$1(tmpvec3, yUnitVec3, a2);
|
|
14970
|
-
normalize$
|
|
14970
|
+
normalize$4(tmpvec3, tmpvec3);
|
|
14971
14971
|
setAxisAngle(out, tmpvec3, Math.PI);
|
|
14972
14972
|
return out;
|
|
14973
14973
|
} else if (dot2 > 0.999999) {
|
|
@@ -14982,7 +14982,7 @@ var rotationTo = function() {
|
|
|
14982
14982
|
out[1] = tmpvec3[1];
|
|
14983
14983
|
out[2] = tmpvec3[2];
|
|
14984
14984
|
out[3] = 1 + dot2;
|
|
14985
|
-
return normalize$
|
|
14985
|
+
return normalize$2(out, out);
|
|
14986
14986
|
}
|
|
14987
14987
|
};
|
|
14988
14988
|
}();
|
|
@@ -15008,7 +15008,7 @@ var rotationTo = function() {
|
|
|
15008
15008
|
matr[2] = -view[0];
|
|
15009
15009
|
matr[5] = -view[1];
|
|
15010
15010
|
matr[8] = -view[2];
|
|
15011
|
-
return normalize$
|
|
15011
|
+
return normalize$2(out, fromMat3(out, matr));
|
|
15012
15012
|
};
|
|
15013
15013
|
})();
|
|
15014
15014
|
const IDENTITY_QUATERNION = [0, 0, 0, 1];
|
|
@@ -36697,7 +36697,7 @@ function copyFlatRing(target, targetStartIndex, positions, size, srcStartIndex =
|
|
|
36697
36697
|
modifyPolygonWindingDirection(target, windingDirection, windingOptions);
|
|
36698
36698
|
return targetIndex;
|
|
36699
36699
|
}
|
|
36700
|
-
function normalize(polygon2, positionSize) {
|
|
36700
|
+
function normalize$1(polygon2, positionSize) {
|
|
36701
36701
|
validate(polygon2);
|
|
36702
36702
|
const positions = [];
|
|
36703
36703
|
const holeIndices = [];
|
|
@@ -36803,7 +36803,7 @@ class PolygonTesselator extends Tesselator {
|
|
|
36803
36803
|
}
|
|
36804
36804
|
normalizeGeometry(polygon2) {
|
|
36805
36805
|
if (this.normalize) {
|
|
36806
|
-
const normalizedPolygon = normalize(polygon2, this.positionSize);
|
|
36806
|
+
const normalizedPolygon = normalize$1(polygon2, this.positionSize);
|
|
36807
36807
|
if (this.opts.resolution) {
|
|
36808
36808
|
return cutPolygonByGrid(getPositions(normalizedPolygon), getHoleIndices(normalizedPolygon), {
|
|
36809
36809
|
size: this.positionSize,
|
|
@@ -37425,7 +37425,7 @@ class PolygonLayer extends CompositeLayer {
|
|
|
37425
37425
|
objectInfo.index++;
|
|
37426
37426
|
let polygon2 = getPolygon(object2, objectInfo);
|
|
37427
37427
|
if (_normalize) {
|
|
37428
|
-
polygon2 = normalize(polygon2, positionSize);
|
|
37428
|
+
polygon2 = normalize$1(polygon2, positionSize);
|
|
37429
37429
|
}
|
|
37430
37430
|
const {
|
|
37431
37431
|
holeIndices
|
|
@@ -82840,7 +82840,7 @@ function clipExtent(x02, y02, x12, y12) {
|
|
|
82840
82840
|
return clipStream;
|
|
82841
82841
|
};
|
|
82842
82842
|
}
|
|
82843
|
-
function extent() {
|
|
82843
|
+
function extent$1() {
|
|
82844
82844
|
var x02 = 0, y02 = 0, x12 = 960, y12 = 500, cache2, cacheStream, clip2;
|
|
82845
82845
|
return clip2 = {
|
|
82846
82846
|
stream: function(stream) {
|
|
@@ -84247,7 +84247,7 @@ const d3Geo$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
|
|
|
84247
84247
|
geoBounds: bounds,
|
|
84248
84248
|
geoCentroid: centroid$3,
|
|
84249
84249
|
geoCircle: circle$2,
|
|
84250
|
-
geoClipExtent: extent,
|
|
84250
|
+
geoClipExtent: extent$1,
|
|
84251
84251
|
geoConicConformal: conicConformal,
|
|
84252
84252
|
geoConicConformalRaw: conicConformalRaw,
|
|
84253
84253
|
geoConicEqualArea: conicEqualArea,
|
|
@@ -103488,28 +103488,38 @@ const PASS_THROUGH_PROPS = [
|
|
|
103488
103488
|
];
|
|
103489
103489
|
class SelectionLayer extends CompositeLayer {
|
|
103490
103490
|
_selectPolygonObjects(coordinates2) {
|
|
103491
|
-
const {
|
|
103491
|
+
const { flipY, obsLayers } = this.props;
|
|
103492
103492
|
const flippedCoordinates = flipY ? coordinates2.map((poly) => poly.map((p) => [p[0], -p[1]])) : coordinates2;
|
|
103493
103493
|
const selectedPolygon = polygon(flippedCoordinates);
|
|
103494
|
-
|
|
103495
|
-
|
|
103496
|
-
const
|
|
103497
|
-
|
|
103498
|
-
|
|
103499
|
-
|
|
103500
|
-
|
|
103501
|
-
|
|
103502
|
-
|
|
103503
|
-
|
|
103504
|
-
|
|
103505
|
-
|
|
103506
|
-
|
|
103507
|
-
|
|
103494
|
+
obsLayers.forEach((obsLayer) => {
|
|
103495
|
+
const { getObsCoords, obsQuadTree, obsIndex, onSelect: layerOnSelect } = obsLayer;
|
|
103496
|
+
const pickingInfos = [];
|
|
103497
|
+
obsQuadTree == null ? void 0 : obsQuadTree.visit((node, x02, y02, x12, y12) => {
|
|
103498
|
+
const nodePoints = [[[x02, y02], [x12, y02], [x12, y12], [x02, y12], [x02, y02]]];
|
|
103499
|
+
const nodePolygon = polygon(nodePoints);
|
|
103500
|
+
const nodePolygonContainsSelectedPolygon = booleanContains(nodePolygon, selectedPolygon);
|
|
103501
|
+
const nodePolygonWithinSelectedPolygon = booleanWithin(nodePolygon, selectedPolygon);
|
|
103502
|
+
const nodePolygonOverlapsSelectedPolgyon = booleanOverlap(nodePolygon, selectedPolygon);
|
|
103503
|
+
if (!nodePolygonContainsSelectedPolygon && !nodePolygonWithinSelectedPolygon && !nodePolygonOverlapsSelectedPolgyon) {
|
|
103504
|
+
return true;
|
|
103505
|
+
}
|
|
103506
|
+
if (node.data && booleanPointInPolygon$1(point([].slice.call(getObsCoords(node.data))), selectedPolygon)) {
|
|
103507
|
+
pickingInfos.push(node.data);
|
|
103508
|
+
}
|
|
103509
|
+
return false;
|
|
103510
|
+
});
|
|
103511
|
+
const pickingIds = pickingInfos.map((obsI) => obsIndex[obsI]);
|
|
103512
|
+
layerOnSelect(pickingIds);
|
|
103513
|
+
});
|
|
103514
|
+
}
|
|
103515
|
+
_selectEmpty() {
|
|
103516
|
+
const { obsLayers } = this.props;
|
|
103517
|
+
obsLayers.forEach((obsLayer) => {
|
|
103518
|
+
const { onSelect: layerOnSelect } = obsLayer;
|
|
103519
|
+
layerOnSelect([]);
|
|
103508
103520
|
});
|
|
103509
|
-
onSelect({ pickingInfos });
|
|
103510
103521
|
}
|
|
103511
103522
|
renderLayers() {
|
|
103512
|
-
const { onSelect } = this.props;
|
|
103513
103523
|
const mode = MODE_MAP[this.props.selectionType] || distEs6.ViewMode;
|
|
103514
103524
|
const inheritedProps = {};
|
|
103515
103525
|
PASS_THROUGH_PROPS.forEach((p) => {
|
|
@@ -103531,7 +103541,7 @@ class SelectionLayer extends CompositeLayer {
|
|
|
103531
103541
|
const { coordinates: coordinates2 } = updatedData.features[0].geometry;
|
|
103532
103542
|
this._selectPolygonObjects(coordinates2);
|
|
103533
103543
|
} else if (editType === EDIT_TYPE_CLEAR) {
|
|
103534
|
-
|
|
103544
|
+
this._selectEmpty();
|
|
103535
103545
|
}
|
|
103536
103546
|
},
|
|
103537
103547
|
_subLayerProps: {
|
|
@@ -103563,25 +103573,23 @@ SelectionLayer.defaultProps = defaultProps$f;
|
|
|
103563
103573
|
function getBaseLayerId(layerId) {
|
|
103564
103574
|
return `base-${layerId}`;
|
|
103565
103575
|
}
|
|
103566
|
-
|
|
103576
|
+
const onSelectNoop = ({ pickingInfos }) => {
|
|
103577
|
+
};
|
|
103578
|
+
function getSelectionLayer(tool, zoom, layerId, obsLayers, flipY = false) {
|
|
103567
103579
|
if (!tool) {
|
|
103568
103580
|
return [];
|
|
103569
103581
|
}
|
|
103570
103582
|
const cellBaseLayerId = getBaseLayerId(layerId);
|
|
103571
103583
|
const editHandlePointRadius = 5 / (zoom + 16);
|
|
103572
|
-
return
|
|
103584
|
+
return new SelectionLayer({
|
|
103573
103585
|
id: "selection",
|
|
103574
103586
|
flipY,
|
|
103575
|
-
|
|
103576
|
-
getCellCoords,
|
|
103587
|
+
obsLayers,
|
|
103577
103588
|
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
|
|
103578
103589
|
selectionType: tool,
|
|
103579
|
-
onSelect
|
|
103580
|
-
|
|
103581
|
-
|
|
103582
|
-
updateCellsSelection(cellIds);
|
|
103583
|
-
}
|
|
103584
|
-
},
|
|
103590
|
+
// This onSelect is no longer used since
|
|
103591
|
+
// the obsLayers each have their own onSelect.
|
|
103592
|
+
onSelect: onSelectNoop,
|
|
103585
103593
|
layerIds: [cellBaseLayerId],
|
|
103586
103594
|
getTentativeFillColor: () => [255, 255, 255, 95],
|
|
103587
103595
|
getTentativeLineColor: () => [143, 143, 143, 255],
|
|
@@ -103593,7 +103601,7 @@ function getSelectionLayers(tool, zoom, layerId, getCellCoords, obsIndex, update
|
|
|
103593
103601
|
editHandlePointRadiusScale: 1,
|
|
103594
103602
|
editHandlePointRadiusMinPixels: editHandlePointRadius,
|
|
103595
103603
|
editHandlePointRadiusMaxPixels: 2 * editHandlePointRadius
|
|
103596
|
-
})
|
|
103604
|
+
});
|
|
103597
103605
|
}
|
|
103598
103606
|
const TILE_SIZE = 4096;
|
|
103599
103607
|
const DATA_TEXTURE_SIZE = 4096;
|
|
@@ -104707,16 +104715,16 @@ function addDecoder(cases, importFn) {
|
|
|
104707
104715
|
}
|
|
104708
104716
|
cases.forEach((c2) => registry$1.set(c2, importFn));
|
|
104709
104717
|
}
|
|
104710
|
-
addDecoder([void 0, 1], () => import("./raw-
|
|
104711
|
-
addDecoder(5, () => import("./lzw-
|
|
104718
|
+
addDecoder([void 0, 1], () => import("./raw-b9a1aa09.js").then((m2) => m2.default));
|
|
104719
|
+
addDecoder(5, () => import("./lzw-91120d0e.js").then((m2) => m2.default));
|
|
104712
104720
|
addDecoder(6, () => {
|
|
104713
104721
|
throw new Error("old style JPEG compression is not supported.");
|
|
104714
104722
|
});
|
|
104715
|
-
addDecoder(7, () => import("./jpeg-
|
|
104716
|
-
addDecoder([8, 32946], () => import("./deflate-
|
|
104717
|
-
addDecoder(32773, () => import("./packbits-
|
|
104718
|
-
addDecoder(34887, () => import("./lerc-
|
|
104719
|
-
addDecoder(50001, () => import("./webimage-
|
|
104723
|
+
addDecoder(7, () => import("./jpeg-46e4967f.js").then((m2) => m2.default));
|
|
104724
|
+
addDecoder([8, 32946], () => import("./deflate-9071f9f0.js").then((m2) => m2.default));
|
|
104725
|
+
addDecoder(32773, () => import("./packbits-ad7c6a7a.js").then((m2) => m2.default));
|
|
104726
|
+
addDecoder(34887, () => import("./lerc-f7e82495.js").then((m2) => m2.default));
|
|
104727
|
+
addDecoder(50001, () => import("./webimage-0722f414.js").then((m2) => m2.default));
|
|
104720
104728
|
function decodeRowAcc(row, stride) {
|
|
104721
104729
|
let length2 = row.length - stride;
|
|
104722
104730
|
let offset5 = 0;
|
|
@@ -111509,7 +111517,7 @@ const SIGNAL_ABORTED = "__vivSignalAborted";
|
|
|
111509
111517
|
addDecoder(5, () => LZWDecoder);
|
|
111510
111518
|
const MAX_COLOR_INTENSITY = 255;
|
|
111511
111519
|
const DEFAULT_COLOR_OFF = [0, 0, 0];
|
|
111512
|
-
const MAX_CHANNELS = 6;
|
|
111520
|
+
const MAX_CHANNELS$1 = 6;
|
|
111513
111521
|
const DEFAULT_FONT_FAMILY = "-apple-system, 'Helvetica Neue', Arial, sans-serif";
|
|
111514
111522
|
const DTYPE_VALUES = {
|
|
111515
111523
|
Uint8: {
|
|
@@ -113025,7 +113033,7 @@ const AdditiveColormapExtension = class extends LayerExtension {
|
|
|
113025
113033
|
};
|
|
113026
113034
|
AdditiveColormapExtension.extensionName = "AdditiveColormapExtension";
|
|
113027
113035
|
AdditiveColormapExtension.defaultProps = defaultProps$4$1;
|
|
113028
|
-
const fs$1$
|
|
113036
|
+
const fs$1$2 = `uniform vec3 transparentColor;
|
|
113029
113037
|
uniform bool useTransparentColor;
|
|
113030
113038
|
uniform float opacity;
|
|
113031
113039
|
|
|
@@ -113052,12 +113060,12 @@ rgba = apply_opacity(rgb);
|
|
|
113052
113060
|
`;
|
|
113053
113061
|
const colorPalette = {
|
|
113054
113062
|
name: "color-palette-module",
|
|
113055
|
-
fs: fs$1$
|
|
113063
|
+
fs: fs$1$2,
|
|
113056
113064
|
inject: {
|
|
113057
113065
|
"fs:DECKGL_MUTATE_COLOR": DECKGL_MUTATE_COLOR
|
|
113058
113066
|
}
|
|
113059
113067
|
};
|
|
113060
|
-
function padWithDefault$
|
|
113068
|
+
function padWithDefault$3(arr, defaultValue2, padWidth) {
|
|
113061
113069
|
for (let i2 = 0; i2 < padWidth; i2 += 1) {
|
|
113062
113070
|
arr.push(defaultValue2);
|
|
113063
113071
|
}
|
|
@@ -113083,8 +113091,8 @@ function padColors({ colors, channelsVisible }) {
|
|
|
113083
113091
|
const newColors = colors.map(
|
|
113084
113092
|
(color, i2) => channelsVisible[i2] ? color.map((c2) => c2 / MAX_COLOR_INTENSITY) : DEFAULT_COLOR_OFF
|
|
113085
113093
|
);
|
|
113086
|
-
const padSize = MAX_CHANNELS - newColors.length;
|
|
113087
|
-
const paddedColors = padWithDefault$
|
|
113094
|
+
const padSize = MAX_CHANNELS$1 - newColors.length;
|
|
113095
|
+
const paddedColors = padWithDefault$3(
|
|
113088
113096
|
newColors,
|
|
113089
113097
|
DEFAULT_COLOR_OFF,
|
|
113090
113098
|
padSize
|
|
@@ -113203,7 +113211,7 @@ const lens = {
|
|
|
113203
113211
|
`
|
|
113204
113212
|
}
|
|
113205
113213
|
};
|
|
113206
|
-
const defaultProps$2$
|
|
113214
|
+
const defaultProps$2$2 = {
|
|
113207
113215
|
lensEnabled: { type: "boolean", value: false, compare: true },
|
|
113208
113216
|
lensSelection: { type: "number", value: 0, compare: true },
|
|
113209
113217
|
lensRadius: { type: "number", value: 100, compare: true },
|
|
@@ -113225,7 +113233,7 @@ const LensExtension = class extends LayerExtension {
|
|
|
113225
113233
|
}
|
|
113226
113234
|
const onMouseMove = () => {
|
|
113227
113235
|
const { viewportId } = layer.props;
|
|
113228
|
-
const { lensRadius = defaultProps$2$
|
|
113236
|
+
const { lensRadius = defaultProps$2$2.lensRadius.value } = this.props;
|
|
113229
113237
|
if (!viewportId) {
|
|
113230
113238
|
layer.setState({ unprojectLensBounds: [0, 0, 0, 0] });
|
|
113231
113239
|
return;
|
|
@@ -113272,10 +113280,10 @@ const LensExtension = class extends LayerExtension {
|
|
|
113272
113280
|
const { unprojectLensBounds = [0, 0, 0, 0] } = this.state;
|
|
113273
113281
|
const {
|
|
113274
113282
|
bounds: bounds2,
|
|
113275
|
-
lensEnabled = defaultProps$2$
|
|
113276
|
-
lensSelection = defaultProps$2$
|
|
113277
|
-
lensBorderColor = defaultProps$2$
|
|
113278
|
-
lensBorderRadius = defaultProps$2$
|
|
113283
|
+
lensEnabled = defaultProps$2$2.lensEnabled.value,
|
|
113284
|
+
lensSelection = defaultProps$2$2.lensSelection.value,
|
|
113285
|
+
lensBorderColor = defaultProps$2$2.lensBorderColor.value,
|
|
113286
|
+
lensBorderRadius = defaultProps$2$2.lensBorderRadius.value,
|
|
113279
113287
|
colors,
|
|
113280
113288
|
channelsVisible
|
|
113281
113289
|
} = this.props;
|
|
@@ -113316,7 +113324,7 @@ const LensExtension = class extends LayerExtension {
|
|
|
113316
113324
|
}
|
|
113317
113325
|
};
|
|
113318
113326
|
LensExtension.extensionName = "LensExtension";
|
|
113319
|
-
LensExtension.defaultProps = defaultProps$2$
|
|
113327
|
+
LensExtension.defaultProps = defaultProps$2$2;
|
|
113320
113328
|
function colormapModuleFactory3D(name2, apply_cmap) {
|
|
113321
113329
|
const fs2 = `${apply_cmap}
|
|
113322
113330
|
|
|
@@ -113556,7 +113564,7 @@ const channels = {
|
|
|
113556
113564
|
function range$3(len2) {
|
|
113557
113565
|
return [...Array(len2).keys()];
|
|
113558
113566
|
}
|
|
113559
|
-
function padWithDefault$
|
|
113567
|
+
function padWithDefault$2(arr, defaultValue2, padWidth) {
|
|
113560
113568
|
for (let i2 = 0; i2 < padWidth; i2 += 1) {
|
|
113561
113569
|
arr.push(defaultValue2);
|
|
113562
113570
|
}
|
|
@@ -113580,13 +113588,13 @@ function padContrastLimits({
|
|
|
113580
113588
|
const newContrastLimits = contrastLimits.map(
|
|
113581
113589
|
(slider, i2) => channelsVisible[i2] ? slider : [maxSliderValue, maxSliderValue]
|
|
113582
113590
|
);
|
|
113583
|
-
const padSize = MAX_CHANNELS - newContrastLimits.length;
|
|
113591
|
+
const padSize = MAX_CHANNELS$1 - newContrastLimits.length;
|
|
113584
113592
|
if (padSize < 0) {
|
|
113585
113593
|
throw Error(
|
|
113586
113594
|
`${newContrastLimits.lengths} channels passed in, but only 6 are allowed.`
|
|
113587
113595
|
);
|
|
113588
113596
|
}
|
|
113589
|
-
const paddedContrastLimits = padWithDefault$
|
|
113597
|
+
const paddedContrastLimits = padWithDefault$2(
|
|
113590
113598
|
newContrastLimits,
|
|
113591
113599
|
[maxSliderValue, maxSliderValue],
|
|
113592
113600
|
padSize
|
|
@@ -113616,7 +113624,7 @@ function makeBoundingBox(viewState) {
|
|
|
113616
113624
|
viewport.unproject([0, viewport.height])
|
|
113617
113625
|
];
|
|
113618
113626
|
}
|
|
113619
|
-
const fs$1 = `#define SHADER_NAME xr-layer-fragment-shader
|
|
113627
|
+
const fs$1$1 = `#define SHADER_NAME xr-layer-fragment-shader
|
|
113620
113628
|
|
|
113621
113629
|
precision highp float;
|
|
113622
113630
|
precision highp int;
|
|
@@ -113657,7 +113665,7 @@ void main() {
|
|
|
113657
113665
|
DECKGL_FILTER_COLOR(gl_FragColor, geometry);
|
|
113658
113666
|
}
|
|
113659
113667
|
`;
|
|
113660
|
-
const vs$1 = `#define SHADER_NAME xr-layer-vertex-shader
|
|
113668
|
+
const vs$1$1 = `#define SHADER_NAME xr-layer-vertex-shader
|
|
113661
113669
|
|
|
113662
113670
|
attribute vec2 texCoords;
|
|
113663
113671
|
attribute vec3 positions;
|
|
@@ -113676,7 +113684,7 @@ void main(void) {
|
|
|
113676
113684
|
DECKGL_FILTER_COLOR(color, geometry);
|
|
113677
113685
|
}
|
|
113678
113686
|
`;
|
|
113679
|
-
const coreShaderModule = { fs: fs$1, vs: vs$1 };
|
|
113687
|
+
const coreShaderModule = { fs: fs$1$1, vs: vs$1$1 };
|
|
113680
113688
|
function validateWebGL2Filter(gl, interpolation) {
|
|
113681
113689
|
const canShowFloat = hasFeature(gl, FEATURES$1.TEXTURE_FLOAT);
|
|
113682
113690
|
const canShowLinear = hasFeature(gl, FEATURES$1.TEXTURE_FILTER_LINEAR_FLOAT);
|
|
@@ -114410,7 +114418,7 @@ function getPosition$1(boundingBox, position, length2) {
|
|
|
114410
114418
|
}
|
|
114411
114419
|
}
|
|
114412
114420
|
}
|
|
114413
|
-
const defaultProps$2 = {
|
|
114421
|
+
const defaultProps$2$1 = {
|
|
114414
114422
|
pickable: { type: "boolean", value: true, compare: true },
|
|
114415
114423
|
viewState: {
|
|
114416
114424
|
type: "object",
|
|
@@ -114503,7 +114511,7 @@ const ScaleBarLayer = class extends CompositeLayer {
|
|
|
114503
114511
|
}
|
|
114504
114512
|
};
|
|
114505
114513
|
ScaleBarLayer.layerName = "ScaleBarLayer";
|
|
114506
|
-
ScaleBarLayer.defaultProps = defaultProps$2;
|
|
114514
|
+
ScaleBarLayer.defaultProps = defaultProps$2$1;
|
|
114507
114515
|
const vs$2 = `#version 300 es
|
|
114508
114516
|
#define SHADER_NAME xr-layer-vertex-shader
|
|
114509
114517
|
|
|
@@ -114909,7 +114917,7 @@ const XR3DLayer = class extends Layer {
|
|
|
114909
114917
|
});
|
|
114910
114918
|
const invertedScaleMatrix = scaleMatrix.clone().invert();
|
|
114911
114919
|
const invertedResolutionMatrix = resolutionMatrix.clone().invert();
|
|
114912
|
-
const paddedClippingPlanes = padWithDefault$
|
|
114920
|
+
const paddedClippingPlanes = padWithDefault$2(
|
|
114913
114921
|
clippingPlanes.map(
|
|
114914
114922
|
(p) => p.clone().transform(invertedScaleMatrix).transform(invertedResolutionMatrix)
|
|
114915
114923
|
),
|
|
@@ -115221,7 +115229,7 @@ const VolumeLayer = class extends CompositeLayer {
|
|
|
115221
115229
|
};
|
|
115222
115230
|
VolumeLayer.layerName = "VolumeLayer";
|
|
115223
115231
|
VolumeLayer.defaultProps = defaultProps$9;
|
|
115224
|
-
const vs = `
|
|
115232
|
+
const vs$1 = `
|
|
115225
115233
|
#define SHADER_NAME bitmask-layer-vertex-shader
|
|
115226
115234
|
|
|
115227
115235
|
attribute vec2 texCoords;
|
|
@@ -115242,7 +115250,7 @@ void main(void) {
|
|
|
115242
115250
|
DECKGL_FILTER_COLOR(color, geometry);
|
|
115243
115251
|
}
|
|
115244
115252
|
`;
|
|
115245
|
-
const fs = `
|
|
115253
|
+
const fs$1 = `
|
|
115246
115254
|
#define SHADER_NAME bitmask-layer-fragment-shader
|
|
115247
115255
|
precision highp float;
|
|
115248
115256
|
|
|
@@ -115310,14 +115318,14 @@ void main() {
|
|
|
115310
115318
|
DECKGL_FILTER_COLOR(gl_FragColor, geometry);
|
|
115311
115319
|
}
|
|
115312
115320
|
`;
|
|
115313
|
-
function padWithDefault(arr, defaultValue2, padWidth) {
|
|
115321
|
+
function padWithDefault$1(arr, defaultValue2, padWidth) {
|
|
115314
115322
|
const newArr = [...arr];
|
|
115315
115323
|
for (let i2 = 0; i2 < padWidth; i2 += 1) {
|
|
115316
115324
|
newArr.push(defaultValue2);
|
|
115317
115325
|
}
|
|
115318
115326
|
return newArr;
|
|
115319
115327
|
}
|
|
115320
|
-
const defaultProps$
|
|
115328
|
+
const defaultProps$2 = {
|
|
115321
115329
|
hoveredCell: { type: "number", value: null, compare: true },
|
|
115322
115330
|
// We do not want to deep-compare cellColorData,
|
|
115323
115331
|
// as it is potentially a TypedArray with millions of elements.
|
|
@@ -115329,13 +115337,13 @@ const defaultProps$1 = {
|
|
|
115329
115337
|
// Same as with cellColorData, we do not want to deep-compare expressionData.
|
|
115330
115338
|
expressionData: { type: "object", value: null, compare: 0 }
|
|
115331
115339
|
};
|
|
115332
|
-
class BitmaskLayer extends XRLayer {
|
|
115340
|
+
let BitmaskLayer$1 = class BitmaskLayer extends XRLayer {
|
|
115333
115341
|
// eslint-disable-next-line class-methods-use-this
|
|
115334
115342
|
getShaders() {
|
|
115335
115343
|
const { colormap } = this.props;
|
|
115336
115344
|
return {
|
|
115337
|
-
fs,
|
|
115338
|
-
vs,
|
|
115345
|
+
fs: fs$1,
|
|
115346
|
+
vs: vs$1,
|
|
115339
115347
|
modules: [project32, picking],
|
|
115340
115348
|
defines: {
|
|
115341
115349
|
[COLORMAP_SHADER_PLACEHOLDER]: GLSL_COLORMAPS.includes(colormap) ? colormap : GLSL_COLORMAP_DEFAULT
|
|
@@ -115395,7 +115403,7 @@ class BitmaskLayer extends XRLayer {
|
|
|
115395
115403
|
expressionTex,
|
|
115396
115404
|
colorTexHeight: colorTex.height,
|
|
115397
115405
|
colorTexWidth: colorTex.width,
|
|
115398
|
-
channelsVisible: padWithDefault(
|
|
115406
|
+
channelsVisible: padWithDefault$1(
|
|
115399
115407
|
channelsVisible,
|
|
115400
115408
|
false,
|
|
115401
115409
|
// There are six texture entries on the shaders
|
|
@@ -115432,9 +115440,9 @@ class BitmaskLayer extends XRLayer {
|
|
|
115432
115440
|
type: GL$1.FLOAT
|
|
115433
115441
|
});
|
|
115434
115442
|
}
|
|
115435
|
-
}
|
|
115436
|
-
BitmaskLayer.layerName = "BitmaskLayer";
|
|
115437
|
-
BitmaskLayer.defaultProps = defaultProps$
|
|
115443
|
+
};
|
|
115444
|
+
BitmaskLayer$1.layerName = "BitmaskLayer";
|
|
115445
|
+
BitmaskLayer$1.defaultProps = defaultProps$2;
|
|
115438
115446
|
var pluralize = { exports: {} };
|
|
115439
115447
|
(function(module2, exports2) {
|
|
115440
115448
|
(function(root2, pluralize2) {
|
|
@@ -123869,8 +123877,10 @@ const ViewType$1 = {
|
|
|
123869
123877
|
STATUS: "status",
|
|
123870
123878
|
SCATTERPLOT: "scatterplot",
|
|
123871
123879
|
SPATIAL: "spatial",
|
|
123880
|
+
SPATIAL_BETA: "spatialBeta",
|
|
123872
123881
|
HEATMAP: "heatmap",
|
|
123873
123882
|
LAYER_CONTROLLER: "layerController",
|
|
123883
|
+
LAYER_CONTROLLER_BETA: "layerControllerBeta",
|
|
123874
123884
|
GENOMIC_PROFILES: "genomicProfiles",
|
|
123875
123885
|
GATING: "gating",
|
|
123876
123886
|
FEATURE_LIST: "featureList",
|
|
@@ -123882,20 +123892,24 @@ const ViewType$1 = {
|
|
|
123882
123892
|
const DataType$1 = {
|
|
123883
123893
|
OBS_LABELS: "obsLabels",
|
|
123884
123894
|
OBS_EMBEDDING: "obsEmbedding",
|
|
123885
|
-
OBS_LOCATIONS: "obsLocations",
|
|
123886
123895
|
OBS_FEATURE_MATRIX: "obsFeatureMatrix",
|
|
123887
123896
|
OBS_SETS: "obsSets",
|
|
123888
123897
|
FEATURE_LABELS: "featureLabels",
|
|
123889
123898
|
IMAGE: "image",
|
|
123890
123899
|
OBS_SEGMENTATIONS: "obsSegmentations",
|
|
123891
123900
|
NEIGHBORHOODS: "neighborhoods",
|
|
123892
|
-
GENOMIC_PROFILES: "genomic-profiles"
|
|
123901
|
+
GENOMIC_PROFILES: "genomic-profiles",
|
|
123902
|
+
OBS_SPOTS: "obsSpots",
|
|
123903
|
+
OBS_POINTS: "obsPoints",
|
|
123904
|
+
OBS_LOCATIONS: "obsLocations"
|
|
123893
123905
|
};
|
|
123894
123906
|
const FileType$1 = {
|
|
123895
123907
|
// Joint file types
|
|
123896
123908
|
ANNDATA_ZARR: "anndata.zarr",
|
|
123897
123909
|
// Atomic file types
|
|
123898
123910
|
OBS_EMBEDDING_CSV: "obsEmbedding.csv",
|
|
123911
|
+
OBS_SPOTS_CSV: "obsSpots.csv",
|
|
123912
|
+
OBS_POINTS_CSV: "obsPoints.csv",
|
|
123899
123913
|
OBS_LOCATIONS_CSV: "obsLocations.csv",
|
|
123900
123914
|
OBS_LABELS_CSV: "obsLabels.csv",
|
|
123901
123915
|
FEATURE_LABELS_CSV: "featureLabels.csv",
|
|
@@ -123908,6 +123922,8 @@ const FileType$1 = {
|
|
|
123908
123922
|
OBS_FEATURE_MATRIX_ANNDATA_ZARR: "obsFeatureMatrix.anndata.zarr",
|
|
123909
123923
|
OBS_SETS_ANNDATA_ZARR: "obsSets.anndata.zarr",
|
|
123910
123924
|
OBS_EMBEDDING_ANNDATA_ZARR: "obsEmbedding.anndata.zarr",
|
|
123925
|
+
OBS_SPOTS_ANNDATA_ZARR: "obsSpots.anndata.zarr",
|
|
123926
|
+
OBS_POINTS_ANNDATA_ZARR: "obsPoints.anndata.zarr",
|
|
123911
123927
|
OBS_LOCATIONS_ANNDATA_ZARR: "obsLocations.anndata.zarr",
|
|
123912
123928
|
OBS_SEGMENTATIONS_ANNDATA_ZARR: "obsSegmentations.anndata.zarr",
|
|
123913
123929
|
OBS_LABELS_ANNDATA_ZARR: "obsLabels.anndata.zarr",
|
|
@@ -123916,6 +123932,8 @@ const FileType$1 = {
|
|
|
123916
123932
|
OBS_FEATURE_MATRIX_MUDATA_ZARR: "obsFeatureMatrix.mudata.zarr",
|
|
123917
123933
|
OBS_SETS_MUDATA_ZARR: "obsSets.mudata.zarr",
|
|
123918
123934
|
OBS_EMBEDDING_MUDATA_ZARR: "obsEmbedding.mudata.zarr",
|
|
123935
|
+
OBS_SPOTS_MUDATA_ZARR: "obsSpots.mudata.zarr",
|
|
123936
|
+
OBS_POINTS_MUDATA_ZARR: "obsPoints.mudata.zarr",
|
|
123919
123937
|
OBS_LOCATIONS_MUDATA_ZARR: "obsLocations.mudata.zarr",
|
|
123920
123938
|
OBS_SEGMENTATIONS_MUDATA_ZARR: "obsSegmentations.mudata.zarr",
|
|
123921
123939
|
OBS_LABELS_MUDATA_ZARR: "obsLabels.mudata.zarr",
|
|
@@ -123959,10 +123977,8 @@ const FileType$1 = {
|
|
|
123959
123977
|
ANNDATA_EXPRESSION_MATRIX_ZARR: "anndata-expression-matrix.zarr"
|
|
123960
123978
|
};
|
|
123961
123979
|
const CoordinationType$1 = {
|
|
123962
|
-
// Meta coordination scopes
|
|
123963
123980
|
META_COORDINATION_SCOPES: "metaCoordinationScopes",
|
|
123964
123981
|
META_COORDINATION_SCOPES_BY: "metaCoordinationScopesBy",
|
|
123965
|
-
// Other coordination scopes
|
|
123966
123982
|
DATASET: "dataset",
|
|
123967
123983
|
// Entity types
|
|
123968
123984
|
OBS_TYPE: "obsType",
|
|
@@ -123988,6 +124004,7 @@ const CoordinationType$1 = {
|
|
|
123988
124004
|
SPATIAL_TARGET_X: "spatialTargetX",
|
|
123989
124005
|
SPATIAL_TARGET_Y: "spatialTargetY",
|
|
123990
124006
|
SPATIAL_TARGET_Z: "spatialTargetZ",
|
|
124007
|
+
SPATIAL_TARGET_T: "spatialTargetT",
|
|
123991
124008
|
SPATIAL_ROTATION_X: "spatialRotationX",
|
|
123992
124009
|
SPATIAL_ROTATION_Y: "spatialRotationY",
|
|
123993
124010
|
SPATIAL_ROTATION_Z: "spatialRotationZ",
|
|
@@ -124025,7 +124042,46 @@ const CoordinationType$1 = {
|
|
|
124025
124042
|
GATING_FEATURE_SELECTION_X: "gatingFeatureSelectionX",
|
|
124026
124043
|
GATING_FEATURE_SELECTION_Y: "gatingFeatureSelectionY",
|
|
124027
124044
|
FEATURE_VALUE_TRANSFORM_COEFFICIENT: "featureValueTransformCoefficient",
|
|
124028
|
-
TOOLTIPS_VISIBLE: "tooltipsVisible"
|
|
124045
|
+
TOOLTIPS_VISIBLE: "tooltipsVisible",
|
|
124046
|
+
FILE_UID: "fileUid",
|
|
124047
|
+
IMAGE_LAYER: "imageLayer",
|
|
124048
|
+
IMAGE_CHANNEL: "imageChannel",
|
|
124049
|
+
SEGMENTATION_LAYER: "segmentationLayer",
|
|
124050
|
+
SEGMENTATION_CHANNEL: "segmentationChannel",
|
|
124051
|
+
SPATIAL_TARGET_C: "spatialTargetC",
|
|
124052
|
+
SPATIAL_LAYER_VISIBLE: "spatialLayerVisible",
|
|
124053
|
+
SPATIAL_LAYER_OPACITY: "spatialLayerOpacity",
|
|
124054
|
+
SPATIAL_LAYER_COLORMAP: "spatialLayerColormap",
|
|
124055
|
+
SPATIAL_LAYER_TRANSPARENT_COLOR: "spatialLayerTransparentColor",
|
|
124056
|
+
SPATIAL_LAYER_MODEL_MATRIX: "spatialLayerModelMatrix",
|
|
124057
|
+
SPATIAL_SEGMENTATION_FILLED: "spatialSegmentationFilled",
|
|
124058
|
+
SPATIAL_SEGMENTATION_STROKE_WIDTH: "spatialSegmentationStrokeWidth",
|
|
124059
|
+
SPATIAL_CHANNEL_COLOR: "spatialChannelColor",
|
|
124060
|
+
SPATIAL_CHANNEL_VISIBLE: "spatialChannelVisible",
|
|
124061
|
+
SPATIAL_CHANNEL_OPACITY: "spatialChannelOpacity",
|
|
124062
|
+
SPATIAL_CHANNEL_WINDOW: "spatialChannelWindow",
|
|
124063
|
+
PHOTOMETRIC_INTERPRETATION: "photometricInterpretation",
|
|
124064
|
+
// For 3D volume rendering
|
|
124065
|
+
SPATIAL_RENDERING_MODE: "spatialRenderingMode",
|
|
124066
|
+
VOLUMETRIC_RENDERING_ALGORITHM: "volumetricRenderingAlgorithm",
|
|
124067
|
+
SPATIAL_TARGET_RESOLUTION: "spatialTargetResolution",
|
|
124068
|
+
// For clipping plane sliders
|
|
124069
|
+
SPATIAL_SLICE_X: "spatialSliceX",
|
|
124070
|
+
SPATIAL_SLICE_Y: "spatialSliceY",
|
|
124071
|
+
SPATIAL_SLICE_Z: "spatialSliceZ",
|
|
124072
|
+
// For spatial spot and point layers
|
|
124073
|
+
SPOT_LAYER: "spotLayer",
|
|
124074
|
+
POINT_LAYER: "pointLayer",
|
|
124075
|
+
SPATIAL_SPOT_RADIUS: "spatialSpotRadius",
|
|
124076
|
+
SPATIAL_SPOT_FILLED: "spatialSpotFilled",
|
|
124077
|
+
SPATIAL_SPOT_STROKE_WIDTH: "spatialSpotStrokeWidth",
|
|
124078
|
+
SPATIAL_LAYER_COLOR: "spatialLayerColor",
|
|
124079
|
+
PIXEL_HIGHLIGHT: "pixelHighlight",
|
|
124080
|
+
TOOLTIP_CROSSHAIRS_VISIBLE: "tooltipCrosshairsVisible",
|
|
124081
|
+
LEGEND_VISIBLE: "legendVisible",
|
|
124082
|
+
SPATIAL_CHANNEL_LABELS_VISIBLE: "spatialChannelLabelsVisible",
|
|
124083
|
+
SPATIAL_CHANNEL_LABELS_ORIENTATION: "spatialChannelLabelsOrientation",
|
|
124084
|
+
SPATIAL_CHANNEL_LABEL_SIZE: "spatialChannelLabelSize"
|
|
124029
124085
|
};
|
|
124030
124086
|
const ViewType = {
|
|
124031
124087
|
GENES: [
|
|
@@ -124286,6 +124342,8 @@ const annDataObsSets = z.array(z.object({
|
|
|
124286
124342
|
]),
|
|
124287
124343
|
scorePath: z.string().optional().describe("The location in the AnnData store for the set confidence scores, like 'obs/celltype_prediction_score.'")
|
|
124288
124344
|
}));
|
|
124345
|
+
const annDataObsSpots = annDataObsm;
|
|
124346
|
+
const annDataObsPoints = annDataObsm;
|
|
124289
124347
|
const annDataObsLocations = annDataObsm;
|
|
124290
124348
|
const annDataObsEmbedding = annDataObsm;
|
|
124291
124349
|
const annDataObsSegmentations = annDataObs;
|
|
@@ -124312,10 +124370,21 @@ z.object({
|
|
|
124312
124370
|
z.object({
|
|
124313
124371
|
obsIndex: z.string(),
|
|
124314
124372
|
obsEmbedding: z.array(z.string()).length(2)
|
|
124373
|
+
// TODO: support 3D?
|
|
124374
|
+
});
|
|
124375
|
+
z.object({
|
|
124376
|
+
obsIndex: z.string(),
|
|
124377
|
+
obsSpots: z.array(z.string()).length(2)
|
|
124378
|
+
// TODO: support 3D?
|
|
124379
|
+
});
|
|
124380
|
+
z.object({
|
|
124381
|
+
obsIndex: z.string(),
|
|
124382
|
+
obsPoints: z.array(z.string()).length(3)
|
|
124315
124383
|
});
|
|
124316
124384
|
z.object({
|
|
124317
124385
|
obsIndex: z.string(),
|
|
124318
124386
|
obsLocations: z.array(z.string()).length(2)
|
|
124387
|
+
// TODO: support 3D?
|
|
124319
124388
|
});
|
|
124320
124389
|
z.object({
|
|
124321
124390
|
obsIndex: z.string(),
|
|
@@ -124347,6 +124416,8 @@ z.object({
|
|
|
124347
124416
|
]),
|
|
124348
124417
|
obsFeatureMatrix: annDataObsFeatureMatrix,
|
|
124349
124418
|
obsSets: annDataObsSets,
|
|
124419
|
+
obsSpots: annDataObsSpots,
|
|
124420
|
+
obsPoints: annDataObsPoints,
|
|
124350
124421
|
obsLocations: annDataObsLocations,
|
|
124351
124422
|
obsSegmentations: annDataObsSegmentations,
|
|
124352
124423
|
obsEmbedding: z.union([
|
|
@@ -130893,6 +130964,596 @@ function interpolateSequentialMulti(range2) {
|
|
|
130893
130964
|
}
|
|
130894
130965
|
interpolateRgbBasis(schemeRdBu);
|
|
130895
130966
|
interpolateSequentialMulti(schemePlasma);
|
|
130967
|
+
const vs = `
|
|
130968
|
+
#define SHADER_NAME bitmask-layer-vertex-shader
|
|
130969
|
+
|
|
130970
|
+
attribute vec2 texCoords;
|
|
130971
|
+
attribute vec3 positions;
|
|
130972
|
+
attribute vec3 positions64Low;
|
|
130973
|
+
attribute vec3 instancePickingColors;
|
|
130974
|
+
|
|
130975
|
+
varying vec2 vTexCoord;
|
|
130976
|
+
|
|
130977
|
+
void main(void) {
|
|
130978
|
+
geometry.worldPosition = positions;
|
|
130979
|
+
geometry.uv = texCoords;
|
|
130980
|
+
geometry.pickingColor = instancePickingColors;
|
|
130981
|
+
gl_Position = project_position_to_clipspace(positions, positions64Low, vec3(0.0), geometry.position);
|
|
130982
|
+
DECKGL_FILTER_GL_POSITION(gl_Position, geometry);
|
|
130983
|
+
vTexCoord = texCoords;
|
|
130984
|
+
vec4 color = vec4(0.0);
|
|
130985
|
+
DECKGL_FILTER_COLOR(color, geometry);
|
|
130986
|
+
}
|
|
130987
|
+
`;
|
|
130988
|
+
const fs = `
|
|
130989
|
+
#define SHADER_NAME bitmask-layer-fragment-shader
|
|
130990
|
+
precision highp float;
|
|
130991
|
+
|
|
130992
|
+
${colormaps}
|
|
130993
|
+
|
|
130994
|
+
// Note: can have a maximum of 16 textures in most browsers
|
|
130995
|
+
// Reference: https://webglreport.com/
|
|
130996
|
+
|
|
130997
|
+
// Data (mask) texture
|
|
130998
|
+
uniform sampler2D channel0;
|
|
130999
|
+
uniform sampler2D channel1;
|
|
131000
|
+
uniform sampler2D channel2;
|
|
131001
|
+
uniform sampler2D channel3;
|
|
131002
|
+
uniform sampler2D channel4;
|
|
131003
|
+
uniform sampler2D channel5;
|
|
131004
|
+
uniform sampler2D channel6;
|
|
131005
|
+
|
|
131006
|
+
// Color texture
|
|
131007
|
+
uniform float hovered;
|
|
131008
|
+
|
|
131009
|
+
// Channel-specific properties
|
|
131010
|
+
uniform bool channelsVisible[7];
|
|
131011
|
+
uniform float channelOpacities[7];
|
|
131012
|
+
uniform bool channelIsStaticColorMode[7]; // TODO: should this be a single float?
|
|
131013
|
+
uniform bool channelIsSetColorMode[7]; // TODO: should this be a single float?
|
|
131014
|
+
|
|
131015
|
+
// TODO: can array of tuples/vec2 be used?
|
|
131016
|
+
uniform float channelColormapRangeStarts[7];
|
|
131017
|
+
uniform float channelColormapRangeEnds[7];
|
|
131018
|
+
|
|
131019
|
+
uniform float multiFeatureTexSize;
|
|
131020
|
+
|
|
131021
|
+
// Use one expressionTex for all channels, using an offset mechanism.
|
|
131022
|
+
uniform sampler2D valueTex;
|
|
131023
|
+
uniform float valueTexOffsets[7];
|
|
131024
|
+
uniform float valueTexHeight;
|
|
131025
|
+
|
|
131026
|
+
// Textures for set colors, using the same offset mechanism.
|
|
131027
|
+
uniform sampler2D colorTex;
|
|
131028
|
+
uniform float colorTexOffsets[7];
|
|
131029
|
+
uniform float colorTexHeight;
|
|
131030
|
+
|
|
131031
|
+
|
|
131032
|
+
// Static colors
|
|
131033
|
+
// TODO: For some reason I cannot use uniform vec3 colors[7]; and i cannot figure out why.
|
|
131034
|
+
uniform vec3 color0;
|
|
131035
|
+
uniform vec3 color1;
|
|
131036
|
+
uniform vec3 color2;
|
|
131037
|
+
uniform vec3 color3;
|
|
131038
|
+
uniform vec3 color4;
|
|
131039
|
+
uniform vec3 color5;
|
|
131040
|
+
uniform vec3 color6;
|
|
131041
|
+
|
|
131042
|
+
// Info for edge-only mode
|
|
131043
|
+
uniform float scaleFactor;
|
|
131044
|
+
uniform bool channelsFilled[7];
|
|
131045
|
+
uniform float channelStrokeWidths[7];
|
|
131046
|
+
|
|
131047
|
+
// opacity
|
|
131048
|
+
uniform float opacity;
|
|
131049
|
+
|
|
131050
|
+
varying vec2 vTexCoord;
|
|
131051
|
+
|
|
131052
|
+
vec3 sampleAndGetData(sampler2D dataTex, vec2 coord, bool isFilled, float strokeWidth, bool isOn) {
|
|
131053
|
+
float sampledData = texture(dataTex, coord).r;
|
|
131054
|
+
float clampedSampledData = max(0., min(sampledData, 1.));
|
|
131055
|
+
|
|
131056
|
+
bool isEdge = true;
|
|
131057
|
+
|
|
131058
|
+
if(!isFilled) {
|
|
131059
|
+
vec2 uTextureSize = vec2(2048.0, 2048.0);
|
|
131060
|
+
vec2 onePixel = vec2(1.0, 1.0) / uTextureSize;
|
|
131061
|
+
|
|
131062
|
+
// Vary the edgeSize based on user-defined stroke width.
|
|
131063
|
+
float edgeSize = 150.0 * strokeWidth * scaleFactor;
|
|
131064
|
+
|
|
131065
|
+
float pixN = texture(dataTex, coord + vec2(0.0, onePixel.y * edgeSize)).r;
|
|
131066
|
+
float pixS = texture(dataTex, coord - vec2(0.0, onePixel.y * edgeSize)).r;
|
|
131067
|
+
float pixW = texture(dataTex, coord + vec2(onePixel.x * edgeSize, 0.0)).r;
|
|
131068
|
+
float pixE = texture(dataTex, coord - vec2(onePixel.x * edgeSize, 0.0)).r;
|
|
131069
|
+
|
|
131070
|
+
float pixNW = texture(dataTex, coord + vec2(onePixel.y * edgeSize, onePixel.y * edgeSize)).r;
|
|
131071
|
+
float pixNE = texture(dataTex, coord + vec2(-1.0 * onePixel.x * edgeSize, onePixel.y * edgeSize)).r;
|
|
131072
|
+
float pixSW = texture(dataTex, coord - vec2(onePixel.x * edgeSize, onePixel.y * edgeSize)).r;
|
|
131073
|
+
float pixSE = texture(dataTex, coord - vec2(-1.0 * onePixel.x * edgeSize, onePixel.y * edgeSize)).r;
|
|
131074
|
+
|
|
131075
|
+
isEdge = (pixN != sampledData || pixS != sampledData || pixW != sampledData || pixE != sampledData || pixNW != sampledData || pixNE != sampledData || pixSW != sampledData || pixSE != sampledData);
|
|
131076
|
+
}
|
|
131077
|
+
// Return a tuple of (sampledData, isEdge)
|
|
131078
|
+
return vec3(clampedSampledData * float(isOn), sampledData, float(isEdge));
|
|
131079
|
+
}
|
|
131080
|
+
|
|
131081
|
+
vec4 dataToColor(vec3 sampledDataAndIsEdge, bool isStaticColorMode, vec3 channelColor, float channelOpacity, float valueOffset, float rangeStart, float rangeEnd, bool isSetColorMode, float setColorOffset) {
|
|
131082
|
+
float clampedSampledDataAndIsOn = sampledDataAndIsEdge.x;
|
|
131083
|
+
float sampledData = sampledDataAndIsEdge.y;
|
|
131084
|
+
float isEdge = sampledDataAndIsEdge.z;
|
|
131085
|
+
|
|
131086
|
+
|
|
131087
|
+
vec4 hoveredColor = float(sampledData == hovered && sampledData > 0. && hovered > 0.) * vec4(0., 0., 1., 1.);
|
|
131088
|
+
|
|
131089
|
+
// Colors are laid out corresponding to ids in row-major order in the texture. So if width of the texture is 10, and you want ID 25,
|
|
131090
|
+
// you need coordinate (1, 4) (i.e 2 rows down, and 5 columns over indexed from 0 for a total of 25 units covered in row major order).
|
|
131091
|
+
float offsetSampledData = sampledData + valueOffset - 1.0;
|
|
131092
|
+
vec2 colorTexCoord = vec2(mod(offsetSampledData, multiFeatureTexSize) / multiFeatureTexSize, floor(offsetSampledData / multiFeatureTexSize) / (valueTexHeight - 1.));
|
|
131093
|
+
|
|
131094
|
+
// Get expression value
|
|
131095
|
+
float expressionValue = texture(valueTex, colorTexCoord).r / 255.;
|
|
131096
|
+
float scaledExpressionValue = (expressionValue - rangeStart) / max(0.005, (rangeEnd - rangeStart));
|
|
131097
|
+
|
|
131098
|
+
|
|
131099
|
+
// Get set color index value
|
|
131100
|
+
vec2 setIndicesTexCoord = vec2(mod(offsetSampledData, multiFeatureTexSize) / multiFeatureTexSize, floor(offsetSampledData / multiFeatureTexSize) / (valueTexHeight - 1.));
|
|
131101
|
+
float setColorIndex = texture(valueTex, setIndicesTexCoord).r;
|
|
131102
|
+
|
|
131103
|
+
// Initialize to the default "null" color.
|
|
131104
|
+
vec3 setColor = vec3(200. / 255., 200. / 255., 200. / 255.);
|
|
131105
|
+
if(setColorIndex != 0.) {
|
|
131106
|
+
// Subtract one from setColorIndex because we have already checked for the "null" value.
|
|
131107
|
+
setColorIndex = setColorIndex - 1.;
|
|
131108
|
+
|
|
131109
|
+
float setColorOffsetR = (setColorIndex + setColorOffset) * 3.0 + 0.0;
|
|
131110
|
+
vec2 setColorTexCoordR = vec2(mod(setColorOffsetR, multiFeatureTexSize) / multiFeatureTexSize, floor(setColorOffsetR / multiFeatureTexSize) / (colorTexHeight - 1.));
|
|
131111
|
+
float setColorR = texture(colorTex, setColorTexCoordR).r / 255.;
|
|
131112
|
+
|
|
131113
|
+
float setColorOffsetG = (setColorIndex + setColorOffset) * 3.0 + 1.0;
|
|
131114
|
+
vec2 setColorTexCoordG = vec2(mod(setColorOffsetG, multiFeatureTexSize) / multiFeatureTexSize, floor(setColorOffsetG / multiFeatureTexSize) / (colorTexHeight - 1.));
|
|
131115
|
+
float setColorG = texture(colorTex, setColorTexCoordG).r / 255.;
|
|
131116
|
+
|
|
131117
|
+
float setColorOffsetB = (setColorIndex + setColorOffset) * 3.0 + 2.0;
|
|
131118
|
+
vec2 setColorTexCoordB = vec2(mod(setColorOffsetB, multiFeatureTexSize) / multiFeatureTexSize, floor(setColorOffsetB / multiFeatureTexSize) / (colorTexHeight - 1.));
|
|
131119
|
+
float setColorB = texture(colorTex, setColorTexCoordB).r / 255.;
|
|
131120
|
+
|
|
131121
|
+
setColor = vec3(setColorR, setColorG, setColorB);
|
|
131122
|
+
}
|
|
131123
|
+
|
|
131124
|
+
|
|
131125
|
+
vec4 sampledColor = (1. - (float(isStaticColorMode) + float(isSetColorMode))) * vec4(COLORMAP_FUNC(clamp(scaledExpressionValue, 0.0, 1.0)).rgb, channelOpacity) + float(isStaticColorMode) * vec4(channelColor.rgb, channelOpacity) + float(isSetColorMode) * vec4(setColor, channelOpacity);
|
|
131126
|
+
// Only return a color if the data is non-zero.
|
|
131127
|
+
|
|
131128
|
+
return clampedSampledDataAndIsOn * isEdge * sampledColor;
|
|
131129
|
+
}
|
|
131130
|
+
|
|
131131
|
+
void main() {
|
|
131132
|
+
|
|
131133
|
+
// Get the color and alpha value for each channel.
|
|
131134
|
+
vec3 dat0 = sampleAndGetData(channel0, vTexCoord, channelsFilled[0], channelStrokeWidths[0], channelsVisible[0]);
|
|
131135
|
+
vec3 dat1 = sampleAndGetData(channel1, vTexCoord, channelsFilled[1], channelStrokeWidths[1], channelsVisible[1]);
|
|
131136
|
+
vec3 dat2 = sampleAndGetData(channel2, vTexCoord, channelsFilled[2], channelStrokeWidths[2], channelsVisible[2]);
|
|
131137
|
+
vec3 dat3 = sampleAndGetData(channel3, vTexCoord, channelsFilled[3], channelStrokeWidths[3], channelsVisible[3]);
|
|
131138
|
+
vec3 dat4 = sampleAndGetData(channel4, vTexCoord, channelsFilled[4], channelStrokeWidths[4], channelsVisible[4]);
|
|
131139
|
+
vec3 dat5 = sampleAndGetData(channel5, vTexCoord, channelsFilled[5], channelStrokeWidths[5], channelsVisible[5]);
|
|
131140
|
+
vec3 dat6 = sampleAndGetData(channel6, vTexCoord, channelsFilled[6], channelStrokeWidths[6], channelsVisible[6]);
|
|
131141
|
+
|
|
131142
|
+
vec4 val0 = dataToColor(dat0, channelIsStaticColorMode[0], color0, channelOpacities[0], valueTexOffsets[0], channelColormapRangeStarts[0], channelColormapRangeEnds[0], channelIsSetColorMode[0], colorTexOffsets[0]);
|
|
131143
|
+
vec4 val1 = dataToColor(dat1, channelIsStaticColorMode[1], color1, channelOpacities[1], valueTexOffsets[1], channelColormapRangeStarts[1], channelColormapRangeEnds[1], channelIsSetColorMode[1], colorTexOffsets[1]);
|
|
131144
|
+
vec4 val2 = dataToColor(dat2, channelIsStaticColorMode[2], color2, channelOpacities[2], valueTexOffsets[2], channelColormapRangeStarts[2], channelColormapRangeEnds[2], channelIsSetColorMode[2], colorTexOffsets[2]);
|
|
131145
|
+
vec4 val3 = dataToColor(dat3, channelIsStaticColorMode[3], color3, channelOpacities[3], valueTexOffsets[3], channelColormapRangeStarts[3], channelColormapRangeEnds[3], channelIsSetColorMode[3], colorTexOffsets[3]);
|
|
131146
|
+
vec4 val4 = dataToColor(dat4, channelIsStaticColorMode[4], color4, channelOpacities[4], valueTexOffsets[4], channelColormapRangeStarts[4], channelColormapRangeEnds[4], channelIsSetColorMode[4], colorTexOffsets[4]);
|
|
131147
|
+
vec4 val5 = dataToColor(dat5, channelIsStaticColorMode[5], color5, channelOpacities[5], valueTexOffsets[5], channelColormapRangeStarts[5], channelColormapRangeEnds[5], channelIsSetColorMode[5], colorTexOffsets[5]);
|
|
131148
|
+
vec4 val6 = dataToColor(dat6, channelIsStaticColorMode[6], color6, channelOpacities[6], valueTexOffsets[6], channelColormapRangeStarts[6], channelColormapRangeEnds[6], channelIsSetColorMode[6], colorTexOffsets[6]);
|
|
131149
|
+
|
|
131150
|
+
// If all of the channels are "empty", then discard this pixel so that it is not considered during picking.
|
|
131151
|
+
float emptyDat = 0.;
|
|
131152
|
+
if(dat0.x == emptyDat && dat1.x == emptyDat && dat2.x == emptyDat && dat3.x == emptyDat && dat4.x == emptyDat && dat5.x == emptyDat && dat6.x == emptyDat) {
|
|
131153
|
+
discard;
|
|
131154
|
+
}
|
|
131155
|
+
|
|
131156
|
+
// If the next channel color and the currently stored color (gl_FragColor) are identical,
|
|
131157
|
+
// or the next channel color is transparent black,
|
|
131158
|
+
// just use the currently stored color. Repeat this for all channels.
|
|
131159
|
+
|
|
131160
|
+
// Mix colors where necessary, using the alpha value of the next channel as the weight.
|
|
131161
|
+
// Use the maximum alpha value as the resulting alpha value.
|
|
131162
|
+
gl_FragColor = val0;
|
|
131163
|
+
gl_FragColor = (val1 == gl_FragColor || val1 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val1, val1.a).rgb, max(gl_FragColor.a, val1.a));
|
|
131164
|
+
gl_FragColor = (val2 == gl_FragColor || val2 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val2, val2.a).rgb, max(gl_FragColor.a, val2.a));
|
|
131165
|
+
gl_FragColor = (val3 == gl_FragColor || val3 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val3, val3.a).rgb, max(gl_FragColor.a, val3.a));
|
|
131166
|
+
gl_FragColor = (val4 == gl_FragColor || val4 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val4, val4.a).rgb, max(gl_FragColor.a, val4.a));
|
|
131167
|
+
gl_FragColor = (val5 == gl_FragColor || val5 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val5, val5.a).rgb, max(gl_FragColor.a, val5.a));
|
|
131168
|
+
gl_FragColor = (val6 == gl_FragColor || val6 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val6, val6.a).rgb, max(gl_FragColor.a, val6.a));
|
|
131169
|
+
|
|
131170
|
+
|
|
131171
|
+
|
|
131172
|
+
// TODO: multiply the resulting channel-level opacity value by the layer-level opacity value.
|
|
131173
|
+
|
|
131174
|
+
geometry.uv = vTexCoord;
|
|
131175
|
+
DECKGL_FILTER_COLOR(gl_FragColor, geometry);
|
|
131176
|
+
}
|
|
131177
|
+
`;
|
|
131178
|
+
function extent(values2, valueof) {
|
|
131179
|
+
let min;
|
|
131180
|
+
let max;
|
|
131181
|
+
if (valueof === void 0) {
|
|
131182
|
+
for (const value of values2) {
|
|
131183
|
+
if (value != null) {
|
|
131184
|
+
if (min === void 0) {
|
|
131185
|
+
if (value >= value)
|
|
131186
|
+
min = max = value;
|
|
131187
|
+
} else {
|
|
131188
|
+
if (min > value)
|
|
131189
|
+
min = value;
|
|
131190
|
+
if (max < value)
|
|
131191
|
+
max = value;
|
|
131192
|
+
}
|
|
131193
|
+
}
|
|
131194
|
+
}
|
|
131195
|
+
} else {
|
|
131196
|
+
let index2 = -1;
|
|
131197
|
+
for (let value of values2) {
|
|
131198
|
+
if ((value = valueof(value, ++index2, values2)) != null) {
|
|
131199
|
+
if (min === void 0) {
|
|
131200
|
+
if (value >= value)
|
|
131201
|
+
min = max = value;
|
|
131202
|
+
} else {
|
|
131203
|
+
if (min > value)
|
|
131204
|
+
min = value;
|
|
131205
|
+
if (max < value)
|
|
131206
|
+
max = value;
|
|
131207
|
+
}
|
|
131208
|
+
}
|
|
131209
|
+
}
|
|
131210
|
+
}
|
|
131211
|
+
return [min, max];
|
|
131212
|
+
}
|
|
131213
|
+
function normalize(arr) {
|
|
131214
|
+
const [min, max] = extent(arr);
|
|
131215
|
+
const ratio = 255 / (max - min);
|
|
131216
|
+
const data = new Uint8Array(arr.map((i2) => Math.floor((i2 - min) * ratio)));
|
|
131217
|
+
return data;
|
|
131218
|
+
}
|
|
131219
|
+
function multiSetsToTextureData(multiFeatureValues, setColorValues, channelIsSetColorMode, texSize) {
|
|
131220
|
+
let totalValuesLength = 0;
|
|
131221
|
+
let totalColorsLength = 0;
|
|
131222
|
+
channelIsSetColorMode.forEach((isSetColorMode, channelIndex) => {
|
|
131223
|
+
var _a2, _b, _c, _d, _e;
|
|
131224
|
+
if (isSetColorMode) {
|
|
131225
|
+
totalValuesLength += ((_b = (_a2 = setColorValues[channelIndex]) == null ? void 0 : _a2.obsIndex) == null ? void 0 : _b.length) || 0;
|
|
131226
|
+
totalColorsLength += (((_d = (_c = setColorValues[channelIndex]) == null ? void 0 : _c.setColors) == null ? void 0 : _d.length) || 0) * 3;
|
|
131227
|
+
} else {
|
|
131228
|
+
totalValuesLength += ((_e = multiFeatureValues[channelIndex]) == null ? void 0 : _e.length) || 0;
|
|
131229
|
+
}
|
|
131230
|
+
});
|
|
131231
|
+
const valueTexHeight = Math.max(2, Math.ceil(totalValuesLength / texSize));
|
|
131232
|
+
const colorTexHeight = Math.max(2, Math.ceil(totalColorsLength / texSize));
|
|
131233
|
+
if (valueTexHeight > texSize) {
|
|
131234
|
+
console.error("Error: length of concatenated quantitative feature values larger than maximum texture size");
|
|
131235
|
+
}
|
|
131236
|
+
if (colorTexHeight > texSize) {
|
|
131237
|
+
console.error("Error: length of concatenated quantitative feature values larger than maximum texture size");
|
|
131238
|
+
}
|
|
131239
|
+
const totalData = new Uint8Array(texSize * valueTexHeight);
|
|
131240
|
+
const totalColors = new Uint8Array(texSize * colorTexHeight);
|
|
131241
|
+
const indicesOffsets = [];
|
|
131242
|
+
const colorsOffsets = [];
|
|
131243
|
+
let indexOffset = 0;
|
|
131244
|
+
let colorOffset = 0;
|
|
131245
|
+
channelIsSetColorMode.forEach((isSetColorMode, channelIndex) => {
|
|
131246
|
+
if (isSetColorMode) {
|
|
131247
|
+
const { setColorIndices, setColors, obsIndex } = setColorValues[channelIndex] || {};
|
|
131248
|
+
if (setColorIndices && setColors && obsIndex) {
|
|
131249
|
+
for (let i2 = 0; i2 < obsIndex.length; i2++) {
|
|
131250
|
+
const colorIndex = setColorIndices.get(String(i2 + 1));
|
|
131251
|
+
totalData[indexOffset + i2] = colorIndex === void 0 ? 0 : colorIndex + 1;
|
|
131252
|
+
}
|
|
131253
|
+
for (let i2 = 0; i2 < setColors.length; i2++) {
|
|
131254
|
+
const { color: [r2, g2, b] } = setColors[i2];
|
|
131255
|
+
totalColors[(colorOffset + i2) * 3 + 0] = r2;
|
|
131256
|
+
totalColors[(colorOffset + i2) * 3 + 1] = g2;
|
|
131257
|
+
totalColors[(colorOffset + i2) * 3 + 2] = b;
|
|
131258
|
+
}
|
|
131259
|
+
}
|
|
131260
|
+
indicesOffsets.push(indexOffset);
|
|
131261
|
+
colorsOffsets.push(colorOffset);
|
|
131262
|
+
indexOffset += (obsIndex == null ? void 0 : obsIndex.length) || 0;
|
|
131263
|
+
colorOffset += (setColors == null ? void 0 : setColors.length) || 0;
|
|
131264
|
+
} else {
|
|
131265
|
+
const featureArr = multiFeatureValues[channelIndex];
|
|
131266
|
+
totalData.set(normalize(featureArr), indexOffset);
|
|
131267
|
+
indicesOffsets.push(indexOffset);
|
|
131268
|
+
indexOffset += featureArr.length;
|
|
131269
|
+
colorsOffsets.push(colorOffset);
|
|
131270
|
+
}
|
|
131271
|
+
});
|
|
131272
|
+
return [
|
|
131273
|
+
totalData,
|
|
131274
|
+
valueTexHeight,
|
|
131275
|
+
indicesOffsets,
|
|
131276
|
+
totalColors,
|
|
131277
|
+
colorTexHeight,
|
|
131278
|
+
colorsOffsets
|
|
131279
|
+
];
|
|
131280
|
+
}
|
|
131281
|
+
const MAX_CHANNELS = 7;
|
|
131282
|
+
const MULTI_FEATURE_TEX_SIZE = 2048;
|
|
131283
|
+
function padWithDefault(arr, defaultValue2, padWidth) {
|
|
131284
|
+
const newArr = [...arr];
|
|
131285
|
+
for (let i2 = 0; i2 < padWidth; i2 += 1) {
|
|
131286
|
+
newArr.push(defaultValue2);
|
|
131287
|
+
}
|
|
131288
|
+
return newArr;
|
|
131289
|
+
}
|
|
131290
|
+
function getColor(arr) {
|
|
131291
|
+
return arr ? arr.map((v) => v / 255) : [0, 0, 0];
|
|
131292
|
+
}
|
|
131293
|
+
const defaultProps$1 = {
|
|
131294
|
+
channelStrokeWidths: { type: "array", value: null, compare: true },
|
|
131295
|
+
channelsFilled: { type: "array", value: null, compare: true },
|
|
131296
|
+
channelOpacities: { type: "array", value: null, compare: true },
|
|
131297
|
+
channelColors: { type: "array", value: null, compare: true },
|
|
131298
|
+
hoveredCell: { type: "number", value: null, compare: true },
|
|
131299
|
+
colormap: { type: "string", value: GLSL_COLORMAP_DEFAULT, compare: true },
|
|
131300
|
+
expressionData: { type: "object", value: null, compare: true },
|
|
131301
|
+
multiFeatureValues: { type: "array", value: null, compare: true },
|
|
131302
|
+
setColorValues: { type: "array", value: null, compare: true },
|
|
131303
|
+
channelFeatureValueColormaps: { type: "array", value: null, compare: true },
|
|
131304
|
+
channelFeatureValueColormapRanges: { type: "array", value: null, compare: true },
|
|
131305
|
+
channelIsStaticColorMode: { type: "array", value: null, compare: true },
|
|
131306
|
+
channelIsSetColorMode: { type: "array", value: null, compare: true }
|
|
131307
|
+
};
|
|
131308
|
+
class BitmaskLayer2 extends XRLayer {
|
|
131309
|
+
// eslint-disable-next-line class-methods-use-this
|
|
131310
|
+
getShaders() {
|
|
131311
|
+
const { colormap } = this.props;
|
|
131312
|
+
return {
|
|
131313
|
+
fs,
|
|
131314
|
+
vs,
|
|
131315
|
+
modules: [project32, picking],
|
|
131316
|
+
defines: {
|
|
131317
|
+
[COLORMAP_SHADER_PLACEHOLDER]: GLSL_COLORMAPS.includes(colormap) ? colormap : GLSL_COLORMAP_DEFAULT
|
|
131318
|
+
}
|
|
131319
|
+
};
|
|
131320
|
+
}
|
|
131321
|
+
/**
|
|
131322
|
+
* Override the parent loadChannelTextures to enable
|
|
131323
|
+
* up to eight channels (rather than six).
|
|
131324
|
+
* Reference: https://github.com/hms-dbmi/viv/blob/v0.13.3/packages/layers/src/xr-layer/xr-layer.js#L316
|
|
131325
|
+
*/
|
|
131326
|
+
loadChannelTextures(channelData) {
|
|
131327
|
+
const textures = {
|
|
131328
|
+
channel0: null,
|
|
131329
|
+
channel1: null,
|
|
131330
|
+
channel2: null,
|
|
131331
|
+
channel3: null,
|
|
131332
|
+
channel4: null,
|
|
131333
|
+
channel5: null,
|
|
131334
|
+
channel6: null
|
|
131335
|
+
};
|
|
131336
|
+
if (this.state.textures) {
|
|
131337
|
+
Object.values(this.state.textures).forEach((tex) => tex && tex.delete());
|
|
131338
|
+
}
|
|
131339
|
+
if (channelData && Object.keys(channelData).length > 0 && channelData.data) {
|
|
131340
|
+
channelData.data.forEach((d, i2) => {
|
|
131341
|
+
textures[`channel${i2}`] = this.dataToTexture(d, channelData.width, channelData.height);
|
|
131342
|
+
}, this);
|
|
131343
|
+
this.setState({ textures });
|
|
131344
|
+
}
|
|
131345
|
+
}
|
|
131346
|
+
updateState({ props: props2, oldProps, changeFlags }) {
|
|
131347
|
+
super.updateState({ props: props2, oldProps, changeFlags });
|
|
131348
|
+
if (props2.multiFeatureValues !== oldProps.multiFeatureValues || props2.setColorValues !== oldProps.setColorValues || props2.channelIsSetColorMode !== oldProps.channelIsSetColorMode) {
|
|
131349
|
+
const { multiFeatureValues, setColorValues, channelIsSetColorMode } = this.props;
|
|
131350
|
+
const [valueTex, colorTex, valueTexOffsets, colorTexOffsets, valueTexHeight, colorTexHeight] = this.multiSetsToTexture(multiFeatureValues, setColorValues, channelIsSetColorMode);
|
|
131351
|
+
this.setState({
|
|
131352
|
+
valueTex,
|
|
131353
|
+
colorTex,
|
|
131354
|
+
valueTexOffsets,
|
|
131355
|
+
colorTexOffsets,
|
|
131356
|
+
valueTexHeight,
|
|
131357
|
+
colorTexHeight
|
|
131358
|
+
});
|
|
131359
|
+
}
|
|
131360
|
+
if (props2.colormap !== oldProps.colormap) {
|
|
131361
|
+
const { gl } = this.context;
|
|
131362
|
+
if (this.state.model) {
|
|
131363
|
+
this.state.model.delete();
|
|
131364
|
+
}
|
|
131365
|
+
this.setState({ model: this._getModel(gl) });
|
|
131366
|
+
this.getAttributeManager().invalidateAll();
|
|
131367
|
+
}
|
|
131368
|
+
}
|
|
131369
|
+
draw(opts2) {
|
|
131370
|
+
const { uniforms } = opts2;
|
|
131371
|
+
const {
|
|
131372
|
+
channelStrokeWidths,
|
|
131373
|
+
channelsFilled,
|
|
131374
|
+
channelOpacities,
|
|
131375
|
+
channelColors,
|
|
131376
|
+
channelsVisible,
|
|
131377
|
+
// TODO: use `channelFeatureValueColormaps` in shader,
|
|
131378
|
+
// figure out how to call multiple GLSL colormap functions
|
|
131379
|
+
channelFeatureValueColormaps,
|
|
131380
|
+
channelFeatureValueColormapRanges,
|
|
131381
|
+
channelIsStaticColorMode,
|
|
131382
|
+
channelIsSetColorMode,
|
|
131383
|
+
hoveredCell,
|
|
131384
|
+
colorScaleLo,
|
|
131385
|
+
colorScaleHi,
|
|
131386
|
+
isExpressionMode,
|
|
131387
|
+
zoom,
|
|
131388
|
+
minZoom,
|
|
131389
|
+
maxZoom,
|
|
131390
|
+
zoomOffset
|
|
131391
|
+
// TODO: figure out if this needs to be used or not
|
|
131392
|
+
} = this.props;
|
|
131393
|
+
const {
|
|
131394
|
+
textures,
|
|
131395
|
+
model,
|
|
131396
|
+
// Expression and set index (and colors) textures with offsets
|
|
131397
|
+
valueTex,
|
|
131398
|
+
colorTex,
|
|
131399
|
+
valueTexOffsets,
|
|
131400
|
+
colorTexOffsets,
|
|
131401
|
+
valueTexHeight,
|
|
131402
|
+
colorTexHeight
|
|
131403
|
+
} = this.state;
|
|
131404
|
+
if (textures && model) {
|
|
131405
|
+
const scaleFactor = 1 / 2 ** (maxZoom - zoom);
|
|
131406
|
+
const colors = fromEntries(range$2(MAX_CHANNELS).map((i2) => [`color${i2}`, getColor(channelColors[i2])]));
|
|
131407
|
+
model.setUniforms(Object.assign({}, uniforms, {
|
|
131408
|
+
...colors,
|
|
131409
|
+
// Bitmask image channel data textures
|
|
131410
|
+
...textures,
|
|
131411
|
+
multiFeatureTexSize: MULTI_FEATURE_TEX_SIZE,
|
|
131412
|
+
// Expression textures with offsets
|
|
131413
|
+
valueTex,
|
|
131414
|
+
valueTexOffsets: padWithDefault(valueTexOffsets, 0, MAX_CHANNELS - valueTexOffsets.length),
|
|
131415
|
+
valueTexHeight,
|
|
131416
|
+
// Set indices and colors textures with offsets
|
|
131417
|
+
colorTex,
|
|
131418
|
+
colorTexOffsets: padWithDefault(colorTexOffsets, 0, MAX_CHANNELS - colorTexOffsets.length),
|
|
131419
|
+
colorTexHeight,
|
|
131420
|
+
// Visualization properties
|
|
131421
|
+
channelsFilled: padWithDefault(
|
|
131422
|
+
channelsFilled,
|
|
131423
|
+
true,
|
|
131424
|
+
// There are six texture entries on the shaders
|
|
131425
|
+
MAX_CHANNELS - channelsFilled.length
|
|
131426
|
+
),
|
|
131427
|
+
channelOpacities: padWithDefault(
|
|
131428
|
+
channelOpacities,
|
|
131429
|
+
0,
|
|
131430
|
+
// There are six texture entries on the shaders
|
|
131431
|
+
MAX_CHANNELS - channelOpacities.length
|
|
131432
|
+
),
|
|
131433
|
+
channelStrokeWidths: padWithDefault(
|
|
131434
|
+
channelStrokeWidths,
|
|
131435
|
+
1,
|
|
131436
|
+
// There are six texture entries on the shaders
|
|
131437
|
+
MAX_CHANNELS - channelStrokeWidths.length
|
|
131438
|
+
),
|
|
131439
|
+
channelColormapRangeStarts: padWithDefault(
|
|
131440
|
+
channelFeatureValueColormapRanges.map((r2) => (r2 == null ? void 0 : r2[0]) || 0),
|
|
131441
|
+
0,
|
|
131442
|
+
// There are six texture entries on the shaders
|
|
131443
|
+
MAX_CHANNELS - channelFeatureValueColormapRanges.length
|
|
131444
|
+
),
|
|
131445
|
+
channelColormapRangeEnds: padWithDefault(
|
|
131446
|
+
channelFeatureValueColormapRanges.map((r2) => (r2 == null ? void 0 : r2[1]) || 1),
|
|
131447
|
+
1,
|
|
131448
|
+
// There are six texture entries on the shaders
|
|
131449
|
+
MAX_CHANNELS - channelFeatureValueColormapRanges.length
|
|
131450
|
+
),
|
|
131451
|
+
channelIsStaticColorMode: padWithDefault(
|
|
131452
|
+
channelIsStaticColorMode,
|
|
131453
|
+
true,
|
|
131454
|
+
// There are six texture entries on the shaders
|
|
131455
|
+
MAX_CHANNELS - channelIsStaticColorMode.length
|
|
131456
|
+
),
|
|
131457
|
+
channelIsSetColorMode: padWithDefault(
|
|
131458
|
+
channelIsSetColorMode,
|
|
131459
|
+
false,
|
|
131460
|
+
// There are six texture entries on the shaders
|
|
131461
|
+
MAX_CHANNELS - channelIsSetColorMode.length
|
|
131462
|
+
),
|
|
131463
|
+
hovered: hoveredCell || 0,
|
|
131464
|
+
channelsVisible: padWithDefault(
|
|
131465
|
+
channelsVisible,
|
|
131466
|
+
false,
|
|
131467
|
+
// There are six texture entries on the shaders
|
|
131468
|
+
MAX_CHANNELS - channelsVisible.length
|
|
131469
|
+
),
|
|
131470
|
+
// uColorScaleRange: [colorScaleLo, colorScaleHi],
|
|
131471
|
+
// uIsExpressionMode: isExpressionMode,
|
|
131472
|
+
// uIsOutlined: false,
|
|
131473
|
+
scaleFactor
|
|
131474
|
+
})).draw();
|
|
131475
|
+
}
|
|
131476
|
+
}
|
|
131477
|
+
/**
|
|
131478
|
+
* This function creates textures from the data
|
|
131479
|
+
*/
|
|
131480
|
+
dataToTexture(data, width, height) {
|
|
131481
|
+
const isWebGL2On = isWebGL2$1(this.context.gl);
|
|
131482
|
+
return new Texture2D(this.context.gl, {
|
|
131483
|
+
width,
|
|
131484
|
+
height,
|
|
131485
|
+
// Only use Float32 so we don't have to write two shaders
|
|
131486
|
+
data: new Float32Array(data),
|
|
131487
|
+
// we don't want or need mimaps
|
|
131488
|
+
mipmaps: false,
|
|
131489
|
+
parameters: {
|
|
131490
|
+
// NEAREST for integer data
|
|
131491
|
+
[GL$1.TEXTURE_MIN_FILTER]: GL$1.NEAREST,
|
|
131492
|
+
[GL$1.TEXTURE_MAG_FILTER]: GL$1.NEAREST,
|
|
131493
|
+
// CLAMP_TO_EDGE to remove tile artifacts
|
|
131494
|
+
[GL$1.TEXTURE_WRAP_S]: GL$1.CLAMP_TO_EDGE,
|
|
131495
|
+
[GL$1.TEXTURE_WRAP_T]: GL$1.CLAMP_TO_EDGE
|
|
131496
|
+
},
|
|
131497
|
+
format: isWebGL2On ? GL$1.R32F : GL$1.LUMINANCE,
|
|
131498
|
+
dataFormat: isWebGL2On ? GL$1.RED : GL$1.LUMINANCE,
|
|
131499
|
+
type: GL$1.FLOAT
|
|
131500
|
+
});
|
|
131501
|
+
}
|
|
131502
|
+
multiSetsToTexture(multiFeatureValues, setColorValues, channelIsSetColorMode) {
|
|
131503
|
+
const isWebGL2On = isWebGL2$1(this.context.gl);
|
|
131504
|
+
const [totalData, valueTexHeight, indicesOffsets, totalColors, colorTexHeight, colorsOffsets] = multiSetsToTextureData(multiFeatureValues, setColorValues, channelIsSetColorMode, MULTI_FEATURE_TEX_SIZE);
|
|
131505
|
+
return [
|
|
131506
|
+
// Color indices texture
|
|
131507
|
+
new Texture2D(this.context.gl, {
|
|
131508
|
+
width: MULTI_FEATURE_TEX_SIZE,
|
|
131509
|
+
height: valueTexHeight,
|
|
131510
|
+
// Only use Float32 so we don't have to write two shaders
|
|
131511
|
+
data: new Float32Array(totalData),
|
|
131512
|
+
// we don't want or need mimaps
|
|
131513
|
+
mipmaps: false,
|
|
131514
|
+
parameters: {
|
|
131515
|
+
// NEAREST for integer data
|
|
131516
|
+
[GL$1.TEXTURE_MIN_FILTER]: GL$1.NEAREST,
|
|
131517
|
+
[GL$1.TEXTURE_MAG_FILTER]: GL$1.NEAREST,
|
|
131518
|
+
// CLAMP_TO_EDGE to remove tile artifacts
|
|
131519
|
+
[GL$1.TEXTURE_WRAP_S]: GL$1.CLAMP_TO_EDGE,
|
|
131520
|
+
[GL$1.TEXTURE_WRAP_T]: GL$1.CLAMP_TO_EDGE
|
|
131521
|
+
},
|
|
131522
|
+
format: isWebGL2On ? GL$1.R32F : GL$1.LUMINANCE,
|
|
131523
|
+
dataFormat: isWebGL2On ? GL$1.RED : GL$1.LUMINANCE,
|
|
131524
|
+
type: GL$1.FLOAT
|
|
131525
|
+
}),
|
|
131526
|
+
// Colors texture
|
|
131527
|
+
new Texture2D(this.context.gl, {
|
|
131528
|
+
width: MULTI_FEATURE_TEX_SIZE,
|
|
131529
|
+
height: colorTexHeight,
|
|
131530
|
+
// Only use Float32 so we don't have to write two shaders
|
|
131531
|
+
data: new Float32Array(totalColors),
|
|
131532
|
+
// we don't want or need mimaps
|
|
131533
|
+
mipmaps: false,
|
|
131534
|
+
parameters: {
|
|
131535
|
+
// NEAREST for integer data
|
|
131536
|
+
[GL$1.TEXTURE_MIN_FILTER]: GL$1.NEAREST,
|
|
131537
|
+
[GL$1.TEXTURE_MAG_FILTER]: GL$1.NEAREST,
|
|
131538
|
+
// CLAMP_TO_EDGE to remove tile artifacts
|
|
131539
|
+
[GL$1.TEXTURE_WRAP_S]: GL$1.CLAMP_TO_EDGE,
|
|
131540
|
+
[GL$1.TEXTURE_WRAP_T]: GL$1.CLAMP_TO_EDGE
|
|
131541
|
+
},
|
|
131542
|
+
format: isWebGL2On ? GL$1.R32F : GL$1.LUMINANCE,
|
|
131543
|
+
dataFormat: isWebGL2On ? GL$1.RED : GL$1.LUMINANCE,
|
|
131544
|
+
type: GL$1.FLOAT
|
|
131545
|
+
}),
|
|
131546
|
+
// Offsets
|
|
131547
|
+
indicesOffsets,
|
|
131548
|
+
colorsOffsets,
|
|
131549
|
+
// Texture heights
|
|
131550
|
+
valueTexHeight,
|
|
131551
|
+
colorTexHeight
|
|
131552
|
+
];
|
|
131553
|
+
}
|
|
131554
|
+
}
|
|
131555
|
+
BitmaskLayer2.layerName = "BitmaskLayer";
|
|
131556
|
+
BitmaskLayer2.defaultProps = defaultProps$1;
|
|
130896
131557
|
function r(e2) {
|
|
130897
131558
|
var t2, f2, n2 = "";
|
|
130898
131559
|
if ("string" == typeof e2 || "number" == typeof e2)
|
|
@@ -141039,10 +141700,9 @@ class AbstractSpatialOrScatterplot extends PureComponent {
|
|
|
141039
141700
|
const {
|
|
141040
141701
|
setViewState,
|
|
141041
141702
|
viewState,
|
|
141042
|
-
layers,
|
|
141043
141703
|
spatialAxisFixed
|
|
141044
141704
|
} = this.props;
|
|
141045
|
-
const use3d =
|
|
141705
|
+
const use3d = this.use3d();
|
|
141046
141706
|
setViewState({
|
|
141047
141707
|
...nextViewState,
|
|
141048
141708
|
// If the axis is fixed, just use the current target in state i.e don't change target.
|
|
@@ -141090,6 +141750,8 @@ class AbstractSpatialOrScatterplot extends PureComponent {
|
|
|
141090
141750
|
getLayers() {
|
|
141091
141751
|
return [];
|
|
141092
141752
|
}
|
|
141753
|
+
// TODO: remove this method and use the layer-level onHover instead.
|
|
141754
|
+
// (e.g., see delegateHover in spatial-beta/SpatialSubscriber.js).
|
|
141093
141755
|
// eslint-disable-next-line consistent-return
|
|
141094
141756
|
onHover(info) {
|
|
141095
141757
|
const {
|
|
@@ -141236,7 +141898,8 @@ class AbstractSpatialOrScatterplot extends PureComponent {
|
|
|
141236
141898
|
deckRef,
|
|
141237
141899
|
viewState,
|
|
141238
141900
|
uuid,
|
|
141239
|
-
hideTools
|
|
141901
|
+
hideTools,
|
|
141902
|
+
orbitAxis
|
|
141240
141903
|
} = this.props;
|
|
141241
141904
|
const { gl, tool } = this.state;
|
|
141242
141905
|
const layers = this.getLayers();
|
|
@@ -141263,7 +141926,7 @@ class AbstractSpatialOrScatterplot extends PureComponent {
|
|
|
141263
141926
|
id: `deckgl-overlay-${uuid}`,
|
|
141264
141927
|
ref: deckRef,
|
|
141265
141928
|
views: [
|
|
141266
|
-
use3d ? new OrbitView({ id: "orbit", controller: true, orbitAxis
|
|
141929
|
+
use3d ? new OrbitView({ id: "orbit", controller: true, orbitAxis }) : new OrthographicView({
|
|
141267
141930
|
id: "ortho"
|
|
141268
141931
|
})
|
|
141269
141932
|
],
|
|
@@ -141589,7 +142252,7 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
141589
142252
|
}
|
|
141590
142253
|
return result;
|
|
141591
142254
|
}
|
|
141592
|
-
|
|
142255
|
+
createSelectionLayer() {
|
|
141593
142256
|
const {
|
|
141594
142257
|
obsEmbeddingIndex: obsIndex,
|
|
141595
142258
|
obsEmbedding,
|
|
@@ -141600,14 +142263,20 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
141600
142263
|
const { cellsQuadTree } = this;
|
|
141601
142264
|
const flipYTooltip = true;
|
|
141602
142265
|
const getCellCoords = makeDefaultGetObsCoords(obsEmbedding);
|
|
141603
|
-
return
|
|
142266
|
+
return getSelectionLayer(
|
|
141604
142267
|
tool,
|
|
141605
142268
|
viewState.zoom,
|
|
141606
142269
|
CELLS_LAYER_ID,
|
|
141607
|
-
|
|
141608
|
-
|
|
141609
|
-
|
|
141610
|
-
|
|
142270
|
+
[
|
|
142271
|
+
{
|
|
142272
|
+
getObsCoords: getCellCoords,
|
|
142273
|
+
obsIndex,
|
|
142274
|
+
obsQuadTree: cellsQuadTree,
|
|
142275
|
+
onSelect: (obsIds) => {
|
|
142276
|
+
setCellSelection(obsIds);
|
|
142277
|
+
}
|
|
142278
|
+
}
|
|
142279
|
+
],
|
|
141611
142280
|
flipYTooltip
|
|
141612
142281
|
);
|
|
141613
142282
|
}
|
|
@@ -141619,7 +142288,7 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
|
|
|
141619
142288
|
return [
|
|
141620
142289
|
cellsLayer,
|
|
141621
142290
|
...cellSetsLayers,
|
|
141622
|
-
|
|
142291
|
+
this.createSelectionLayer()
|
|
141623
142292
|
];
|
|
141624
142293
|
}
|
|
141625
142294
|
onUpdateCellsData() {
|