@grafana/flamegraph 11.5.1 → 11.6.0-221763

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -56,7 +56,7 @@ const FlameGraphContextMenu = ({
56
56
  search
57
57
  }) => {
58
58
  function renderItems() {
59
- const extraButtons = (getExtraContextMenuButtons == null ? void 0 : getExtraContextMenuButtons(itemData, data.data, {
59
+ const extraButtons = (getExtraContextMenuButtons == null ? undefined : getExtraContextMenuButtons(itemData, data.data, {
60
60
  selectedView,
61
61
  isDiff: data.isDiffFlamegraph(),
62
62
  search,
@@ -475,10 +475,10 @@ function getPackageName(name) {
475
475
  for (const [_, matcher] of matchers) {
476
476
  const match = name.match(matcher);
477
477
  if (match) {
478
- return ((_a = match.groups) == null ? void 0 : _a.packageName) || "";
478
+ return ((_a = match.groups) == null ? undefined : _a.packageName) || "";
479
479
  }
480
480
  }
481
- return void 0;
481
+ return undefined;
482
482
  }
483
483
 
484
484
  function useFlameRender(options) {
@@ -620,7 +620,7 @@ function walkTree(root, direction, data, totalViewTicks, rangeMin, rangeMax, wra
620
620
  const stack = [];
621
621
  stack.push({ item: root, levelOffset: 0 });
622
622
  const pixelsPerTick = wrapperWidth * window.devicePixelRatio / totalViewTicks / (rangeMax - rangeMin);
623
- let collapsedItemRendered = void 0;
623
+ let collapsedItemRendered = undefined;
624
624
  while (stack.length > 0) {
625
625
  const { item, levelOffset } = stack.shift();
626
626
  let curBarTicks = item.value;
@@ -639,10 +639,10 @@ function walkTree(root, direction, data, totalViewTicks, rangeMin, rangeMax, wra
639
639
  offsetModifier = direction === "children" ? -1 : 1;
640
640
  skipRender = true;
641
641
  } else {
642
- collapsedItemRendered = void 0;
642
+ collapsedItemRendered = undefined;
643
643
  }
644
644
  } else {
645
- collapsedItemRendered = void 0;
645
+ collapsedItemRendered = undefined;
646
646
  }
647
647
  if (!skipRender) {
648
648
  const barX = getBarX(item.start, totalViewTicks, rangeMin, pixelsPerTick);
@@ -665,7 +665,7 @@ function useColorFunction(totalTicks, totalTicksRight, colorScheme, theme, muted
665
665
  if (muted && !matchedLabels) {
666
666
  return mutedColor;
667
667
  }
668
- const barColor = item.valueRight !== void 0 && (colorScheme === ColorSchemeDiff.Default || colorScheme === ColorSchemeDiff.DiffColorBlind) ? getBarColorByDiff(item.value, item.valueRight, totalTicks, totalTicksRight, colorScheme) : colorScheme === ColorScheme.ValueBased ? getBarColorByValue(item.value, totalTicks, rangeMin, rangeMax) : getBarColorByPackage(label, theme);
668
+ const barColor = item.valueRight !== undefined && (colorScheme === ColorSchemeDiff.Default || colorScheme === ColorSchemeDiff.DiffColorBlind) ? getBarColorByDiff(item.value, item.valueRight, totalTicks, totalTicksRight, colorScheme) : colorScheme === ColorScheme.ValueBased ? getBarColorByValue(item.value, totalTicks, rangeMin, rangeMax) : getBarColorByPackage(label, theme);
669
669
  if (matchedLabels) {
670
670
  return matchedLabels.has(label) ? barColor.toHslString() : mutedColor;
671
671
  }
@@ -769,7 +769,7 @@ const FlameGraphCanvas = ({
769
769
  });
770
770
  const onGraphClick = react.useCallback(
771
771
  (e) => {
772
- setTooltipItem(void 0);
772
+ setTooltipItem(undefined);
773
773
  const pixelsPerTick = graphRef.current.clientWidth / totalViewTicks / (rangeMax - rangeMin);
774
774
  const item = convertPixelCoordinatesToBarCoordinates(
775
775
  { x: e.nativeEvent.offsetX, y: e.nativeEvent.offsetY },
@@ -789,7 +789,7 @@ const FlameGraphCanvas = ({
789
789
  label: data.getLabel(item.itemIndexes[0])
790
790
  });
791
791
  } else {
792
- setClickedItemData(void 0);
792
+ setClickedItemData(undefined);
793
793
  }
794
794
  },
795
795
  [data, rangeMin, rangeMax, totalViewTicks, root, direction, depth, collapsedMap]
@@ -797,9 +797,9 @@ const FlameGraphCanvas = ({
797
797
  const [mousePosition, setMousePosition] = react.useState();
798
798
  const onGraphMouseMove = react.useCallback(
799
799
  (e) => {
800
- if (clickedItemData === void 0) {
801
- setTooltipItem(void 0);
802
- setMousePosition(void 0);
800
+ if (clickedItemData === undefined) {
801
+ setTooltipItem(undefined);
802
+ setMousePosition(undefined);
803
803
  const pixelsPerTick = graphRef.current.clientWidth / totalViewTicks / (rangeMax - rangeMin);
804
804
  const item = convertPixelCoordinatesToBarCoordinates(
805
805
  { x: e.nativeEvent.offsetX, y: e.nativeEvent.offsetY },
@@ -820,13 +820,13 @@ const FlameGraphCanvas = ({
820
820
  [rangeMin, rangeMax, totalViewTicks, clickedItemData, setMousePosition, root, direction, depth, collapsedMap]
821
821
  );
822
822
  const onGraphMouseLeave = react.useCallback(() => {
823
- setTooltipItem(void 0);
823
+ setTooltipItem(undefined);
824
824
  }, []);
825
825
  react.useEffect(() => {
826
826
  const handleOnClick = (e) => {
827
827
  var _a;
828
- if (e.target instanceof HTMLElement && ((_a = e.target.parentElement) == null ? void 0 : _a.id) !== "flameGraphCanvasContainer_clickOutsideCheck") {
829
- setClickedItemData(void 0);
828
+ if (e.target instanceof HTMLElement && ((_a = e.target.parentElement) == null ? undefined : _a.id) !== "flameGraphCanvasContainer_clickOutsideCheck") {
829
+ setClickedItemData(undefined);
830
830
  }
831
831
  };
832
832
  window.addEventListener("click", handleOnClick);
@@ -850,7 +850,7 @@ const FlameGraphCanvas = ({
850
850
  item: tooltipItem,
851
851
  data,
852
852
  totalTicks: totalViewTicks,
853
- collapseConfig: tooltipItem ? collapsedMap.get(tooltipItem) : void 0
853
+ collapseConfig: tooltipItem ? collapsedMap.get(tooltipItem) : undefined
854
854
  }
855
855
  ),
856
856
  !showFlameGraphOnly && clickedItemData && /* @__PURE__ */ jsxRuntime.jsx(
@@ -861,7 +861,7 @@ const FlameGraphCanvas = ({
861
861
  collapsing,
862
862
  collapseConfig: collapsedMap.get(clickedItemData.item),
863
863
  onMenuItemClick: () => {
864
- setClickedItemData(void 0);
864
+ setClickedItemData(undefined);
865
865
  },
866
866
  onItemFocus: () => {
867
867
  setRangeMin(clickedItemData.item.start / totalViewTicks);
@@ -925,10 +925,10 @@ const convertPixelCoordinatesToBarCoordinates = (pos, root, direction, depth, pi
925
925
  let next = root;
926
926
  let currentLevel = direction === "children" ? 0 : depth - 1;
927
927
  const levelIndex = Math.floor(pos.y / (PIXELS_PER_LEVEL / window.devicePixelRatio));
928
- let found = void 0;
928
+ let found = undefined;
929
929
  while (next) {
930
930
  const node = next;
931
- next = void 0;
931
+ next = undefined;
932
932
  if (currentLevel === levelIndex) {
933
933
  found = node;
934
934
  break;
@@ -976,7 +976,7 @@ const FlameGraphMetadata = react.memo(
976
976
  );
977
977
  if (sandwichedLabel) {
978
978
  parts.push(
979
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
979
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: sandwichedLabel, placement: "top", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
980
980
  /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { size: "sm", name: "angle-right" }),
981
981
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles.metadataPill, children: [
982
982
  /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { size: "sm", name: "gf-show-context" }),
@@ -994,17 +994,18 @@ const FlameGraphMetadata = react.memo(
994
994
  }
995
995
  )
996
996
  ] })
997
- ] }, "sandwich")
997
+ ] }) }, "sandwich")
998
998
  );
999
999
  }
1000
1000
  if (focusedItem) {
1001
- const percentValue = Math.round(1e4 * (focusedItem.item.value / totalTicks)) / 100;
1001
+ const percentValue = totalTicks > 0 ? Math.round(1e4 * (focusedItem.item.value / totalTicks)) / 100 : 0;
1002
+ const iconName = percentValue > 0 ? "eye" : "exclamation-circle";
1002
1003
  parts.push(
1003
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1004
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: focusedItem.label, placement: "top", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1004
1005
  /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { size: "sm", name: "angle-right" }),
1005
1006
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles.metadataPill, children: [
1006
- /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { size: "sm", name: "eye" }),
1007
- " ",
1007
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { size: "sm", name: iconName }),
1008
+ "\xA0",
1008
1009
  percentValue,
1009
1010
  "% of total",
1010
1011
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1019,7 +1020,7 @@ const FlameGraphMetadata = react.memo(
1019
1020
  }
1020
1021
  )
1021
1022
  ] })
1022
- ] }, "focus")
1023
+ ] }) }, "focus")
1023
1024
  );
1024
1025
  }
1025
1026
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles.metadata, children: parts });
@@ -1045,8 +1046,10 @@ const getStyles$4 = (theme) => ({
1045
1046
  margin: theme.spacing(0, 0.5)
1046
1047
  }),
1047
1048
  metadata: css.css({
1048
- margin: "8px 0",
1049
- textAlign: "center"
1049
+ display: "flex",
1050
+ alignItems: "center",
1051
+ justifyContent: "center",
1052
+ margin: "8px 0"
1050
1053
  }),
1051
1054
  metadataPillName: css.css({
1052
1055
  label: "metadataPillName",
@@ -1092,14 +1095,14 @@ const FlameGraph = ({
1092
1095
  if (data) {
1093
1096
  let levels2 = data.getLevels();
1094
1097
  let totalProfileTicks2 = levels2.length ? levels2[0][0].value : 0;
1095
- let totalProfileTicksRight2 = levels2.length ? levels2[0][0].valueRight : void 0;
1098
+ let totalProfileTicksRight2 = levels2.length ? levels2[0][0].valueRight : undefined;
1096
1099
  let totalViewTicks2 = totalProfileTicks2;
1097
- let levelsCallers2 = void 0;
1100
+ let levelsCallers2 = undefined;
1098
1101
  if (sandwichItem) {
1099
1102
  const [callers, callees] = data.getSandwichLevels(sandwichItem);
1100
1103
  levels2 = callees;
1101
1104
  levelsCallers2 = callers;
1102
- totalViewTicks2 = (_c = (_b = (_a = callees[0]) == null ? void 0 : _a[0]) == null ? void 0 : _b.value) != null ? _c : 0;
1105
+ totalViewTicks2 = (_c = (_b = (_a = callees[0]) == null ? undefined : _a[0]) == null ? undefined : _b.value) != null ? _c : 0;
1103
1106
  }
1104
1107
  setLevels(levels2);
1105
1108
  setLevelsCallers(levelsCallers2);
@@ -1134,40 +1137,45 @@ const FlameGraph = ({
1134
1137
  search,
1135
1138
  selectedView
1136
1139
  };
1137
- const canvas = levelsCallers ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1138
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles.sandwichCanvasWrapper, children: [
1139
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles.sandwichMarker, children: [
1140
- "Callers",
1141
- /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { className: styles.sandwichMarkerIcon, name: "arrow-down" })
1142
- ] }),
1143
- /* @__PURE__ */ jsxRuntime.jsx(
1144
- FlameGraphCanvas,
1145
- {
1146
- ...commonCanvasProps,
1147
- root: levelsCallers[levelsCallers.length - 1][0],
1148
- depth: levelsCallers.length,
1149
- direction: "parents",
1150
- collapsing: false
1151
- }
1152
- )
1153
- ] }),
1154
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles.sandwichCanvasWrapper, children: [
1155
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: css.cx(styles.sandwichMarker, styles.sandwichMarkerCalees), children: [
1156
- /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { className: styles.sandwichMarkerIcon, name: "arrow-up" }),
1157
- "Callees"
1140
+ let canvas = null;
1141
+ if (levelsCallers == null ? undefined : levelsCallers.length) {
1142
+ canvas = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1143
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles.sandwichCanvasWrapper, children: [
1144
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles.sandwichMarker, children: [
1145
+ "Callers",
1146
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { className: styles.sandwichMarkerIcon, name: "arrow-down" })
1147
+ ] }),
1148
+ /* @__PURE__ */ jsxRuntime.jsx(
1149
+ FlameGraphCanvas,
1150
+ {
1151
+ ...commonCanvasProps,
1152
+ root: levelsCallers[levelsCallers.length - 1][0],
1153
+ depth: levelsCallers.length,
1154
+ direction: "parents",
1155
+ collapsing: false
1156
+ }
1157
+ )
1158
1158
  ] }),
