{"version":3,"file":"FlameGraphTopTableContainer.cjs","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  type DataFrame,\n  type DataLinkClickEvent,\n  type Field,\n  FieldType,\n  type GrafanaTheme2,\n  MappingType,\n  escapeStringForRegex,\n} from '@grafana/data';\nimport {\n  IconButton,\n  Table,\n  TableCellDisplayMode,\n  type TableCustomCellOptions,\n  type TableFieldOptions,\n  type TableSortByFieldState,\n  useStyles2,\n  useTheme2,\n} from '@grafana/ui';\n\nimport { diffColorBlindColors, diffDefaultColors } from '../FlameGraph/colors';\nimport { type FlameGraphDataContainer } from '../FlameGraph/dataTransform';\nimport { TOP_TABLE_COLUMN_WIDTH } from '../constants';\nimport { type ColorScheme, ColorSchemeDiff, type 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(() => buildFilteredTable(data, matchedLabels), [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 buildFilteredTable(data: FlameGraphDataContainer, matchedLabels?: Set<string>) {\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 } = Object.create(null);\n\n  // Track call stack to detect recursive calls\n  const callStack: string[] = [];\n\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    const level = data.getLevel(i);\n\n    // Maintain call stack based on level changes\n    while (callStack.length > level) {\n      callStack.pop();\n    }\n\n    // Check if this is a recursive call (same label already in call stack)\n    const isRecursive = callStack.some((entry) => entry === label);\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\n      // Only add to total if this is not a recursive call\n      if (!isRecursive) {\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\n    // Add current call to the stack\n    callStack.push(label);\n  }\n\n  return filteredTable;\n}\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 === `^${escapeStringForRegex(String(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 { buildFilteredTable };\n\nexport default FlameGraphTopTableContainer;\n"],"names":["memo","useMemo","useStyles2","useTheme2","useState","jsx","AutoSizer","Table","data","FieldType","TOP_TABLE_COLUMN_WIDTH","TableCellDisplayMode","ColorSchemeDiff","diffColorBlindColors","diffDefaultColors","MappingType","applyFieldOverrides","escapeStringForRegex","jsxs","IconButton","css"],"mappings":"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"}