@vitessce/heatmap 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.
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import React__default, { Children, isValidElement, cloneElement, useRef, useEffect, useLayoutEffect, createElement, forwardRef, useState, useMemo, useImperativeHandle, useReducer, useCallback, useId } from "react";
2
+ import React__default, { Children, isValidElement, cloneElement, useRef, useMemo, useEffect, useLayoutEffect, createElement, forwardRef, useState, useImperativeHandle, useReducer, useCallback, useId } from "react";
3
3
  import { useVitessceContainer, useComponentHover, useComponentViewInfo, usePlotOptionsStyles, OptionsContainer, OptionSelect, useLoaders, useSetComponentHover, useSetComponentViewInfo, useCoordination, useDeckCanvasSize, useMultiObsLabels, useFeatureLabelsData, useObsFeatureMatrixData, useObsSetsData, useReady, useUrls, useUint8ObsFeatureMatrix, useGetObsInfo, useGetObsMembership, TitleInfo } from "@vitessce/vit-s";
4
4
  import * as ReactDOM from "react-dom";
5
5
  function _mergeNamespaces(n2, m) {
@@ -10838,8 +10838,10 @@ const ViewType$1 = {
10838
10838
  STATUS: "status",
10839
10839
  SCATTERPLOT: "scatterplot",
10840
10840
  SPATIAL: "spatial",
10841
+ SPATIAL_BETA: "spatialBeta",
10841
10842
  HEATMAP: "heatmap",
10842
10843
  LAYER_CONTROLLER: "layerController",
10844
+ LAYER_CONTROLLER_BETA: "layerControllerBeta",
10843
10845
  GENOMIC_PROFILES: "genomicProfiles",
10844
10846
  GATING: "gating",
10845
10847
  FEATURE_LIST: "featureList",
@@ -10851,20 +10853,24 @@ const ViewType$1 = {
10851
10853
  const DataType$2 = {
10852
10854
  OBS_LABELS: "obsLabels",
10853
10855
  OBS_EMBEDDING: "obsEmbedding",
10854
- OBS_LOCATIONS: "obsLocations",
10855
10856
  OBS_FEATURE_MATRIX: "obsFeatureMatrix",
10856
10857
  OBS_SETS: "obsSets",
10857
10858
  FEATURE_LABELS: "featureLabels",
10858
10859
  IMAGE: "image",
10859
10860
  OBS_SEGMENTATIONS: "obsSegmentations",
10860
10861
  NEIGHBORHOODS: "neighborhoods",
10861
- GENOMIC_PROFILES: "genomic-profiles"
10862
+ GENOMIC_PROFILES: "genomic-profiles",
10863
+ OBS_SPOTS: "obsSpots",
10864
+ OBS_POINTS: "obsPoints",
10865
+ OBS_LOCATIONS: "obsLocations"
10862
10866
  };
10863
10867
  const FileType$1 = {
10864
10868
  // Joint file types
10865
10869
  ANNDATA_ZARR: "anndata.zarr",
10866
10870
  // Atomic file types
10867
10871
  OBS_EMBEDDING_CSV: "obsEmbedding.csv",
10872
+ OBS_SPOTS_CSV: "obsSpots.csv",
10873
+ OBS_POINTS_CSV: "obsPoints.csv",
10868
10874
  OBS_LOCATIONS_CSV: "obsLocations.csv",
10869
10875
  OBS_LABELS_CSV: "obsLabels.csv",
10870
10876
  FEATURE_LABELS_CSV: "featureLabels.csv",
@@ -10877,6 +10883,8 @@ const FileType$1 = {
10877
10883
  OBS_FEATURE_MATRIX_ANNDATA_ZARR: "obsFeatureMatrix.anndata.zarr",
10878
10884
  OBS_SETS_ANNDATA_ZARR: "obsSets.anndata.zarr",
10879
10885
  OBS_EMBEDDING_ANNDATA_ZARR: "obsEmbedding.anndata.zarr",
10886
+ OBS_SPOTS_ANNDATA_ZARR: "obsSpots.anndata.zarr",
10887
+ OBS_POINTS_ANNDATA_ZARR: "obsPoints.anndata.zarr",
10880
10888
  OBS_LOCATIONS_ANNDATA_ZARR: "obsLocations.anndata.zarr",
10881
10889
  OBS_SEGMENTATIONS_ANNDATA_ZARR: "obsSegmentations.anndata.zarr",
10882
10890
  OBS_LABELS_ANNDATA_ZARR: "obsLabels.anndata.zarr",
@@ -10885,6 +10893,8 @@ const FileType$1 = {
10885
10893
  OBS_FEATURE_MATRIX_MUDATA_ZARR: "obsFeatureMatrix.mudata.zarr",
10886
10894
  OBS_SETS_MUDATA_ZARR: "obsSets.mudata.zarr",
10887
10895
  OBS_EMBEDDING_MUDATA_ZARR: "obsEmbedding.mudata.zarr",
10896
+ OBS_SPOTS_MUDATA_ZARR: "obsSpots.mudata.zarr",
10897
+ OBS_POINTS_MUDATA_ZARR: "obsPoints.mudata.zarr",
10888
10898
  OBS_LOCATIONS_MUDATA_ZARR: "obsLocations.mudata.zarr",
10889
10899
  OBS_SEGMENTATIONS_MUDATA_ZARR: "obsSegmentations.mudata.zarr",
10890
10900
  OBS_LABELS_MUDATA_ZARR: "obsLabels.mudata.zarr",
@@ -10928,10 +10938,8 @@ const FileType$1 = {
10928
10938
  ANNDATA_EXPRESSION_MATRIX_ZARR: "anndata-expression-matrix.zarr"
10929
10939
  };
10930
10940
  const CoordinationType$1 = {
10931
- // Meta coordination scopes
10932
10941
  META_COORDINATION_SCOPES: "metaCoordinationScopes",
10933
10942
  META_COORDINATION_SCOPES_BY: "metaCoordinationScopesBy",
10934
- // Other coordination scopes
10935
10943
  DATASET: "dataset",
10936
10944
  // Entity types
10937
10945
  OBS_TYPE: "obsType",
@@ -10957,6 +10965,7 @@ const CoordinationType$1 = {
10957
10965
  SPATIAL_TARGET_X: "spatialTargetX",
10958
10966
  SPATIAL_TARGET_Y: "spatialTargetY",
10959
10967
  SPATIAL_TARGET_Z: "spatialTargetZ",
10968
+ SPATIAL_TARGET_T: "spatialTargetT",
10960
10969
  SPATIAL_ROTATION_X: "spatialRotationX",
10961
10970
  SPATIAL_ROTATION_Y: "spatialRotationY",
10962
10971
  SPATIAL_ROTATION_Z: "spatialRotationZ",
@@ -10994,7 +11003,46 @@ const CoordinationType$1 = {
10994
11003
  GATING_FEATURE_SELECTION_X: "gatingFeatureSelectionX",
10995
11004
  GATING_FEATURE_SELECTION_Y: "gatingFeatureSelectionY",
10996
11005
  FEATURE_VALUE_TRANSFORM_COEFFICIENT: "featureValueTransformCoefficient",
10997
- TOOLTIPS_VISIBLE: "tooltipsVisible"
11006
+ TOOLTIPS_VISIBLE: "tooltipsVisible",
11007
+ FILE_UID: "fileUid",
11008
+ IMAGE_LAYER: "imageLayer",
11009
+ IMAGE_CHANNEL: "imageChannel",
11010
+ SEGMENTATION_LAYER: "segmentationLayer",
11011
+ SEGMENTATION_CHANNEL: "segmentationChannel",
11012
+ SPATIAL_TARGET_C: "spatialTargetC",
11013
+ SPATIAL_LAYER_VISIBLE: "spatialLayerVisible",
11014
+ SPATIAL_LAYER_OPACITY: "spatialLayerOpacity",
11015
+ SPATIAL_LAYER_COLORMAP: "spatialLayerColormap",
11016
+ SPATIAL_LAYER_TRANSPARENT_COLOR: "spatialLayerTransparentColor",
11017
+ SPATIAL_LAYER_MODEL_MATRIX: "spatialLayerModelMatrix",
11018
+ SPATIAL_SEGMENTATION_FILLED: "spatialSegmentationFilled",
11019
+ SPATIAL_SEGMENTATION_STROKE_WIDTH: "spatialSegmentationStrokeWidth",
11020
+ SPATIAL_CHANNEL_COLOR: "spatialChannelColor",
11021
+ SPATIAL_CHANNEL_VISIBLE: "spatialChannelVisible",
11022
+ SPATIAL_CHANNEL_OPACITY: "spatialChannelOpacity",
11023
+ SPATIAL_CHANNEL_WINDOW: "spatialChannelWindow",
11024
+ PHOTOMETRIC_INTERPRETATION: "photometricInterpretation",
11025
+ // For 3D volume rendering
11026
+ SPATIAL_RENDERING_MODE: "spatialRenderingMode",
11027
+ VOLUMETRIC_RENDERING_ALGORITHM: "volumetricRenderingAlgorithm",
11028
+ SPATIAL_TARGET_RESOLUTION: "spatialTargetResolution",
11029
+ // For clipping plane sliders
11030
+ SPATIAL_SLICE_X: "spatialSliceX",
11031
+ SPATIAL_SLICE_Y: "spatialSliceY",
11032
+ SPATIAL_SLICE_Z: "spatialSliceZ",
11033
+ // For spatial spot and point layers
11034
+ SPOT_LAYER: "spotLayer",
11035
+ POINT_LAYER: "pointLayer",
11036
+ SPATIAL_SPOT_RADIUS: "spatialSpotRadius",
11037
+ SPATIAL_SPOT_FILLED: "spatialSpotFilled",
11038
+ SPATIAL_SPOT_STROKE_WIDTH: "spatialSpotStrokeWidth",
11039
+ SPATIAL_LAYER_COLOR: "spatialLayerColor",
11040
+ PIXEL_HIGHLIGHT: "pixelHighlight",
11041
+ TOOLTIP_CROSSHAIRS_VISIBLE: "tooltipCrosshairsVisible",
11042
+ LEGEND_VISIBLE: "legendVisible",
11043
+ SPATIAL_CHANNEL_LABELS_VISIBLE: "spatialChannelLabelsVisible",
11044
+ SPATIAL_CHANNEL_LABELS_ORIENTATION: "spatialChannelLabelsOrientation",
11045
+ SPATIAL_CHANNEL_LABEL_SIZE: "spatialChannelLabelSize"
10998
11046
  };
10999
11047
  const COMPONENT_COORDINATION_TYPES = {
11000
11048
  [ViewType$1.SCATTERPLOT]: [
@@ -11098,6 +11146,77 @@ const COMPONENT_COORDINATION_TYPES = {
11098
11146
  CoordinationType$1.MOLECULE_HIGHLIGHT,
11099
11147
  CoordinationType$1.TOOLTIPS_VISIBLE
11100
11148
  ],
11149
+ [ViewType$1.SPATIAL_BETA]: [
11150
+ CoordinationType$1.META_COORDINATION_SCOPES,
11151
+ CoordinationType$1.META_COORDINATION_SCOPES_BY,
11152
+ CoordinationType$1.DATASET,
11153
+ CoordinationType$1.OBS_TYPE,
11154
+ CoordinationType$1.OBS_LABELS_TYPE,
11155
+ CoordinationType$1.FEATURE_TYPE,
11156
+ CoordinationType$1.FEATURE_VALUE_TYPE,
11157
+ CoordinationType$1.SPATIAL_ZOOM,
11158
+ CoordinationType$1.SPATIAL_ROTATION,
11159
+ CoordinationType$1.SPATIAL_POINT_LAYER,
11160
+ CoordinationType$1.SPATIAL_NEIGHBORHOOD_LAYER,
11161
+ CoordinationType$1.SPATIAL_TARGET_X,
11162
+ CoordinationType$1.SPATIAL_TARGET_Y,
11163
+ CoordinationType$1.SPATIAL_TARGET_Z,
11164
+ CoordinationType$1.SPATIAL_TARGET_T,
11165
+ CoordinationType$1.SPATIAL_ROTATION_X,
11166
+ CoordinationType$1.SPATIAL_ROTATION_Y,
11167
+ CoordinationType$1.SPATIAL_ROTATION_Z,
11168
+ CoordinationType$1.SPATIAL_ROTATION_ORBIT,
11169
+ CoordinationType$1.SPATIAL_ORBIT_AXIS,
11170
+ CoordinationType$1.SPATIAL_AXIS_FIXED,
11171
+ CoordinationType$1.OBS_FILTER,
11172
+ CoordinationType$1.OBS_HIGHLIGHT,
11173
+ CoordinationType$1.OBS_SET_SELECTION,
11174
+ CoordinationType$1.OBS_SET_HIGHLIGHT,
11175
+ CoordinationType$1.OBS_SET_COLOR,
11176
+ CoordinationType$1.FEATURE_HIGHLIGHT,
11177
+ CoordinationType$1.FEATURE_SELECTION,
11178
+ CoordinationType$1.FEATURE_VALUE_COLORMAP,
11179
+ CoordinationType$1.FEATURE_VALUE_COLORMAP_RANGE,
11180
+ CoordinationType$1.OBS_COLOR_ENCODING,
11181
+ CoordinationType$1.ADDITIONAL_OBS_SETS,
11182
+ CoordinationType$1.MOLECULE_HIGHLIGHT,
11183
+ CoordinationType$1.TOOLTIPS_VISIBLE,
11184
+ CoordinationType$1.FILE_UID,
11185
+ CoordinationType$1.SPATIAL_TARGET_C,
11186
+ CoordinationType$1.SPATIAL_LAYER_VISIBLE,
11187
+ CoordinationType$1.SPATIAL_LAYER_OPACITY,
11188
+ CoordinationType$1.SPATIAL_LAYER_COLORMAP,
11189
+ CoordinationType$1.SPATIAL_LAYER_TRANSPARENT_COLOR,
11190
+ CoordinationType$1.SPATIAL_LAYER_MODEL_MATRIX,
11191
+ CoordinationType$1.SPATIAL_CHANNEL_COLOR,
11192
+ CoordinationType$1.SPATIAL_SEGMENTATION_FILLED,
11193
+ CoordinationType$1.SPATIAL_SEGMENTATION_STROKE_WIDTH,
11194
+ CoordinationType$1.IMAGE_LAYER,
11195
+ CoordinationType$1.SEGMENTATION_LAYER,
11196
+ CoordinationType$1.IMAGE_CHANNEL,
11197
+ CoordinationType$1.SEGMENTATION_CHANNEL,
11198
+ CoordinationType$1.SPATIAL_CHANNEL_VISIBLE,
11199
+ CoordinationType$1.SPATIAL_CHANNEL_OPACITY,
11200
+ CoordinationType$1.SPATIAL_CHANNEL_WINDOW,
11201
+ CoordinationType$1.SPATIAL_RENDERING_MODE,
11202
+ CoordinationType$1.VOLUMETRIC_RENDERING_ALGORITHM,
11203
+ CoordinationType$1.SPATIAL_TARGET_RESOLUTION,
11204
+ CoordinationType$1.SPATIAL_SLICE_X,
11205
+ CoordinationType$1.SPATIAL_SLICE_Y,
11206
+ CoordinationType$1.SPATIAL_SLICE_Z,
11207
+ CoordinationType$1.SPOT_LAYER,
11208
+ CoordinationType$1.POINT_LAYER,
11209
+ CoordinationType$1.SPATIAL_SPOT_RADIUS,
11210
+ CoordinationType$1.SPATIAL_SPOT_FILLED,
11211
+ CoordinationType$1.SPATIAL_SPOT_STROKE_WIDTH,
11212
+ CoordinationType$1.SPATIAL_LAYER_COLOR,
11213
+ CoordinationType$1.PIXEL_HIGHLIGHT,
11214
+ CoordinationType$1.TOOLTIP_CROSSHAIRS_VISIBLE,
11215
+ CoordinationType$1.LEGEND_VISIBLE,
11216
+ CoordinationType$1.SPATIAL_CHANNEL_LABELS_VISIBLE,
11217
+ CoordinationType$1.SPATIAL_CHANNEL_LABELS_ORIENTATION,
11218
+ CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE
11219
+ ],
11101
11220
  [ViewType$1.HEATMAP]: [
11102
11221
  CoordinationType$1.DATASET,
11103
11222
  CoordinationType$1.OBS_TYPE,
@@ -11203,6 +11322,61 @@ const COMPONENT_COORDINATION_TYPES = {
11203
11322
  CoordinationType$1.SPATIAL_ROTATION_ORBIT,
11204
11323
  CoordinationType$1.SPATIAL_ORBIT_AXIS
11205
11324
  ],
11325
+ [ViewType$1.LAYER_CONTROLLER_BETA]: [
11326
+ CoordinationType$1.META_COORDINATION_SCOPES,
11327
+ CoordinationType$1.META_COORDINATION_SCOPES_BY,
11328
+ CoordinationType$1.DATASET,
11329
+ CoordinationType$1.OBS_TYPE,
11330
+ CoordinationType$1.FEATURE_TYPE,
11331
+ CoordinationType$1.FEATURE_VALUE_TYPE,
11332
+ CoordinationType$1.SPATIAL_POINT_LAYER,
11333
+ CoordinationType$1.SPATIAL_NEIGHBORHOOD_LAYER,
11334
+ CoordinationType$1.SPATIAL_ZOOM,
11335
+ CoordinationType$1.SPATIAL_TARGET_X,
11336
+ CoordinationType$1.SPATIAL_TARGET_Y,
11337
+ CoordinationType$1.SPATIAL_TARGET_Z,
11338
+ CoordinationType$1.SPATIAL_TARGET_T,
11339
+ CoordinationType$1.SPATIAL_ROTATION_X,
11340
+ CoordinationType$1.SPATIAL_ROTATION_Y,
11341
+ CoordinationType$1.SPATIAL_ROTATION_Z,
11342
+ CoordinationType$1.SPATIAL_ROTATION_ORBIT,
11343
+ CoordinationType$1.SPATIAL_ORBIT_AXIS,
11344
+ CoordinationType$1.FILE_UID,
11345
+ CoordinationType$1.SPATIAL_TARGET_C,
11346
+ CoordinationType$1.SPATIAL_LAYER_VISIBLE,
11347
+ CoordinationType$1.SPATIAL_LAYER_OPACITY,
11348
+ CoordinationType$1.SPATIAL_LAYER_COLORMAP,
11349
+ CoordinationType$1.SPATIAL_LAYER_TRANSPARENT_COLOR,
11350
+ CoordinationType$1.SPATIAL_LAYER_MODEL_MATRIX,
11351
+ CoordinationType$1.SPATIAL_CHANNEL_COLOR,
11352
+ CoordinationType$1.SPATIAL_SEGMENTATION_FILLED,
11353
+ CoordinationType$1.SPATIAL_SEGMENTATION_STROKE_WIDTH,
11354
+ CoordinationType$1.IMAGE_CHANNEL,
11355
+ CoordinationType$1.SEGMENTATION_CHANNEL,
11356
+ CoordinationType$1.SPATIAL_CHANNEL_VISIBLE,
11357
+ CoordinationType$1.SPATIAL_CHANNEL_OPACITY,
11358
+ CoordinationType$1.SPATIAL_CHANNEL_WINDOW,
11359
+ CoordinationType$1.PHOTOMETRIC_INTERPRETATION,
11360
+ CoordinationType$1.SPATIAL_RENDERING_MODE,
11361
+ CoordinationType$1.VOLUMETRIC_RENDERING_ALGORITHM,
11362
+ CoordinationType$1.SPATIAL_TARGET_RESOLUTION,
11363
+ CoordinationType$1.SPATIAL_SLICE_X,
11364
+ CoordinationType$1.SPATIAL_SLICE_Y,
11365
+ CoordinationType$1.SPATIAL_SLICE_Z,
11366
+ CoordinationType$1.SPOT_LAYER,
11367
+ CoordinationType$1.POINT_LAYER,
11368
+ CoordinationType$1.SPATIAL_SPOT_RADIUS,
11369
+ CoordinationType$1.SPATIAL_SPOT_FILLED,
11370
+ CoordinationType$1.SPATIAL_SPOT_STROKE_WIDTH,
11371
+ CoordinationType$1.SPATIAL_LAYER_COLOR,
11372
+ CoordinationType$1.OBS_COLOR_ENCODING,
11373
+ CoordinationType$1.TOOLTIPS_VISIBLE,
11374
+ CoordinationType$1.TOOLTIP_CROSSHAIRS_VISIBLE,
11375
+ CoordinationType$1.LEGEND_VISIBLE,
11376
+ CoordinationType$1.SPATIAL_CHANNEL_LABELS_VISIBLE,
11377
+ CoordinationType$1.SPATIAL_CHANNEL_LABELS_ORIENTATION,
11378
+ CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE
11379
+ ],
11206
11380
  [ViewType$1.GENOMIC_PROFILES]: [
11207
11381
  CoordinationType$1.DATASET,
11208
11382
  CoordinationType$1.OBS_TYPE,
@@ -11494,6 +11668,8 @@ const annDataObsSets = z.array(z.object({
11494
11668
  ]),
11495
11669
  scorePath: z.string().optional().describe("The location in the AnnData store for the set confidence scores, like 'obs/celltype_prediction_score.'")
11496
11670
  }));
11671
+ const annDataObsSpots = annDataObsm;
11672
+ const annDataObsPoints = annDataObsm;
11497
11673
  const annDataObsLocations = annDataObsm;
11498
11674
  const annDataObsEmbedding = annDataObsm;
11499
11675
  const annDataObsSegmentations = annDataObs;
@@ -11520,10 +11696,21 @@ z.object({
11520
11696
  z.object({
11521
11697
  obsIndex: z.string(),
11522
11698
  obsEmbedding: z.array(z.string()).length(2)
11699
+ // TODO: support 3D?
11700
+ });
11701
+ z.object({
11702
+ obsIndex: z.string(),
11703
+ obsSpots: z.array(z.string()).length(2)
11704
+ // TODO: support 3D?
11705
+ });
11706
+ z.object({
11707
+ obsIndex: z.string(),
11708
+ obsPoints: z.array(z.string()).length(3)
11523
11709
  });
11524
11710
  z.object({
11525
11711
  obsIndex: z.string(),
11526
11712
  obsLocations: z.array(z.string()).length(2)
11713
+ // TODO: support 3D?
11527
11714
  });
11528
11715
  z.object({
11529
11716
  obsIndex: z.string(),
@@ -11555,6 +11742,8 @@ z.object({
11555
11742
  ]),
11556
11743
  obsFeatureMatrix: annDataObsFeatureMatrix,
11557
11744
  obsSets: annDataObsSets,
11745
+ obsSpots: annDataObsSpots,
11746
+ obsPoints: annDataObsPoints,
11558
11747
  obsLocations: annDataObsLocations,
11559
11748
  obsSegmentations: annDataObsSegmentations,
11560
11749
  obsEmbedding: z.union([
@@ -18262,6 +18451,24 @@ class Pool {
18262
18451
  }
18263
18452
  }
18264
18453
  }
18454
+ function r$1(e3) {
18455
+ var t2, f2, n2 = "";
18456
+ if ("string" == typeof e3 || "number" == typeof e3)
18457
+ n2 += e3;
18458
+ else if ("object" == typeof e3)
18459
+ if (Array.isArray(e3))
18460
+ for (t2 = 0; t2 < e3.length; t2++)
18461
+ e3[t2] && (f2 = r$1(e3[t2])) && (n2 && (n2 += " "), n2 += f2);
18462
+ else
18463
+ for (t2 in e3)
18464
+ e3[t2] && (n2 && (n2 += " "), n2 += t2);
18465
+ return n2;
18466
+ }
18467
+ function clsx() {
18468
+ for (var e3, t2, f2 = 0, n2 = ""; f2 < arguments.length; )
18469
+ (e3 = arguments[f2++]) && (t2 = r$1(e3)) && (n2 && (n2 += " "), n2 += t2);
18470
+ return n2;
18471
+ }
18265
18472
  var common$2 = {
18266
18473
  black: "#000",
18267
18474
  white: "#fff"
@@ -23262,24 +23469,6 @@ function makeStyles$1(stylesOrCreator) {
23262
23469
  };
23263
23470
  return useStyles2;
23264
23471
  }
23265
- function r$1(e3) {
23266
- var t2, f2, n2 = "";
23267
- if ("string" == typeof e3 || "number" == typeof e3)
23268
- n2 += e3;
23269
- else if ("object" == typeof e3)
23270
- if (Array.isArray(e3))
23271
- for (t2 = 0; t2 < e3.length; t2++)
23272
- e3[t2] && (f2 = r$1(e3[t2])) && (n2 && (n2 += " "), n2 += f2);
23273
- else
23274
- for (t2 in e3)
23275
- e3[t2] && (n2 && (n2 += " "), n2 += t2);
23276
- return n2;
23277
- }
23278
- function clsx() {
23279
- for (var e3, t2, f2 = 0, n2 = ""; f2 < arguments.length; )
23280
- (e3 = arguments[f2++]) && (t2 = r$1(e3)) && (n2 && (n2 += " "), n2 += t2);
23281
- return n2;
23282
- }
23283
23472
  var reactIs = reactIsExports$1;
23284
23473
  var REACT_STATICS = {
23285
23474
  childContextTypes: true,
@@ -29066,6 +29255,41 @@ const ascendingBisect = bisector$1(ascending$1);
29066
29255
  const bisectRight = ascendingBisect.right;
29067
29256
  bisector$1(number$2).center;
29068
29257
  const bisect = bisectRight;
29258
+ function extent$1(values2, valueof) {
29259
+ let min;
29260
+ let max;
29261
+ if (valueof === void 0) {
29262
+ for (const value of values2) {
29263
+ if (value != null) {
29264
+ if (min === void 0) {
29265
+ if (value >= value)
29266
+ min = max = value;
29267
+ } else {
29268
+ if (min > value)
29269
+ min = value;
29270
+ if (max < value)
29271
+ max = value;
29272
+ }
29273
+ }
29274
+ }
29275
+ } else {
29276
+ let index2 = -1;
29277
+ for (let value of values2) {
29278
+ if ((value = valueof(value, ++index2, values2)) != null) {
29279
+ if (min === void 0) {
29280
+ if (value >= value)
29281
+ min = max = value;
29282
+ } else {
29283
+ if (min > value)
29284
+ min = value;
29285
+ if (max < value)
29286
+ max = value;
29287
+ }
29288
+ }
29289
+ }
29290
+ }
29291
+ return [min, max];
29292
+ }
29069
29293
  var e10 = Math.sqrt(50), e5 = Math.sqrt(10), e2 = Math.sqrt(2);
29070
29294
  function ticks(start, stop, count2) {
29071
29295
  var reverse, i2 = -1, n2, ticks2, step;
@@ -29647,7 +29871,7 @@ var unit = [0, 1];
29647
29871
  function identity$7(x2) {
29648
29872
  return x2;
29649
29873
  }
29650
- function normalize$4(a2, b) {
29874
+ function normalize$5(a2, b) {
29651
29875
  return (b -= a2 = +a2) ? function(x2) {
29652
29876
  return (x2 - a2) / b;
29653
29877
  } : constants$3(isNaN(b) ? NaN : 0.5);
@@ -29663,9 +29887,9 @@ function clamper(a2, b) {
29663
29887
  function bimap(domain, range2, interpolate2) {
29664
29888
  var d0 = domain[0], d1 = domain[1], r0 = range2[0], r1 = range2[1];
29665
29889
  if (d1 < d0)
29666
- d0 = normalize$4(d1, d0), r0 = interpolate2(r1, r0);
29890
+ d0 = normalize$5(d1, d0), r0 = interpolate2(r1, r0);
29667
29891
  else
29668
- d0 = normalize$4(d0, d1), r0 = interpolate2(r0, r1);
29892
+ d0 = normalize$5(d0, d1), r0 = interpolate2(r0, r1);
29669
29893
  return function(x2) {
29670
29894
  return r0(d0(x2));
29671
29895
  };
@@ -29677,7 +29901,7 @@ function polymap(domain, range2, interpolate2) {
29677
29901
  range2 = range2.slice().reverse();
29678
29902
  }
29679
29903
  while (++i2 < j) {
29680
- d[i2] = normalize$4(domain[i2], domain[i2 + 1]);
29904
+ d[i2] = normalize$5(domain[i2], domain[i2 + 1]);
29681
29905
  r2[i2] = interpolate2(range2[i2], range2[i2 + 1]);
29682
29906
  }
29683
29907
  return function(x2) {
@@ -30266,14 +30490,12 @@ function getXlinkHref(cmap) {
30266
30490
  }
30267
30491
  const useStyles$1 = makeStyles(() => ({
30268
30492
  legend: {
30269
- position: "absolute",
30270
30493
  top: "2px",
30271
30494
  right: "2px",
30272
30495
  zIndex: "100",
30273
30496
  fontSize: "10px !important",
30274
- display: "flex",
30275
30497
  flexDirection: "column",
30276
- backgroundColor: "rgba(215, 215, 215, 0.2)",
30498
+ backgroundColor: "rgba(215, 215, 215, 0.7)",
30277
30499
  borderRadius: "4px",
30278
30500
  padding: "2px",
30279
30501
  lineHeight: "10px !important",
@@ -30282,26 +30504,55 @@ const useStyles$1 = makeStyles(() => ({
30282
30504
  left: 0,
30283
30505
  position: "relative"
30284
30506
  }
30507
+ },
30508
+ legendAbsolute: {
30509
+ position: "absolute",
30510
+ display: "inline-block"
30511
+ },
30512
+ legendRelative: {
30513
+ position: "relative",
30514
+ marginBottom: "2px",
30515
+ display: "block"
30516
+ },
30517
+ legendHighContrast: {
30518
+ backgroundColor: "rgba(215, 215, 215, 0.7)"
30519
+ },
30520
+ legendLowContrast: {
30521
+ backgroundColor: "rgba(215, 215, 215, 0.2)"
30522
+ },
30523
+ legendInvisible: {
30524
+ display: "none"
30285
30525
  }
30286
30526
  }));
30287
30527
  const titleHeight = 10;
30288
30528
  const rectHeight = 8;
30529
+ const rectMarginY = 2;
30530
+ const rectMarginX = 2;
30289
30531
  function Legend(props2) {
30290
- const { visible: visibleProp, obsType, featureValueType, considerSelections = true, obsColorEncoding, featureSelection, featureLabelsMap, featureValueColormap, featureValueColormapRange, extent: extent2, width = 100, height = 36, theme } = props2;
30532
+ 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;
30291
30533
  const svgRef = useRef();
30292
30534
  const classes = useStyles$1();
30293
30535
  const isDarkTheme = theme === "dark";
30294
- const visible = visibleProp && (!considerSelections || obsColorEncoding === "geneSelection" && featureSelection && Array.isArray(featureSelection) && featureSelection.length === 1);
30536
+ const isStaticColor = obsColorEncoding === "spatialChannelColor" || obsColorEncoding === "spatialLayerColor";
30537
+ const isSetColor = obsColorEncoding === "cellSetSelection";
30538
+ const layerColor = Array.isArray(spatialLayerColor) && spatialLayerColor.length === 3 ? spatialLayerColor : getDefaultColor(theme);
30539
+ const channelColor = Array.isArray(spatialChannelColor) && spatialChannelColor.length === 3 ? spatialChannelColor : getDefaultColor(theme);
30540
+ const staticColor = obsColorEncoding === "spatialChannelColor" ? channelColor : layerColor;
30541
+ 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);
30542
+ const levelZeroNames = useMemo(() => Array.from(new Set((obsSetSelection == null ? void 0 : obsSetSelection.map((setPath) => setPath[0])) || [])), [obsSetSelection]);
30543
+ const dynamicHeight = isSetColor ? levelZeroNames.length * titleHeight + (obsSetSelection == null ? void 0 : obsSetSelection.length) * (rectHeight + rectMarginY) : height;
30295
30544
  useEffect(() => {
30296
30545
  const domElement = svgRef.current;
30297
- const foregroundColor = isDarkTheme ? "white" : "black";
30546
+ const foregroundColor = highContrast ? "black" : isDarkTheme ? "white" : "black";
30298
30547
  const svg = select(domElement);
30299
30548
  svg.selectAll("g").remove();
30300
- svg.attr("width", width).attr("height", height);
30301
- const g2 = svg.append("g").attr("width", width).attr("height", height);
30302
- const xlinkHref = getXlinkHref(featureValueColormap);
30549
+ svg.attr("width", width).attr("height", dynamicHeight);
30550
+ const g2 = svg.append("g").attr("width", width).attr("height", dynamicHeight);
30303
30551
  if (!considerSelections || obsColorEncoding === "geneSelection") {
30304
- g2.append("image").attr("x", 0).attr("y", titleHeight).attr("width", width).attr("height", rectHeight).attr("preserveAspectRatio", "none").attr("href", xlinkHref);
30552
+ if (featureValueColormap) {
30553
+ const xlinkHref = getXlinkHref(featureValueColormap);
30554
+ g2.append("image").attr("x", 0).attr("y", titleHeight).attr("width", width).attr("height", rectHeight).attr("preserveAspectRatio", "none").attr("href", xlinkHref);
30555
+ }
30305
30556
  const [xMin, xMax] = extent2 || [0, 1];
30306
30557
  const [rMin, rMax] = featureValueColormapRange;
30307
30558
  const scaledDataExtent = [
@@ -30314,9 +30565,42 @@ function Legend(props2) {
30314
30565
  axisTicks.selectAll("text").style("fill", foregroundColor);
30315
30566
  axisTicks.selectAll("text").attr("text-anchor", (d, i2) => i2 === 0 ? "start" : "end");
30316
30567
  }
30317
- const featureLabel = featureSelection && featureSelection.length >= 1 ? (featureLabelsMap == null ? void 0 : featureLabelsMap.get(featureSelection[0])) || featureSelection[0] : null;
30318
- const legendLabel = considerSelections ? featureLabel || capitalize$1(featureValueType) : capitalize$1(featureValueType);
30319
- 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);
30568
+ if (isStaticColor) {
30569
+ g2.append("rect").attr("x", 0).attr("y", titleHeight).attr("width", width).attr("height", rectHeight).attr("fill", `rgb(${staticColor[0]},${staticColor[1]},${staticColor[2]})`);
30570
+ }
30571
+ if (isSetColor && obsSetSelection && obsSetColor) {
30572
+ const obsSetSelectionByLevelZero = {};
30573
+ obsSetSelection.forEach((setPath) => {
30574
+ const levelZeroName = setPath[0];
30575
+ if (!obsSetSelectionByLevelZero[levelZeroName]) {
30576
+ obsSetSelectionByLevelZero[levelZeroName] = [];
30577
+ }
30578
+ obsSetSelectionByLevelZero[levelZeroName].push(setPath);
30579
+ });
30580
+ let y2 = 0;
30581
+ Object.entries(obsSetSelectionByLevelZero).forEach(([levelZeroName, setPaths]) => {
30582
+ 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);
30583
+ y2 += titleHeight;
30584
+ setPaths.forEach((setPath) => {
30585
+ const setColor = obsSetColor.find((d) => isEqual$1(d.path, setPath)).color;
30586
+ g2.append("rect").attr("x", 0).attr("y", y2).attr("width", rectHeight).attr("height", rectHeight).attr("fill", `rgb(${setColor[0]},${setColor[1]},${setColor[2]})`);
30587
+ 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);
30588
+ y2 += rectHeight + rectMarginY;
30589
+ });
30590
+ });
30591
+ }
30592
+ const featureSelectionLabel = featureSelection && featureSelection.length >= 1 && !isStaticColor ? (featureLabelsMap == null ? void 0 : featureLabelsMap.get(featureSelection[0])) || featureSelection[0] : null;
30593
+ const obsLabel = capitalize$1(obsType);
30594
+ const featureLabel = considerSelections ? featureSelectionLabel || capitalize$1(featureValueType) : capitalize$1(featureValueType);
30595
+ const mainLabel = showObsLabel ? obsLabel : featureLabel;
30596
+ const subLabel = showObsLabel ? featureLabel : null;
30597
+ const hasSubLabel = subLabel !== null;
30598
+ if (!isSetColor) {
30599
+ 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);
30600
+ }
30601
+ if (hasSubLabel) {
30602
+ 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);
30603
+ }
30320
30604
  }, [
30321
30605
  width,
30322
30606
  height,
@@ -30329,13 +30613,51 @@ function Legend(props2) {
30329
30613
  isDarkTheme,
30330
30614
  featureValueType,
30331
30615
  extent2,
30332
- featureLabelsMap
30616
+ featureLabelsMap,
30617
+ spatialChannelColor,
30618
+ obsSetColor,
30619
+ obsSetSelection,
30620
+ isSetColor
30333
30621
  ]);
30334
- return jsxRuntimeExports.jsx("div", { className: classes.legend, style: { display: visible ? "inline-block" : "none" }, children: jsxRuntimeExports.jsx("svg", { ref: svgRef, style: {
30622
+ return jsxRuntimeExports.jsx("div", { className: clsx(classes.legend, {
30623
+ [classes.legendRelative]: positionRelative,
30624
+ [classes.legendAbsolute]: !positionRelative,
30625
+ [classes.legendHighContrast]: highContrast,
30626
+ [classes.legendLowContrast]: !highContrast,
30627
+ [classes.legendInvisible]: !visible
30628
+ }), children: jsxRuntimeExports.jsx("svg", { ref: svgRef, style: {
30335
30629
  width: `${width}px`,
30336
- height: `${height}px`
30630
+ height: `${dynamicHeight}px`
30337
30631
  } }) });
30338
30632
  }
30633
+ makeStyles(() => ({
30634
+ multiLegend: {
30635
+ position: "absolute",
30636
+ top: "0px",
30637
+ right: "0px"
30638
+ }
30639
+ }));
30640
+ makeStyles(() => ({
30641
+ channelNamesLegendContainer: {
30642
+ position: "absolute",
30643
+ bottom: "0px",
30644
+ left: "0px",
30645
+ paddingLeft: "10px",
30646
+ paddingBottom: "10px"
30647
+ },
30648
+ channelNamesLegendLayer: {
30649
+ display: "flex"
30650
+ },
30651
+ channelNamesRow: {
30652
+ flexDirection: "column"
30653
+ },
30654
+ channelNamesCol: {
30655
+ flexDirection: "row"
30656
+ },
30657
+ channelNameText: {
30658
+ marginRight: "10px"
30659
+ }
30660
+ }));
30339
30661
  function assert$c(condition, message) {
30340
30662
  if (!condition) {
30341
30663
  throw new Error(message || "loader assertion failed.");
@@ -31693,17 +32015,17 @@ let COLOR;
31693
32015
  COLOR2[COLOR2["BRIGHT_CYAN"] = 96] = "BRIGHT_CYAN";
31694
32016
  COLOR2[COLOR2["BRIGHT_WHITE"] = 97] = "BRIGHT_WHITE";
31695
32017
  })(COLOR || (COLOR = {}));
31696
- function getColor(color2) {
32018
+ function getColor$1(color2) {
31697
32019
  return typeof color2 === "string" ? COLOR[color2.toUpperCase()] || COLOR.WHITE : color2;
31698
32020
  }
31699
32021
  function addColor(string2, color2, background) {
31700
32022
  if (!isBrowser$1 && typeof string2 === "string") {
31701
32023
  if (color2) {
31702
- color2 = getColor(color2);
32024
+ color2 = getColor$1(color2);
31703
32025
  string2 = "\x1B[".concat(color2, "m").concat(string2, "\x1B[39m");
31704
32026
  }
31705
32027
  if (background) {
31706
- color2 = getColor(background);
32028
+ color2 = getColor$1(background);
31707
32029
  string2 = "\x1B[".concat(background + 10, "m").concat(string2, "\x1B[49m");
31708
32030
  }
31709
32031
  }
@@ -41727,7 +42049,7 @@ function negate(out, a2) {
41727
42049
  out[2] = -a2[2];
41728
42050
  return out;
41729
42051
  }
41730
- function normalize$3(out, a2) {
42052
+ function normalize$4(out, a2) {
41731
42053
  var x2 = a2[0];
41732
42054
  var y2 = a2[1];
41733
42055
  var z2 = a2[2];
@@ -43036,7 +43358,7 @@ function squaredLength$1(a2) {
43036
43358
  var w2 = a2[3];
43037
43359
  return x2 * x2 + y2 * y2 + z2 * z2 + w2 * w2;
43038
43360
  }
43039
- function normalize$2(out, a2) {
43361
+ function normalize$3(out, a2) {
43040
43362
  var x2 = a2[0];
43041
43363
  var y2 = a2[1];
43042
43364
  var z2 = a2[2];
@@ -43673,7 +43995,7 @@ var dot$1 = dot$2;
43673
43995
  var lerp$1 = lerp$2;
43674
43996
  var length$2 = length$3;
43675
43997
  var squaredLength = squaredLength$1;
43676
- var normalize$1 = normalize$2;
43998
+ var normalize$2 = normalize$3;
43677
43999
  var rotationTo = function() {
43678
44000
  var tmpvec3 = create$3();
43679
44001
  var xUnitVec3 = fromValues(1, 0, 0);
@@ -43684,7 +44006,7 @@ var rotationTo = function() {
43684
44006
  cross(tmpvec3, xUnitVec3, a2);
43685
44007
  if (len(tmpvec3) < 1e-6)
43686
44008
  cross(tmpvec3, yUnitVec3, a2);
43687
- normalize$3(tmpvec3, tmpvec3);
44009
+ normalize$4(tmpvec3, tmpvec3);
43688
44010
  setAxisAngle(out, tmpvec3, Math.PI);
43689
44011
  return out;
43690
44012
  } else if (dot2 > 0.999999) {
@@ -43699,7 +44021,7 @@ var rotationTo = function() {
43699
44021
  out[1] = tmpvec3[1];
43700
44022
  out[2] = tmpvec3[2];
43701
44023
  out[3] = 1 + dot2;
43702
- return normalize$1(out, out);
44024
+ return normalize$2(out, out);
43703
44025
  }
43704
44026
  };
43705
44027
  }();
@@ -43725,7 +44047,7 @@ var rotationTo = function() {
43725
44047
  matr[2] = -view[0];
43726
44048
  matr[5] = -view[1];
43727
44049
  matr[8] = -view[2];
43728
- return normalize$1(out, fromMat3(out, matr));
44050
+ return normalize$2(out, fromMat3(out, matr));
43729
44051
  };
43730
44052
  })();
43731
44053
  const IDENTITY_QUATERNION = [0, 0, 0, 1];
@@ -65414,7 +65736,7 @@ function copyFlatRing(target, targetStartIndex, positions, size, srcStartIndex =
65414
65736
  modifyPolygonWindingDirection(target, windingDirection, windingOptions);
65415
65737
  return targetIndex;
65416
65738
  }
65417
- function normalize(polygon2, positionSize) {
65739
+ function normalize$1(polygon2, positionSize) {
65418
65740
  validate(polygon2);
65419
65741
  const positions = [];
65420
65742
  const holeIndices = [];
@@ -65520,7 +65842,7 @@ class PolygonTesselator extends Tesselator {
65520
65842
  }
65521
65843
  normalizeGeometry(polygon2) {
65522
65844
  if (this.normalize) {
65523
- const normalizedPolygon = normalize(polygon2, this.positionSize);
65845
+ const normalizedPolygon = normalize$1(polygon2, this.positionSize);
65524
65846
  if (this.opts.resolution) {
65525
65847
  return cutPolygonByGrid(getPositions(normalizedPolygon), getHoleIndices(normalizedPolygon), {
65526
65848
  size: this.positionSize,
@@ -66142,7 +66464,7 @@ class PolygonLayer extends CompositeLayer {
66142
66464
  objectInfo.index++;
66143
66465
  let polygon2 = getPolygon(object2, objectInfo);
66144
66466
  if (_normalize) {
66145
- polygon2 = normalize(polygon2, positionSize);
66467
+ polygon2 = normalize$1(polygon2, positionSize);
66146
66468
  }
66147
66469
  const {
66148
66470
  holeIndices
@@ -131001,28 +131323,38 @@ const PASS_THROUGH_PROPS = [
131001
131323
  ];
131002
131324
  class SelectionLayer extends CompositeLayer {
131003
131325
  _selectPolygonObjects(coordinates2) {
131004
- const { onSelect, getCellCoords, cellsQuadTree, flipY } = this.props;
131326
+ const { flipY, obsLayers } = this.props;
131005
131327
  const flippedCoordinates = flipY ? coordinates2.map((poly) => poly.map((p) => [p[0], -p[1]])) : coordinates2;
131006
131328
  const selectedPolygon = polygon(flippedCoordinates);
131007
- const pickingInfos = [];
131008
- cellsQuadTree.visit((node, x02, y02, x12, y12) => {
131009
- const nodePoints = [[[x02, y02], [x12, y02], [x12, y12], [x02, y12], [x02, y02]]];
131010
- const nodePolygon = polygon(nodePoints);
131011
- const nodePolygonContainsSelectedPolygon = booleanContains(nodePolygon, selectedPolygon);
131012
- const nodePolygonWithinSelectedPolygon = booleanWithin(nodePolygon, selectedPolygon);
131013
- const nodePolygonOverlapsSelectedPolgyon = booleanOverlap(nodePolygon, selectedPolygon);
131014
- if (!nodePolygonContainsSelectedPolygon && !nodePolygonWithinSelectedPolygon && !nodePolygonOverlapsSelectedPolgyon) {
131015
- return true;
131016
- }
131017
- if (node.data && booleanPointInPolygon$1(point([].slice.call(getCellCoords(node.data))), selectedPolygon)) {
131018
- pickingInfos.push(node.data);
131019
- }
131020
- return false;
131329
+ obsLayers.forEach((obsLayer) => {
131330
+ const { getObsCoords, obsQuadTree, obsIndex, onSelect: layerOnSelect } = obsLayer;
131331
+ const pickingInfos = [];
131332
+ obsQuadTree == null ? void 0 : obsQuadTree.visit((node, x02, y02, x12, y12) => {
131333
+ const nodePoints = [[[x02, y02], [x12, y02], [x12, y12], [x02, y12], [x02, y02]]];
131334
+ const nodePolygon = polygon(nodePoints);
131335
+ const nodePolygonContainsSelectedPolygon = booleanContains(nodePolygon, selectedPolygon);
131336
+ const nodePolygonWithinSelectedPolygon = booleanWithin(nodePolygon, selectedPolygon);
131337
+ const nodePolygonOverlapsSelectedPolgyon = booleanOverlap(nodePolygon, selectedPolygon);
131338
+ if (!nodePolygonContainsSelectedPolygon && !nodePolygonWithinSelectedPolygon && !nodePolygonOverlapsSelectedPolgyon) {
131339
+ return true;
131340
+ }
131341
+ if (node.data && booleanPointInPolygon$1(point([].slice.call(getObsCoords(node.data))), selectedPolygon)) {
131342
+ pickingInfos.push(node.data);
131343
+ }
131344
+ return false;
131345
+ });
131346
+ const pickingIds = pickingInfos.map((obsI) => obsIndex[obsI]);
131347
+ layerOnSelect(pickingIds);
131348
+ });
131349
+ }
131350
+ _selectEmpty() {
131351
+ const { obsLayers } = this.props;
131352
+ obsLayers.forEach((obsLayer) => {
131353
+ const { onSelect: layerOnSelect } = obsLayer;
131354
+ layerOnSelect([]);
131021
131355
  });
131022
- onSelect({ pickingInfos });
131023
131356
  }
131024
131357
  renderLayers() {
131025
- const { onSelect } = this.props;
131026
131358
  const mode = MODE_MAP[this.props.selectionType] || distEs6.ViewMode;
131027
131359
  const inheritedProps = {};
131028
131360
  PASS_THROUGH_PROPS.forEach((p) => {
@@ -131044,7 +131376,7 @@ class SelectionLayer extends CompositeLayer {
131044
131376
  const { coordinates: coordinates2 } = updatedData.features[0].geometry;
131045
131377
  this._selectPolygonObjects(coordinates2);
131046
131378
  } else if (editType === EDIT_TYPE_CLEAR) {
131047
- onSelect({ pickingInfos: [] });
131379
+ this._selectEmpty();
131048
131380
  }
131049
131381
  },
131050
131382
  _subLayerProps: {
@@ -132189,16 +132521,16 @@ function addDecoder(cases, importFn) {
132189
132521
  }
132190
132522
  cases.forEach((c) => registry$1.set(c, importFn));
132191
132523
  }
132192
- addDecoder([void 0, 1], () => import("./raw-3b0ca314.js").then((m) => m.default));
132193
- addDecoder(5, () => import("./lzw-14c81650.js").then((m) => m.default));
132524
+ addDecoder([void 0, 1], () => import("./raw-67eae85c.js").then((m) => m.default));
132525
+ addDecoder(5, () => import("./lzw-6f9c40ad.js").then((m) => m.default));
132194
132526
  addDecoder(6, () => {
132195
132527
  throw new Error("old style JPEG compression is not supported.");
132196
132528
  });
132197
- addDecoder(7, () => import("./jpeg-afe48021.js").then((m) => m.default));
132198
- addDecoder([8, 32946], () => import("./deflate-4947343d.js").then((m) => m.default));
132199
- addDecoder(32773, () => import("./packbits-e4daad19.js").then((m) => m.default));
132200
- addDecoder(34887, () => import("./lerc-ff568b35.js").then((m) => m.default));
132201
- addDecoder(50001, () => import("./webimage-df0b6c92.js").then((m) => m.default));
132529
+ addDecoder(7, () => import("./jpeg-aa330cdf.js").then((m) => m.default));
132530
+ addDecoder([8, 32946], () => import("./deflate-6b41b0a6.js").then((m) => m.default));
132531
+ addDecoder(32773, () => import("./packbits-c64561b9.js").then((m) => m.default));
132532
+ addDecoder(34887, () => import("./lerc-e665fe72.js").then((m) => m.default));
132533
+ addDecoder(50001, () => import("./webimage-8d441440.js").then((m) => m.default));
132202
132534
  function decodeRowAcc(row, stride) {
132203
132535
  let length2 = row.length - stride;
132204
132536
  let offset5 = 0;
@@ -138991,7 +139323,7 @@ const SIGNAL_ABORTED = "__vivSignalAborted";
138991
139323
  addDecoder(5, () => LZWDecoder);
138992
139324
  const MAX_COLOR_INTENSITY = 255;
138993
139325
  const DEFAULT_COLOR_OFF = [0, 0, 0];
138994
- const MAX_CHANNELS = 6;
139326
+ const MAX_CHANNELS$1 = 6;
138995
139327
  const DEFAULT_FONT_FAMILY = "-apple-system, 'Helvetica Neue', Arial, sans-serif";
138996
139328
  const DTYPE_VALUES = {
138997
139329
  Uint8: {
@@ -140507,7 +140839,7 @@ const AdditiveColormapExtension = class extends LayerExtension {
140507
140839
  };
140508
140840
  AdditiveColormapExtension.extensionName = "AdditiveColormapExtension";
140509
140841
  AdditiveColormapExtension.defaultProps = defaultProps$4$1;
140510
- const fs$1$1 = `uniform vec3 transparentColor;
140842
+ const fs$1$2 = `uniform vec3 transparentColor;
140511
140843
  uniform bool useTransparentColor;
140512
140844
  uniform float opacity;
140513
140845
 
@@ -140534,12 +140866,12 @@ rgba = apply_opacity(rgb);
140534
140866
  `;
140535
140867
  const colorPalette = {
140536
140868
  name: "color-palette-module",
140537
- fs: fs$1$1,
140869
+ fs: fs$1$2,
140538
140870
  inject: {
140539
140871
  "fs:DECKGL_MUTATE_COLOR": DECKGL_MUTATE_COLOR
140540
140872
  }
140541
140873
  };
140542
- function padWithDefault$2(arr, defaultValue2, padWidth) {
140874
+ function padWithDefault$3(arr, defaultValue2, padWidth) {
140543
140875
  for (let i2 = 0; i2 < padWidth; i2 += 1) {
140544
140876
  arr.push(defaultValue2);
140545
140877
  }
@@ -140565,8 +140897,8 @@ function padColors({ colors, channelsVisible }) {
140565
140897
  const newColors = colors.map(
140566
140898
  (color2, i2) => channelsVisible[i2] ? color2.map((c) => c / MAX_COLOR_INTENSITY) : DEFAULT_COLOR_OFF
140567
140899
  );
140568
- const padSize = MAX_CHANNELS - newColors.length;
140569
- const paddedColors = padWithDefault$2(
140900
+ const padSize = MAX_CHANNELS$1 - newColors.length;
140901
+ const paddedColors = padWithDefault$3(
140570
140902
  newColors,
140571
140903
  DEFAULT_COLOR_OFF,
140572
140904
  padSize
@@ -140810,7 +141142,7 @@ vec4 colormap(float intensity, float opacity) {
140810
141142
  fs: fs2
140811
141143
  };
140812
141144
  }
140813
- const defaultProps$1$1 = {
141145
+ const defaultProps$1$2 = {
140814
141146
  colormap: { type: "string", value: "viridis", compare: true }
140815
141147
  };
140816
141148
  const BaseExtension$1 = class extends LayerExtension {
@@ -140820,7 +141152,7 @@ const BaseExtension$1 = class extends LayerExtension {
140820
141152
  }
140821
141153
  getShaders() {
140822
141154
  var _a2;
140823
- const name2 = ((_a2 = this == null ? void 0 : this.props) == null ? void 0 : _a2.colormap) || defaultProps$1$1.colormap.value;
141155
+ const name2 = ((_a2 = this == null ? void 0 : this.props) == null ? void 0 : _a2.colormap) || defaultProps$1$2.colormap.value;
140824
141156
  const apply_cmap = cmaps[name2];
140825
141157
  return {
140826
141158
  ...super.getShaders(),
@@ -140839,7 +141171,7 @@ const BaseExtension$1 = class extends LayerExtension {
140839
141171
  }
140840
141172
  };
140841
141173
  BaseExtension$1.extensionName = "BaseExtension";
140842
- BaseExtension$1.defaultProps = defaultProps$1$1;
141174
+ BaseExtension$1.defaultProps = defaultProps$1$2;
140843
141175
  const _BEFORE_RENDER$5 = "";
140844
141176
  const _RENDER$5 = ` float intensityArray[6] = float[6](intensityValue0, intensityValue1, intensityValue2, intensityValue3, intensityValue4, intensityValue5);
140845
141177
  float total = 0.0;
@@ -141038,7 +141370,7 @@ const channels = {
141038
141370
  function range(len2) {
141039
141371
  return [...Array(len2).keys()];
141040
141372
  }
141041
- function padWithDefault$1(arr, defaultValue2, padWidth) {
141373
+ function padWithDefault$2(arr, defaultValue2, padWidth) {
141042
141374
  for (let i2 = 0; i2 < padWidth; i2 += 1) {
141043
141375
  arr.push(defaultValue2);
141044
141376
  }
@@ -141062,13 +141394,13 @@ function padContrastLimits({
141062
141394
  const newContrastLimits = contrastLimits.map(
141063
141395
  (slider, i2) => channelsVisible[i2] ? slider : [maxSliderValue, maxSliderValue]
141064
141396
  );
141065
- const padSize = MAX_CHANNELS - newContrastLimits.length;
141397
+ const padSize = MAX_CHANNELS$1 - newContrastLimits.length;
141066
141398
  if (padSize < 0) {
141067
141399
  throw Error(
141068
141400
  `${newContrastLimits.lengths} channels passed in, but only 6 are allowed.`
141069
141401
  );
141070
141402
  }
141071
- const paddedContrastLimits = padWithDefault$1(
141403
+ const paddedContrastLimits = padWithDefault$2(
141072
141404
  newContrastLimits,
141073
141405
  [maxSliderValue, maxSliderValue],
141074
141406
  padSize
@@ -141098,7 +141430,7 @@ function makeBoundingBox(viewState) {
141098
141430
  viewport.unproject([0, viewport.height])
141099
141431
  ];
141100
141432
  }
141101
- const fs$1 = `#define SHADER_NAME xr-layer-fragment-shader
141433
+ const fs$1$1 = `#define SHADER_NAME xr-layer-fragment-shader
141102
141434
 
141103
141435
  precision highp float;
141104
141436
  precision highp int;
@@ -141139,7 +141471,7 @@ void main() {
141139
141471
  DECKGL_FILTER_COLOR(gl_FragColor, geometry);
141140
141472
  }
141141
141473
  `;
141142
- const vs$1 = `#define SHADER_NAME xr-layer-vertex-shader
141474
+ const vs$1$1 = `#define SHADER_NAME xr-layer-vertex-shader
141143
141475
 
141144
141476
  attribute vec2 texCoords;
141145
141477
  attribute vec3 positions;
@@ -141158,7 +141490,7 @@ void main(void) {
141158
141490
  DECKGL_FILTER_COLOR(color, geometry);
141159
141491
  }
141160
141492
  `;
141161
- const coreShaderModule = { fs: fs$1, vs: vs$1 };
141493
+ const coreShaderModule = { fs: fs$1$1, vs: vs$1$1 };
141162
141494
  function validateWebGL2Filter(gl, interpolation) {
141163
141495
  const canShowFloat = hasFeature(gl, FEATURES$1.TEXTURE_FLOAT);
141164
141496
  const canShowLinear = hasFeature(gl, FEATURES$1.TEXTURE_FILTER_LINEAR_FLOAT);
@@ -142249,7 +142581,7 @@ const CUBE_STRIP = [
142249
142581
  0
142250
142582
  ];
142251
142583
  const NUM_PLANES_DEFAULT = 1;
142252
- const defaultProps$1 = {
142584
+ const defaultProps$1$1 = {
142253
142585
  pickable: false,
142254
142586
  coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
142255
142587
  channelData: { type: "object", value: {}, compare: true },
@@ -142391,7 +142723,7 @@ const XR3DLayer = class extends Layer {
142391
142723
  });
142392
142724
  const invertedScaleMatrix = scaleMatrix.clone().invert();
142393
142725
  const invertedResolutionMatrix = resolutionMatrix.clone().invert();
142394
- const paddedClippingPlanes = padWithDefault$1(
142726
+ const paddedClippingPlanes = padWithDefault$2(
142395
142727
  clippingPlanes.map(
142396
142728
  (p) => p.clone().transform(invertedScaleMatrix).transform(invertedResolutionMatrix)
142397
142729
  ),
@@ -142481,7 +142813,7 @@ const XR3DLayer = class extends Layer {
142481
142813
  }
142482
142814
  };
142483
142815
  XR3DLayer.layerName = "XR3DLayer";
142484
- XR3DLayer.defaultProps = defaultProps$1;
142816
+ XR3DLayer.defaultProps = defaultProps$1$1;
142485
142817
  async function getVolume({
142486
142818
  source,
142487
142819
  selection,
@@ -142703,7 +143035,7 @@ const VolumeLayer = class extends CompositeLayer {
142703
143035
  };
142704
143036
  VolumeLayer.layerName = "VolumeLayer";
142705
143037
  VolumeLayer.defaultProps = defaultProps$9;
142706
- const vs = `
143038
+ const vs$1 = `
142707
143039
  #define SHADER_NAME bitmask-layer-vertex-shader
142708
143040
 
142709
143041
  attribute vec2 texCoords;
@@ -142724,7 +143056,7 @@ void main(void) {
142724
143056
  DECKGL_FILTER_COLOR(color, geometry);
142725
143057
  }
142726
143058
  `;
142727
- const fs = `
143059
+ const fs$1 = `
142728
143060
  #define SHADER_NAME bitmask-layer-fragment-shader
142729
143061
  precision highp float;
142730
143062
 
@@ -142792,14 +143124,14 @@ void main() {
142792
143124
  DECKGL_FILTER_COLOR(gl_FragColor, geometry);
142793
143125
  }
142794
143126
  `;
142795
- function padWithDefault(arr, defaultValue2, padWidth) {
143127
+ function padWithDefault$1(arr, defaultValue2, padWidth) {
142796
143128
  const newArr = [...arr];
142797
143129
  for (let i2 = 0; i2 < padWidth; i2 += 1) {
142798
143130
  newArr.push(defaultValue2);
142799
143131
  }
142800
143132
  return newArr;
142801
143133
  }
142802
- const defaultProps = {
143134
+ const defaultProps$1 = {
142803
143135
  hoveredCell: { type: "number", value: null, compare: true },
142804
143136
  // We do not want to deep-compare cellColorData,
142805
143137
  // as it is potentially a TypedArray with millions of elements.
@@ -142811,13 +143143,13 @@ const defaultProps = {
142811
143143
  // Same as with cellColorData, we do not want to deep-compare expressionData.
142812
143144
  expressionData: { type: "object", value: null, compare: 0 }
142813
143145
  };
142814
- class BitmaskLayer extends XRLayer {
143146
+ let BitmaskLayer$1 = class BitmaskLayer extends XRLayer {
142815
143147
  // eslint-disable-next-line class-methods-use-this
142816
143148
  getShaders() {
142817
143149
  const { colormap } = this.props;
142818
143150
  return {
142819
- fs,
142820
- vs,
143151
+ fs: fs$1,
143152
+ vs: vs$1,
142821
143153
  modules: [project32, picking],
142822
143154
  defines: {
142823
143155
  [COLORMAP_SHADER_PLACEHOLDER]: GLSL_COLORMAPS.includes(colormap) ? colormap : GLSL_COLORMAP_DEFAULT
@@ -142877,7 +143209,7 @@ class BitmaskLayer extends XRLayer {
142877
143209
  expressionTex,
142878
143210
  colorTexHeight: colorTex.height,
142879
143211
  colorTexWidth: colorTex.width,
142880
- channelsVisible: padWithDefault(
143212
+ channelsVisible: padWithDefault$1(
142881
143213
  channelsVisible,
142882
143214
  false,
142883
143215
  // There are six texture entries on the shaders
@@ -142914,9 +143246,564 @@ class BitmaskLayer extends XRLayer {
142914
143246
  type: GL$1.FLOAT
142915
143247
  });
142916
143248
  }
143249
+ };
143250
+ BitmaskLayer$1.layerName = "BitmaskLayer";
143251
+ BitmaskLayer$1.defaultProps = defaultProps$1;
143252
+ const vs = `
143253
+ #define SHADER_NAME bitmask-layer-vertex-shader
143254
+
143255
+ attribute vec2 texCoords;
143256
+ attribute vec3 positions;
143257
+ attribute vec3 positions64Low;
143258
+ attribute vec3 instancePickingColors;
143259
+
143260
+ varying vec2 vTexCoord;
143261
+
143262
+ void main(void) {
143263
+ geometry.worldPosition = positions;
143264
+ geometry.uv = texCoords;
143265
+ geometry.pickingColor = instancePickingColors;
143266
+ gl_Position = project_position_to_clipspace(positions, positions64Low, vec3(0.0), geometry.position);
143267
+ DECKGL_FILTER_GL_POSITION(gl_Position, geometry);
143268
+ vTexCoord = texCoords;
143269
+ vec4 color = vec4(0.0);
143270
+ DECKGL_FILTER_COLOR(color, geometry);
143271
+ }
143272
+ `;
143273
+ const fs = `
143274
+ #define SHADER_NAME bitmask-layer-fragment-shader
143275
+ precision highp float;
143276
+
143277
+ ${colormaps}
143278
+
143279
+ // Note: can have a maximum of 16 textures in most browsers
143280
+ // Reference: https://webglreport.com/
143281
+
143282
+ // Data (mask) texture
143283
+ uniform sampler2D channel0;
143284
+ uniform sampler2D channel1;
143285
+ uniform sampler2D channel2;
143286
+ uniform sampler2D channel3;
143287
+ uniform sampler2D channel4;
143288
+ uniform sampler2D channel5;
143289
+ uniform sampler2D channel6;
143290
+
143291
+ // Color texture
143292
+ uniform float hovered;
143293
+
143294
+ // Channel-specific properties
143295
+ uniform bool channelsVisible[7];
143296
+ uniform float channelOpacities[7];
143297
+ uniform bool channelIsStaticColorMode[7]; // TODO: should this be a single float?
143298
+ uniform bool channelIsSetColorMode[7]; // TODO: should this be a single float?
143299
+
143300
+ // TODO: can array of tuples/vec2 be used?
143301
+ uniform float channelColormapRangeStarts[7];
143302
+ uniform float channelColormapRangeEnds[7];
143303
+
143304
+ uniform float multiFeatureTexSize;
143305
+
143306
+ // Use one expressionTex for all channels, using an offset mechanism.
143307
+ uniform sampler2D valueTex;
143308
+ uniform float valueTexOffsets[7];
143309
+ uniform float valueTexHeight;
143310
+
143311
+ // Textures for set colors, using the same offset mechanism.
143312
+ uniform sampler2D colorTex;
143313
+ uniform float colorTexOffsets[7];
143314
+ uniform float colorTexHeight;
143315
+
143316
+
143317
+ // Static colors
143318
+ // TODO: For some reason I cannot use uniform vec3 colors[7]; and i cannot figure out why.
143319
+ uniform vec3 color0;
143320
+ uniform vec3 color1;
143321
+ uniform vec3 color2;
143322
+ uniform vec3 color3;
143323
+ uniform vec3 color4;
143324
+ uniform vec3 color5;
143325
+ uniform vec3 color6;
143326
+
143327
+ // Info for edge-only mode
143328
+ uniform float scaleFactor;
143329
+ uniform bool channelsFilled[7];
143330
+ uniform float channelStrokeWidths[7];
143331
+
143332
+ // opacity
143333
+ uniform float opacity;
143334
+
143335
+ varying vec2 vTexCoord;
143336
+
143337
+ vec3 sampleAndGetData(sampler2D dataTex, vec2 coord, bool isFilled, float strokeWidth, bool isOn) {
143338
+ float sampledData = texture(dataTex, coord).r;
143339
+ float clampedSampledData = max(0., min(sampledData, 1.));
143340
+
143341
+ bool isEdge = true;
143342
+
143343
+ if(!isFilled) {
143344
+ vec2 uTextureSize = vec2(2048.0, 2048.0);
143345
+ vec2 onePixel = vec2(1.0, 1.0) / uTextureSize;
143346
+
143347
+ // Vary the edgeSize based on user-defined stroke width.
143348
+ float edgeSize = 150.0 * strokeWidth * scaleFactor;
143349
+
143350
+ float pixN = texture(dataTex, coord + vec2(0.0, onePixel.y * edgeSize)).r;
143351
+ float pixS = texture(dataTex, coord - vec2(0.0, onePixel.y * edgeSize)).r;
143352
+ float pixW = texture(dataTex, coord + vec2(onePixel.x * edgeSize, 0.0)).r;
143353
+ float pixE = texture(dataTex, coord - vec2(onePixel.x * edgeSize, 0.0)).r;
143354
+
143355
+ float pixNW = texture(dataTex, coord + vec2(onePixel.y * edgeSize, onePixel.y * edgeSize)).r;
143356
+ float pixNE = texture(dataTex, coord + vec2(-1.0 * onePixel.x * edgeSize, onePixel.y * edgeSize)).r;
143357
+ float pixSW = texture(dataTex, coord - vec2(onePixel.x * edgeSize, onePixel.y * edgeSize)).r;
143358
+ float pixSE = texture(dataTex, coord - vec2(-1.0 * onePixel.x * edgeSize, onePixel.y * edgeSize)).r;
143359
+
143360
+ isEdge = (pixN != sampledData || pixS != sampledData || pixW != sampledData || pixE != sampledData || pixNW != sampledData || pixNE != sampledData || pixSW != sampledData || pixSE != sampledData);
143361
+ }
143362
+ // Return a tuple of (sampledData, isEdge)
143363
+ return vec3(clampedSampledData * float(isOn), sampledData, float(isEdge));
143364
+ }
143365
+
143366
+ vec4 dataToColor(vec3 sampledDataAndIsEdge, bool isStaticColorMode, vec3 channelColor, float channelOpacity, float valueOffset, float rangeStart, float rangeEnd, bool isSetColorMode, float setColorOffset) {
143367
+ float clampedSampledDataAndIsOn = sampledDataAndIsEdge.x;
143368
+ float sampledData = sampledDataAndIsEdge.y;
143369
+ float isEdge = sampledDataAndIsEdge.z;
143370
+
143371
+
143372
+ vec4 hoveredColor = float(sampledData == hovered && sampledData > 0. && hovered > 0.) * vec4(0., 0., 1., 1.);
143373
+
143374
+ // 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,
143375
+ // 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).
143376
+ float offsetSampledData = sampledData + valueOffset - 1.0;
143377
+ vec2 colorTexCoord = vec2(mod(offsetSampledData, multiFeatureTexSize) / multiFeatureTexSize, floor(offsetSampledData / multiFeatureTexSize) / (valueTexHeight - 1.));
143378
+
143379
+ // Get expression value
143380
+ float expressionValue = texture(valueTex, colorTexCoord).r / 255.;
143381
+ float scaledExpressionValue = (expressionValue - rangeStart) / max(0.005, (rangeEnd - rangeStart));
143382
+
143383
+
143384
+ // Get set color index value
143385
+ vec2 setIndicesTexCoord = vec2(mod(offsetSampledData, multiFeatureTexSize) / multiFeatureTexSize, floor(offsetSampledData / multiFeatureTexSize) / (valueTexHeight - 1.));
143386
+ float setColorIndex = texture(valueTex, setIndicesTexCoord).r;
143387
+
143388
+ // Initialize to the default "null" color.
143389
+ vec3 setColor = vec3(200. / 255., 200. / 255., 200. / 255.);
143390
+ if(setColorIndex != 0.) {
143391
+ // Subtract one from setColorIndex because we have already checked for the "null" value.
143392
+ setColorIndex = setColorIndex - 1.;
143393
+
143394
+ float setColorOffsetR = (setColorIndex + setColorOffset) * 3.0 + 0.0;
143395
+ vec2 setColorTexCoordR = vec2(mod(setColorOffsetR, multiFeatureTexSize) / multiFeatureTexSize, floor(setColorOffsetR / multiFeatureTexSize) / (colorTexHeight - 1.));
143396
+ float setColorR = texture(colorTex, setColorTexCoordR).r / 255.;
143397
+
143398
+ float setColorOffsetG = (setColorIndex + setColorOffset) * 3.0 + 1.0;
143399
+ vec2 setColorTexCoordG = vec2(mod(setColorOffsetG, multiFeatureTexSize) / multiFeatureTexSize, floor(setColorOffsetG / multiFeatureTexSize) / (colorTexHeight - 1.));
143400
+ float setColorG = texture(colorTex, setColorTexCoordG).r / 255.;
143401
+
143402
+ float setColorOffsetB = (setColorIndex + setColorOffset) * 3.0 + 2.0;
143403
+ vec2 setColorTexCoordB = vec2(mod(setColorOffsetB, multiFeatureTexSize) / multiFeatureTexSize, floor(setColorOffsetB / multiFeatureTexSize) / (colorTexHeight - 1.));
143404
+ float setColorB = texture(colorTex, setColorTexCoordB).r / 255.;
143405
+
143406
+ setColor = vec3(setColorR, setColorG, setColorB);
143407
+ }
143408
+
143409
+
143410
+ 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);
143411
+ // Only return a color if the data is non-zero.
143412
+
143413
+ return clampedSampledDataAndIsOn * isEdge * sampledColor;
143414
+ }
143415
+
143416
+ void main() {
143417
+
143418
+ // Get the color and alpha value for each channel.
143419
+ vec3 dat0 = sampleAndGetData(channel0, vTexCoord, channelsFilled[0], channelStrokeWidths[0], channelsVisible[0]);
143420
+ vec3 dat1 = sampleAndGetData(channel1, vTexCoord, channelsFilled[1], channelStrokeWidths[1], channelsVisible[1]);
143421
+ vec3 dat2 = sampleAndGetData(channel2, vTexCoord, channelsFilled[2], channelStrokeWidths[2], channelsVisible[2]);
143422
+ vec3 dat3 = sampleAndGetData(channel3, vTexCoord, channelsFilled[3], channelStrokeWidths[3], channelsVisible[3]);
143423
+ vec3 dat4 = sampleAndGetData(channel4, vTexCoord, channelsFilled[4], channelStrokeWidths[4], channelsVisible[4]);
143424
+ vec3 dat5 = sampleAndGetData(channel5, vTexCoord, channelsFilled[5], channelStrokeWidths[5], channelsVisible[5]);
143425
+ vec3 dat6 = sampleAndGetData(channel6, vTexCoord, channelsFilled[6], channelStrokeWidths[6], channelsVisible[6]);
143426
+
143427
+ vec4 val0 = dataToColor(dat0, channelIsStaticColorMode[0], color0, channelOpacities[0], valueTexOffsets[0], channelColormapRangeStarts[0], channelColormapRangeEnds[0], channelIsSetColorMode[0], colorTexOffsets[0]);
143428
+ vec4 val1 = dataToColor(dat1, channelIsStaticColorMode[1], color1, channelOpacities[1], valueTexOffsets[1], channelColormapRangeStarts[1], channelColormapRangeEnds[1], channelIsSetColorMode[1], colorTexOffsets[1]);
143429
+ vec4 val2 = dataToColor(dat2, channelIsStaticColorMode[2], color2, channelOpacities[2], valueTexOffsets[2], channelColormapRangeStarts[2], channelColormapRangeEnds[2], channelIsSetColorMode[2], colorTexOffsets[2]);
143430
+ vec4 val3 = dataToColor(dat3, channelIsStaticColorMode[3], color3, channelOpacities[3], valueTexOffsets[3], channelColormapRangeStarts[3], channelColormapRangeEnds[3], channelIsSetColorMode[3], colorTexOffsets[3]);
143431
+ vec4 val4 = dataToColor(dat4, channelIsStaticColorMode[4], color4, channelOpacities[4], valueTexOffsets[4], channelColormapRangeStarts[4], channelColormapRangeEnds[4], channelIsSetColorMode[4], colorTexOffsets[4]);
143432
+ vec4 val5 = dataToColor(dat5, channelIsStaticColorMode[5], color5, channelOpacities[5], valueTexOffsets[5], channelColormapRangeStarts[5], channelColormapRangeEnds[5], channelIsSetColorMode[5], colorTexOffsets[5]);
143433
+ vec4 val6 = dataToColor(dat6, channelIsStaticColorMode[6], color6, channelOpacities[6], valueTexOffsets[6], channelColormapRangeStarts[6], channelColormapRangeEnds[6], channelIsSetColorMode[6], colorTexOffsets[6]);
143434
+
143435
+ // If all of the channels are "empty", then discard this pixel so that it is not considered during picking.
143436
+ float emptyDat = 0.;
143437
+ if(dat0.x == emptyDat && dat1.x == emptyDat && dat2.x == emptyDat && dat3.x == emptyDat && dat4.x == emptyDat && dat5.x == emptyDat && dat6.x == emptyDat) {
143438
+ discard;
143439
+ }
143440
+
143441
+ // If the next channel color and the currently stored color (gl_FragColor) are identical,
143442
+ // or the next channel color is transparent black,
143443
+ // just use the currently stored color. Repeat this for all channels.
143444
+
143445
+ // Mix colors where necessary, using the alpha value of the next channel as the weight.
143446
+ // Use the maximum alpha value as the resulting alpha value.
143447
+ gl_FragColor = val0;
143448
+ gl_FragColor = (val1 == gl_FragColor || val1 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val1, val1.a).rgb, max(gl_FragColor.a, val1.a));
143449
+ gl_FragColor = (val2 == gl_FragColor || val2 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val2, val2.a).rgb, max(gl_FragColor.a, val2.a));
143450
+ gl_FragColor = (val3 == gl_FragColor || val3 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val3, val3.a).rgb, max(gl_FragColor.a, val3.a));
143451
+ gl_FragColor = (val4 == gl_FragColor || val4 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val4, val4.a).rgb, max(gl_FragColor.a, val4.a));
143452
+ gl_FragColor = (val5 == gl_FragColor || val5 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val5, val5.a).rgb, max(gl_FragColor.a, val5.a));
143453
+ gl_FragColor = (val6 == gl_FragColor || val6 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val6, val6.a).rgb, max(gl_FragColor.a, val6.a));
143454
+
143455
+
143456
+
143457
+ // TODO: multiply the resulting channel-level opacity value by the layer-level opacity value.
143458
+
143459
+ geometry.uv = vTexCoord;
143460
+ DECKGL_FILTER_COLOR(gl_FragColor, geometry);
143461
+ }
143462
+ `;
143463
+ function normalize(arr) {
143464
+ const [min, max] = extent$1(arr);
143465
+ const ratio = 255 / (max - min);
143466
+ const data = new Uint8Array(arr.map((i2) => Math.floor((i2 - min) * ratio)));
143467
+ return data;
143468
+ }
143469
+ function multiSetsToTextureData(multiFeatureValues, setColorValues, channelIsSetColorMode, texSize) {
143470
+ let totalValuesLength = 0;
143471
+ let totalColorsLength = 0;
143472
+ channelIsSetColorMode.forEach((isSetColorMode, channelIndex) => {
143473
+ var _a2, _b, _c, _d, _e;
143474
+ if (isSetColorMode) {
143475
+ totalValuesLength += ((_b = (_a2 = setColorValues[channelIndex]) == null ? void 0 : _a2.obsIndex) == null ? void 0 : _b.length) || 0;
143476
+ totalColorsLength += (((_d = (_c = setColorValues[channelIndex]) == null ? void 0 : _c.setColors) == null ? void 0 : _d.length) || 0) * 3;
143477
+ } else {
143478
+ totalValuesLength += ((_e = multiFeatureValues[channelIndex]) == null ? void 0 : _e.length) || 0;
143479
+ }
143480
+ });
143481
+ const valueTexHeight = Math.max(2, Math.ceil(totalValuesLength / texSize));
143482
+ const colorTexHeight = Math.max(2, Math.ceil(totalColorsLength / texSize));
143483
+ if (valueTexHeight > texSize) {
143484
+ console.error("Error: length of concatenated quantitative feature values larger than maximum texture size");
143485
+ }
143486
+ if (colorTexHeight > texSize) {
143487
+ console.error("Error: length of concatenated quantitative feature values larger than maximum texture size");
143488
+ }
143489
+ const totalData = new Uint8Array(texSize * valueTexHeight);
143490
+ const totalColors = new Uint8Array(texSize * colorTexHeight);
143491
+ const indicesOffsets = [];
143492
+ const colorsOffsets = [];
143493
+ let indexOffset = 0;
143494
+ let colorOffset = 0;
143495
+ channelIsSetColorMode.forEach((isSetColorMode, channelIndex) => {
143496
+ if (isSetColorMode) {
143497
+ const { setColorIndices, setColors, obsIndex } = setColorValues[channelIndex] || {};
143498
+ if (setColorIndices && setColors && obsIndex) {
143499
+ for (let i2 = 0; i2 < obsIndex.length; i2++) {
143500
+ const colorIndex = setColorIndices.get(String(i2 + 1));
143501
+ totalData[indexOffset + i2] = colorIndex === void 0 ? 0 : colorIndex + 1;
143502
+ }
143503
+ for (let i2 = 0; i2 < setColors.length; i2++) {
143504
+ const { color: [r2, g2, b] } = setColors[i2];
143505
+ totalColors[(colorOffset + i2) * 3 + 0] = r2;
143506
+ totalColors[(colorOffset + i2) * 3 + 1] = g2;
143507
+ totalColors[(colorOffset + i2) * 3 + 2] = b;
143508
+ }
143509
+ }
143510
+ indicesOffsets.push(indexOffset);
143511
+ colorsOffsets.push(colorOffset);
143512
+ indexOffset += (obsIndex == null ? void 0 : obsIndex.length) || 0;
143513
+ colorOffset += (setColors == null ? void 0 : setColors.length) || 0;
143514
+ } else {
143515
+ const featureArr = multiFeatureValues[channelIndex];
143516
+ totalData.set(normalize(featureArr), indexOffset);
143517
+ indicesOffsets.push(indexOffset);
143518
+ indexOffset += featureArr.length;
143519
+ colorsOffsets.push(colorOffset);
143520
+ }
143521
+ });
143522
+ return [
143523
+ totalData,
143524
+ valueTexHeight,
143525
+ indicesOffsets,
143526
+ totalColors,
143527
+ colorTexHeight,
143528
+ colorsOffsets
143529
+ ];
143530
+ }
143531
+ const MAX_CHANNELS = 7;
143532
+ const MULTI_FEATURE_TEX_SIZE = 2048;
143533
+ function padWithDefault(arr, defaultValue2, padWidth) {
143534
+ const newArr = [...arr];
143535
+ for (let i2 = 0; i2 < padWidth; i2 += 1) {
143536
+ newArr.push(defaultValue2);
143537
+ }
143538
+ return newArr;
143539
+ }
143540
+ function getColor(arr) {
143541
+ return arr ? arr.map((v) => v / 255) : [0, 0, 0];
143542
+ }
143543
+ const defaultProps = {
143544
+ channelStrokeWidths: { type: "array", value: null, compare: true },
143545
+ channelsFilled: { type: "array", value: null, compare: true },
143546
+ channelOpacities: { type: "array", value: null, compare: true },
143547
+ channelColors: { type: "array", value: null, compare: true },
143548
+ hoveredCell: { type: "number", value: null, compare: true },
143549
+ colormap: { type: "string", value: GLSL_COLORMAP_DEFAULT, compare: true },
143550
+ expressionData: { type: "object", value: null, compare: true },
143551
+ multiFeatureValues: { type: "array", value: null, compare: true },
143552
+ setColorValues: { type: "array", value: null, compare: true },
143553
+ channelFeatureValueColormaps: { type: "array", value: null, compare: true },
143554
+ channelFeatureValueColormapRanges: { type: "array", value: null, compare: true },
143555
+ channelIsStaticColorMode: { type: "array", value: null, compare: true },
143556
+ channelIsSetColorMode: { type: "array", value: null, compare: true }
143557
+ };
143558
+ class BitmaskLayer2 extends XRLayer {
143559
+ // eslint-disable-next-line class-methods-use-this
143560
+ getShaders() {
143561
+ const { colormap } = this.props;
143562
+ return {
143563
+ fs,
143564
+ vs,
143565
+ modules: [project32, picking],
143566
+ defines: {
143567
+ [COLORMAP_SHADER_PLACEHOLDER]: GLSL_COLORMAPS.includes(colormap) ? colormap : GLSL_COLORMAP_DEFAULT
143568
+ }
143569
+ };
143570
+ }
143571
+ /**
143572
+ * Override the parent loadChannelTextures to enable
143573
+ * up to eight channels (rather than six).
143574
+ * Reference: https://github.com/hms-dbmi/viv/blob/v0.13.3/packages/layers/src/xr-layer/xr-layer.js#L316
143575
+ */
143576
+ loadChannelTextures(channelData) {
143577
+ const textures = {
143578
+ channel0: null,
143579
+ channel1: null,
143580
+ channel2: null,
143581
+ channel3: null,
143582
+ channel4: null,
143583
+ channel5: null,
143584
+ channel6: null
143585
+ };
143586
+ if (this.state.textures) {
143587
+ Object.values(this.state.textures).forEach((tex) => tex && tex.delete());
143588
+ }
143589
+ if (channelData && Object.keys(channelData).length > 0 && channelData.data) {
143590
+ channelData.data.forEach((d, i2) => {
143591
+ textures[`channel${i2}`] = this.dataToTexture(d, channelData.width, channelData.height);
143592
+ }, this);
143593
+ this.setState({ textures });
143594
+ }
143595
+ }
143596
+ updateState({ props: props2, oldProps, changeFlags }) {
143597
+ super.updateState({ props: props2, oldProps, changeFlags });
143598
+ if (props2.multiFeatureValues !== oldProps.multiFeatureValues || props2.setColorValues !== oldProps.setColorValues || props2.channelIsSetColorMode !== oldProps.channelIsSetColorMode) {
143599
+ const { multiFeatureValues, setColorValues, channelIsSetColorMode } = this.props;
143600
+ const [valueTex, colorTex, valueTexOffsets, colorTexOffsets, valueTexHeight, colorTexHeight] = this.multiSetsToTexture(multiFeatureValues, setColorValues, channelIsSetColorMode);
143601
+ this.setState({
143602
+ valueTex,
143603
+ colorTex,
143604
+ valueTexOffsets,
143605
+ colorTexOffsets,
143606
+ valueTexHeight,
143607
+ colorTexHeight
143608
+ });
143609
+ }
143610
+ if (props2.colormap !== oldProps.colormap) {
143611
+ const { gl } = this.context;
143612
+ if (this.state.model) {
143613
+ this.state.model.delete();
143614
+ }
143615
+ this.setState({ model: this._getModel(gl) });
143616
+ this.getAttributeManager().invalidateAll();
143617
+ }
143618
+ }
143619
+ draw(opts2) {
143620
+ const { uniforms } = opts2;
143621
+ const {
143622
+ channelStrokeWidths,
143623
+ channelsFilled,
143624
+ channelOpacities,
143625
+ channelColors,
143626
+ channelsVisible,
143627
+ // TODO: use `channelFeatureValueColormaps` in shader,
143628
+ // figure out how to call multiple GLSL colormap functions
143629
+ channelFeatureValueColormaps,
143630
+ channelFeatureValueColormapRanges,
143631
+ channelIsStaticColorMode,
143632
+ channelIsSetColorMode,
143633
+ hoveredCell,
143634
+ colorScaleLo,
143635
+ colorScaleHi,
143636
+ isExpressionMode,
143637
+ zoom,
143638
+ minZoom,
143639
+ maxZoom,
143640
+ zoomOffset
143641
+ // TODO: figure out if this needs to be used or not
143642
+ } = this.props;
143643
+ const {
143644
+ textures,
143645
+ model,
143646
+ // Expression and set index (and colors) textures with offsets
143647
+ valueTex,
143648
+ colorTex,
143649
+ valueTexOffsets,
143650
+ colorTexOffsets,
143651
+ valueTexHeight,
143652
+ colorTexHeight
143653
+ } = this.state;
143654
+ if (textures && model) {
143655
+ const scaleFactor = 1 / 2 ** (maxZoom - zoom);
143656
+ const colors = fromEntries(range$5(MAX_CHANNELS).map((i2) => [`color${i2}`, getColor(channelColors[i2])]));
143657
+ model.setUniforms(Object.assign({}, uniforms, {
143658
+ ...colors,
143659
+ // Bitmask image channel data textures
143660
+ ...textures,
143661
+ multiFeatureTexSize: MULTI_FEATURE_TEX_SIZE,
143662
+ // Expression textures with offsets
143663
+ valueTex,
143664
+ valueTexOffsets: padWithDefault(valueTexOffsets, 0, MAX_CHANNELS - valueTexOffsets.length),
143665
+ valueTexHeight,
143666
+ // Set indices and colors textures with offsets
143667
+ colorTex,
143668
+ colorTexOffsets: padWithDefault(colorTexOffsets, 0, MAX_CHANNELS - colorTexOffsets.length),
143669
+ colorTexHeight,
143670
+ // Visualization properties
143671
+ channelsFilled: padWithDefault(
143672
+ channelsFilled,
143673
+ true,
143674
+ // There are six texture entries on the shaders
143675
+ MAX_CHANNELS - channelsFilled.length
143676
+ ),
143677
+ channelOpacities: padWithDefault(
143678
+ channelOpacities,
143679
+ 0,
143680
+ // There are six texture entries on the shaders
143681
+ MAX_CHANNELS - channelOpacities.length
143682
+ ),
143683
+ channelStrokeWidths: padWithDefault(
143684
+ channelStrokeWidths,
143685
+ 1,
143686
+ // There are six texture entries on the shaders
143687
+ MAX_CHANNELS - channelStrokeWidths.length
143688
+ ),
143689
+ channelColormapRangeStarts: padWithDefault(
143690
+ channelFeatureValueColormapRanges.map((r2) => (r2 == null ? void 0 : r2[0]) || 0),
143691
+ 0,
143692
+ // There are six texture entries on the shaders
143693
+ MAX_CHANNELS - channelFeatureValueColormapRanges.length
143694
+ ),
143695
+ channelColormapRangeEnds: padWithDefault(
143696
+ channelFeatureValueColormapRanges.map((r2) => (r2 == null ? void 0 : r2[1]) || 1),
143697
+ 1,
143698
+ // There are six texture entries on the shaders
143699
+ MAX_CHANNELS - channelFeatureValueColormapRanges.length
143700
+ ),
143701
+ channelIsStaticColorMode: padWithDefault(
143702
+ channelIsStaticColorMode,
143703
+ true,
143704
+ // There are six texture entries on the shaders
143705
+ MAX_CHANNELS - channelIsStaticColorMode.length
143706
+ ),
143707
+ channelIsSetColorMode: padWithDefault(
143708
+ channelIsSetColorMode,
143709
+ false,
143710
+ // There are six texture entries on the shaders
143711
+ MAX_CHANNELS - channelIsSetColorMode.length
143712
+ ),
143713
+ hovered: hoveredCell || 0,
143714
+ channelsVisible: padWithDefault(
143715
+ channelsVisible,
143716
+ false,
143717
+ // There are six texture entries on the shaders
143718
+ MAX_CHANNELS - channelsVisible.length
143719
+ ),
143720
+ // uColorScaleRange: [colorScaleLo, colorScaleHi],
143721
+ // uIsExpressionMode: isExpressionMode,
143722
+ // uIsOutlined: false,
143723
+ scaleFactor
143724
+ })).draw();
143725
+ }
143726
+ }
143727
+ /**
143728
+ * This function creates textures from the data
143729
+ */
143730
+ dataToTexture(data, width, height) {
143731
+ const isWebGL2On = isWebGL2$1(this.context.gl);
143732
+ return new Texture2D(this.context.gl, {
143733
+ width,
143734
+ height,
143735
+ // Only use Float32 so we don't have to write two shaders
143736
+ data: new Float32Array(data),
143737
+ // we don't want or need mimaps
143738
+ mipmaps: false,
143739
+ parameters: {
143740
+ // NEAREST for integer data
143741
+ [GL$1.TEXTURE_MIN_FILTER]: GL$1.NEAREST,
143742
+ [GL$1.TEXTURE_MAG_FILTER]: GL$1.NEAREST,
143743
+ // CLAMP_TO_EDGE to remove tile artifacts
143744
+ [GL$1.TEXTURE_WRAP_S]: GL$1.CLAMP_TO_EDGE,
143745
+ [GL$1.TEXTURE_WRAP_T]: GL$1.CLAMP_TO_EDGE
143746
+ },
143747
+ format: isWebGL2On ? GL$1.R32F : GL$1.LUMINANCE,
143748
+ dataFormat: isWebGL2On ? GL$1.RED : GL$1.LUMINANCE,
143749
+ type: GL$1.FLOAT
143750
+ });
143751
+ }
143752
+ multiSetsToTexture(multiFeatureValues, setColorValues, channelIsSetColorMode) {
143753
+ const isWebGL2On = isWebGL2$1(this.context.gl);
143754
+ const [totalData, valueTexHeight, indicesOffsets, totalColors, colorTexHeight, colorsOffsets] = multiSetsToTextureData(multiFeatureValues, setColorValues, channelIsSetColorMode, MULTI_FEATURE_TEX_SIZE);
143755
+ return [
143756
+ // Color indices texture
143757
+ new Texture2D(this.context.gl, {
143758
+ width: MULTI_FEATURE_TEX_SIZE,
143759
+ height: valueTexHeight,
143760
+ // Only use Float32 so we don't have to write two shaders
143761
+ data: new Float32Array(totalData),
143762
+ // we don't want or need mimaps
143763
+ mipmaps: false,
143764
+ parameters: {
143765
+ // NEAREST for integer data
143766
+ [GL$1.TEXTURE_MIN_FILTER]: GL$1.NEAREST,
143767
+ [GL$1.TEXTURE_MAG_FILTER]: GL$1.NEAREST,
143768
+ // CLAMP_TO_EDGE to remove tile artifacts
143769
+ [GL$1.TEXTURE_WRAP_S]: GL$1.CLAMP_TO_EDGE,
143770
+ [GL$1.TEXTURE_WRAP_T]: GL$1.CLAMP_TO_EDGE
143771
+ },
143772
+ format: isWebGL2On ? GL$1.R32F : GL$1.LUMINANCE,
143773
+ dataFormat: isWebGL2On ? GL$1.RED : GL$1.LUMINANCE,
143774
+ type: GL$1.FLOAT
143775
+ }),
143776
+ // Colors texture
143777
+ new Texture2D(this.context.gl, {
143778
+ width: MULTI_FEATURE_TEX_SIZE,
143779
+ height: colorTexHeight,
143780
+ // Only use Float32 so we don't have to write two shaders
143781
+ data: new Float32Array(totalColors),
143782
+ // we don't want or need mimaps
143783
+ mipmaps: false,
143784
+ parameters: {
143785
+ // NEAREST for integer data
143786
+ [GL$1.TEXTURE_MIN_FILTER]: GL$1.NEAREST,
143787
+ [GL$1.TEXTURE_MAG_FILTER]: GL$1.NEAREST,
143788
+ // CLAMP_TO_EDGE to remove tile artifacts
143789
+ [GL$1.TEXTURE_WRAP_S]: GL$1.CLAMP_TO_EDGE,
143790
+ [GL$1.TEXTURE_WRAP_T]: GL$1.CLAMP_TO_EDGE
143791
+ },
143792
+ format: isWebGL2On ? GL$1.R32F : GL$1.LUMINANCE,
143793
+ dataFormat: isWebGL2On ? GL$1.RED : GL$1.LUMINANCE,
143794
+ type: GL$1.FLOAT
143795
+ }),
143796
+ // Offsets
143797
+ indicesOffsets,
143798
+ colorsOffsets,
143799
+ // Texture heights
143800
+ valueTexHeight,
143801
+ colorTexHeight
143802
+ ];
143803
+ }
142917
143804
  }
142918
- BitmaskLayer.layerName = "BitmaskLayer";
142919
- BitmaskLayer.defaultProps = defaultProps;
143805
+ BitmaskLayer2.layerName = "BitmaskLayer";
143806
+ BitmaskLayer2.defaultProps = defaultProps;
142920
143807
  function layerFilter({ layer, viewport }) {
142921
143808
  if (viewport.id === "axisLeft") {
142922
143809
  return layer.id.startsWith("axisLeft");