@deephaven/js-plugin-pivot 0.2.0 → 0.2.1-alpha-pivots.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.
Files changed (2) hide show
  1. package/dist/index.js +869 -389
  2. package/package.json +7 -7
package/dist/index.js CHANGED
@@ -274,6 +274,9 @@ class EventShimCustomEvent extends CustomEvent {
274
274
  super(typeArg, eventInitDict);
275
275
  }
276
276
  }
277
+ function isNotNullOrUndefined(value2) {
278
+ return value2 != null;
279
+ }
277
280
  function assertNotNull(value2) {
278
281
  var message = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "Value is null or undefined";
279
282
  if (value2 == null)
@@ -1690,30 +1693,24 @@ function find(str2, type = null, opts = null) {
1690
1693
  }
1691
1694
  return filtered;
1692
1695
  }
1693
- function _defineProperty$9(obj, key, value2) {
1694
- key = _toPropertyKey$9(key);
1695
- if (key in obj) {
1696
- Object.defineProperty(obj, key, { value: value2, enumerable: true, configurable: true, writable: true });
1697
- } else {
1698
- obj[key] = value2;
1699
- }
1700
- return obj;
1701
- }
1702
- function _toPropertyKey$9(arg) {
1703
- var key = _toPrimitive$9(arg, "string");
1704
- return typeof key === "symbol" ? key : String(key);
1705
- }
1706
- function _toPrimitive$9(input, hint) {
1707
- if (typeof input !== "object" || input === null)
1708
- return input;
1709
- var prim = input[Symbol.toPrimitive];
1710
- if (prim !== void 0) {
1711
- var res = prim.call(input, hint || "default");
1712
- if (typeof res !== "object")
1713
- return res;
1696
+ function _defineProperty$9(e, r, t) {
1697
+ return (r = _toPropertyKey$9(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
1698
+ }
1699
+ function _toPropertyKey$9(t) {
1700
+ var i = _toPrimitive$9(t, "string");
1701
+ return "symbol" == typeof i ? i : i + "";
1702
+ }
1703
+ function _toPrimitive$9(t, r) {
1704
+ if ("object" != typeof t || !t)
1705
+ return t;
1706
+ var e = t[Symbol.toPrimitive];
1707
+ if (void 0 !== e) {
1708
+ var i = e.call(t, r || "default");
1709
+ if ("object" != typeof i)
1710
+ return i;
1714
1711
  throw new TypeError("@@toPrimitive must return a primitive value.");
1715
1712
  }
1716
- return (hint === "string" ? String : Number)(input);
1713
+ return ("string" === r ? String : Number)(t);
1717
1714
  }
1718
1715
  var SELECTION_DIRECTION;
1719
1716
  (function(SELECTION_DIRECTION2) {
@@ -2349,51 +2346,45 @@ function isAxisRange(range) {
2349
2346
  function isBoundedAxisRange(range) {
2350
2347
  return isAxisRange(range) && range[0] != null && range[1] != null;
2351
2348
  }
2352
- function ownKeys$1(object, enumerableOnly) {
2353
- var keys2 = Object.keys(object);
2349
+ function ownKeys$1(e, r) {
2350
+ var t = Object.keys(e);
2354
2351
  if (Object.getOwnPropertySymbols) {
2355
- var symbols = Object.getOwnPropertySymbols(object);
2356
- enumerableOnly && (symbols = symbols.filter(function(sym) {
2357
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
2358
- })), keys2.push.apply(keys2, symbols);
2359
- }
2360
- return keys2;
2361
- }
2362
- function _objectSpread$1(target) {
2363
- for (var i = 1; i < arguments.length; i++) {
2364
- var source = null != arguments[i] ? arguments[i] : {};
2365
- i % 2 ? ownKeys$1(Object(source), true).forEach(function(key) {
2366
- _defineProperty$8(target, key, source[key]);
2367
- }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$1(Object(source)).forEach(function(key) {
2368
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
2352
+ var o = Object.getOwnPropertySymbols(e);
2353
+ r && (o = o.filter(function(r2) {
2354
+ return Object.getOwnPropertyDescriptor(e, r2).enumerable;
2355
+ })), t.push.apply(t, o);
2356
+ }
2357
+ return t;
2358
+ }
2359
+ function _objectSpread$1(e) {
2360
+ for (var r = 1; r < arguments.length; r++) {
2361
+ var t = null != arguments[r] ? arguments[r] : {};
2362
+ r % 2 ? ownKeys$1(Object(t), true).forEach(function(r2) {
2363
+ _defineProperty$8(e, r2, t[r2]);
2364
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$1(Object(t)).forEach(function(r2) {
2365
+ Object.defineProperty(e, r2, Object.getOwnPropertyDescriptor(t, r2));
2369
2366
  });
2370
2367
  }
2371
- return target;
2368
+ return e;
2372
2369
  }
2373
- function _defineProperty$8(obj, key, value2) {
2374
- key = _toPropertyKey$8(key);
2375
- if (key in obj) {
2376
- Object.defineProperty(obj, key, { value: value2, enumerable: true, configurable: true, writable: true });
2377
- } else {
2378
- obj[key] = value2;
2379
- }
2380
- return obj;
2381
- }
2382
- function _toPropertyKey$8(arg) {
2383
- var key = _toPrimitive$8(arg, "string");
2384
- return typeof key === "symbol" ? key : String(key);
2385
- }
2386
- function _toPrimitive$8(input, hint) {
2387
- if (typeof input !== "object" || input === null)
2388
- return input;
2389
- var prim = input[Symbol.toPrimitive];
2390
- if (prim !== void 0) {
2391
- var res = prim.call(input, hint || "default");
2392
- if (typeof res !== "object")
2393
- return res;
2370
+ function _defineProperty$8(e, r, t) {
2371
+ return (r = _toPropertyKey$8(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
2372
+ }
2373
+ function _toPropertyKey$8(t) {
2374
+ var i = _toPrimitive$8(t, "string");
2375
+ return "symbol" == typeof i ? i : i + "";
2376
+ }
2377
+ function _toPrimitive$8(t, r) {
2378
+ if ("object" != typeof t || !t)
2379
+ return t;
2380
+ var e = t[Symbol.toPrimitive];
2381
+ if (void 0 !== e) {
2382
+ var i = e.call(t, r || "default");
2383
+ if ("object" != typeof i)
2384
+ return i;
2394
2385
  throw new TypeError("@@toPrimitive must return a primitive value.");
2395
2386
  }
2396
- return (hint === "string" ? String : Number)(input);
2387
+ return ("string" === r ? String : Number)(t);
2397
2388
  }
2398
2389
  class GridUtils {
2399
2390
  // use same constant as chrome source for windows
@@ -2666,15 +2657,35 @@ class GridUtils {
2666
2657
  } = metrics;
2667
2658
  return GridUtils.getNextShownItem(startIndex, modelRows, visibleRows, userRowHeights);
2668
2659
  }
2660
+ /**
2661
+ * Check if a separator exists between a column and the next column at a given depth.
2662
+ * A separator exists if adjacent columns have different header text at the specified depth.
2663
+ *
2664
+ * @param model The grid model
2665
+ * @param depth The header depth to check at
2666
+ * @param columnIndex The current model column index
2667
+ * @param nextColumnIndex The next model column index (undefined for last column)
2668
+ * @returns true if a separator should be shown, false otherwise
2669
+ */
2670
+ static hasColumnSeparatorAtDepth(model, depth, columnIndex, nextColumnIndex) {
2671
+ if (depth == null || columnIndex == null) {
2672
+ return false;
2673
+ }
2674
+ if (nextColumnIndex == null) {
2675
+ return true;
2676
+ }
2677
+ return model.textForColumnHeader(columnIndex, depth) !== model.textForColumnHeader(nextColumnIndex, depth);
2678
+ }
2669
2679
  /**
2670
2680
  * Gets the column index if the x/y coordinates provided are close enough to the separator, otherwise null
2671
2681
  * @param x Mouse x coordinate
2672
2682
  * @param y Mouse y coordinate
2673
2683
  * @param metrics The grid metrics
2674
2684
  * @param theme The grid theme with potential user overrides
2685
+ * @param model The grid model
2675
2686
  * @returns Index of the column separator at the coordinates provided, or null if none match
2676
2687
  */
2677
- static getColumnSeparatorIndex(x, y, metrics, theme) {
2688
+ static getColumnSeparatorIndex(x, y, metrics, theme, model) {
2678
2689
  var {
2679
2690
  rowHeaderWidth,
2680
2691
  columnHeaderHeight,
@@ -2683,7 +2694,8 @@ class GridUtils {
2683
2694
  visibleColumns,
2684
2695
  allColumnXs,
2685
2696
  allColumnWidths,
2686
- columnHeaderMaxDepth
2697
+ columnHeaderMaxDepth,
2698
+ modelColumns
2687
2699
  } = metrics;
2688
2700
  var {
2689
2701
  allowColumnResize,
@@ -2694,6 +2706,7 @@ class GridUtils {
2694
2706
  }
2695
2707
  var gridX = x - rowHeaderWidth;
2696
2708
  var halfSeparatorSize = headerSeparatorHandleSize * 0.5;
2709
+ var depth = GridUtils.getColumnHeaderDepthAtY(y, metrics);
2697
2710
  var isPreviousColumnHidden = false;
2698
2711
  for (var i = floatingColumns.length - 1; i >= 0; i -= 1) {
2699
2712
  var _allColumnXs$get, _allColumnWidths$get;
@@ -2710,7 +2723,7 @@ class GridUtils {
2710
2723
  }
2711
2724
  var minX = midX - halfSeparatorSize;
2712
2725
  var maxX = midX + halfSeparatorSize;
2713
- if (minX <= gridX && gridX <= maxX) {
2726
+ if (minX <= gridX && gridX <= maxX && GridUtils.hasColumnSeparatorAtDepth(model, depth, modelColumns.get(column), modelColumns.get(column + 1))) {
2714
2727
  return column;
2715
2728
  }
2716
2729
  isPreviousColumnHidden = isColumnHidden;
@@ -2735,7 +2748,7 @@ class GridUtils {
2735
2748
  }
2736
2749
  var _minX = _midX - halfSeparatorSize;
2737
2750
  var _maxX = _midX + halfSeparatorSize;
2738
- if (_minX <= gridX && gridX <= _maxX) {
2751
+ if (_minX <= gridX && gridX <= _maxX && GridUtils.hasColumnSeparatorAtDepth(model, depth, modelColumns.get(_column), modelColumns.get(_column + 1))) {
2739
2752
  return _column;
2740
2753
  }
2741
2754
  isPreviousColumnHidden = _isColumnHidden;
@@ -5874,51 +5887,45 @@ var memoizee = function(fn) {
5874
5887
  requireRefCounter();
5875
5888
  return plain(fn, options);
5876
5889
  };
5877
- function ownKeys(object, enumerableOnly) {
5878
- var keys2 = Object.keys(object);
5890
+ function ownKeys(e, r) {
5891
+ var t = Object.keys(e);
5879
5892
  if (Object.getOwnPropertySymbols) {
5880
- var symbols = Object.getOwnPropertySymbols(object);
5881
- enumerableOnly && (symbols = symbols.filter(function(sym) {
5882
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
5883
- })), keys2.push.apply(keys2, symbols);
5884
- }
5885
- return keys2;
5886
- }
5887
- function _objectSpread(target) {
5888
- for (var i = 1; i < arguments.length; i++) {
5889
- var source = null != arguments[i] ? arguments[i] : {};
5890
- i % 2 ? ownKeys(Object(source), true).forEach(function(key) {
5891
- _defineProperty$7(target, key, source[key]);
5892
- }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function(key) {
5893
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
5893
+ var o = Object.getOwnPropertySymbols(e);
5894
+ r && (o = o.filter(function(r2) {
5895
+ return Object.getOwnPropertyDescriptor(e, r2).enumerable;
5896
+ })), t.push.apply(t, o);
5897
+ }
5898
+ return t;
5899
+ }
5900
+ function _objectSpread(e) {
5901
+ for (var r = 1; r < arguments.length; r++) {
5902
+ var t = null != arguments[r] ? arguments[r] : {};
5903
+ r % 2 ? ownKeys(Object(t), true).forEach(function(r2) {
5904
+ _defineProperty$7(e, r2, t[r2]);
5905
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r2) {
5906
+ Object.defineProperty(e, r2, Object.getOwnPropertyDescriptor(t, r2));
5894
5907
  });
5895
5908
  }
5896
- return target;
5909
+ return e;
5897
5910
  }
5898
- function _defineProperty$7(obj, key, value2) {
5899
- key = _toPropertyKey$7(key);
5900
- if (key in obj) {
5901
- Object.defineProperty(obj, key, { value: value2, enumerable: true, configurable: true, writable: true });
5902
- } else {
5903
- obj[key] = value2;
5904
- }
5905
- return obj;
5906
- }
5907
- function _toPropertyKey$7(arg) {
5908
- var key = _toPrimitive$7(arg, "string");
5909
- return typeof key === "symbol" ? key : String(key);
5910
- }
5911
- function _toPrimitive$7(input, hint) {
5912
- if (typeof input !== "object" || input === null)
5913
- return input;
5914
- var prim = input[Symbol.toPrimitive];
5915
- if (prim !== void 0) {
5916
- var res = prim.call(input, hint || "default");
5917
- if (typeof res !== "object")
5918
- return res;
5911
+ function _defineProperty$7(e, r, t) {
5912
+ return (r = _toPropertyKey$7(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
5913
+ }
5914
+ function _toPropertyKey$7(t) {
5915
+ var i = _toPrimitive$7(t, "string");
5916
+ return "symbol" == typeof i ? i : i + "";
5917
+ }
5918
+ function _toPrimitive$7(t, r) {
5919
+ if ("object" != typeof t || !t)
5920
+ return t;
5921
+ var e = t[Symbol.toPrimitive];
5922
+ if (void 0 !== e) {
5923
+ var i = e.call(t, r || "default");
5924
+ if ("object" != typeof i)
5925
+ return i;
5919
5926
  throw new TypeError("@@toPrimitive must return a primitive value.");
5920
5927
  }
5921
- return (hint === "string" ? String : Number)(input);
5928
+ return ("string" === r ? String : Number)(t);
5922
5929
  }
5923
5930
  var memoizeClear = (fn, options) => {
5924
5931
  var isClearingCache = false;
@@ -6963,30 +6970,24 @@ const GridColorUtils = {
6963
6970
  rgbToHex,
6964
6971
  lerpColor
6965
6972
  };
6966
- function _defineProperty$6(obj, key, value2) {
6967
- key = _toPropertyKey$6(key);
6968
- if (key in obj) {
6969
- Object.defineProperty(obj, key, { value: value2, enumerable: true, configurable: true, writable: true });
6970
- } else {
6971
- obj[key] = value2;
6972
- }
6973
- return obj;
6974
- }
6975
- function _toPropertyKey$6(arg) {
6976
- var key = _toPrimitive$6(arg, "string");
6977
- return typeof key === "symbol" ? key : String(key);
6978
- }
6979
- function _toPrimitive$6(input, hint) {
6980
- if (typeof input !== "object" || input === null)
6981
- return input;
6982
- var prim = input[Symbol.toPrimitive];
6983
- if (prim !== void 0) {
6984
- var res = prim.call(input, hint || "default");
6985
- if (typeof res !== "object")
6986
- return res;
6973
+ function _defineProperty$6(e, r, t) {
6974
+ return (r = _toPropertyKey$6(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
6975
+ }
6976
+ function _toPropertyKey$6(t) {
6977
+ var i = _toPrimitive$6(t, "string");
6978
+ return "symbol" == typeof i ? i : i + "";
6979
+ }
6980
+ function _toPrimitive$6(t, r) {
6981
+ if ("object" != typeof t || !t)
6982
+ return t;
6983
+ var e = t[Symbol.toPrimitive];
6984
+ if (void 0 !== e) {
6985
+ var i = e.call(t, r || "default");
6986
+ if ("object" != typeof i)
6987
+ return i;
6987
6988
  throw new TypeError("@@toPrimitive must return a primitive value.");
6988
6989
  }
6989
- return (hint === "string" ? String : Number)(input);
6990
+ return ("string" === r ? String : Number)(t);
6990
6991
  }
6991
6992
  class GridMouseHandler {
6992
6993
  // What order this mouse handler should trigger in. Smaller numbers trigger first
@@ -7026,30 +7027,24 @@ class GridMouseHandler {
7026
7027
  return false;
7027
7028
  }
7028
7029
  }
7029
- function _defineProperty$5(obj, key, value2) {
7030
- key = _toPropertyKey$5(key);
7031
- if (key in obj) {
7032
- Object.defineProperty(obj, key, { value: value2, enumerable: true, configurable: true, writable: true });
7033
- } else {
7034
- obj[key] = value2;
7035
- }
7036
- return obj;
7037
- }
7038
- function _toPropertyKey$5(arg) {
7039
- var key = _toPrimitive$5(arg, "string");
7040
- return typeof key === "symbol" ? key : String(key);
7041
- }
7042
- function _toPrimitive$5(input, hint) {
7043
- if (typeof input !== "object" || input === null)
7044
- return input;
7045
- var prim = input[Symbol.toPrimitive];
7046
- if (prim !== void 0) {
7047
- var res = prim.call(input, hint || "default");
7048
- if (typeof res !== "object")
7049
- return res;
7030
+ function _defineProperty$5(e, r, t) {
7031
+ return (r = _toPropertyKey$5(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
7032
+ }
7033
+ function _toPropertyKey$5(t) {
7034
+ var i = _toPrimitive$5(t, "string");
7035
+ return "symbol" == typeof i ? i : i + "";
7036
+ }
7037
+ function _toPrimitive$5(t, r) {
7038
+ if ("object" != typeof t || !t)
7039
+ return t;
7040
+ var e = t[Symbol.toPrimitive];
7041
+ if (void 0 !== e) {
7042
+ var i = e.call(t, r || "default");
7043
+ if ("object" != typeof i)
7044
+ return i;
7050
7045
  throw new TypeError("@@toPrimitive must return a primitive value.");
7051
7046
  }
7052
- return (hint === "string" ? String : Number)(input);
7047
+ return ("string" === r ? String : Number)(t);
7053
7048
  }
7054
7049
  class GridSeparatorMouseHandler extends GridMouseHandler {
7055
7050
  constructor() {
@@ -7257,30 +7252,24 @@ class GridSeparatorMouseHandler extends GridMouseHandler {
7257
7252
  }
7258
7253
  }
7259
7254
  const GridSeparatorMouseHandler$1 = GridSeparatorMouseHandler;
7260
- function _defineProperty$4(obj, key, value2) {
7261
- key = _toPropertyKey$4(key);
7262
- if (key in obj) {
7263
- Object.defineProperty(obj, key, { value: value2, enumerable: true, configurable: true, writable: true });
7264
- } else {
7265
- obj[key] = value2;
7266
- }
7267
- return obj;
7268
- }
7269
- function _toPropertyKey$4(arg) {
7270
- var key = _toPrimitive$4(arg, "string");
7271
- return typeof key === "symbol" ? key : String(key);
7272
- }
7273
- function _toPrimitive$4(input, hint) {
7274
- if (typeof input !== "object" || input === null)
7275
- return input;
7276
- var prim = input[Symbol.toPrimitive];
7277
- if (prim !== void 0) {
7278
- var res = prim.call(input, hint || "default");
7279
- if (typeof res !== "object")
7280
- return res;
7255
+ function _defineProperty$4(e, r, t) {
7256
+ return (r = _toPropertyKey$4(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
7257
+ }
7258
+ function _toPropertyKey$4(t) {
7259
+ var i = _toPrimitive$4(t, "string");
7260
+ return "symbol" == typeof i ? i : i + "";
7261
+ }
7262
+ function _toPrimitive$4(t, r) {
7263
+ if ("object" != typeof t || !t)
7264
+ return t;
7265
+ var e = t[Symbol.toPrimitive];
7266
+ if (void 0 !== e) {
7267
+ var i = e.call(t, r || "default");
7268
+ if ("object" != typeof i)
7269
+ return i;
7281
7270
  throw new TypeError("@@toPrimitive must return a primitive value.");
7282
7271
  }
7283
- return (hint === "string" ? String : Number)(input);
7272
+ return ("string" === r ? String : Number)(t);
7284
7273
  }
7285
7274
  class GridColumnSeparatorMouseHandler extends GridSeparatorMouseHandler$1 {
7286
7275
  constructor() {
@@ -7313,7 +7302,7 @@ class GridColumnSeparatorMouseHandler extends GridSeparatorMouseHandler$1 {
7313
7302
  var {
7314
7303
  modelColumns
7315
7304
  } = metrics;
7316
- var separatorIndex = GridUtils.getColumnSeparatorIndex(x, y, metrics, theme);
7305
+ var separatorIndex = GridUtils.getColumnSeparatorIndex(x, y, metrics, theme, model);
7317
7306
  if (separatorIndex == null || depth == null) {
7318
7307
  return null;
7319
7308
  }
@@ -7341,30 +7330,24 @@ class GridColumnSeparatorMouseHandler extends GridSeparatorMouseHandler$1 {
7341
7330
  }
7342
7331
  const GridColumnSeparatorMouseHandler$1 = GridColumnSeparatorMouseHandler;
7343
7332
  var DEFAULT_FONT_WIDTH = 10;
7344
- function _defineProperty$3(obj, key, value2) {
7345
- key = _toPropertyKey$3(key);
7346
- if (key in obj) {
7347
- Object.defineProperty(obj, key, { value: value2, enumerable: true, configurable: true, writable: true });
7348
- } else {
7349
- obj[key] = value2;
7350
- }
7351
- return obj;
7352
- }
7353
- function _toPropertyKey$3(arg) {
7354
- var key = _toPrimitive$3(arg, "string");
7355
- return typeof key === "symbol" ? key : String(key);
7356
- }
7357
- function _toPrimitive$3(input, hint) {
7358
- if (typeof input !== "object" || input === null)
7359
- return input;
7360
- var prim = input[Symbol.toPrimitive];
7361
- if (prim !== void 0) {
7362
- var res = prim.call(input, hint || "default");
7363
- if (typeof res !== "object")
7364
- return res;
7333
+ function _defineProperty$3(e, r, t) {
7334
+ return (r = _toPropertyKey$3(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
7335
+ }
7336
+ function _toPropertyKey$3(t) {
7337
+ var i = _toPrimitive$3(t, "string");
7338
+ return "symbol" == typeof i ? i : i + "";
7339
+ }
7340
+ function _toPrimitive$3(t, r) {
7341
+ if ("object" != typeof t || !t)
7342
+ return t;
7343
+ var e = t[Symbol.toPrimitive];
7344
+ if (void 0 !== e) {
7345
+ var i = e.call(t, r || "default");
7346
+ if ("object" != typeof i)
7347
+ return i;
7365
7348
  throw new TypeError("@@toPrimitive must return a primitive value.");
7366
7349
  }
7367
- return (hint === "string" ? String : Number)(input);
7350
+ return ("string" === r ? String : Number)(t);
7368
7351
  }
7369
7352
  class CellRenderer {
7370
7353
  constructor() {
@@ -7424,30 +7407,24 @@ const CellRenderer$1 = CellRenderer;
7424
7407
  function isDataBarGridModel(model) {
7425
7408
  return (model === null || model === void 0 ? void 0 : model.dataBarOptionsForCell) !== void 0;
7426
7409
  }
7427
- function _defineProperty$2(obj, key, value2) {
7428
- key = _toPropertyKey$2(key);
7429
- if (key in obj) {
7430
- Object.defineProperty(obj, key, { value: value2, enumerable: true, configurable: true, writable: true });
7431
- } else {
7432
- obj[key] = value2;
7433
- }
7434
- return obj;
7435
- }
7436
- function _toPropertyKey$2(arg) {
7437
- var key = _toPrimitive$2(arg, "string");
7438
- return typeof key === "symbol" ? key : String(key);
7439
- }
7440
- function _toPrimitive$2(input, hint) {
7441
- if (typeof input !== "object" || input === null)
7442
- return input;
7443
- var prim = input[Symbol.toPrimitive];
7444
- if (prim !== void 0) {
7445
- var res = prim.call(input, hint || "default");
7446
- if (typeof res !== "object")
7447
- return res;
7410
+ function _defineProperty$2(e, r, t) {
7411
+ return (r = _toPropertyKey$2(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
7412
+ }
7413
+ function _toPropertyKey$2(t) {
7414
+ var i = _toPrimitive$2(t, "string");
7415
+ return "symbol" == typeof i ? i : i + "";
7416
+ }
7417
+ function _toPrimitive$2(t, r) {
7418
+ if ("object" != typeof t || !t)
7419
+ return t;
7420
+ var e = t[Symbol.toPrimitive];
7421
+ if (void 0 !== e) {
7422
+ var i = e.call(t, r || "default");
7423
+ if ("object" != typeof i)
7424
+ return i;
7448
7425
  throw new TypeError("@@toPrimitive must return a primitive value.");
7449
7426
  }
7450
- return (hint === "string" ? String : Number)(input);
7427
+ return ("string" === r ? String : Number)(t);
7451
7428
  }
7452
7429
  class DataBarCellRenderer extends CellRenderer$1 {
7453
7430
  constructor() {
@@ -7801,30 +7778,24 @@ _defineProperty$2(DataBarCellRenderer, "getGradient", memoizeClear$1((width, col
7801
7778
  // Stringify the arguments for memoization. Lets the color arrays be different arrays in memory, but still cache hit
7802
7779
  }));
7803
7780
  const DataBarCellRenderer$1 = DataBarCellRenderer;
7804
- function _defineProperty$1(obj, key, value2) {
7805
- key = _toPropertyKey$1(key);
7806
- if (key in obj) {
7807
- Object.defineProperty(obj, key, { value: value2, enumerable: true, configurable: true, writable: true });
7808
- } else {
7809
- obj[key] = value2;
7810
- }
7811
- return obj;
7812
- }
7813
- function _toPropertyKey$1(arg) {
7814
- var key = _toPrimitive$1(arg, "string");
7815
- return typeof key === "symbol" ? key : String(key);
7816
- }
7817
- function _toPrimitive$1(input, hint) {
7818
- if (typeof input !== "object" || input === null)
7819
- return input;
7820
- var prim = input[Symbol.toPrimitive];
7821
- if (prim !== void 0) {
7822
- var res = prim.call(input, hint || "default");
7823
- if (typeof res !== "object")
7824
- return res;
7781
+ function _defineProperty$1(e, r, t) {
7782
+ return (r = _toPropertyKey$1(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
7783
+ }
7784
+ function _toPropertyKey$1(t) {
7785
+ var i = _toPrimitive$1(t, "string");
7786
+ return "symbol" == typeof i ? i : i + "";
7787
+ }
7788
+ function _toPrimitive$1(t, r) {
7789
+ if ("object" != typeof t || !t)
7790
+ return t;
7791
+ var e = t[Symbol.toPrimitive];
7792
+ if (void 0 !== e) {
7793
+ var i = e.call(t, r || "default");
7794
+ if ("object" != typeof i)
7795
+ return i;
7825
7796
  throw new TypeError("@@toPrimitive must return a primitive value.");
7826
7797
  }
7827
- return (hint === "string" ? String : Number)(input);
7798
+ return ("string" === r ? String : Number)(t);
7828
7799
  }
7829
7800
  class TextCellRenderer extends CellRenderer$1 {
7830
7801
  constructor() {
@@ -8009,30 +7980,24 @@ class TextCellRenderer extends CellRenderer$1 {
8009
7980
  */
8010
7981
  }
8011
7982
  const TextCellRenderer$1 = TextCellRenderer;
8012
- function _defineProperty(obj, key, value2) {
8013
- key = _toPropertyKey(key);
8014
- if (key in obj) {
8015
- Object.defineProperty(obj, key, { value: value2, enumerable: true, configurable: true, writable: true });
8016
- } else {
8017
- obj[key] = value2;
8018
- }
8019
- return obj;
8020
- }
8021
- function _toPropertyKey(arg) {
8022
- var key = _toPrimitive(arg, "string");
8023
- return typeof key === "symbol" ? key : String(key);
8024
- }
8025
- function _toPrimitive(input, hint) {
8026
- if (typeof input !== "object" || input === null)
8027
- return input;
8028
- var prim = input[Symbol.toPrimitive];
8029
- if (prim !== void 0) {
8030
- var res = prim.call(input, hint || "default");
8031
- if (typeof res !== "object")
8032
- return res;
7983
+ function _defineProperty(e, r, t) {
7984
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e;
7985
+ }
7986
+ function _toPropertyKey(t) {
7987
+ var i = _toPrimitive(t, "string");
7988
+ return "symbol" == typeof i ? i : i + "";
7989
+ }
7990
+ function _toPrimitive(t, r) {
7991
+ if ("object" != typeof t || !t)
7992
+ return t;
7993
+ var e = t[Symbol.toPrimitive];
7994
+ if (void 0 !== e) {
7995
+ var i = e.call(t, r || "default");
7996
+ if ("object" != typeof i)
7997
+ return i;
8033
7998
  throw new TypeError("@@toPrimitive must return a primitive value.");
8034
7999
  }
8035
- return (hint === "string" ? String : Number)(input);
8000
+ return ("string" === r ? String : Number)(t);
8036
8001
  }
8037
8002
  class GridRenderer {
8038
8003
  constructor() {
@@ -9020,7 +8985,8 @@ class GridRenderer {
9020
8985
  var columnIndex = startIndex;
9021
8986
  while (columnIndex <= endIndex) {
9022
8987
  var {
9023
- columnCount
8988
+ columnCount,
8989
+ calculatedColumnWidths
9024
8990
  } = metrics;
9025
8991
  var modelColumn = getOrThrow(modelColumns, columnIndex);
9026
8992
  var columnGroupName = model.textForColumnHeader(modelColumn, depth);
@@ -9030,23 +8996,23 @@ class GridRenderer {
9030
8996
  if (columnGroupName != null) {
9031
8997
  var prevColumnIndex = columnIndex - 1;
9032
8998
  while (prevColumnIndex >= 0 && (columnGroupRight - columnGroupLeft < visibleWidth || columnGroupLeft > minX)) {
9033
- var _modelColumns$get, _ref3, _userColumnWidths$get;
8999
+ var _modelColumns$get, _ref3, _ref4, _userColumnWidths$get;
9034
9000
  var prevModelIndex = (_modelColumns$get = modelColumns.get(prevColumnIndex)) !== null && _modelColumns$get !== void 0 ? _modelColumns$get : GridUtils.getModelIndex(prevColumnIndex, movedColumns);
9035
9001
  if (prevModelIndex == null || model.textForColumnHeader(prevModelIndex, depth) !== columnGroupName) {
9036
9002
  break;
9037
9003
  }
9038
- var prevColumnWidth = (_ref3 = (_userColumnWidths$get = userColumnWidths.get(prevModelIndex)) !== null && _userColumnWidths$get !== void 0 ? _userColumnWidths$get : allColumnWidths.get(prevColumnIndex)) !== null && _ref3 !== void 0 ? _ref3 : columnWidth;
9004
+ var prevColumnWidth = (_ref3 = (_ref4 = (_userColumnWidths$get = userColumnWidths.get(prevModelIndex)) !== null && _userColumnWidths$get !== void 0 ? _userColumnWidths$get : allColumnWidths.get(prevColumnIndex)) !== null && _ref4 !== void 0 ? _ref4 : calculatedColumnWidths.get(prevModelIndex)) !== null && _ref3 !== void 0 ? _ref3 : columnWidth;
9039
9005
  columnGroupLeft -= prevColumnWidth;
9040
9006
  prevColumnIndex -= 1;
9041
9007
  }
9042
9008
  var nextColumnIndex = columnIndex + 1;
9043
9009
  while (nextColumnIndex < columnCount && (columnGroupRight - columnGroupLeft < visibleWidth || columnGroupRight < maxX)) {
9044
- var _modelColumns$get2, _ref4, _userColumnWidths$get2;
9010
+ var _modelColumns$get2, _ref5, _userColumnWidths$get2;
9045
9011
  var nextModelIndex = (_modelColumns$get2 = modelColumns.get(nextColumnIndex)) !== null && _modelColumns$get2 !== void 0 ? _modelColumns$get2 : GridUtils.getModelIndex(nextColumnIndex, movedColumns);
9046
9012
  if (model.textForColumnHeader(nextModelIndex, depth) !== columnGroupName) {
9047
9013
  break;
9048
9014
  }
9049
- var nextColumnWidth = (_ref4 = (_userColumnWidths$get2 = userColumnWidths.get(nextModelIndex)) !== null && _userColumnWidths$get2 !== void 0 ? _userColumnWidths$get2 : allColumnWidths.get(nextColumnIndex)) !== null && _ref4 !== void 0 ? _ref4 : columnWidth;
9015
+ var nextColumnWidth = (_ref5 = (_userColumnWidths$get2 = userColumnWidths.get(nextModelIndex)) !== null && _userColumnWidths$get2 !== void 0 ? _userColumnWidths$get2 : allColumnWidths.get(nextColumnIndex)) !== null && _ref5 !== void 0 ? _ref5 : columnWidth;
9050
9016
  columnGroupRight += nextColumnWidth;
9051
9017
  nextColumnIndex += 1;
9052
9018
  }
@@ -9957,6 +9923,16 @@ class PivotColumnHeaderGroup extends irisGrid.ColumnHeaderGroup {
9957
9923
  function isCorePlusDh(dh) {
9958
9924
  return "coreplus" in dh;
9959
9925
  }
9926
+ function getKeyColumnGroups(model) {
9927
+ const keyColumnGroups = [];
9928
+ for (let depth = 0; depth <= model.columnHeaderMaxDepth; depth += 1) {
9929
+ const group = model.getColumnHeaderGroup(0, depth);
9930
+ if (isPivotColumnHeaderGroup(group) && group.isKeyColumnGroup) {
9931
+ keyColumnGroups.push(group);
9932
+ }
9933
+ }
9934
+ return keyColumnGroups;
9935
+ }
9960
9936
  const GRAND_TOTALS_GROUP_NAME = "Grand Total";
9961
9937
  const TOTALS_GROUP_NAME = "Total";
9962
9938
  const ROOT_DEPTH = 2;
@@ -9972,6 +9948,7 @@ function makeColumn({
9972
9948
  type,
9973
9949
  index,
9974
9950
  description,
9951
+ isFilterable = false,
9975
9952
  isSortable = false,
9976
9953
  depth = ROOT_DEPTH,
9977
9954
  hasChildren = false,
@@ -9989,6 +9966,7 @@ function makeColumn({
9989
9966
  displayName,
9990
9967
  type,
9991
9968
  isPartitionColumn: false,
9969
+ isFilterable,
9992
9970
  isSortable,
9993
9971
  isProxy,
9994
9972
  description,
@@ -10065,10 +10043,12 @@ function makePlaceholderColumn(valueSource, originalIndex, offset) {
10065
10043
  }
10066
10044
  function makeColumnFromSource(source, index) {
10067
10045
  const { name, type, isSortable, description } = source;
10046
+ const isFilterable = true;
10068
10047
  return makeColumn({
10069
10048
  name,
10070
10049
  type,
10071
10050
  index,
10051
+ isFilterable,
10072
10052
  isSortable,
10073
10053
  description,
10074
10054
  filter: source.filter.bind(source),
@@ -10192,7 +10172,7 @@ function makeColumnGroups(pivotTable, snapshotColumns, isRootColumnExpanded = tr
10192
10172
  );
10193
10173
  return [...virtualColumnGroups, ...snapshotColumnGroups];
10194
10174
  }
10195
- const log$3 = Log.module("@deephaven/js-plugin-pivot/IrisGridPivotModel");
10175
+ const log$4 = Log.module("@deephaven/js-plugin-pivot/IrisGridPivotModel");
10196
10176
  const SET_VIEWPORT_THROTTLE = 150;
10197
10177
  const APPLY_VIEWPORT_THROTTLE = 0;
10198
10178
  const ROW_BUFFER_PAGES = 1;
@@ -10342,7 +10322,7 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
10342
10322
  return this.dh.RangeSet.ofRange(0, totalColumnCount);
10343
10323
  }
10344
10324
  if (viewportColumns.length === 0) {
10345
- log$3.debug(
10325
+ log$4.debug(
10346
10326
  "Empty viewport columns, returning minimal range",
10347
10327
  viewportColumns
10348
10328
  );
@@ -10365,7 +10345,7 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
10365
10345
  ) ?? 0
10366
10346
  );
10367
10347
  if (minIndex > maxIndex) {
10368
- log$3.warn(
10348
+ log$4.warn(
10369
10349
  "Invalid column range, minIndex > maxIndex",
10370
10350
  viewportColumns,
10371
10351
  minIndex,
@@ -10385,12 +10365,12 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
10385
10365
  __publicField(this, "setViewport", lodash_throttle(
10386
10366
  (top, bottom, columns) => {
10387
10367
  if (bottom < top) {
10388
- log$3.error("Invalid viewport", top, bottom);
10368
+ log$4.error("Invalid viewport", top, bottom);
10389
10369
  return;
10390
10370
  }
10391
10371
  const { viewport } = this;
10392
10372
  if (viewport != null && viewport.top === top && viewport.bottom === bottom && viewport.columns === columns) {
10393
- log$3.debug2("Ignoring duplicate viewport", viewport);
10373
+ log$4.debug2("Ignoring duplicate viewport", viewport);
10394
10374
  return;
10395
10375
  }
10396
10376
  this.viewport = {
@@ -10398,7 +10378,7 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
10398
10378
  bottom,
10399
10379
  columns
10400
10380
  };
10401
- log$3.debug2("setViewport", this.viewport);
10381
+ log$4.debug2("setViewport", this.viewport);
10402
10382
  this.applyViewport();
10403
10383
  },
10404
10384
  SET_VIEWPORT_THROTTLE
@@ -10419,7 +10399,7 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
10419
10399
  if (!this.viewport) {
10420
10400
  return;
10421
10401
  }
10422
- log$3.debug2("applyViewport", this.viewport);
10402
+ log$4.debug2("applyViewport", this.viewport);
10423
10403
  const { top, bottom, columns } = this.viewport;
10424
10404
  const [viewportTop, viewportBottom] = this.getCachedViewportRowRange(
10425
10405
  top,
@@ -10453,9 +10433,12 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
10453
10433
  };
10454
10434
  }
10455
10435
  get filter() {
10456
- return EMPTY_ARRAY;
10436
+ return this.pivotTable.filter;
10457
10437
  }
10458
- set filter(_) {
10438
+ set filter(filters) {
10439
+ log$4.debug2("Setting filter on pivot table", filters);
10440
+ this.pivotTable.applyFilter(filters);
10441
+ this.applyViewport();
10459
10442
  }
10460
10443
  hydratePivotSort(sort) {
10461
10444
  const sourceIndex = this.getColumnIndexByName(sort.column.name);
@@ -10466,19 +10449,19 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
10466
10449
  return this._sorts ?? EMPTY_ARRAY;
10467
10450
  }
10468
10451
  set sort(sorts) {
10469
- log$3.debug("Setting sorts on pivot table", sorts);
10452
+ log$4.debug("Setting sorts on pivot table", sorts);
10470
10453
  this._sorts = sorts;
10471
10454
  const columnBySorts = [];
10472
10455
  const rowBySorts = [];
10473
10456
  sorts.forEach((s) => {
10474
10457
  const sort = this.hydratePivotSort(s);
10475
10458
  if (sort == null) {
10476
- log$3.warn(`Cannot hydrate sort for source: ${s.column.name}`, s);
10459
+ log$4.warn(`Cannot hydrate sort for source: ${s.column.name}`, s);
10477
10460
  return;
10478
10461
  }
10479
10462
  const index = this.getColumnIndexByName(sort.name);
10480
10463
  if (index == null) {
10481
- log$3.warn(`Cannot find index for source: ${s.column.name}`, s);
10464
+ log$4.warn(`Cannot find index for source: ${s.column.name}`, s);
10482
10465
  return;
10483
10466
  }
10484
10467
  if (index < 0) {
@@ -10684,7 +10667,8 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
10684
10667
  return false;
10685
10668
  }
10686
10669
  isFilterable(columnIndex) {
10687
- return false;
10670
+ var _a;
10671
+ return ((_a = this.columns[columnIndex]) == null ? void 0 : _a.isFilterable) ?? false;
10688
10672
  }
10689
10673
  isColumnSortable(columnIndex) {
10690
10674
  var _a;
@@ -10740,7 +10724,7 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
10740
10724
  }
10741
10725
  }
10742
10726
  handleModelEvent(event) {
10743
- log$3.debug2("handleModelEvent", event);
10727
+ log$4.debug2("handleModelEvent", event);
10744
10728
  const { detail, type } = event;
10745
10729
  this.dispatchEvent(new EventShimCustomEvent(type, { detail }));
10746
10730
  }
@@ -10754,7 +10738,7 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
10754
10738
  this.formattedStringData = [];
10755
10739
  this.viewportData = this.extractSnapshotData(snapshot);
10756
10740
  this.updatePendingExpandCollapseState();
10757
- log$3.debug2("Pivot updated", {
10741
+ log$4.debug2("Pivot updated", {
10758
10742
  columns: this.columns,
10759
10743
  snapshot,
10760
10744
  snapshotColumns: this.snapshotColumns,
@@ -10769,7 +10753,7 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
10769
10753
  })
10770
10754
  );
10771
10755
  } else {
10772
- log$3.debug2("Pivot columns did not change in the update");
10756
+ log$4.debug2("Pivot columns did not change in the update");
10773
10757
  }
10774
10758
  this.dispatchEvent(new EventShimCustomEvent(irisGrid.IrisGridModel.EVENT.UPDATED));
10775
10759
  }
@@ -10919,7 +10903,7 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
10919
10903
  }
10920
10904
  }
10921
10905
  close() {
10922
- log$3.debug("close");
10906
+ log$4.debug("close");
10923
10907
  this.pivotTable.close();
10924
10908
  }
10925
10909
  get formatter() {
@@ -11011,11 +10995,11 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
11011
10995
  return true;
11012
10996
  }
11013
10997
  expandAllColumns() {
11014
- log$3.debug("expandAllColumns");
10998
+ log$4.debug("expandAllColumns");
11015
10999
  this.setColumnExpanded(this.keyColumns.length, true, true);
11016
11000
  }
11017
11001
  collapseAllColumns() {
11018
- log$3.debug("collapseAllColumns");
11002
+ log$4.debug("collapseAllColumns");
11019
11003
  this.setColumnExpanded(this.keyColumns.length, false, true);
11020
11004
  }
11021
11005
  isColumnExpandable(x, depth) {
@@ -11040,7 +11024,7 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
11040
11024
  return ((_a = this.columns[x]) == null ? void 0 : _a.isExpanded) ?? false;
11041
11025
  }
11042
11026
  setColumnExpanded(x, isExpanded, expandDescendants = false) {
11043
- log$3.debug2("setColumnExpanded", {
11027
+ log$4.debug2("setColumnExpanded", {
11044
11028
  x,
11045
11029
  isExpanded,
11046
11030
  expandDescendants
@@ -11174,7 +11158,7 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
11174
11158
  this.virtualColumns.length,
11175
11159
  this.snapshotValueSources.length
11176
11160
  );
11177
- log$3.debug2("applyBufferedViewport", {
11161
+ log$4.debug2("applyBufferedViewport", {
11178
11162
  top,
11179
11163
  bottom,
11180
11164
  columns,
@@ -11253,17 +11237,17 @@ function useIrisGridPivotModel(fetch) {
11253
11237
  }
11254
11238
  throw new Error("Invalid state");
11255
11239
  }
11256
- const log$2 = Log.module("@deephaven/js-plugin-pivot/usePivotTableFetch");
11240
+ const log$3 = Log.module("@deephaven/js-plugin-pivot/usePivotTableFetch");
11257
11241
  function usePivotTableFetch(fetch) {
11258
11242
  const api = jsapiBootstrap.useApi();
11259
11243
  return React.useCallback(
11260
11244
  () => fetch().then((widget) => {
11261
- log$2.debug("Pivot fetch result:", widget);
11245
+ log$3.debug("Pivot fetch result:", widget);
11262
11246
  if (!isCorePlusDh(api)) {
11263
11247
  throw new Error("CorePlus is not available");
11264
11248
  }
11265
11249
  const pivotTable = new api.coreplus.pivot.PivotTable(widget);
11266
- log$2.debug("Created pivot table:", pivotTable);
11250
+ log$3.debug("Created pivot table:", pivotTable);
11267
11251
  return pivotTable;
11268
11252
  }),
11269
11253
  [api, fetch]
@@ -11321,41 +11305,276 @@ class PivotColumnGroupMouseHandler extends GridMouseHandler {
11321
11305
  return false;
11322
11306
  }
11323
11307
  }
11324
- class PivotSortMouseHandler extends GridMouseHandler {
11325
- constructor(irisGrid2) {
11326
- super();
11327
- __publicField(this, "columnSource");
11328
- __publicField(this, "irisGrid");
11329
- this.columnSource = null;
11330
- this.irisGrid = irisGrid2;
11308
+ function getColumnWidth(column, metrics, themeColumnWidth) {
11309
+ const {
11310
+ firstColumn,
11311
+ allColumnWidths,
11312
+ calculatedColumnWidths,
11313
+ userColumnWidths,
11314
+ treePaddingX
11315
+ } = metrics;
11316
+ const modelColumn = GridUtils.getModelIndex(column, metrics.movedColumns);
11317
+ return userColumnWidths.get(modelColumn) ?? allColumnWidths.get(column) ?? (calculatedColumnWidths.has(modelColumn) ? (calculatedColumnWidths.get(modelColumn) ?? 0) + (column === firstColumn ? treePaddingX : 0) : void 0) ?? themeColumnWidth;
11318
+ }
11319
+ function getColumnHeaderCoordinates(state, group) {
11320
+ const { metrics, theme } = state;
11321
+ const { childIndexes, depth } = group;
11322
+ const firstChildIndex = childIndexes[0];
11323
+ const lastChildIndex = childIndexes[childIndexes.length - 1];
11324
+ if (firstChildIndex == null || lastChildIndex == null) {
11325
+ throw new Error("Group has no child columns");
11326
+ }
11327
+ const { left, right, allColumnXs, allColumnWidths, gridX, gridY } = metrics;
11328
+ const {
11329
+ filterBarHeight,
11330
+ columnHeaderHeight,
11331
+ columnWidth: themeColumnWidth
11332
+ } = theme;
11333
+ const firstVisible = Math.max(left, firstChildIndex);
11334
+ const lastVisible = Math.min(right, lastChildIndex);
11335
+ if (firstVisible > lastChildIndex || lastVisible < firstChildIndex) {
11336
+ return null;
11337
+ }
11338
+ const firstVisibleX = allColumnXs.get(firstVisible);
11339
+ if (firstVisibleX == null) {
11340
+ return null;
11341
+ }
11342
+ let groupX1 = firstVisibleX;
11343
+ for (let i = firstChildIndex; i < firstVisible; i += 1) {
11344
+ groupX1 -= getColumnWidth(i, metrics, themeColumnWidth);
11345
+ }
11346
+ const lastColumnX = allColumnXs.get(lastVisible);
11347
+ const lastColumnWidth = allColumnWidths.get(lastVisible);
11348
+ if (lastColumnX == null || lastColumnWidth == null) {
11349
+ return null;
11350
+ }
11351
+ let groupX2 = lastColumnX + lastColumnWidth;
11352
+ for (let i = lastVisible + 1; i <= lastChildIndex; i += 1) {
11353
+ groupX2 += getColumnWidth(i, metrics, themeColumnWidth);
11354
+ }
11355
+ return {
11356
+ x1: gridX + groupX1,
11357
+ y1: gridY - filterBarHeight - (depth + 1) * columnHeaderHeight,
11358
+ x2: gridX + groupX2,
11359
+ y2: gridY - filterBarHeight - depth * columnHeaderHeight
11360
+ };
11361
+ }
11362
+ class IrisGridPivotMetricCalculator extends irisGrid.IrisGridMetricCalculator {
11363
+ constructor() {
11364
+ super(...arguments);
11365
+ // Initialize with null to ensure the first check always triggers reset
11366
+ __publicField(this, "cachedIsFilterBarShown", null);
11367
+ __publicField(this, "getCachedColumnSourceLabelWidth", memoizeOne(
11368
+ (keyColumnGroups, headerHorizontalPadding, maxColumnWidth, state) => {
11369
+ let result = 0;
11370
+ keyColumnGroups.forEach((group) => {
11371
+ const sourceIndex = -group.depth;
11372
+ const width = this.getColumnHeaderGroupWidth(
11373
+ sourceIndex,
11374
+ 0,
11375
+ state,
11376
+ maxColumnWidth
11377
+ );
11378
+ result = Math.max(result, width + headerHorizontalPadding);
11379
+ });
11380
+ return result;
11381
+ }
11382
+ ));
11331
11383
  }
11332
11384
  /**
11333
- * Get the column source from a grid point
11334
- * @param gridPoint The grid point to check
11335
- * @returns The column source index if the grid point is in a column source header, else null
11385
+ * Resets column width caches if filter bar visibility has changed
11386
+ * to adjust for the minimum filter box width.
11387
+ * @param state The current IrisGridPivotMetricState
11336
11388
  */
11337
- getColumnSourceHeaderFromGridPoint(gridPoint) {
11338
- const { column, row, columnHeaderDepth } = gridPoint;
11339
- const { model } = this.irisGrid.props;
11340
- assertNotNull(model);
11341
- const sourceIndex = columnHeaderDepth != null ? -columnHeaderDepth : null;
11342
- if (column == null || row !== null || columnHeaderDepth == null) {
11389
+ resetHeaderWidthsIfFilterBarChanged(state) {
11390
+ const { isFilterBarShown } = state;
11391
+ if (this.cachedIsFilterBarShown !== isFilterBarShown) {
11392
+ this.resetCalculatedHeaderGroupWidths();
11393
+ }
11394
+ this.cachedIsFilterBarShown = isFilterBarShown;
11395
+ }
11396
+ getColumnHeaderGroupWidth(modelColumn, depth, state, maxColumnWidth) {
11397
+ const baseWidth = super.getColumnHeaderGroupWidth(
11398
+ modelColumn,
11399
+ depth,
11400
+ state,
11401
+ maxColumnWidth
11402
+ );
11403
+ const { isFilterBarShown, model } = state;
11404
+ if (!isFilterBarShown) {
11405
+ return baseWidth;
11406
+ }
11407
+ const group = model.getColumnHeaderGroup(modelColumn, depth);
11408
+ if (!isPivotColumnHeaderGroup(group) || !group.isKeyColumnGroup) {
11409
+ return baseWidth;
11410
+ }
11411
+ const { theme } = state;
11412
+ const { columnSourceFilterMinWidth } = theme;
11413
+ return baseWidth + columnSourceFilterMinWidth;
11414
+ }
11415
+ /**
11416
+ * Calculate the width needed for the column source labels
11417
+ * @param model The IrisGridPivotModel instance
11418
+ * @param state The current IrisGridPivotMetricState
11419
+ * @returns The calculated width for the column source labels
11420
+ */
11421
+ calculateColumnSourceLabelWidth(model, state) {
11422
+ const { theme } = state;
11423
+ const { headerHorizontalPadding, maxColumnWidth } = theme;
11424
+ const keyColumnGroups = getKeyColumnGroups(model);
11425
+ return this.getCachedColumnSourceLabelWidth(
11426
+ keyColumnGroups,
11427
+ headerHorizontalPadding,
11428
+ maxColumnWidth,
11429
+ state
11430
+ );
11431
+ }
11432
+ /**
11433
+ * Gets the metrics for the current state. This method has to be called before setColumnSize or resetColumnSize.
11434
+ * @param state The current IrisGridPivotMetricState
11435
+ * @returns The metrics for the current state
11436
+ */
11437
+ getMetrics(state) {
11438
+ const { model } = state;
11439
+ if (!isIrisGridPivotModel(model)) {
11440
+ throw new Error("Model is not an IrisGridPivotModel");
11441
+ }
11442
+ const columnSourceLabelWidth = this.calculateColumnSourceLabelWidth(
11443
+ model,
11444
+ state
11445
+ );
11446
+ this.resetHeaderWidthsIfFilterBarChanged(state);
11447
+ return {
11448
+ ...super.getMetrics(state),
11449
+ columnSourceLabelWidth
11450
+ };
11451
+ }
11452
+ /**
11453
+ * Get metrics for positioning the filter bar input field.
11454
+ * @param index The visible index of the column to get the filter box coordinates for
11455
+ * @param state The current IrisGridMetricState
11456
+ * @param metrics The grid metrics
11457
+ * @returns Coordinates for the filter input field, or null if positioning cannot be calculated
11458
+ */
11459
+ // eslint-disable-next-line class-methods-use-this
11460
+ getFilterInputCoordinates(index, state, metrics) {
11461
+ if (index >= 0) {
11462
+ return super.getFilterInputCoordinates(index, state, metrics);
11463
+ }
11464
+ const { model, theme } = state;
11465
+ if (!isIrisGridPivotModel(model)) {
11343
11466
  return null;
11344
11467
  }
11345
- const group = model.getColumnHeaderGroup(column, columnHeaderDepth);
11346
- if (sourceIndex != null && sourceIndex < 0 && isIrisGridPivotModel(model) && model.isColumnSortable(sourceIndex) && isPivotColumnHeaderGroup(group) && group.isKeyColumnGroup) {
11347
- return sourceIndex;
11468
+ const { gridY, columnSourceLabelWidth } = metrics;
11469
+ const { columnSourceFilterMinWidth, filterBarHeight } = theme;
11470
+ const depth = -index;
11471
+ const keyColumnGroup = model.getColumnHeaderGroup(0, depth);
11472
+ if (keyColumnGroup == null || !isPivotColumnHeaderGroup(keyColumnGroup) || !keyColumnGroup.isKeyColumnGroup) {
11473
+ return null;
11474
+ }
11475
+ const groupCoords = getColumnHeaderCoordinates(
11476
+ { metrics, theme, model },
11477
+ keyColumnGroup
11478
+ );
11479
+ if (groupCoords == null) {
11480
+ return null;
11481
+ }
11482
+ const { x1, x2 } = groupCoords;
11483
+ const columnSourceFilterWidth = Math.max(
11484
+ columnSourceFilterMinWidth,
11485
+ x2 - x1 - columnSourceLabelWidth
11486
+ );
11487
+ const x = x2 - columnSourceFilterWidth;
11488
+ const y = gridY - theme.columnHeaderHeight - (1 - index) * (filterBarHeight ?? 0);
11489
+ return {
11490
+ x,
11491
+ y,
11492
+ width: columnSourceFilterWidth + 1,
11493
+ // cover right border
11494
+ height: (filterBarHeight ?? 0) - 1
11495
+ // remove bottom border
11496
+ };
11497
+ }
11498
+ /**
11499
+ * Calculate the new left index to bring the given column into view.
11500
+ * @param column The column that should be scrolled into view
11501
+ * @param state The current IrisGridMetricState
11502
+ * @param metrics The grid metrics
11503
+ * @returns The left column index to scroll to, or null if no scroll is needed
11504
+ */
11505
+ getScrollLeftForColumn(column, state, metrics) {
11506
+ if (column < 0) {
11507
+ return null;
11348
11508
  }
11509
+ return super.getScrollLeftForColumn(column, state, metrics);
11510
+ }
11511
+ }
11512
+ function getColumnSourceHeaderFromGridPoint(model, gridPoint) {
11513
+ const { column, row, columnHeaderDepth } = gridPoint;
11514
+ const sourceIndex = columnHeaderDepth != null ? -columnHeaderDepth : null;
11515
+ if (column == null || row !== null || columnHeaderDepth == null) {
11349
11516
  return null;
11350
11517
  }
11518
+ const group = model.getColumnHeaderGroup(column, columnHeaderDepth);
11519
+ if (sourceIndex != null && sourceIndex < 0 && isIrisGridPivotModel(model) && isPivotColumnHeaderGroup(group) && group.isKeyColumnGroup) {
11520
+ return sourceIndex;
11521
+ }
11522
+ return null;
11523
+ }
11524
+ function isGridPointInColumnSourceFilterBox(model, gridPoint, metrics, theme) {
11525
+ if (!isIrisGridPivotModel(model)) {
11526
+ return false;
11527
+ }
11528
+ const { column, row, columnHeaderDepth } = gridPoint;
11529
+ if (column == null || row !== null || columnHeaderDepth == null) {
11530
+ return false;
11531
+ }
11532
+ const sourceIndex = getColumnSourceHeaderFromGridPoint(model, gridPoint);
11533
+ if (sourceIndex == null) {
11534
+ return false;
11535
+ }
11536
+ const group = model.getColumnHeaderGroup(column, columnHeaderDepth);
11537
+ if (!isPivotColumnHeaderGroup(group)) {
11538
+ return false;
11539
+ }
11540
+ const coords = getColumnHeaderCoordinates(
11541
+ { metrics, theme, model },
11542
+ group
11543
+ );
11544
+ if (coords == null) {
11545
+ return false;
11546
+ }
11547
+ const { columnSourceFilterMinWidth } = theme;
11548
+ const { columnSourceLabelWidth } = metrics;
11549
+ const { x1, x2 } = coords;
11550
+ const columnSourceFilterWidth = Math.max(
11551
+ x2 - x1 - columnSourceLabelWidth,
11552
+ columnSourceFilterMinWidth
11553
+ );
11554
+ return gridPoint.x > x2 - columnSourceFilterWidth;
11555
+ }
11556
+ const log$2 = Log.module("@deephaven/js-plugin-pivot/PivotSortMouseHandler");
11557
+ class PivotSortMouseHandler extends GridMouseHandler {
11558
+ constructor(irisGrid2) {
11559
+ super();
11560
+ __publicField(this, "columnSource");
11561
+ __publicField(this, "irisGrid");
11562
+ this.columnSource = null;
11563
+ this.irisGrid = irisGrid2;
11564
+ }
11351
11565
  // We need to remember where the down started, because the canvas element will trigger a click where mouseUp is
11352
11566
  onDown(gridPoint, grid, event) {
11353
- this.columnSource = this.getColumnSourceHeaderFromGridPoint(gridPoint);
11567
+ const { model } = this.irisGrid.props;
11568
+ assertNotNull(model);
11569
+ this.columnSource = getColumnSourceHeaderFromGridPoint(model, gridPoint);
11570
+ log$2.debug("onDown", gridPoint, this.columnSource);
11354
11571
  return false;
11355
11572
  }
11356
11573
  onClick(gridPoint, grid, event) {
11357
- const columnSource = this.getColumnSourceHeaderFromGridPoint(gridPoint);
11358
- if (columnSource != null && columnSource === this.columnSource) {
11574
+ const { model } = this.irisGrid.props;
11575
+ assertNotNull(model);
11576
+ const columnSource = getColumnSourceHeaderFromGridPoint(model, gridPoint);
11577
+ if (columnSource != null && columnSource === this.columnSource && model.isColumnSortable(columnSource)) {
11359
11578
  const addToExisting = components.ContextActionUtils.isModifierKeyDown(event);
11360
11579
  this.irisGrid.toggleSort(columnSource, addToExisting);
11361
11580
  return true;
@@ -11363,10 +11582,55 @@ class PivotSortMouseHandler extends GridMouseHandler {
11363
11582
  return false;
11364
11583
  }
11365
11584
  }
11585
+ function isPivotGridMetrics(metrics) {
11586
+ return metrics.columnSourceLabelWidth !== void 0;
11587
+ }
11588
+ class PivotFilterMouseHandler extends GridMouseHandler {
11589
+ constructor(irisGrid2) {
11590
+ super();
11591
+ __publicField(this, "irisGrid");
11592
+ this.irisGrid = irisGrid2;
11593
+ }
11594
+ onDown(gridPoint) {
11595
+ const { model } = this.irisGrid.props;
11596
+ const { isFilterBarShown, metrics } = this.irisGrid.state;
11597
+ const sourceIndex = getColumnSourceHeaderFromGridPoint(model, gridPoint);
11598
+ if (sourceIndex != null) {
11599
+ assertNotNull(metrics, "Metrics not set");
11600
+ if (!isPivotGridMetrics(metrics)) {
11601
+ throw new Error("PivotGridMetrics required");
11602
+ }
11603
+ const theme = this.irisGrid.getTheme();
11604
+ if (isFilterBarShown && theme.columnHeaderHeight != null && theme.filterBarHeight != null && isGridPointInColumnSourceFilterBox(model, gridPoint, metrics, theme)) {
11605
+ this.irisGrid.focusFilterBar(sourceIndex);
11606
+ return true;
11607
+ }
11608
+ }
11609
+ return false;
11610
+ }
11611
+ onClick(gridPoint, grid, event) {
11612
+ const { model } = this.irisGrid.props;
11613
+ const { isFilterBarShown, metrics } = this.irisGrid.state;
11614
+ const sourceIndex = getColumnSourceHeaderFromGridPoint(model, gridPoint);
11615
+ if (sourceIndex != null) {
11616
+ assertNotNull(metrics, "Metrics not set");
11617
+ if (!isPivotGridMetrics(metrics)) {
11618
+ throw new Error("PivotGridMetrics required");
11619
+ }
11620
+ const theme = this.irisGrid.getTheme();
11621
+ if (isFilterBarShown && theme.columnHeaderHeight != null && theme.filterBarHeight != null && isGridPointInColumnSourceFilterBox(model, gridPoint, metrics, theme)) {
11622
+ return true;
11623
+ }
11624
+ }
11625
+ return false;
11626
+ }
11627
+ }
11366
11628
  function usePivotMouseHandlers() {
11367
11629
  return React.useMemo(
11368
11630
  () => [
11369
11631
  (irisGrid2) => new PivotColumnGroupMouseHandler(irisGrid2),
11632
+ // Filter handler should consume events before sort
11633
+ (irisGrid2) => new PivotFilterMouseHandler(irisGrid2),
11370
11634
  (irisGrid2) => new PivotSortMouseHandler(irisGrid2)
11371
11635
  ],
11372
11636
  []
@@ -11377,23 +11641,19 @@ function getColumnGroupName(model, modelColumn, depth) {
11377
11641
  return (_a = model.getColumnHeaderGroup(modelColumn, depth ?? 0)) == null ? void 0 : _a.name;
11378
11642
  }
11379
11643
  class IrisGridPivotRenderer extends irisGrid.IrisGridRenderer {
11644
+ drawColumnHeaders(context, state) {
11645
+ super.drawColumnHeaders(context, state);
11646
+ this.drawColumnSourceFilters(context, state);
11647
+ }
11380
11648
  drawColumnHeadersAtDepth(context, state, range, bounds, depth) {
11381
- const { metrics, model, theme } = state;
11649
+ const { isFilterBarShown, metrics, model, theme } = state;
11382
11650
  if (!isIrisGridPivotModel(model)) {
11383
11651
  throw new Error("Unsupported model type");
11384
11652
  }
11385
- const {
11386
- modelColumns,
11387
- allColumnXs,
11388
- gridX,
11389
- userColumnWidths,
11390
- allColumnWidths,
11391
- movedColumns
11392
- } = metrics;
11393
- const { columnHeaderHeight, columnWidth } = theme;
11653
+ const { modelColumns } = metrics;
11654
+ const { columnHeaderHeight } = theme;
11394
11655
  const { columnHeaderMaxDepth } = model;
11395
11656
  const { minX, maxX } = bounds;
11396
- const visibleWidth = maxX - minX;
11397
11657
  if (columnHeaderMaxDepth === 0) {
11398
11658
  return;
11399
11659
  }
@@ -11413,71 +11673,61 @@ class IrisGridPivotRenderer extends irisGrid.IrisGridRenderer {
11413
11673
  if (depth > 0) {
11414
11674
  let columnIndex = startIndex;
11415
11675
  while (columnIndex <= endIndex) {
11416
- const { columnCount } = metrics;
11417
11676
  const modelColumn = getOrThrow(modelColumns, columnIndex);
11418
11677
  const columnGroupColor = model.colorForColumnHeader(
11419
11678
  modelColumn,
11420
11679
  depth,
11421
11680
  theme
11422
11681
  );
11423
- const headerGroup = model.getColumnHeaderGroup(modelColumn, depth ?? 0);
11682
+ const headerGroup = model.getColumnHeaderGroup(modelColumn, depth);
11424
11683
  const isExpandable = isPivotColumnHeaderGroup(headerGroup) && headerGroup.isExpandable;
11425
11684
  const isExpanded = isPivotColumnHeaderGroup(headerGroup) && headerGroup.isExpanded;
11426
- const columnGroupName = getColumnGroupName(model, modelColumn, depth);
11427
- let columnGroupLeft = getOrThrow(allColumnXs, columnIndex) + gridX;
11428
- let columnGroupRight = columnGroupLeft + getOrThrow(allColumnWidths, columnIndex);
11429
- if (columnGroupName != null) {
11430
- let prevColumnIndex = columnIndex - 1;
11431
- while (prevColumnIndex >= 0 && (columnGroupRight - columnGroupLeft < visibleWidth || columnGroupLeft > minX)) {
11432
- const prevModelIndex = modelColumns.get(prevColumnIndex) ?? GridUtils.getModelIndex(prevColumnIndex, movedColumns);
11433
- if (prevModelIndex == null || getColumnGroupName(model, prevModelIndex, depth) !== columnGroupName) {
11434
- break;
11435
- }
11436
- const prevColumnWidth = userColumnWidths.get(prevModelIndex) ?? allColumnWidths.get(prevColumnIndex) ?? columnWidth;
11437
- columnGroupLeft -= prevColumnWidth;
11438
- prevColumnIndex -= 1;
11439
- }
11440
- let nextColumnIndex = columnIndex + 1;
11441
- while (nextColumnIndex < columnCount && (columnGroupRight - columnGroupLeft < visibleWidth || columnGroupRight < maxX)) {
11442
- const nextModelIndex = modelColumns.get(nextColumnIndex) ?? GridUtils.getModelIndex(nextColumnIndex, movedColumns);
11443
- if (getColumnGroupName(model, nextModelIndex, depth) !== columnGroupName) {
11444
- break;
11445
- }
11446
- const nextColumnWidth = userColumnWidths.get(nextModelIndex) ?? allColumnWidths.get(nextColumnIndex) ?? columnWidth;
11447
- columnGroupRight += nextColumnWidth;
11448
- nextColumnIndex += 1;
11449
- }
11450
- columnIndex = nextColumnIndex - 1;
11451
- const isFullWidth = columnGroupRight - columnGroupLeft >= visibleWidth;
11452
- let x = columnGroupLeft;
11453
- if (isFullWidth) {
11454
- if (columnGroupRight < maxX) {
11455
- x = columnGroupRight - visibleWidth;
11456
- } else if (columnGroupLeft < minX) {
11457
- x = minX;
11685
+ const groupName = getColumnGroupName(model, modelColumn, depth);
11686
+ if (groupName != null && isPivotColumnHeaderGroup(headerGroup)) {
11687
+ const coords = getColumnHeaderCoordinates(state, headerGroup);
11688
+ if (coords != null) {
11689
+ const { x1: columnGroupLeft, x2: columnGroupRight } = coords;
11690
+ columnIndex = headerGroup.childIndexes[headerGroup.childIndexes.length - 1];
11691
+ const columnWidth = columnGroupRight - columnGroupLeft;
11692
+ let headerRightPadding;
11693
+ if (isPivotColumnHeaderGroup(headerGroup) && headerGroup.isKeyColumnGroup === true && theme.columnSourceFilterMinWidth != null) {
11694
+ if (isFilterBarShown) {
11695
+ headerRightPadding = Math.max(
11696
+ theme.columnSourceFilterMinWidth,
11697
+ columnWidth - metrics.columnSourceLabelWidth
11698
+ );
11699
+ } else {
11700
+ const { advancedFilters, quickFilters } = state;
11701
+ const { filterBarCollapsedHeight } = theme;
11702
+ if (advancedFilters.size > 0 || quickFilters.size > 0) {
11703
+ headerRightPadding = filterBarCollapsedHeight;
11704
+ }
11705
+ }
11458
11706
  }
11707
+ const sort = jsapiUtils.TableUtils.getSortForColumn(model.sort, groupName);
11708
+ this.drawColumnHeader(
11709
+ context,
11710
+ state,
11711
+ model.textForColumnHeader(modelColumn, depth) ?? "",
11712
+ columnGroupLeft,
11713
+ columnWidth,
11714
+ {
11715
+ backgroundColor: columnGroupColor ?? void 0
11716
+ },
11717
+ bounds,
11718
+ isExpandable,
11719
+ isExpanded,
11720
+ sort,
11721
+ headerRightPadding
11722
+ );
11459
11723
  }
11460
- this.drawColumnHeader(
11461
- context,
11462
- state,
11463
- model.textForColumnHeader(modelColumn, depth) ?? "",
11464
- x,
11465
- Math.min(columnGroupRight - columnGroupLeft, visibleWidth),
11466
- {
11467
- backgroundColor: columnGroupColor ?? void 0
11468
- },
11469
- bounds,
11470
- isExpandable,
11471
- isExpanded,
11472
- jsapiUtils.TableUtils.getSortForColumn(model.sort, columnGroupName)
11473
- );
11474
11724
  }
11475
11725
  columnIndex += 1;
11476
11726
  }
11477
11727
  }
11478
11728
  context.restore();
11479
11729
  }
11480
- drawColumnHeader(context, state, columnText, columnX, columnWidth, style, bounds, isExpandable = false, isExpanded = false, sort = null) {
11730
+ drawColumnHeader(context, state, columnText, columnX, columnWidth, style, bounds, isExpandable = false, isExpanded = false, sort = null, headerRightPadding) {
11481
11731
  if (columnWidth <= 0) {
11482
11732
  return;
11483
11733
  }
@@ -11493,7 +11743,7 @@ class IrisGridPivotRenderer extends irisGrid.IrisGridRenderer {
11493
11743
  white
11494
11744
  } = theme;
11495
11745
  const { fontWidthsLower, fontWidthsUpper, width } = metrics;
11496
- const maxWidth = columnWidth - headerHorizontalPadding * 2;
11746
+ const maxLabelWidth = columnWidth - headerHorizontalPadding * 2 - (headerRightPadding ?? 0);
11497
11747
  const {
11498
11748
  backgroundColor = headerBackgroundColor,
11499
11749
  separatorColor = headerSeparatorColor
@@ -11539,7 +11789,7 @@ class IrisGridPivotRenderer extends irisGrid.IrisGridRenderer {
11539
11789
  const renderText = this.textCellRenderer.getCachedTruncatedString(
11540
11790
  context,
11541
11791
  columnText,
11542
- maxWidth,
11792
+ maxLabelWidth,
11543
11793
  fontWidthLower,
11544
11794
  fontWidthUpper
11545
11795
  );
@@ -11549,15 +11799,15 @@ class IrisGridPivotRenderer extends irisGrid.IrisGridRenderer {
11549
11799
  maxX -= headerHorizontalPadding;
11550
11800
  const treeMarkerPadding = isExpandable ? iconSize : 0;
11551
11801
  const contentLeft = columnX + headerHorizontalPadding;
11552
- const visibleLeft = lodash_clamp(contentLeft, minX, maxX);
11553
- const contentRight = columnX + columnWidth - headerHorizontalPadding;
11554
- const visibleRight = lodash_clamp(contentRight, minX, maxX);
11555
- const visibleWidth = visibleRight - visibleLeft;
11802
+ const contentViewportLeft = lodash_clamp(contentLeft, minX, maxX);
11803
+ const contentRight = columnX + columnWidth - headerHorizontalPadding - (headerRightPadding ?? 0);
11804
+ const contentViewportRight = lodash_clamp(contentRight, minX, maxX);
11805
+ const contentViewportWidth = contentViewportRight - contentViewportLeft;
11556
11806
  const textWidth = this.getCachedHeaderWidth(context, renderText);
11557
11807
  const contentWidth = textWidth + treeMarkerPadding;
11558
11808
  const isBeyondLeft = contentLeft < minX;
11559
11809
  if (isBeyondLeft) {
11560
- if (contentWidth < visibleWidth) {
11810
+ if (contentWidth < contentViewportWidth) {
11561
11811
  x = minX;
11562
11812
  } else {
11563
11813
  x = contentRight - contentWidth;
@@ -11622,9 +11872,13 @@ class IrisGridPivotRenderer extends irisGrid.IrisGridRenderer {
11622
11872
  );
11623
11873
  }
11624
11874
  drawColumnSourceSortIndicator(context, state, sort, columnText, columnX, columnWidth, bounds) {
11625
- const { metrics, theme } = state;
11626
- const { gridX, columnHeaderHeight } = metrics;
11627
- const { headerHorizontalPadding, iconSize: themeIconSize } = theme;
11875
+ const { isFilterBarShown, metrics, theme, quickFilters, advancedFilters } = state;
11876
+ const { gridX, columnHeaderHeight, columnSourceLabelWidth } = metrics;
11877
+ const {
11878
+ iconSize: themeIconSize,
11879
+ columnSourceFilterMinWidth,
11880
+ filterBarCollapsedHeight
11881
+ } = theme;
11628
11882
  const iconSize = Math.round(themeIconSize * 0.75);
11629
11883
  if (sort == null) {
11630
11884
  return;
@@ -11633,12 +11887,15 @@ class IrisGridPivotRenderer extends irisGrid.IrisGridRenderer {
11633
11887
  if (!icon) {
11634
11888
  return;
11635
11889
  }
11636
- const textWidth = this.getCachedHeaderWidth(context, columnText);
11637
- const textRight = gridX + columnX + textWidth + headerHorizontalPadding;
11638
- let { maxX } = bounds;
11639
- maxX -= headerHorizontalPadding;
11640
- const defaultX = gridX + columnX + columnWidth - iconSize;
11641
- const x = textRight > maxX ? textRight + 1 : Math.min(maxX, defaultX);
11890
+ if (columnSourceFilterMinWidth == null || columnSourceFilterMinWidth <= 0) {
11891
+ return;
11892
+ }
11893
+ const expandedFilterWidth = Math.max(
11894
+ columnWidth - columnSourceLabelWidth,
11895
+ columnSourceFilterMinWidth
11896
+ );
11897
+ const collapsedFilterWidth = advancedFilters.size > 0 || quickFilters.size > 0 ? filterBarCollapsedHeight : 0;
11898
+ const x = gridX + columnX + columnWidth - iconSize - (isFilterBarShown ? expandedFilterWidth : collapsedFilterWidth) - 1;
11642
11899
  const y = (columnHeaderHeight - iconSize) * 0.5;
11643
11900
  context.save();
11644
11901
  context.fillStyle = theme.headerSortBarColor;
@@ -11646,6 +11903,218 @@ class IrisGridPivotRenderer extends irisGrid.IrisGridRenderer {
11646
11903
  context.fill(icon);
11647
11904
  context.restore();
11648
11905
  }
11906
+ drawColumnSourceFilters(context, state) {
11907
+ const { isFilterBarShown, quickFilters, advancedFilters } = state;
11908
+ if (isFilterBarShown) {
11909
+ this.drawExpandedColumnSourceFilters(context, state);
11910
+ } else if (quickFilters != null && quickFilters.size > 0 || advancedFilters != null && advancedFilters.size > 0) {
11911
+ this.drawCollapsedColumnSourceFilters(context, state);
11912
+ }
11913
+ }
11914
+ drawExpandedColumnSourceFilters(context, state) {
11915
+ const { model, metrics, theme, quickFilters, advancedFilters } = state;
11916
+ const { columnSourceFilterMinWidth } = theme;
11917
+ if (columnSourceFilterMinWidth == null || columnSourceFilterMinWidth <= 0) {
11918
+ return;
11919
+ }
11920
+ const { columnSourceLabelWidth } = metrics;
11921
+ const filterBoxes = getKeyColumnGroups(model).map((group) => {
11922
+ const coords = getColumnHeaderCoordinates(state, group);
11923
+ if (coords == null) {
11924
+ return null;
11925
+ }
11926
+ const { x1, y1, x2, y2 } = coords;
11927
+ const columnSourceFilterWidth = Math.max(
11928
+ x2 - x1 - columnSourceLabelWidth,
11929
+ columnSourceFilterMinWidth
11930
+ );
11931
+ return {
11932
+ depth: group.depth,
11933
+ x1: x2 - columnSourceFilterWidth,
11934
+ y1,
11935
+ x2,
11936
+ y2
11937
+ };
11938
+ }).filter(isNotNullOrUndefined);
11939
+ if (filterBoxes.length === 0) {
11940
+ return;
11941
+ }
11942
+ context.save();
11943
+ context.font = theme.filterBarFont;
11944
+ context.textAlign = "left";
11945
+ if (quickFilters != null && quickFilters.size > 0 || advancedFilters != null && advancedFilters.size > 0) {
11946
+ context.fillStyle = theme.filterBarExpandedActiveBackgroundColor;
11947
+ } else {
11948
+ context.fillStyle = theme.filterBarExpandedBackgroundColor;
11949
+ }
11950
+ context.fillRect(
11951
+ filterBoxes[0].x1,
11952
+ filterBoxes[filterBoxes.length - 1].y1,
11953
+ filterBoxes[0].x2 - filterBoxes[0].x1,
11954
+ filterBoxes[0].y2 - filterBoxes[filterBoxes.length - 1].y1
11955
+ );
11956
+ context.strokeStyle = theme.filterBarSeparatorColor;
11957
+ context.beginPath();
11958
+ filterBoxes.forEach(({ x1, y1, x2, y2 }) => {
11959
+ const w = x2 - x1;
11960
+ const h = y2 - y1;
11961
+ context.rect(x1 + 0.5, y1 + 0.5, w, h - 2);
11962
+ });
11963
+ context.stroke();
11964
+ filterBoxes.forEach(({ x1, x2, depth }) => {
11965
+ this.drawExpandedColumnSourceFilter(context, state, depth, x1, x2 - x1);
11966
+ });
11967
+ context.restore();
11968
+ }
11969
+ drawExpandedColumnSourceFilter(context, state, headerDepth, inputX, inputWidth) {
11970
+ if (inputWidth <= 0) {
11971
+ return;
11972
+ }
11973
+ const { metrics, theme, quickFilters, advancedFilters } = state;
11974
+ const {
11975
+ filterBarHeight,
11976
+ filterBarExpandedActiveCellBackgroundColor,
11977
+ filterBarErrorColor,
11978
+ filterBarHorizontalPadding,
11979
+ headerColor
11980
+ } = theme;
11981
+ const { columnHeaderHeight, gridY } = metrics;
11982
+ const filterIndex = -headerDepth;
11983
+ const quickFilter = quickFilters.get(filterIndex);
11984
+ const advancedFilter = advancedFilters.get(filterIndex);
11985
+ if (quickFilter == null && advancedFilter == null) {
11986
+ return;
11987
+ }
11988
+ let text = null;
11989
+ if (quickFilter != null) {
11990
+ const { text: filterText } = quickFilter;
11991
+ text = filterText;
11992
+ if (text == null || text === "") {
11993
+ text = jsapiUtils.TableUtils.getFilterText(quickFilter.filter);
11994
+ }
11995
+ if (text != null) {
11996
+ const { fontWidthsLower, fontWidthsUpper } = metrics;
11997
+ const fontWidthLower = fontWidthsLower.get(context.font);
11998
+ const fontWidthUpper = fontWidthsUpper.get(context.font);
11999
+ const maxLength = inputWidth - filterBarHorizontalPadding * 2;
12000
+ text = this.textCellRenderer.getCachedTruncatedString(
12001
+ context,
12002
+ text,
12003
+ maxLength,
12004
+ fontWidthLower,
12005
+ fontWidthUpper
12006
+ );
12007
+ }
12008
+ }
12009
+ const inputY = gridY - filterBarHeight - columnHeaderHeight - columnHeaderHeight * headerDepth;
12010
+ const isFilterValid = irisGrid.IrisGridRenderer.isFilterValid(
12011
+ advancedFilter,
12012
+ quickFilter
12013
+ );
12014
+ context.save();
12015
+ if (isFilterValid && filterBarExpandedActiveCellBackgroundColor != null) {
12016
+ context.fillStyle = filterBarExpandedActiveCellBackgroundColor;
12017
+ context.fillRect(
12018
+ inputX + 1,
12019
+ // +1 left border
12020
+ inputY + 1,
12021
+ // +1 top border
12022
+ inputWidth - 1,
12023
+ // -1 right border
12024
+ filterBarHeight - 3
12025
+ // -3 top, bottom border and bottom casing
12026
+ );
12027
+ } else if (filterBarErrorColor != null) {
12028
+ context.fillStyle = filterBarErrorColor;
12029
+ context.lineWidth = 2;
12030
+ context.strokeStyle = filterBarErrorColor;
12031
+ const rectLeft = inputX + 2;
12032
+ const rectTop = inputY + 2;
12033
+ const rectWidth = inputWidth - 3;
12034
+ const rectHeight = filterBarHeight - 5;
12035
+ context.strokeRect(rectLeft, rectTop, rectWidth, rectHeight);
12036
+ }
12037
+ if (text != null && text !== "") {
12038
+ const textX = inputX + filterBarHorizontalPadding;
12039
+ const textY = inputY + filterBarHeight * 0.5 + 1;
12040
+ context.fillStyle = headerColor;
12041
+ context.fillText(text, textX, textY);
12042
+ }
12043
+ context.restore();
12044
+ }
12045
+ drawCollapsedColumnSourceFilters(context, state) {
12046
+ const { metrics, model, theme } = state;
12047
+ const { gridX, gridY, columnHeaderHeight, columnHeaderMaxDepth } = metrics;
12048
+ const { headerSeparatorColor, filterBarCollapsedHeight } = theme;
12049
+ if (filterBarCollapsedHeight <= 0) {
12050
+ return;
12051
+ }
12052
+ const filterBoxes = getKeyColumnGroups(model).map((group) => {
12053
+ const coords = getColumnHeaderCoordinates(state, group);
12054
+ if (coords == null) {
12055
+ return null;
12056
+ }
12057
+ const { x2: x22, y1, y2 } = coords;
12058
+ return {
12059
+ depth: group.depth,
12060
+ x1: x22 - filterBarCollapsedHeight,
12061
+ y1,
12062
+ x2: x22,
12063
+ y2
12064
+ };
12065
+ }).filter(isNotNullOrUndefined);
12066
+ if (filterBoxes.length === 0) {
12067
+ return;
12068
+ }
12069
+ context.save();
12070
+ const { x2 } = filterBoxes[filterBoxes.length - 1];
12071
+ context.fillStyle = headerSeparatorColor;
12072
+ context.fillRect(
12073
+ gridX + x2 - filterBarCollapsedHeight,
12074
+ gridY - columnHeaderHeight * columnHeaderMaxDepth - filterBarCollapsedHeight,
12075
+ filterBarCollapsedHeight,
12076
+ columnHeaderHeight * (columnHeaderMaxDepth - 1)
12077
+ );
12078
+ filterBoxes.forEach(({ x2: columnRight, depth }) => {
12079
+ this.drawCollapsedColumnSourceFilter(context, state, depth, columnRight);
12080
+ });
12081
+ context.restore();
12082
+ }
12083
+ // eslint-disable-next-line class-methods-use-this
12084
+ drawCollapsedColumnSourceFilter(context, state, headerDepth, columnRight) {
12085
+ if (columnRight <= 0) {
12086
+ return;
12087
+ }
12088
+ const { metrics, theme, quickFilters, advancedFilters } = state;
12089
+ const { columnHeaderHeight, gridY } = metrics;
12090
+ const filterIndex = -headerDepth;
12091
+ const quickFilter = quickFilters.get(filterIndex);
12092
+ const advancedFilter = advancedFilters.get(filterIndex);
12093
+ const {
12094
+ filterBarCollapsedHeight,
12095
+ filterBarActiveColor,
12096
+ filterBarActiveBackgroundColor,
12097
+ filterBarErrorColor
12098
+ } = theme;
12099
+ context.save();
12100
+ const isFilterValid = irisGrid.IrisGridRenderer.isFilterValid(
12101
+ advancedFilter,
12102
+ quickFilter
12103
+ );
12104
+ if (filterBarActiveBackgroundColor != null && quickFilter == null && advancedFilter == null) {
12105
+ context.fillStyle = filterBarActiveBackgroundColor;
12106
+ } else if (filterBarActiveColor != null && isFilterValid) {
12107
+ context.fillStyle = filterBarActiveColor;
12108
+ } else if (filterBarErrorColor != null) {
12109
+ context.fillStyle = filterBarErrorColor;
12110
+ }
12111
+ const x = columnRight - filterBarCollapsedHeight + 1;
12112
+ const y = gridY - filterBarCollapsedHeight - columnHeaderHeight - columnHeaderHeight * headerDepth;
12113
+ const rectWidth = filterBarCollapsedHeight - 1;
12114
+ const rectHeight = columnHeaderHeight - 1;
12115
+ context.fillRect(x, y, rectWidth, rectHeight);
12116
+ context.restore();
12117
+ }
11649
12118
  }
11650
12119
  function usePivotRenderer() {
11651
12120
  return React.useMemo(() => new IrisGridPivotRenderer(), []);
@@ -11656,7 +12125,8 @@ const IrisGridPivotThemeColors = Object.freeze({
11656
12125
  });
11657
12126
  function getIrisGridPivotTheme() {
11658
12127
  return Object.freeze({
11659
- ...components.resolveCssVariablesInRecord(IrisGridPivotThemeColors)
12128
+ ...components.resolveCssVariablesInRecord(IrisGridPivotThemeColors),
12129
+ columnSourceFilterMinWidth: 120
11660
12130
  });
11661
12131
  }
11662
12132
  const log$1 = Log.module("@deephaven/js-plugin-pivot/usePivotTheme");
@@ -11667,6 +12137,12 @@ function usePivotTheme() {
11667
12137
  return getIrisGridPivotTheme();
11668
12138
  }, [theme]);
11669
12139
  }
12140
+ function usePivotMetricCalculatorFactory() {
12141
+ return React.useMemo(
12142
+ () => (...args) => new IrisGridPivotMetricCalculator(...args),
12143
+ []
12144
+ );
12145
+ }
11670
12146
  function PivotWidget({
11671
12147
  fetch
11672
12148
  }) {
@@ -11674,6 +12150,7 @@ function PivotWidget({
11674
12150
  const mouseHandlers = usePivotMouseHandlers();
11675
12151
  const renderer = usePivotRenderer();
11676
12152
  const pivotTheme = usePivotTheme();
12153
+ const getPivotMetricCalculator = usePivotMetricCalculatorFactory();
11677
12154
  const fetchResult = useIrisGridPivotModel(pivotFetch);
11678
12155
  if (fetchResult.status === "loading") {
11679
12156
  return /* @__PURE__ */ jsxRuntimeExports.jsx(components.LoadingOverlay, { isLoading: true });
@@ -11694,7 +12171,8 @@ function PivotWidget({
11694
12171
  model,
11695
12172
  mouseHandlers,
11696
12173
  renderer,
11697
- theme: pivotTheme
12174
+ theme: pivotTheme,
12175
+ getMetricCalculator: getPivotMetricCalculator
11698
12176
  }
11699
12177
  );
11700
12178
  }
@@ -11707,6 +12185,7 @@ function useHydratePivotGrid(id, metadata) {
11707
12185
  const mouseHandlers = usePivotMouseHandlers();
11708
12186
  const renderer = usePivotRenderer();
11709
12187
  const theme = usePivotTheme();
12188
+ const getMetricCalculator = usePivotMetricCalculatorFactory();
11710
12189
  const { status } = objectFetch;
11711
12190
  if (status === "loading") {
11712
12191
  log.debug("Widget is loading");
@@ -11739,7 +12218,8 @@ function useHydratePivotGrid(id, metadata) {
11739
12218
  metadata,
11740
12219
  mouseHandlers,
11741
12220
  renderer,
11742
- theme
12221
+ theme,
12222
+ getMetricCalculator
11743
12223
  }
11744
12224
  };
11745
12225
  }