@grafana/flamegraph 11.5.0-221751 → 11.5.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.
package/README.md CHANGED
@@ -26,18 +26,17 @@ import { Flamegraph } from '@grafana/flamegraph';
26
26
 
27
27
  #### Props
28
28
 
29
- | Name | Type | Description |
30
- | --------------------- | ------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
31
- | data | DataFrame | DataFrame with the profile data. Optional, if missing or empty the flamegraph is not rendered |
32
- | stickyHeader | boolean | Whether the header should be sticky and be always visible on the top when scrolling. |
33
- | getTheme | () => GrafanaTheme2 | Provides a theme for the visualization on which colors and some sizes are based. |
34
- | onTableSymbolClick | (symbol: string) => void | Interaction hook that can be used to report on the interaction. Fires when user click on a name in the table. |
35
- | onViewSelected | (view: string) => void | Interaction hook that can be used to report on the interaction. Fires when user changes the view to show (table/graph/both) |
36
- | onTextAlignSelected | (align: string) => void | Interaction hook that can be used to report on the interaction. Fires when user changes the text align. |
37
- | onTableSort | (sort: string) => void | Interaction hook that can be used to report on the interaction. Fires when user changes the teble sorting. |
38
- | extraHeaderElements | React.ReactNode | Elements that will be shown in the header on the right side of the header buttons. Useful for additional functionality. |
39
- | vertical | boolean | If true the flamegraph will be rendered on top of the table. |
40
- | keepFocusOnDataChange | boolean | If true any focused block will stay focused when the profile data changes. Same for the sandwich view. |
29
+ | Name | Type | Description |
30
+ | ------------------- | ------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
31
+ | data | DataFrame | DataFrame with the profile data. Optional, if missing or empty the flamegraph is not rendered |
32
+ | stickyHeader | boolean | Whether the header should be sticky and be always visible on the top when scrolling. |
33
+ | getTheme | () => GrafanaTheme2 | Provides a theme for the visualization on which colors and some sizes are based. |
34
+ | onTableSymbolClick | (symbol: string) => void | Interaction hook that can be used to report on the interaction. Fires when user click on a name in the table. |
35
+ | onViewSelected | (view: string) => void | Interaction hook that can be used to report on the interaction. Fires when user changes the view to show (table/graph/both) |
36
+ | onTextAlignSelected | (align: string) => void | Interaction hook that can be used to report on the interaction. Fires when user changes the text align. |
37
+ | onTableSort | (sort: string) => void | Interaction hook that can be used to report on the interaction. Fires when user changes the teble sorting. |
38
+ | extraHeaderElements | React.ReactNode | Elements that will be shown in the header on the right side of the header buttons. Useful for additional functionality. |
39
+ | vertical | boolean | If true the flamegraph will be rendered on top of the table. |
41
40
 
42
41
  ##### DataFrame schema
43
42
 
