@vitessce/scatterplot-embedding 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.
@@ -11039,8 +11039,10 @@ const ViewType$1 = {
11039
11039
  STATUS: "status",
11040
11040
  SCATTERPLOT: "scatterplot",
11041
11041
  SPATIAL: "spatial",
11042
+ SPATIAL_BETA: "spatialBeta",
11042
11043
  HEATMAP: "heatmap",
11043
11044
  LAYER_CONTROLLER: "layerController",
11045
+ LAYER_CONTROLLER_BETA: "layerControllerBeta",
11044
11046
  GENOMIC_PROFILES: "genomicProfiles",
11045
11047
  GATING: "gating",
11046
11048
  FEATURE_LIST: "featureList",
@@ -11052,20 +11054,24 @@ const ViewType$1 = {
11052
11054
  const DataType$2 = {
11053
11055
  OBS_LABELS: "obsLabels",
11054
11056
  OBS_EMBEDDING: "obsEmbedding",
11055
- OBS_LOCATIONS: "obsLocations",
11056
11057
  OBS_FEATURE_MATRIX: "obsFeatureMatrix",
11057
11058
  OBS_SETS: "obsSets",
11058
11059
  FEATURE_LABELS: "featureLabels",
11059
11060
  IMAGE: "image",
11060
11061
  OBS_SEGMENTATIONS: "obsSegmentations",
11061
11062
  NEIGHBORHOODS: "neighborhoods",
11062
- GENOMIC_PROFILES: "genomic-profiles"
11063
+ GENOMIC_PROFILES: "genomic-profiles",
11064
+ OBS_SPOTS: "obsSpots",
11065
+ OBS_POINTS: "obsPoints",
11066
+ OBS_LOCATIONS: "obsLocations"
11063
11067
  };
11064
11068
  const FileType$1 = {
11065
11069
  // Joint file types
11066
11070
  ANNDATA_ZARR: "anndata.zarr",
11067
11071
  // Atomic file types
11068
11072
  OBS_EMBEDDING_CSV: "obsEmbedding.csv",
11073
+ OBS_SPOTS_CSV: "obsSpots.csv",
11074
+ OBS_POINTS_CSV: "obsPoints.csv",
11069
11075
  OBS_LOCATIONS_CSV: "obsLocations.csv",
11070
11076
  OBS_LABELS_CSV: "obsLabels.csv",
11071
11077
  FEATURE_LABELS_CSV: "featureLabels.csv",
@@ -11078,6 +11084,8 @@ const FileType$1 = {
11078
11084
  OBS_FEATURE_MATRIX_ANNDATA_ZARR: "obsFeatureMatrix.anndata.zarr",
11079
11085
  OBS_SETS_ANNDATA_ZARR: "obsSets.anndata.zarr",
11080
11086
  OBS_EMBEDDING_ANNDATA_ZARR: "obsEmbedding.anndata.zarr",
11087
+ OBS_SPOTS_ANNDATA_ZARR: "obsSpots.anndata.zarr",
11088
+ OBS_POINTS_ANNDATA_ZARR: "obsPoints.anndata.zarr",
11081
11089
  OBS_LOCATIONS_ANNDATA_ZARR: "obsLocations.anndata.zarr",
11082
11090
  OBS_SEGMENTATIONS_ANNDATA_ZARR: "obsSegmentations.anndata.zarr",
11083
11091
  OBS_LABELS_ANNDATA_ZARR: "obsLabels.anndata.zarr",
@@ -11086,6 +11094,8 @@ const FileType$1 = {
11086
11094
  OBS_FEATURE_MATRIX_MUDATA_ZARR: "obsFeatureMatrix.mudata.zarr",
11087
11095
  OBS_SETS_MUDATA_ZARR: "obsSets.mudata.zarr",
11088
11096
  OBS_EMBEDDING_MUDATA_ZARR: "obsEmbedding.mudata.zarr",
11097
+ OBS_SPOTS_MUDATA_ZARR: "obsSpots.mudata.zarr",
11098
+ OBS_POINTS_MUDATA_ZARR: "obsPoints.mudata.zarr",
11089
11099
  OBS_LOCATIONS_MUDATA_ZARR: "obsLocations.mudata.zarr",
11090
11100
  OBS_SEGMENTATIONS_MUDATA_ZARR: "obsSegmentations.mudata.zarr",
11091
11101
  OBS_LABELS_MUDATA_ZARR: "obsLabels.mudata.zarr",
@@ -11129,10 +11139,8 @@ const FileType$1 = {
11129
11139
  ANNDATA_EXPRESSION_MATRIX_ZARR: "anndata-expression-matrix.zarr"
11130
11140
  };
11131
11141
  const CoordinationType$1 = {
11132
- // Meta coordination scopes
11133
11142
  META_COORDINATION_SCOPES: "metaCoordinationScopes",
11134
11143
  META_COORDINATION_SCOPES_BY: "metaCoordinationScopesBy",
11135
- // Other coordination scopes
11136
11144
  DATASET: "dataset",
11137
11145
  // Entity types
11138
11146
  OBS_TYPE: "obsType",
@@ -11158,6 +11166,7 @@ const CoordinationType$1 = {
11158
11166
  SPATIAL_TARGET_X: "spatialTargetX",
11159
11167
  SPATIAL_TARGET_Y: "spatialTargetY",
11160
11168
  SPATIAL_TARGET_Z: "spatialTargetZ",
11169
+ SPATIAL_TARGET_T: "spatialTargetT",
11161
11170
  SPATIAL_ROTATION_X: "spatialRotationX",
11162
11171
  SPATIAL_ROTATION_Y: "spatialRotationY",
11163
11172
  SPATIAL_ROTATION_Z: "spatialRotationZ",
@@ -11195,7 +11204,46 @@ const CoordinationType$1 = {
11195
11204
  GATING_FEATURE_SELECTION_X: "gatingFeatureSelectionX",
11196
11205
  GATING_FEATURE_SELECTION_Y: "gatingFeatureSelectionY",
11197
11206
  FEATURE_VALUE_TRANSFORM_COEFFICIENT: "featureValueTransformCoefficient",
11198
- TOOLTIPS_VISIBLE: "tooltipsVisible"
11207
+ TOOLTIPS_VISIBLE: "tooltipsVisible",
11208
+ FILE_UID: "fileUid",
11209
+ IMAGE_LAYER: "imageLayer",
11210
+ IMAGE_CHANNEL: "imageChannel",
11211
+ SEGMENTATION_LAYER: "segmentationLayer",
11212
+ SEGMENTATION_CHANNEL: "segmentationChannel",
11213
+ SPATIAL_TARGET_C: "spatialTargetC",
11214
+ SPATIAL_LAYER_VISIBLE: "spatialLayerVisible",
11215
+ SPATIAL_LAYER_OPACITY: "spatialLayerOpacity",
11216
+ SPATIAL_LAYER_COLORMAP: "spatialLayerColormap",
11217
+ SPATIAL_LAYER_TRANSPARENT_COLOR: "spatialLayerTransparentColor",
11218
+ SPATIAL_LAYER_MODEL_MATRIX: "spatialLayerModelMatrix",
11219
+ SPATIAL_SEGMENTATION_FILLED: "spatialSegmentationFilled",
11220
+ SPATIAL_SEGMENTATION_STROKE_WIDTH: "spatialSegmentationStrokeWidth",
11221
+ SPATIAL_CHANNEL_COLOR: "spatialChannelColor",
11222
+ SPATIAL_CHANNEL_VISIBLE: "spatialChannelVisible",
11223
+ SPATIAL_CHANNEL_OPACITY: "spatialChannelOpacity",
11224
+ SPATIAL_CHANNEL_WINDOW: "spatialChannelWindow",
11225
+ PHOTOMETRIC_INTERPRETATION: "photometricInterpretation",
11226
+ // For 3D volume rendering
11227
+ SPATIAL_RENDERING_MODE: "spatialRenderingMode",
11228
+ VOLUMETRIC_RENDERING_ALGORITHM: "volumetricRenderingAlgorithm",
11229
+ SPATIAL_TARGET_RESOLUTION: "spatialTargetResolution",
11230
+ // For clipping plane sliders
11231
+ SPATIAL_SLICE_X: "spatialSliceX",
11232
+ SPATIAL_SLICE_Y: "spatialSliceY",
11233
+ SPATIAL_SLICE_Z: "spatialSliceZ",
11234
+ // For spatial spot and point layers
11235
+ SPOT_LAYER: "spotLayer",
11236
+ POINT_LAYER: "pointLayer",
11237
+ SPATIAL_SPOT_RADIUS: "spatialSpotRadius",
11238
+ SPATIAL_SPOT_FILLED: "spatialSpotFilled",
11239
+ SPATIAL_SPOT_STROKE_WIDTH: "spatialSpotStrokeWidth",
11240
+ SPATIAL_LAYER_COLOR: "spatialLayerColor",
11241
+ PIXEL_HIGHLIGHT: "pixelHighlight",
11242
+ TOOLTIP_CROSSHAIRS_VISIBLE: "tooltipCrosshairsVisible",
11243
+ LEGEND_VISIBLE: "legendVisible",
11244
+ SPATIAL_CHANNEL_LABELS_VISIBLE: "spatialChannelLabelsVisible",
11245
+ SPATIAL_CHANNEL_LABELS_ORIENTATION: "spatialChannelLabelsOrientation",
11246
+ SPATIAL_CHANNEL_LABEL_SIZE: "spatialChannelLabelSize"
11199
11247
  };
11200
11248
  const COMPONENT_COORDINATION_TYPES = {
11201
11249
  [ViewType$1.SCATTERPLOT]: [
@@ -11299,6 +11347,77 @@ const COMPONENT_COORDINATION_TYPES = {
11299
11347
  CoordinationType$1.MOLECULE_HIGHLIGHT,
11300
11348
  CoordinationType$1.TOOLTIPS_VISIBLE
11301
11349
  ],
11350
+ [ViewType$1.SPATIAL_BETA]: [
11351
+ CoordinationType$1.META_COORDINATION_SCOPES,
11352
+ CoordinationType$1.META_COORDINATION_SCOPES_BY,
11353
+ CoordinationType$1.DATASET,
11354
+ CoordinationType$1.OBS_TYPE,
11355
+ CoordinationType$1.OBS_LABELS_TYPE,
11356
+ CoordinationType$1.FEATURE_TYPE,
11357
+ CoordinationType$1.FEATURE_VALUE_TYPE,
11358
+ CoordinationType$1.SPATIAL_ZOOM,
11359
+ CoordinationType$1.SPATIAL_ROTATION,
11360
+ CoordinationType$1.SPATIAL_POINT_LAYER,
11361
+ CoordinationType$1.SPATIAL_NEIGHBORHOOD_LAYER,
11362
+ CoordinationType$1.SPATIAL_TARGET_X,
11363
+ CoordinationType$1.SPATIAL_TARGET_Y,
11364
+ CoordinationType$1.SPATIAL_TARGET_Z,
11365
+ CoordinationType$1.SPATIAL_TARGET_T,
11366
+ CoordinationType$1.SPATIAL_ROTATION_X,
11367
+ CoordinationType$1.SPATIAL_ROTATION_Y,
11368
+ CoordinationType$1.SPATIAL_ROTATION_Z,
11369
+ CoordinationType$1.SPATIAL_ROTATION_ORBIT,
11370
+ CoordinationType$1.SPATIAL_ORBIT_AXIS,
11371
+ CoordinationType$1.SPATIAL_AXIS_FIXED,
11372
+ CoordinationType$1.OBS_FILTER,
11373
+ CoordinationType$1.OBS_HIGHLIGHT,
11374
+ CoordinationType$1.OBS_SET_SELECTION,
11375
+ CoordinationType$1.OBS_SET_HIGHLIGHT,
11376
+ CoordinationType$1.OBS_SET_COLOR,
11377
+ CoordinationType$1.FEATURE_HIGHLIGHT,
11378
+ CoordinationType$1.FEATURE_SELECTION,
11379
+ CoordinationType$1.FEATURE_VALUE_COLORMAP,
11380
+ CoordinationType$1.FEATURE_VALUE_COLORMAP_RANGE,
11381
+ CoordinationType$1.OBS_COLOR_ENCODING,
11382
+ CoordinationType$1.ADDITIONAL_OBS_SETS,
11383
+ CoordinationType$1.MOLECULE_HIGHLIGHT,
11384
+ CoordinationType$1.TOOLTIPS_VISIBLE,
11385
+ CoordinationType$1.FILE_UID,
11386
+ CoordinationType$1.SPATIAL_TARGET_C,
11387
+ CoordinationType$1.SPATIAL_LAYER_VISIBLE,
11388
+ CoordinationType$1.SPATIAL_LAYER_OPACITY,
11389
+ CoordinationType$1.SPATIAL_LAYER_COLORMAP,
11390
+ CoordinationType$1.SPATIAL_LAYER_TRANSPARENT_COLOR,
11391
+ CoordinationType$1.SPATIAL_LAYER_MODEL_MATRIX,
11392
+ CoordinationType$1.SPATIAL_CHANNEL_COLOR,
11393
+ CoordinationType$1.SPATIAL_SEGMENTATION_FILLED,
11394
+ CoordinationType$1.SPATIAL_SEGMENTATION_STROKE_WIDTH,
11395
+ CoordinationType$1.IMAGE_LAYER,
11396
+ CoordinationType$1.SEGMENTATION_LAYER,
11397
+ CoordinationType$1.IMAGE_CHANNEL,
11398
+ CoordinationType$1.SEGMENTATION_CHANNEL,
11399
+ CoordinationType$1.SPATIAL_CHANNEL_VISIBLE,
11400
+ CoordinationType$1.SPATIAL_CHANNEL_OPACITY,
11401
+ CoordinationType$1.SPATIAL_CHANNEL_WINDOW,
11402
+ CoordinationType$1.SPATIAL_RENDERING_MODE,
11403
+ CoordinationType$1.VOLUMETRIC_RENDERING_ALGORITHM,
11404
+ CoordinationType$1.SPATIAL_TARGET_RESOLUTION,
11405
+ CoordinationType$1.SPATIAL_SLICE_X,
11406
+ CoordinationType$1.SPATIAL_SLICE_Y,
11407
+ CoordinationType$1.SPATIAL_SLICE_Z,
11408
+ CoordinationType$1.SPOT_LAYER,
11409
+ CoordinationType$1.POINT_LAYER,
11410
+ CoordinationType$1.SPATIAL_SPOT_RADIUS,
11411
+ CoordinationType$1.SPATIAL_SPOT_FILLED,
11412
+ CoordinationType$1.SPATIAL_SPOT_STROKE_WIDTH,
11413
+ CoordinationType$1.SPATIAL_LAYER_COLOR,
11414
+ CoordinationType$1.PIXEL_HIGHLIGHT,
11415
+ CoordinationType$1.TOOLTIP_CROSSHAIRS_VISIBLE,
11416
+ CoordinationType$1.LEGEND_VISIBLE,
11417
+ CoordinationType$1.SPATIAL_CHANNEL_LABELS_VISIBLE,
11418
+ CoordinationType$1.SPATIAL_CHANNEL_LABELS_ORIENTATION,
11419
+ CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE
11420
+ ],
11302
11421
  [ViewType$1.HEATMAP]: [
11303
11422
  CoordinationType$1.DATASET,
11304
11423
  CoordinationType$1.OBS_TYPE,
@@ -11404,6 +11523,61 @@ const COMPONENT_COORDINATION_TYPES = {
11404
11523
  CoordinationType$1.SPATIAL_ROTATION_ORBIT,
11405
11524
  CoordinationType$1.SPATIAL_ORBIT_AXIS
11406
11525
  ],
11526
+ [ViewType$1.LAYER_CONTROLLER_BETA]: [
11527
+ CoordinationType$1.META_COORDINATION_SCOPES,
11528
+ CoordinationType$1.META_COORDINATION_SCOPES_BY,
11529
+ CoordinationType$1.DATASET,
11530
+ CoordinationType$1.OBS_TYPE,
11531
+ CoordinationType$1.FEATURE_TYPE,
11532
+ CoordinationType$1.FEATURE_VALUE_TYPE,
11533
+ CoordinationType$1.SPATIAL_POINT_LAYER,
11534
+ CoordinationType$1.SPATIAL_NEIGHBORHOOD_LAYER,
11535
+ CoordinationType$1.SPATIAL_ZOOM,
11536
+ CoordinationType$1.SPATIAL_TARGET_X,
11537
+ CoordinationType$1.SPATIAL_TARGET_Y,
11538
+ CoordinationType$1.SPATIAL_TARGET_Z,
11539
+ CoordinationType$1.SPATIAL_TARGET_T,
11540
+ CoordinationType$1.SPATIAL_ROTATION_X,
11541
+ CoordinationType$1.SPATIAL_ROTATION_Y,
11542
+ CoordinationType$1.SPATIAL_ROTATION_Z,
11543
+ CoordinationType$1.SPATIAL_ROTATION_ORBIT,
11544
+ CoordinationType$1.SPATIAL_ORBIT_AXIS,
11545
+ CoordinationType$1.FILE_UID,
11546
+ CoordinationType$1.SPATIAL_TARGET_C,
11547
+ CoordinationType$1.SPATIAL_LAYER_VISIBLE,
11548
+ CoordinationType$1.SPATIAL_LAYER_OPACITY,
11549
+ CoordinationType$1.SPATIAL_LAYER_COLORMAP,
11550
+ CoordinationType$1.SPATIAL_LAYER_TRANSPARENT_COLOR,
11551
+ CoordinationType$1.SPATIAL_LAYER_MODEL_MATRIX,
11552
+ CoordinationType$1.SPATIAL_CHANNEL_COLOR,
11553
+ CoordinationType$1.SPATIAL_SEGMENTATION_FILLED,
11554
+ CoordinationType$1.SPATIAL_SEGMENTATION_STROKE_WIDTH,
11555
+ CoordinationType$1.IMAGE_CHANNEL,
11556
+ CoordinationType$1.SEGMENTATION_CHANNEL,
11557
+ CoordinationType$1.SPATIAL_CHANNEL_VISIBLE,
11558
+ CoordinationType$1.SPATIAL_CHANNEL_OPACITY,
11559
+ CoordinationType$1.SPATIAL_CHANNEL_WINDOW,
11560
+ CoordinationType$1.PHOTOMETRIC_INTERPRETATION,
11561
+ CoordinationType$1.SPATIAL_RENDERING_MODE,
11562
+ CoordinationType$1.VOLUMETRIC_RENDERING_ALGORITHM,
11563
+ CoordinationType$1.SPATIAL_TARGET_RESOLUTION,
11564
+ CoordinationType$1.SPATIAL_SLICE_X,
11565
+ CoordinationType$1.SPATIAL_SLICE_Y,
11566
+ CoordinationType$1.SPATIAL_SLICE_Z,
11567
+ CoordinationType$1.SPOT_LAYER,
11568
+ CoordinationType$1.POINT_LAYER,
11569
+ CoordinationType$1.SPATIAL_SPOT_RADIUS,
11570
+ CoordinationType$1.SPATIAL_SPOT_FILLED,
11571
+ CoordinationType$1.SPATIAL_SPOT_STROKE_WIDTH,
11572
+ CoordinationType$1.SPATIAL_LAYER_COLOR,
11573
+ CoordinationType$1.OBS_COLOR_ENCODING,
11574
+ CoordinationType$1.TOOLTIPS_VISIBLE,
11575
+ CoordinationType$1.TOOLTIP_CROSSHAIRS_VISIBLE,
11576
+ CoordinationType$1.LEGEND_VISIBLE,
11577
+ CoordinationType$1.SPATIAL_CHANNEL_LABELS_VISIBLE,
11578
+ CoordinationType$1.SPATIAL_CHANNEL_LABELS_ORIENTATION,
11579
+ CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE
11580
+ ],
11407
11581
  [ViewType$1.GENOMIC_PROFILES]: [
11408
11582
  CoordinationType$1.DATASET,
11409
11583
  CoordinationType$1.OBS_TYPE,
@@ -11695,6 +11869,8 @@ const annDataObsSets = z.array(z.object({
11695
11869
  ]),
11696
11870
  scorePath: z.string().optional().describe("The location in the AnnData store for the set confidence scores, like 'obs/celltype_prediction_score.'")
11697
11871
  }));
11872
+ const annDataObsSpots = annDataObsm;
11873
+ const annDataObsPoints = annDataObsm;
11698
11874
  const annDataObsLocations = annDataObsm;
11699
11875
  const annDataObsEmbedding = annDataObsm;
11700
11876
  const annDataObsSegmentations = annDataObs;
@@ -11721,10 +11897,21 @@ z.object({
11721
11897
  z.object({
11722
11898
  obsIndex: z.string(),
11723
11899
  obsEmbedding: z.array(z.string()).length(2)
11900
+ // TODO: support 3D?
11901
+ });
11902
+ z.object({
11903
+ obsIndex: z.string(),
11904
+ obsSpots: z.array(z.string()).length(2)
11905
+ // TODO: support 3D?
11906
+ });
11907
+ z.object({
11908
+ obsIndex: z.string(),
11909
+ obsPoints: z.array(z.string()).length(3)
11724
11910
  });
11725
11911
  z.object({
11726
11912
  obsIndex: z.string(),
11727
11913
  obsLocations: z.array(z.string()).length(2)
11914
+ // TODO: support 3D?
11728
11915
  });
11729
11916
  z.object({
11730
11917
  obsIndex: z.string(),
@@ -11756,6 +11943,8 @@ z.object({
11756
11943
  ]),
11757
11944
  obsFeatureMatrix: annDataObsFeatureMatrix,
11758
11945
  obsSets: annDataObsSets,
11946
+ obsSpots: annDataObsSpots,
11947
+ obsPoints: annDataObsPoints,
11759
11948
  obsLocations: annDataObsLocations,
11760
11949
  obsSegmentations: annDataObsSegmentations,
11761
11950
  obsEmbedding: z.union([
@@ -20456,17 +20645,17 @@ let COLOR;
20456
20645
  COLOR2[COLOR2["BRIGHT_CYAN"] = 96] = "BRIGHT_CYAN";
20457
20646
  COLOR2[COLOR2["BRIGHT_WHITE"] = 97] = "BRIGHT_WHITE";
20458
20647
  })(COLOR || (COLOR = {}));
20459
- function getColor(color2) {
20648
+ function getColor$1(color2) {
20460
20649
  return typeof color2 === "string" ? COLOR[color2.toUpperCase()] || COLOR.WHITE : color2;
20461
20650
  }
20462
20651
  function addColor(string2, color2, background) {
20463
20652
  if (!isBrowser$3 && typeof string2 === "string") {
20464
20653
  if (color2) {
20465
- color2 = getColor(color2);
20654
+ color2 = getColor$1(color2);
20466
20655
  string2 = "\x1B[".concat(color2, "m").concat(string2, "\x1B[39m");
20467
20656
  }
20468
20657
  if (background) {
20469
- color2 = getColor(background);
20658
+ color2 = getColor$1(background);
20470
20659
  string2 = "\x1B[".concat(background + 10, "m").concat(string2, "\x1B[49m");
20471
20660
  }
20472
20661
  }
@@ -30490,7 +30679,7 @@ function negate(out, a2) {
30490
30679
  out[2] = -a2[2];
30491
30680
  return out;
30492
30681
  }
30493
- function normalize$4(out, a2) {
30682
+ function normalize$5(out, a2) {
30494
30683
  var x2 = a2[0];
30495
30684
  var y2 = a2[1];
30496
30685
  var z2 = a2[2];
@@ -31799,7 +31988,7 @@ function squaredLength$1(a2) {
31799
31988
  var w2 = a2[3];
31800
31989
  return x2 * x2 + y2 * y2 + z2 * z2 + w2 * w2;
31801
31990
  }
31802
- function normalize$3(out, a2) {
31991
+ function normalize$4(out, a2) {
31803
31992
  var x2 = a2[0];
31804
31993
  var y2 = a2[1];
31805
31994
  var z2 = a2[2];
@@ -32436,7 +32625,7 @@ var dot$1 = dot$2;
32436
32625
  var lerp$1 = lerp$2;
32437
32626
  var length$2 = length$3;
32438
32627
  var squaredLength = squaredLength$1;
32439
- var normalize$2 = normalize$3;
32628
+ var normalize$3 = normalize$4;
32440
32629
  var rotationTo = function() {
32441
32630
  var tmpvec3 = create$3();
32442
32631
  var xUnitVec3 = fromValues(1, 0, 0);
@@ -32447,7 +32636,7 @@ var rotationTo = function() {
32447
32636
  cross(tmpvec3, xUnitVec3, a2);
32448
32637
  if (len(tmpvec3) < 1e-6)
32449
32638
  cross(tmpvec3, yUnitVec3, a2);
32450
- normalize$4(tmpvec3, tmpvec3);
32639
+ normalize$5(tmpvec3, tmpvec3);
32451
32640
  setAxisAngle(out, tmpvec3, Math.PI);
32452
32641
  return out;
32453
32642
  } else if (dot2 > 0.999999) {
@@ -32462,7 +32651,7 @@ var rotationTo = function() {
32462
32651
  out[1] = tmpvec3[1];
32463
32652
  out[2] = tmpvec3[2];
32464
32653
  out[3] = 1 + dot2;
32465
- return normalize$2(out, out);
32654
+ return normalize$3(out, out);
32466
32655
  }
32467
32656
  };
32468
32657
  }();
@@ -32488,7 +32677,7 @@ var rotationTo = function() {
32488
32677
  matr[2] = -view[0];
32489
32678
  matr[5] = -view[1];
32490
32679
  matr[8] = -view[2];
32491
- return normalize$2(out, fromMat3(out, matr));
32680
+ return normalize$3(out, fromMat3(out, matr));
32492
32681
  };
32493
32682
  })();
32494
32683
  const IDENTITY_QUATERNION = [0, 0, 0, 1];
@@ -54177,7 +54366,7 @@ function copyFlatRing(target, targetStartIndex, positions, size, srcStartIndex =
54177
54366
  modifyPolygonWindingDirection(target, windingDirection, windingOptions);
54178
54367
  return targetIndex;
54179
54368
  }
54180
- function normalize$1(polygon2, positionSize) {
54369
+ function normalize$2(polygon2, positionSize) {
54181
54370
  validate(polygon2);
54182
54371
  const positions = [];
54183
54372
  const holeIndices = [];
@@ -54283,7 +54472,7 @@ class PolygonTesselator extends Tesselator {
54283
54472
  }
54284
54473
  normalizeGeometry(polygon2) {
54285
54474
  if (this.normalize) {
54286
- const normalizedPolygon = normalize$1(polygon2, this.positionSize);
54475
+ const normalizedPolygon = normalize$2(polygon2, this.positionSize);
54287
54476
  if (this.opts.resolution) {
54288
54477
  return cutPolygonByGrid(getPositions(normalizedPolygon), getHoleIndices(normalizedPolygon), {
54289
54478
  size: this.positionSize,
@@ -54905,7 +55094,7 @@ class PolygonLayer extends CompositeLayer {
54905
55094
  objectInfo.index++;
54906
55095
  let polygon2 = getPolygon(object2, objectInfo);
54907
55096
  if (_normalize) {
54908
- polygon2 = normalize$1(polygon2, positionSize);
55097
+ polygon2 = normalize$2(polygon2, positionSize);
54909
55098
  }
54910
55099
  const {
54911
55100
  holeIndices
@@ -119764,28 +119953,38 @@ const PASS_THROUGH_PROPS = [
119764
119953
  ];
119765
119954
  class SelectionLayer extends CompositeLayer {
119766
119955
  _selectPolygonObjects(coordinates2) {
119767
- const { onSelect, getCellCoords, cellsQuadTree, flipY } = this.props;
119956
+ const { flipY, obsLayers } = this.props;
119768
119957
  const flippedCoordinates = flipY ? coordinates2.map((poly) => poly.map((p) => [p[0], -p[1]])) : coordinates2;
119769
119958
  const selectedPolygon = polygon(flippedCoordinates);
119770
- const pickingInfos = [];
119771
- cellsQuadTree.visit((node, x02, y02, x12, y12) => {
119772
- const nodePoints = [[[x02, y02], [x12, y02], [x12, y12], [x02, y12], [x02, y02]]];
119773
- const nodePolygon = polygon(nodePoints);
119774
- const nodePolygonContainsSelectedPolygon = booleanContains(nodePolygon, selectedPolygon);
119775
- const nodePolygonWithinSelectedPolygon = booleanWithin(nodePolygon, selectedPolygon);
119776
- const nodePolygonOverlapsSelectedPolgyon = booleanOverlap(nodePolygon, selectedPolygon);
119777
- if (!nodePolygonContainsSelectedPolygon && !nodePolygonWithinSelectedPolygon && !nodePolygonOverlapsSelectedPolgyon) {
119778
- return true;
119779
- }
119780
- if (node.data && booleanPointInPolygon$1(point([].slice.call(getCellCoords(node.data))), selectedPolygon)) {
119781
- pickingInfos.push(node.data);
119782
- }
119783
- return false;
119959
+ obsLayers.forEach((obsLayer) => {
119960
+ const { getObsCoords, obsQuadTree, obsIndex, onSelect: layerOnSelect } = obsLayer;
119961
+ const pickingInfos = [];
119962
+ obsQuadTree == null ? void 0 : obsQuadTree.visit((node, x02, y02, x12, y12) => {
119963
+ const nodePoints = [[[x02, y02], [x12, y02], [x12, y12], [x02, y12], [x02, y02]]];
119964
+ const nodePolygon = polygon(nodePoints);
119965
+ const nodePolygonContainsSelectedPolygon = booleanContains(nodePolygon, selectedPolygon);
119966
+ const nodePolygonWithinSelectedPolygon = booleanWithin(nodePolygon, selectedPolygon);
119967
+ const nodePolygonOverlapsSelectedPolgyon = booleanOverlap(nodePolygon, selectedPolygon);
119968
+ if (!nodePolygonContainsSelectedPolygon && !nodePolygonWithinSelectedPolygon && !nodePolygonOverlapsSelectedPolgyon) {
119969
+ return true;
119970
+ }
119971
+ if (node.data && booleanPointInPolygon$1(point([].slice.call(getObsCoords(node.data))), selectedPolygon)) {
119972
+ pickingInfos.push(node.data);
119973
+ }
119974
+ return false;
119975
+ });
119976
+ const pickingIds = pickingInfos.map((obsI) => obsIndex[obsI]);
119977
+ layerOnSelect(pickingIds);
119978
+ });
119979
+ }
119980
+ _selectEmpty() {
119981
+ const { obsLayers } = this.props;
119982
+ obsLayers.forEach((obsLayer) => {
119983
+ const { onSelect: layerOnSelect } = obsLayer;
119984
+ layerOnSelect([]);
119784
119985
  });
119785
- onSelect({ pickingInfos });
119786
119986
  }
119787
119987
  renderLayers() {
119788
- const { onSelect } = this.props;
119789
119988
  const mode = MODE_MAP[this.props.selectionType] || distEs6.ViewMode;
119790
119989
  const inheritedProps = {};
119791
119990
  PASS_THROUGH_PROPS.forEach((p) => {
@@ -119807,7 +120006,7 @@ class SelectionLayer extends CompositeLayer {
119807
120006
  const { coordinates: coordinates2 } = updatedData.features[0].geometry;
119808
120007
  this._selectPolygonObjects(coordinates2);
119809
120008
  } else if (editType === EDIT_TYPE_CLEAR) {
119810
- onSelect({ pickingInfos: [] });
120009
+ this._selectEmpty();
119811
120010
  }
119812
120011
  },
119813
120012
  _subLayerProps: {
@@ -119839,25 +120038,23 @@ SelectionLayer.defaultProps = defaultProps$f;
119839
120038
  function getBaseLayerId(layerId) {
119840
120039
  return `base-${layerId}`;
119841
120040
  }
119842
- function getSelectionLayers(tool, zoom, layerId, getCellCoords, obsIndex, updateCellsSelection, cellsQuadTree, flipY = false) {
120041
+ const onSelectNoop = ({ pickingInfos }) => {
120042
+ };
120043
+ function getSelectionLayer(tool, zoom, layerId, obsLayers, flipY = false) {
119843
120044
  if (!tool) {
119844
120045
  return [];
119845
120046
  }
119846
120047
  const cellBaseLayerId = getBaseLayerId(layerId);
119847
120048
  const editHandlePointRadius = 5 / (zoom + 16);
119848
- return [new SelectionLayer({
120049
+ return new SelectionLayer({
119849
120050
  id: "selection",
119850
120051
  flipY,
119851
- cellsQuadTree,
119852
- getCellCoords,
120052
+ obsLayers,
119853
120053
  coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
119854
120054
  selectionType: tool,
119855
- onSelect: ({ pickingInfos }) => {
119856
- const cellIds = pickingInfos.map((i2) => obsIndex[i2]);
119857
- if (updateCellsSelection) {
119858
- updateCellsSelection(cellIds);
119859
- }
119860
- },
120055
+ // This onSelect is no longer used since
120056
+ // the obsLayers each have their own onSelect.
120057
+ onSelect: onSelectNoop,
119861
120058
  layerIds: [cellBaseLayerId],
119862
120059
  getTentativeFillColor: () => [255, 255, 255, 95],
119863
120060
  getTentativeLineColor: () => [143, 143, 143, 255],
@@ -119869,7 +120066,7 @@ function getSelectionLayers(tool, zoom, layerId, getCellCoords, obsIndex, update
119869
120066
  editHandlePointRadiusScale: 1,
119870
120067
  editHandlePointRadiusMinPixels: editHandlePointRadius,
119871
120068
  editHandlePointRadiusMaxPixels: 2 * editHandlePointRadius
119872
- })];
120069
+ });
119873
120070
  }
119874
120071
  const TILE_SIZE = 4096;
119875
120072
  const DATA_TEXTURE_SIZE = 4096;
@@ -120983,16 +121180,16 @@ function addDecoder(cases, importFn) {
120983
121180
  }
120984
121181
  cases.forEach((c2) => registry$1.set(c2, importFn));
120985
121182
  }
120986
- addDecoder([void 0, 1], () => import("./raw-589273c1.js").then((m2) => m2.default));
120987
- addDecoder(5, () => import("./lzw-6da36e65.js").then((m2) => m2.default));
121183
+ addDecoder([void 0, 1], () => import("./raw-42eaa5bd.js").then((m2) => m2.default));
121184
+ addDecoder(5, () => import("./lzw-1258bf90.js").then((m2) => m2.default));
120988
121185
  addDecoder(6, () => {
120989
121186
  throw new Error("old style JPEG compression is not supported.");
120990
121187
  });
120991
- addDecoder(7, () => import("./jpeg-e27c7111.js").then((m2) => m2.default));
120992
- addDecoder([8, 32946], () => import("./deflate-7455633d.js").then((m2) => m2.default));
120993
- addDecoder(32773, () => import("./packbits-f9f4e24f.js").then((m2) => m2.default));
120994
- addDecoder(34887, () => import("./lerc-a121511e.js").then((m2) => m2.default));
120995
- addDecoder(50001, () => import("./webimage-532eb642.js").then((m2) => m2.default));
121188
+ addDecoder(7, () => import("./jpeg-a05285b9.js").then((m2) => m2.default));
121189
+ addDecoder([8, 32946], () => import("./deflate-c642ec70.js").then((m2) => m2.default));
121190
+ addDecoder(32773, () => import("./packbits-b526be77.js").then((m2) => m2.default));
121191
+ addDecoder(34887, () => import("./lerc-59152b4a.js").then((m2) => m2.default));
121192
+ addDecoder(50001, () => import("./webimage-49ce920f.js").then((m2) => m2.default));
120996
121193
  function decodeRowAcc(row, stride) {
120997
121194
  let length2 = row.length - stride;
120998
121195
  let offset5 = 0;
@@ -127785,7 +127982,7 @@ const SIGNAL_ABORTED = "__vivSignalAborted";
127785
127982
  addDecoder(5, () => LZWDecoder);
127786
127983
  const MAX_COLOR_INTENSITY = 255;
127787
127984
  const DEFAULT_COLOR_OFF = [0, 0, 0];
127788
- const MAX_CHANNELS = 6;
127985
+ const MAX_CHANNELS$1 = 6;
127789
127986
  const DEFAULT_FONT_FAMILY = "-apple-system, 'Helvetica Neue', Arial, sans-serif";
127790
127987
  const DTYPE_VALUES = {
127791
127988
  Uint8: {
@@ -129301,7 +129498,7 @@ const AdditiveColormapExtension = class extends LayerExtension {
129301
129498
  };
129302
129499
  AdditiveColormapExtension.extensionName = "AdditiveColormapExtension";
129303
129500
  AdditiveColormapExtension.defaultProps = defaultProps$4$1;
129304
- const fs$1$1 = `uniform vec3 transparentColor;
129501
+ const fs$1$2 = `uniform vec3 transparentColor;
129305
129502
  uniform bool useTransparentColor;
129306
129503
  uniform float opacity;
129307
129504
 
@@ -129328,12 +129525,12 @@ rgba = apply_opacity(rgb);
129328
129525
  `;
129329
129526
  const colorPalette = {
129330
129527
  name: "color-palette-module",
129331
- fs: fs$1$1,
129528
+ fs: fs$1$2,
129332
129529
  inject: {
129333
129530
  "fs:DECKGL_MUTATE_COLOR": DECKGL_MUTATE_COLOR
129334
129531
  }
129335
129532
  };
129336
- function padWithDefault$2(arr, defaultValue2, padWidth) {
129533
+ function padWithDefault$3(arr, defaultValue2, padWidth) {
129337
129534
  for (let i2 = 0; i2 < padWidth; i2 += 1) {
129338
129535
  arr.push(defaultValue2);
129339
129536
  }
@@ -129359,8 +129556,8 @@ function padColors({ colors, channelsVisible }) {
129359
129556
  const newColors = colors.map(
129360
129557
  (color2, i2) => channelsVisible[i2] ? color2.map((c2) => c2 / MAX_COLOR_INTENSITY) : DEFAULT_COLOR_OFF
129361
129558
  );
129362
- const padSize = MAX_CHANNELS - newColors.length;
129363
- const paddedColors = padWithDefault$2(
129559
+ const padSize = MAX_CHANNELS$1 - newColors.length;
129560
+ const paddedColors = padWithDefault$3(
129364
129561
  newColors,
129365
129562
  DEFAULT_COLOR_OFF,
129366
129563
  padSize
@@ -129479,7 +129676,7 @@ const lens = {
129479
129676
  `
129480
129677
  }
129481
129678
  };
129482
- const defaultProps$2$1 = {
129679
+ const defaultProps$2$2 = {
129483
129680
  lensEnabled: { type: "boolean", value: false, compare: true },
129484
129681
  lensSelection: { type: "number", value: 0, compare: true },
129485
129682
  lensRadius: { type: "number", value: 100, compare: true },
@@ -129501,7 +129698,7 @@ const LensExtension = class extends LayerExtension {
129501
129698
  }
129502
129699
  const onMouseMove = () => {
129503
129700
  const { viewportId } = layer.props;
129504
- const { lensRadius = defaultProps$2$1.lensRadius.value } = this.props;
129701
+ const { lensRadius = defaultProps$2$2.lensRadius.value } = this.props;
129505
129702
  if (!viewportId) {
129506
129703
  layer.setState({ unprojectLensBounds: [0, 0, 0, 0] });
129507
129704
  return;
@@ -129548,10 +129745,10 @@ const LensExtension = class extends LayerExtension {
129548
129745
  const { unprojectLensBounds = [0, 0, 0, 0] } = this.state;
129549
129746
  const {
129550
129747
  bounds: bounds2,
129551
- lensEnabled = defaultProps$2$1.lensEnabled.value,
129552
- lensSelection = defaultProps$2$1.lensSelection.value,
129553
- lensBorderColor = defaultProps$2$1.lensBorderColor.value,
129554
- lensBorderRadius = defaultProps$2$1.lensBorderRadius.value,
129748
+ lensEnabled = defaultProps$2$2.lensEnabled.value,
129749
+ lensSelection = defaultProps$2$2.lensSelection.value,
129750
+ lensBorderColor = defaultProps$2$2.lensBorderColor.value,
129751
+ lensBorderRadius = defaultProps$2$2.lensBorderRadius.value,
129555
129752
  colors,
129556
129753
  channelsVisible
129557
129754
  } = this.props;
@@ -129592,7 +129789,7 @@ const LensExtension = class extends LayerExtension {
129592
129789
  }
129593
129790
  };
129594
129791
  LensExtension.extensionName = "LensExtension";
129595
- LensExtension.defaultProps = defaultProps$2$1;
129792
+ LensExtension.defaultProps = defaultProps$2$2;
129596
129793
  function colormapModuleFactory3D(name2, apply_cmap) {
129597
129794
  const fs2 = `${apply_cmap}
129598
129795
 
@@ -129832,7 +130029,7 @@ const channels = {
129832
130029
  function range(len2) {
129833
130030
  return [...Array(len2).keys()];
129834
130031
  }
129835
- function padWithDefault$1(arr, defaultValue2, padWidth) {
130032
+ function padWithDefault$2(arr, defaultValue2, padWidth) {
129836
130033
  for (let i2 = 0; i2 < padWidth; i2 += 1) {
129837
130034
  arr.push(defaultValue2);
129838
130035
  }
@@ -129856,13 +130053,13 @@ function padContrastLimits({
129856
130053
  const newContrastLimits = contrastLimits.map(
129857
130054
  (slider, i2) => channelsVisible[i2] ? slider : [maxSliderValue, maxSliderValue]
129858
130055
  );
129859
- const padSize = MAX_CHANNELS - newContrastLimits.length;
130056
+ const padSize = MAX_CHANNELS$1 - newContrastLimits.length;
129860
130057
  if (padSize < 0) {
129861
130058
  throw Error(
129862
130059
  `${newContrastLimits.lengths} channels passed in, but only 6 are allowed.`
129863
130060
  );
129864
130061
  }
129865
- const paddedContrastLimits = padWithDefault$1(
130062
+ const paddedContrastLimits = padWithDefault$2(
129866
130063
  newContrastLimits,
129867
130064
  [maxSliderValue, maxSliderValue],
129868
130065
  padSize
@@ -129892,7 +130089,7 @@ function makeBoundingBox(viewState) {
129892
130089
  viewport.unproject([0, viewport.height])
129893
130090
  ];
129894
130091
  }
129895
- const fs$1 = `#define SHADER_NAME xr-layer-fragment-shader
130092
+ const fs$1$1 = `#define SHADER_NAME xr-layer-fragment-shader
129896
130093
 
129897
130094
  precision highp float;
129898
130095
  precision highp int;
@@ -129933,7 +130130,7 @@ void main() {
129933
130130
  DECKGL_FILTER_COLOR(gl_FragColor, geometry);
129934
130131
  }
129935
130132
  `;
129936
- const vs$1 = `#define SHADER_NAME xr-layer-vertex-shader
130133
+ const vs$1$1 = `#define SHADER_NAME xr-layer-vertex-shader
129937
130134
 
129938
130135
  attribute vec2 texCoords;
129939
130136
  attribute vec3 positions;
@@ -129952,7 +130149,7 @@ void main(void) {
129952
130149
  DECKGL_FILTER_COLOR(color, geometry);
129953
130150
  }
129954
130151
  `;
129955
- const coreShaderModule = { fs: fs$1, vs: vs$1 };
130152
+ const coreShaderModule = { fs: fs$1$1, vs: vs$1$1 };
129956
130153
  function validateWebGL2Filter(gl, interpolation) {
129957
130154
  const canShowFloat = hasFeature(gl, FEATURES$1.TEXTURE_FLOAT);
129958
130155
  const canShowLinear = hasFeature(gl, FEATURES$1.TEXTURE_FILTER_LINEAR_FLOAT);
@@ -130686,7 +130883,7 @@ function getPosition$1(boundingBox, position, length2) {
130686
130883
  }
130687
130884
  }
130688
130885
  }
130689
- const defaultProps$2 = {
130886
+ const defaultProps$2$1 = {
130690
130887
  pickable: { type: "boolean", value: true, compare: true },
130691
130888
  viewState: {
130692
130889
  type: "object",
@@ -130779,7 +130976,7 @@ const ScaleBarLayer = class extends CompositeLayer {
130779
130976
  }
130780
130977
  };
130781
130978
  ScaleBarLayer.layerName = "ScaleBarLayer";
130782
- ScaleBarLayer.defaultProps = defaultProps$2;
130979
+ ScaleBarLayer.defaultProps = defaultProps$2$1;
130783
130980
  const vs$2 = `#version 300 es
130784
130981
  #define SHADER_NAME xr-layer-vertex-shader
130785
130982
 
@@ -131185,7 +131382,7 @@ const XR3DLayer = class extends Layer {
131185
131382
  });
131186
131383
  const invertedScaleMatrix = scaleMatrix.clone().invert();
131187
131384
  const invertedResolutionMatrix = resolutionMatrix.clone().invert();
131188
- const paddedClippingPlanes = padWithDefault$1(
131385
+ const paddedClippingPlanes = padWithDefault$2(
131189
131386
  clippingPlanes.map(
131190
131387
  (p) => p.clone().transform(invertedScaleMatrix).transform(invertedResolutionMatrix)
131191
131388
  ),
@@ -131497,7 +131694,7 @@ const VolumeLayer = class extends CompositeLayer {
131497
131694
  };
131498
131695
  VolumeLayer.layerName = "VolumeLayer";
131499
131696
  VolumeLayer.defaultProps = defaultProps$9;
131500
- const vs = `
131697
+ const vs$1 = `
131501
131698
  #define SHADER_NAME bitmask-layer-vertex-shader
131502
131699
 
131503
131700
  attribute vec2 texCoords;
@@ -131518,7 +131715,7 @@ void main(void) {
131518
131715
  DECKGL_FILTER_COLOR(color, geometry);
131519
131716
  }
131520
131717
  `;
131521
- const fs = `
131718
+ const fs$1 = `
131522
131719
  #define SHADER_NAME bitmask-layer-fragment-shader
131523
131720
  precision highp float;
131524
131721
 
@@ -131586,14 +131783,14 @@ void main() {
131586
131783
  DECKGL_FILTER_COLOR(gl_FragColor, geometry);
131587
131784
  }
131588
131785
  `;
131589
- function padWithDefault(arr, defaultValue2, padWidth) {
131786
+ function padWithDefault$1(arr, defaultValue2, padWidth) {
131590
131787
  const newArr = [...arr];
131591
131788
  for (let i2 = 0; i2 < padWidth; i2 += 1) {
131592
131789
  newArr.push(defaultValue2);
131593
131790
  }
131594
131791
  return newArr;
131595
131792
  }
131596
- const defaultProps$1 = {
131793
+ const defaultProps$2 = {
131597
131794
  hoveredCell: { type: "number", value: null, compare: true },
131598
131795
  // We do not want to deep-compare cellColorData,
131599
131796
  // as it is potentially a TypedArray with millions of elements.
@@ -131605,13 +131802,13 @@ const defaultProps$1 = {
131605
131802
  // Same as with cellColorData, we do not want to deep-compare expressionData.
131606
131803
  expressionData: { type: "object", value: null, compare: 0 }
131607
131804
  };
131608
- class BitmaskLayer extends XRLayer {
131805
+ let BitmaskLayer$1 = class BitmaskLayer extends XRLayer {
131609
131806
  // eslint-disable-next-line class-methods-use-this
131610
131807
  getShaders() {
131611
131808
  const { colormap } = this.props;
131612
131809
  return {
131613
- fs,
131614
- vs,
131810
+ fs: fs$1,
131811
+ vs: vs$1,
131615
131812
  modules: [project32, picking],
131616
131813
  defines: {
131617
131814
  [COLORMAP_SHADER_PLACEHOLDER]: GLSL_COLORMAPS.includes(colormap) ? colormap : GLSL_COLORMAP_DEFAULT
@@ -131671,7 +131868,7 @@ class BitmaskLayer extends XRLayer {
131671
131868
  expressionTex,
131672
131869
  colorTexHeight: colorTex.height,
131673
131870
  colorTexWidth: colorTex.width,
131674
- channelsVisible: padWithDefault(
131871
+ channelsVisible: padWithDefault$1(
131675
131872
  channelsVisible,
131676
131873
  false,
131677
131874
  // There are six texture entries on the shaders
@@ -131708,9 +131905,564 @@ class BitmaskLayer extends XRLayer {
131708
131905
  type: GL$1.FLOAT
131709
131906
  });
131710
131907
  }
131908
+ };
131909
+ BitmaskLayer$1.layerName = "BitmaskLayer";
131910
+ BitmaskLayer$1.defaultProps = defaultProps$2;
131911
+ const vs = `
131912
+ #define SHADER_NAME bitmask-layer-vertex-shader
131913
+
131914
+ attribute vec2 texCoords;
131915
+ attribute vec3 positions;
131916
+ attribute vec3 positions64Low;
131917
+ attribute vec3 instancePickingColors;
131918
+
131919
+ varying vec2 vTexCoord;
131920
+
131921
+ void main(void) {
131922
+ geometry.worldPosition = positions;
131923
+ geometry.uv = texCoords;
131924
+ geometry.pickingColor = instancePickingColors;
131925
+ gl_Position = project_position_to_clipspace(positions, positions64Low, vec3(0.0), geometry.position);
131926
+ DECKGL_FILTER_GL_POSITION(gl_Position, geometry);
131927
+ vTexCoord = texCoords;
131928
+ vec4 color = vec4(0.0);
131929
+ DECKGL_FILTER_COLOR(color, geometry);
131930
+ }
131931
+ `;
131932
+ const fs = `
131933
+ #define SHADER_NAME bitmask-layer-fragment-shader
131934
+ precision highp float;
131935
+
131936
+ ${colormaps$1}
131937
+
131938
+ // Note: can have a maximum of 16 textures in most browsers
131939
+ // Reference: https://webglreport.com/
131940
+
131941
+ // Data (mask) texture
131942
+ uniform sampler2D channel0;
131943
+ uniform sampler2D channel1;
131944
+ uniform sampler2D channel2;
131945
+ uniform sampler2D channel3;
131946
+ uniform sampler2D channel4;
131947
+ uniform sampler2D channel5;
131948
+ uniform sampler2D channel6;
131949
+
131950
+ // Color texture
131951
+ uniform float hovered;
131952
+
131953
+ // Channel-specific properties
131954
+ uniform bool channelsVisible[7];
131955
+ uniform float channelOpacities[7];
131956
+ uniform bool channelIsStaticColorMode[7]; // TODO: should this be a single float?
131957
+ uniform bool channelIsSetColorMode[7]; // TODO: should this be a single float?
131958
+
131959
+ // TODO: can array of tuples/vec2 be used?
131960
+ uniform float channelColormapRangeStarts[7];
131961
+ uniform float channelColormapRangeEnds[7];
131962
+
131963
+ uniform float multiFeatureTexSize;
131964
+
131965
+ // Use one expressionTex for all channels, using an offset mechanism.
131966
+ uniform sampler2D valueTex;
131967
+ uniform float valueTexOffsets[7];
131968
+ uniform float valueTexHeight;
131969
+
131970
+ // Textures for set colors, using the same offset mechanism.
131971
+ uniform sampler2D colorTex;
131972
+ uniform float colorTexOffsets[7];
131973
+ uniform float colorTexHeight;
131974
+
131975
+
131976
+ // Static colors
131977
+ // TODO: For some reason I cannot use uniform vec3 colors[7]; and i cannot figure out why.
131978
+ uniform vec3 color0;
131979
+ uniform vec3 color1;
131980
+ uniform vec3 color2;
131981
+ uniform vec3 color3;
131982
+ uniform vec3 color4;
131983
+ uniform vec3 color5;
131984
+ uniform vec3 color6;
131985
+
131986
+ // Info for edge-only mode
131987
+ uniform float scaleFactor;
131988
+ uniform bool channelsFilled[7];
131989
+ uniform float channelStrokeWidths[7];
131990
+
131991
+ // opacity
131992
+ uniform float opacity;
131993
+
131994
+ varying vec2 vTexCoord;
131995
+
131996
+ vec3 sampleAndGetData(sampler2D dataTex, vec2 coord, bool isFilled, float strokeWidth, bool isOn) {
131997
+ float sampledData = texture(dataTex, coord).r;
131998
+ float clampedSampledData = max(0., min(sampledData, 1.));
131999
+
132000
+ bool isEdge = true;
132001
+
132002
+ if(!isFilled) {
132003
+ vec2 uTextureSize = vec2(2048.0, 2048.0);
132004
+ vec2 onePixel = vec2(1.0, 1.0) / uTextureSize;
132005
+
132006
+ // Vary the edgeSize based on user-defined stroke width.
132007
+ float edgeSize = 150.0 * strokeWidth * scaleFactor;
132008
+
132009
+ float pixN = texture(dataTex, coord + vec2(0.0, onePixel.y * edgeSize)).r;
132010
+ float pixS = texture(dataTex, coord - vec2(0.0, onePixel.y * edgeSize)).r;
132011
+ float pixW = texture(dataTex, coord + vec2(onePixel.x * edgeSize, 0.0)).r;
132012
+ float pixE = texture(dataTex, coord - vec2(onePixel.x * edgeSize, 0.0)).r;
132013
+
132014
+ float pixNW = texture(dataTex, coord + vec2(onePixel.y * edgeSize, onePixel.y * edgeSize)).r;
132015
+ float pixNE = texture(dataTex, coord + vec2(-1.0 * onePixel.x * edgeSize, onePixel.y * edgeSize)).r;
132016
+ float pixSW = texture(dataTex, coord - vec2(onePixel.x * edgeSize, onePixel.y * edgeSize)).r;
132017
+ float pixSE = texture(dataTex, coord - vec2(-1.0 * onePixel.x * edgeSize, onePixel.y * edgeSize)).r;
132018
+
132019
+ isEdge = (pixN != sampledData || pixS != sampledData || pixW != sampledData || pixE != sampledData || pixNW != sampledData || pixNE != sampledData || pixSW != sampledData || pixSE != sampledData);
132020
+ }
132021
+ // Return a tuple of (sampledData, isEdge)
132022
+ return vec3(clampedSampledData * float(isOn), sampledData, float(isEdge));
131711
132023
  }
131712
- BitmaskLayer.layerName = "BitmaskLayer";
131713
- BitmaskLayer.defaultProps = defaultProps$1;
132024
+
132025
+ vec4 dataToColor(vec3 sampledDataAndIsEdge, bool isStaticColorMode, vec3 channelColor, float channelOpacity, float valueOffset, float rangeStart, float rangeEnd, bool isSetColorMode, float setColorOffset) {
132026
+ float clampedSampledDataAndIsOn = sampledDataAndIsEdge.x;
132027
+ float sampledData = sampledDataAndIsEdge.y;
132028
+ float isEdge = sampledDataAndIsEdge.z;
132029
+
132030
+
132031
+ vec4 hoveredColor = float(sampledData == hovered && sampledData > 0. && hovered > 0.) * vec4(0., 0., 1., 1.);
132032
+
132033
+ // 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,
132034
+ // 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).
132035
+ float offsetSampledData = sampledData + valueOffset - 1.0;
132036
+ vec2 colorTexCoord = vec2(mod(offsetSampledData, multiFeatureTexSize) / multiFeatureTexSize, floor(offsetSampledData / multiFeatureTexSize) / (valueTexHeight - 1.));
132037
+
132038
+ // Get expression value
132039
+ float expressionValue = texture(valueTex, colorTexCoord).r / 255.;
132040
+ float scaledExpressionValue = (expressionValue - rangeStart) / max(0.005, (rangeEnd - rangeStart));
132041
+
132042
+
132043
+ // Get set color index value
132044
+ vec2 setIndicesTexCoord = vec2(mod(offsetSampledData, multiFeatureTexSize) / multiFeatureTexSize, floor(offsetSampledData / multiFeatureTexSize) / (valueTexHeight - 1.));
132045
+ float setColorIndex = texture(valueTex, setIndicesTexCoord).r;
132046
+
132047
+ // Initialize to the default "null" color.
132048
+ vec3 setColor = vec3(200. / 255., 200. / 255., 200. / 255.);
132049
+ if(setColorIndex != 0.) {
132050
+ // Subtract one from setColorIndex because we have already checked for the "null" value.
132051
+ setColorIndex = setColorIndex - 1.;
132052
+
132053
+ float setColorOffsetR = (setColorIndex + setColorOffset) * 3.0 + 0.0;
132054
+ vec2 setColorTexCoordR = vec2(mod(setColorOffsetR, multiFeatureTexSize) / multiFeatureTexSize, floor(setColorOffsetR / multiFeatureTexSize) / (colorTexHeight - 1.));
132055
+ float setColorR = texture(colorTex, setColorTexCoordR).r / 255.;
132056
+
132057
+ float setColorOffsetG = (setColorIndex + setColorOffset) * 3.0 + 1.0;
132058
+ vec2 setColorTexCoordG = vec2(mod(setColorOffsetG, multiFeatureTexSize) / multiFeatureTexSize, floor(setColorOffsetG / multiFeatureTexSize) / (colorTexHeight - 1.));
132059
+ float setColorG = texture(colorTex, setColorTexCoordG).r / 255.;
132060
+
132061
+ float setColorOffsetB = (setColorIndex + setColorOffset) * 3.0 + 2.0;
132062
+ vec2 setColorTexCoordB = vec2(mod(setColorOffsetB, multiFeatureTexSize) / multiFeatureTexSize, floor(setColorOffsetB / multiFeatureTexSize) / (colorTexHeight - 1.));
132063
+ float setColorB = texture(colorTex, setColorTexCoordB).r / 255.;
132064
+
132065
+ setColor = vec3(setColorR, setColorG, setColorB);
132066
+ }
132067
+
132068
+
132069
+ 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);
132070
+ // Only return a color if the data is non-zero.
132071
+
132072
+ return clampedSampledDataAndIsOn * isEdge * sampledColor;
132073
+ }
132074
+
132075
+ void main() {
132076
+
132077
+ // Get the color and alpha value for each channel.
132078
+ vec3 dat0 = sampleAndGetData(channel0, vTexCoord, channelsFilled[0], channelStrokeWidths[0], channelsVisible[0]);
132079
+ vec3 dat1 = sampleAndGetData(channel1, vTexCoord, channelsFilled[1], channelStrokeWidths[1], channelsVisible[1]);
132080
+ vec3 dat2 = sampleAndGetData(channel2, vTexCoord, channelsFilled[2], channelStrokeWidths[2], channelsVisible[2]);
132081
+ vec3 dat3 = sampleAndGetData(channel3, vTexCoord, channelsFilled[3], channelStrokeWidths[3], channelsVisible[3]);
132082
+ vec3 dat4 = sampleAndGetData(channel4, vTexCoord, channelsFilled[4], channelStrokeWidths[4], channelsVisible[4]);
132083
+ vec3 dat5 = sampleAndGetData(channel5, vTexCoord, channelsFilled[5], channelStrokeWidths[5], channelsVisible[5]);
132084
+ vec3 dat6 = sampleAndGetData(channel6, vTexCoord, channelsFilled[6], channelStrokeWidths[6], channelsVisible[6]);
132085
+
132086
+ vec4 val0 = dataToColor(dat0, channelIsStaticColorMode[0], color0, channelOpacities[0], valueTexOffsets[0], channelColormapRangeStarts[0], channelColormapRangeEnds[0], channelIsSetColorMode[0], colorTexOffsets[0]);
132087
+ vec4 val1 = dataToColor(dat1, channelIsStaticColorMode[1], color1, channelOpacities[1], valueTexOffsets[1], channelColormapRangeStarts[1], channelColormapRangeEnds[1], channelIsSetColorMode[1], colorTexOffsets[1]);
132088
+ vec4 val2 = dataToColor(dat2, channelIsStaticColorMode[2], color2, channelOpacities[2], valueTexOffsets[2], channelColormapRangeStarts[2], channelColormapRangeEnds[2], channelIsSetColorMode[2], colorTexOffsets[2]);
132089
+ vec4 val3 = dataToColor(dat3, channelIsStaticColorMode[3], color3, channelOpacities[3], valueTexOffsets[3], channelColormapRangeStarts[3], channelColormapRangeEnds[3], channelIsSetColorMode[3], colorTexOffsets[3]);
132090
+ vec4 val4 = dataToColor(dat4, channelIsStaticColorMode[4], color4, channelOpacities[4], valueTexOffsets[4], channelColormapRangeStarts[4], channelColormapRangeEnds[4], channelIsSetColorMode[4], colorTexOffsets[4]);
132091
+ vec4 val5 = dataToColor(dat5, channelIsStaticColorMode[5], color5, channelOpacities[5], valueTexOffsets[5], channelColormapRangeStarts[5], channelColormapRangeEnds[5], channelIsSetColorMode[5], colorTexOffsets[5]);
132092
+ vec4 val6 = dataToColor(dat6, channelIsStaticColorMode[6], color6, channelOpacities[6], valueTexOffsets[6], channelColormapRangeStarts[6], channelColormapRangeEnds[6], channelIsSetColorMode[6], colorTexOffsets[6]);
132093
+
132094
+ // If all of the channels are "empty", then discard this pixel so that it is not considered during picking.
132095
+ float emptyDat = 0.;
132096
+ if(dat0.x == emptyDat && dat1.x == emptyDat && dat2.x == emptyDat && dat3.x == emptyDat && dat4.x == emptyDat && dat5.x == emptyDat && dat6.x == emptyDat) {
132097
+ discard;
132098
+ }
132099
+
132100
+ // If the next channel color and the currently stored color (gl_FragColor) are identical,
132101
+ // or the next channel color is transparent black,
132102
+ // just use the currently stored color. Repeat this for all channels.
132103
+
132104
+ // Mix colors where necessary, using the alpha value of the next channel as the weight.
132105
+ // Use the maximum alpha value as the resulting alpha value.
132106
+ gl_FragColor = val0;
132107
+ gl_FragColor = (val1 == gl_FragColor || val1 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val1, val1.a).rgb, max(gl_FragColor.a, val1.a));
132108
+ gl_FragColor = (val2 == gl_FragColor || val2 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val2, val2.a).rgb, max(gl_FragColor.a, val2.a));
132109
+ gl_FragColor = (val3 == gl_FragColor || val3 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val3, val3.a).rgb, max(gl_FragColor.a, val3.a));
132110
+ gl_FragColor = (val4 == gl_FragColor || val4 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val4, val4.a).rgb, max(gl_FragColor.a, val4.a));
132111
+ gl_FragColor = (val5 == gl_FragColor || val5 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val5, val5.a).rgb, max(gl_FragColor.a, val5.a));
132112
+ gl_FragColor = (val6 == gl_FragColor || val6 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val6, val6.a).rgb, max(gl_FragColor.a, val6.a));
132113
+
132114
+
132115
+
132116
+ // TODO: multiply the resulting channel-level opacity value by the layer-level opacity value.
132117
+
132118
+ geometry.uv = vTexCoord;
132119
+ DECKGL_FILTER_COLOR(gl_FragColor, geometry);
132120
+ }
132121
+ `;
132122
+ function normalize$1(arr) {
132123
+ const [min, max] = extent$1(arr);
132124
+ const ratio = 255 / (max - min);
132125
+ const data = new Uint8Array(arr.map((i2) => Math.floor((i2 - min) * ratio)));
132126
+ return data;
132127
+ }
132128
+ function multiSetsToTextureData(multiFeatureValues, setColorValues, channelIsSetColorMode, texSize) {
132129
+ let totalValuesLength = 0;
132130
+ let totalColorsLength = 0;
132131
+ channelIsSetColorMode.forEach((isSetColorMode, channelIndex) => {
132132
+ var _a2, _b, _c, _d, _e;
132133
+ if (isSetColorMode) {
132134
+ totalValuesLength += ((_b = (_a2 = setColorValues[channelIndex]) == null ? void 0 : _a2.obsIndex) == null ? void 0 : _b.length) || 0;
132135
+ totalColorsLength += (((_d = (_c = setColorValues[channelIndex]) == null ? void 0 : _c.setColors) == null ? void 0 : _d.length) || 0) * 3;
132136
+ } else {
132137
+ totalValuesLength += ((_e = multiFeatureValues[channelIndex]) == null ? void 0 : _e.length) || 0;
132138
+ }
132139
+ });
132140
+ const valueTexHeight = Math.max(2, Math.ceil(totalValuesLength / texSize));
132141
+ const colorTexHeight = Math.max(2, Math.ceil(totalColorsLength / texSize));
132142
+ if (valueTexHeight > texSize) {
132143
+ console.error("Error: length of concatenated quantitative feature values larger than maximum texture size");
132144
+ }
132145
+ if (colorTexHeight > texSize) {
132146
+ console.error("Error: length of concatenated quantitative feature values larger than maximum texture size");
132147
+ }
132148
+ const totalData = new Uint8Array(texSize * valueTexHeight);
132149
+ const totalColors = new Uint8Array(texSize * colorTexHeight);
132150
+ const indicesOffsets = [];
132151
+ const colorsOffsets = [];
132152
+ let indexOffset = 0;
132153
+ let colorOffset = 0;
132154
+ channelIsSetColorMode.forEach((isSetColorMode, channelIndex) => {
132155
+ if (isSetColorMode) {
132156
+ const { setColorIndices, setColors, obsIndex } = setColorValues[channelIndex] || {};
132157
+ if (setColorIndices && setColors && obsIndex) {
132158
+ for (let i2 = 0; i2 < obsIndex.length; i2++) {
132159
+ const colorIndex = setColorIndices.get(String(i2 + 1));
132160
+ totalData[indexOffset + i2] = colorIndex === void 0 ? 0 : colorIndex + 1;
132161
+ }
132162
+ for (let i2 = 0; i2 < setColors.length; i2++) {
132163
+ const { color: [r2, g2, b] } = setColors[i2];
132164
+ totalColors[(colorOffset + i2) * 3 + 0] = r2;
132165
+ totalColors[(colorOffset + i2) * 3 + 1] = g2;
132166
+ totalColors[(colorOffset + i2) * 3 + 2] = b;
132167
+ }
132168
+ }
132169
+ indicesOffsets.push(indexOffset);
132170
+ colorsOffsets.push(colorOffset);
132171
+ indexOffset += (obsIndex == null ? void 0 : obsIndex.length) || 0;
132172
+ colorOffset += (setColors == null ? void 0 : setColors.length) || 0;
132173
+ } else {
132174
+ const featureArr = multiFeatureValues[channelIndex];
132175
+ totalData.set(normalize$1(featureArr), indexOffset);
132176
+ indicesOffsets.push(indexOffset);
132177
+ indexOffset += featureArr.length;
132178
+ colorsOffsets.push(colorOffset);
132179
+ }
132180
+ });
132181
+ return [
132182
+ totalData,
132183
+ valueTexHeight,
132184
+ indicesOffsets,
132185
+ totalColors,
132186
+ colorTexHeight,
132187
+ colorsOffsets
132188
+ ];
132189
+ }
132190
+ const MAX_CHANNELS = 7;
132191
+ const MULTI_FEATURE_TEX_SIZE = 2048;
132192
+ function padWithDefault(arr, defaultValue2, padWidth) {
132193
+ const newArr = [...arr];
132194
+ for (let i2 = 0; i2 < padWidth; i2 += 1) {
132195
+ newArr.push(defaultValue2);
132196
+ }
132197
+ return newArr;
132198
+ }
132199
+ function getColor(arr) {
132200
+ return arr ? arr.map((v) => v / 255) : [0, 0, 0];
132201
+ }
132202
+ const defaultProps$1 = {
132203
+ channelStrokeWidths: { type: "array", value: null, compare: true },
132204
+ channelsFilled: { type: "array", value: null, compare: true },
132205
+ channelOpacities: { type: "array", value: null, compare: true },
132206
+ channelColors: { type: "array", value: null, compare: true },
132207
+ hoveredCell: { type: "number", value: null, compare: true },
132208
+ colormap: { type: "string", value: GLSL_COLORMAP_DEFAULT, compare: true },
132209
+ expressionData: { type: "object", value: null, compare: true },
132210
+ multiFeatureValues: { type: "array", value: null, compare: true },
132211
+ setColorValues: { type: "array", value: null, compare: true },
132212
+ channelFeatureValueColormaps: { type: "array", value: null, compare: true },
132213
+ channelFeatureValueColormapRanges: { type: "array", value: null, compare: true },
132214
+ channelIsStaticColorMode: { type: "array", value: null, compare: true },
132215
+ channelIsSetColorMode: { type: "array", value: null, compare: true }
132216
+ };
132217
+ class BitmaskLayer2 extends XRLayer {
132218
+ // eslint-disable-next-line class-methods-use-this
132219
+ getShaders() {
132220
+ const { colormap } = this.props;
132221
+ return {
132222
+ fs,
132223
+ vs,
132224
+ modules: [project32, picking],
132225
+ defines: {
132226
+ [COLORMAP_SHADER_PLACEHOLDER]: GLSL_COLORMAPS.includes(colormap) ? colormap : GLSL_COLORMAP_DEFAULT
132227
+ }
132228
+ };
132229
+ }
132230
+ /**
132231
+ * Override the parent loadChannelTextures to enable
132232
+ * up to eight channels (rather than six).
132233
+ * Reference: https://github.com/hms-dbmi/viv/blob/v0.13.3/packages/layers/src/xr-layer/xr-layer.js#L316
132234
+ */
132235
+ loadChannelTextures(channelData) {
132236
+ const textures = {
132237
+ channel0: null,
132238
+ channel1: null,
132239
+ channel2: null,
132240
+ channel3: null,
132241
+ channel4: null,
132242
+ channel5: null,
132243
+ channel6: null
132244
+ };
132245
+ if (this.state.textures) {
132246
+ Object.values(this.state.textures).forEach((tex) => tex && tex.delete());
132247
+ }
132248
+ if (channelData && Object.keys(channelData).length > 0 && channelData.data) {
132249
+ channelData.data.forEach((d, i2) => {
132250
+ textures[`channel${i2}`] = this.dataToTexture(d, channelData.width, channelData.height);
132251
+ }, this);
132252
+ this.setState({ textures });
132253
+ }
132254
+ }
132255
+ updateState({ props: props2, oldProps, changeFlags }) {
132256
+ super.updateState({ props: props2, oldProps, changeFlags });
132257
+ if (props2.multiFeatureValues !== oldProps.multiFeatureValues || props2.setColorValues !== oldProps.setColorValues || props2.channelIsSetColorMode !== oldProps.channelIsSetColorMode) {
132258
+ const { multiFeatureValues, setColorValues, channelIsSetColorMode } = this.props;
132259
+ const [valueTex, colorTex, valueTexOffsets, colorTexOffsets, valueTexHeight, colorTexHeight] = this.multiSetsToTexture(multiFeatureValues, setColorValues, channelIsSetColorMode);
132260
+ this.setState({
132261
+ valueTex,
132262
+ colorTex,
132263
+ valueTexOffsets,
132264
+ colorTexOffsets,
132265
+ valueTexHeight,
132266
+ colorTexHeight
132267
+ });
132268
+ }
132269
+ if (props2.colormap !== oldProps.colormap) {
132270
+ const { gl } = this.context;
132271
+ if (this.state.model) {
132272
+ this.state.model.delete();
132273
+ }
132274
+ this.setState({ model: this._getModel(gl) });
132275
+ this.getAttributeManager().invalidateAll();
132276
+ }
132277
+ }
132278
+ draw(opts2) {
132279
+ const { uniforms } = opts2;
132280
+ const {
132281
+ channelStrokeWidths,
132282
+ channelsFilled,
132283
+ channelOpacities,
132284
+ channelColors,
132285
+ channelsVisible,
132286
+ // TODO: use `channelFeatureValueColormaps` in shader,
132287
+ // figure out how to call multiple GLSL colormap functions
132288
+ channelFeatureValueColormaps,
132289
+ channelFeatureValueColormapRanges,
132290
+ channelIsStaticColorMode,
132291
+ channelIsSetColorMode,
132292
+ hoveredCell,
132293
+ colorScaleLo,
132294
+ colorScaleHi,
132295
+ isExpressionMode,
132296
+ zoom,
132297
+ minZoom,
132298
+ maxZoom,
132299
+ zoomOffset
132300
+ // TODO: figure out if this needs to be used or not
132301
+ } = this.props;
132302
+ const {
132303
+ textures,
132304
+ model,
132305
+ // Expression and set index (and colors) textures with offsets
132306
+ valueTex,
132307
+ colorTex,
132308
+ valueTexOffsets,
132309
+ colorTexOffsets,
132310
+ valueTexHeight,
132311
+ colorTexHeight
132312
+ } = this.state;
132313
+ if (textures && model) {
132314
+ const scaleFactor = 1 / 2 ** (maxZoom - zoom);
132315
+ const colors = fromEntries(range$5(MAX_CHANNELS).map((i2) => [`color${i2}`, getColor(channelColors[i2])]));
132316
+ model.setUniforms(Object.assign({}, uniforms, {
132317
+ ...colors,
132318
+ // Bitmask image channel data textures
132319
+ ...textures,
132320
+ multiFeatureTexSize: MULTI_FEATURE_TEX_SIZE,
132321
+ // Expression textures with offsets
132322
+ valueTex,
132323
+ valueTexOffsets: padWithDefault(valueTexOffsets, 0, MAX_CHANNELS - valueTexOffsets.length),
132324
+ valueTexHeight,
132325
+ // Set indices and colors textures with offsets
132326
+ colorTex,
132327
+ colorTexOffsets: padWithDefault(colorTexOffsets, 0, MAX_CHANNELS - colorTexOffsets.length),
132328
+ colorTexHeight,
132329
+ // Visualization properties
132330
+ channelsFilled: padWithDefault(
132331
+ channelsFilled,
132332
+ true,
132333
+ // There are six texture entries on the shaders
132334
+ MAX_CHANNELS - channelsFilled.length
132335
+ ),
132336
+ channelOpacities: padWithDefault(
132337
+ channelOpacities,
132338
+ 0,
132339
+ // There are six texture entries on the shaders
132340
+ MAX_CHANNELS - channelOpacities.length
132341
+ ),
132342
+ channelStrokeWidths: padWithDefault(
132343
+ channelStrokeWidths,
132344
+ 1,
132345
+ // There are six texture entries on the shaders
132346
+ MAX_CHANNELS - channelStrokeWidths.length
132347
+ ),
132348
+ channelColormapRangeStarts: padWithDefault(
132349
+ channelFeatureValueColormapRanges.map((r2) => (r2 == null ? void 0 : r2[0]) || 0),
132350
+ 0,
132351
+ // There are six texture entries on the shaders
132352
+ MAX_CHANNELS - channelFeatureValueColormapRanges.length
132353
+ ),
132354
+ channelColormapRangeEnds: padWithDefault(
132355
+ channelFeatureValueColormapRanges.map((r2) => (r2 == null ? void 0 : r2[1]) || 1),
132356
+ 1,
132357
+ // There are six texture entries on the shaders
132358
+ MAX_CHANNELS - channelFeatureValueColormapRanges.length
132359
+ ),
132360
+ channelIsStaticColorMode: padWithDefault(
132361
+ channelIsStaticColorMode,
132362
+ true,
132363
+ // There are six texture entries on the shaders
132364
+ MAX_CHANNELS - channelIsStaticColorMode.length
132365
+ ),
132366
+ channelIsSetColorMode: padWithDefault(
132367
+ channelIsSetColorMode,
132368
+ false,
132369
+ // There are six texture entries on the shaders
132370
+ MAX_CHANNELS - channelIsSetColorMode.length
132371
+ ),
132372
+ hovered: hoveredCell || 0,
132373
+ channelsVisible: padWithDefault(
132374
+ channelsVisible,
132375
+ false,
132376
+ // There are six texture entries on the shaders
132377
+ MAX_CHANNELS - channelsVisible.length
132378
+ ),
132379
+ // uColorScaleRange: [colorScaleLo, colorScaleHi],
132380
+ // uIsExpressionMode: isExpressionMode,
132381
+ // uIsOutlined: false,
132382
+ scaleFactor
132383
+ })).draw();
132384
+ }
132385
+ }
132386
+ /**
132387
+ * This function creates textures from the data
132388
+ */
132389
+ dataToTexture(data, width, height) {
132390
+ const isWebGL2On = isWebGL2$1(this.context.gl);
132391
+ return new Texture2D(this.context.gl, {
132392
+ width,
132393
+ height,
132394
+ // Only use Float32 so we don't have to write two shaders
132395
+ data: new Float32Array(data),
132396
+ // we don't want or need mimaps
132397
+ mipmaps: false,
132398
+ parameters: {
132399
+ // NEAREST for integer data
132400
+ [GL$1.TEXTURE_MIN_FILTER]: GL$1.NEAREST,
132401
+ [GL$1.TEXTURE_MAG_FILTER]: GL$1.NEAREST,
132402
+ // CLAMP_TO_EDGE to remove tile artifacts
132403
+ [GL$1.TEXTURE_WRAP_S]: GL$1.CLAMP_TO_EDGE,
132404
+ [GL$1.TEXTURE_WRAP_T]: GL$1.CLAMP_TO_EDGE
132405
+ },
132406
+ format: isWebGL2On ? GL$1.R32F : GL$1.LUMINANCE,
132407
+ dataFormat: isWebGL2On ? GL$1.RED : GL$1.LUMINANCE,
132408
+ type: GL$1.FLOAT
132409
+ });
132410
+ }
132411
+ multiSetsToTexture(multiFeatureValues, setColorValues, channelIsSetColorMode) {
132412
+ const isWebGL2On = isWebGL2$1(this.context.gl);
132413
+ const [totalData, valueTexHeight, indicesOffsets, totalColors, colorTexHeight, colorsOffsets] = multiSetsToTextureData(multiFeatureValues, setColorValues, channelIsSetColorMode, MULTI_FEATURE_TEX_SIZE);
132414
+ return [
132415
+ // Color indices texture
132416
+ new Texture2D(this.context.gl, {
132417
+ width: MULTI_FEATURE_TEX_SIZE,
132418
+ height: valueTexHeight,
132419
+ // Only use Float32 so we don't have to write two shaders
132420
+ data: new Float32Array(totalData),
132421
+ // we don't want or need mimaps
132422
+ mipmaps: false,
132423
+ parameters: {
132424
+ // NEAREST for integer data
132425
+ [GL$1.TEXTURE_MIN_FILTER]: GL$1.NEAREST,
132426
+ [GL$1.TEXTURE_MAG_FILTER]: GL$1.NEAREST,
132427
+ // CLAMP_TO_EDGE to remove tile artifacts
132428
+ [GL$1.TEXTURE_WRAP_S]: GL$1.CLAMP_TO_EDGE,
132429
+ [GL$1.TEXTURE_WRAP_T]: GL$1.CLAMP_TO_EDGE
132430
+ },
132431
+ format: isWebGL2On ? GL$1.R32F : GL$1.LUMINANCE,
132432
+ dataFormat: isWebGL2On ? GL$1.RED : GL$1.LUMINANCE,
132433
+ type: GL$1.FLOAT
132434
+ }),
132435
+ // Colors texture
132436
+ new Texture2D(this.context.gl, {
132437
+ width: MULTI_FEATURE_TEX_SIZE,
132438
+ height: colorTexHeight,
132439
+ // Only use Float32 so we don't have to write two shaders
132440
+ data: new Float32Array(totalColors),
132441
+ // we don't want or need mimaps
132442
+ mipmaps: false,
132443
+ parameters: {
132444
+ // NEAREST for integer data
132445
+ [GL$1.TEXTURE_MIN_FILTER]: GL$1.NEAREST,
132446
+ [GL$1.TEXTURE_MAG_FILTER]: GL$1.NEAREST,
132447
+ // CLAMP_TO_EDGE to remove tile artifacts
132448
+ [GL$1.TEXTURE_WRAP_S]: GL$1.CLAMP_TO_EDGE,
132449
+ [GL$1.TEXTURE_WRAP_T]: GL$1.CLAMP_TO_EDGE
132450
+ },
132451
+ format: isWebGL2On ? GL$1.R32F : GL$1.LUMINANCE,
132452
+ dataFormat: isWebGL2On ? GL$1.RED : GL$1.LUMINANCE,
132453
+ type: GL$1.FLOAT
132454
+ }),
132455
+ // Offsets
132456
+ indicesOffsets,
132457
+ colorsOffsets,
132458
+ // Texture heights
132459
+ valueTexHeight,
132460
+ colorTexHeight
132461
+ ];
132462
+ }
132463
+ }
132464
+ BitmaskLayer2.layerName = "BitmaskLayer";
132465
+ BitmaskLayer2.defaultProps = defaultProps$1;
131714
132466
  function r(e3) {
131715
132467
  var t2, f2, n2 = "";
131716
132468
  if ("string" == typeof e3 || "number" == typeof e3)
@@ -141794,8 +142546,8 @@ class AbstractSpatialOrScatterplot extends PureComponent {
141794
142546
  * @param {object} params.viewState The next deck.gl viewState.
141795
142547
  */
141796
142548
  onViewStateChange({ viewState: nextViewState }) {
141797
- const { setViewState, viewState, layers, spatialAxisFixed } = this.props;
141798
- const use3d = layers == null ? void 0 : layers.some((l2) => l2.use3d);
142549
+ const { setViewState, viewState, spatialAxisFixed } = this.props;
142550
+ const use3d = this.use3d();
141799
142551
  setViewState({
141800
142552
  ...nextViewState,
141801
142553
  // If the axis is fixed, just use the current target in state i.e don't change target.
@@ -141843,6 +142595,8 @@ class AbstractSpatialOrScatterplot extends PureComponent {
141843
142595
  getLayers() {
141844
142596
  return [];
141845
142597
  }
142598
+ // TODO: remove this method and use the layer-level onHover instead.
142599
+ // (e.g., see delegateHover in spatial-beta/SpatialSubscriber.js).
141846
142600
  // eslint-disable-next-line consistent-return
141847
142601
  onHover(info) {
141848
142602
  const { coordinate, sourceLayer: layer, tile } = info;
@@ -141963,7 +142717,7 @@ class AbstractSpatialOrScatterplot extends PureComponent {
141963
142717
  */
141964
142718
  render() {
141965
142719
  var _a2, _b, _c, _d;
141966
- const { deckRef, viewState, uuid, hideTools } = this.props;
142720
+ const { deckRef, viewState, uuid, hideTools, orbitAxis } = this.props;
141967
142721
  const { gl, tool } = this.state;
141968
142722
  const layers = this.getLayers();
141969
142723
  const use3d = this.use3d();
@@ -141974,7 +142728,7 @@ class AbstractSpatialOrScatterplot extends PureComponent {
141974
142728
  pan: showPanTool && !hideTools,
141975
142729
  selectLasso: showCellSelectionTools && !hideTools
141976
142730
  }, recenterOnClick: this.recenter }), jsxRuntimeExports.jsx(DeckGL$1, { id: `deckgl-overlay-${uuid}`, ref: deckRef, views: [
141977
- use3d ? new OrbitView({ id: "orbit", controller: true, orbitAxis: "Y" }) : new OrthographicView({
142731
+ use3d ? new OrbitView({ id: "orbit", controller: true, orbitAxis }) : new OrthographicView({
141978
142732
  id: "ortho"
141979
142733
  })
141980
142734
  ], layers: gl && viewState.target.slice(0, 2).every((i2) => typeof i2 === "number") ? layers : [], glOptions: DEFAULT_GL_OPTIONS, onWebGLInitialized: this.onWebGLInitialized, onViewStateChange: this.onViewStateChange, viewState, useDevicePixels, controller: tool ? { dragPan: false } : true, getCursor: tool ? getCursorWithTool : getCursor, onHover: this.onHover, children: this.onInitializeViewInfo })] });
@@ -142276,20 +143030,29 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
142276
143030
  }
142277
143031
  return result;
142278
143032
  }
142279
- createSelectionLayers() {
143033
+ createSelectionLayer() {
142280
143034
  const { obsEmbeddingIndex: obsIndex, obsEmbedding, viewState, setCellSelection } = this.props;
142281
143035
  const { tool } = this.state;
142282
143036
  const { cellsQuadTree } = this;
142283
143037
  const flipYTooltip = true;
142284
143038
  const getCellCoords = makeDefaultGetObsCoords(obsEmbedding);
142285
- return getSelectionLayers(tool, viewState.zoom, CELLS_LAYER_ID, getCellCoords, obsIndex, setCellSelection, cellsQuadTree, flipYTooltip);
143039
+ return getSelectionLayer(tool, viewState.zoom, CELLS_LAYER_ID, [
143040
+ {
143041
+ getObsCoords: getCellCoords,
143042
+ obsIndex,
143043
+ obsQuadTree: cellsQuadTree,
143044
+ onSelect: (obsIds) => {
143045
+ setCellSelection(obsIds);
143046
+ }
143047
+ }
143048
+ ], flipYTooltip);
142286
143049
  }
142287
143050
  getLayers() {
142288
143051
  const { cellsLayer, cellSetsLayers } = this;
142289
143052
  return [
142290
143053
  cellsLayer,
142291
143054
  ...cellSetsLayers,
142292
- ...this.createSelectionLayers()
143055
+ this.createSelectionLayer()
142293
143056
  ];
142294
143057
  }
142295
143058
  onUpdateCellsData() {
@@ -144444,14 +145207,12 @@ function getXlinkHref(cmap) {
144444
145207
  }
144445
145208
  const useStyles = makeStyles(() => ({
144446
145209
  legend: {
144447
- position: "absolute",
144448
145210
  top: "2px",
144449
145211
  right: "2px",
144450
145212
  zIndex: "100",
144451
145213
  fontSize: "10px !important",
144452
- display: "flex",
144453
145214
  flexDirection: "column",
144454
- backgroundColor: "rgba(215, 215, 215, 0.2)",
145215
+ backgroundColor: "rgba(215, 215, 215, 0.7)",
144455
145216
  borderRadius: "4px",
144456
145217
  padding: "2px",
144457
145218
  lineHeight: "10px !important",
@@ -144460,26 +145221,55 @@ const useStyles = makeStyles(() => ({
144460
145221
  left: 0,
144461
145222
  position: "relative"
144462
145223
  }
145224
+ },
145225
+ legendAbsolute: {
145226
+ position: "absolute",
145227
+ display: "inline-block"
145228
+ },
145229
+ legendRelative: {
145230
+ position: "relative",
145231
+ marginBottom: "2px",
145232
+ display: "block"
145233
+ },
145234
+ legendHighContrast: {
145235
+ backgroundColor: "rgba(215, 215, 215, 0.7)"
145236
+ },
145237
+ legendLowContrast: {
145238
+ backgroundColor: "rgba(215, 215, 215, 0.2)"
145239
+ },
145240
+ legendInvisible: {
145241
+ display: "none"
144463
145242
  }
144464
145243
  }));
144465
145244
  const titleHeight = 10;
144466
145245
  const rectHeight = 8;
145246
+ const rectMarginY = 2;
145247
+ const rectMarginX = 2;
144467
145248
  function Legend(props2) {
144468
- const { visible: visibleProp, obsType, featureValueType, considerSelections = true, obsColorEncoding, featureSelection, featureLabelsMap, featureValueColormap, featureValueColormapRange, extent: extent2, width = 100, height = 36, theme } = props2;
145249
+ const { visible: visibleProp, positionRelative = false, highContrast = false, obsType, featureValueType, considerSelections = true, obsColorEncoding, featureSelection, featureLabelsMap, featureValueColormap, featureValueColormapRange, spatialChannelColor, spatialLayerColor, obsSetSelection, obsSetColor, extent: extent2, width = 100, height = 36, theme, showObsLabel = false } = props2;
144469
145250
  const svgRef = useRef();
144470
145251
  const classes = useStyles();
144471
145252
  const isDarkTheme = theme === "dark";
144472
- const visible = visibleProp && (!considerSelections || obsColorEncoding === "geneSelection" && featureSelection && Array.isArray(featureSelection) && featureSelection.length === 1);
145253
+ const isStaticColor = obsColorEncoding === "spatialChannelColor" || obsColorEncoding === "spatialLayerColor";
145254
+ const isSetColor = obsColorEncoding === "cellSetSelection";
145255
+ const layerColor = Array.isArray(spatialLayerColor) && spatialLayerColor.length === 3 ? spatialLayerColor : getDefaultColor(theme);
145256
+ const channelColor = Array.isArray(spatialChannelColor) && spatialChannelColor.length === 3 ? spatialChannelColor : getDefaultColor(theme);
145257
+ const staticColor = obsColorEncoding === "spatialChannelColor" ? channelColor : layerColor;
145258
+ 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);
145259
+ const levelZeroNames = useMemo(() => Array.from(new Set((obsSetSelection == null ? void 0 : obsSetSelection.map((setPath) => setPath[0])) || [])), [obsSetSelection]);
145260
+ const dynamicHeight = isSetColor ? levelZeroNames.length * titleHeight + (obsSetSelection == null ? void 0 : obsSetSelection.length) * (rectHeight + rectMarginY) : height;
144473
145261
  useEffect(() => {
144474
145262
  const domElement = svgRef.current;
144475
- const foregroundColor = isDarkTheme ? "white" : "black";
145263
+ const foregroundColor = highContrast ? "black" : isDarkTheme ? "white" : "black";
144476
145264
  const svg = select(domElement);
144477
145265
  svg.selectAll("g").remove();
144478
- svg.attr("width", width).attr("height", height);
144479
- const g2 = svg.append("g").attr("width", width).attr("height", height);
144480
- const xlinkHref = getXlinkHref(featureValueColormap);
145266
+ svg.attr("width", width).attr("height", dynamicHeight);
145267
+ const g2 = svg.append("g").attr("width", width).attr("height", dynamicHeight);
144481
145268
  if (!considerSelections || obsColorEncoding === "geneSelection") {
144482
- g2.append("image").attr("x", 0).attr("y", titleHeight).attr("width", width).attr("height", rectHeight).attr("preserveAspectRatio", "none").attr("href", xlinkHref);
145269
+ if (featureValueColormap) {
145270
+ const xlinkHref = getXlinkHref(featureValueColormap);
145271
+ g2.append("image").attr("x", 0).attr("y", titleHeight).attr("width", width).attr("height", rectHeight).attr("preserveAspectRatio", "none").attr("href", xlinkHref);
145272
+ }
144483
145273
  const [xMin, xMax] = extent2 || [0, 1];
144484
145274
  const [rMin, rMax] = featureValueColormapRange;
144485
145275
  const scaledDataExtent = [
@@ -144492,9 +145282,42 @@ function Legend(props2) {
144492
145282
  axisTicks.selectAll("text").style("fill", foregroundColor);
144493
145283
  axisTicks.selectAll("text").attr("text-anchor", (d, i2) => i2 === 0 ? "start" : "end");
144494
145284
  }
144495
- const featureLabel = featureSelection && featureSelection.length >= 1 ? (featureLabelsMap == null ? void 0 : featureLabelsMap.get(featureSelection[0])) || featureSelection[0] : null;
144496
- const legendLabel = considerSelections ? featureLabel || capitalize$1(featureValueType) : capitalize$1(featureValueType);
144497
- g2.append("text").attr("text-anchor", "end").attr("dominant-baseline", "hanging").attr("x", width).attr("y", 0).text(legendLabel).style("font-size", "10px").style("fill", foregroundColor);
145285
+ if (isStaticColor) {
145286
+ g2.append("rect").attr("x", 0).attr("y", titleHeight).attr("width", width).attr("height", rectHeight).attr("fill", `rgb(${staticColor[0]},${staticColor[1]},${staticColor[2]})`);
145287
+ }
145288
+ if (isSetColor && obsSetSelection && obsSetColor) {
145289
+ const obsSetSelectionByLevelZero = {};
145290
+ obsSetSelection.forEach((setPath) => {
145291
+ const levelZeroName = setPath[0];
145292
+ if (!obsSetSelectionByLevelZero[levelZeroName]) {
145293
+ obsSetSelectionByLevelZero[levelZeroName] = [];
145294
+ }
145295
+ obsSetSelectionByLevelZero[levelZeroName].push(setPath);
145296
+ });
145297
+ let y2 = 0;
145298
+ Object.entries(obsSetSelectionByLevelZero).forEach(([levelZeroName, setPaths]) => {
145299
+ g2.append("text").attr("text-anchor", "start").attr("dominant-baseline", "hanging").attr("x", 0).attr("y", y2).text(levelZeroName).style("font-size", "9px").style("fill", foregroundColor);
145300
+ y2 += titleHeight;
145301
+ setPaths.forEach((setPath) => {
145302
+ const setColor = obsSetColor.find((d) => isEqual$1(d.path, setPath)).color;
145303
+ g2.append("rect").attr("x", 0).attr("y", y2).attr("width", rectHeight).attr("height", rectHeight).attr("fill", `rgb(${setColor[0]},${setColor[1]},${setColor[2]})`);
145304
+ g2.append("text").attr("text-anchor", "start").attr("dominant-baseline", "hanging").attr("x", rectHeight + rectMarginX).attr("y", y2).text(setPath.at(-1)).style("font-size", "9px").style("fill", foregroundColor);
145305
+ y2 += rectHeight + rectMarginY;
145306
+ });
145307
+ });
145308
+ }
145309
+ const featureSelectionLabel = featureSelection && featureSelection.length >= 1 && !isStaticColor ? (featureLabelsMap == null ? void 0 : featureLabelsMap.get(featureSelection[0])) || featureSelection[0] : null;
145310
+ const obsLabel = capitalize$1(obsType);
145311
+ const featureLabel = considerSelections ? featureSelectionLabel || capitalize$1(featureValueType) : capitalize$1(featureValueType);
145312
+ const mainLabel = showObsLabel ? obsLabel : featureLabel;
145313
+ const subLabel = showObsLabel ? featureLabel : null;
145314
+ const hasSubLabel = subLabel !== null;
145315
+ if (!isSetColor) {
145316
+ g2.append("text").attr("text-anchor", hasSubLabel ? "start" : "end").attr("dominant-baseline", "hanging").attr("x", hasSubLabel ? 0 : width).attr("y", 0).text(mainLabel).style("font-size", "10px").style("fill", foregroundColor);
145317
+ }
145318
+ if (hasSubLabel) {
145319
+ g2.append("text").attr("text-anchor", "end").attr("dominant-baseline", "hanging").attr("x", width).attr("y", titleHeight).text(subLabel).style("font-size", "9px").style("fill", foregroundColor);
145320
+ }
144498
145321
  }, [
144499
145322
  width,
144500
145323
  height,
@@ -144507,13 +145330,51 @@ function Legend(props2) {
144507
145330
  isDarkTheme,
144508
145331
  featureValueType,
144509
145332
  extent2,
144510
- featureLabelsMap
145333
+ featureLabelsMap,
145334
+ spatialChannelColor,
145335
+ obsSetColor,
145336
+ obsSetSelection,
145337
+ isSetColor
144511
145338
  ]);
144512
- return jsxRuntimeExports.jsx("div", { className: classes.legend, style: { display: visible ? "inline-block" : "none" }, children: jsxRuntimeExports.jsx("svg", { ref: svgRef, style: {
145339
+ return jsxRuntimeExports.jsx("div", { className: clsx(classes.legend, {
145340
+ [classes.legendRelative]: positionRelative,
145341
+ [classes.legendAbsolute]: !positionRelative,
145342
+ [classes.legendHighContrast]: highContrast,
145343
+ [classes.legendLowContrast]: !highContrast,
145344
+ [classes.legendInvisible]: !visible
145345
+ }), children: jsxRuntimeExports.jsx("svg", { ref: svgRef, style: {
144513
145346
  width: `${width}px`,
144514
- height: `${height}px`
145347
+ height: `${dynamicHeight}px`
144515
145348
  } }) });
144516
145349
  }
145350
+ makeStyles(() => ({
145351
+ multiLegend: {
145352
+ position: "absolute",
145353
+ top: "0px",
145354
+ right: "0px"
145355
+ }
145356
+ }));
145357
+ makeStyles(() => ({
145358
+ channelNamesLegendContainer: {
145359
+ position: "absolute",
145360
+ bottom: "0px",
145361
+ left: "0px",
145362
+ paddingLeft: "10px",
145363
+ paddingBottom: "10px"
145364
+ },
145365
+ channelNamesLegendLayer: {
145366
+ display: "flex"
145367
+ },
145368
+ channelNamesRow: {
145369
+ flexDirection: "column"
145370
+ },
145371
+ channelNamesCol: {
145372
+ flexDirection: "row"
145373
+ },
145374
+ channelNameText: {
145375
+ marginRight: "10px"
145376
+ }
145377
+ }));
144517
145378
  function EmbeddingScatterplotSubscriber(props2) {
144518
145379
  const {
144519
145380
  uuid,