@vitessce/heatmap 3.8.9 → 3.8.13

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.
@@ -3,7 +3,7 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  var _a2, _b;
5
5
  import * as React from "react";
6
- import React__default, { useContext, forwardRef, useRef, useMemo, createContext, createElement, isValidElement, cloneElement, Children, useEffect, useLayoutEffect, useState, useImperativeHandle, useReducer, useCallback } from "react";
6
+ import React__default, { useContext, forwardRef, useRef, useMemo, createContext, createElement, isValidElement, cloneElement, Children, useState, useEffect, useCallback, useLayoutEffect, useImperativeHandle, useReducer } from "react";
7
7
  import { useVitessceContainer, useComponentHover, useComponentViewInfo, usePlotOptionsStyles, OptionsContainer, OptionSelect, useLoaders, useCoordinationScopes, useSetComponentHover, useSetComponentViewInfo, useCoordination, useDeckCanvasSize, useMultiObsLabels, useFeatureLabelsData, useExpandedFeatureLabelsMap, useObsFeatureMatrixData, useObsSetsData, useReady, useUrls, useUint8ObsFeatureMatrix, useGetObsInfo, useGetObsMembership, TitleInfo } from "@vitessce/vit-s";
8
8
  import * as ReactDOM from "react-dom";
9
9
  function _mergeNamespaces(n2, m) {
@@ -788,6 +788,34 @@ class Pool {
788
788
  }
789
789
  }
790
790
  }
791
+ function extent$1(values2, valueof) {
792
+ let min;
793
+ let max2;
794
+ {
795
+ for (const value of values2) {
796
+ if (value != null) {
797
+ if (min === void 0) {
798
+ if (value >= value) min = max2 = value;
799
+ } else {
800
+ if (min > value) min = value;
801
+ if (max2 < value) max2 = value;
802
+ }
803
+ }
804
+ }
805
+ }
806
+ return [min, max2];
807
+ }
808
+ function max(values2, valueof) {
809
+ let max2;
810
+ {
811
+ for (const value of values2) {
812
+ if (value != null && (max2 < value || max2 === void 0 && value >= value)) {
813
+ max2 = value;
814
+ }
815
+ }
816
+ }
817
+ return max2;
818
+ }
791
819
  let getRandomValues$1;
792
820
  const rnds8$1 = new Uint8Array(16);