@@ -40,14 +40,14 @@ const FlameGraph = ({
40
40
  if (data) {
41
41
  let levels2 = data.getLevels();
42
42
  let totalProfileTicks2 = levels2.length ? levels2[0][0].value : 0;
43
- let totalProfileTicksRight2 = levels2.length ? levels2[0][0].valueRight : undefined;
43
+ let totalProfileTicksRight2 = levels2.length ? levels2[0][0].valueRight : void 0;
44
44
  let totalViewTicks2 = totalProfileTicks2;
45
- let levelsCallers2 = undefined;
45
+ let levelsCallers2 = void 0;
46
46
  if (sandwichItem) {
47
47
  const [callers, callees] = data.getSandwichLevels(sandwichItem);
48
48
  levels2 = callees;
49
49
  levelsCallers2 = callers;
50
- totalViewTicks2 = (_c = (_b = (_a = callees[0]) == null ? undefined : _a[0]) == null ? undefined : _b.value) != null ? _c : 0;
50
+ totalViewTicks2 = (_c = (_b = (_a = callees[0]) == null ? void 0 : _a[0]) == null ? void 0 : _b.value) != null ? _c : 0;
51
51
  }
52
52
  setLevels(levels2);
53
53
  setLevelsCallers(levelsCallers2);
@@ -82,45 +82,40 @@ const FlameGraph = ({
82
82
  search,
83
83
  selectedView
84
84
  };
85
- let canvas = null;
86
- if (levelsCallers == null ? undefined : levelsCallers.length) {
87
- canvas = /* @__PURE__ */ jsxs(Fragment, { children: [
88
- /* @__PURE__ */ jsxs("div", { className: styles.sandwichCanvasWrapper, children: [
89
- /* @__PURE__ */ jsxs("div", { className: styles.sandwichMarker, children: [
90
- "Callers",
91
- /* @__PURE__ */ jsx(Icon, { className: styles.sandwichMarkerIcon, name: "arrow-down" })
92
- ] }),
93
- /* @__PURE__ */ jsx(
94
- FlameGraphCanvas,
95
- {
96
- ...commonCanvasProps,
97
- root: levelsCallers[levelsCallers.length - 1][0],
98
- depth: levelsCallers.length,
99
- direction: "parents",
100
- collapsing: false
101
- }
102
- )
85
+ const canvas = levelsCallers ? /* @__PURE__ */ jsxs(Fragment, { children: [
86
+ /* @__PURE__ */ jsxs("div", { className: styles.sandwichCanvasWrapper, children: [
87
+ /* @__PURE__ */ jsxs("div", { className: styles.sandwichMarker, children: [
88
+ "Callers",
89
+ /* @__PURE__ */ jsx(Icon, { className: styles.sandwichMarkerIcon, name: "arrow-down" })
103
90
  ] }),
104
- /* @__PURE__ */ jsxs("div", { className: styles.sandwichCanvasWrapper, children: [
105
- /* @__PURE__ */ jsxs("div", { className: cx(styles.sandwichMarker, styles.sandwichMarkerCalees), children: [
106
- /* @__PURE__ */ jsx(Icon, { className: styles.sandwichMarkerIcon, name: "arrow-up" }),
107
- "Callees"
108
- ] }),
109
- /* @__PURE__ */ jsx(
110
- FlameGraphCanvas,
111
- {
112
- ...commonCanvasProps,
113
- root: levels[0][0],
114
- depth: levels.length,
115
- direction: "children",
116
- collapsing: false
117
- }
118
- )
119
- ] })
120
- ] });
121
- } else if (levels == null ? undefined : levels.length) {
122
- canvas = /* @__PURE__ */ jsx(FlameGraphCanvas, { ...commonCanvasProps, root: levels[0][0], depth: levels.length, direction: "children" });
123
- }
91
+ /* @__PURE__ */ jsx(
92
+ FlameGraphCanvas,
93
+ {
94
+ ...commonCanvasProps,
95
+ root: levelsCallers[levelsCallers.length - 1][0],
96
+ depth: levelsCallers.length,
97
+ direction: "parents",
98
+ collapsing: false
99
+ }
100
+ )
101
+ ] }),
102
+ /* @__PURE__ */ jsxs("div", { className: styles.sandwichCanvasWrapper, children: [
103
+ /* @__PURE__ */ jsxs("div", { className: cx(styles.sandwichMarker, styles.sandwichMarkerCalees), children: [
104
+ /* @__PURE__ */ jsx(Icon, { className: styles.sandwichMarkerIcon, name: "arrow-up" }),
105
+ "Callees"
106
+ ] }),
107
+ /* @__PURE__ */ jsx(
108
+ FlameGraphCanvas,
109
+ {
110
+ ...commonCanvasProps,
111
+ root: levels[0][0],
112
+ depth: levels.length,
113
+ direction: "children",
114
+ collapsing: false
115
+ }
116
+ )
117
+ ] })
118
+ ] }) : /* @__PURE__ */ jsx(FlameGraphCanvas, { ...commonCanvasProps, root: levels[0][0], depth: levels.length, direction: "children" });
124
119
  return /* @__PURE__ */ jsxs("div", { className: styles.graph, children: [
125
120
  /* @__PURE__ */ jsx(
126
121
  FlameGraphMetadata,
@@ -1 +1 @@
1
- {"version":3,"file":"FlameGraph.js","sources":["../../../src/FlameGraph/FlameGraph.tsx"],"sourcesContent":["// This component is based on logic from the flamebearer project\n// https://github.com/mapbox/flamebearer\n\n// ISC License\n\n// Copyright (c) 2018, Mapbox\n\n// Permission to use, copy, modify, and/or distribute this software for any purpose\n// with or without fee is hereby granted, provided that the above copyright notice\n// and this permission notice appear in all copies.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\n// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS\n// OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\n// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\n// THIS SOFTWARE.\nimport { css, cx } from '@emotion/css';\nimport { useEffect, useState } from 'react';\nimport * as React from 'react';\n\nimport { Icon } from '@grafana/ui';\n\nimport { PIXELS_PER_LEVEL } from '../constants';\nimport { ClickedItemData, ColorScheme, ColorSchemeDiff, SelectedView, TextAlign } from '../types';\n\nimport FlameGraphCanvas from './FlameGraphCanvas';\nimport { GetExtraContextMenuButtonsFunction } from './FlameGraphContextMenu';\nimport FlameGraphMetadata from './FlameGraphMetadata';\nimport { CollapsedMap, FlameGraphDataContainer, LevelItem } from './dataTransform';\n\ntype Props = {\n data: FlameGraphDataContainer;\n rangeMin: number;\n rangeMax: number;\n matchedLabels?: Set<string>;\n setRangeMin: (range: number) => void;\n setRangeMax: (range: number) => void;\n style?: React.CSSProperties;\n onItemFocused: (data: ClickedItemData) => void;\n focusedItemData?: ClickedItemData;\n textAlign: TextAlign;\n sandwichItem?: string;\n onSandwich: (label: string) => void;\n onFocusPillClick: () => void;\n onSandwichPillClick: () => void;\n colorScheme: ColorScheme | ColorSchemeDiff;\n showFlameGraphOnly?: boolean;\n getExtraContextMenuButtons?: GetExtraContextMenuButtonsFunction;\n collapsing?: boolean;\n selectedView: SelectedView;\n search: string;\n collapsedMap: CollapsedMap;\n setCollapsedMap: (collapsedMap: CollapsedMap) => void;\n};\n\nconst FlameGraph = ({\n data,\n rangeMin,\n rangeMax,\n matchedLabels,\n setRangeMin,\n setRangeMax,\n onItemFocused,\n focusedItemData,\n textAlign,\n onSandwich,\n sandwichItem,\n onFocusPillClick,\n onSandwichPillClick,\n colorScheme,\n showFlameGraphOnly,\n getExtraContextMenuButtons,\n collapsing,\n selectedView,\n search,\n collapsedMap,\n setCollapsedMap,\n}: Props) => {\n const styles = getStyles();\n\n const [levels, setLevels] = useState<LevelItem[][]>();\n const [levelsCallers, setLevelsCallers] = useState<LevelItem[][]>();\n const [totalProfileTicks, setTotalProfileTicks] = useState<number>(0);\n const [totalProfileTicksRight, setTotalProfileTicksRight] = useState<number>();\n const [totalViewTicks, setTotalViewTicks] = useState<number>(0);\n\n useEffect(() => {\n if (data) {\n let levels = data.getLevels();\n let totalProfileTicks = levels.length ? levels[0][0].value : 0;\n let totalProfileTicksRight = levels.length ? levels[0][0].valueRight : undefined;\n let totalViewTicks = totalProfileTicks;\n let levelsCallers = undefined;\n\n if (sandwichItem) {\n const [callers, callees] = data.getSandwichLevels(sandwichItem);\n levels = callees;\n levelsCallers = callers;\n // We need this separate as in case of diff profile we want to compute diff colors based on the original ticks.\n totalViewTicks = callees[0]?.[0]?.value ?? 0;\n }\n setLevels(levels);\n setLevelsCallers(levelsCallers);\n setTotalProfileTicks(totalProfileTicks);\n setTotalProfileTicksRight(totalProfileTicksRight);\n setTotalViewTicks(totalViewTicks);\n }\n }, [data, sandwichItem]);\n\n if (!levels) {\n return null;\n }\n\n const commonCanvasProps = {\n data,\n rangeMin,\n rangeMax,\n matchedLabels,\n setRangeMin,\n setRangeMax,\n onItemFocused,\n focusedItemData,\n textAlign,\n onSandwich,\n colorScheme,\n totalProfileTicks,\n totalProfileTicksRight,\n totalViewTicks,\n showFlameGraphOnly,\n collapsedMap,\n setCollapsedMap,\n getExtraContextMenuButtons,\n collapsing,\n search,\n selectedView,\n };\n let canvas = null;\n\n if (levelsCallers?.length) {\n canvas = (\n <>\n <div className={styles.sandwichCanvasWrapper}>\n <div className={styles.sandwichMarker}>\n Callers\n <Icon className={styles.sandwichMarkerIcon} name={'arrow-down'} />\n </div>\n <FlameGraphCanvas\n {...commonCanvasProps}\n root={levelsCallers[levelsCallers.length - 1][0]}\n depth={levelsCallers.length}\n direction={'parents'}\n // We do not support collapsing in sandwich view for now.\n collapsing={false}\n />\n </div>\n\n <div className={styles.sandwichCanvasWrapper}>\n <div className={cx(styles.sandwichMarker, styles.sandwichMarkerCalees)}>\n <Icon className={styles.sandwichMarkerIcon} name={'arrow-up'} />\n Callees\n </div>\n <FlameGraphCanvas\n {...commonCanvasProps}\n root={levels[0][0]}\n depth={levels.length}\n direction={'children'}\n collapsing={false}\n />\n </div>\n </>\n );\n } else if (levels?.length) {\n canvas = (\n <FlameGraphCanvas {...commonCanvasProps} root={levels[0][0]} depth={levels.length} direction={'children'} />\n );\n }\n\n return (\n <div className={styles.graph}>\n <FlameGraphMetadata\n data={data}\n focusedItem={focusedItemData}\n sandwichedLabel={sandwichItem}\n totalTicks={totalViewTicks}\n onFocusPillClick={onFocusPillClick}\n onSandwichPillClick={onSandwichPillClick}\n />\n {canvas}\n </div>\n );\n};\n\nconst getStyles = () => ({\n graph: css({\n label: 'graph',\n overflow: 'auto',\n flexGrow: 1,\n flexBasis: '50%',\n }),\n sandwichCanvasWrapper: css({\n label: 'sandwichCanvasWrapper',\n display: 'flex',\n marginBottom: `${PIXELS_PER_LEVEL / window.devicePixelRatio}px`,\n }),\n sandwichMarker: css({\n label: 'sandwichMarker',\n writingMode: 'vertical-lr',\n transform: 'rotate(180deg)',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n }),\n sandwichMarkerCalees: css({\n label: 'sandwichMarkerCalees',\n textAlign: 'right',\n }),\n sandwichMarkerIcon: css({\n label: 'sandwichMarkerIcon',\n verticalAlign: 'baseline',\n }),\n});\n\nexport default FlameGraph;\n"],"names":["levels","totalProfileTicks","totalProfileTicksRight","totalViewTicks","levelsCallers"],"mappings":"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"}
1
+ {"version":3,"file":"FlameGraph.js","sources":["../../../src/FlameGraph/FlameGraph.tsx"],"sourcesContent":["// This component is based on logic from the flamebearer project\n// https://github.com/mapbox/flamebearer\n\n// ISC License\n\n// Copyright (c) 2018, Mapbox\n\n// Permission to use, copy, modify, and/or distribute this software for any purpose\n// with or without fee is hereby granted, provided that the above copyright notice\n// and this permission notice appear in all copies.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\n// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS\n// OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\n// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\n// THIS SOFTWARE.\nimport { css, cx } from '@emotion/css';\nimport { useEffect, useState } from 'react';\nimport * as React from 'react';\n\nimport { Icon } from '@grafana/ui';\n\nimport { PIXELS_PER_LEVEL } from '../constants';\nimport { ClickedItemData, ColorScheme, ColorSchemeDiff, SelectedView, TextAlign } from '../types';\n\nimport FlameGraphCanvas from './FlameGraphCanvas';\nimport { GetExtraContextMenuButtonsFunction } from './FlameGraphContextMenu';\nimport FlameGraphMetadata from './FlameGraphMetadata';\nimport { CollapsedMap, FlameGraphDataContainer, LevelItem } from './dataTransform';\n\ntype Props = {\n data: FlameGraphDataContainer;\n rangeMin: number;\n rangeMax: number;\n matchedLabels?: Set<string>;\n setRangeMin: (range: number) => void;\n setRangeMax: (range: number) => void;\n style?: React.CSSProperties;\n onItemFocused: (data: ClickedItemData) => void;\n focusedItemData?: ClickedItemData;\n textAlign: TextAlign;\n sandwichItem?: string;\n onSandwich: (label: string) => void;\n onFocusPillClick: () => void;\n onSandwichPillClick: () => void;\n colorScheme: ColorScheme | ColorSchemeDiff;\n showFlameGraphOnly?: boolean;\n getExtraContextMenuButtons?: GetExtraContextMenuButtonsFunction;\n collapsing?: boolean;\n selectedView: SelectedView;\n search: string;\n collapsedMap: CollapsedMap;\n setCollapsedMap: (collapsedMap: CollapsedMap) => void;\n};\n\nconst FlameGraph = ({\n data,\n rangeMin,\n rangeMax,\n matchedLabels,\n setRangeMin,\n setRangeMax,\n onItemFocused,\n focusedItemData,\n textAlign,\n onSandwich,\n sandwichItem,\n onFocusPillClick,\n onSandwichPillClick,\n colorScheme,\n showFlameGraphOnly,\n getExtraContextMenuButtons,\n collapsing,\n selectedView,\n search,\n collapsedMap,\n setCollapsedMap,\n}: Props) => {\n const styles = getStyles();\n\n const [levels, setLevels] = useState<LevelItem[][]>();\n const [levelsCallers, setLevelsCallers] = useState<LevelItem[][]>();\n const [totalProfileTicks, setTotalProfileTicks] = useState<number>(0);\n const [totalProfileTicksRight, setTotalProfileTicksRight] = useState<number>();\n const [totalViewTicks, setTotalViewTicks] = useState<number>(0);\n\n useEffect(() => {\n if (data) {\n let levels = data.getLevels();\n let totalProfileTicks = levels.length ? levels[0][0].value : 0;\n let totalProfileTicksRight = levels.length ? levels[0][0].valueRight : undefined;\n let totalViewTicks = totalProfileTicks;\n let levelsCallers = undefined;\n\n if (sandwichItem) {\n const [callers, callees] = data.getSandwichLevels(sandwichItem);\n levels = callees;\n levelsCallers = callers;\n // We need this separate as in case of diff profile we want to compute diff colors based on the original ticks.\n totalViewTicks = callees[0]?.[0]?.value ?? 0;\n }\n setLevels(levels);\n setLevelsCallers(levelsCallers);\n setTotalProfileTicks(totalProfileTicks);\n setTotalProfileTicksRight(totalProfileTicksRight);\n setTotalViewTicks(totalViewTicks);\n }\n }, [data, sandwichItem]);\n\n if (!levels) {\n return null;\n }\n\n const commonCanvasProps = {\n data,\n rangeMin,\n rangeMax,\n matchedLabels,\n setRangeMin,\n setRangeMax,\n onItemFocused,\n focusedItemData,\n textAlign,\n onSandwich,\n colorScheme,\n totalProfileTicks,\n totalProfileTicksRight,\n totalViewTicks,\n showFlameGraphOnly,\n collapsedMap,\n setCollapsedMap,\n getExtraContextMenuButtons,\n collapsing,\n search,\n selectedView,\n };\n const canvas = levelsCallers ? (\n <>\n <div className={styles.sandwichCanvasWrapper}>\n <div className={styles.sandwichMarker}>\n Callers\n <Icon className={styles.sandwichMarkerIcon} name={'arrow-down'} />\n </div>\n <FlameGraphCanvas\n {...commonCanvasProps}\n root={levelsCallers[levelsCallers.length - 1][0]}\n depth={levelsCallers.length}\n direction={'parents'}\n // We do not support collapsing in sandwich view for now.\n collapsing={false}\n />\n </div>\n\n <div className={styles.sandwichCanvasWrapper}>\n <div className={cx(styles.sandwichMarker, styles.sandwichMarkerCalees)}>\n <Icon className={styles.sandwichMarkerIcon} name={'arrow-up'} />\n Callees\n </div>\n <FlameGraphCanvas\n {...commonCanvasProps}\n root={levels[0][0]}\n depth={levels.length}\n direction={'children'}\n collapsing={false}\n />\n </div>\n </>\n ) : (\n <FlameGraphCanvas {...commonCanvasProps} root={levels[0][0]} depth={levels.length} direction={'children'} />\n );\n\n return (\n <div className={styles.graph}>\n <FlameGraphMetadata\n data={data}\n focusedItem={focusedItemData}\n sandwichedLabel={sandwichItem}\n totalTicks={totalViewTicks}\n onFocusPillClick={onFocusPillClick}\n onSandwichPillClick={onSandwichPillClick}\n />\n {canvas}\n </div>\n );\n};\n\nconst getStyles = () => ({\n graph: css({\n label: 'graph',\n overflow: 'auto',\n flexGrow: 1,\n flexBasis: '50%',\n }),\n sandwichCanvasWrapper: css({\n label: 'sandwichCanvasWrapper',\n display: 'flex',\n marginBottom: `${PIXELS_PER_LEVEL / window.devicePixelRatio}px`,\n }),\n sandwichMarker: css({\n label: 'sandwichMarker',\n writingMode: 'vertical-lr',\n transform: 'rotate(180deg)',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n }),\n sandwichMarkerCalees: css({\n label: 'sandwichMarkerCalees',\n textAlign: 'right',\n }),\n sandwichMarkerIcon: css({\n label: 'sandwichMarkerIcon',\n verticalAlign: 'baseline',\n }),\n});\n\nexport default FlameGraph;\n"],"names":["levels","totalProfileTicks","totalProfileTicksRight","totalViewTicks","levelsCallers"],"mappings":"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"}
@@ -59,7 +59,7 @@ const FlameGraphCanvas = ({
59
59
  });
60
60
  const onGraphClick = useCallback(
61
61
  (e) => {
62
- setTooltipItem(undefined);
62
+ setTooltipItem(void 0);
63
63
  const pixelsPerTick = graphRef.current.clientWidth / totalViewTicks / (rangeMax - rangeMin);
64
64
  const item = convertPixelCoordinatesToBarCoordinates(
65
65
  { x: e.nativeEvent.offsetX, y: e.nativeEvent.offsetY },
@@ -79,7 +79,7 @@ const FlameGraphCanvas = ({
79
79
  label: data.getLabel(item.itemIndexes[0])
80
80
  });
81
81
  } else {
82
- setClickedItemData(undefined);
82
+ setClickedItemData(void 0);
83
83
  }
84
84
  },
85
85
  [data, rangeMin, rangeMax, totalViewTicks, root, direction, depth, collapsedMap]
@@ -87,9 +87,9 @@ const FlameGraphCanvas = ({
87
87
  const [mousePosition, setMousePosition] = useState();
88
88
  const onGraphMouseMove = useCallback(
89
89
  (e) => {
90
- if (clickedItemData === undefined) {
91
- setTooltipItem(undefined);
92
- setMousePosition(undefined);
90
+ if (clickedItemData === void 0) {
91
+ setTooltipItem(void 0);
92
+ setMousePosition(void 0);
93
93
  const pixelsPerTick = graphRef.current.clientWidth / totalViewTicks / (rangeMax - rangeMin);
94
94
  const item = convertPixelCoordinatesToBarCoordinates(
95
95
  { x: e.nativeEvent.offsetX, y: e.nativeEvent.offsetY },
@@ -110,13 +110,13 @@ const FlameGraphCanvas = ({
110
110
  [rangeMin, rangeMax, totalViewTicks, clickedItemData, setMousePosition, root, direction, depth, collapsedMap]
111
111
  );
112
112
  const onGraphMouseLeave = useCallback(() => {
113
- setTooltipItem(undefined);
113
+ setTooltipItem(void 0);
114
114
  }, []);
115
115
  useEffect(() => {
116
116
  const handleOnClick = (e) => {
117
117
  var _a;
118
- if (e.target instanceof HTMLElement && ((_a = e.target.parentElement) == null ? undefined : _a.id) !== "flameGraphCanvasContainer_clickOutsideCheck") {
119
- setClickedItemData(undefined);
118
+ if (e.target instanceof HTMLElement && ((_a = e.target.parentElement) == null ? void 0 : _a.id) !== "flameGraphCanvasContainer_clickOutsideCheck") {
119
+ setClickedItemData(void 0);
120
120
  }
121
121
  };
122
122
  window.addEventListener("click", handleOnClick);
@@ -140,7 +140,7 @@ const FlameGraphCanvas = ({
140
140
  item: tooltipItem,
141
141
  data,
142
142
  totalTicks: totalViewTicks,
143
- collapseConfig: tooltipItem ? collapsedMap.get(tooltipItem) : undefined
143
+ collapseConfig: tooltipItem ? collapsedMap.get(tooltipItem) : void 0
144
144
  }
145
145
  ),
146
146
  !showFlameGraphOnly && clickedItemData && /* @__PURE__ */ jsx(
@@ -151,7 +151,7 @@ const FlameGraphCanvas = ({
151
151
  collapsing,
152
152
  collapseConfig: collapsedMap.get(clickedItemData.item),
153
153
  onMenuItemClick: () => {
154
- setClickedItemData(undefined);
154
+ setClickedItemData(void 0);
155
155
  },
156
156
  onItemFocus: () => {
157
157
  setRangeMin(clickedItemData.item.start / totalViewTicks);
@@ -215,10 +215,10 @@ const convertPixelCoordinatesToBarCoordinates = (pos, root, direction, depth, pi
215
215
  let next = root;
216
216
  let currentLevel = direction === "children" ? 0 : depth - 1;
217
217
  const levelIndex = Math.floor(pos.y / (PIXELS_PER_LEVEL / window.devicePixelRatio));
218
- let found = undefined;
218
+ let found = void 0;
219
219
  while (next) {
220
220
  const node = next;
221
- next = undefined;
221
+ next = void 0;
222
222
  if (currentLevel === levelIndex) {
223
223
  found = node;
224
224
  break;
@@ -1 +1 @@
1
- {"version":3,"file":"FlameGraphCanvas.js","sources":["../../../src/FlameGraph/FlameGraphCanvas.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport { MouseEvent as ReactMouseEvent, useCallback, useEffect, useRef, useState } from 'react';\nimport * as React from 'react';\nimport { useMeasure } from 'react-use';\n\nimport { PIXELS_PER_LEVEL } from '../constants';\nimport { ClickedItemData, ColorScheme, ColorSchemeDiff, SelectedView, TextAlign } from '../types';\n\nimport FlameGraphContextMenu, { GetExtraContextMenuButtonsFunction } from './FlameGraphContextMenu';\nimport FlameGraphTooltip from './FlameGraphTooltip';\nimport { CollapsedMap, FlameGraphDataContainer, LevelItem } from './dataTransform';\nimport { getBarX, useFlameRender } from './rendering';\n\ntype Props = {\n data: FlameGraphDataContainer;\n rangeMin: number;\n rangeMax: number;\n matchedLabels: Set<string> | undefined;\n setRangeMin: (range: number) => void;\n setRangeMax: (range: number) => void;\n style?: React.CSSProperties;\n onItemFocused: (data: ClickedItemData) => void;\n focusedItemData?: ClickedItemData;\n textAlign: TextAlign;\n onSandwich: (label: string) => void;\n colorScheme: ColorScheme | ColorSchemeDiff;\n\n root: LevelItem;\n direction: 'children' | 'parents';\n // Depth in number of levels\n depth: number;\n\n totalProfileTicks: number;\n totalProfileTicksRight?: number;\n totalViewTicks: number;\n showFlameGraphOnly?: boolean;\n\n collapsedMap: CollapsedMap;\n setCollapsedMap: (collapsedMap: CollapsedMap) => void;\n collapsing?: boolean;\n getExtraContextMenuButtons?: GetExtraContextMenuButtonsFunction;\n\n selectedView: SelectedView;\n search: string;\n};\n\nconst FlameGraphCanvas = ({\n data,\n rangeMin,\n rangeMax,\n matchedLabels,\n setRangeMin,\n setRangeMax,\n onItemFocused,\n focusedItemData,\n textAlign,\n onSandwich,\n colorScheme,\n totalProfileTicks,\n totalProfileTicksRight,\n totalViewTicks,\n root,\n direction,\n depth,\n showFlameGraphOnly,\n collapsedMap,\n setCollapsedMap,\n collapsing,\n getExtraContextMenuButtons,\n selectedView,\n search,\n}: Props) => {\n const styles = getStyles();\n\n const [sizeRef, { width: wrapperWidth }] = useMeasure<HTMLDivElement>();\n const graphRef = useRef<HTMLCanvasElement>(null);\n const [tooltipItem, setTooltipItem] = useState<LevelItem>();\n\n const [clickedItemData, setClickedItemData] = useState<ClickedItemData>();\n\n useFlameRender({\n canvasRef: graphRef,\n colorScheme,\n data,\n focusedItemData,\n root,\n direction,\n depth,\n rangeMax,\n rangeMin,\n matchedLabels,\n textAlign,\n totalViewTicks,\n // We need this so that if we have a diff profile and are in sandwich view we still show the same diff colors.\n totalColorTicks: data.isDiffFlamegraph() ? totalProfileTicks : totalViewTicks,\n totalTicksRight: totalProfileTicksRight,\n wrapperWidth,\n collapsedMap,\n });\n\n const onGraphClick = useCallback(\n (e: ReactMouseEvent<HTMLCanvasElement>) => {\n setTooltipItem(undefined);\n const pixelsPerTick = graphRef.current!.clientWidth / totalViewTicks / (rangeMax - rangeMin);\n const item = convertPixelCoordinatesToBarCoordinates(\n { x: e.nativeEvent.offsetX, y: e.nativeEvent.offsetY },\n root,\n direction,\n depth,\n pixelsPerTick,\n totalViewTicks,\n rangeMin,\n collapsedMap\n );\n\n // if clicking on a block in the canvas\n if (item) {\n setClickedItemData({\n posY: e.clientY,\n posX: e.clientX,\n item,\n label: data.getLabel(item.itemIndexes[0]),\n });\n } else {\n // if clicking on the canvas but there is no block beneath the cursor\n setClickedItemData(undefined);\n }\n },\n [data, rangeMin, rangeMax, totalViewTicks, root, direction, depth, collapsedMap]\n );\n\n const [mousePosition, setMousePosition] = useState<{ x: number; y: number }>();\n const onGraphMouseMove = useCallback(\n (e: ReactMouseEvent<HTMLCanvasElement>) => {\n if (clickedItemData === undefined) {\n setTooltipItem(undefined);\n setMousePosition(undefined);\n const pixelsPerTick = graphRef.current!.clientWidth / totalViewTicks / (rangeMax - rangeMin);\n const item = convertPixelCoordinatesToBarCoordinates(\n { x: e.nativeEvent.offsetX, y: e.nativeEvent.offsetY },\n root,\n direction,\n depth,\n pixelsPerTick,\n totalViewTicks,\n rangeMin,\n collapsedMap\n );\n\n if (item) {\n setMousePosition({ x: e.clientX, y: e.clientY });\n setTooltipItem(item);\n }\n }\n },\n [rangeMin, rangeMax, totalViewTicks, clickedItemData, setMousePosition, root, direction, depth, collapsedMap]\n );\n\n const onGraphMouseLeave = useCallback(() => {\n setTooltipItem(undefined);\n }, []);\n\n // hide context menu if outside the flame graph canvas is clicked\n useEffect(() => {\n const handleOnClick = (e: MouseEvent) => {\n if (\n e.target instanceof HTMLElement &&\n e.target.parentElement?.id !== 'flameGraphCanvasContainer_clickOutsideCheck'\n ) {\n setClickedItemData(undefined);\n }\n };\n window.addEventListener('click', handleOnClick);\n return () => window.removeEventListener('click', handleOnClick);\n }, [setClickedItemData]);\n\n return (\n <div className={styles.graph}>\n <div className={styles.canvasWrapper} id=\"flameGraphCanvasContainer_clickOutsideCheck\" ref={sizeRef}>\n <canvas\n ref={graphRef}\n data-testid=\"flameGraph\"\n onClick={onGraphClick}\n onMouseMove={onGraphMouseMove}\n onMouseLeave={onGraphMouseLeave}\n />\n </div>\n <FlameGraphTooltip\n position={mousePosition}\n item={tooltipItem}\n data={data}\n totalTicks={totalViewTicks}\n collapseConfig={tooltipItem ? collapsedMap.get(tooltipItem) : undefined}\n />\n {!showFlameGraphOnly && clickedItemData && (\n <FlameGraphContextMenu\n data={data}\n itemData={clickedItemData}\n collapsing={collapsing}\n collapseConfig={collapsedMap.get(clickedItemData.item)}\n onMenuItemClick={() => {\n setClickedItemData(undefined);\n }}\n onItemFocus={() => {\n setRangeMin(clickedItemData.item.start / totalViewTicks);\n setRangeMax((clickedItemData.item.start + clickedItemData.item.value) / totalViewTicks);\n onItemFocused(clickedItemData);\n }}\n onSandwich={() => {\n onSandwich(data.getLabel(clickedItemData.item.itemIndexes[0]));\n }}\n onExpandGroup={() => {\n setCollapsedMap(collapsedMap.setCollapsedStatus(clickedItemData.item, false));\n }}\n onCollapseGroup={() => {\n setCollapsedMap(collapsedMap.setCollapsedStatus(clickedItemData.item, true));\n }}\n onExpandAllGroups={() => {\n setCollapsedMap(collapsedMap.setAllCollapsedStatus(false));\n }}\n onCollapseAllGroups={() => {\n setCollapsedMap(collapsedMap.setAllCollapsedStatus(true));\n }}\n allGroupsCollapsed={Array.from(collapsedMap.values()).every((i) => i.collapsed)}\n allGroupsExpanded={Array.from(collapsedMap.values()).every((i) => !i.collapsed)}\n getExtraContextMenuButtons={getExtraContextMenuButtons}\n selectedView={selectedView}\n search={search}\n />\n )}\n </div>\n );\n};\n\nconst getStyles = () => ({\n graph: css({\n label: 'graph',\n overflow: 'auto',\n flexGrow: 1,\n flexBasis: '50%',\n }),\n canvasContainer: css({\n label: 'canvasContainer',\n display: 'flex',\n }),\n canvasWrapper: css({\n label: 'canvasWrapper',\n cursor: 'pointer',\n flex: 1,\n overflow: 'hidden',\n }),\n sandwichMarker: css({\n label: 'sandwichMarker',\n writingMode: 'vertical-lr',\n transform: 'rotate(180deg)',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n }),\n sandwichMarkerIcon: css({\n label: 'sandwichMarkerIcon',\n verticalAlign: 'baseline',\n }),\n});\n\nexport const convertPixelCoordinatesToBarCoordinates = (\n // position relative to the start of the graph\n pos: { x: number; y: number },\n root: LevelItem,\n direction: 'children' | 'parents',\n depth: number,\n pixelsPerTick: number,\n totalTicks: number,\n rangeMin: number,\n collapsedMap: CollapsedMap\n): LevelItem | undefined => {\n let next: LevelItem | undefined = root;\n let currentLevel = direction === 'children' ? 0 : depth - 1;\n const levelIndex = Math.floor(pos.y / (PIXELS_PER_LEVEL / window.devicePixelRatio));\n let found = undefined;\n\n while (next) {\n const node: LevelItem = next;\n next = undefined;\n if (currentLevel === levelIndex) {\n found = node;\n break;\n }\n\n const nextList = direction === 'children' ? node.children : node.parents || [];\n\n for (const child of nextList) {\n const xStart = getBarX(child.start, totalTicks, rangeMin, pixelsPerTick);\n const xEnd = getBarX(child.start + child.value, totalTicks, rangeMin, pixelsPerTick);\n if (xStart <= pos.x && pos.x < xEnd) {\n next = child;\n // Check if item is a collapsed item. if so also check if the item is the first collapsed item in the chain,\n // which we render, or a child which we don't render. If it's a child in the chain then don't increase the\n // level end effectively skip it.\n const collapsedConfig = collapsedMap.get(child);\n if (!collapsedConfig || !collapsedConfig.collapsed || collapsedConfig.items[0] === child) {\n currentLevel = currentLevel + (direction === 'children' ? 1 : -1);\n }\n break;\n }\n }\n }\n\n return found;\n};\n\nexport default FlameGraphCanvas;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FlameGraphCanvas.js","sources":["../../../src/FlameGraph/FlameGraphCanvas.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport { MouseEvent as ReactMouseEvent, useCallback, useEffect, useRef, useState } from 'react';\nimport * as React from 'react';\nimport { useMeasure } from 'react-use';\n\nimport { PIXELS_PER_LEVEL } from '../constants';\nimport { ClickedItemData, ColorScheme, ColorSchemeDiff, SelectedView, TextAlign } from '../types';\n\nimport FlameGraphContextMenu, { GetExtraContextMenuButtonsFunction } from './FlameGraphContextMenu';\nimport FlameGraphTooltip from './FlameGraphTooltip';\nimport { CollapsedMap, FlameGraphDataContainer, LevelItem } from './dataTransform';\nimport { getBarX, useFlameRender } from './rendering';\n\ntype Props = {\n data: FlameGraphDataContainer;\n rangeMin: number;\n rangeMax: number;\n matchedLabels: Set<string> | undefined;\n setRangeMin: (range: number) => void;\n setRangeMax: (range: number) => void;\n style?: React.CSSProperties;\n onItemFocused: (data: ClickedItemData) => void;\n focusedItemData?: ClickedItemData;\n textAlign: TextAlign;\n onSandwich: (label: string) => void;\n colorScheme: ColorScheme | ColorSchemeDiff;\n\n root: LevelItem;\n direction: 'children' | 'parents';\n // Depth in number of levels\n depth: number;\n\n totalProfileTicks: number;\n totalProfileTicksRight?: number;\n totalViewTicks: number;\n showFlameGraphOnly?: boolean;\n\n collapsedMap: CollapsedMap;\n setCollapsedMap: (collapsedMap: CollapsedMap) => void;\n collapsing?: boolean;\n getExtraContextMenuButtons?: GetExtraContextMenuButtonsFunction;\n\n selectedView: SelectedView;\n search: string;\n};\n\nconst FlameGraphCanvas = ({\n data,\n rangeMin,\n rangeMax,\n matchedLabels,\n setRangeMin,\n setRangeMax,\n onItemFocused,\n focusedItemData,\n textAlign,\n onSandwich,\n colorScheme,\n totalProfileTicks,\n totalProfileTicksRight,\n totalViewTicks,\n root,\n direction,\n depth,\n showFlameGraphOnly,\n collapsedMap,\n setCollapsedMap,\n collapsing,\n getExtraContextMenuButtons,\n selectedView,\n search,\n}: Props) => {\n const styles = getStyles();\n\n const [sizeRef, { width: wrapperWidth }] = useMeasure<HTMLDivElement>();\n const graphRef = useRef<HTMLCanvasElement>(null);\n const [tooltipItem, setTooltipItem] = useState<LevelItem>();\n\n const [clickedItemData, setClickedItemData] = useState<ClickedItemData>();\n\n useFlameRender({\n canvasRef: graphRef,\n colorScheme,\n data,\n focusedItemData,\n root,\n direction,\n depth,\n rangeMax,\n rangeMin,\n matchedLabels,\n textAlign,\n totalViewTicks,\n // We need this so that if we have a diff profile and are in sandwich view we still show the same diff colors.\n totalColorTicks: data.isDiffFlamegraph() ? totalProfileTicks : totalViewTicks,\n totalTicksRight: totalProfileTicksRight,\n wrapperWidth,\n collapsedMap,\n });\n\n const onGraphClick = useCallback(\n (e: ReactMouseEvent<HTMLCanvasElement>) => {\n setTooltipItem(undefined);\n const pixelsPerTick = graphRef.current!.clientWidth / totalViewTicks / (rangeMax - rangeMin);\n const item = convertPixelCoordinatesToBarCoordinates(\n { x: e.nativeEvent.offsetX, y: e.nativeEvent.offsetY },\n root,\n direction,\n depth,\n pixelsPerTick,\n totalViewTicks,\n rangeMin,\n collapsedMap\n );\n\n // if clicking on a block in the canvas\n if (item) {\n setClickedItemData({\n posY: e.clientY,\n posX: e.clientX,\n item,\n label: data.getLabel(item.itemIndexes[0]),\n });\n } else {\n // if clicking on the canvas but there is no block beneath the cursor\n setClickedItemData(undefined);\n }\n },\n [data, rangeMin, rangeMax, totalViewTicks, root, direction, depth, collapsedMap]\n );\n\n const [mousePosition, setMousePosition] = useState<{ x: number; y: number }>();\n const onGraphMouseMove = useCallback(\n (e: ReactMouseEvent<HTMLCanvasElement>) => {\n if (clickedItemData === undefined) {\n setTooltipItem(undefined);\n setMousePosition(undefined);\n const pixelsPerTick = graphRef.current!.clientWidth / totalViewTicks / (rangeMax - rangeMin);\n const item = convertPixelCoordinatesToBarCoordinates(\n { x: e.nativeEvent.offsetX, y: e.nativeEvent.offsetY },\n root,\n direction,\n depth,\n pixelsPerTick,\n totalViewTicks,\n rangeMin,\n collapsedMap\n );\n\n if (item) {\n setMousePosition({ x: e.clientX, y: e.clientY });\n setTooltipItem(item);\n }\n }\n },\n [rangeMin, rangeMax, totalViewTicks, clickedItemData, setMousePosition, root, direction, depth, collapsedMap]\n );\n\n const onGraphMouseLeave = useCallback(() => {\n setTooltipItem(undefined);\n }, []);\n\n // hide context menu if outside the flame graph canvas is clicked\n useEffect(() => {\n const handleOnClick = (e: MouseEvent) => {\n if (\n e.target instanceof HTMLElement &&\n e.target.parentElement?.id !== 'flameGraphCanvasContainer_clickOutsideCheck'\n ) {\n setClickedItemData(undefined);\n }\n };\n window.addEventListener('click', handleOnClick);\n return () => window.removeEventListener('click', handleOnClick);\n }, [setClickedItemData]);\n\n return (\n <div className={styles.graph}>\n <div className={styles.canvasWrapper} id=\"flameGraphCanvasContainer_clickOutsideCheck\" ref={sizeRef}>\n <canvas\n ref={graphRef}\n data-testid=\"flameGraph\"\n onClick={onGraphClick}\n onMouseMove={onGraphMouseMove}\n onMouseLeave={onGraphMouseLeave}\n />\n </div>\n <FlameGraphTooltip\n position={mousePosition}\n item={tooltipItem}\n data={data}\n totalTicks={totalViewTicks}\n collapseConfig={tooltipItem ? collapsedMap.get(tooltipItem) : undefined}\n />\n {!showFlameGraphOnly && clickedItemData && (\n <FlameGraphContextMenu\n data={data}\n itemData={clickedItemData}\n collapsing={collapsing}\n collapseConfig={collapsedMap.get(clickedItemData.item)}\n onMenuItemClick={() => {\n setClickedItemData(undefined);\n }}\n onItemFocus={() => {\n setRangeMin(clickedItemData.item.start / totalViewTicks);\n setRangeMax((clickedItemData.item.start + clickedItemData.item.value) / totalViewTicks);\n onItemFocused(clickedItemData);\n }}\n onSandwich={() => {\n onSandwich(data.getLabel(clickedItemData.item.itemIndexes[0]));\n }}\n onExpandGroup={() => {\n setCollapsedMap(collapsedMap.setCollapsedStatus(clickedItemData.item, false));\n }}\n onCollapseGroup={() => {\n setCollapsedMap(collapsedMap.setCollapsedStatus(clickedItemData.item, true));\n }}\n onExpandAllGroups={() => {\n setCollapsedMap(collapsedMap.setAllCollapsedStatus(false));\n }}\n onCollapseAllGroups={() => {\n setCollapsedMap(collapsedMap.setAllCollapsedStatus(true));\n }}\n allGroupsCollapsed={Array.from(collapsedMap.values()).every((i) => i.collapsed)}\n allGroupsExpanded={Array.from(collapsedMap.values()).every((i) => !i.collapsed)}\n getExtraContextMenuButtons={getExtraContextMenuButtons}\n selectedView={selectedView}\n search={search}\n />\n )}\n </div>\n );\n};\n\nconst getStyles = () => ({\n graph: css({\n label: 'graph',\n overflow: 'auto',\n flexGrow: 1,\n flexBasis: '50%',\n }),\n canvasContainer: css({\n label: 'canvasContainer',\n display: 'flex',\n }),\n canvasWrapper: css({\n label: 'canvasWrapper',\n cursor: 'pointer',\n flex: 1,\n overflow: 'hidden',\n }),\n sandwichMarker: css({\n label: 'sandwichMarker',\n writingMode: 'vertical-lr',\n transform: 'rotate(180deg)',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n }),\n sandwichMarkerIcon: css({\n label: 'sandwichMarkerIcon',\n verticalAlign: 'baseline',\n }),\n});\n\nexport const convertPixelCoordinatesToBarCoordinates = (\n // position relative to the start of the graph\n pos: { x: number; y: number },\n root: LevelItem,\n direction: 'children' | 'parents',\n depth: number,\n pixelsPerTick: number,\n totalTicks: number,\n rangeMin: number,\n collapsedMap: CollapsedMap\n): LevelItem | undefined => {\n let next: LevelItem | undefined = root;\n let currentLevel = direction === 'children' ? 0 : depth - 1;\n const levelIndex = Math.floor(pos.y / (PIXELS_PER_LEVEL / window.devicePixelRatio));\n let found = undefined;\n\n while (next) {\n const node: LevelItem = next;\n next = undefined;\n if (currentLevel === levelIndex) {\n found = node;\n break;\n }\n\n const nextList = direction === 'children' ? node.children : node.parents || [];\n\n for (const child of nextList) {\n const xStart = getBarX(child.start, totalTicks, rangeMin, pixelsPerTick);\n const xEnd = getBarX(child.start + child.value, totalTicks, rangeMin, pixelsPerTick);\n if (xStart <= pos.x && pos.x < xEnd) {\n next = child;\n // Check if item is a collapsed item. if so also check if the item is the first collapsed item in the chain,\n // which we render, or a child which we don't render. If it's a child in the chain then don't increase the\n // level end effectively skip it.\n const collapsedConfig = collapsedMap.get(child);\n if (!collapsedConfig || !collapsedConfig.collapsed || collapsedConfig.items[0] === child) {\n currentLevel = currentLevel + (direction === 'children' ? 1 : -1);\n }\n break;\n }\n }\n }\n\n return found;\n};\n\nexport default FlameGraphCanvas;\n"],"names":[],"mappings":"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"}
@@ -20,7 +20,7 @@ const FlameGraphContextMenu = ({
20
20
  search
21
21
  }) => {
22
22
  function renderItems() {
23
- const extraButtons = (getExtraContextMenuButtons == null ? undefined : getExtraContextMenuButtons(itemData, data.data, {
23
+ const extraButtons = (getExtraContextMenuButtons == null ? void 0 : getExtraContextMenuButtons(itemData, data.data, {
24
24
  selectedView,
25
25
  isDiff: data.isDiffFlamegraph(),
26
26
  search,
@@ -1 +1 @@
1
- {"version":3,"file":"FlameGraphContextMenu.js","sources":["../../../src/FlameGraph/FlameGraphContextMenu.tsx"],"sourcesContent":["import { DataFrame } from '@grafana/data';\nimport { MenuItem, MenuGroup, ContextMenu, IconName } from '@grafana/ui';\n\nimport { ClickedItemData, SelectedView } from '../types';\n\nimport { CollapseConfig, FlameGraphDataContainer } from './dataTransform';\n\nexport type GetExtraContextMenuButtonsFunction = (\n clickedItemData: ClickedItemData,\n data: DataFrame,\n state: { selectedView: SelectedView; isDiff: boolean; search: string; collapseConfig?: CollapseConfig }\n) => ExtraContextMenuButton[];\n\nexport type ExtraContextMenuButton = {\n label: string;\n icon: IconName;\n onClick: () => void;\n};\n\ntype Props = {\n data: FlameGraphDataContainer;\n itemData: ClickedItemData;\n onMenuItemClick: () => void;\n onItemFocus: () => void;\n onSandwich: () => void;\n onExpandGroup: () => void;\n onCollapseGroup: () => void;\n onExpandAllGroups: () => void;\n onCollapseAllGroups: () => void;\n getExtraContextMenuButtons?: GetExtraContextMenuButtonsFunction;\n collapseConfig?: CollapseConfig;\n collapsing?: boolean;\n allGroupsCollapsed?: boolean;\n allGroupsExpanded?: boolean;\n selectedView: SelectedView;\n search: string;\n};\n\nconst FlameGraphContextMenu = ({\n data,\n itemData,\n onMenuItemClick,\n onItemFocus,\n onSandwich,\n collapseConfig,\n onExpandGroup,\n onCollapseGroup,\n onExpandAllGroups,\n onCollapseAllGroups,\n getExtraContextMenuButtons,\n collapsing,\n allGroupsExpanded,\n allGroupsCollapsed,\n selectedView,\n search,\n}: Props) => {\n function renderItems() {\n const extraButtons =\n getExtraContextMenuButtons?.(itemData, data.data, {\n selectedView,\n isDiff: data.isDiffFlamegraph(),\n search,\n collapseConfig,\n }) || [];\n return (\n <>\n <MenuItem\n label=\"Focus block\"\n icon={'eye'}\n onClick={() => {\n onItemFocus();\n onMenuItemClick();\n }}\n />\n <MenuItem\n label=\"Copy function name\"\n icon={'copy'}\n onClick={() => {\n navigator.clipboard.writeText(itemData.label).then(() => {\n onMenuItemClick();\n });\n }}\n />\n <MenuItem\n label=\"Sandwich view\"\n icon={'gf-show-context'}\n onClick={() => {\n onSandwich();\n onMenuItemClick();\n }}\n />\n {extraButtons.map(({ label, icon, onClick }) => {\n return <MenuItem label={label} icon={icon} onClick={() => onClick()} key={label} />;\n })}\n {collapsing && (\n <MenuGroup label={'Grouping'}>\n {collapseConfig ? (\n collapseConfig.collapsed ? (\n <MenuItem\n label=\"Expand group\"\n icon={'angle-double-down'}\n onClick={() => {\n onExpandGroup();\n onMenuItemClick();\n }}\n />\n ) : (\n <MenuItem\n label=\"Collapse group\"\n icon={'angle-double-up'}\n onClick={() => {\n onCollapseGroup();\n onMenuItemClick();\n }}\n />\n )\n ) : null}\n {!allGroupsExpanded && (\n <MenuItem\n label=\"Expand all groups\"\n icon={'angle-double-down'}\n onClick={() => {\n onExpandAllGroups();\n onMenuItemClick();\n }}\n />\n )}\n {!allGroupsCollapsed && (\n <MenuItem\n label=\"Collapse all groups\"\n icon={'angle-double-up'}\n onClick={() => {\n onCollapseAllGroups();\n onMenuItemClick();\n }}\n />\n )}\n </MenuGroup>\n )}\n </>\n );\n }\n\n return (\n <div data-testid=\"contextMenu\">\n <ContextMenu\n renderMenuItems={renderItems}\n x={itemData.posX + 10}\n y={itemData.posY}\n focusOnOpen={false}\n ></ContextMenu>\n </div>\n );\n};\n\nexport default FlameGraphContextMenu;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FlameGraphContextMenu.js","sources":["../../../src/FlameGraph/FlameGraphContextMenu.tsx"],"sourcesContent":["import { DataFrame } from '@grafana/data';\nimport { MenuItem, MenuGroup, ContextMenu, IconName } from '@grafana/ui';\n\nimport { ClickedItemData, SelectedView } from '../types';\n\nimport { CollapseConfig, FlameGraphDataContainer } from './dataTransform';\n\nexport type GetExtraContextMenuButtonsFunction = (\n clickedItemData: ClickedItemData,\n data: DataFrame,\n state: { selectedView: SelectedView; isDiff: boolean; search: string; collapseConfig?: CollapseConfig }\n) => ExtraContextMenuButton[];\n\nexport type ExtraContextMenuButton = {\n label: string;\n icon: IconName;\n onClick: () => void;\n};\n\ntype Props = {\n data: FlameGraphDataContainer;\n itemData: ClickedItemData;\n onMenuItemClick: () => void;\n onItemFocus: () => void;\n onSandwich: () => void;\n onExpandGroup: () => void;\n onCollapseGroup: () => void;\n onExpandAllGroups: () => void;\n onCollapseAllGroups: () => void;\n getExtraContextMenuButtons?: GetExtraContextMenuButtonsFunction;\n collapseConfig?: CollapseConfig;\n collapsing?: boolean;\n allGroupsCollapsed?: boolean;\n allGroupsExpanded?: boolean;\n selectedView: SelectedView;\n search: string;\n};\n\nconst FlameGraphContextMenu = ({\n data,\n itemData,\n onMenuItemClick,\n onItemFocus,\n onSandwich,\n collapseConfig,\n onExpandGroup,\n onCollapseGroup,\n onExpandAllGroups,\n onCollapseAllGroups,\n getExtraContextMenuButtons,\n collapsing,\n allGroupsExpanded,\n allGroupsCollapsed,\n selectedView,\n search,\n}: Props) => {\n function renderItems() {\n const extraButtons =\n getExtraContextMenuButtons?.(itemData, data.data, {\n selectedView,\n isDiff: data.isDiffFlamegraph(),\n search,\n collapseConfig,\n }) || [];\n return (\n <>\n <MenuItem\n label=\"Focus block\"\n icon={'eye'}\n onClick={() => {\n onItemFocus();\n onMenuItemClick();\n }}\n />\n <MenuItem\n label=\"Copy function name\"\n icon={'copy'}\n onClick={() => {\n navigator.clipboard.writeText(itemData.label).then(() => {\n onMenuItemClick();\n });\n }}\n />\n <MenuItem\n label=\"Sandwich view\"\n icon={'gf-show-context'}\n onClick={() => {\n onSandwich();\n onMenuItemClick();\n }}\n />\n {extraButtons.map(({ label, icon, onClick }) => {\n return <MenuItem label={label} icon={icon} onClick={() => onClick()} key={label} />;\n })}\n {collapsing && (\n <MenuGroup label={'Grouping'}>\n {collapseConfig ? (\n collapseConfig.collapsed ? (\n <MenuItem\n label=\"Expand group\"\n icon={'angle-double-down'}\n onClick={() => {\n onExpandGroup();\n onMenuItemClick();\n }}\n />\n ) : (\n <MenuItem\n label=\"Collapse group\"\n icon={'angle-double-up'}\n onClick={() => {\n onCollapseGroup();\n onMenuItemClick();\n }}\n />\n )\n ) : null}\n {!allGroupsExpanded && (\n <MenuItem\n label=\"Expand all groups\"\n icon={'angle-double-down'}\n onClick={() => {\n onExpandAllGroups();\n onMenuItemClick();\n }}\n />\n )}\n {!allGroupsCollapsed && (\n <MenuItem\n label=\"Collapse all groups\"\n icon={'angle-double-up'}\n onClick={() => {\n onCollapseAllGroups();\n onMenuItemClick();\n }}\n />\n )}\n </MenuGroup>\n )}\n </>\n );\n }\n\n return (\n <div data-testid=\"contextMenu\">\n <ContextMenu\n renderMenuItems={renderItems}\n x={itemData.posX + 10}\n y={itemData.posY}\n focusOnOpen={false}\n ></ContextMenu>\n </div>\n );\n};\n\nexport default FlameGraphContextMenu;\n"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { css } from '@emotion/css';
3
3
  import { memo } from 'react';
4
4
  import { getValueFormat } from '@grafana/data';
5
- import { useStyles2, Tooltip, Icon, IconButton } from '@grafana/ui';
5
+ import { useStyles2, Icon, IconButton } from '@grafana/ui';
6
6
 
7
7
  const FlameGraphMetadata = memo(
8
8
  ({ data, focusedItem, totalTicks, sandwichedLabel, onFocusPillClick, onSandwichPillClick }) => {
@@ -30,7 +30,7 @@ const FlameGraphMetadata = memo(
30
30
  );
31
31
  if (sandwichedLabel) {
32
32
  parts.push(
33
- /* @__PURE__ */ jsx(Tooltip, { content: sandwichedLabel, placement: "top", children: /* @__PURE__ */ jsxs("div", { children: [
33
+ /* @__PURE__ */ jsxs("span", { children: [
34
34
  /* @__PURE__ */ jsx(Icon, { size: "sm", name: "angle-right" }),
35
35
  /* @__PURE__ */ jsxs("div", { className: styles.metadataPill, children: [
36
36
  /* @__PURE__ */ jsx(Icon, { size: "sm", name: "gf-show-context" }),
@@ -48,18 +48,17 @@ const FlameGraphMetadata = memo(
48
48
  }
49
49
  )
50
50
  ] })
51
- ] }) }, "sandwich")
51
+ ] }, "sandwich")
52
52
  );
53
53
  }
54
54
  if (focusedItem) {
55
- const percentValue = totalTicks > 0 ? Math.round(1e4 * (focusedItem.item.value / totalTicks)) / 100 : 0;
56
- const iconName = percentValue > 0 ? "eye" : "exclamation-circle";
55
+ const percentValue = Math.round(1e4 * (focusedItem.item.value / totalTicks)) / 100;
57
56
  parts.push(
58
- /* @__PURE__ */ jsx(Tooltip, { content: focusedItem.label, placement: "top", children: /* @__PURE__ */ jsxs("div", { children: [
57
+ /* @__PURE__ */ jsxs("span", { children: [
59
58
  /* @__PURE__ */ jsx(Icon, { size: "sm", name: "angle-right" }),
60
59
  /* @__PURE__ */ jsxs("div", { className: styles.metadataPill, children: [
61
- /* @__PURE__ */ jsx(Icon, { size: "sm", name: iconName }),
62
- "\xA0",
60
+ /* @__PURE__ */ jsx(Icon, { size: "sm", name: "eye" }),
61
+ " ",
63
62
  percentValue,
64
63
  "% of total",
65
64
  /* @__PURE__ */ jsx(
@@ -74,7 +73,7 @@ const FlameGraphMetadata = memo(
74
73
  }
75
74
  )
76
75
  ] })
77
- ] }) }, "focus")
76
+ ] }, "focus")
78
77
  );
79
78
  }
80
79
  return /* @__PURE__ */ jsx("div", { className: styles.metadata, children: parts });
@@ -100,10 +99,8 @@ const getStyles = (theme) => ({
100
99
  margin: theme.spacing(0, 0.5)
101
100
  }),
102
101
  metadata: css({
103
- display: "flex",
104
- alignItems: "center",
105
- justifyContent: "center",
106
- margin: "8px 0"
102
+ margin: "8px 0",
103
+ textAlign: "center"
107
104
  }),
108
105
  metadataPillName: css({
109
106
  label: "metadataPillName",
@@ -1 +1 @@
1
- {"version":3,"file":"FlameGraphMetadata.js","sources":["../../../src/FlameGraph/FlameGraphMetadata.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport { memo, ReactNode } from 'react';\n\nimport { getValueFormat, GrafanaTheme2 } from '@grafana/data';\nimport { Icon, IconButton, Tooltip, useStyles2 } from '@grafana/ui';\n\nimport { ClickedItemData } from '../types';\n\nimport { FlameGraphDataContainer } from './dataTransform';\n\ntype Props = {\n data: FlameGraphDataContainer;\n totalTicks: number;\n onFocusPillClick: () => void;\n onSandwichPillClick: () => void;\n focusedItem?: ClickedItemData;\n sandwichedLabel?: string;\n};\n\nconst FlameGraphMetadata = memo(\n ({ data, focusedItem, totalTicks, sandwichedLabel, onFocusPillClick, onSandwichPillClick }: Props) => {\n const styles = useStyles2(getStyles);\n const parts: ReactNode[] = [];\n const ticksVal = getValueFormat('short')(totalTicks);\n\n const displayValue = data.valueDisplayProcessor(totalTicks);\n let unitValue = displayValue.text + displayValue.suffix;\n const unitTitle = data.getUnitTitle();\n if (unitTitle === 'Count') {\n if (!displayValue.suffix) {\n // Makes sure we don't show 123undefined or something like that if suffix isn't defined\n unitValue = displayValue.text;\n }\n }\n\n parts.push(\n <div className={styles.metadataPill} key={'default'}>\n {unitValue} | {ticksVal.text}\n {ticksVal.suffix} samples ({unitTitle})\n </div>\n );\n\n if (sandwichedLabel) {\n parts.push(\n <Tooltip key={'sandwich'} content={sandwichedLabel} placement=\"top\">\n <div>\n <Icon size={'sm'} name={'angle-right'} />\n <div className={styles.metadataPill}>\n <Icon size={'sm'} name={'gf-show-context'} />{' '}\n <span className={styles.metadataPillName}>\n {sandwichedLabel.substring(sandwichedLabel.lastIndexOf('/') + 1)}\n </span>\n <IconButton\n className={styles.pillCloseButton}\n name={'times'}\n size={'sm'}\n onClick={onSandwichPillClick}\n tooltip={'Remove sandwich view'}\n aria-label={'Remove sandwich view'}\n />\n </div>\n </div>\n </Tooltip>\n );\n }\n\n if (focusedItem) {\n const percentValue = totalTicks > 0 ? Math.round(10000 * (focusedItem.item.value / totalTicks)) / 100 : 0;\n const iconName = percentValue > 0 ? 'eye' : 'exclamation-circle';\n\n parts.push(\n <Tooltip key={'focus'} content={focusedItem.label} placement=\"top\">\n <div>\n <Icon size={'sm'} name={'angle-right'} />\n <div className={styles.metadataPill}>\n <Icon size={'sm'} name={iconName} />\n &nbsp;{percentValue}% of total\n <IconButton\n className={styles.pillCloseButton}\n name={'times'}\n size={'sm'}\n onClick={onFocusPillClick}\n tooltip={'Remove focus'}\n aria-label={'Remove focus'}\n />\n </div>\n </div>\n </Tooltip>\n );\n }\n\n return <div className={styles.metadata}>{parts}</div>;\n }\n);\n\nFlameGraphMetadata.displayName = 'FlameGraphMetadata';\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n metadataPill: css({\n label: 'metadataPill',\n display: 'inline-flex',\n alignItems: 'center',\n background: theme.colors.background.secondary,\n borderRadius: theme.shape.borderRadius(8),\n padding: theme.spacing(0.5, 1),\n fontSize: theme.typography.bodySmall.fontSize,\n fontWeight: theme.typography.fontWeightMedium,\n lineHeight: theme.typography.bodySmall.lineHeight,\n color: theme.colors.text.secondary,\n }),\n pillCloseButton: css({\n label: 'pillCloseButton',\n verticalAlign: 'text-bottom',\n margin: theme.spacing(0, 0.5),\n }),\n metadata: css({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n margin: '8px 0',\n }),\n metadataPillName: css({\n label: 'metadataPillName',\n maxWidth: '200px',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n marginLeft: theme.spacing(0.5),\n }),\n});\n\nexport default FlameGraphMetadata;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FlameGraphMetadata.js","sources":["../../../src/FlameGraph/FlameGraphMetadata.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport { memo, ReactNode } from 'react';\n\nimport { getValueFormat, GrafanaTheme2 } from '@grafana/data';\nimport { Icon, IconButton, useStyles2 } from '@grafana/ui';\n\nimport { ClickedItemData } from '../types';\n\nimport { FlameGraphDataContainer } from './dataTransform';\n\ntype Props = {\n data: FlameGraphDataContainer;\n totalTicks: number;\n onFocusPillClick: () => void;\n onSandwichPillClick: () => void;\n focusedItem?: ClickedItemData;\n sandwichedLabel?: string;\n};\n\nconst FlameGraphMetadata = memo(\n ({ data, focusedItem, totalTicks, sandwichedLabel, onFocusPillClick, onSandwichPillClick }: Props) => {\n const styles = useStyles2(getStyles);\n const parts: ReactNode[] = [];\n const ticksVal = getValueFormat('short')(totalTicks);\n\n const displayValue = data.valueDisplayProcessor(totalTicks);\n let unitValue = displayValue.text + displayValue.suffix;\n const unitTitle = data.getUnitTitle();\n if (unitTitle === 'Count') {\n if (!displayValue.suffix) {\n // Makes sure we don't show 123undefined or something like that if suffix isn't defined\n unitValue = displayValue.text;\n }\n }\n\n parts.push(\n <div className={styles.metadataPill} key={'default'}>\n {unitValue} | {ticksVal.text}\n {ticksVal.suffix} samples ({unitTitle})\n </div>\n );\n\n if (sandwichedLabel) {\n parts.push(\n <span key={'sandwich'}>\n <Icon size={'sm'} name={'angle-right'} />\n <div className={styles.metadataPill}>\n <Icon size={'sm'} name={'gf-show-context'} />{' '}\n <span className={styles.metadataPillName}>\n {sandwichedLabel.substring(sandwichedLabel.lastIndexOf('/') + 1)}\n </span>\n <IconButton\n className={styles.pillCloseButton}\n name={'times'}\n size={'sm'}\n onClick={onSandwichPillClick}\n tooltip={'Remove sandwich view'}\n aria-label={'Remove sandwich view'}\n />\n </div>\n </span>\n );\n }\n\n if (focusedItem) {\n const percentValue = Math.round(10000 * (focusedItem.item.value / totalTicks)) / 100;\n parts.push(\n <span key={'focus'}>\n <Icon size={'sm'} name={'angle-right'} />\n <div className={styles.metadataPill}>\n <Icon size={'sm'} name={'eye'} /> {percentValue}% of total\n <IconButton\n className={styles.pillCloseButton}\n name={'times'}\n size={'sm'}\n onClick={onFocusPillClick}\n tooltip={'Remove focus'}\n aria-label={'Remove focus'}\n />\n </div>\n </span>\n );\n }\n\n return <div className={styles.metadata}>{parts}</div>;\n }\n);\n\nFlameGraphMetadata.displayName = 'FlameGraphMetadata';\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n metadataPill: css({\n label: 'metadataPill',\n display: 'inline-flex',\n alignItems: 'center',\n background: theme.colors.background.secondary,\n borderRadius: theme.shape.borderRadius(8),\n padding: theme.spacing(0.5, 1),\n fontSize: theme.typography.bodySmall.fontSize,\n fontWeight: theme.typography.fontWeightMedium,\n lineHeight: theme.typography.bodySmall.lineHeight,\n color: theme.colors.text.secondary,\n }),\n pillCloseButton: css({\n label: 'pillCloseButton',\n verticalAlign: 'text-bottom',\n margin: theme.spacing(0, 0.5),\n }),\n metadata: css({\n margin: '8px 0',\n textAlign: 'center',\n }),\n metadataPillName: css({\n label: 'metadataPillName',\n maxWidth: '200px',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n marginLeft: theme.spacing(0.5),\n }),\n});\n\nexport default FlameGraphMetadata;\n"],"names":[],"mappings":"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"}
@@ -90,10 +90,10 @@ function getPackageName(name) {
90
90
  for (const [_, matcher] of matchers) {
91
91
  const match = name.match(matcher);
92
92
  if (match) {
93
- return ((_a = match.groups) == null ? undefined : _a.packageName) || "";
93
+ return ((_a = match.groups) == null ? void 0 : _a.packageName) || "";
94
94
  }
95
95
  }
96
- return undefined;
96
+ return void 0;
97
97
  }
98
98
 
99
99
  export { byPackageGradient, byValueGradient, diffColorBlindColors, diffColorBlindGradient, diffDefaultColors, diffDefaultGradient, getBarColorByDiff, getBarColorByPackage, getBarColorByValue };
@@ -1 +1 @@
1
- {"version":3,"file":"colors.js","sources":["../../../src/FlameGraph/colors.ts"],"sourcesContent":["import { scaleLinear } from 'd3';\nimport color from 'tinycolor2';\n\nimport { GrafanaTheme2 } from '@grafana/data';\n\nimport { ColorSchemeDiff } from '../types';\n\nimport murmurhash3_32_gc from './murmur3';\n\n// Colors taken from pyroscope, they should be from Grafana originally, but I didn't find from where exactly.\nconst packageColors = [\n color({ h: 24, s: 69, l: 60 }),\n color({ h: 34, s: 65, l: 65 }),\n color({ h: 194, s: 52, l: 61 }),\n color({ h: 163, s: 45, l: 55 }),\n color({ h: 211, s: 48, l: 60 }),\n color({ h: 246, s: 40, l: 65 }),\n color({ h: 305, s: 63, l: 79 }),\n color({ h: 47, s: 100, l: 73 }),\n\n color({ r: 183, g: 219, b: 171 }),\n color({ r: 244, g: 213, b: 152 }),\n color({ r: 78, g: 146, b: 249 }),\n color({ r: 249, g: 186, b: 143 }),\n color({ r: 242, g: 145, b: 145 }),\n color({ r: 130, g: 181, b: 216 }),\n color({ r: 229, g: 168, b: 226 }),\n color({ r: 174, g: 162, b: 224 }),\n color({ r: 154, g: 196, b: 138 }),\n color({ r: 242, g: 201, b: 109 }),\n color({ r: 101, g: 197, b: 219 }),\n color({ r: 249, g: 147, b: 78 }),\n color({ r: 234, g: 100, b: 96 }),\n color({ r: 81, g: 149, b: 206 }),\n color({ r: 214, g: 131, b: 206 }),\n color({ r: 128, g: 110, b: 183 }),\n];\n\nconst byValueMinColor = getBarColorByValue(1, 100, 0, 1);\nconst byValueMaxColor = getBarColorByValue(100, 100, 0, 1);\nexport const byValueGradient = `linear-gradient(90deg, ${byValueMinColor} 0%, ${byValueMaxColor} 100%)`;\n\n// Handpicked some vaguely rainbow-ish colors\nexport const byPackageGradient = `linear-gradient(90deg, ${packageColors[0]} 0%, ${packageColors[2]} 30%, ${packageColors[6]} 50%, ${packageColors[7]} 70%, ${packageColors[8]} 100%)`;\n\nexport function getBarColorByValue(value: number, totalTicks: number, rangeMin: number, rangeMax: number) {\n // / (rangeMax - rangeMin) here so when you click a bar it will adjust the top (clicked)bar to the most 'intense' color\n const intensity = Math.min(1, value / totalTicks / (rangeMax - rangeMin));\n const h = 50 - 50 * intensity;\n const l = 65 + 7 * intensity;\n\n return color({ h, s: 100, l });\n}\n\nexport function getBarColorByPackage(label: string, theme: GrafanaTheme2) {\n const packageName = getPackageName(label);\n // TODO: similar thing happens in trace view with selecting colors of the spans, so maybe this could be unified.\n const hash = murmurhash3_32_gc(packageName || '', 0);\n const colorIndex = hash % packageColors.length;\n let packageColor = packageColors[colorIndex].clone();\n if (theme.isLight) {\n packageColor = packageColor.brighten(15);\n }\n return packageColor;\n}\n\n// green to red\nexport const diffDefaultColors = ['rgb(0, 170, 0)', 'rgb(148, 142, 142)', 'rgb(200, 0, 0)'];\nexport const diffDefaultGradient = `linear-gradient(90deg, ${diffDefaultColors[0]} 0%, ${diffDefaultColors[1]} 50%, ${diffDefaultColors[2]} 100%)`;\nexport const diffColorBlindColors = ['rgb(26, 133, 255)', 'rgb(148, 142, 142)', 'rgb(220, 50, 32)'];\nexport const diffColorBlindGradient = `linear-gradient(90deg, ${diffColorBlindColors[0]} 0%, ${diffColorBlindColors[1]} 50%, ${diffColorBlindColors[2]} 100%)`;\n\nexport function getBarColorByDiff(\n ticks: number,\n ticksRight: number,\n totalTicks: number,\n totalTicksRight: number,\n colorScheme: ColorSchemeDiff\n) {\n const range = colorScheme === ColorSchemeDiff.Default ? diffDefaultColors : diffColorBlindColors;\n const colorScale = scaleLinear()\n .domain([-100, 0, 100])\n // TODO types from DefinitelyTyped seem to mismatch\n // @ts-ignore\n .range(range);\n\n const ticksLeft = ticks - ticksRight;\n const totalTicksLeft = totalTicks - totalTicksRight;\n\n if (totalTicksRight === 0 || totalTicksLeft === 0) {\n // TODO types from DefinitelyTyped seem to mismatch\n // @ts-ignore\n const rgbString: string = colorScale(0);\n // Fallback to neutral color as we probably have no data for one of the sides.\n return color(rgbString);\n }\n\n const percentageLeft = Math.round((10000 * ticksLeft) / totalTicksLeft) / 100;\n const percentageRight = Math.round((10000 * ticksRight) / totalTicksRight) / 100;\n\n const diff = ((percentageRight - percentageLeft) / percentageLeft) * 100;\n\n // TODO types from DefinitelyTyped seem to mismatch\n // @ts-ignore\n const rgbString: string = colorScale(diff);\n return color(rgbString);\n}\n\n// const getColors = memoizeOne((theme) => getFilteredColors(colors, theme));\n\n// Different regexes to get the package name and function name from the label. We may at some point get an info about\n// the language from the backend and use the right regex but right now we just try all of them from most to least\n// specific.\nconst matchers = [\n ['phpspy', /^(?<packageName>([^\\/]*\\/)*)(?<filename>.*\\.php+)(?<line_info>.*)$/],\n ['pyspy', /^(?<packageName>([^\\/]*\\/)*)(?<filename>.*\\.py+)(?<line_info>.*)$/],\n ['rbspy', /^(?<packageName>([^\\/]*\\/)*)(?<filename>.*\\.rb+)(?<line_info>.*)$/],\n [\n 'nodespy',\n /^(\\.\\/node_modules\\/)?(?<packageName>[^/]*)(?<filename>.*\\.?(jsx?|tsx?)?):(?<functionName>.*):(?<line_info>.*)$/,\n ],\n ['gospy', /^(?<packageName>.*?\\/.*?\\.|.*?\\.|.+)(?<functionName>.*)$/], // also 'scrape'\n ['javaspy', /^(?<packageName>.+\\/)(?<filename>.+\\.)(?<functionName>.+)$/],\n ['dotnetspy', /^(?<packageName>.+)\\.(.+)\\.(.+)\\(.*\\)$/],\n ['tracing', /^(?<packageName>.+?):.*$/],\n ['pyroscope-rs', /^(?<packageName>[^::]+)/],\n ['ebpfspy', /^(?<packageName>.+)$/],\n ['unknown', /^(?<packageName>.+)$/],\n];\n\n// Get the package name from the symbol. Try matchers from the list and return first one that matches.\nfunction getPackageName(name: string): string | undefined {\n for (const [_, matcher] of matchers) {\n const match = name.match(matcher);\n if (match) {\n return match.groups?.packageName || '';\n }\n }\n return undefined;\n}\n"],"names":["rgbString"],"mappings":"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"}
1
+ {"version":3,"file":"colors.js","sources":["../../../src/FlameGraph/colors.ts"],"sourcesContent":["import { scaleLinear } from 'd3';\nimport color from 'tinycolor2';\n\nimport { GrafanaTheme2 } from '@grafana/data';\n\nimport { ColorSchemeDiff } from '../types';\n\nimport murmurhash3_32_gc from './murmur3';\n\n// Colors taken from pyroscope, they should be from Grafana originally, but I didn't find from where exactly.\nconst packageColors = [\n color({ h: 24, s: 69, l: 60 }),\n color({ h: 34, s: 65, l: 65 }),\n color({ h: 194, s: 52, l: 61 }),\n color({ h: 163, s: 45, l: 55 }),\n color({ h: 211, s: 48, l: 60 }),\n color({ h: 246, s: 40, l: 65 }),\n color({ h: 305, s: 63, l: 79 }),\n color({ h: 47, s: 100, l: 73 }),\n\n color({ r: 183, g: 219, b: 171 }),\n color({ r: 244, g: 213, b: 152 }),\n color({ r: 78, g: 146, b: 249 }),\n color({ r: 249, g: 186, b: 143 }),\n color({ r: 242, g: 145, b: 145 }),\n color({ r: 130, g: 181, b: 216 }),\n color({ r: 229, g: 168, b: 226 }),\n color({ r: 174, g: 162, b: 224 }),\n color({ r: 154, g: 196, b: 138 }),\n color({ r: 242, g: 201, b: 109 }),\n color({ r: 101, g: 197, b: 219 }),\n color({ r: 249, g: 147, b: 78 }),\n color({ r: 234, g: 100, b: 96 }),\n color({ r: 81, g: 149, b: 206 }),\n color({ r: 214, g: 131, b: 206 }),\n color({ r: 128, g: 110, b: 183 }),\n];\n\nconst byValueMinColor = getBarColorByValue(1, 100, 0, 1);\nconst byValueMaxColor = getBarColorByValue(100, 100, 0, 1);\nexport const byValueGradient = `linear-gradient(90deg, ${byValueMinColor} 0%, ${byValueMaxColor} 100%)`;\n\n// Handpicked some vaguely rainbow-ish colors\nexport const byPackageGradient = `linear-gradient(90deg, ${packageColors[0]} 0%, ${packageColors[2]} 30%, ${packageColors[6]} 50%, ${packageColors[7]} 70%, ${packageColors[8]} 100%)`;\n\nexport function getBarColorByValue(value: number, totalTicks: number, rangeMin: number, rangeMax: number) {\n // / (rangeMax - rangeMin) here so when you click a bar it will adjust the top (clicked)bar to the most 'intense' color\n const intensity = Math.min(1, value / totalTicks / (rangeMax - rangeMin));\n const h = 50 - 50 * intensity;\n const l = 65 + 7 * intensity;\n\n return color({ h, s: 100, l });\n}\n\nexport function getBarColorByPackage(label: string, theme: GrafanaTheme2) {\n const packageName = getPackageName(label);\n // TODO: similar thing happens in trace view with selecting colors of the spans, so maybe this could be unified.\n const hash = murmurhash3_32_gc(packageName || '', 0);\n const colorIndex = hash % packageColors.length;\n let packageColor = packageColors[colorIndex].clone();\n if (theme.isLight) {\n packageColor = packageColor.brighten(15);\n }\n return packageColor;\n}\n\n// green to red\nexport const diffDefaultColors = ['rgb(0, 170, 0)', 'rgb(148, 142, 142)', 'rgb(200, 0, 0)'];\nexport const diffDefaultGradient = `linear-gradient(90deg, ${diffDefaultColors[0]} 0%, ${diffDefaultColors[1]} 50%, ${diffDefaultColors[2]} 100%)`;\nexport const diffColorBlindColors = ['rgb(26, 133, 255)', 'rgb(148, 142, 142)', 'rgb(220, 50, 32)'];\nexport const diffColorBlindGradient = `linear-gradient(90deg, ${diffColorBlindColors[0]} 0%, ${diffColorBlindColors[1]} 50%, ${diffColorBlindColors[2]} 100%)`;\n\nexport function getBarColorByDiff(\n ticks: number,\n ticksRight: number,\n totalTicks: number,\n totalTicksRight: number,\n colorScheme: ColorSchemeDiff\n) {\n const range = colorScheme === ColorSchemeDiff.Default ? diffDefaultColors : diffColorBlindColors;\n const colorScale = scaleLinear()\n .domain([-100, 0, 100])\n // TODO types from DefinitelyTyped seem to mismatch\n // @ts-ignore\n .range(range);\n\n const ticksLeft = ticks - ticksRight;\n const totalTicksLeft = totalTicks - totalTicksRight;\n\n if (totalTicksRight === 0 || totalTicksLeft === 0) {\n // TODO types from DefinitelyTyped seem to mismatch\n // @ts-ignore\n const rgbString: string = colorScale(0);\n // Fallback to neutral color as we probably have no data for one of the sides.\n return color(rgbString);\n }\n\n const percentageLeft = Math.round((10000 * ticksLeft) / totalTicksLeft) / 100;\n const percentageRight = Math.round((10000 * ticksRight) / totalTicksRight) / 100;\n\n const diff = ((percentageRight - percentageLeft) / percentageLeft) * 100;\n\n // TODO types from DefinitelyTyped seem to mismatch\n // @ts-ignore\n const rgbString: string = colorScale(diff);\n return color(rgbString);\n}\n\n// const getColors = memoizeOne((theme) => getFilteredColors(colors, theme));\n\n// Different regexes to get the package name and function name from the label. We may at some point get an info about\n// the language from the backend and use the right regex but right now we just try all of them from most to least\n// specific.\nconst matchers = [\n ['phpspy', /^(?<packageName>([^\\/]*\\/)*)(?<filename>.*\\.php+)(?<line_info>.*)$/],\n ['pyspy', /^(?<packageName>([^\\/]*\\/)*)(?<filename>.*\\.py+)(?<line_info>.*)$/],\n ['rbspy', /^(?<packageName>([^\\/]*\\/)*)(?<filename>.*\\.rb+)(?<line_info>.*)$/],\n [\n 'nodespy',\n /^(\\.\\/node_modules\\/)?(?<packageName>[^/]*)(?<filename>.*\\.?(jsx?|tsx?)?):(?<functionName>.*):(?<line_info>.*)$/,\n ],\n ['gospy', /^(?<packageName>.*?\\/.*?\\.|.*?\\.|.+)(?<functionName>.*)$/], // also 'scrape'\n ['javaspy', /^(?<packageName>.+\\/)(?<filename>.+\\.)(?<functionName>.+)$/],\n ['dotnetspy', /^(?<packageName>.+)\\.(.+)\\.(.+)\\(.*\\)$/],\n ['tracing', /^(?<packageName>.+?):.*$/],\n ['pyroscope-rs', /^(?<packageName>[^::]+)/],\n ['ebpfspy', /^(?<packageName>.+)$/],\n ['unknown', /^(?<packageName>.+)$/],\n];\n\n// Get the package name from the symbol. Try matchers from the list and return first one that matches.\nfunction getPackageName(name: string): string | undefined {\n for (const [_, matcher] of matchers) {\n const match = name.match(matcher);\n if (match) {\n return match.groups?.packageName || '';\n }\n }\n return undefined;\n}\n"],"names":["rgbString"],"mappings":"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"}