@perses-dev/flame-chart-plugin 0.2.0 → 0.3.1
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/__mf/js/FlameChart.d9fcbf0f.js +5 -0
- package/__mf/js/async/109.c49d097c.js +73 -0
- package/__mf/js/async/200.dd3d1322.js +38 -0
- package/__mf/js/async/624.a5e6980d.js +7 -0
- package/__mf/js/async/__federation_expose_FlameChart.6909ede6.js +17 -0
- package/__mf/js/main.b0093a6f.js +5 -0
- package/lib/FlameChart.d.ts +1 -1
- package/lib/FlameChart.d.ts.map +1 -1
- package/lib/FlameChart.js +1 -2
- package/lib/FlameChart.js.map +1 -1
- package/lib/cjs/FlameChart.js +3 -4
- package/lib/cjs/components/FlameChart.js +1 -1
- package/lib/cjs/components/FlameChartOptionsEditorSettings.js +22 -5
- package/lib/cjs/components/FlameChartPanel.js +22 -5
- package/lib/cjs/utils/data-transform.js +32 -21
- package/lib/cjs/utils/utils.js +14 -0
- package/lib/components/FlameChart.js +2 -2
- package/lib/components/FlameChart.js.map +1 -1
- package/lib/components/FlameChartOptionsEditorSettings.d.ts.map +1 -1
- package/lib/components/FlameChartOptionsEditorSettings.js +25 -8
- package/lib/components/FlameChartOptionsEditorSettings.js.map +1 -1
- package/lib/components/FlameChartPanel.d.ts.map +1 -1
- package/lib/components/FlameChartPanel.js +23 -6
- package/lib/components/FlameChartPanel.js.map +1 -1
- package/lib/flame-chart-model.d.ts +1 -0
- package/lib/flame-chart-model.d.ts.map +1 -1
- package/lib/flame-chart-model.js.map +1 -1
- package/lib/utils/data-transform.d.ts +3 -2
- package/lib/utils/data-transform.d.ts.map +1 -1
- package/lib/utils/data-transform.js +27 -17
- package/lib/utils/data-transform.js.map +1 -1
- package/lib/utils/utils.d.ts +7 -0
- package/lib/utils/utils.d.ts.map +1 -1
- package/lib/utils/utils.js +13 -0
- package/lib/utils/utils.js.map +1 -1
- package/mf-manifest.json +11 -11
- package/mf-stats.json +11 -11
- package/package.json +5 -5
- package/__mf/js/FlameChart.96aae761.js +0 -5
- package/__mf/js/async/109.f7e97e30.js +0 -73
- package/__mf/js/async/464.bb266d9b.js +0 -7
- package/__mf/js/async/600.fdf527b8.js +0 -38
- package/__mf/js/async/__federation_expose_FlameChart.aaa6df30.js +0 -17
- package/__mf/js/main.4931a266.js +0 -5
- /package/__mf/js/async/{109.f7e97e30.js.LICENSE.txt → 109.c49d097c.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{464.bb266d9b.js.LICENSE.txt → 624.a5e6980d.js.LICENSE.txt} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/FlameChart.tsx"],"sourcesContent":["// Copyright 2025 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport {\n CustomSeriesRenderItem,\n CustomSeriesRenderItemAPI,\n CustomSeriesRenderItemParams,\n CustomSeriesRenderItemReturn,\n} from 'echarts';\nimport { Stack, Box, Menu, MenuItem, Divider, useTheme } from '@mui/material';\nimport { ReactElement, useState, useMemo, MouseEvent } from 'react';\nimport { ProfileData } from '@perses-dev/core';\nimport { useChartsTheme, EChart, MouseEventsParameters } from '@perses-dev/components';\nimport RefreshIcon from 'mdi-material-ui/Refresh';\nimport EyeIcon from 'mdi-material-ui/EyeOutline';\nimport ContentCopyIcon from 'mdi-material-ui/ContentCopy';\nimport { EChartsCoreOption } from 'echarts/core';\nimport { recursionJson, findTotalSampleByName } from '../utils/data-transform';\nimport { generateTooltip } from '../utils/tooltip';\nimport { FlameChartSample as Sample } from '../utils/data-model';\nimport { CustomBreadcrumb } from './CustomBreadcrumb';\n\nconst ITEM_GAP = 2; // vertical gap between flame chart items\nconst Y_MIN_SMALL = 6; // min value of y axis for small containers\nconst Y_MIN_LARGE = 20; // min value of y axis for large containers\nconst LARGE_CONTAINER_THRESHOLD = 600;\nconst CONTAINER_PADDING = 10;\nconst BREADCRUMB_SPACE = 50;\n\nexport interface FlameChartProps {\n width: number;\n height: number;\n data: ProfileData;\n palette: 'package-name' | 'value';\n selectedId: number;\n searchValue: string;\n onSelectedIdChange: (newId: number) => void;\n}\n\nexport function FlameChart(props: FlameChartProps): ReactElement {\n const { width, height, data, palette, selectedId, searchValue, onSelectedIdChange } = props;\n const theme = useTheme();\n const chartsTheme = useChartsTheme();\n const [menuPosition, setMenuPosition] = useState<{ mouseX: number; mouseY: number } | null>(null);\n const [selectedItem, setSelectedItem] = useState<{ id: number; name: string }>({ id: 0, name: '' });\n const [isCopied, setIsCopied] = useState(false);\n\n const seriesData = useMemo(\n () => recursionJson(palette, data.metadata, data.profile.stackTrace, searchValue, selectedId),\n [palette, data.metadata, data.profile.stackTrace, selectedId, searchValue]\n );\n\n const handleItemClick = (params: MouseEventsParameters<Sample>): void => {\n const data: Sample = params.data;\n const functionName = data.value[6];\n const functionId = data.name;\n setSelectedItem({ id: functionId, name: functionName });\n\n // To ensure that the cursor is positioned inside the menu when it opens,\n // we adjust the click event coordinates as follows:\n if ('event' in params) {\n const mouseEvent = params.event as { event: MouseEvent };\n setMenuPosition({\n mouseX: mouseEvent.event.clientX - 2,\n mouseY: mouseEvent.event.clientY - 4,\n });\n }\n };\n\n const handleFocusBlock = (): void => {\n onSelectedIdChange(selectedItem.id);\n handleClose();\n };\n\n const handleCopyFunctionName = (): void => {\n if ((selectedId || selectedId === 0) && selectedItem.name) {\n navigator.clipboard.writeText(selectedItem.name);\n }\n setIsCopied(true);\n };\n\n const handleResetGraph = (): void => {\n if (selectedId) {\n onSelectedIdChange(0);\n }\n handleClose();\n };\n\n const handleClose = (): void => {\n setMenuPosition(null);\n if (isCopied) setIsCopied(false);\n };\n\n const renderItem: CustomSeriesRenderItem = (params: CustomSeriesRenderItemParams, api: CustomSeriesRenderItemAPI) => {\n const level = api.value(0);\n const start = api.coord([api.value(1), level]);\n const end = api.coord([api.value(2), level]);\n const height = (((api.size && api.size([0, 1])) || [0, 20]) as number[])[1];\n const width = (end?.[0] ?? 0) - (start?.[0] ?? 0);\n\n return {\n type: 'rect',\n transition: ['shape'],\n shape: {\n x: start?.[0],\n y: (start?.[1] ?? 0) - (height ?? 0) / 2,\n width,\n height: (height ?? ITEM_GAP) - ITEM_GAP,\n r: 0,\n },\n style: {\n fill: api.visual('color'),\n },\n emphasis: {\n style: {\n stroke: '#000',\n },\n },\n textConfig: {\n position: 'insideLeft',\n },\n textContent: {\n style: {\n text: api.value(3),\n fill: '#000',\n width: width - 4,\n overflow: 'truncate',\n ellipsis: '..',\n truncateMinChar: 1,\n },\n emphasis: {\n style: {\n stroke: '#000',\n lineWidth: 0.5,\n },\n },\n },\n } as CustomSeriesRenderItemReturn;\n };\n\n const option: EChartsCoreOption = useMemo(() => {\n if (data.profile.stackTrace === undefined) return chartsTheme.noDataOption;\n\n const maxDepth = Math.max(...seriesData.map((s) => s.value[0])); // maximum depth of the stack trace\n const yAxisMax = Math.max(height > LARGE_CONTAINER_THRESHOLD ? Y_MIN_LARGE : Y_MIN_SMALL, maxDepth);\n const totalStart = seriesData[0]?.value[1]; // start value of the total function\n const totalEnd = seriesData[0]?.value[2]; // end value of the total function\n const xAxisMin = totalStart;\n const xAxisMax = totalEnd;\n\n // compute flame chart padding top and bottom\n const padding = (height / (yAxisMax - 1) - ITEM_GAP) / 2 + 1;\n\n const option = {\n tooltip: {\n appendToBody: true,\n confine: true,\n formatter: (params: Sample): string => generateTooltip(params, data.metadata?.units),\n backgroundColor: theme.palette.background.paper,\n borderColor: theme.palette.background.paper,\n textStyle: {\n color: theme.palette.text.primary,\n },\n },\n xAxis: {\n show: false,\n min: xAxisMin,\n max: xAxisMax,\n axisLabel: {\n show: false,\n },\n },\n yAxis: {\n show: false,\n max: yAxisMax,\n inverse: true, // Reverse Y axis\n axisLabel: {\n show: false,\n },\n },\n axisLabel: {\n overflow: 'truncate',\n width: width / 3,\n },\n grid: {\n left: 5,\n right: 5,\n top: padding + 5,\n bottom: padding,\n },\n series: [\n {\n type: 'custom',\n renderItem,\n encode: {\n x: [0, 1, 2],\n y: 0,\n },\n data: seriesData,\n },\n ],\n };\n\n return option;\n }, [data, chartsTheme, theme, width, seriesData, height]);\n\n // Use useMemo to memoize the flame chart component and prevent unnecessary re-renders.\n // This ensures the chart does not re-render when the onClick event updates state variables\n // like menuPosition or selectedId.\n const flameChart = useMemo(\n () => (\n <EChart\n sx={{\n width: width,\n height: height - 2 * CONTAINER_PADDING - BREADCRUMB_SPACE,\n }}\n option={option} // even data is in this prop\n theme={chartsTheme.echartsTheme}\n onEvents={{\n click: handleItemClick as (params: MouseEventsParameters<unknown>) => void,\n }}\n />\n ),\n [chartsTheme.echartsTheme, height, option, width]\n );\n\n return (\n <Stack\n style={{\n width: width,\n height: height,\n }}\n alignItems=\"center\"\n >\n <CustomBreadcrumb\n totalValue={seriesData[0]?.value[3] || ''} // name of the total function\n totalSample={seriesData[0]?.value[8] || 0} // total sample of the total function\n otherItemSample={findTotalSampleByName(seriesData, selectedId)} // total sample of the selected function\n onSelectedIdChange={onSelectedIdChange}\n />\n {flameChart}\n <Menu\n sx={{\n '& .MuiPaper-root': {\n backgroundColor: theme.palette.background.paper,\n color: theme.palette.text.primary,\n padding: '5px',\n paddingBottom: '0px',\n },\n '& .MuiMenuItem-root': {\n '&:hover': {\n backgroundColor: theme.palette.action.hover,\n },\n },\n }}\n open={menuPosition !== null}\n onClose={handleClose}\n anchorReference=\"anchorPosition\"\n anchorPosition={menuPosition !== null ? { top: menuPosition.mouseY, left: menuPosition.mouseX } : undefined}\n >\n <Box\n sx={{\n paddingLeft: '16px',\n paddingBottom: '8px',\n }}\n >\n {selectedItem.name}\n </Box>\n <Divider sx={{ backgroundColor: theme.palette.divider }} />\n <MenuItem onClick={handleFocusBlock}>\n <EyeIcon fontSize=\"small\" color=\"secondary\" sx={{ marginRight: '10px' }} />\n Focus block\n </MenuItem>\n <MenuItem onClick={handleCopyFunctionName} disabled={isCopied}>\n <ContentCopyIcon fontSize=\"small\" color=\"secondary\" sx={{ marginRight: '10px' }} />\n {isCopied ? 'Copied' : 'Copy function name'}\n </MenuItem>\n <MenuItem onClick={handleResetGraph}>\n <RefreshIcon fontSize=\"small\" color=\"secondary\" sx={{ marginRight: '10px' }} />\n Reset graph\n </MenuItem>\n </Menu>\n </Stack>\n );\n}\n"],"names":["Stack","Box","Menu","MenuItem","Divider","useTheme","useState","useMemo","useChartsTheme","EChart","RefreshIcon","EyeIcon","ContentCopyIcon","recursionJson","findTotalSampleByName","generateTooltip","CustomBreadcrumb","ITEM_GAP","Y_MIN_SMALL","Y_MIN_LARGE","LARGE_CONTAINER_THRESHOLD","CONTAINER_PADDING","BREADCRUMB_SPACE","FlameChart","props","width","height","data","palette","selectedId","searchValue","onSelectedIdChange","theme","chartsTheme","menuPosition","setMenuPosition","selectedItem","setSelectedItem","id","name","isCopied","setIsCopied","seriesData","metadata","profile","stackTrace","handleItemClick","params","functionName","value","functionId","mouseEvent","event","mouseX","clientX","mouseY","clientY","handleFocusBlock","handleClose","handleCopyFunctionName","navigator","clipboard","writeText","handleResetGraph","renderItem","api","level","start","coord","end","size","type","transition","shape","x","y","r","style","fill","visual","emphasis","stroke","textConfig","position","textContent","text","overflow","ellipsis","truncateMinChar","lineWidth","option","undefined","noDataOption","maxDepth","Math","max","map","s","yAxisMax","totalStart","totalEnd","xAxisMin","xAxisMax","padding","tooltip","appendToBody","confine","formatter","units","backgroundColor","background","paper","borderColor","textStyle","color","primary","xAxis","show","min","axisLabel","yAxis","inverse","grid","left","right","top","bottom","series","encode","flameChart","sx","echartsTheme","onEvents","click","alignItems","totalValue","totalSample","otherItemSample","paddingBottom","action","hover","open","onClose","anchorReference","anchorPosition","paddingLeft","divider","onClick","fontSize","marginRight","disabled"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/FlameChart.tsx"],"sourcesContent":["// Copyright 2025 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport {\n CustomSeriesRenderItem,\n CustomSeriesRenderItemAPI,\n CustomSeriesRenderItemParams,\n CustomSeriesRenderItemReturn,\n} from 'echarts';\nimport { Stack, Box, Menu, MenuItem, Divider, useTheme } from '@mui/material';\nimport { ReactElement, useState, useMemo, MouseEvent } from 'react';\nimport { ProfileData } from '@perses-dev/core';\nimport { useChartsTheme, EChart, MouseEventsParameters } from '@perses-dev/components';\nimport RefreshIcon from 'mdi-material-ui/Refresh';\nimport EyeIcon from 'mdi-material-ui/EyeOutline';\nimport ContentCopyIcon from 'mdi-material-ui/ContentCopy';\nimport { EChartsCoreOption } from 'echarts/core';\nimport { buildSamples, findTotalSampleByName } from '../utils/data-transform';\nimport { generateTooltip } from '../utils/tooltip';\nimport { FlameChartSample as Sample } from '../utils/data-model';\nimport { CustomBreadcrumb } from './CustomBreadcrumb';\n\nconst ITEM_GAP = 2; // vertical gap between flame chart items\nconst Y_MIN_SMALL = 6; // min value of y axis for small containers\nconst Y_MIN_LARGE = 20; // min value of y axis for large containers\nconst LARGE_CONTAINER_THRESHOLD = 600;\nconst CONTAINER_PADDING = 10;\nconst BREADCRUMB_SPACE = 50;\n\nexport interface FlameChartProps {\n width: number;\n height: number;\n data: ProfileData;\n palette: 'package-name' | 'value';\n selectedId: number;\n searchValue: string;\n onSelectedIdChange: (newId: number) => void;\n}\n\nexport function FlameChart(props: FlameChartProps): ReactElement {\n const { width, height, data, palette, selectedId, searchValue, onSelectedIdChange } = props;\n const theme = useTheme();\n const chartsTheme = useChartsTheme();\n const [menuPosition, setMenuPosition] = useState<{ mouseX: number; mouseY: number } | null>(null);\n const [selectedItem, setSelectedItem] = useState<{ id: number; name: string }>({ id: 0, name: '' });\n const [isCopied, setIsCopied] = useState(false);\n\n const seriesData = useMemo(\n () => buildSamples(palette, data.metadata, data.profile.stackTrace, searchValue, selectedId),\n [palette, data.metadata, data.profile.stackTrace, selectedId, searchValue]\n );\n\n const handleItemClick = (params: MouseEventsParameters<Sample>): void => {\n const data: Sample = params.data;\n const functionName = data.value[6];\n const functionId = data.name;\n setSelectedItem({ id: functionId, name: functionName });\n\n // To ensure that the cursor is positioned inside the menu when it opens,\n // we adjust the click event coordinates as follows:\n if ('event' in params) {\n const mouseEvent = params.event as { event: MouseEvent };\n setMenuPosition({\n mouseX: mouseEvent.event.clientX - 2,\n mouseY: mouseEvent.event.clientY - 4,\n });\n }\n };\n\n const handleFocusBlock = (): void => {\n onSelectedIdChange(selectedItem.id);\n handleClose();\n };\n\n const handleCopyFunctionName = (): void => {\n if ((selectedId || selectedId === 0) && selectedItem.name) {\n navigator.clipboard.writeText(selectedItem.name);\n }\n setIsCopied(true);\n };\n\n const handleResetGraph = (): void => {\n if (selectedId) {\n onSelectedIdChange(0);\n }\n handleClose();\n };\n\n const handleClose = (): void => {\n setMenuPosition(null);\n if (isCopied) setIsCopied(false);\n };\n\n const renderItem: CustomSeriesRenderItem = (params: CustomSeriesRenderItemParams, api: CustomSeriesRenderItemAPI) => {\n const level = api.value(0);\n const start = api.coord([api.value(1), level]);\n const end = api.coord([api.value(2), level]);\n const height = (((api.size && api.size([0, 1])) || [0, 20]) as number[])[1];\n const width = (end?.[0] ?? 0) - (start?.[0] ?? 0);\n\n return {\n type: 'rect',\n transition: ['shape'],\n shape: {\n x: start?.[0],\n y: (start?.[1] ?? 0) - (height ?? 0) / 2,\n width,\n height: (height ?? ITEM_GAP) - ITEM_GAP,\n r: 0,\n },\n style: {\n fill: api.visual('color'),\n },\n emphasis: {\n style: {\n stroke: '#000',\n },\n },\n textConfig: {\n position: 'insideLeft',\n },\n textContent: {\n style: {\n text: api.value(3),\n fill: '#000',\n width: width - 4,\n overflow: 'truncate',\n ellipsis: '..',\n truncateMinChar: 1,\n },\n emphasis: {\n style: {\n stroke: '#000',\n lineWidth: 0.5,\n },\n },\n },\n } as CustomSeriesRenderItemReturn;\n };\n\n const option: EChartsCoreOption = useMemo(() => {\n if (data.profile.stackTrace === undefined) return chartsTheme.noDataOption;\n\n const maxDepth = Math.max(...seriesData.map((s) => s.value[0])); // maximum depth of the stack trace\n const yAxisMax = Math.max(height > LARGE_CONTAINER_THRESHOLD ? Y_MIN_LARGE : Y_MIN_SMALL, maxDepth);\n const totalStart = seriesData[0]?.value[1]; // start value of the total function\n const totalEnd = seriesData[0]?.value[2]; // end value of the total function\n const xAxisMin = totalStart;\n const xAxisMax = totalEnd;\n\n // compute flame chart padding top and bottom\n const padding = (height / (yAxisMax - 1) - ITEM_GAP) / 2 + 1;\n\n const option = {\n tooltip: {\n appendToBody: true,\n confine: true,\n formatter: (params: Sample): string => generateTooltip(params, data.metadata?.units),\n backgroundColor: theme.palette.background.paper,\n borderColor: theme.palette.background.paper,\n textStyle: {\n color: theme.palette.text.primary,\n },\n },\n xAxis: {\n show: false,\n min: xAxisMin,\n max: xAxisMax,\n axisLabel: {\n show: false,\n },\n },\n yAxis: {\n show: false,\n max: yAxisMax,\n inverse: true, // Reverse Y axis\n axisLabel: {\n show: false,\n },\n },\n axisLabel: {\n overflow: 'truncate',\n width: width / 3,\n },\n grid: {\n left: 5,\n right: 5,\n top: padding + 5,\n bottom: padding,\n },\n series: [\n {\n type: 'custom',\n renderItem,\n encode: {\n x: [0, 1, 2],\n y: 0,\n },\n data: seriesData,\n },\n ],\n };\n\n return option;\n }, [data, chartsTheme, theme, width, seriesData, height]);\n\n // Use useMemo to memoize the flame chart component and prevent unnecessary re-renders.\n // This ensures the chart does not re-render when the onClick event updates state variables\n // like menuPosition or selectedId.\n const flameChart = useMemo(\n () => (\n <EChart\n sx={{\n width: width,\n height: height - 2 * CONTAINER_PADDING - BREADCRUMB_SPACE,\n }}\n option={option} // even data is in this prop\n theme={chartsTheme.echartsTheme}\n onEvents={{\n click: handleItemClick as (params: MouseEventsParameters<unknown>) => void,\n }}\n />\n ),\n [chartsTheme.echartsTheme, height, option, width]\n );\n\n return (\n <Stack\n style={{\n width: width,\n height: height,\n }}\n alignItems=\"center\"\n >\n <CustomBreadcrumb\n totalValue={seriesData[0]?.value[3] || ''} // name of the total function\n totalSample={seriesData[0]?.value[8] || 0} // total sample of the total function\n otherItemSample={findTotalSampleByName(seriesData, selectedId)} // total sample of the selected function\n onSelectedIdChange={onSelectedIdChange}\n />\n {flameChart}\n <Menu\n sx={{\n '& .MuiPaper-root': {\n backgroundColor: theme.palette.background.paper,\n color: theme.palette.text.primary,\n padding: '5px',\n paddingBottom: '0px',\n },\n '& .MuiMenuItem-root': {\n '&:hover': {\n backgroundColor: theme.palette.action.hover,\n },\n },\n }}\n open={menuPosition !== null}\n onClose={handleClose}\n anchorReference=\"anchorPosition\"\n anchorPosition={menuPosition !== null ? { top: menuPosition.mouseY, left: menuPosition.mouseX } : undefined}\n >\n <Box\n sx={{\n paddingLeft: '16px',\n paddingBottom: '8px',\n }}\n >\n {selectedItem.name}\n </Box>\n <Divider sx={{ backgroundColor: theme.palette.divider }} />\n <MenuItem onClick={handleFocusBlock}>\n <EyeIcon fontSize=\"small\" color=\"secondary\" sx={{ marginRight: '10px' }} />\n Focus block\n </MenuItem>\n <MenuItem onClick={handleCopyFunctionName} disabled={isCopied}>\n <ContentCopyIcon fontSize=\"small\" color=\"secondary\" sx={{ marginRight: '10px' }} />\n {isCopied ? 'Copied' : 'Copy function name'}\n </MenuItem>\n <MenuItem onClick={handleResetGraph}>\n <RefreshIcon fontSize=\"small\" color=\"secondary\" sx={{ marginRight: '10px' }} />\n Reset graph\n </MenuItem>\n </Menu>\n </Stack>\n );\n}\n"],"names":["Stack","Box","Menu","MenuItem","Divider","useTheme","useState","useMemo","useChartsTheme","EChart","RefreshIcon","EyeIcon","ContentCopyIcon","buildSamples","findTotalSampleByName","generateTooltip","CustomBreadcrumb","ITEM_GAP","Y_MIN_SMALL","Y_MIN_LARGE","LARGE_CONTAINER_THRESHOLD","CONTAINER_PADDING","BREADCRUMB_SPACE","FlameChart","props","width","height","data","palette","selectedId","searchValue","onSelectedIdChange","theme","chartsTheme","menuPosition","setMenuPosition","selectedItem","setSelectedItem","id","name","isCopied","setIsCopied","seriesData","metadata","profile","stackTrace","handleItemClick","params","functionName","value","functionId","mouseEvent","event","mouseX","clientX","mouseY","clientY","handleFocusBlock","handleClose","handleCopyFunctionName","navigator","clipboard","writeText","handleResetGraph","renderItem","api","level","start","coord","end","size","type","transition","shape","x","y","r","style","fill","visual","emphasis","stroke","textConfig","position","textContent","text","overflow","ellipsis","truncateMinChar","lineWidth","option","undefined","noDataOption","maxDepth","Math","max","map","s","yAxisMax","totalStart","totalEnd","xAxisMin","xAxisMax","padding","tooltip","appendToBody","confine","formatter","units","backgroundColor","background","paper","borderColor","textStyle","color","primary","xAxis","show","min","axisLabel","yAxis","inverse","grid","left","right","top","bottom","series","encode","flameChart","sx","echartsTheme","onEvents","click","alignItems","totalValue","totalSample","otherItemSample","paddingBottom","action","hover","open","onClose","anchorReference","anchorPosition","paddingLeft","divider","onClick","fontSize","marginRight","disabled"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FlameChartOptionsEditorSettings.d.ts","sourceRoot":"","sources":["../../../src/components/FlameChartOptionsEditorSettings.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"FlameChartOptionsEditorSettings.d.ts","sourceRoot":"","sources":["../../../src/components/FlameChartOptionsEditorSettings.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAQrC,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AAapE,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,4BAA4B,GAAG,YAAY,CA6CjG"}
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
-
import { OptionsEditorGroup, OptionsEditorGrid, OptionsEditorColumn } from '@perses-dev/components';
|
|
15
|
-
import { Button } from '@mui/material';
|
|
16
|
-
import { usePaletteState, useShowSettingsState, useShowSeriesState, useShowTableState, useShowFlameGraphState, resetSettings } from '../utils/utils';
|
|
14
|
+
import { OptionsEditorGroup, OptionsEditorGrid, OptionsEditorColumn, OptionsEditorControl } from '@perses-dev/components';
|
|
15
|
+
import { Button, TextField } from '@mui/material';
|
|
16
|
+
import { usePaletteState, useShowSettingsState, useShowSeriesState, useShowTableState, useShowFlameGraphState, resetSettings, useTraceHeightState } from '../utils/utils';
|
|
17
17
|
import { PaletteSelector } from './PaletteSelector';
|
|
18
18
|
import { SwitchSelector } from './SwitchSelector';
|
|
19
19
|
export function FlameChartOptionsEditorSettings(props) {
|
|
@@ -23,15 +23,32 @@ export function FlameChartOptionsEditorSettings(props) {
|
|
|
23
23
|
const { handleShowSeriesChange } = useShowSeriesState(props);
|
|
24
24
|
const { handleShowTableChange } = useShowTableState(props);
|
|
25
25
|
const { handleShowFlameGraphChange } = useShowFlameGraphState(props);
|
|
26
|
+
const { handleTraceHeightChange } = useTraceHeightState(props);
|
|
26
27
|
return /*#__PURE__*/ _jsxs(OptionsEditorGrid, {
|
|
27
28
|
children: [
|
|
28
29
|
/*#__PURE__*/ _jsx(OptionsEditorColumn, {
|
|
29
|
-
children: /*#__PURE__*/
|
|
30
|
+
children: /*#__PURE__*/ _jsxs(OptionsEditorGroup, {
|
|
30
31
|
title: "Misc",
|
|
31
|
-
children:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
children: [
|
|
33
|
+
/*#__PURE__*/ _jsx(PaletteSelector, {
|
|
34
|
+
value: value.palette,
|
|
35
|
+
onChange: handlePaletteChange
|
|
36
|
+
}),
|
|
37
|
+
/*#__PURE__*/ _jsx(OptionsEditorControl, {
|
|
38
|
+
label: "Trace Height",
|
|
39
|
+
control: /*#__PURE__*/ _jsx(TextField, {
|
|
40
|
+
type: "number",
|
|
41
|
+
value: value.traceHeight ?? '',
|
|
42
|
+
slotProps: {
|
|
43
|
+
htmlInput: {
|
|
44
|
+
min: 0,
|
|
45
|
+
step: 1
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
onChange: handleTraceHeightChange
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
]
|
|
35
52
|
})
|
|
36
53
|
}),
|
|
37
54
|
/*#__PURE__*/ _jsx(OptionsEditorColumn, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/FlameChartOptionsEditorSettings.tsx"],"sourcesContent":["// Copyright 2025 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ReactElement } from 'react';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/components/FlameChartOptionsEditorSettings.tsx"],"sourcesContent":["// Copyright 2025 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ReactElement } from 'react';\nimport {\n OptionsEditorGroup,\n OptionsEditorGrid,\n OptionsEditorColumn,\n OptionsEditorControl,\n} from '@perses-dev/components';\nimport { Button, TextField } from '@mui/material';\nimport { FlameChartOptionsEditorProps } from '../flame-chart-model';\nimport {\n usePaletteState,\n useShowSettingsState,\n useShowSeriesState,\n useShowTableState,\n useShowFlameGraphState,\n resetSettings,\n useTraceHeightState,\n} from '../utils/utils';\nimport { PaletteSelector } from './PaletteSelector';\nimport { SwitchSelector } from './SwitchSelector';\n\nexport function FlameChartOptionsEditorSettings(props: FlameChartOptionsEditorProps): ReactElement {\n const { value } = props;\n\n const { handlePaletteChange } = usePaletteState(props);\n const { handleShowSettingsChange } = useShowSettingsState(props);\n const { handleShowSeriesChange } = useShowSeriesState(props);\n const { handleShowTableChange } = useShowTableState(props);\n const { handleShowFlameGraphChange } = useShowFlameGraphState(props);\n const { handleTraceHeightChange } = useTraceHeightState(props);\n\n return (\n <OptionsEditorGrid>\n <OptionsEditorColumn>\n <OptionsEditorGroup title=\"Misc\">\n <PaletteSelector value={value.palette} onChange={handlePaletteChange} />\n <OptionsEditorControl\n label=\"Trace Height\"\n control={\n <TextField\n type=\"number\"\n value={value.traceHeight ?? ''}\n slotProps={{ htmlInput: { min: 0, step: 1 } }}\n onChange={handleTraceHeightChange}\n />\n }\n />\n </OptionsEditorGroup>\n </OptionsEditorColumn>\n <OptionsEditorColumn>\n <OptionsEditorGroup title=\"Panels to display\">\n <SwitchSelector label=\"Show Options\" value={value.showSettings} onChange={handleShowSettingsChange} />\n <SwitchSelector label=\"Show Series\" value={value.showSeries} onChange={handleShowSeriesChange} />\n <SwitchSelector label=\"Show Table\" value={value.showTable} onChange={handleShowTableChange} />\n <SwitchSelector label=\"Show Flame Graph\" value={value.showFlameGraph} onChange={handleShowFlameGraphChange} />\n </OptionsEditorGroup>\n </OptionsEditorColumn>\n <OptionsEditorColumn>\n <OptionsEditorGroup title=\"Reset Settings\">\n <Button variant=\"outlined\" color=\"secondary\" onClick={() => resetSettings(props)}>\n Reset To Defaults\n </Button>\n </OptionsEditorGroup>\n </OptionsEditorColumn>\n </OptionsEditorGrid>\n );\n}\n"],"names":["OptionsEditorGroup","OptionsEditorGrid","OptionsEditorColumn","OptionsEditorControl","Button","TextField","usePaletteState","useShowSettingsState","useShowSeriesState","useShowTableState","useShowFlameGraphState","resetSettings","useTraceHeightState","PaletteSelector","SwitchSelector","FlameChartOptionsEditorSettings","props","value","handlePaletteChange","handleShowSettingsChange","handleShowSeriesChange","handleShowTableChange","handleShowFlameGraphChange","handleTraceHeightChange","title","palette","onChange","label","control","type","traceHeight","slotProps","htmlInput","min","step","showSettings","showSeries","showTable","showFlameGraph","variant","color","onClick"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAGjC,SACEA,kBAAkB,EAClBC,iBAAiB,EACjBC,mBAAmB,EACnBC,oBAAoB,QACf,yBAAyB;AAChC,SAASC,MAAM,EAAEC,SAAS,QAAQ,gBAAgB;AAElD,SACEC,eAAe,EACfC,oBAAoB,EACpBC,kBAAkB,EAClBC,iBAAiB,EACjBC,sBAAsB,EACtBC,aAAa,EACbC,mBAAmB,QACd,iBAAiB;AACxB,SAASC,eAAe,QAAQ,oBAAoB;AACpD,SAASC,cAAc,QAAQ,mBAAmB;AAElD,OAAO,SAASC,gCAAgCC,KAAmC;IACjF,MAAM,EAAEC,KAAK,EAAE,GAAGD;IAElB,MAAM,EAAEE,mBAAmB,EAAE,GAAGZ,gBAAgBU;IAChD,MAAM,EAAEG,wBAAwB,EAAE,GAAGZ,qBAAqBS;IAC1D,MAAM,EAAEI,sBAAsB,EAAE,GAAGZ,mBAAmBQ;IACtD,MAAM,EAAEK,qBAAqB,EAAE,GAAGZ,kBAAkBO;IACpD,MAAM,EAAEM,0BAA0B,EAAE,GAAGZ,uBAAuBM;IAC9D,MAAM,EAAEO,uBAAuB,EAAE,GAAGX,oBAAoBI;IAExD,qBACE,MAACf;;0BACC,KAACC;0BACC,cAAA,MAACF;oBAAmBwB,OAAM;;sCACxB,KAACX;4BAAgBI,OAAOA,MAAMQ,OAAO;4BAAEC,UAAUR;;sCACjD,KAACf;4BACCwB,OAAM;4BACNC,uBACE,KAACvB;gCACCwB,MAAK;gCACLZ,OAAOA,MAAMa,WAAW,IAAI;gCAC5BC,WAAW;oCAAEC,WAAW;wCAAEC,KAAK;wCAAGC,MAAM;oCAAE;gCAAE;gCAC5CR,UAAUH;;;;;;0BAMpB,KAACrB;0BACC,cAAA,MAACF;oBAAmBwB,OAAM;;sCACxB,KAACV;4BAAea,OAAM;4BAAeV,OAAOA,MAAMkB,YAAY;4BAAET,UAAUP;;sCAC1E,KAACL;4BAAea,OAAM;4BAAcV,OAAOA,MAAMmB,UAAU;4BAAEV,UAAUN;;sCACvE,KAACN;4BAAea,OAAM;4BAAaV,OAAOA,MAAMoB,SAAS;4BAAEX,UAAUL;;sCACrE,KAACP;4BAAea,OAAM;4BAAmBV,OAAOA,MAAMqB,cAAc;4BAAEZ,UAAUJ;;;;;0BAGpF,KAACpB;0BACC,cAAA,KAACF;oBAAmBwB,OAAM;8BACxB,cAAA,KAACpB;wBAAOmC,SAAQ;wBAAWC,OAAM;wBAAYC,SAAS,IAAM9B,cAAcK;kCAAQ;;;;;;AAO5F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FlameChartPanel.d.ts","sourceRoot":"","sources":["../../../src/components/FlameChartPanel.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAE,EAAE,
|
|
1
|
+
{"version":3,"file":"FlameChartPanel.d.ts","sourceRoot":"","sources":["../../../src/components/FlameChartPanel.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAE,EAAE,EAAgC,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,WAAW,EAAc,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAUzD,MAAM,MAAM,oBAAoB,GAAG,UAAU,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC;AAE9E,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CA+JpD,CAAC"}
|
|
@@ -13,12 +13,13 @@
|
|
|
13
13
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
14
|
import { useChartsTheme } from '@perses-dev/components';
|
|
15
15
|
import { Stack, Typography, useMediaQuery, useTheme } from '@mui/material';
|
|
16
|
-
import { useState, useEffect } from 'react';
|
|
16
|
+
import { useState, useEffect, useMemo } from 'react';
|
|
17
|
+
import { filterStackTraceById, getMaxDepth } from '../utils/data-transform';
|
|
17
18
|
import { FlameChart } from './FlameChart';
|
|
18
19
|
import { Settings } from './Settings';
|
|
19
20
|
import { TableChart } from './TableChart';
|
|
20
21
|
import { SeriesChart } from './SeriesChart';
|
|
21
|
-
const
|
|
22
|
+
const LARGE_PANEL_THRESHOLD = 600;
|
|
22
23
|
const DEFAULT_SERIES_CHART_HEIGHT = 200;
|
|
23
24
|
export const FlameChartPanel = (props)=>{
|
|
24
25
|
const { contentDimensions, queryResults, spec } = props;
|
|
@@ -38,8 +39,22 @@ export const FlameChartPanel = (props)=>{
|
|
|
38
39
|
spec
|
|
39
40
|
]);
|
|
40
41
|
const chartsTheme = useChartsTheme();
|
|
41
|
-
const flameChartData =
|
|
42
|
-
|
|
42
|
+
const flameChartData = useMemo(()=>{
|
|
43
|
+
return queryResults[0];
|
|
44
|
+
}, [
|
|
45
|
+
queryResults
|
|
46
|
+
]);
|
|
47
|
+
const selectedStackTrace = useMemo(()=>{
|
|
48
|
+
if (!flameChartData) return undefined;
|
|
49
|
+
if (!selectedId) return flameChartData.data.profile.stackTrace;
|
|
50
|
+
return filterStackTraceById(flameChartData.data.profile.stackTrace, selectedId);
|
|
51
|
+
}, [
|
|
52
|
+
flameChartData,
|
|
53
|
+
selectedId
|
|
54
|
+
]);
|
|
55
|
+
const maxDepth = useMemo(()=>selectedStackTrace ? getMaxDepth(selectedStackTrace) : 0, [
|
|
56
|
+
selectedStackTrace
|
|
57
|
+
]);
|
|
43
58
|
const noDataTextStyle = chartsTheme.noDataOption.title.textStyle;
|
|
44
59
|
const onChangePalette = (newPalette)=>{
|
|
45
60
|
setLiveSpec((prev)=>{
|
|
@@ -65,12 +80,14 @@ export const FlameChartPanel = (props)=>{
|
|
|
65
80
|
};
|
|
66
81
|
});
|
|
67
82
|
};
|
|
83
|
+
if (!contentDimensions) return null;
|
|
68
84
|
const PADDING = liveSpec.showSeries && liveSpec.showSettings ? 32 : liveSpec.showSeries || liveSpec.showSettings ? 16 : 0;
|
|
69
85
|
const SETTINGS_HEIGHT = liveSpec.showSettings ? 30 : 0;
|
|
70
86
|
const SERIES_CHART_HEIGHT = liveSpec.showSeries ? contentDimensions.height < DEFAULT_SERIES_CHART_HEIGHT ? contentDimensions.height : DEFAULT_SERIES_CHART_HEIGHT : 0;
|
|
71
|
-
const TABLE_FLAME_CHART_HEIGHT = contentDimensions.height - (contentDimensions.height >
|
|
87
|
+
const TABLE_FLAME_CHART_HEIGHT = liveSpec.traceHeight ? Math.max(contentDimensions.height - (contentDimensions.height > LARGE_PANEL_THRESHOLD ? SERIES_CHART_HEIGHT + SETTINGS_HEIGHT + PADDING : 0), maxDepth * liveSpec.traceHeight) : contentDimensions.height - (contentDimensions.height > LARGE_PANEL_THRESHOLD ? SERIES_CHART_HEIGHT + SETTINGS_HEIGHT + PADDING : 0);
|
|
72
88
|
const TABLE_CHART_WIDTH = isMobileSize ? contentDimensions.width : liveSpec.showFlameGraph ? 0.4 * contentDimensions.width : contentDimensions.width;
|
|
73
89
|
const FLAME_CHART_WIDTH = isMobileSize ? contentDimensions.width : liveSpec.showTable ? 0.6 * contentDimensions.width : contentDimensions.width;
|
|
90
|
+
// TODO (gladorme): allow users to override height (useful for explorer for stack traces with high depth)
|
|
74
91
|
return /*#__PURE__*/ _jsx(Stack, {
|
|
75
92
|
height: contentDimensions.height,
|
|
76
93
|
width: contentDimensions.width,
|
|
@@ -87,7 +104,7 @@ export const FlameChartPanel = (props)=>{
|
|
|
87
104
|
sx: {
|
|
88
105
|
overflowY: 'auto',
|
|
89
106
|
scrollbarGutter: 'stable both-edges',
|
|
90
|
-
paddingTop: liveSpec.showSeries ?
|
|
107
|
+
paddingTop: liveSpec.showSettings || liveSpec.showSeries ? 1 : 0
|
|
91
108
|
},
|
|
92
109
|
children: [
|
|
93
110
|
liveSpec.showSeries && /*#__PURE__*/ _jsx(SeriesChart, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/FlameChartPanel.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { TitleComponentOption } from 'echarts';\nimport { useChartsTheme } from '@perses-dev/components';\nimport { Stack, Typography, SxProps, useMediaQuery, useTheme } from '@mui/material';\nimport { FC, useState, useEffect } from 'react';\nimport { ProfileData } from '@perses-dev/core';\nimport { PanelProps } from '@perses-dev/plugin-system';\nimport { FlameChartOptions } from '../flame-chart-model';\nimport { FlameChart } from './FlameChart';\nimport { Settings } from './Settings';\nimport { TableChart } from './TableChart';\nimport { SeriesChart } from './SeriesChart';\n\nconst LARGE_PANEL_TRESHOLD = 600;\nconst DEFAULT_SERIES_CHART_HEIGHT = 200;\n\nexport type FlameChartPanelProps = PanelProps<FlameChartOptions, ProfileData>;\n\nexport const FlameChartPanel: FC<FlameChartPanelProps> = (props) => {\n const { contentDimensions, queryResults, spec } = props;\n\n const isMobileSize = useMediaQuery(useTheme().breakpoints.down('sm'));\n\n // selectedId equals 0 => Flame Graph is not zoomed in\n // selectedId different from 0 => Flame Graph is zoomed in\n const [selectedId, setSelectedId] = useState(0);\n const [searchValue, setSearchValue] = useState('');\n\n // This spec is used to manage settings temporarily\n const [liveSpec, setLiveSpec] = useState<FlameChartOptions>(spec);\n\n // keep liveSpec up to date\n useEffect(() => {\n setLiveSpec(spec);\n setSelectedId(0);\n setSearchValue('');\n }, [spec]);\n\n const chartsTheme = useChartsTheme();\n const flameChartData = queryResults[0];\n\n if (contentDimensions === undefined) return null;\n\n const noDataTextStyle = (chartsTheme.noDataOption.title as TitleComponentOption).textStyle as SxProps;\n\n const onChangePalette = (newPalette: 'package-name' | 'value') => {\n setLiveSpec((prev) => {\n return { ...prev, palette: newPalette };\n });\n };\n\n const onDisplayChange = (value: 'table' | 'flame-graph' | 'both' | 'none') => {\n let showTable = true;\n let showFlameGraph = true;\n if (value === 'table') {\n showFlameGraph = false;\n } else if (value === 'flame-graph') {\n showTable = false;\n }\n setLiveSpec((prev) => {\n return { ...prev, showTable: showTable, showFlameGraph: showFlameGraph };\n });\n };\n\n const PADDING =\n liveSpec.showSeries && liveSpec.showSettings ? 32 : liveSpec.showSeries || liveSpec.showSettings ? 16 : 0;\n\n const SETTINGS_HEIGHT = liveSpec.showSettings ? 30 : 0;\n const SERIES_CHART_HEIGHT = liveSpec.showSeries\n ? contentDimensions.height < DEFAULT_SERIES_CHART_HEIGHT\n ? contentDimensions.height\n : DEFAULT_SERIES_CHART_HEIGHT\n : 0;\n const TABLE_FLAME_CHART_HEIGHT =\n contentDimensions.height -\n (contentDimensions.height > LARGE_PANEL_TRESHOLD ? SERIES_CHART_HEIGHT + SETTINGS_HEIGHT + PADDING : 0);\n\n const TABLE_CHART_WIDTH = isMobileSize\n ? contentDimensions.width\n : liveSpec.showFlameGraph\n ? 0.4 * contentDimensions.width\n : contentDimensions.width;\n\n const FLAME_CHART_WIDTH = isMobileSize\n ? contentDimensions.width\n : liveSpec.showTable\n ? 0.6 * contentDimensions.width\n : contentDimensions.width;\n\n return (\n <Stack\n height={contentDimensions.height}\n width={contentDimensions.width}\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n {queryResults.length > 1 ? (\n // display a message if there is more than one query\n <Typography sx={{ ...noDataTextStyle }}>\n There is more than one query. Please make sure that you provided only one query.\n </Typography>\n ) : flameChartData ? (\n <Stack\n gap={2}\n sx={{ overflowY: 'auto', scrollbarGutter: 'stable both-edges', paddingTop: liveSpec.showSeries ? 0 : 1 }}\n >\n {liveSpec.showSeries && (\n <SeriesChart width={contentDimensions.width} height={SERIES_CHART_HEIGHT} data={flameChartData.data} />\n )}\n {liveSpec.showSettings && (\n <Settings\n onSelectedIdChange={setSelectedId}\n onChangePalette={onChangePalette}\n onDisplayChange={onDisplayChange}\n value={liveSpec}\n selectedId={selectedId}\n />\n )}\n <Stack\n direction={isMobileSize ? 'column' : 'row'}\n justifyContent=\"center\"\n alignItems={isMobileSize ? 'center' : 'top'}\n >\n {liveSpec.showTable && (\n <TableChart\n width={TABLE_CHART_WIDTH}\n height={TABLE_FLAME_CHART_HEIGHT}\n data={flameChartData.data}\n searchValue={searchValue}\n onSearchValueChange={setSearchValue}\n onSelectedIdChange={setSelectedId}\n />\n )}\n {liveSpec.showFlameGraph && (\n <FlameChart\n width={FLAME_CHART_WIDTH}\n height={TABLE_FLAME_CHART_HEIGHT}\n data={flameChartData.data}\n palette={liveSpec.palette}\n selectedId={selectedId}\n searchValue={searchValue}\n onSelectedIdChange={setSelectedId}\n />\n )}\n </Stack>\n </Stack>\n ) : (\n <Typography sx={{ ...noDataTextStyle }}>No data</Typography>\n )}\n </Stack>\n );\n};\n"],"names":["useChartsTheme","Stack","Typography","useMediaQuery","useTheme","useState","useEffect","FlameChart","Settings","TableChart","SeriesChart","LARGE_PANEL_TRESHOLD","DEFAULT_SERIES_CHART_HEIGHT","FlameChartPanel","props","contentDimensions","queryResults","spec","isMobileSize","breakpoints","down","selectedId","setSelectedId","searchValue","setSearchValue","liveSpec","setLiveSpec","chartsTheme","flameChartData","undefined","noDataTextStyle","noDataOption","title","textStyle","onChangePalette","newPalette","prev","palette","onDisplayChange","value","showTable","showFlameGraph","PADDING","showSeries","showSettings","SETTINGS_HEIGHT","SERIES_CHART_HEIGHT","height","TABLE_FLAME_CHART_HEIGHT","TABLE_CHART_WIDTH","width","FLAME_CHART_WIDTH","justifyContent","alignItems","length","sx","gap","overflowY","scrollbarGutter","paddingTop","data","onSelectedIdChange","direction","onSearchValueChange"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/FlameChartPanel.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { TitleComponentOption } from 'echarts';\nimport { useChartsTheme } from '@perses-dev/components';\nimport { Stack, Typography, SxProps, useMediaQuery, useTheme } from '@mui/material';\nimport { FC, useState, useEffect, useMemo } from 'react';\nimport { ProfileData, StackTrace } from '@perses-dev/core';\nimport { PanelProps } from '@perses-dev/plugin-system';\nimport { FlameChartOptions } from '../flame-chart-model';\nimport { filterStackTraceById, getMaxDepth } from '../utils/data-transform';\nimport { FlameChart } from './FlameChart';\nimport { Settings } from './Settings';\nimport { TableChart } from './TableChart';\nimport { SeriesChart } from './SeriesChart';\n\nconst LARGE_PANEL_THRESHOLD = 600;\nconst DEFAULT_SERIES_CHART_HEIGHT = 200;\n\nexport type FlameChartPanelProps = PanelProps<FlameChartOptions, ProfileData>;\n\nexport const FlameChartPanel: FC<FlameChartPanelProps> = (props) => {\n const { contentDimensions, queryResults, spec } = props;\n\n const isMobileSize = useMediaQuery(useTheme().breakpoints.down('sm'));\n\n // selectedId equals 0 => Flame Graph is not zoomed in\n // selectedId different from 0 => Flame Graph is zoomed in\n const [selectedId, setSelectedId] = useState(0);\n const [searchValue, setSearchValue] = useState('');\n\n // This spec is used to manage settings temporarily\n const [liveSpec, setLiveSpec] = useState<FlameChartOptions>(spec);\n\n // keep liveSpec up to date\n useEffect(() => {\n setLiveSpec(spec);\n setSelectedId(0);\n setSearchValue('');\n }, [spec]);\n\n const chartsTheme = useChartsTheme();\n const flameChartData = useMemo(() => {\n return queryResults[0];\n }, [queryResults]);\n\n const selectedStackTrace: StackTrace | undefined = useMemo(() => {\n if (!flameChartData) return undefined;\n if (!selectedId) return flameChartData.data.profile.stackTrace;\n\n return filterStackTraceById(flameChartData.data.profile.stackTrace, selectedId);\n }, [flameChartData, selectedId]);\n\n const maxDepth: number = useMemo(\n () => (selectedStackTrace ? getMaxDepth(selectedStackTrace) : 0),\n [selectedStackTrace]\n );\n\n const noDataTextStyle = (chartsTheme.noDataOption.title as TitleComponentOption).textStyle as SxProps;\n\n const onChangePalette = (newPalette: 'package-name' | 'value') => {\n setLiveSpec((prev) => {\n return { ...prev, palette: newPalette };\n });\n };\n\n const onDisplayChange = (value: 'table' | 'flame-graph' | 'both' | 'none') => {\n let showTable = true;\n let showFlameGraph = true;\n if (value === 'table') {\n showFlameGraph = false;\n } else if (value === 'flame-graph') {\n showTable = false;\n }\n setLiveSpec((prev) => {\n return { ...prev, showTable: showTable, showFlameGraph: showFlameGraph };\n });\n };\n\n if (!contentDimensions) return null;\n\n const PADDING =\n liveSpec.showSeries && liveSpec.showSettings ? 32 : liveSpec.showSeries || liveSpec.showSettings ? 16 : 0;\n\n const SETTINGS_HEIGHT = liveSpec.showSettings ? 30 : 0;\n\n const SERIES_CHART_HEIGHT = liveSpec.showSeries\n ? contentDimensions.height < DEFAULT_SERIES_CHART_HEIGHT\n ? contentDimensions.height\n : DEFAULT_SERIES_CHART_HEIGHT\n : 0;\n\n const TABLE_FLAME_CHART_HEIGHT = liveSpec.traceHeight\n ? Math.max(\n contentDimensions.height -\n (contentDimensions.height > LARGE_PANEL_THRESHOLD ? SERIES_CHART_HEIGHT + SETTINGS_HEIGHT + PADDING : 0),\n maxDepth * liveSpec.traceHeight\n )\n : contentDimensions.height -\n (contentDimensions.height > LARGE_PANEL_THRESHOLD ? SERIES_CHART_HEIGHT + SETTINGS_HEIGHT + PADDING : 0);\n\n const TABLE_CHART_WIDTH = isMobileSize\n ? contentDimensions.width\n : liveSpec.showFlameGraph\n ? 0.4 * contentDimensions.width\n : contentDimensions.width;\n\n const FLAME_CHART_WIDTH = isMobileSize\n ? contentDimensions.width\n : liveSpec.showTable\n ? 0.6 * contentDimensions.width\n : contentDimensions.width;\n\n // TODO (gladorme): allow users to override height (useful for explorer for stack traces with high depth)\n return (\n <Stack\n height={contentDimensions.height}\n width={contentDimensions.width}\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n {queryResults.length > 1 ? (\n // display a message if there is more than one query\n <Typography sx={{ ...noDataTextStyle }}>\n There is more than one query. Please make sure that you provided only one query.\n </Typography>\n ) : flameChartData ? (\n <Stack\n gap={2}\n sx={{\n overflowY: 'auto',\n scrollbarGutter: 'stable both-edges',\n paddingTop: liveSpec.showSettings || liveSpec.showSeries ? 1 : 0,\n }}\n >\n {liveSpec.showSeries && (\n <SeriesChart width={contentDimensions.width} height={SERIES_CHART_HEIGHT} data={flameChartData.data} />\n )}\n {liveSpec.showSettings && (\n <Settings\n onSelectedIdChange={setSelectedId}\n onChangePalette={onChangePalette}\n onDisplayChange={onDisplayChange}\n value={liveSpec}\n selectedId={selectedId}\n />\n )}\n <Stack\n direction={isMobileSize ? 'column' : 'row'}\n justifyContent=\"center\"\n alignItems={isMobileSize ? 'center' : 'top'}\n >\n {liveSpec.showTable && (\n <TableChart\n width={TABLE_CHART_WIDTH}\n height={TABLE_FLAME_CHART_HEIGHT}\n data={flameChartData.data}\n searchValue={searchValue}\n onSearchValueChange={setSearchValue}\n onSelectedIdChange={setSelectedId}\n />\n )}\n {liveSpec.showFlameGraph && (\n <FlameChart\n width={FLAME_CHART_WIDTH}\n height={TABLE_FLAME_CHART_HEIGHT}\n data={flameChartData.data}\n palette={liveSpec.palette}\n selectedId={selectedId}\n searchValue={searchValue}\n onSelectedIdChange={setSelectedId}\n />\n )}\n </Stack>\n </Stack>\n ) : (\n <Typography sx={{ ...noDataTextStyle }}>No data</Typography>\n )}\n </Stack>\n );\n};\n"],"names":["useChartsTheme","Stack","Typography","useMediaQuery","useTheme","useState","useEffect","useMemo","filterStackTraceById","getMaxDepth","FlameChart","Settings","TableChart","SeriesChart","LARGE_PANEL_THRESHOLD","DEFAULT_SERIES_CHART_HEIGHT","FlameChartPanel","props","contentDimensions","queryResults","spec","isMobileSize","breakpoints","down","selectedId","setSelectedId","searchValue","setSearchValue","liveSpec","setLiveSpec","chartsTheme","flameChartData","selectedStackTrace","undefined","data","profile","stackTrace","maxDepth","noDataTextStyle","noDataOption","title","textStyle","onChangePalette","newPalette","prev","palette","onDisplayChange","value","showTable","showFlameGraph","PADDING","showSeries","showSettings","SETTINGS_HEIGHT","SERIES_CHART_HEIGHT","height","TABLE_FLAME_CHART_HEIGHT","traceHeight","Math","max","TABLE_CHART_WIDTH","width","FLAME_CHART_WIDTH","justifyContent","alignItems","length","sx","gap","overflowY","scrollbarGutter","paddingTop","onSelectedIdChange","direction","onSearchValueChange"],"mappings":"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"}
|
|
@@ -12,6 +12,7 @@ export interface FlameChartOptions {
|
|
|
12
12
|
showSeries: boolean;
|
|
13
13
|
showTable: boolean;
|
|
14
14
|
showFlameGraph: boolean;
|
|
15
|
+
traceHeight?: number;
|
|
15
16
|
}
|
|
16
17
|
export type FlameChartOptionsEditorProps = OptionsEditorProps<FlameChartOptions>;
|
|
17
18
|
export declare function createInitialFlameChartOptions(): FlameChartOptions;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flame-chart-model.d.ts","sourceRoot":"","sources":["../../src/flame-chart-model.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,UAAU,CAAC,iBAAiB,CAAC;IACzE,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC;IAClC,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"flame-chart-model.d.ts","sourceRoot":"","sources":["../../src/flame-chart-model.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,UAAU,CAAC,iBAAiB,CAAC;IACzE,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC;IAClC,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,4BAA4B,GAAG,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;AAEjF,wBAAgB,8BAA8B,IAAI,iBAAiB,CAQlE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/flame-chart-model.ts"],"sourcesContent":["// Copyright 2025 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Definition } from '@perses-dev/core';\nimport { OptionsEditorProps } from '@perses-dev/plugin-system';\n\n/**\n * The schema for a FlameChart panel.\n */\nexport interface FlameChartDefinition extends Definition<FlameChartOptions> {\n kind: 'FlameChart';\n}\n\nexport interface FlameChartOptions {\n palette: 'package-name' | 'value';\n showSettings: boolean;\n showSeries: boolean;\n showTable: boolean;\n showFlameGraph: boolean;\n}\n\nexport type FlameChartOptionsEditorProps = OptionsEditorProps<FlameChartOptions>;\n\nexport function createInitialFlameChartOptions(): FlameChartOptions {\n return {\n palette: 'package-name',\n showSettings: true,\n showSeries: false,\n showTable: true,\n showFlameGraph: true,\n };\n}\n"],"names":["createInitialFlameChartOptions","palette","showSettings","showSeries","showTable","showFlameGraph"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;
|
|
1
|
+
{"version":3,"sources":["../../src/flame-chart-model.ts"],"sourcesContent":["// Copyright 2025 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Definition } from '@perses-dev/core';\nimport { OptionsEditorProps } from '@perses-dev/plugin-system';\n\n/**\n * The schema for a FlameChart panel.\n */\nexport interface FlameChartDefinition extends Definition<FlameChartOptions> {\n kind: 'FlameChart';\n}\n\nexport interface FlameChartOptions {\n palette: 'package-name' | 'value';\n showSettings: boolean;\n showSeries: boolean;\n showTable: boolean;\n showFlameGraph: boolean;\n traceHeight?: number;\n}\n\nexport type FlameChartOptionsEditorProps = OptionsEditorProps<FlameChartOptions>;\n\nexport function createInitialFlameChartOptions(): FlameChartOptions {\n return {\n palette: 'package-name',\n showSettings: true,\n showSeries: false,\n showTable: true,\n showFlameGraph: true,\n };\n}\n"],"names":["createInitialFlameChartOptions","palette","showSettings","showSeries","showTable","showFlameGraph"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAuBjC,OAAO,SAASA;IACd,OAAO;QACLC,SAAS;QACTC,cAAc;QACdC,YAAY;QACZC,WAAW;QACXC,gBAAgB;IAClB;AACF"}
|
|
@@ -3,11 +3,11 @@ import { FlameChartSample as Sample, TableChartSample } from './data-model';
|
|
|
3
3
|
/**
|
|
4
4
|
* Filter the global stacktrace by a function ID to focus on that function and display its corresponding flame chart
|
|
5
5
|
*/
|
|
6
|
-
export declare function
|
|
6
|
+
export declare function filterStackTraceById(trace: StackTrace, id: number | undefined): StackTrace;
|
|
7
7
|
/**
|
|
8
8
|
* Build series data for the flame chart option
|
|
9
9
|
*/
|
|
10
|
-
export declare function
|
|
10
|
+
export declare function buildSamples(palette: string, metadata: ProfileMetaData | undefined, traces: StackTrace, searchValue: string, id?: number): Sample[];
|
|
11
11
|
/**
|
|
12
12
|
* Transform query results to a tabular format for the table chart
|
|
13
13
|
*/
|
|
@@ -16,4 +16,5 @@ export declare function tableRecursionJson(jsonObj: StackTrace, searchValue: str
|
|
|
16
16
|
* Finds the total sample value of the series data item with the specified name.
|
|
17
17
|
*/
|
|
18
18
|
export declare function findTotalSampleByName(seriesData: Sample[], name: number | undefined): number | undefined;
|
|
19
|
+
export declare function getMaxDepth(trace: StackTrace): number;
|
|
19
20
|
//# sourceMappingURL=data-transform.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-transform.d.ts","sourceRoot":"","sources":["../../../src/utils/data-transform.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,IAAI,MAAM,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAI5E;;GAEG;AACH,wBAAgB,
|
|
1
|
+
{"version":3,"file":"data-transform.d.ts","sourceRoot":"","sources":["../../../src/utils/data-transform.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,IAAI,MAAM,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAI5E;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CA2B1F;AA8BD;;GAEG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,eAAe,GAAG,SAAS,EACrC,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE,MAAM,EACnB,EAAE,CAAC,EAAE,MAAM,GACV,MAAM,EAAE,CAqCV;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAsB/F;AAmBD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAKxG;AAKD,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAKrD"}
|
|
@@ -14,30 +14,32 @@ import { getSpanColor } from './palette-gen';
|
|
|
14
14
|
import { formatItemValue } from './format';
|
|
15
15
|
/**
|
|
16
16
|
* Filter the global stacktrace by a function ID to focus on that function and display its corresponding flame chart
|
|
17
|
-
*/ export function
|
|
18
|
-
if (id ===
|
|
19
|
-
return
|
|
17
|
+
*/ export function filterStackTraceById(trace, id) {
|
|
18
|
+
if (id === undefined) {
|
|
19
|
+
return trace;
|
|
20
20
|
}
|
|
21
|
-
const recur = (
|
|
22
|
-
if (
|
|
23
|
-
return
|
|
21
|
+
const recur = (trace, id)=>{
|
|
22
|
+
if (trace.id === id) {
|
|
23
|
+
return trace;
|
|
24
24
|
}
|
|
25
|
-
for (const child of
|
|
25
|
+
for (const child of trace.children ?? []){
|
|
26
26
|
const temp = recur(child, id);
|
|
27
27
|
if (temp) {
|
|
28
|
-
|
|
28
|
+
trace = {
|
|
29
|
+
...trace
|
|
30
|
+
}; // Create a shallow copy of the trace to avoid mutating the original object
|
|
31
|
+
// Override parents' values
|
|
32
|
+
trace.children = [
|
|
29
33
|
temp
|
|
30
34
|
];
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
// item.self = temp.self;
|
|
35
|
-
// item.total = temp.total;
|
|
36
|
-
return item;
|
|
35
|
+
trace.start = temp.start;
|
|
36
|
+
trace.end = temp.end;
|
|
37
|
+
return trace;
|
|
37
38
|
}
|
|
38
39
|
}
|
|
40
|
+
return undefined;
|
|
39
41
|
};
|
|
40
|
-
return recur(
|
|
42
|
+
return recur(trace, id) ?? trace;
|
|
41
43
|
}
|
|
42
44
|
// build the name of the corresponding flamechart item
|
|
43
45
|
function formatName(item, rootVal, unit) {
|
|
@@ -63,9 +65,9 @@ function formatName(item, rootVal, unit) {
|
|
|
63
65
|
}
|
|
64
66
|
/**
|
|
65
67
|
* Build series data for the flame chart option
|
|
66
|
-
*/ export function
|
|
68
|
+
*/ export function buildSamples(palette, metadata, traces, searchValue, id) {
|
|
67
69
|
const data = [];
|
|
68
|
-
const filteredJson =
|
|
70
|
+
const filteredJson = filterStackTraceById(traces, id);
|
|
69
71
|
const rootVal = filteredJson.total; // total samples of root node
|
|
70
72
|
const currentVal = getCurrentTotalValue(filteredJson, id); // total samples of the selected item, used to generate items colors
|
|
71
73
|
const recur = (item)=>{
|
|
@@ -134,5 +136,13 @@ function isItemNameMatchesSearchFilters(itemName, searchValue) {
|
|
|
134
136
|
const totalSample = item?.value[8];
|
|
135
137
|
return Number(totalSample);
|
|
136
138
|
}
|
|
139
|
+
/*
|
|
140
|
+
* Calculate the maximum depth of the stack trace
|
|
141
|
+
*/ export function getMaxDepth(trace) {
|
|
142
|
+
if (!trace.children?.length) {
|
|
143
|
+
return 1;
|
|
144
|
+
}
|
|
145
|
+
return 1 + Math.max(...trace.children.map(getMaxDepth));
|
|
146
|
+
}
|
|
137
147
|
|
|
138
148
|
//# sourceMappingURL=data-transform.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/data-transform.ts"],"sourcesContent":["// Copyright 2025 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ProfileMetaData, StackTrace } from '@perses-dev/core';\nimport { FlameChartSample as Sample, TableChartSample } from './data-model';\nimport { getSpanColor } from './palette-gen';\nimport { formatItemValue } from './format';\n\n/**\n * Filter the global stacktrace by a function ID to focus on that function and display its corresponding flame chart\n */\nexport function
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/data-transform.ts"],"sourcesContent":["// Copyright 2025 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ProfileMetaData, StackTrace } from '@perses-dev/core';\nimport { FlameChartSample as Sample, TableChartSample } from './data-model';\nimport { getSpanColor } from './palette-gen';\nimport { formatItemValue } from './format';\n\n/**\n * Filter the global stacktrace by a function ID to focus on that function and display its corresponding flame chart\n */\nexport function filterStackTraceById(trace: StackTrace, id: number | undefined): StackTrace {\n if (id === undefined) {\n return trace;\n }\n\n const recur = (trace: StackTrace, id: number | undefined): StackTrace | undefined => {\n if (trace.id === id) {\n return trace;\n }\n\n for (const child of trace.children ?? []) {\n const temp = recur(child, id);\n if (temp) {\n trace = { ...trace }; // Create a shallow copy of the trace to avoid mutating the original object\n // Override parents' values\n trace.children = [temp];\n trace.start = temp.start;\n trace.end = temp.end;\n\n return trace;\n }\n }\n\n return undefined;\n };\n\n return recur(trace, id) ?? trace;\n}\n\n// build the name of the corresponding flamechart item\nfunction formatName(item: StackTrace, rootVal: number, unit: string | undefined): string {\n return (item.total / rootVal) * 100 < 1 ? '' : item.name + ` (${formatItemValue(unit, item.total)})`;\n}\n\n/**\n * Search the total value of an item corresponding to a given ID\n */\nfunction getCurrentTotalValue(json: StackTrace, id: number | undefined): number {\n if (id === undefined) return 0;\n\n const recur = (item: StackTrace): number => {\n if (item.id === id) {\n return item.total;\n }\n\n for (const child of item.children || []) {\n const total = recur(child);\n if (total !== undefined) {\n return total;\n }\n }\n return 0; // If not found, return 0\n };\n\n return recur(json);\n}\n\n/**\n * Build series data for the flame chart option\n */\nexport function buildSamples(\n palette: string,\n metadata: ProfileMetaData | undefined,\n traces: StackTrace,\n searchValue: string,\n id?: number\n): Sample[] {\n const data: Sample[] = [];\n const filteredJson = filterStackTraceById(traces, id);\n\n const rootVal = filteredJson.total; // total samples of root node\n const currentVal = getCurrentTotalValue(filteredJson, id); // total samples of the selected item, used to generate items colors\n\n const recur = (item: StackTrace): void => {\n const temp = {\n name: item.id,\n value: [\n item.level,\n item.start,\n item.end,\n formatName(item, currentVal ? currentVal : rootVal, metadata?.units),\n (item.total / rootVal) * 100,\n (item.self / rootVal) * 100,\n item.name,\n item.self,\n item.total,\n ],\n itemStyle: {\n color: !isItemNameMatchesSearchFilters(item.name, searchValue)\n ? '#dee2e6'\n : getSpanColor(palette, item.name, (item.total / (currentVal ? currentVal : rootVal)) * 100),\n },\n };\n data.push(temp as Sample);\n\n for (const child of item.children || []) {\n recur(child);\n }\n };\n\n // check is filteredJson is not empty before call recur\n if (filteredJson.id) recur(filteredJson);\n return data;\n}\n\n/**\n * Transform query results to a tabular format for the table chart\n */\nexport function tableRecursionJson(jsonObj: StackTrace, searchValue: string): TableChartSample[] {\n const data: TableChartSample[] = [];\n const structuredJson = structuredClone(jsonObj);\n\n const recur = (item: StackTrace): void => {\n const temp = {\n id: item.id,\n name: item.name,\n self: item.self,\n total: item.total,\n };\n\n if (isItemNameMatchesSearchFilters(temp.name, searchValue)) data.push(temp as TableChartSample);\n\n for (const child of item.children || []) {\n recur(child);\n }\n };\n\n // check is structuredJson is not empty before call recur\n if (structuredJson.id) recur(structuredJson);\n return data;\n}\n\n// Checks if an item name matches all parts of a search value.\nfunction isItemNameMatchesSearchFilters(itemName: string, searchValue: string): boolean {\n if (searchValue === '') return true;\n\n const filters = searchValue\n .trim()\n .toLocaleLowerCase()\n .split(/[^a-zA-Z0-9']+/)\n .filter((s) => s !== '');\n\n if (filters.length === 0) {\n return false;\n } else {\n return filters.every((filter) => itemName.toLowerCase().includes(filter.trim()));\n }\n}\n\n/**\n * Finds the total sample value of the series data item with the specified name.\n */\nexport function findTotalSampleByName(seriesData: Sample[], name: number | undefined): number | undefined {\n if (name === undefined || name === 0) return undefined;\n const item = seriesData.find((item) => item.name === name);\n const totalSample = item?.value[8];\n return Number(totalSample);\n}\n\n/*\n * Calculate the maximum depth of the stack trace\n */\nexport function getMaxDepth(trace: StackTrace): number {\n if (!trace.children?.length) {\n return 1;\n }\n return 1 + Math.max(...trace.children.map(getMaxDepth));\n}\n"],"names":["getSpanColor","formatItemValue","filterStackTraceById","trace","id","undefined","recur","child","children","temp","start","end","formatName","item","rootVal","unit","total","name","getCurrentTotalValue","json","buildSamples","palette","metadata","traces","searchValue","data","filteredJson","currentVal","value","level","units","self","itemStyle","color","isItemNameMatchesSearchFilters","push","tableRecursionJson","jsonObj","structuredJson","structuredClone","itemName","filters","trim","toLocaleLowerCase","split","filter","s","length","every","toLowerCase","includes","findTotalSampleByName","seriesData","find","totalSample","Number","getMaxDepth","Math","max","map"],"mappings":"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"}
|
package/lib/utils/utils.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ChangeEventHandler } from 'react';
|
|
1
2
|
import { FlameChartOptionsEditorProps } from '../flame-chart-model';
|
|
2
3
|
/**
|
|
3
4
|
* Hook to manage `palette` state.
|
|
@@ -5,6 +6,12 @@ import { FlameChartOptionsEditorProps } from '../flame-chart-model';
|
|
|
5
6
|
export declare function usePaletteState(props: FlameChartOptionsEditorProps): {
|
|
6
7
|
handlePaletteChange: (newPalette: 'package-name' | 'value') => void;
|
|
7
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* Hook to manage `traceHeight` state.
|
|
11
|
+
*/
|
|
12
|
+
export declare function useTraceHeightState(props: FlameChartOptionsEditorProps): {
|
|
13
|
+
handleTraceHeightChange: ChangeEventHandler<HTMLInputElement>;
|
|
14
|
+
};
|
|
8
15
|
/**
|
|
9
16
|
* Hook to manage `showSettings` state.
|
|
10
17
|
*/
|
package/lib/utils/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/utils/utils.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AAEpE;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,4BAA4B,GAAG;IACpE,mBAAmB,EAAE,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO,KAAK,IAAI,CAAC;CACrE,CAYA;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,4BAA4B,GAAG;IACzE,wBAAwB,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CACvD,CAYA;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,4BAA4B,GAAG;IACvE,sBAAsB,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CACrD,CAYA;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,4BAA4B,GAAG;IACtE,qBAAqB,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CACpD,CAYA;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,4BAA4B,GAAG;IAC3E,0BAA0B,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CACzD,CAYA;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,4BAA4B,GAAG,IAAI,CAYvE"}
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/utils/utils.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AAEpE;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,4BAA4B,GAAG;IACpE,mBAAmB,EAAE,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO,KAAK,IAAI,CAAC;CACrE,CAYA;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,4BAA4B,GAAG;IACxE,uBAAuB,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;CAC/D,CAYA;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,4BAA4B,GAAG;IACzE,wBAAwB,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CACvD,CAYA;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,4BAA4B,GAAG;IACvE,sBAAsB,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CACrD,CAYA;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,4BAA4B,GAAG;IACtE,qBAAqB,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CACpD,CAYA;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,4BAA4B,GAAG;IAC3E,0BAA0B,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CACzD,CAYA;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,4BAA4B,GAAG,IAAI,CAYvE"}
|
package/lib/utils/utils.js
CHANGED
|
@@ -24,6 +24,19 @@ import { produce } from 'immer';
|
|
|
24
24
|
handlePaletteChange
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Hook to manage `traceHeight` state.
|
|
29
|
+
*/ export function useTraceHeightState(props) {
|
|
30
|
+
const { onChange, value } = props;
|
|
31
|
+
const handleTraceHeightChange = (event)=>{
|
|
32
|
+
onChange(produce(value, (draft)=>{
|
|
33
|
+
draft.traceHeight = event.target.value ? Number(event.target.value) : undefined;
|
|
34
|
+
}));
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
handleTraceHeightChange
|
|
38
|
+
};
|
|
39
|
+
}
|
|
27
40
|
/**
|
|
28
41
|
* Hook to manage `showSettings` state.
|
|
29
42
|
*/ export function useShowSettingsState(props) {
|
package/lib/utils/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/utils.ts"],"sourcesContent":["// Copyright 2025 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { produce } from 'immer';\nimport { FlameChartOptionsEditorProps } from '../flame-chart-model';\n\n/**\n * Hook to manage `palette` state.\n */\nexport function usePaletteState(props: FlameChartOptionsEditorProps): {\n handlePaletteChange: (newPalette: 'package-name' | 'value') => void;\n} {\n const { onChange, value } = props;\n\n const handlePaletteChange = (newPalette: 'package-name' | 'value'): void => {\n onChange(\n produce(value, (draft) => {\n draft.palette = newPalette;\n })\n );\n };\n\n return { handlePaletteChange };\n}\n\n/**\n * Hook to manage `showSettings` state.\n */\nexport function useShowSettingsState(props: FlameChartOptionsEditorProps): {\n handleShowSettingsChange: (newValue: boolean) => void;\n} {\n const { onChange, value } = props;\n\n const handleShowSettingsChange = (newValue: boolean): void => {\n onChange(\n produce(value, (draft) => {\n draft.showSettings = newValue;\n })\n );\n };\n\n return { handleShowSettingsChange };\n}\n\n/**\n * Hook to manage `showSeries` state.\n */\nexport function useShowSeriesState(props: FlameChartOptionsEditorProps): {\n handleShowSeriesChange: (newValue: boolean) => void;\n} {\n const { onChange, value } = props;\n\n const handleShowSeriesChange = (newValue: boolean): void => {\n onChange(\n produce(value, (draft) => {\n draft.showSeries = newValue;\n })\n );\n };\n\n return { handleShowSeriesChange };\n}\n\n/**\n * Hook to manage `showTable` state.\n */\nexport function useShowTableState(props: FlameChartOptionsEditorProps): {\n handleShowTableChange: (newValue: boolean) => void;\n} {\n const { onChange, value } = props;\n\n const handleShowTableChange = (newValue: boolean): void => {\n onChange(\n produce(value, (draft) => {\n draft.showTable = newValue;\n })\n );\n };\n\n return { handleShowTableChange };\n}\n\n/**\n * Hook to manage `showFlameGraph` state.\n */\nexport function useShowFlameGraphState(props: FlameChartOptionsEditorProps): {\n handleShowFlameGraphChange: (newValue: boolean) => void;\n} {\n const { onChange, value } = props;\n\n const handleShowFlameGraphChange = (newValue: boolean): void => {\n onChange(\n produce(value, (draft) => {\n draft.showFlameGraph = newValue;\n })\n );\n };\n\n return { handleShowFlameGraphChange };\n}\n\n/**\n * Reset all settings to their initial values\n */\nexport function resetSettings(props: FlameChartOptionsEditorProps): void {\n const { onChange, value } = props;\n\n onChange(\n produce(value, (draft) => {\n draft.palette = 'package-name';\n draft.showSettings = true;\n draft.showSeries = false;\n draft.showTable = true;\n draft.showFlameGraph = true;\n })\n );\n}\n"],"names":["produce","usePaletteState","props","onChange","value","handlePaletteChange","newPalette","draft","palette","useShowSettingsState","handleShowSettingsChange","newValue","showSettings","useShowSeriesState","handleShowSeriesChange","showSeries","useShowTableState","handleShowTableChange","showTable","useShowFlameGraphState","handleShowFlameGraphChange","showFlameGraph","resetSettings"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,OAAO,QAAQ,QAAQ;
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/utils.ts"],"sourcesContent":["// Copyright 2025 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { produce } from 'immer';\nimport { ChangeEventHandler } from 'react';\nimport { FlameChartOptionsEditorProps } from '../flame-chart-model';\n\n/**\n * Hook to manage `palette` state.\n */\nexport function usePaletteState(props: FlameChartOptionsEditorProps): {\n handlePaletteChange: (newPalette: 'package-name' | 'value') => void;\n} {\n const { onChange, value } = props;\n\n const handlePaletteChange = (newPalette: 'package-name' | 'value'): void => {\n onChange(\n produce(value, (draft) => {\n draft.palette = newPalette;\n })\n );\n };\n\n return { handlePaletteChange };\n}\n\n/**\n * Hook to manage `traceHeight` state.\n */\nexport function useTraceHeightState(props: FlameChartOptionsEditorProps): {\n handleTraceHeightChange: ChangeEventHandler<HTMLInputElement>;\n} {\n const { onChange, value } = props;\n\n const handleTraceHeightChange: ChangeEventHandler<HTMLInputElement> = (event): void => {\n onChange(\n produce(value, (draft) => {\n draft.traceHeight = event.target.value ? Number(event.target.value) : undefined;\n })\n );\n };\n\n return { handleTraceHeightChange };\n}\n\n/**\n * Hook to manage `showSettings` state.\n */\nexport function useShowSettingsState(props: FlameChartOptionsEditorProps): {\n handleShowSettingsChange: (newValue: boolean) => void;\n} {\n const { onChange, value } = props;\n\n const handleShowSettingsChange = (newValue: boolean): void => {\n onChange(\n produce(value, (draft) => {\n draft.showSettings = newValue;\n })\n );\n };\n\n return { handleShowSettingsChange };\n}\n\n/**\n * Hook to manage `showSeries` state.\n */\nexport function useShowSeriesState(props: FlameChartOptionsEditorProps): {\n handleShowSeriesChange: (newValue: boolean) => void;\n} {\n const { onChange, value } = props;\n\n const handleShowSeriesChange = (newValue: boolean): void => {\n onChange(\n produce(value, (draft) => {\n draft.showSeries = newValue;\n })\n );\n };\n\n return { handleShowSeriesChange };\n}\n\n/**\n * Hook to manage `showTable` state.\n */\nexport function useShowTableState(props: FlameChartOptionsEditorProps): {\n handleShowTableChange: (newValue: boolean) => void;\n} {\n const { onChange, value } = props;\n\n const handleShowTableChange = (newValue: boolean): void => {\n onChange(\n produce(value, (draft) => {\n draft.showTable = newValue;\n })\n );\n };\n\n return { handleShowTableChange };\n}\n\n/**\n * Hook to manage `showFlameGraph` state.\n */\nexport function useShowFlameGraphState(props: FlameChartOptionsEditorProps): {\n handleShowFlameGraphChange: (newValue: boolean) => void;\n} {\n const { onChange, value } = props;\n\n const handleShowFlameGraphChange = (newValue: boolean): void => {\n onChange(\n produce(value, (draft) => {\n draft.showFlameGraph = newValue;\n })\n );\n };\n\n return { handleShowFlameGraphChange };\n}\n\n/**\n * Reset all settings to their initial values\n */\nexport function resetSettings(props: FlameChartOptionsEditorProps): void {\n const { onChange, value } = props;\n\n onChange(\n produce(value, (draft) => {\n draft.palette = 'package-name';\n draft.showSettings = true;\n draft.showSeries = false;\n draft.showTable = true;\n draft.showFlameGraph = true;\n })\n );\n}\n"],"names":["produce","usePaletteState","props","onChange","value","handlePaletteChange","newPalette","draft","palette","useTraceHeightState","handleTraceHeightChange","event","traceHeight","target","Number","undefined","useShowSettingsState","handleShowSettingsChange","newValue","showSettings","useShowSeriesState","handleShowSeriesChange","showSeries","useShowTableState","handleShowTableChange","showTable","useShowFlameGraphState","handleShowFlameGraphChange","showFlameGraph","resetSettings"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,OAAO,QAAQ,QAAQ;AAIhC;;CAEC,GACD,OAAO,SAASC,gBAAgBC,KAAmC;IAGjE,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAE,GAAGF;IAE5B,MAAMG,sBAAsB,CAACC;QAC3BH,SACEH,QAAQI,OAAO,CAACG;YACdA,MAAMC,OAAO,GAAGF;QAClB;IAEJ;IAEA,OAAO;QAAED;IAAoB;AAC/B;AAEA;;CAEC,GACD,OAAO,SAASI,oBAAoBP,KAAmC;IAGrE,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAE,GAAGF;IAE5B,MAAMQ,0BAAgE,CAACC;QACrER,SACEH,QAAQI,OAAO,CAACG;YACdA,MAAMK,WAAW,GAAGD,MAAME,MAAM,CAACT,KAAK,GAAGU,OAAOH,MAAME,MAAM,CAACT,KAAK,IAAIW;QACxE;IAEJ;IAEA,OAAO;QAAEL;IAAwB;AACnC;AAEA;;CAEC,GACD,OAAO,SAASM,qBAAqBd,KAAmC;IAGtE,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAE,GAAGF;IAE5B,MAAMe,2BAA2B,CAACC;QAChCf,SACEH,QAAQI,OAAO,CAACG;YACdA,MAAMY,YAAY,GAAGD;QACvB;IAEJ;IAEA,OAAO;QAAED;IAAyB;AACpC;AAEA;;CAEC,GACD,OAAO,SAASG,mBAAmBlB,KAAmC;IAGpE,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAE,GAAGF;IAE5B,MAAMmB,yBAAyB,CAACH;QAC9Bf,SACEH,QAAQI,OAAO,CAACG;YACdA,MAAMe,UAAU,GAAGJ;QACrB;IAEJ;IAEA,OAAO;QAAEG;IAAuB;AAClC;AAEA;;CAEC,GACD,OAAO,SAASE,kBAAkBrB,KAAmC;IAGnE,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAE,GAAGF;IAE5B,MAAMsB,wBAAwB,CAACN;QAC7Bf,SACEH,QAAQI,OAAO,CAACG;YACdA,MAAMkB,SAAS,GAAGP;QACpB;IAEJ;IAEA,OAAO;QAAEM;IAAsB;AACjC;AAEA;;CAEC,GACD,OAAO,SAASE,uBAAuBxB,KAAmC;IAGxE,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAE,GAAGF;IAE5B,MAAMyB,6BAA6B,CAACT;QAClCf,SACEH,QAAQI,OAAO,CAACG;YACdA,MAAMqB,cAAc,GAAGV;QACzB;IAEJ;IAEA,OAAO;QAAES;IAA2B;AACtC;AAEA;;CAEC,GACD,OAAO,SAASE,cAAc3B,KAAmC;IAC/D,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAE,GAAGF;IAE5BC,SACEH,QAAQI,OAAO,CAACG;QACdA,MAAMC,OAAO,GAAG;QAChBD,MAAMY,YAAY,GAAG;QACrBZ,MAAMe,UAAU,GAAG;QACnBf,MAAMkB,SAAS,GAAG;QAClBlB,MAAMqB,cAAc,GAAG;IACzB;AAEJ"}
|