@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/README.md +12 -11
- package/dist/esm/FlameGraph/FlameGraph.js +41 -36
- package/dist/esm/FlameGraph/FlameGraph.js.map +1 -1
- package/dist/esm/FlameGraph/FlameGraphCanvas.js +12 -12
- package/dist/esm/FlameGraph/FlameGraphCanvas.js.map +1 -1
- package/dist/esm/FlameGraph/FlameGraphContextMenu.js +1 -1
- package/dist/esm/FlameGraph/FlameGraphContextMenu.js.map +1 -1
- package/dist/esm/FlameGraph/FlameGraphMetadata.js +13 -10
- package/dist/esm/FlameGraph/FlameGraphMetadata.js.map +1 -1
- package/dist/esm/FlameGraph/colors.js +2 -2
- package/dist/esm/FlameGraph/colors.js.map +1 -1
- package/dist/esm/FlameGraph/dataTransform.js +11 -11
- package/dist/esm/FlameGraph/dataTransform.js.map +1 -1
- package/dist/esm/FlameGraph/rendering.js +4 -4
- package/dist/esm/FlameGraph/rendering.js.map +1 -1
- package/dist/esm/FlameGraph/treeTransforms.js +4 -4
- package/dist/esm/FlameGraph/treeTransforms.js.map +1 -1
- package/dist/esm/FlameGraphContainer.js +40 -12
- package/dist/esm/FlameGraphContainer.js.map +1 -1
- package/dist/esm/TopTable/FlameGraphTopTableContainer.js +4 -4
- package/dist/esm/TopTable/FlameGraphTopTableContainer.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +131 -95
- package/dist/index.js.map +1 -1
- package/package.json +11 -11
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"FlameGraphContainer.js","sources":["../../src/FlameGraphContainer.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport uFuzzy from '@leeoniya/ufuzzy';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport * as React from 'react';\nimport { useMeasure } from 'react-use';\n\nimport { DataFrame, GrafanaTheme2 } from '@grafana/data';\nimport { ThemeContext } from '@grafana/ui';\n\nimport FlameGraph from './FlameGraph/FlameGraph';\nimport { GetExtraContextMenuButtonsFunction } from './FlameGraph/FlameGraphContextMenu';\nimport { CollapsedMap, FlameGraphDataContainer } from './FlameGraph/dataTransform';\nimport FlameGraphHeader from './FlameGraphHeader';\nimport FlameGraphTopTableContainer from './TopTable/FlameGraphTopTableContainer';\nimport { MIN_WIDTH_TO_SHOW_BOTH_TOPTABLE_AND_FLAMEGRAPH } from './constants';\nimport { ClickedItemData, ColorScheme, ColorSchemeDiff, SelectedView, TextAlign } from './types';\n\nconst ufuzzy = new uFuzzy();\n\nexport type Props = {\n /**\n * DataFrame with the profile data. The dataFrame needs to have the following fields:\n * label: string - the label of the node\n * level: number - the nesting level of the node\n * value: number - the total value of the node\n * self: number - the self value of the node\n * Optionally if it represents diff of 2 different profiles it can also have fields:\n * valueRight: number - the total value of the node in the right profile\n * selfRight: number - the self value of the node in the right profile\n */\n data?: DataFrame;\n\n /**\n * Whether the header should be sticky and be always visible on the top when scrolling.\n */\n stickyHeader?: boolean;\n\n /**\n * Provides a theme for the visualization on which colors and some sizes are based.\n */\n getTheme: () => GrafanaTheme2;\n\n /**\n * Various interaction hooks that can be used to report on the interaction.\n */\n onTableSymbolClick?: (symbol: string) => void;\n onViewSelected?: (view: string) => void;\n onTextAlignSelected?: (align: string) => void;\n onTableSort?: (sort: string) => void;\n\n /**\n * Elements that will be shown in the header on the right side of the header buttons. Useful for additional\n * functionality.\n */\n extraHeaderElements?: React.ReactNode;\n\n /**\n * Extra buttons that will be shown in the context menu when user clicks on a Node.\n */\n getExtraContextMenuButtons?: GetExtraContextMenuButtonsFunction;\n\n /**\n * If true the flamegraph will be rendered on top of the table.\n */\n vertical?: boolean;\n\n /**\n * If true only the flamegraph will be rendered.\n */\n showFlameGraphOnly?: boolean;\n\n /**\n * Disable behaviour where similar items in the same stack will be collapsed into single item.\n */\n disableCollapsing?: boolean;\n};\n\nconst FlameGraphContainer = ({\n data,\n onTableSymbolClick,\n onViewSelected,\n onTextAlignSelected,\n onTableSort,\n getTheme,\n stickyHeader,\n extraHeaderElements,\n vertical,\n showFlameGraphOnly,\n disableCollapsing,\n getExtraContextMenuButtons,\n}: Props) => {\n const [focusedItemData, setFocusedItemData] = useState<ClickedItemData>();\n\n const [rangeMin, setRangeMin] = useState(0);\n const [rangeMax, setRangeMax] = useState(1);\n const [search, setSearch] = useState('');\n const [selectedView, setSelectedView] = useState(SelectedView.Both);\n const [sizeRef, { width: containerWidth }] = useMeasure<HTMLDivElement>();\n const [textAlign, setTextAlign] = useState<TextAlign>('left');\n // This is a label of the item because in sandwich view we group all items by label and present a merged graph\n const [sandwichItem, setSandwichItem] = useState<string>();\n const [collapsedMap, setCollapsedMap] = useState(new CollapsedMap());\n\n const theme = useMemo(() => getTheme(), [getTheme]);\n const dataContainer = useMemo((): FlameGraphDataContainer | undefined => {\n if (!data) {\n return;\n }\n\n const container = new FlameGraphDataContainer(data, { collapsing: !disableCollapsing }, theme);\n setCollapsedMap(container.getCollapsedMap());\n return container;\n }, [data, theme, disableCollapsing]);\n const [colorScheme, setColorScheme] = useColorScheme(dataContainer);\n const styles = getStyles(theme);\n const matchedLabels = useLabelSearch(search, dataContainer);\n\n // If user resizes window with both as the selected view\n useEffect(() => {\n if (\n containerWidth > 0 &&\n containerWidth < MIN_WIDTH_TO_SHOW_BOTH_TOPTABLE_AND_FLAMEGRAPH &&\n selectedView === SelectedView.Both &&\n !vertical\n ) {\n setSelectedView(SelectedView.FlameGraph);\n }\n }, [selectedView, setSelectedView, containerWidth, vertical]);\n\n const resetFocus = useCallback(() => {\n setFocusedItemData(undefined);\n setRangeMin(0);\n setRangeMax(1);\n }, [setFocusedItemData, setRangeMax, setRangeMin]);\n\n function resetSandwich() {\n setSandwichItem(undefined);\n }\n\n useEffect(() => {\n resetFocus();\n resetSandwich();\n }, [data, resetFocus]);\n\n const onSymbolClick = useCallback(\n (symbol: string) => {\n if (search === symbol) {\n setSearch('');\n } else {\n onTableSymbolClick?.(symbol);\n setSearch(symbol);\n resetFocus();\n }\n },\n [setSearch, resetFocus, onTableSymbolClick, search]\n );\n\n if (!dataContainer) {\n return null;\n }\n\n const flameGraph = (\n <FlameGraph\n data={dataContainer}\n rangeMin={rangeMin}\n rangeMax={rangeMax}\n matchedLabels={matchedLabels}\n setRangeMin={setRangeMin}\n setRangeMax={setRangeMax}\n onItemFocused={(data) => setFocusedItemData(data)}\n focusedItemData={focusedItemData}\n textAlign={textAlign}\n sandwichItem={sandwichItem}\n onSandwich={(label: string) => {\n resetFocus();\n setSandwichItem(label);\n }}\n onFocusPillClick={resetFocus}\n onSandwichPillClick={resetSandwich}\n colorScheme={colorScheme}\n showFlameGraphOnly={showFlameGraphOnly}\n collapsing={!disableCollapsing}\n getExtraContextMenuButtons={getExtraContextMenuButtons}\n selectedView={selectedView}\n search={search}\n collapsedMap={collapsedMap}\n setCollapsedMap={setCollapsedMap}\n />\n );\n\n const table = (\n <FlameGraphTopTableContainer\n data={dataContainer}\n onSymbolClick={onSymbolClick}\n search={search}\n matchedLabels={matchedLabels}\n sandwichItem={sandwichItem}\n onSandwich={setSandwichItem}\n onSearch={setSearch}\n onTableSort={onTableSort}\n colorScheme={colorScheme}\n />\n );\n\n let body;\n if (showFlameGraphOnly || selectedView === SelectedView.FlameGraph) {\n body = flameGraph;\n } else if (selectedView === SelectedView.TopTable) {\n body = <div className={styles.tableContainer}>{table}</div>;\n } else if (selectedView === SelectedView.Both) {\n if (vertical) {\n body = (\n <div>\n <div className={styles.verticalGraphContainer}>{flameGraph}</div>\n <div className={styles.verticalTableContainer}>{table}</div>\n </div>\n );\n } else {\n body = (\n <div className={styles.horizontalContainer}>\n <div className={styles.horizontalTableContainer}>{table}</div>\n <div className={styles.horizontalGraphContainer}>{flameGraph}</div>\n </div>\n );\n }\n }\n\n return (\n // We add the theme context to bridge the gap if this is rendered in non grafana environment where the context\n // isn't already provided.\n <ThemeContext.Provider value={theme}>\n <div ref={sizeRef} className={styles.container}>\n {!showFlameGraphOnly && (\n <FlameGraphHeader\n search={search}\n setSearch={setSearch}\n selectedView={selectedView}\n setSelectedView={(view) => {\n setSelectedView(view);\n onViewSelected?.(view);\n }}\n containerWidth={containerWidth}\n onReset={() => {\n resetFocus();\n resetSandwich();\n }}\n textAlign={textAlign}\n onTextAlignChange={(align) => {\n setTextAlign(align);\n onTextAlignSelected?.(align);\n }}\n showResetButton={Boolean(focusedItemData || sandwichItem)}\n colorScheme={colorScheme}\n onColorSchemeChange={setColorScheme}\n stickyHeader={Boolean(stickyHeader)}\n extraHeaderElements={extraHeaderElements}\n vertical={vertical}\n isDiffMode={dataContainer.isDiffFlamegraph()}\n setCollapsedMap={setCollapsedMap}\n collapsedMap={collapsedMap}\n />\n )}\n\n <div className={styles.body}>{body}</div>\n </div>\n </ThemeContext.Provider>\n );\n};\n\nfunction useColorScheme(dataContainer: FlameGraphDataContainer | undefined) {\n const defaultColorScheme = dataContainer?.isDiffFlamegraph() ? ColorSchemeDiff.Default : ColorScheme.PackageBased;\n const [colorScheme, setColorScheme] = useState<ColorScheme | ColorSchemeDiff>(defaultColorScheme);\n\n // This makes sure that if we change the data to/from diff profile we reset the color scheme.\n useEffect(() => {\n setColorScheme(defaultColorScheme);\n }, [defaultColorScheme]);\n\n return [colorScheme, setColorScheme] as const;\n}\n\n/**\n * Based on the search string it does a fuzzy search over all the unique labels, so we can highlight them later.\n */\nfunction useLabelSearch(\n search: string | undefined,\n data: FlameGraphDataContainer | undefined\n): Set<string> | undefined {\n return useMemo(() => {\n if (search && data) {\n const foundLabels = new Set<string>();\n let idxs = ufuzzy.filter(data.getUniqueLabels(), search);\n\n if (idxs) {\n for (let idx of idxs) {\n foundLabels.add(data.getUniqueLabels()[idx]);\n }\n }\n\n return foundLabels;\n }\n // In this case undefined means there was no search so no attempt to highlighting anything should be made.\n return undefined;\n }, [search, data]);\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n container: css({\n label: 'container',\n overflow: 'auto',\n height: '100%',\n display: 'flex',\n flex: '1 1 0',\n flexDirection: 'column',\n minHeight: 0,\n gap: theme.spacing(1),\n }),\n body: css({\n label: 'body',\n flexGrow: 1,\n }),\n\n tableContainer: css({\n // This is not ideal for dashboard panel where it creates a double scroll. In a panel it should be 100% but then\n // in explore we need a specific height.\n height: 800,\n }),\n\n horizontalContainer: css({\n label: 'horizontalContainer',\n display: 'flex',\n minHeight: 0,\n flexDirection: 'row',\n columnGap: theme.spacing(1),\n width: '100%',\n }),\n\n horizontalGraphContainer: css({\n flexBasis: '50%',\n }),\n\n horizontalTableContainer: css({\n flexBasis: '50%',\n maxHeight: 800,\n }),\n\n verticalGraphContainer: css({\n marginBottom: theme.spacing(1),\n }),\n\n verticalTableContainer: css({\n height: 800,\n }),\n };\n}\n\nexport default FlameGraphContainer;\n"],"names":["data"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"FlameGraphContainer.js","sources":["../../src/FlameGraphContainer.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport uFuzzy from '@leeoniya/ufuzzy';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport * as React from 'react';\nimport { useMeasure } from 'react-use';\n\nimport { DataFrame, GrafanaTheme2 } from '@grafana/data';\nimport { ThemeContext } from '@grafana/ui';\n\nimport FlameGraph from './FlameGraph/FlameGraph';\nimport { GetExtraContextMenuButtonsFunction } from './FlameGraph/FlameGraphContextMenu';\nimport { CollapsedMap, FlameGraphDataContainer } from './FlameGraph/dataTransform';\nimport FlameGraphHeader from './FlameGraphHeader';\nimport FlameGraphTopTableContainer from './TopTable/FlameGraphTopTableContainer';\nimport { MIN_WIDTH_TO_SHOW_BOTH_TOPTABLE_AND_FLAMEGRAPH } from './constants';\nimport { ClickedItemData, ColorScheme, ColorSchemeDiff, SelectedView, TextAlign } from './types';\n\nconst ufuzzy = new uFuzzy();\n\nexport type Props = {\n /**\n * DataFrame with the profile data. The dataFrame needs to have the following fields:\n * label: string - the label of the node\n * level: number - the nesting level of the node\n * value: number - the total value of the node\n * self: number - the self value of the node\n * Optionally if it represents diff of 2 different profiles it can also have fields:\n * valueRight: number - the total value of the node in the right profile\n * selfRight: number - the self value of the node in the right profile\n */\n data?: DataFrame;\n\n /**\n * Whether the header should be sticky and be always visible on the top when scrolling.\n */\n stickyHeader?: boolean;\n\n /**\n * Provides a theme for the visualization on which colors and some sizes are based.\n */\n getTheme: () => GrafanaTheme2;\n\n /**\n * Various interaction hooks that can be used to report on the interaction.\n */\n onTableSymbolClick?: (symbol: string) => void;\n onViewSelected?: (view: string) => void;\n onTextAlignSelected?: (align: string) => void;\n onTableSort?: (sort: string) => void;\n\n /**\n * Elements that will be shown in the header on the right side of the header buttons. Useful for additional\n * functionality.\n */\n extraHeaderElements?: React.ReactNode;\n\n /**\n * Extra buttons that will be shown in the context menu when user clicks on a Node.\n */\n getExtraContextMenuButtons?: GetExtraContextMenuButtonsFunction;\n\n /**\n * If true the flamegraph will be rendered on top of the table.\n */\n vertical?: boolean;\n\n /**\n * If true only the flamegraph will be rendered.\n */\n showFlameGraphOnly?: boolean;\n\n /**\n * Disable behaviour where similar items in the same stack will be collapsed into single item.\n */\n disableCollapsing?: boolean;\n /**\n * Whether or not to keep any focused item when the profile data changes.\n */\n keepFocusOnDataChange?: boolean;\n};\n\nconst FlameGraphContainer = ({\n data,\n onTableSymbolClick,\n onViewSelected,\n onTextAlignSelected,\n onTableSort,\n getTheme,\n stickyHeader,\n extraHeaderElements,\n vertical,\n showFlameGraphOnly,\n disableCollapsing,\n keepFocusOnDataChange,\n getExtraContextMenuButtons,\n}: Props) => {\n const [focusedItemData, setFocusedItemData] = useState<ClickedItemData>();\n\n const [rangeMin, setRangeMin] = useState(0);\n const [rangeMax, setRangeMax] = useState(1);\n const [search, setSearch] = useState('');\n const [selectedView, setSelectedView] = useState(SelectedView.Both);\n const [sizeRef, { width: containerWidth }] = useMeasure<HTMLDivElement>();\n const [textAlign, setTextAlign] = useState<TextAlign>('left');\n // This is a label of the item because in sandwich view we group all items by label and present a merged graph\n const [sandwichItem, setSandwichItem] = useState<string>();\n const [collapsedMap, setCollapsedMap] = useState(new CollapsedMap());\n\n const theme = useMemo(() => getTheme(), [getTheme]);\n const dataContainer = useMemo((): FlameGraphDataContainer | undefined => {\n if (!data) {\n return;\n }\n\n const container = new FlameGraphDataContainer(data, { collapsing: !disableCollapsing }, theme);\n setCollapsedMap(container.getCollapsedMap());\n return container;\n }, [data, theme, disableCollapsing]);\n const [colorScheme, setColorScheme] = useColorScheme(dataContainer);\n const styles = getStyles(theme);\n const matchedLabels = useLabelSearch(search, dataContainer);\n\n // If user resizes window with both as the selected view\n useEffect(() => {\n if (\n containerWidth > 0 &&\n containerWidth < MIN_WIDTH_TO_SHOW_BOTH_TOPTABLE_AND_FLAMEGRAPH &&\n selectedView === SelectedView.Both &&\n !vertical\n ) {\n setSelectedView(SelectedView.FlameGraph);\n }\n }, [selectedView, setSelectedView, containerWidth, vertical]);\n\n const resetFocus = useCallback(() => {\n setFocusedItemData(undefined);\n setRangeMin(0);\n setRangeMax(1);\n }, [setFocusedItemData, setRangeMax, setRangeMin]);\n\n const resetSandwich = useCallback(() => {\n setSandwichItem(undefined);\n }, [setSandwichItem]);\n\n useEffect(() => {\n if (!keepFocusOnDataChange) {\n resetFocus();\n resetSandwich();\n return;\n }\n\n if (dataContainer && focusedItemData) {\n const item = dataContainer.getNodesWithLabel(focusedItemData.label)?.[0];\n\n if (item) {\n setFocusedItemData({ ...focusedItemData, item });\n\n const levels = dataContainer.getLevels();\n const totalViewTicks = levels.length ? levels[0][0].value : 0;\n setRangeMin(item.start / totalViewTicks);\n setRangeMax((item.start + item.value) / totalViewTicks);\n } else {\n setFocusedItemData({\n ...focusedItemData,\n item: {\n start: 0,\n value: 0,\n itemIndexes: [],\n children: [],\n level: 0,\n },\n });\n\n setRangeMin(0);\n setRangeMax(1);\n }\n }\n }, [dataContainer, keepFocusOnDataChange]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const onSymbolClick = useCallback(\n (symbol: string) => {\n if (search === symbol) {\n setSearch('');\n } else {\n onTableSymbolClick?.(symbol);\n setSearch(symbol);\n resetFocus();\n }\n },\n [setSearch, resetFocus, onTableSymbolClick, search]\n );\n\n if (!dataContainer) {\n return null;\n }\n\n const flameGraph = (\n <FlameGraph\n data={dataContainer}\n rangeMin={rangeMin}\n rangeMax={rangeMax}\n matchedLabels={matchedLabels}\n setRangeMin={setRangeMin}\n setRangeMax={setRangeMax}\n onItemFocused={(data) => setFocusedItemData(data)}\n focusedItemData={focusedItemData}\n textAlign={textAlign}\n sandwichItem={sandwichItem}\n onSandwich={(label: string) => {\n resetFocus();\n setSandwichItem(label);\n }}\n onFocusPillClick={resetFocus}\n onSandwichPillClick={resetSandwich}\n colorScheme={colorScheme}\n showFlameGraphOnly={showFlameGraphOnly}\n collapsing={!disableCollapsing}\n getExtraContextMenuButtons={getExtraContextMenuButtons}\n selectedView={selectedView}\n search={search}\n collapsedMap={collapsedMap}\n setCollapsedMap={setCollapsedMap}\n />\n );\n\n const table = (\n <FlameGraphTopTableContainer\n data={dataContainer}\n onSymbolClick={onSymbolClick}\n search={search}\n matchedLabels={matchedLabels}\n sandwichItem={sandwichItem}\n onSandwich={setSandwichItem}\n onSearch={setSearch}\n onTableSort={onTableSort}\n colorScheme={colorScheme}\n />\n );\n\n let body;\n if (showFlameGraphOnly || selectedView === SelectedView.FlameGraph) {\n body = flameGraph;\n } else if (selectedView === SelectedView.TopTable) {\n body = <div className={styles.tableContainer}>{table}</div>;\n } else if (selectedView === SelectedView.Both) {\n if (vertical) {\n body = (\n <div>\n <div className={styles.verticalGraphContainer}>{flameGraph}</div>\n <div className={styles.verticalTableContainer}>{table}</div>\n </div>\n );\n } else {\n body = (\n <div className={styles.horizontalContainer}>\n <div className={styles.horizontalTableContainer}>{table}</div>\n <div className={styles.horizontalGraphContainer}>{flameGraph}</div>\n </div>\n );\n }\n }\n\n return (\n // We add the theme context to bridge the gap if this is rendered in non grafana environment where the context\n // isn't already provided.\n <ThemeContext.Provider value={theme}>\n <div ref={sizeRef} className={styles.container}>\n {!showFlameGraphOnly && (\n <FlameGraphHeader\n search={search}\n setSearch={setSearch}\n selectedView={selectedView}\n setSelectedView={(view) => {\n setSelectedView(view);\n onViewSelected?.(view);\n }}\n containerWidth={containerWidth}\n onReset={() => {\n resetFocus();\n resetSandwich();\n }}\n textAlign={textAlign}\n onTextAlignChange={(align) => {\n setTextAlign(align);\n onTextAlignSelected?.(align);\n }}\n showResetButton={Boolean(focusedItemData || sandwichItem)}\n colorScheme={colorScheme}\n onColorSchemeChange={setColorScheme}\n stickyHeader={Boolean(stickyHeader)}\n extraHeaderElements={extraHeaderElements}\n vertical={vertical}\n isDiffMode={dataContainer.isDiffFlamegraph()}\n setCollapsedMap={setCollapsedMap}\n collapsedMap={collapsedMap}\n />\n )}\n\n <div className={styles.body}>{body}</div>\n </div>\n </ThemeContext.Provider>\n );\n};\n\nfunction useColorScheme(dataContainer: FlameGraphDataContainer | undefined) {\n const defaultColorScheme = dataContainer?.isDiffFlamegraph() ? ColorSchemeDiff.Default : ColorScheme.PackageBased;\n const [colorScheme, setColorScheme] = useState<ColorScheme | ColorSchemeDiff>(defaultColorScheme);\n\n // This makes sure that if we change the data to/from diff profile we reset the color scheme.\n useEffect(() => {\n setColorScheme(defaultColorScheme);\n }, [defaultColorScheme]);\n\n return [colorScheme, setColorScheme] as const;\n}\n\n/**\n * Based on the search string it does a fuzzy search over all the unique labels, so we can highlight them later.\n */\nfunction useLabelSearch(\n search: string | undefined,\n data: FlameGraphDataContainer | undefined\n): Set<string> | undefined {\n return useMemo(() => {\n if (search && data) {\n const foundLabels = new Set<string>();\n let idxs = ufuzzy.filter(data.getUniqueLabels(), search);\n\n if (idxs) {\n for (let idx of idxs) {\n foundLabels.add(data.getUniqueLabels()[idx]);\n }\n }\n\n return foundLabels;\n }\n // In this case undefined means there was no search so no attempt to highlighting anything should be made.\n return undefined;\n }, [search, data]);\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n container: css({\n label: 'container',\n overflow: 'auto',\n height: '100%',\n display: 'flex',\n flex: '1 1 0',\n flexDirection: 'column',\n minHeight: 0,\n gap: theme.spacing(1),\n }),\n body: css({\n label: 'body',\n flexGrow: 1,\n }),\n\n tableContainer: css({\n // This is not ideal for dashboard panel where it creates a double scroll. In a panel it should be 100% but then\n // in explore we need a specific height.\n height: 800,\n }),\n\n horizontalContainer: css({\n label: 'horizontalContainer',\n display: 'flex',\n minHeight: 0,\n flexDirection: 'row',\n columnGap: theme.spacing(1),\n width: '100%',\n }),\n\n horizontalGraphContainer: css({\n flexBasis: '50%',\n }),\n\n horizontalTableContainer: css({\n flexBasis: '50%',\n maxHeight: 800,\n }),\n\n verticalGraphContainer: css({\n marginBottom: theme.spacing(1),\n }),\n\n verticalTableContainer: css({\n height: 800,\n }),\n };\n}\n\nexport default FlameGraphContainer;\n"],"names":["data"],"mappings":"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"}
|
@@ -61,7 +61,7 @@ const FlameGraphTopTableContainer = memo(
|
|
61
61
|
initialSortBy: sort,
|
62
62
|
onSortByChange: (s) => {
|
63
63
|
if (s && s.length) {
|
64
|
-
onTableSort == null ?
|
64
|
+
onTableSort == null ? undefined : onTableSort(s[0].displayName + "_" + (s[0].desc ? "desc" : "asc"));
|
65
65
|
}
|
66
66
|
setSort(s);
|
67
67
|
},
|
@@ -111,7 +111,7 @@ function buildTableDataFrame(data, table, width, onSymbolClick, onSearch, onSand
|
|
111
111
|
];
|
112
112
|
const levels = data.getLevels();
|
113
113
|
const totalTicks = levels.length ? levels[0][0].value : 0;
|
114
|
-
const totalTicksRight = levels.length ? levels[0][0].valueRight :
|
114
|
+
const totalTicksRight = levels.length ? levels[0][0].valueRight : undefined;
|
115
115
|
for (let key in table) {
|
116
116
|
actionField.values.push(null);
|
117
117
|
symbolField.values.push(key);
|
@@ -206,7 +206,7 @@ function createActionField(onSandwich, onSearch, search, sandwichItem) {
|
|
206
206
|
function ActionCell(props) {
|
207
207
|
var _a;
|
208
208
|
const styles = getStylesActionCell();
|
209
|
-
const symbol = (_a = props.frame.fields.find((f) => f.name === "Symbol")) == null ?
|
209
|
+
const symbol = (_a = props.frame.fields.find((f) => f.name === "Symbol")) == null ? undefined : _a.values[props.rowIndex];
|
210
210
|
const isSearched = props.search === symbol;
|
211
211
|
const isSandwiched = props.sandwichItem === symbol;
|
212
212
|
return /* @__PURE__ */ jsxs("div", { className: styles.actionCellWrapper, children: [
|
@@ -232,7 +232,7 @@ function ActionCell(props) {
|
|
232
232
|
variant: isSandwiched ? "primary" : "secondary",
|
233
233
|
"aria-label": isSandwiched ? "Remove from sandwich view" : "Show in sandwich view",
|
234
234
|
onClick: () => {
|
235
|
-
props.onSandwich(isSandwiched ?
|
235
|
+
props.onSandwich(isSandwiched ? undefined : symbol);
|
236
236
|
}
|
237
237
|
}
|
238
238
|
)
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"FlameGraphTopTableContainer.js","sources":["../../../src/TopTable/FlameGraphTopTableContainer.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport { memo, useMemo, useState } from 'react';\nimport AutoSizer from 'react-virtualized-auto-sizer';\n\nimport {\n applyFieldOverrides,\n DataFrame,\n DataLinkClickEvent,\n Field,\n FieldType,\n GrafanaTheme2,\n MappingType,\n} from '@grafana/data';\nimport {\n IconButton,\n Table,\n TableCellDisplayMode,\n TableCustomCellOptions,\n TableFieldOptions,\n TableSortByFieldState,\n useStyles2,\n useTheme2,\n} from '@grafana/ui';\n\nimport { diffColorBlindColors, diffDefaultColors } from '../FlameGraph/colors';\nimport { FlameGraphDataContainer } from '../FlameGraph/dataTransform';\nimport { TOP_TABLE_COLUMN_WIDTH } from '../constants';\nimport { ColorScheme, ColorSchemeDiff, TableData } from '../types';\n\ntype Props = {\n data: FlameGraphDataContainer;\n onSymbolClick: (symbol: string) => void;\n // This is used for highlighting the search button in case there is exact match.\n search?: string;\n // We use these to filter out rows in the table if users is doing text search.\n matchedLabels?: Set<string>;\n sandwichItem?: string;\n onSearch: (str: string) => void;\n onSandwich: (str?: string) => void;\n onTableSort?: (sort: string) => void;\n colorScheme: ColorScheme | ColorSchemeDiff;\n};\n\nconst FlameGraphTopTableContainer = memo(\n ({\n data,\n onSymbolClick,\n search,\n matchedLabels,\n onSearch,\n sandwichItem,\n onSandwich,\n onTableSort,\n colorScheme,\n }: Props) => {\n const table = useMemo(() => {\n // Group the data by label, we show only one row per label and sum the values\n // TODO: should be by filename + funcName + linenumber?\n let filteredTable: { [key: string]: TableData } = {};\n for (let i = 0; i < data.data.length; i++) {\n const value = data.getValue(i);\n const valueRight = data.getValueRight(i);\n const self = data.getSelf(i);\n const label = data.getLabel(i);\n\n // If user is doing text search we filter out labels in the same way we highlight them in flame graph.\n if (!matchedLabels || matchedLabels.has(label)) {\n filteredTable[label] = filteredTable[label] || {};\n filteredTable[label].self = filteredTable[label].self ? filteredTable[label].self + self : self;\n filteredTable[label].total = filteredTable[label].total ? filteredTable[label].total + value : value;\n filteredTable[label].totalRight = filteredTable[label].totalRight\n ? filteredTable[label].totalRight + valueRight\n : valueRight;\n }\n }\n return filteredTable;\n }, [data, matchedLabels]);\n\n const styles = useStyles2(getStyles);\n const theme = useTheme2();\n\n const [sort, setSort] = useState<TableSortByFieldState[]>([{ displayName: 'Self', desc: true }]);\n\n return (\n <div className={styles.topTableContainer} data-testid=\"topTable\">\n <AutoSizer style={{ width: '100%' }}>\n {({ width, height }) => {\n if (width < 3 || height < 3) {\n return null;\n }\n\n const frame = buildTableDataFrame(\n data,\n table,\n width,\n onSymbolClick,\n onSearch,\n onSandwich,\n theme,\n colorScheme,\n search,\n sandwichItem\n );\n return (\n <Table\n initialSortBy={sort}\n onSortByChange={(s) => {\n if (s && s.length) {\n onTableSort?.(s[0].displayName + '_' + (s[0].desc ? 'desc' : 'asc'));\n }\n setSort(s);\n }}\n data={frame}\n width={width}\n height={height}\n />\n );\n }}\n </AutoSizer>\n </div>\n );\n }\n);\n\nFlameGraphTopTableContainer.displayName = 'FlameGraphTopTableContainer';\n\nfunction buildTableDataFrame(\n data: FlameGraphDataContainer,\n table: { [key: string]: TableData },\n width: number,\n onSymbolClick: (str: string) => void,\n onSearch: (str: string) => void,\n onSandwich: (str?: string) => void,\n theme: GrafanaTheme2,\n colorScheme: ColorScheme | ColorSchemeDiff,\n search?: string,\n sandwichItem?: string\n): DataFrame {\n const actionField: Field = createActionField(onSandwich, onSearch, search, sandwichItem);\n\n const symbolField: Field = {\n type: FieldType.string,\n name: 'Symbol',\n values: [],\n config: {\n custom: { width: width - actionColumnWidth - TOP_TABLE_COLUMN_WIDTH * 2 },\n links: [\n {\n title: 'Highlight symbol',\n url: '',\n onClick: (e: DataLinkClickEvent) => {\n const field: Field = e.origin.field;\n const value = field.values[e.origin.rowIndex];\n onSymbolClick(value);\n },\n },\n ],\n },\n };\n\n let frame;\n\n if (data.isDiffFlamegraph()) {\n symbolField.config.custom.width = width - actionColumnWidth - TOP_TABLE_COLUMN_WIDTH * 3;\n\n const baselineField = createNumberField('Baseline', 'percent');\n const comparisonField = createNumberField('Comparison', 'percent');\n const diffField = createNumberField('Diff', 'percent');\n diffField.config.custom.cellOptions.type = TableCellDisplayMode.ColorText;\n\n const [removeColor, addColor] =\n colorScheme === ColorSchemeDiff.DiffColorBlind\n ? [diffColorBlindColors[0], diffColorBlindColors[2]]\n : [diffDefaultColors[0], diffDefaultColors[2]];\n\n diffField.config.mappings = [\n { type: MappingType.ValueToText, options: { [Infinity]: { text: 'new', color: addColor } } },\n { type: MappingType.ValueToText, options: { [-100]: { text: 'removed', color: removeColor } } },\n { type: MappingType.RangeToText, options: { from: 0, to: Infinity, result: { color: addColor } } },\n { type: MappingType.RangeToText, options: { from: -Infinity, to: 0, result: { color: removeColor } } },\n ];\n\n // For this we don't really consider sandwich view even though you can switch it on.\n const levels = data.getLevels();\n const totalTicks = levels.length ? levels[0][0].value : 0;\n const totalTicksRight = levels.length ? levels[0][0].valueRight : undefined;\n\n for (let key in table) {\n actionField.values.push(null);\n symbolField.values.push(key);\n\n const ticksLeft = table[key].total;\n const ticksRight = table[key].totalRight;\n\n // We are iterating over table of the data so totalTicksRight needs to be defined\n const totalTicksLeft = totalTicks - totalTicksRight!;\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 diffField.values.push(diff);\n baselineField.values.push(percentageLeft);\n comparisonField.values.push(percentageRight);\n }\n\n frame = {\n fields: [actionField, symbolField, baselineField, comparisonField, diffField],\n length: symbolField.values.length,\n };\n } else {\n const selfField = createNumberField('Self', data.selfField.config.unit);\n const totalField = createNumberField('Total', data.valueField.config.unit);\n\n for (let key in table) {\n actionField.values.push(null);\n symbolField.values.push(key);\n selfField.values.push(table[key].self);\n totalField.values.push(table[key].total);\n }\n\n frame = { fields: [actionField, symbolField, selfField, totalField], length: symbolField.values.length };\n }\n\n const dataFrames = applyFieldOverrides({\n data: [frame],\n fieldConfig: {\n defaults: {},\n overrides: [],\n },\n replaceVariables: (value: string) => value,\n theme,\n });\n\n return dataFrames[0];\n}\n\nfunction createNumberField(name: string, unit?: string): Field {\n const tableFieldOptions: TableFieldOptions = {\n width: TOP_TABLE_COLUMN_WIDTH,\n align: 'auto',\n inspect: false,\n cellOptions: { type: TableCellDisplayMode.Auto },\n };\n\n return {\n type: FieldType.number,\n name,\n values: [],\n config: {\n unit,\n custom: tableFieldOptions,\n },\n };\n}\n\nconst actionColumnWidth = 61;\n\nfunction createActionField(\n onSandwich: (str?: string) => void,\n onSearch: (str: string) => void,\n search?: string,\n sandwichItem?: string\n): Field {\n const options: TableCustomCellOptions = {\n type: TableCellDisplayMode.Custom,\n cellComponent: (props) => {\n return (\n <ActionCell\n frame={props.frame}\n onSandwich={onSandwich}\n onSearch={onSearch}\n search={search}\n sandwichItem={sandwichItem}\n rowIndex={props.rowIndex}\n />\n );\n },\n };\n\n const actionFieldTableConfig: TableFieldOptions = {\n filterable: false,\n width: actionColumnWidth,\n hideHeader: true,\n inspect: false,\n align: 'auto',\n cellOptions: options,\n };\n\n return {\n type: FieldType.number,\n name: 'actions',\n values: [],\n config: {\n custom: actionFieldTableConfig,\n },\n };\n}\n\ntype ActionCellProps = {\n frame: DataFrame;\n rowIndex: number;\n search?: string;\n sandwichItem?: string;\n onSearch: (symbol: string) => void;\n onSandwich: (symbol: string) => void;\n};\n\nfunction ActionCell(props: ActionCellProps) {\n const styles = getStylesActionCell();\n const symbol = props.frame.fields.find((f: Field) => f.name === 'Symbol')?.values[props.rowIndex];\n const isSearched = props.search === symbol;\n const isSandwiched = props.sandwichItem === symbol;\n\n return (\n <div className={styles.actionCellWrapper}>\n <IconButton\n className={styles.actionCellButton}\n name={'search'}\n variant={isSearched ? 'primary' : 'secondary'}\n tooltip={isSearched ? 'Clear from search' : 'Search for symbol'}\n aria-label={isSearched ? 'Clear from search' : 'Search for symbol'}\n onClick={() => {\n props.onSearch(isSearched ? '' : symbol);\n }}\n />\n <IconButton\n className={styles.actionCellButton}\n name={'gf-show-context'}\n tooltip={isSandwiched ? 'Remove from sandwich view' : 'Show in sandwich view'}\n variant={isSandwiched ? 'primary' : 'secondary'}\n aria-label={isSandwiched ? 'Remove from sandwich view' : 'Show in sandwich view'}\n onClick={() => {\n props.onSandwich(isSandwiched ? undefined : symbol);\n }}\n />\n </div>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => {\n return {\n topTableContainer: css({\n label: 'topTableContainer',\n padding: theme.spacing(1),\n backgroundColor: theme.colors.background.secondary,\n height: '100%',\n }),\n };\n};\n\nconst getStylesActionCell = () => {\n return {\n actionCellWrapper: css({\n label: 'actionCellWrapper',\n display: 'flex',\n height: '24px',\n }),\n actionCellButton: css({\n label: 'actionCellButton',\n marginRight: 0,\n width: '24px',\n }),\n };\n};\n\nexport default FlameGraphTopTableContainer;\n"],"names":[],"mappings":"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"}
|
1
|
+
{"version":3,"file":"FlameGraphTopTableContainer.js","sources":["../../../src/TopTable/FlameGraphTopTableContainer.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport { memo, useMemo, useState } from 'react';\nimport AutoSizer from 'react-virtualized-auto-sizer';\n\nimport {\n applyFieldOverrides,\n DataFrame,\n DataLinkClickEvent,\n Field,\n FieldType,\n GrafanaTheme2,\n MappingType,\n} from '@grafana/data';\nimport {\n IconButton,\n Table,\n TableCellDisplayMode,\n TableCustomCellOptions,\n TableFieldOptions,\n TableSortByFieldState,\n useStyles2,\n useTheme2,\n} from '@grafana/ui';\n\nimport { diffColorBlindColors, diffDefaultColors } from '../FlameGraph/colors';\nimport { FlameGraphDataContainer } from '../FlameGraph/dataTransform';\nimport { TOP_TABLE_COLUMN_WIDTH } from '../constants';\nimport { ColorScheme, ColorSchemeDiff, TableData } from '../types';\n\ntype Props = {\n data: FlameGraphDataContainer;\n onSymbolClick: (symbol: string) => void;\n // This is used for highlighting the search button in case there is exact match.\n search?: string;\n // We use these to filter out rows in the table if users is doing text search.\n matchedLabels?: Set<string>;\n sandwichItem?: string;\n onSearch: (str: string) => void;\n onSandwich: (str?: string) => void;\n onTableSort?: (sort: string) => void;\n colorScheme: ColorScheme | ColorSchemeDiff;\n};\n\nconst FlameGraphTopTableContainer = memo(\n ({\n data,\n onSymbolClick,\n search,\n matchedLabels,\n onSearch,\n sandwichItem,\n onSandwich,\n onTableSort,\n colorScheme,\n }: Props) => {\n const table = useMemo(() => {\n // Group the data by label, we show only one row per label and sum the values\n // TODO: should be by filename + funcName + linenumber?\n let filteredTable: { [key: string]: TableData } = {};\n for (let i = 0; i < data.data.length; i++) {\n const value = data.getValue(i);\n const valueRight = data.getValueRight(i);\n const self = data.getSelf(i);\n const label = data.getLabel(i);\n\n // If user is doing text search we filter out labels in the same way we highlight them in flame graph.\n if (!matchedLabels || matchedLabels.has(label)) {\n filteredTable[label] = filteredTable[label] || {};\n filteredTable[label].self = filteredTable[label].self ? filteredTable[label].self + self : self;\n filteredTable[label].total = filteredTable[label].total ? filteredTable[label].total + value : value;\n filteredTable[label].totalRight = filteredTable[label].totalRight\n ? filteredTable[label].totalRight + valueRight\n : valueRight;\n }\n }\n return filteredTable;\n }, [data, matchedLabels]);\n\n const styles = useStyles2(getStyles);\n const theme = useTheme2();\n\n const [sort, setSort] = useState<TableSortByFieldState[]>([{ displayName: 'Self', desc: true }]);\n\n return (\n <div className={styles.topTableContainer} data-testid=\"topTable\">\n <AutoSizer style={{ width: '100%' }}>\n {({ width, height }) => {\n if (width < 3 || height < 3) {\n return null;\n }\n\n const frame = buildTableDataFrame(\n data,\n table,\n width,\n onSymbolClick,\n onSearch,\n onSandwich,\n theme,\n colorScheme,\n search,\n sandwichItem\n );\n return (\n <Table\n initialSortBy={sort}\n onSortByChange={(s) => {\n if (s && s.length) {\n onTableSort?.(s[0].displayName + '_' + (s[0].desc ? 'desc' : 'asc'));\n }\n setSort(s);\n }}\n data={frame}\n width={width}\n height={height}\n />\n );\n }}\n </AutoSizer>\n </div>\n );\n }\n);\n\nFlameGraphTopTableContainer.displayName = 'FlameGraphTopTableContainer';\n\nfunction buildTableDataFrame(\n data: FlameGraphDataContainer,\n table: { [key: string]: TableData },\n width: number,\n onSymbolClick: (str: string) => void,\n onSearch: (str: string) => void,\n onSandwich: (str?: string) => void,\n theme: GrafanaTheme2,\n colorScheme: ColorScheme | ColorSchemeDiff,\n search?: string,\n sandwichItem?: string\n): DataFrame {\n const actionField: Field = createActionField(onSandwich, onSearch, search, sandwichItem);\n\n const symbolField: Field = {\n type: FieldType.string,\n name: 'Symbol',\n values: [],\n config: {\n custom: { width: width - actionColumnWidth - TOP_TABLE_COLUMN_WIDTH * 2 },\n links: [\n {\n title: 'Highlight symbol',\n url: '',\n onClick: (e: DataLinkClickEvent) => {\n const field: Field = e.origin.field;\n const value = field.values[e.origin.rowIndex];\n onSymbolClick(value);\n },\n },\n ],\n },\n };\n\n let frame;\n\n if (data.isDiffFlamegraph()) {\n symbolField.config.custom.width = width - actionColumnWidth - TOP_TABLE_COLUMN_WIDTH * 3;\n\n const baselineField = createNumberField('Baseline', 'percent');\n const comparisonField = createNumberField('Comparison', 'percent');\n const diffField = createNumberField('Diff', 'percent');\n diffField.config.custom.cellOptions.type = TableCellDisplayMode.ColorText;\n\n const [removeColor, addColor] =\n colorScheme === ColorSchemeDiff.DiffColorBlind\n ? [diffColorBlindColors[0], diffColorBlindColors[2]]\n : [diffDefaultColors[0], diffDefaultColors[2]];\n\n diffField.config.mappings = [\n { type: MappingType.ValueToText, options: { [Infinity]: { text: 'new', color: addColor } } },\n { type: MappingType.ValueToText, options: { [-100]: { text: 'removed', color: removeColor } } },\n { type: MappingType.RangeToText, options: { from: 0, to: Infinity, result: { color: addColor } } },\n { type: MappingType.RangeToText, options: { from: -Infinity, to: 0, result: { color: removeColor } } },\n ];\n\n // For this we don't really consider sandwich view even though you can switch it on.\n const levels = data.getLevels();\n const totalTicks = levels.length ? levels[0][0].value : 0;\n const totalTicksRight = levels.length ? levels[0][0].valueRight : undefined;\n\n for (let key in table) {\n actionField.values.push(null);\n symbolField.values.push(key);\n\n const ticksLeft = table[key].total;\n const ticksRight = table[key].totalRight;\n\n // We are iterating over table of the data so totalTicksRight needs to be defined\n const totalTicksLeft = totalTicks - totalTicksRight!;\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 diffField.values.push(diff);\n baselineField.values.push(percentageLeft);\n comparisonField.values.push(percentageRight);\n }\n\n frame = {\n fields: [actionField, symbolField, baselineField, comparisonField, diffField],\n length: symbolField.values.length,\n };\n } else {\n const selfField = createNumberField('Self', data.selfField.config.unit);\n const totalField = createNumberField('Total', data.valueField.config.unit);\n\n for (let key in table) {\n actionField.values.push(null);\n symbolField.values.push(key);\n selfField.values.push(table[key].self);\n totalField.values.push(table[key].total);\n }\n\n frame = { fields: [actionField, symbolField, selfField, totalField], length: symbolField.values.length };\n }\n\n const dataFrames = applyFieldOverrides({\n data: [frame],\n fieldConfig: {\n defaults: {},\n overrides: [],\n },\n replaceVariables: (value: string) => value,\n theme,\n });\n\n return dataFrames[0];\n}\n\nfunction createNumberField(name: string, unit?: string): Field {\n const tableFieldOptions: TableFieldOptions = {\n width: TOP_TABLE_COLUMN_WIDTH,\n align: 'auto',\n inspect: false,\n cellOptions: { type: TableCellDisplayMode.Auto },\n };\n\n return {\n type: FieldType.number,\n name,\n values: [],\n config: {\n unit,\n custom: tableFieldOptions,\n },\n };\n}\n\nconst actionColumnWidth = 61;\n\nfunction createActionField(\n onSandwich: (str?: string) => void,\n onSearch: (str: string) => void,\n search?: string,\n sandwichItem?: string\n): Field {\n const options: TableCustomCellOptions = {\n type: TableCellDisplayMode.Custom,\n cellComponent: (props) => {\n return (\n <ActionCell\n frame={props.frame}\n onSandwich={onSandwich}\n onSearch={onSearch}\n search={search}\n sandwichItem={sandwichItem}\n rowIndex={props.rowIndex}\n />\n );\n },\n };\n\n const actionFieldTableConfig: TableFieldOptions = {\n filterable: false,\n width: actionColumnWidth,\n hideHeader: true,\n inspect: false,\n align: 'auto',\n cellOptions: options,\n };\n\n return {\n type: FieldType.number,\n name: 'actions',\n values: [],\n config: {\n custom: actionFieldTableConfig,\n },\n };\n}\n\ntype ActionCellProps = {\n frame: DataFrame;\n rowIndex: number;\n search?: string;\n sandwichItem?: string;\n onSearch: (symbol: string) => void;\n onSandwich: (symbol: string) => void;\n};\n\nfunction ActionCell(props: ActionCellProps) {\n const styles = getStylesActionCell();\n const symbol = props.frame.fields.find((f: Field) => f.name === 'Symbol')?.values[props.rowIndex];\n const isSearched = props.search === symbol;\n const isSandwiched = props.sandwichItem === symbol;\n\n return (\n <div className={styles.actionCellWrapper}>\n <IconButton\n className={styles.actionCellButton}\n name={'search'}\n variant={isSearched ? 'primary' : 'secondary'}\n tooltip={isSearched ? 'Clear from search' : 'Search for symbol'}\n aria-label={isSearched ? 'Clear from search' : 'Search for symbol'}\n onClick={() => {\n props.onSearch(isSearched ? '' : symbol);\n }}\n />\n <IconButton\n className={styles.actionCellButton}\n name={'gf-show-context'}\n tooltip={isSandwiched ? 'Remove from sandwich view' : 'Show in sandwich view'}\n variant={isSandwiched ? 'primary' : 'secondary'}\n aria-label={isSandwiched ? 'Remove from sandwich view' : 'Show in sandwich view'}\n onClick={() => {\n props.onSandwich(isSandwiched ? undefined : symbol);\n }}\n />\n </div>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => {\n return {\n topTableContainer: css({\n label: 'topTableContainer',\n padding: theme.spacing(1),\n backgroundColor: theme.colors.background.secondary,\n height: '100%',\n }),\n };\n};\n\nconst getStylesActionCell = () => {\n return {\n actionCellWrapper: css({\n label: 'actionCellWrapper',\n display: 'flex',\n height: '24px',\n }),\n actionCellButton: css({\n label: 'actionCellButton',\n marginRight: 0,\n width: '24px',\n }),\n };\n};\n\nexport default FlameGraphTopTableContainer;\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
@@ -99,8 +99,12 @@ type Props = {
|
|
99
99
|
* Disable behaviour where similar items in the same stack will be collapsed into single item.
|
100
100
|
*/
|
101
101
|
disableCollapsing?: boolean;
|
102
|
+
/**
|
103
|
+
* Whether or not to keep any focused item when the profile data changes.
|
104
|
+
*/
|
105
|
+
keepFocusOnDataChange?: boolean;
|
102
106
|
};
|
103
|
-
declare const FlameGraphContainer: ({ data, onTableSymbolClick, onViewSelected, onTextAlignSelected, onTableSort, getTheme, stickyHeader, extraHeaderElements, vertical, showFlameGraphOnly, disableCollapsing, getExtraContextMenuButtons, }: Props) => react_jsx_runtime.JSX.Element | null;
|
107
|
+
declare const FlameGraphContainer: ({ data, onTableSymbolClick, onViewSelected, onTextAlignSelected, onTableSort, getTheme, stickyHeader, extraHeaderElements, vertical, showFlameGraphOnly, disableCollapsing, keepFocusOnDataChange, getExtraContextMenuButtons, }: Props) => react_jsx_runtime.JSX.Element | null;
|
104
108
|
|
105
109
|
declare const data: DataFrameDTO;
|
106
110
|
|