1159
- /* @__PURE__ */ jsxRuntime.jsx(
1160
- FlameGraphCanvas,
1161
- {
1162
- ...commonCanvasProps,
1163
- root: levels[0][0],
1164
- depth: levels.length,
1165
- direction: "children",
1166
- collapsing: false
1167
- }
1168
- )
1169
- ] })
1170
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(FlameGraphCanvas, { ...commonCanvasProps, root: levels[0][0], depth: levels.length, direction: "children" });
1159
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles.sandwichCanvasWrapper, children: [
1160
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: css.cx(styles.sandwichMarker, styles.sandwichMarkerCalees), children: [
1161
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { className: styles.sandwichMarkerIcon, name: "arrow-up" }),
1162
+ "Callees"
1163
+ ] }),
1164
+ /* @__PURE__ */ jsxRuntime.jsx(
1165
+ FlameGraphCanvas,
1166
+ {
1167
+ ...commonCanvasProps,
1168
+ root: levels[0][0],
1169
+ depth: levels.length,
1170
+ direction: "children",
1171
+ collapsing: false
1172
+ }
1173
+ )
1174
+ ] })
1175
+ ] });
1176
+ } else if (levels == null ? undefined : levels.length) {
1177
+ canvas = /* @__PURE__ */ jsxRuntime.jsx(FlameGraphCanvas, { ...commonCanvasProps, root: levels[0][0], depth: levels.length, direction: "children" });
1178
+ }
1171
1179
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles.graph, children: [
1172
1180
  /* @__PURE__ */ jsxRuntime.jsx(
1173
1181
  FlameGraphMetadata,
@@ -1219,7 +1227,7 @@ function mergeParentSubtrees(roots, data) {
1219
1227
  function getParentSubtrees(roots) {
1220
1228
  return roots.map((r) => {
1221
1229
  var _a, _b;
1222
- if (!((_a = r.parents) == null ? void 0 : _a.length)) {
1230
+ if (!((_a = r.parents) == null ? undefined : _a.length)) {
1223
1231
  return r;
1224
1232
  }
1225
1233
  const newRoot = {
@@ -1240,7 +1248,7 @@ function getParentSubtrees(roots) {
1240
1248
  newNode.value = args.child.value;
1241
1249
  args.child.parents = [newNode];
1242
1250
  }
1243
- if ((_b = args.parent.parents) == null ? void 0 : _b.length) {
1251
+ if ((_b = args.parent.parents) == null ? undefined : _b.length) {
1244
1252
  stack.push({ child: newNode, parent: args.parent.parents[0] });
1245
1253
  }
1246
1254
  }
@@ -1252,7 +1260,7 @@ function mergeSubtrees(roots, data, direction = "children") {
1252
1260
  const oppositeDirection = direction === "parents" ? "children" : "parents";
1253
1261
  const levels = [];
1254
1262
  const stack = [
1255
- { previous: void 0, items: roots, level: 0 }
1263
+ { previous: undefined, items: roots, level: 0 }
1256
1264
  ];
1257
1265
  while (stack.length) {
1258
1266
  const args = stack.shift();
@@ -1271,7 +1279,7 @@ function mergeSubtrees(roots, data, direction = "children") {
1271
1279
  levels[args.level].push(newItem);
1272
1280
  if (args.previous) {
1273
1281
  newItem[oppositeDirection] = [args.previous];
1274
- const prevSiblingsVal = ((_a = args.previous[direction]) == null ? void 0 : _a.reduce((acc, node) => {
1282
+ const prevSiblingsVal = ((_a = args.previous[direction]) == null ? undefined : _a.reduce((acc, node) => {
1275
1283
  return acc + node.value;
1276
1284
  }, 0)) || 0;
1277
1285
  newItem.start = args.previous.start + prevSiblingsVal;
@@ -1297,11 +1305,11 @@ function mergeSubtrees(roots, data, direction = "children") {
1297
1305
  function nestedSetToLevels(container, options) {
1298
1306
  const levels = [];
1299
1307
  let offset = 0;
1300
- let parent = void 0;
1308
+ let parent = undefined;
1301
1309
  const uniqueLabels = {};
1302
1310
  for (let i = 0; i < container.data.length; i++) {
1303
1311
  const currentLevel = container.getLevel(i);
1304
- const prevLevel = i > 0 ? container.getLevel(i - 1) : void 0;
1312
+ const prevLevel = i > 0 ? container.getLevel(i - 1) : undefined;
1305
1313
  levels[currentLevel] = levels[currentLevel] || [];
1306
1314
  if (prevLevel && prevLevel >= currentLevel) {
1307
1315
  const lastSibling = levels[currentLevel][levels[currentLevel].length - 1];
@@ -1311,7 +1319,7 @@ function nestedSetToLevels(container, options) {
1311
1319
  const newItem = {
1312
1320
  itemIndexes: [i],
1313
1321
  value: container.getValue(i) + container.getValueRight(i),
1314
- valueRight: container.isDiffFlamegraph() ? container.getValueRight(i) : void 0,
1322
+ valueRight: container.isDiffFlamegraph() ? container.getValueRight(i) : undefined,
1315
1323
  start: offset,
1316
1324
  parents: parent && [parent],
1317
1325
  children: [],
@@ -1328,8 +1336,8 @@ function nestedSetToLevels(container, options) {
1328
1336
  parent = newItem;
1329
1337
  levels[currentLevel].push(newItem);
1330
1338
  }
1331
- const collapsedMapContainer = new CollapsedMapBuilder(options == null ? void 0 : options.collapsingThreshold);
1332
- if (options == null ? void 0 : options.collapsing) {
1339
+ const collapsedMapContainer = new CollapsedMapBuilder(options == null ? undefined : options.collapsingThreshold);
1340
+ if (options == null ? undefined : options.collapsing) {
1333
1341
  collapsedMapContainer.addTree(levels[0][0]);
1334
1342
  }
1335
1343
  return [levels, uniqueLabels, collapsedMapContainer.getCollapsedMap()];
@@ -1376,7 +1384,7 @@ class CollapsedMapBuilder {
1376
1384
  constructor(threshold) {
1377
1385
  this.map = /* @__PURE__ */ new Map();
1378
1386
  this.threshold = 0.99;
1379
- if (threshold !== void 0) {
1387
+ if (threshold !== undefined) {
1380
1388
  this.threshold = threshold;
1381
1389
  }
1382
1390
  }
@@ -1385,7 +1393,7 @@ class CollapsedMapBuilder {
1385
1393
  const stack = [root];
1386
1394
  while (stack.length) {
1387
1395
  const current = stack.shift();
1388
- if ((_a = current.parents) == null ? void 0 : _a.length) {
1396
+ if ((_a = current.parents) == null ? undefined : _a.length) {
1389
1397
  this.addItem(current, current.parents[0]);
1390
1398
  }
1391
1399
  if (current.children.length) {
@@ -1433,7 +1441,7 @@ function checkFields(data) {
1433
1441
  const wrongTypeFields = [];
1434
1442
  for (const field of fields) {
1435
1443
  const [name, types] = field;
1436
- const frameField = data == null ? void 0 : data.fields.find((f) => f.name === name);
1444
+ const frameField = data == null ? undefined : data.fields.find((f) => f.name === name);
1437
1445
  if (!frameField) {
1438
1446
  missingFields.push(name);
1439
1447
  continue;
@@ -1448,7 +1456,7 @@ function checkFields(data) {
1448
1456
  missingFields
1449
1457
  };
1450
1458
  }
1451
- return void 0;
1459
+ return undefined;
1452
1460
  }
1453
1461
  class FlameGraphDataContainer {
1454
1462
  constructor(data, options, theme = data$1.createTheme()) {
@@ -1470,7 +1478,7 @@ class FlameGraphDataContainer {
1470
1478
  "Malformed dataFrame: both valueRight and selfRight has to be present if one of them is present."
1471
1479
  );
1472
1480
  }
1473
- const enumConfig = (_c = (_b = (_a = this.labelField) == null ? void 0 : _a.config) == null ? void 0 : _b.type) == null ? void 0 : _c.enum;
1481
+ const enumConfig = (_c = (_b = (_a = this.labelField) == null ? undefined : _a.config) == null ? undefined : _b.type) == null ? undefined : _c.enum;
1474
1482
  if (enumConfig) {
1475
1483
  this.labelDisplayProcessor = data$1.getDisplayProcessor({ field: this.labelField, theme });
1476
1484
  this.uniqueLabels = enumConfig.text || [];
@@ -1528,7 +1536,7 @@ class FlameGraphDataContainer {
1528
1536
  }
1529
1537
  getSandwichLevels(label) {
1530
1538
  const nodes = this.getNodesWithLabel(label);
1531
- if (!(nodes == null ? void 0 : nodes.length)) {
1539
+ if (!(nodes == null ? undefined : nodes.length)) {
1532
1540
  return [[], []];
1533
1541
  }
1534
1542
  const callers = mergeParentSubtrees(nodes, this);
@@ -1895,7 +1903,7 @@ const FlameGraphTopTableContainer = react.memo(
1895
1903
  initialSortBy: sort,
1896
1904
  onSortByChange: (s) => {
1897
1905
  if (s && s.length) {
1898
- onTableSort == null ? void 0 : onTableSort(s[0].displayName + "_" + (s[0].desc ? "desc" : "asc"));
1906
+ onTableSort == null ? undefined : onTableSort(s[0].displayName + "_" + (s[0].desc ? "desc" : "asc"));
1899
1907
  }
1900
1908
  setSort(s);
1901
1909
  },
@@ -1945,7 +1953,7 @@ function buildTableDataFrame(data, table, width, onSymbolClick, onSearch, onSand
1945
1953
  ];
1946
1954
  const levels = data.getLevels();
1947
1955
  const totalTicks = levels.length ? levels[0][0].value : 0;
1948
- const totalTicksRight = levels.length ? levels[0][0].valueRight : void 0;
1956
+ const totalTicksRight = levels.length ? levels[0][0].valueRight : undefined;
1949
1957
  for (let key in table) {
1950
1958
  actionField.values.push(null);
1951
1959
  symbolField.values.push(key);
@@ -2040,7 +2048,7 @@ function createActionField(onSandwich, onSearch, search, sandwichItem) {
2040
2048
  function ActionCell(props) {
2041
2049
  var _a;
2042
2050
  const styles = getStylesActionCell();
2043
- const symbol = (_a = props.frame.fields.find((f) => f.name === "Symbol")) == null ? void 0 : _a.values[props.rowIndex];
2051
+ const symbol = (_a = props.frame.fields.find((f) => f.name === "Symbol")) == null ? undefined : _a.values[props.rowIndex];
2044
2052
  const isSearched = props.search === symbol;
2045
2053
  const isSandwiched = props.sandwichItem === symbol;
2046
2054
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles.actionCellWrapper, children: [
@@ -2066,7 +2074,7 @@ function ActionCell(props) {
2066
2074
  variant: isSandwiched ? "primary" : "secondary",
2067
2075
  "aria-label": isSandwiched ? "Remove from sandwich view" : "Show in sandwich view",
2068
2076
  onClick: () => {
2069
- props.onSandwich(isSandwiched ? void 0 : symbol);
2077
+ props.onSandwich(isSandwiched ? undefined : symbol);
2070
2078
  }
2071
2079
  }
2072
2080
  )
@@ -2110,6 +2118,7 @@ const FlameGraphContainer = ({
2110
2118
  vertical,
2111
2119
  showFlameGraphOnly,
2112
2120
  disableCollapsing,
2121
+ keepFocusOnDataChange,
2113
2122
  getExtraContextMenuButtons
2114
2123
  }) => {
2115
2124
  const [focusedItemData, setFocusedItemData] = react.useState();
@@ -2139,23 +2148,50 @@ const FlameGraphContainer = ({
2139
2148
  }
2140
2149
  }, [selectedView, setSelectedView, containerWidth, vertical]);
2141
2150
  const resetFocus = react.useCallback(() => {
2142
- setFocusedItemData(void 0);
2151
+ setFocusedItemData(undefined);
2143
2152
  setRangeMin(0);
2144
2153
  setRangeMax(1);
2145
2154
  }, [setFocusedItemData, setRangeMax, setRangeMin]);
2146
- function resetSandwich() {
2147
- setSandwichItem(void 0);
2148
- }
2155
+ const resetSandwich = react.useCallback(() => {
2156
+ setSandwichItem(undefined);
2157
+ }, [setSandwichItem]);
2149
2158
  react.useEffect(() => {
2150
- resetFocus();
2151
- resetSandwich();
2152
- }, [data, resetFocus]);
2159
+ var _a;
2160
+ if (!keepFocusOnDataChange) {
2161
+ resetFocus();
2162
+ resetSandwich();
2163
+ return;
2164
+ }
2165
+ if (dataContainer && focusedItemData) {
2166
+ const item = (_a = dataContainer.getNodesWithLabel(focusedItemData.label)) == null ? undefined : _a[0];
2167
+ if (item) {
2168
+ setFocusedItemData({ ...focusedItemData, item });
2169
+ const levels = dataContainer.getLevels();
2170
+ const totalViewTicks = levels.length ? levels[0][0].value : 0;
2171
+ setRangeMin(item.start / totalViewTicks);
2172
+ setRangeMax((item.start + item.value) / totalViewTicks);
2173
+ } else {
2174
+ setFocusedItemData({
2175
+ ...focusedItemData,
2176
+ item: {
2177
+ start: 0,
2178
+ value: 0,
2179
+ itemIndexes: [],
2180
+ children: [],
2181
+ level: 0
2182
+ }
2183
+ });
2184
+ setRangeMin(0);
2185
+ setRangeMax(1);
2186
+ }
2187
+ }
2188
+ }, [dataContainer, keepFocusOnDataChange]);
2153
2189
  const onSymbolClick = react.useCallback(
2154
2190
  (symbol) => {
2155
2191
  if (search === symbol) {
2156
2192
  setSearch("");
2157
2193
  } else {
2158
- onTableSymbolClick == null ? void 0 : onTableSymbolClick(symbol);
2194
+ onTableSymbolClick == null ? undefined : onTableSymbolClick(symbol);
2159
2195
  setSearch(symbol);
2160
2196
  resetFocus();
2161
2197
  }
@@ -2238,7 +2274,7 @@ const FlameGraphContainer = ({
2238
2274
  selectedView,
2239
2275
  setSelectedView: (view) => {
2240
2276
  setSelectedView(view);
2241
- onViewSelected == null ? void 0 : onViewSelected(view);
2277
+ onViewSelected == null ? undefined : onViewSelected(view);
2242
2278
  },
2243
2279
  containerWidth,
2244
2280
  onReset: () => {
@@ -2248,7 +2284,7 @@ const FlameGraphContainer = ({
2248
2284
  textAlign,
2249
2285
  onTextAlignChange: (align) => {
2250
2286
  setTextAlign(align);
2251
- onTextAlignSelected == null ? void 0 : onTextAlignSelected(align);
2287
+ onTextAlignSelected == null ? undefined : onTextAlignSelected(align);
2252
2288
  },
2253
2289
  showResetButton: Boolean(focusedItemData || sandwichItem),
2254
2290
  colorScheme,
@@ -2266,7 +2302,7 @@ const FlameGraphContainer = ({
2266
2302
  );
2267
2303
  };
2268
2304
  function useColorScheme(dataContainer) {
2269
- const defaultColorScheme = (dataContainer == null ? void 0 : dataContainer.isDiffFlamegraph()) ? ColorSchemeDiff.Default : ColorScheme.PackageBased;
2305
+ const defaultColorScheme = (dataContainer == null ? undefined : dataContainer.isDiffFlamegraph()) ? ColorSchemeDiff.Default : ColorScheme.PackageBased;
2270
2306
  const [colorScheme, setColorScheme] = react.useState(defaultColorScheme);
2271
2307
  react.useEffect(() => {
2272
2308
  setColorScheme(defaultColorScheme);
@@ -2285,7 +2321,7 @@ function useLabelSearch(search, data) {
2285
2321
  }
2286
2322
  return foundLabels;
2287
2323
  }
2288
- return void 0;
2324
+ return undefined;
2289
2325
  }, [search, data]);
2290
2326
  }
2291
2327
  function getStyles(theme) {