793
821
  function rng$1() {
@@ -1832,7 +1860,7 @@ function debounce$1(func, wait, options) {
1832
1860
  leading = !!options.leading;
1833
1861
  maxing = "maxWait" in options;
1834
1862
  maxWait = maxing ? nativeMax$1(toNumber(options.maxWait) || 0, wait) : maxWait;
1835
- trailing = "trailing" in options ? true : trailing;
1863
+ trailing = "trailing" in options ? !!options.trailing : trailing;
1836
1864
  }
1837
1865
  function invokeFunc(time) {
1838
1866
  var args = lastArgs, thisArg = lastThis;
@@ -9787,6 +9815,8 @@ const CoordinationType$1 = {
9787
9815
  // Per-spatial-layer
9788
9816
  SPATIAL_MAX_RESOLUTION: "spatialMaxResolution",
9789
9817
  // Per-image-channel (for spatial-accelerated)
9818
+ SPATIAL_LOD_FACTOR: "spatialLodFactor",
9819
+ // LOD factor for 3D volume rendering
9790
9820
  // For clipping plane sliders
9791
9821
  SPATIAL_SLICE_X: "spatialSliceX",
9792
9822
  SPATIAL_SLICE_Y: "spatialSliceY",
@@ -25090,11 +25120,6 @@ const { tss } = createTss({
25090
25120
  "usePlugin": useMuiThemeStyleOverridesPlugin
25091
25121
  });
25092
25122
  const useStyles$3 = tss.create({});
25093
- function chainPropTypes(propType1, propType2) {
25094
- return function validate2(...args) {
25095
- return propType1(...args) || propType2(...args);
25096
- };
25097
- }
25098
25123
  const memoTheme = unstable_memoTheme;
25099
25124
  ({
25100
25125
  // ┌────────────────────────────── Warning ──────────────────────────────┐
@@ -25113,332 +25138,6 @@ const memoTheme = unstable_memoTheme;
25113
25138
  function useDefaultProps(params) {
25114
25139
  return useDefaultProps$1(params);
25115
25140
  }
25116
- function _extends$1() {
25117
- return _extends$1 = Object.assign ? Object.assign.bind() : function(n2) {
25118
- for (var e3 = 1; e3 < arguments.length; e3++) {
25119
- var t = arguments[e3];
25120
- for (var r2 in t) ({}).hasOwnProperty.call(t, r2) && (n2[r2] = t[r2]);
25121
- }
25122
- return n2;
25123
- }, _extends$1.apply(null, arguments);
25124
- }
25125
- function _objectWithoutPropertiesLoose(r2, e3) {
25126
- if (null == r2) return {};
25127
- var t = {};
25128
- for (var n2 in r2) if ({}.hasOwnProperty.call(r2, n2)) {
25129
- if (-1 !== e3.indexOf(n2)) continue;
25130
- t[n2] = r2[n2];
25131
- }
25132
- return t;
25133
- }
25134
- function _setPrototypeOf(t, e3) {
25135
- return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function(t2, e4) {
25136
- return t2.__proto__ = e4, t2;
25137
- }, _setPrototypeOf(t, e3);
25138
- }
25139
- function _inheritsLoose(t, o2) {
25140
- t.prototype = Object.create(o2.prototype), t.prototype.constructor = t, _setPrototypeOf(t, o2);
25141
- }
25142
- const TransitionGroupContext = React__default.createContext(null);
25143
- function _assertThisInitialized(e3) {
25144
- if (void 0 === e3) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
25145
- return e3;
25146
- }
25147
- function getChildMapping(children2, mapFn) {
25148
- var mapper = function mapper2(child) {
25149
- return mapFn && isValidElement(child) ? mapFn(child) : child;
25150
- };
25151
- var result = /* @__PURE__ */ Object.create(null);
25152
- if (children2) Children.map(children2, function(c) {
25153
- return c;
25154
- }).forEach(function(child) {
25155
- result[child.key] = mapper(child);
25156
- });
25157
- return result;
25158
- }
25159
- function mergeChildMappings(prev2, next2) {
25160
- prev2 = prev2 || {};
25161
- next2 = next2 || {};
25162
- function getValueForKey(key) {
25163
- return key in next2 ? next2[key] : prev2[key];
25164
- }
25165
- var nextKeysPending = /* @__PURE__ */ Object.create(null);
25166
- var pendingKeys = [];
25167
- for (var prevKey in prev2) {
25168
- if (prevKey in next2) {
25169
- if (pendingKeys.length) {
25170
- nextKeysPending[prevKey] = pendingKeys;
25171
- pendingKeys = [];
25172
- }
25173
- } else {
25174
- pendingKeys.push(prevKey);
25175
- }
25176
- }
25177
- var i2;
25178
- var childMapping = {};
25179
- for (var nextKey in next2) {
25180
- if (nextKeysPending[nextKey]) {
25181
- for (i2 = 0; i2 < nextKeysPending[nextKey].length; i2++) {
25182
- var pendingNextKey = nextKeysPending[nextKey][i2];
25183
- childMapping[nextKeysPending[nextKey][i2]] = getValueForKey(pendingNextKey);
25184
- }
25185
- }
25186
- childMapping[nextKey] = getValueForKey(nextKey);
25187
- }
25188
- for (i2 = 0; i2 < pendingKeys.length; i2++) {
25189
- childMapping[pendingKeys[i2]] = getValueForKey(pendingKeys[i2]);
25190
- }
25191
- return childMapping;
25192
- }
25193
- function getProp(child, prop, props) {
25194
- return props[prop] != null ? props[prop] : child.props[prop];
25195
- }
25196
- function getInitialChildMapping(props, onExited) {
25197
- return getChildMapping(props.children, function(child) {
25198
- return cloneElement(child, {
25199
- onExited: onExited.bind(null, child),
25200
- in: true,
25201
- appear: getProp(child, "appear", props),
25202
- enter: getProp(child, "enter", props),
25203
- exit: getProp(child, "exit", props)
25204
- });
25205
- });
25206
- }
25207
- function getNextChildMapping(nextProps, prevChildMapping, onExited) {
25208
- var nextChildMapping = getChildMapping(nextProps.children);
25209
- var children2 = mergeChildMappings(prevChildMapping, nextChildMapping);
25210
- Object.keys(children2).forEach(function(key) {
25211
- var child = children2[key];
25212
- if (!isValidElement(child)) return;
25213
- var hasPrev = key in prevChildMapping;
25214
- var hasNext = key in nextChildMapping;
25215
- var prevChild = prevChildMapping[key];
25216
- var isLeaving = isValidElement(prevChild) && !prevChild.props.in;
25217
- if (hasNext && (!hasPrev || isLeaving)) {
25218
- children2[key] = cloneElement(child, {
25219
- onExited: onExited.bind(null, child),
25220
- in: true,
25221
- exit: getProp(child, "exit", nextProps),
25222
- enter: getProp(child, "enter", nextProps)
25223
- });
25224
- } else if (!hasNext && hasPrev && !isLeaving) {
25225
- children2[key] = cloneElement(child, {
25226
- in: false
25227
- });
25228
- } else if (hasNext && hasPrev && isValidElement(prevChild)) {
25229
- children2[key] = cloneElement(child, {
25230
- onExited: onExited.bind(null, child),
25231
- in: prevChild.props.in,
25232
- exit: getProp(child, "exit", nextProps),
25233
- enter: getProp(child, "enter", nextProps)
25234
- });
25235
- }
25236
- });
25237
- return children2;
25238
- }
25239
- var values = Object.values || function(obj) {
25240
- return Object.keys(obj).map(function(k) {
25241
- return obj[k];
25242
- });
25243
- };
25244
- var defaultProps$P = {
25245
- component: "div",
25246
- childFactory: function childFactory(child) {
25247
- return child;
25248
- }
25249
- };
25250
- var TransitionGroup = /* @__PURE__ */ function(_React$Component) {
25251
- _inheritsLoose(TransitionGroup2, _React$Component);
25252
- function TransitionGroup2(props, context) {
25253
- var _this;
25254
- _this = _React$Component.call(this, props, context) || this;
25255
- var handleExited = _this.handleExited.bind(_assertThisInitialized(_this));
25256
- _this.state = {
25257
- contextValue: {
25258
- isMounting: true
25259
- },
25260
- handleExited,
25261
- firstRender: true
25262
- };
25263
- return _this;
25264
- }
25265
- var _proto = TransitionGroup2.prototype;
25266
- _proto.componentDidMount = function componentDidMount() {
25267
- this.mounted = true;
25268
- this.setState({
25269
- contextValue: {
25270
- isMounting: false
25271
- }
25272
- });
25273
- };
25274
- _proto.componentWillUnmount = function componentWillUnmount() {
25275
- this.mounted = false;
25276
- };
25277
- TransitionGroup2.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, _ref) {
25278
- var prevChildMapping = _ref.children, handleExited = _ref.handleExited, firstRender = _ref.firstRender;
25279
- return {
25280
- children: firstRender ? getInitialChildMapping(nextProps, handleExited) : getNextChildMapping(nextProps, prevChildMapping, handleExited),
25281
- firstRender: false
25282
- };
25283
- };
25284
- _proto.handleExited = function handleExited(child, node2) {
25285
- var currentChildMapping = getChildMapping(this.props.children);
25286
- if (child.key in currentChildMapping) return;
25287
- if (child.props.onExited) {
25288
- child.props.onExited(node2);
25289
- }
25290
- if (this.mounted) {
25291
- this.setState(function(state) {
25292
- var children2 = _extends$1({}, state.children);
25293
- delete children2[child.key];
25294
- return {
25295
- children: children2
25296
- };
25297
- });
25298
- }
25299
- };
25300
- _proto.render = function render() {
25301
- var _this$props = this.props, Component2 = _this$props.component, childFactory2 = _this$props.childFactory, props = _objectWithoutPropertiesLoose(_this$props, ["component", "childFactory"]);
25302
- var contextValue = this.state.contextValue;
25303
- var children2 = values(this.state.children).map(childFactory2);
25304
- delete props.appear;
25305
- delete props.enter;
25306
- delete props.exit;
25307
- if (Component2 === null) {
25308
- return /* @__PURE__ */ React__default.createElement(TransitionGroupContext.Provider, {
25309
- value: contextValue
25310
- }, children2);
25311
- }
25312
- return /* @__PURE__ */ React__default.createElement(TransitionGroupContext.Provider, {
25313
- value: contextValue
25314
- }, /* @__PURE__ */ React__default.createElement(Component2, props, children2));
25315
- };
25316
- return TransitionGroup2;
25317
- }(React__default.Component);
25318
- TransitionGroup.propTypes = {
25319
- /**
25320
- * `<TransitionGroup>` renders a `<div>` by default. You can change this
25321
- * behavior by providing a `component` prop.
25322
- * If you use React v16+ and would like to avoid a wrapping `<div>` element
25323
- * you can pass in `component={null}`. This is useful if the wrapping div
25324
- * borks your css styles.
25325
- */
25326
- component: PropTypes.any,
25327
- /**
25328
- * A set of `<Transition>` components, that are toggled `in` and out as they
25329
- * leave. the `<TransitionGroup>` will inject specific transition props, so
25330
- * remember to spread them through if you are wrapping the `<Transition>` as
25331
- * with our `<Fade>` example.
25332
- *
25333
- * While this component is meant for multiple `Transition` or `CSSTransition`
25334
- * children, sometimes you may want to have a single transition child with
25335
- * content that you want to be transitioned out and in when you change it
25336
- * (e.g. routes, images etc.) In that case you can change the `key` prop of
25337
- * the transition child as you change its content, this will cause
25338
- * `TransitionGroup` to transition the child out and back in.
25339
- */
25340
- children: PropTypes.node,
25341
- /**
25342
- * A convenience prop that enables or disables appear animations
25343
- * for all children. Note that specifying this will override any defaults set
25344
- * on individual children Transitions.
25345
- */
25346
- appear: PropTypes.bool,
25347
- /**
25348
- * A convenience prop that enables or disables enter animations
25349
- * for all children. Note that specifying this will override any defaults set
25350
- * on individual children Transitions.
25351
- */
25352
- enter: PropTypes.bool,
25353
- /**
25354
- * A convenience prop that enables or disables exit animations
25355
- * for all children. Note that specifying this will override any defaults set
25356
- * on individual children Transitions.
25357
- */
25358
- exit: PropTypes.bool,
25359
- /**
25360
- * You may need to apply reactive updates to a child as it is exiting.
25361
- * This is generally done by using `cloneElement` however in the case of an exiting
25362
- * child the element has already been removed and not accessible to the consumer.
25363
- *
25364
- * If you do need to update a child as it leaves you can provide a `childFactory`
25365
- * to wrap every child, even the ones that are leaving.
25366
- *
25367
- * @type Function(child: ReactElement) -> ReactElement
25368
- */
25369
- childFactory: PropTypes.func
25370
- };
25371
- TransitionGroup.defaultProps = defaultProps$P;
25372
- const UNINITIALIZED = {};
25373
- function useLazyRef(init, initArg) {
25374
- const ref = React.useRef(UNINITIALIZED);
25375
- if (ref.current === UNINITIALIZED) {
25376
- ref.current = init(initArg);
25377
- }
25378
- return ref;
25379
- }
25380
- const EMPTY$1 = [];
25381
- function useOnMount(fn) {
25382
- React.useEffect(fn, EMPTY$1);
25383
- }
25384
- class Timeout {
25385
- constructor() {
25386
- __publicField(this, "currentId", null);
25387
- __publicField(this, "clear", () => {
25388
- if (this.currentId !== null) {
25389
- clearTimeout(this.currentId);
25390
- this.currentId = null;
25391
- }
25392
- });
25393
- __publicField(this, "disposeEffect", () => {
25394
- return this.clear;
25395
- });
25396
- }
25397
- static create() {
25398
- return new Timeout();
25399
- }
25400
- /**
25401
- * Executes `fn` after `delay`, clearing any previously scheduled call.
25402
- */
25403
- start(delay, fn) {
25404
- this.clear();
25405
- this.currentId = setTimeout(() => {
25406
- this.currentId = null;
25407
- fn();
25408
- }, delay);
25409
- }
25410
- }
25411
- function useTimeout() {
25412
- const timeout = useLazyRef(Timeout.create).current;
25413
- useOnMount(timeout.disposeEffect);
25414
- return timeout;
25415
- }
25416
- function isClassComponent(elementType) {
25417
- const {
25418
- prototype = {}
25419
- } = elementType;
25420
- return Boolean(prototype.isReactComponent);
25421
- }
25422
- function elementTypeAcceptingRef(props, propName, componentName, location, propFullName) {
25423
- const propValue = props[propName];
25424
- const safePropName = propFullName || propName;
25425
- if (propValue == null || // When server-side rendering React doesn't warn either.
25426
- // This is not an accurate check for SSR.
25427
- // This is only in place for emotion compat.
25428
- // TODO: Revisit once https://github.com/facebook/react/issues/20047 is resolved.
25429
- typeof window === "undefined") {
25430
- return null;
25431
- }
25432
- let warningHint;
25433
- if (typeof propValue === "function" && !isClassComponent(propValue)) {
25434
- warningHint = "Did you accidentally provide a plain function component instead?";
25435
- }
25436
- if (warningHint !== void 0) {
25437
- return new Error(`Invalid ${location} \`${safePropName}\` supplied to \`${componentName}\`. Expected an element type that can hold a ref. ${warningHint} For more information see https://mui.com/r/caveat-with-refs-guide`);
25438
- }
25439
- return null;
25440
- }
25441
- const elementTypeAcceptingRef$1 = chainPropTypes(PropTypes.elementType, elementTypeAcceptingRef);
25442
25141
  function getSvgIconUtilityClass(slot) {
25443
25142
  return generateUtilityClass("MuiSvgIcon", slot);
25444
25143
  }
@@ -25855,6 +25554,337 @@ function mergeSlotProps$1(externalSlotProps, defaultSlotProps) {
25855
25554
  }
25856
25555
  };
25857
25556
  }
25557
+ function chainPropTypes(propType1, propType2) {
25558
+ return function validate2(...args) {
25559
+ return propType1(...args) || propType2(...args);
25560
+ };
25561
+ }
25562
+ function _extends$1() {
25563
+ return _extends$1 = Object.assign ? Object.assign.bind() : function(n2) {
25564
+ for (var e3 = 1; e3 < arguments.length; e3++) {
25565
+ var t = arguments[e3];
25566
+ for (var r2 in t) ({}).hasOwnProperty.call(t, r2) && (n2[r2] = t[r2]);
25567
+ }
25568
+ return n2;
25569
+ }, _extends$1.apply(null, arguments);
25570
+ }
25571
+ function _objectWithoutPropertiesLoose(r2, e3) {
25572
+ if (null == r2) return {};
25573
+ var t = {};
25574
+ for (var n2 in r2) if ({}.hasOwnProperty.call(r2, n2)) {
25575
+ if (-1 !== e3.indexOf(n2)) continue;
25576
+ t[n2] = r2[n2];
25577
+ }
25578
+ return t;
25579
+ }
25580
+ function _setPrototypeOf(t, e3) {
25581
+ return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function(t2, e4) {
25582
+ return t2.__proto__ = e4, t2;
25583
+ }, _setPrototypeOf(t, e3);
25584
+ }
25585
+ function _inheritsLoose(t, o2) {
25586
+ t.prototype = Object.create(o2.prototype), t.prototype.constructor = t, _setPrototypeOf(t, o2);
25587
+ }
25588
+ const TransitionGroupContext = React__default.createContext(null);
25589
+ function _assertThisInitialized(e3) {
25590
+ if (void 0 === e3) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
25591
+ return e3;
25592
+ }
25593
+ function getChildMapping(children2, mapFn) {
25594
+ var mapper = function mapper2(child) {
25595
+ return mapFn && isValidElement(child) ? mapFn(child) : child;
25596
+ };
25597
+ var result = /* @__PURE__ */ Object.create(null);
25598
+ if (children2) Children.map(children2, function(c) {
25599
+ return c;
25600
+ }).forEach(function(child) {
25601
+ result[child.key] = mapper(child);
25602
+ });
25603
+ return result;
25604
+ }
25605
+ function mergeChildMappings(prev2, next2) {
25606
+ prev2 = prev2 || {};
25607
+ next2 = next2 || {};
25608
+ function getValueForKey(key) {
25609
+ return key in next2 ? next2[key] : prev2[key];
25610
+ }
25611
+ var nextKeysPending = /* @__PURE__ */ Object.create(null);
25612
+ var pendingKeys = [];
25613
+ for (var prevKey in prev2) {
25614
+ if (prevKey in next2) {
25615
+ if (pendingKeys.length) {
25616
+ nextKeysPending[prevKey] = pendingKeys;
25617
+ pendingKeys = [];
25618
+ }
25619
+ } else {
25620
+ pendingKeys.push(prevKey);
25621
+ }
25622
+ }
25623
+ var i2;
25624
+ var childMapping = {};
25625
+ for (var nextKey in next2) {
25626
+ if (nextKeysPending[nextKey]) {
25627
+ for (i2 = 0; i2 < nextKeysPending[nextKey].length; i2++) {
25628
+ var pendingNextKey = nextKeysPending[nextKey][i2];
25629
+ childMapping[nextKeysPending[nextKey][i2]] = getValueForKey(pendingNextKey);
25630
+ }
25631
+ }
25632
+ childMapping[nextKey] = getValueForKey(nextKey);
25633
+ }
25634
+ for (i2 = 0; i2 < pendingKeys.length; i2++) {
25635
+ childMapping[pendingKeys[i2]] = getValueForKey(pendingKeys[i2]);
25636
+ }
25637
+ return childMapping;
25638
+ }
25639
+ function getProp(child, prop, props) {
25640
+ return props[prop] != null ? props[prop] : child.props[prop];
25641
+ }
25642
+ function getInitialChildMapping(props, onExited) {
25643
+ return getChildMapping(props.children, function(child) {
25644
+ return cloneElement(child, {
25645
+ onExited: onExited.bind(null, child),
25646
+ in: true,
25647
+ appear: getProp(child, "appear", props),
25648
+ enter: getProp(child, "enter", props),
25649
+ exit: getProp(child, "exit", props)
25650
+ });
25651
+ });
25652
+ }
25653
+ function getNextChildMapping(nextProps, prevChildMapping, onExited) {
25654
+ var nextChildMapping = getChildMapping(nextProps.children);
25655
+ var children2 = mergeChildMappings(prevChildMapping, nextChildMapping);
25656
+ Object.keys(children2).forEach(function(key) {
25657
+ var child = children2[key];
25658
+ if (!isValidElement(child)) return;
25659
+ var hasPrev = key in prevChildMapping;
25660
+ var hasNext = key in nextChildMapping;
25661
+ var prevChild = prevChildMapping[key];
25662
+ var isLeaving = isValidElement(prevChild) && !prevChild.props.in;
25663
+ if (hasNext && (!hasPrev || isLeaving)) {
25664
+ children2[key] = cloneElement(child, {
25665
+ onExited: onExited.bind(null, child),
25666
+ in: true,
25667
+ exit: getProp(child, "exit", nextProps),
25668
+ enter: getProp(child, "enter", nextProps)
25669
+ });
25670
+ } else if (!hasNext && hasPrev && !isLeaving) {
25671
+ children2[key] = cloneElement(child, {
25672
+ in: false
25673
+ });
25674
+ } else if (hasNext && hasPrev && isValidElement(prevChild)) {
25675
+ children2[key] = cloneElement(child, {
25676
+ onExited: onExited.bind(null, child),
25677
+ in: prevChild.props.in,
25678
+ exit: getProp(child, "exit", nextProps),
25679
+ enter: getProp(child, "enter", nextProps)
25680
+ });
25681
+ }
25682
+ });
25683
+ return children2;
25684
+ }
25685
+ var values = Object.values || function(obj) {
25686
+ return Object.keys(obj).map(function(k) {
25687
+ return obj[k];
25688
+ });
25689
+ };
25690
+ var defaultProps$P = {
25691
+ component: "div",
25692
+ childFactory: function childFactory(child) {
25693
+ return child;
25694
+ }
25695
+ };
25696
+ var TransitionGroup = /* @__PURE__ */ function(_React$Component) {
25697
+ _inheritsLoose(TransitionGroup2, _React$Component);
25698
+ function TransitionGroup2(props, context) {
25699
+ var _this;
25700
+ _this = _React$Component.call(this, props, context) || this;
25701
+ var handleExited = _this.handleExited.bind(_assertThisInitialized(_this));
25702
+ _this.state = {
25703
+ contextValue: {
25704
+ isMounting: true
25705
+ },
25706
+ handleExited,
25707
+ firstRender: true
25708
+ };
25709
+ return _this;
25710
+ }
25711
+ var _proto = TransitionGroup2.prototype;
25712
+ _proto.componentDidMount = function componentDidMount() {
25713
+ this.mounted = true;
25714
+ this.setState({
25715
+ contextValue: {
25716
+ isMounting: false
25717
+ }
25718
+ });
25719
+ };
25720
+ _proto.componentWillUnmount = function componentWillUnmount() {
25721
+ this.mounted = false;
25722
+ };
25723
+ TransitionGroup2.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, _ref) {
25724
+ var prevChildMapping = _ref.children, handleExited = _ref.handleExited, firstRender = _ref.firstRender;
25725
+ return {
25726
+ children: firstRender ? getInitialChildMapping(nextProps, handleExited) : getNextChildMapping(nextProps, prevChildMapping, handleExited),
25727
+ firstRender: false
25728
+ };
25729
+ };
25730
+ _proto.handleExited = function handleExited(child, node2) {
25731
+ var currentChildMapping = getChildMapping(this.props.children);
25732
+ if (child.key in currentChildMapping) return;
25733
+ if (child.props.onExited) {
25734
+ child.props.onExited(node2);
25735
+ }
25736
+ if (this.mounted) {
25737
+ this.setState(function(state) {
25738
+ var children2 = _extends$1({}, state.children);
25739
+ delete children2[child.key];
25740
+ return {
25741
+ children: children2
25742
+ };
25743
+ });
25744
+ }
25745
+ };
25746
+ _proto.render = function render() {
25747
+ var _this$props = this.props, Component2 = _this$props.component, childFactory2 = _this$props.childFactory, props = _objectWithoutPropertiesLoose(_this$props, ["component", "childFactory"]);
25748
+ var contextValue = this.state.contextValue;
25749
+ var children2 = values(this.state.children).map(childFactory2);
25750
+ delete props.appear;
25751
+ delete props.enter;
25752
+ delete props.exit;
25753
+ if (Component2 === null) {
25754
+ return /* @__PURE__ */ React__default.createElement(TransitionGroupContext.Provider, {
25755
+ value: contextValue
25756
+ }, children2);
25757
+ }
25758
+ return /* @__PURE__ */ React__default.createElement(TransitionGroupContext.Provider, {
25759
+ value: contextValue
25760
+ }, /* @__PURE__ */ React__default.createElement(Component2, props, children2));
25761
+ };
25762
+ return TransitionGroup2;
25763
+ }(React__default.Component);
25764
+ TransitionGroup.propTypes = {
25765
+ /**
25766
+ * `<TransitionGroup>` renders a `<div>` by default. You can change this
25767
+ * behavior by providing a `component` prop.
25768
+ * If you use React v16+ and would like to avoid a wrapping `<div>` element
25769
+ * you can pass in `component={null}`. This is useful if the wrapping div
25770
+ * borks your css styles.
25771
+ */
25772
+ component: PropTypes.any,
25773
+ /**
25774
+ * A set of `<Transition>` components, that are toggled `in` and out as they
25775
+ * leave. the `<TransitionGroup>` will inject specific transition props, so
25776
+ * remember to spread them through if you are wrapping the `<Transition>` as
25777
+ * with our `<Fade>` example.
25778
+ *
25779
+ * While this component is meant for multiple `Transition` or `CSSTransition`
25780
+ * children, sometimes you may want to have a single transition child with
25781
+ * content that you want to be transitioned out and in when you change it
25782
+ * (e.g. routes, images etc.) In that case you can change the `key` prop of
25783
+ * the transition child as you change its content, this will cause
25784
+ * `TransitionGroup` to transition the child out and back in.
25785
+ */
25786
+ children: PropTypes.node,
25787
+ /**
25788
+ * A convenience prop that enables or disables appear animations
25789
+ * for all children. Note that specifying this will override any defaults set
25790
+ * on individual children Transitions.
25791
+ */
25792
+ appear: PropTypes.bool,
25793
+ /**
25794
+ * A convenience prop that enables or disables enter animations
25795
+ * for all children. Note that specifying this will override any defaults set
25796
+ * on individual children Transitions.
25797
+ */
25798
+ enter: PropTypes.bool,
25799
+ /**
25800
+ * A convenience prop that enables or disables exit animations
25801
+ * for all children. Note that specifying this will override any defaults set
25802
+ * on individual children Transitions.
25803
+ */
25804
+ exit: PropTypes.bool,
25805
+ /**
25806
+ * You may need to apply reactive updates to a child as it is exiting.
25807
+ * This is generally done by using `cloneElement` however in the case of an exiting
25808
+ * child the element has already been removed and not accessible to the consumer.
25809
+ *
25810
+ * If you do need to update a child as it leaves you can provide a `childFactory`
25811
+ * to wrap every child, even the ones that are leaving.
25812
+ *
25813
+ * @type Function(child: ReactElement) -> ReactElement
25814
+ */
25815
+ childFactory: PropTypes.func
25816
+ };
25817
+ TransitionGroup.defaultProps = defaultProps$P;
25818
+ const UNINITIALIZED = {};
25819
+ function useLazyRef(init, initArg) {
25820
+ const ref = React.useRef(UNINITIALIZED);
25821
+ if (ref.current === UNINITIALIZED) {
25822
+ ref.current = init(initArg);
25823
+ }
25824
+ return ref;
25825
+ }
25826
+ const EMPTY$1 = [];
25827
+ function useOnMount(fn) {
25828
+ React.useEffect(fn, EMPTY$1);
25829
+ }
25830
+ class Timeout {
25831
+ constructor() {
25832
+ __publicField(this, "currentId", null);
25833
+ __publicField(this, "clear", () => {
25834
+ if (this.currentId !== null) {
25835
+ clearTimeout(this.currentId);
25836
+ this.currentId = null;
25837
+ }
25838
+ });
25839
+ __publicField(this, "disposeEffect", () => {
25840
+ return this.clear;
25841
+ });
25842
+ }
25843
+ static create() {
25844
+ return new Timeout();
25845
+ }
25846
+ /**
25847
+ * Executes `fn` after `delay`, clearing any previously scheduled call.
25848
+ */
25849
+ start(delay, fn) {
25850
+ this.clear();
25851
+ this.currentId = setTimeout(() => {
25852
+ this.currentId = null;
25853
+ fn();
25854
+ }, delay);
25855
+ }
25856
+ }
25857
+ function useTimeout() {
25858
+ const timeout = useLazyRef(Timeout.create).current;
25859
+ useOnMount(timeout.disposeEffect);
25860
+ return timeout;
25861
+ }
25862
+ function isClassComponent(elementType) {
25863
+ const {
25864
+ prototype = {}
25865
+ } = elementType;
25866
+ return Boolean(prototype.isReactComponent);
25867
+ }
25868
+ function elementTypeAcceptingRef(props, propName, componentName, location, propFullName) {
25869
+ const propValue = props[propName];
25870
+ const safePropName = propFullName || propName;
25871
+ if (propValue == null || // When server-side rendering React doesn't warn either.
25872
+ // This is not an accurate check for SSR.
25873
+ // This is only in place for emotion compat.
25874
+ // TODO: Revisit once https://github.com/facebook/react/issues/20047 is resolved.
25875
+ typeof window === "undefined") {
25876
+ return null;
25877
+ }
25878
+ let warningHint;
25879
+ if (typeof propValue === "function" && !isClassComponent(propValue)) {
25880
+ warningHint = "Did you accidentally provide a plain function component instead?";
25881
+ }
25882
+ if (warningHint !== void 0) {
25883
+ return new Error(`Invalid ${location} \`${safePropName}\` supplied to \`${componentName}\`. Expected an element type that can hold a ref. ${warningHint} For more information see https://mui.com/r/caveat-with-refs-guide`);
25884
+ }
25885
+ return null;
25886
+ }
25887
+ const elementTypeAcceptingRef$1 = chainPropTypes(PropTypes.elementType, elementTypeAcceptingRef);
25858
25888
  function getTypeByValue(value) {
25859
25889
  const valueType = typeof value;
25860
25890
  switch (valueType) {
@@ -32438,40 +32468,51 @@ function number$2(x) {
32438
32468
  const ascendingBisect = bisector$1(ascending$2);
32439
32469
  const bisectRight = ascendingBisect.right;
32440
32470
  bisector$1(number$2).center;
32441
- var e10 = Math.sqrt(50), e5 = Math.sqrt(10), e2 = Math.sqrt(2);
32471
+ const e10 = Math.sqrt(50), e5 = Math.sqrt(10), e2 = Math.sqrt(2);
32472
+ function tickSpec(start, stop, count2) {
32473
+ const step = (stop - start) / Math.max(0, count2), power = Math.floor(Math.log10(step)), error2 = step / Math.pow(10, power), factor = error2 >= e10 ? 10 : error2 >= e5 ? 5 : error2 >= e2 ? 2 : 1;
32474
+ let i1, i2, inc;
32475
+ if (power < 0) {
32476
+ inc = Math.pow(10, -power) / factor;
32477
+ i1 = Math.round(start * inc);
32478
+ i2 = Math.round(stop * inc);
32479
+ if (i1 / inc < start) ++i1;
32480
+ if (i2 / inc > stop) --i2;
32481
+ inc = -inc;
32482
+ } else {
32483
+ inc = Math.pow(10, power) * factor;
32484
+ i1 = Math.round(start / inc);
32485
+ i2 = Math.round(stop / inc);
32486
+ if (i1 * inc < start) ++i1;
32487
+ if (i2 * inc > stop) --i2;
32488
+ }
32489
+ if (i2 < i1 && 0.5 <= count2 && count2 < 2) return tickSpec(start, stop, count2 * 2);
32490
+ return [i1, i2, inc];
32491
+ }
32442
32492
  function ticks(start, stop, count2) {
32443
- var reverse, i2 = -1, n2, ticks2, step;
32444
32493
  stop = +stop, start = +start, count2 = +count2;
32445
- if (start === stop && count2 > 0) return [start];
32446
- if (reverse = stop < start) n2 = start, start = stop, stop = n2;
32447
- if ((step = tickIncrement(start, stop, count2)) === 0 || !isFinite(step)) return [];
32448
- if (step > 0) {
32449
- let r0 = Math.round(start / step), r1 = Math.round(stop / step);
32450
- if (r0 * step < start) ++r0;
32451
- if (r1 * step > stop) --r1;
32452
- ticks2 = new Array(n2 = r1 - r0 + 1);
32453
- while (++i2 < n2) ticks2[i2] = (r0 + i2) * step;
32494
+ if (!(count2 > 0)) return [];
32495
+ if (start === stop) return [start];
32496
+ const reverse = stop < start, [i1, i2, inc] = reverse ? tickSpec(stop, start, count2) : tickSpec(start, stop, count2);
32497
+ if (!(i2 >= i1)) return [];
32498
+ const n2 = i2 - i1 + 1, ticks2 = new Array(n2);
32499
+ if (reverse) {
32500
+ if (inc < 0) for (let i3 = 0; i3 < n2; ++i3) ticks2[i3] = (i2 - i3) / -inc;
32501
+ else for (let i3 = 0; i3 < n2; ++i3) ticks2[i3] = (i2 - i3) * inc;
32454
32502
  } else {
32455
- step = -step;
32456
- let r0 = Math.round(start * step), r1 = Math.round(stop * step);
32457
- if (r0 / step < start) ++r0;
32458
- if (r1 / step > stop) --r1;
32459
- ticks2 = new Array(n2 = r1 - r0 + 1);
32460
- while (++i2 < n2) ticks2[i2] = (r0 + i2) / step;
32461
- }
32462
- if (reverse) ticks2.reverse();
32503
+ if (inc < 0) for (let i3 = 0; i3 < n2; ++i3) ticks2[i3] = (i1 + i3) / -inc;
32504
+ else for (let i3 = 0; i3 < n2; ++i3) ticks2[i3] = (i1 + i3) * inc;
32505
+ }
32463
32506
  return ticks2;
32464
32507
  }
32465
32508
  function tickIncrement(start, stop, count2) {
32466
- var step = (stop - start) / Math.max(0, count2), power = Math.floor(Math.log(step) / Math.LN10), error2 = step / Math.pow(10, power);
32467
- return power >= 0 ? (error2 >= e10 ? 10 : error2 >= e5 ? 5 : error2 >= e2 ? 2 : 1) * Math.pow(10, power) : -Math.pow(10, -power) / (error2 >= e10 ? 10 : error2 >= e5 ? 5 : error2 >= e2 ? 2 : 1);
32509
+ stop = +stop, start = +start, count2 = +count2;
32510
+ return tickSpec(start, stop, count2)[2];
32468
32511
  }
32469
32512
  function tickStep(start, stop, count2) {
32470
- var step0 = Math.abs(stop - start) / Math.max(0, count2), step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)), error2 = step0 / step1;
32471
- if (error2 >= e10) step1 *= 10;
32472
- else if (error2 >= e5) step1 *= 5;
32473
- else if (error2 >= e2) step1 *= 2;
32474
- return stop < start ? -step1 : step1;
32513
+ stop = +stop, start = +start, count2 = +count2;
32514
+ const reverse = stop < start, inc = reverse ? tickIncrement(stop, start, count2) : tickIncrement(start, stop, count2);
32515
+ return (reverse ? -1 : 1) * (inc < 0 ? 1 / -inc : inc);
32475
32516
  }
32476
32517
  function initRange(domain, range2) {
32477
32518
  switch (arguments.length) {
@@ -33553,6 +33594,9 @@ function ramp(color2, n2 = 256) {
33553
33594
  canvas.width = n2;
33554
33595
  canvas.height = 1;
33555
33596
  const context = canvas.getContext("2d");
33597
+ if (!context) {
33598
+ throw new Error("Could not get 2d context from canvas");
33599
+ }
33556
33600
  for (let i2 = 0; i2 < n2; ++i2) {
33557
33601
  context.fillStyle = color2(i2 / (n2 - 1));
33558
33602
  context.fillRect(i2, 0, 1, 1);
@@ -33571,6 +33615,8 @@ function getXlinkHref(cmap) {
33571
33615
  }
33572
33616
  const useStyles$2 = makeStyles()(() => ({
33573
33617
  legend: {
33618
+ position: "relative",
33619
+ // Needed for absolute positioning of slider overlay
33574
33620
  top: "2px",
33575
33621
  right: "2px",
33576
33622
  fontSize: "10px !important",
@@ -33602,6 +33648,74 @@ const useStyles$2 = makeStyles()(() => ({
33602
33648
  },
33603
33649
  legendInvisible: {
33604
33650
  display: "none"
33651
+ },
33652
+ sliderContainer: {
33653
+ position: "absolute",
33654
+ // Position at the colormap location: top offset = titleHeight
33655
+ top: "10px",
33656
+ // titleHeight
33657
+ left: "2px",
33658
+ // Account for parent padding
33659
+ width: "calc(100% - 4px)",
33660
+ // Account for left and right padding
33661
+ height: "8px",
33662
+ // rectHeight
33663
+ "&:hover $sliderThumb": {
33664
+ opacity: 1
33665
+ }
33666
+ },
33667
+ sliderRoot: {
33668
+ position: "absolute",
33669
+ top: 0,
33670
+ left: 0,
33671
+ width: "100%",
33672
+ height: "8px",
33673
+ // rectHeight
33674
+ padding: 0,
33675
+ "& .MuiSlider-rail": {
33676
+ display: "none"
33677
+ },
33678
+ "& .MuiSlider-track": {
33679
+ display: "none"
33680
+ },
33681
+ "& .MuiSlider-valueLabel": {
33682
+ fontSize: "9px",
33683
+ padding: "2px 4px",
33684
+ backgroundColor: "rgb(0, 0, 0)",
33685
+ borderRadius: "2px"
33686
+ }
33687
+ },
33688
+ sliderThumb: {
33689
+ width: "4px",
33690
+ height: "12px",
33691
+ borderRadius: "2px",
33692
+ backgroundColor: "white",
33693
+ border: "1px solid black",
33694
+ opacity: 0,
33695
+ transition: "opacity 0.15s ease-in-out",
33696
+ "&:hover, &.Mui-focusVisible": {
33697
+ boxShadow: "0 0 0 4px rgba(0, 0, 0, 0.16)",
33698
+ opacity: 1
33699
+ },
33700
+ "&.Mui-active": {
33701
+ boxShadow: "0 0 0 6px rgba(0, 0, 0, 0.16)",
33702
+ opacity: 1
33703
+ }
33704
+ },
33705
+ colormapImage: {
33706
+ position: "absolute",
33707
+ top: "2px",
33708
+ height: "6px",
33709
+ // rectHeight
33710
+ pointerEvents: "none"
33711
+ },
33712
+ grayTrack: {
33713
+ position: "absolute",
33714
+ top: "2px",
33715
+ height: "6px",
33716
+ // rectHeight
33717
+ backgroundColor: "rgba(128, 128, 128, 0.5)",
33718
+ pointerEvents: "none"
33605
33719
  }
33606
33720
  }));
33607
33721
  const titleHeight = 10;
@@ -33611,21 +33725,23 @@ const rectMarginX = 2;
33611
33725
  function combineExtents(extents, featureAggregationStrategy) {
33612
33726
  if (Array.isArray(extents)) {
33613
33727
  if (Array.isArray(extents == null ? void 0 : extents[0])) {
33728
+ const extentsArray = extents;
33614
33729
  if (featureAggregationStrategy === "first") {
33615
- return extents[0];
33730
+ return extentsArray[0];
33616
33731
  }
33617
33732
  if (featureAggregationStrategy === "last") {
33618
- return extents.at(-1);
33733
+ return extentsArray.at(-1) || null;
33619
33734
  }
33620
33735
  if (typeof featureAggregationStrategy === "number") {
33621
33736
  const i2 = featureAggregationStrategy;
33622
- return extents[i2];
33737
+ return extentsArray[i2];
33623
33738
  }
33624
33739
  if (featureAggregationStrategy === "sum") {
33625
- return extents.reduce((a2, h) => [a2[0] + h[0], a2[1] + h[1]]);
33740
+ return extentsArray.reduce((a2, h) => [a2[0] + h[0], a2[1] + h[1]]);
33626
33741
  }
33627
33742
  if (featureAggregationStrategy === "mean") {
33628
- return extents.reduce((a2, h) => [a2[0] + h[0], a2[1] + h[1]]).map((v) => v / extents.length);
33743
+ const sum2 = extentsArray.reduce((a2, h) => [a2[0] + h[0], a2[1] + h[1]]);
33744
+ return [sum2[0] / extentsArray.length, sum2[1] / extentsArray.length];
33629
33745
  }
33630
33746
  } else {
33631
33747
  return extents;
@@ -33639,7 +33755,7 @@ function combineMissings(missings, featureAggregationStrategy) {
33639
33755
  return missings[0];
33640
33756
  }
33641
33757
  if (featureAggregationStrategy === "last") {
33642
- return missings.at(-1);
33758
+ return missings.at(-1) || null;
33643
33759
  }
33644
33760
  if (typeof featureAggregationStrategy === "number") {
33645
33761
  const i2 = featureAggregationStrategy;
@@ -33655,52 +33771,127 @@ function combineMissings(missings, featureAggregationStrategy) {
33655
33771
  return null;
33656
33772
  }
33657
33773
  function Legend(props) {
33658
- const { visible: visibleProp, positionRelative = false, highContrast = false, obsType, featureValueType, considerSelections = true, obsColorEncoding, featureSelection, featureLabelsMap, featureValueColormap, featureValueColormapRange, spatialChannelColor, spatialLayerColor, obsSetSelection, obsSetColor, featureAggregationStrategy, extent: extent2, missing, width: width2 = 100, height: height2 = 36, maxHeight: maxHeight2 = null, theme, showObsLabel = false, pointsVisible = true, contoursVisible = false, contoursFilled, contourPercentiles, contourThresholds } = props;
33659
- const svgRef = useRef();
33774
+ const {
33775
+ visible: visibleProp,
33776
+ positionRelative = false,
33777
+ highContrast = false,
33778
+ obsType,
33779
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
33780
+ featureType: _featureType = void 0,
33781
+ // Unused but accepted for API compatibility
33782
+ featureValueType,
33783
+ considerSelections = true,
33784
+ obsColorEncoding,
33785
+ featureSelection,
33786
+ featureLabelsMap,
33787
+ featureValueColormap,
33788
+ featureValueColormapRange,
33789
+ setFeatureValueColormapRange,
33790
+ spatialChannelColor,
33791
+ spatialLayerColor,
33792
+ obsSetSelection,
33793
+ obsSetColor,
33794
+ featureAggregationStrategy,
33795
+ extent: extent2,
33796
+ missing,
33797
+ width: width2 = 100,
33798
+ height: height2 = 36,
33799
+ maxHeight: maxHeight2 = null,
33800
+ theme,
33801
+ showObsLabel = false,
33802
+ pointsVisible = true,
33803
+ contoursVisible = false,
33804
+ contoursFilled,
33805
+ contourPercentiles,
33806
+ contourThresholds
33807
+ } = props;
33808
+ const svgRef = useRef(null);
33660
33809
  const { classes } = useStyles$2();
33810
+ const [localRange, setLocalRange] = useState(featureValueColormapRange);
33811
+ useEffect(() => {
33812
+ setLocalRange(featureValueColormapRange);
33813
+ }, [featureValueColormapRange]);
33814
+ const debouncedSetRange = useMemo(() => setFeatureValueColormapRange ? debounce$1((value) => {
33815
+ setFeatureValueColormapRange(value);
33816
+ }, 5, { leading: false, trailing: true }) : null, [setFeatureValueColormapRange]);
33817
+ useEffect(() => () => {
33818
+ if (debouncedSetRange) {
33819
+ debouncedSetRange.cancel();
33820
+ }
33821
+ }, [debouncedSetRange]);
33822
+ const handleSliderChange = useCallback((_event, newValue) => {
33823
+ const rangeValue = newValue;
33824
+ setLocalRange(rangeValue);
33825
+ if (debouncedSetRange) {
33826
+ debouncedSetRange(rangeValue);
33827
+ }
33828
+ }, [debouncedSetRange]);
33661
33829
  const isDarkTheme = theme === "dark";
33662
33830
  const isStaticColor = obsColorEncoding === "spatialChannelColor" || obsColorEncoding === "spatialLayerColor";
33663
33831
  const isSetColor = obsColorEncoding === "cellSetSelection";
33664
- const layerColor = Array.isArray(spatialLayerColor) && spatialLayerColor.length === 3 ? spatialLayerColor : getDefaultColor(theme);
33665
- const channelColor = Array.isArray(spatialChannelColor) && spatialChannelColor.length === 3 ? spatialChannelColor : getDefaultColor(theme);
33832
+ const layerColor = Array.isArray(spatialLayerColor) && spatialLayerColor.length === 3 ? spatialLayerColor : getDefaultColor(theme ?? "light");
33833
+ const channelColor = Array.isArray(spatialChannelColor) && spatialChannelColor.length === 3 ? spatialChannelColor : getDefaultColor(theme ?? "light");
33666
33834
  const staticColor = obsColorEncoding === "spatialChannelColor" ? channelColor : layerColor;
33667
- 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);
33835
+ const visible = visibleProp && (!considerSelections || ["geneSelection", "geneExpression"].includes(obsColorEncoding ?? "") && featureSelection && Array.isArray(featureSelection) && featureSelection.length >= 1 || isSetColor && ((obsSetSelection == null ? void 0 : obsSetSelection.length) ?? 0) > 0 && ((obsSetColor == null ? void 0 : obsSetColor.length) ?? 0) > 0 || isStaticColor);
33668
33836
  const levelZeroNames = useMemo(() => Array.from(new Set((obsSetSelection == null ? void 0 : obsSetSelection.map((setPath) => setPath[0])) || [])), [obsSetSelection]);
33669
- const dynamicHeight = isSetColor && obsSetSelection ? levelZeroNames.length * titleHeight + (obsSetSelection == null ? void 0 : obsSetSelection.length) * (rectHeight + rectMarginY) : height2 + (!pointsVisible && contoursVisible ? 25 : 0);
33837
+ const dynamicHeight = isSetColor && obsSetSelection ? levelZeroNames.length * titleHeight + ((obsSetSelection == null ? void 0 : obsSetSelection.length) ?? 0) * (rectHeight + rectMarginY) : height2 + (!pointsVisible && contoursVisible ? 25 : 0);
33670
33838
  const availHeight = maxHeight2 !== null ? Math.max(0, maxHeight2 - 4) : Infinity;
33671
33839
  const needsScroll = Number.isFinite(availHeight) && dynamicHeight > availHeight + 1;
33672
33840
  useEffect(() => {
33673
33841
  const domElement = svgRef.current;
33842
+ if (!domElement)
33843
+ return;
33674
33844
  const foregroundColor = highContrast ? "black" : isDarkTheme ? "white" : "black";
33675
33845
  const svg = select(domElement);
33676
33846
  svg.selectAll("g").remove();
33677
33847
  svg.attr("width", width2).attr("height", dynamicHeight);
33678
33848
  const g2 = svg.append("g").attr("width", width2).attr("height", dynamicHeight);
33679
- if (!considerSelections || obsColorEncoding === "geneSelection") {
33680
- const [xMin, xMax] = combineExtents(extent2, featureAggregationStrategy) || [0, 1];
33849
+ const showInteractiveSlider2 = setFeatureValueColormapRange && ["geneSelection", "geneExpression"].includes(obsColorEncoding ?? "") && pointsVisible && featureValueColormap;
33850
+ if (!considerSelections || ["geneSelection", "geneExpression"].includes(obsColorEncoding ?? "")) {
33851
+ const combinedExtent = combineExtents(extent2 ?? null, featureAggregationStrategy ?? null) || [0, 1];
33852
+ const [xMin, xMax] = combinedExtent;
33681
33853
  if (featureValueColormap && pointsVisible) {
33682
- const xlinkHref = getXlinkHref(featureValueColormap);
33683
- g2.append("image").attr("x", 0).attr("y", titleHeight).attr("width", width2).attr("height", rectHeight).attr("preserveAspectRatio", "none").attr("href", xlinkHref);
33684
- const [rMin, rMax] = featureValueColormapRange;
33854
+ const xlinkHref2 = getXlinkHref(featureValueColormap);
33855
+ const currentRange = showInteractiveSlider2 ? localRange : featureValueColormapRange;
33856
+ const [rMin, rMax] = currentRange || [0, 1];
33857
+ if (showInteractiveSlider2) ;
33858
+ else if (setFeatureValueColormapRange) {
33859
+ g2.append("image").attr("x", rMin * width2).attr("y", titleHeight).attr("width", (rMax - rMin) * width2).attr("height", rectHeight).attr("preserveAspectRatio", "none").attr("href", xlinkHref2);
33860
+ } else {
33861
+ g2.append("image").attr("x", 0).attr("y", titleHeight).attr("width", width2).attr("height", rectHeight).attr("preserveAspectRatio", "none").attr("href", xlinkHref2);
33862
+ }
33685
33863
  const scaledDataExtent = [
33686
33864
  xMin + (xMax - xMin) * rMin,
33687
33865
  xMax - (xMax - xMin) * (1 - rMax)
33688
33866
  ];
33689
- const x = linear().domain(scaledDataExtent).range([0.5, width2 - 0.5]);
33690
- const axisTicks = g2.append("g").attr("transform", `translate(0,${titleHeight + rectHeight})`).style("font-size", "10px").call(axisBottom(x).tickValues(scaledDataExtent));
33691
- axisTicks.selectAll("line,path").style("stroke", foregroundColor);
33692
- axisTicks.selectAll("text").style("fill", foregroundColor);
33693
- axisTicks.selectAll("text").attr("text-anchor", (d, i2) => i2 === 0 ? "start" : "end");
33694
- } else if (contoursVisible) {
33867
+ let x;
33868
+ if (setFeatureValueColormapRange || showInteractiveSlider2) {
33869
+ x = linear().domain(scaledDataExtent).range([rMin * width2, rMax * width2]);
33870
+ } else {
33871
+ x = linear().domain(scaledDataExtent).range([0, width2]);
33872
+ }
33873
+ if (showInteractiveSlider2) {
33874
+ const xGlobal = linear().domain([xMin, xMax]).range([0, width2 - 4]);
33875
+ const axisTicks = g2.append("g").attr("transform", `translate(0,${titleHeight + rectHeight})`).style("font-size", "10px").call(axisBottom(xGlobal).tickValues([xMin, xMax]));
33876
+ axisTicks.selectAll("line,path").style("stroke", foregroundColor);
33877
+ axisTicks.selectAll("text").style("fill", foregroundColor);
33878
+ axisTicks.selectAll("text").attr("text-anchor", (_d, i2) => i2 === 0 ? "start" : "end");
33879
+ } else {
33880
+ const axisTicks = g2.append("g").attr("transform", `translate(0,${titleHeight + rectHeight})`).style("font-size", "10px").call(axisBottom(x).tickValues(scaledDataExtent));
33881
+ axisTicks.selectAll("line,path").style("stroke", foregroundColor);
33882
+ axisTicks.selectAll("text").style("fill", foregroundColor);
33883
+ axisTicks.selectAll("text").attr("text-anchor", (_d, i2) => i2 === 0 ? "start" : "end");
33884
+ }
33885
+ } else if (contoursVisible && contourPercentiles) {
33695
33886
  const tSize = 12;
33696
33887
  const xPercentile = linear().domain([0, 1]).range([tSize / 2, width2 - tSize / 2 - 2]);
33697
- const axisTicks = g2.append("g").attr("transform", `translate(0,${titleHeight + rectHeight + 15})`).style("font-size", "9px").call(axisBottom(xPercentile).tickValues(contourPercentiles).tickFormat(format(".0%")).tickSizeOuter(0));
33888
+ const axisTicks = g2.append("g").attr("transform", `translate(0,${titleHeight + rectHeight + 15})`).style("font-size", "9px").call(axisBottom(xPercentile).tickValues(contourPercentiles).tickFormat((d) => format(".0%")(d)).tickSizeOuter(0));
33698
33889
  axisTicks.selectAll("line,path").style("stroke", foregroundColor);
33699
33890
  axisTicks.selectAll("text").style("fill", foregroundColor);
33700
33891
  const NEIGHBOR_THRESHOLD = 18;
33701
- const contourPercentages = contourPercentiles.map((x) => x * 100);
33892
+ const contourPercentages = contourPercentiles.map((p) => p * 100);
33702
33893
  if ((contourPercentages == null ? void 0 : contourPercentages[1]) - (contourPercentages == null ? void 0 : contourPercentages[0]) <= NEIGHBOR_THRESHOLD || (contourPercentages == null ? void 0 : contourPercentages[2]) - (contourPercentages == null ? void 0 : contourPercentages[1]) <= NEIGHBOR_THRESHOLD) {
33703
- axisTicks.selectAll("text").attr("transform", (d, i2) => `translate(0,${i2 === 0 || i2 === contourPercentiles.length - 1 ? 0 : 10})`);
33894
+ axisTicks.selectAll("text").attr("transform", (_d, i2) => `translate(0,${i2 === 0 || i2 === contourPercentiles.length - 1 ? 0 : 10})`);
33704
33895
  }
33705
33896
  const triangleGroupG = g2.append("g").attr("transform", `translate(0,${titleHeight + rectHeight + 4})`);
33706
33897
  contourPercentiles.forEach((p, i2) => {
@@ -33710,14 +33901,14 @@ function Legend(props) {
33710
33901
  const thresholdGroupG = g2.append("g").attr("transform", `translate(0,${titleHeight + rectHeight})`);
33711
33902
  const thresholdFormatter = format(".0f");
33712
33903
  contourPercentiles.forEach((p, i2) => {
33713
- const contourThreshold = xMin + (xMax - xMin) * ((contourThresholds == null ? void 0 : contourThresholds[i2]) / 255);
33904
+ const contourThreshold = xMin + (xMax - xMin) * (((contourThresholds == null ? void 0 : contourThresholds[i2]) ?? 0) / 255);
33714
33905
  const thresholdG = thresholdGroupG.append("g").attr("transform", `translate(${xPercentile(p)},0)`).style("font-size", "7px");
33715
33906
  thresholdG.append("text").text(thresholdFormatter(contourThreshold)).style("fill", foregroundColor).attr("text-anchor", "middle");
33716
33907
  });
33717
33908
  }
33718
33909
  }
33719
33910
  if (isStaticColor) {
33720
- g2.append("rect").attr("x", 0).attr("y", titleHeight).attr("width", width2).attr("height", rectHeight).attr("fill", `rgb(${staticColor[0]},${staticColor[1]},${staticColor[2]})`);
33911
+ g2.append("rect").attr("x", 0).attr("y", titleHeight).attr("width", width2 - 4).attr("height", rectHeight).attr("fill", `rgb(${staticColor[0]},${staticColor[1]},${staticColor[2]})`);
33721
33912
  }
33722
33913
  if (isSetColor && obsSetSelection && obsSetColor) {
33723
33914
  const obsSetSelectionByLevelZero = {};
@@ -33734,9 +33925,9 @@ function Legend(props) {
33734
33925
  y += titleHeight;
33735
33926
  setPaths.forEach((setPath) => {
33736
33927
  var _a3;
33737
- const setColor2 = ((_a3 = obsSetColor == null ? void 0 : obsSetColor.find((d) => isEqual$1(d.path, setPath))) == null ? void 0 : _a3.color) || getDefaultColor(theme);
33928
+ const setColor2 = ((_a3 = obsSetColor == null ? void 0 : obsSetColor.find((d) => isEqual$1(d.path, setPath))) == null ? void 0 : _a3.color) || getDefaultColor(theme ?? "light");
33738
33929
  g2.append("rect").attr("x", 0).attr("y", y).attr("width", rectHeight).attr("height", rectHeight).attr("fill", `rgb(${setColor2[0]},${setColor2[1]},${setColor2[2]})`);
33739
- g2.append("text").attr("text-anchor", "start").attr("dominant-baseline", "hanging").attr("x", rectHeight + rectMarginX).attr("y", y).text(setPath.at(-1)).style("font-size", "9px").style("fill", foregroundColor);
33930
+ g2.append("text").attr("text-anchor", "start").attr("dominant-baseline", "hanging").attr("x", rectHeight + rectMarginX).attr("y", y).text(setPath.at(-1) ?? "").style("font-size", "9px").style("fill", foregroundColor);
33740
33931
  y += rectHeight + rectMarginY;
33741
33932
  });
33742
33933
  });
@@ -33751,23 +33942,31 @@ function Legend(props) {
33751
33942
  const i2 = featureAggregationStrategy;
33752
33943
  featureSelectionLabelRawStr = featureSelectionLabelRaw == null ? void 0 : featureSelectionLabelRaw[i2];
33753
33944
  } else if (featureAggregationStrategy === "sum") {
33754
- featureSelectionLabelRawStr = "Sum of features";
33945
+ if (Array.isArray(featureSelection) && featureSelection.length === 1) {
33946
+ featureSelectionLabelRawStr = featureSelectionLabelRaw == null ? void 0 : featureSelectionLabelRaw[0];
33947
+ } else {
33948
+ featureSelectionLabelRawStr = "Sum of features";
33949
+ }
33755
33950
  } else if (featureAggregationStrategy === "mean") {
33756
- featureSelectionLabelRawStr = "Mean of features";
33951
+ if (Array.isArray(featureSelection) && featureSelection.length === 1) {
33952
+ featureSelectionLabelRawStr = featureSelectionLabelRaw == null ? void 0 : featureSelectionLabelRaw[0];
33953
+ } else {
33954
+ featureSelectionLabelRawStr = "Mean of features";
33955
+ }
33757
33956
  } else {
33758
33957
  featureSelectionLabelRawStr = featureSelectionLabelRaw == null ? void 0 : featureSelectionLabelRaw[0];
33759
33958
  }
33760
- const combinedMissing = combineMissings(missing, featureAggregationStrategy);
33959
+ const combinedMissing = combineMissings(missing ?? null, featureAggregationStrategy ?? null);
33761
33960
  const featureSelectionLabel = combinedMissing ? `${featureSelectionLabelRawStr} (${Math.round(combinedMissing * 100)}% NaN)` : featureSelectionLabelRawStr;
33762
- const obsLabel = capitalize$2(obsType);
33763
- const featureLabel = considerSelections ? featureSelectionLabel || capitalize$2(featureValueType) : capitalize$2(featureValueType);
33961
+ const obsLabel = capitalize$2(obsType ?? null);
33962
+ const featureLabel = considerSelections ? featureSelectionLabel || capitalize$2(featureValueType ?? null) : capitalize$2(featureValueType ?? null);
33764
33963
  const mainLabel = showObsLabel ? obsLabel : featureLabel;
33765
33964
  const subLabel = showObsLabel ? featureLabel : null;
33766
33965
  const hasSubLabel = subLabel !== null;
33767
33966
  if (!isSetColor) {
33768
- g2.append("text").attr("text-anchor", hasSubLabel ? "start" : "end").attr("dominant-baseline", "hanging").attr("x", hasSubLabel ? 0 : width2).attr("y", 0).text(mainLabel).style("font-size", "10px").style("fill", foregroundColor);
33967
+ g2.append("text").attr("text-anchor", hasSubLabel ? "start" : "end").attr("dominant-baseline", "hanging").attr("x", hasSubLabel ? 0 : width2 - 4).attr("y", 0).text(mainLabel ?? "").style("font-size", "10px").style("fill", foregroundColor);
33769
33968
  if (hasSubLabel) {
33770
- g2.append("text").attr("text-anchor", "end").attr("dominant-baseline", "hanging").attr("x", width2).attr("y", titleHeight).text(subLabel).style("font-size", "9px").style("fill", foregroundColor);
33969
+ g2.append("text").attr("text-anchor", "end").attr("dominant-baseline", "hanging").attr("x", width2 - 5).attr("y", titleHeight + rectHeight).text(subLabel ?? "").style("font-size", "9px").style("fill", foregroundColor);
33771
33970
  }
33772
33971
  }
33773
33972
  }, [
@@ -33775,6 +33974,7 @@ function Legend(props) {
33775
33974
  height2,
33776
33975
  featureValueColormap,
33777
33976
  featureValueColormapRange,
33977
+ localRange,
33778
33978
  considerSelections,
33779
33979
  obsType,
33780
33980
  obsColorEncoding,
@@ -33793,20 +33993,63 @@ function Legend(props) {
33793
33993
  contoursFilled,
33794
33994
  contoursVisible,
33795
33995
  pointsVisible,
33796
- featureAggregationStrategy
33996
+ featureAggregationStrategy,
33997
+ setFeatureValueColormapRange,
33998
+ dynamicHeight,
33999
+ highContrast,
34000
+ isStaticColor,
34001
+ missing,
34002
+ showObsLabel,
34003
+ staticColor
33797
34004
  ]);
33798
- return jsxRuntimeExports.jsx("div", { className: clsx$1(classes.legend, {
34005
+ const showInteractiveSlider = setFeatureValueColormapRange && ["geneSelection", "geneExpression"].includes(obsColorEncoding ?? "") && pointsVisible && featureValueColormap;
34006
+ const globalExtent = useMemo(() => {
34007
+ const combined = combineExtents(extent2 ?? null, featureAggregationStrategy ?? null);
34008
+ return combined || [0, 1];
34009
+ }, [extent2, featureAggregationStrategy]);
34010
+ const formatSliderValue = useCallback((value) => {
34011
+ const [xMin, xMax] = globalExtent;
34012
+ const dataValue = xMin + (xMax - xMin) * value;
34013
+ const range2 = xMax - xMin;
34014
+ if (range2 < 0.01) {
34015
+ return dataValue.toExponential(2);
34016
+ }
34017
+ if (range2 < 1) {
34018
+ return dataValue.toFixed(3);
34019
+ }
34020
+ if (range2 < 100) {
34021
+ return dataValue.toFixed(1);
34022
+ }
34023
+ return Math.round(dataValue).toString();
34024
+ }, [globalExtent]);
34025
+ const xlinkHref = featureValueColormap ? getXlinkHref(featureValueColormap) : null;
34026
+ const currentLocalRange = localRange || [0, 1];
34027
+ return jsxRuntimeExports.jsxs("div", { className: clsx$1(classes.legend, {
33799
34028
  [classes.legendRelative]: positionRelative,
33800
34029
  [classes.legendAbsolute]: !positionRelative,
33801
34030
  [classes.legendHighContrast]: highContrast,
33802
34031
  [classes.legendLowContrast]: !highContrast,
33803
34032
  [classes.legendInvisible]: !visible
33804
34033
  }), style: {
33805
- ...needsScroll ? { maxHeight: `${Math.floor(availHeight)}px`, overflowY: "auto" } : { maxHeight: void 0, overflowY: "visible" }
33806
- }, children: jsxRuntimeExports.jsx("svg", { ref: svgRef, style: {
34034
+ ...needsScroll ? { maxHeight: `${Math.floor(availHeight)}px`, overflowY: "auto" } : { maxHeight: void 0, overflowY: "visible" },
34035
+ width: `${width2}px`
34036
+ }, children: [jsxRuntimeExports.jsx("svg", { ref: svgRef, style: {
33807
34037
  width: `${width2}px`,
33808
34038
  height: `${dynamicHeight}px`
33809
- } }) });
34039
+ } }), showInteractiveSlider && xlinkHref && jsxRuntimeExports.jsxs("div", { className: classes.sliderContainer, children: [currentLocalRange[0] > 0 && jsxRuntimeExports.jsx("div", { className: classes.grayTrack, style: {
34040
+ left: 0,
34041
+ width: `${currentLocalRange[0] * 100}%`
34042
+ } }), currentLocalRange[1] < 1 && jsxRuntimeExports.jsx("div", { className: classes.grayTrack, style: {
34043
+ left: `${currentLocalRange[1] * 100}%`,
34044
+ width: `${(1 - currentLocalRange[1]) * 100}%`
34045
+ } }), jsxRuntimeExports.jsx("img", { src: xlinkHref, alt: "Colormap gradient", className: classes.colormapImage, style: {
34046
+ left: `${currentLocalRange[0] * 100}%`,
34047
+ width: `${(currentLocalRange[1] - currentLocalRange[0]) * 100}%`
34048
+ } }), jsxRuntimeExports.jsx(Slider, { className: classes.sliderRoot, value: currentLocalRange, onChange: handleSliderChange, min: 0, max: 1, step: 0.01, disableSwap: true, valueLabelDisplay: "auto", valueLabelFormat: formatSliderValue, "aria-label": "Colormap range", getAriaLabel: (index2) => index2 === 0 ? "Colormap minimum" : "Colormap maximum", getAriaValueText: (value) => formatSliderValue(value), slotProps: {
34049
+ thumb: {
34050
+ className: classes.sliderThumb
34051
+ }
34052
+ } })] })] });
33810
34053
  }
33811
34054
  makeStyles()(() => ({
33812
34055
  multiLegend: {
@@ -112664,7 +112907,7 @@ function clipExtent(x02, y02, x12, y12) {
112664
112907
  return clipStream;
112665
112908
  };
112666
112909
  }
112667
- function extent$1() {
112910
+ function extent() {
112668
112911
  var x02 = 0, y02 = 0, x12 = 960, y12 = 500, cache2, cacheStream, clip2;
112669
112912
  return clip2 = {
112670
112913
  stream: function(stream) {
@@ -113998,7 +114241,7 @@ const d3Geo = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
113998
114241
  geoBounds: bounds,
113999
114242
  geoCentroid: centroid,
114000
114243
  geoCircle: circle$1,
114001
- geoClipExtent: extent$1,
114244
+ geoClipExtent: extent,
114002
114245
  geoConicConformal: conicConformal,
114003
114246
  geoConicConformalRaw: conicConformalRaw,
114004
114247
  geoConicEqualArea: conicEqualArea,
@@ -137829,22 +138072,22 @@ function addDecoder(cases, importFn) {
137829
138072
  }
137830
138073
  cases.forEach((c) => registry$1.set(c, importFn));
137831
138074
  }
137832
- addDecoder([void 0, 1], () => import("./raw-CYkXbM-r.js").then((m) => m.default));
137833
- addDecoder(5, () => import("./lzw-DuQQG26m.js").then((m) => m.default));
138075
+ addDecoder([void 0, 1], () => import("./raw-DBEZoTXk.js").then((m) => m.default));
138076
+ addDecoder(5, () => import("./lzw-DIDyT49t.js").then((m) => m.default));
137834
138077
  addDecoder(6, () => {
137835
138078
  throw new Error("old style JPEG compression is not supported.");
137836
138079
  });
137837
- addDecoder(7, () => import("./jpeg-C-aR7Yvm.js").then((m) => m.default));
137838
- addDecoder([8, 32946], () => import("./deflate-D1zCiRQz.js").then((m) => m.default));
137839
- addDecoder(32773, () => import("./packbits-CKkWkWM2.js").then((m) => m.default));
138080
+ addDecoder(7, () => import("./jpeg-BQH57nGA.js").then((m) => m.default));
138081
+ addDecoder([8, 32946], () => import("./deflate-C6kM_d3H.js").then((m) => m.default));
138082
+ addDecoder(32773, () => import("./packbits-x4mUZGOp.js").then((m) => m.default));
137840
138083
  addDecoder(
137841
138084
  34887,
137842
- () => import("./lerc-BDETtaHZ.js").then(async (m) => {
138085
+ () => import("./lerc-Bcypgvlf.js").then(async (m) => {
137843
138086
  await m.zstd.init();
137844
138087
  return m;
137845
138088
  }).then((m) => m.default)
137846
138089
  );
137847
- addDecoder(50001, () => import("./webimage-CK0o5if1.js").then((m) => m.default));
138090
+ addDecoder(50001, () => import("./webimage-DNvdSc-_.js").then((m) => m.default));
137848
138091
  function decodeRowAcc(row, stride) {
137849
138092
  let length2 = row.length - stride;
137850
138093
  let offset2 = 0;
@@ -147813,36 +148056,8 @@ void main() {
147813
148056
  DECKGL_FILTER_COLOR(gl_FragColor, geometry);
147814
148057
  }
147815
148058
  `;
147816
- function extent(values2, valueof) {
147817
- let min;
147818
- let max2;
147819
- {
147820
- for (const value of values2) {
147821
- if (value != null) {
147822
- if (min === void 0) {
147823
- if (value >= value) min = max2 = value;
147824
- } else {
147825
- if (min > value) min = value;
147826
- if (max2 < value) max2 = value;
147827
- }
147828
- }
147829
- }
147830
- }
147831
- return [min, max2];
147832
- }
147833
- function max(values2, valueof) {
147834
- let max2;
147835
- {
147836
- for (const value of values2) {
147837
- if (value != null && (max2 < value || max2 === void 0 && value >= value)) {
147838
- max2 = value;
147839
- }
147840
- }
147841
- }
147842
- return max2;
147843
- }
147844
148059
  function normalize(arr) {
147845
- const [min, max2] = extent(arr);
148060
+ const [min, max2] = extent$1(arr);
147846
148061
  const ratio = 255 / (max2 - min);
147847
148062
  const data = new Uint8Array(arr.map((i2) => Math.floor((i2 - min) * ratio)));
147848
148063
  return data;
@@ -152870,6 +153085,7 @@ function HeatmapSubscriber(props) {
152870
153085
  obsSetSelection: cellSetSelection,
152871
153086
  featureValueColormap: geneExpressionColormap,
152872
153087
  featureValueColormapRange: geneExpressionColormapRange,
153088
+ setFeatureValueColormapRange: setGeneExpressionColormapRange,
152873
153089
  extent: obsFeatureMatrixExtent
152874
153090
  }
152875
153091
  )