{"version":3,"file":"FlameGraphTooltip.cjs","sources":["../../../src/FlameGraph/FlameGraphTooltip.tsx"],"sourcesContent":["import { css } from '@emotion/css';\n\nimport { type DisplayValue, getValueFormat, type GrafanaTheme2, type ValueFormatter } from '@grafana/data';\nimport { InteractiveTable, Portal, useStyles2, VizTooltipContainer } from '@grafana/ui';\n\nimport { type CollapseConfig, type FlameGraphDataContainer, type LevelItem } from './dataTransform';\n\ntype Props = {\n  data: FlameGraphDataContainer;\n  totalTicks: number;\n  position?: { x: number; y: number };\n  item?: LevelItem;\n  collapseConfig?: CollapseConfig;\n};\n\nconst FlameGraphTooltip = ({ data, item, totalTicks, position, collapseConfig }: Props) => {\n  const styles = useStyles2(getStyles);\n\n  if (!(item && position)) {\n    return null;\n  }\n\n  let content;\n\n  if (data.isDiffFlamegraph()) {\n    const tableData = getDiffTooltipData(data, item, totalTicks);\n    content = (\n      <InteractiveTable\n        className={styles.tooltipTable}\n        columns={[\n          { id: 'label', header: '' },\n          { id: 'baseline', header: 'Baseline' },\n          { id: 'comparison', header: 'Comparison' },\n          { id: 'diff', header: 'Diff' },\n        ]}\n        data={tableData}\n        getRowId={(originalRow) => originalRow.rowId}\n      />\n    );\n  } else {\n    const tooltipData = getTooltipData(data, item, totalTicks);\n    content = (\n      <p className={styles.lastParagraph}>\n        {tooltipData.unitTitle}\n        <br />\n        Total: <b>{tooltipData.unitValue}</b> ({tooltipData.percentValue}%)\n        <br />\n        Self: <b>{tooltipData.unitSelf}</b> ({tooltipData.percentSelf}%)\n        <br />\n        Samples: <b>{tooltipData.samples}</b>\n      </p>\n    );\n  }\n\n  return (\n    <Portal>\n      <VizTooltipContainer className={styles.tooltipContainer} position={position} offset={{ x: 15, y: 0 }}>\n        <div className={styles.tooltipContent}>\n          <p className={styles.tooltipName}>\n            {data.getLabel(item.itemIndexes[0])}\n            {collapseConfig && collapseConfig.collapsed ? (\n              <span>\n                <br />\n                and {collapseConfig.items.length} similar items\n              </span>\n            ) : (\n              ''\n            )}\n          </p>\n          {content}\n        </div>\n      </VizTooltipContainer>\n    </Portal>\n  );\n};\n\ntype TooltipData = {\n  percentValue: number;\n  percentSelf: number;\n  unitTitle: string;\n  unitValue: string;\n  unitSelf: string;\n  samples: string;\n};\n\nexport const getTooltipData = (data: FlameGraphDataContainer, item: LevelItem, totalTicks: number): TooltipData => {\n  const displayValue = data.valueDisplayProcessor(item.value);\n  const displaySelf = data.getSelfDisplay(item.itemIndexes);\n\n  const percentValue = Math.round(10000 * (displayValue.numeric / totalTicks)) / 100;\n  const percentSelf = Math.round(10000 * (displaySelf.numeric / totalTicks)) / 100;\n  let unitValue = displayValue.text + displayValue.suffix;\n  let unitSelf = displaySelf.text + displaySelf.suffix;\n\n  const unitTitle = data.getUnitTitle();\n  if (unitTitle === 'Count') {\n    if (!displayValue.suffix) {\n      // Makes sure we don't show 123undefined or something like that if suffix isn't defined\n      unitValue = displayValue.text;\n    }\n    if (!displaySelf.suffix) {\n      // Makes sure we don't show 123undefined or something like that if suffix isn't defined\n      unitSelf = displaySelf.text;\n    }\n  }\n\n  return {\n    percentValue,\n    percentSelf,\n    unitTitle,\n    unitValue,\n    unitSelf,\n    samples: displayValue.numeric.toLocaleString(),\n  };\n};\n\ntype DiffTableData = {\n  rowId: string;\n  label: string;\n  baseline: string | number;\n  comparison: string | number;\n  diff: string | number;\n};\n\nconst formatWithSuffix = (value: number, formatter: ValueFormatter): string => {\n  const displayValue = formatter(value);\n  return displayValue.text + displayValue.suffix;\n};\n\nexport const getDiffTooltipData = (\n  data: FlameGraphDataContainer,\n  item: LevelItem,\n  totalTicks: number\n): DiffTableData[] => {\n  const levels = data.getLevels();\n  const totalTicksRight = levels[0][0].valueRight!;\n  const totalTicksLeft = totalTicks - totalTicksRight;\n  const valueLeft = item.value - item.valueRight!;\n\n  const percentageLeft = Math.round((10000 * valueLeft) / totalTicksLeft) / 100;\n  const percentageRight = Math.round((10000 * item.valueRight!) / totalTicksRight) / 100;\n\n  const diff = ((percentageRight - percentageLeft) / percentageLeft) * 100;\n\n  const displayValueLeft = getValueWithUnit(data, data.valueDisplayProcessor(valueLeft));\n  const displayValueRight = getValueWithUnit(data, data.valueDisplayProcessor(item.valueRight!));\n\n  const shortValFormat = getValueFormat('short');\n\n  return [\n    {\n      rowId: '1',\n      label: '% of total',\n      baseline: percentageLeft + '%',\n      comparison: percentageRight + '%',\n      diff: formatWithSuffix(diff, shortValFormat) + '%',\n    },\n    {\n      rowId: '2',\n      label: 'Value',\n      baseline: displayValueLeft,\n      comparison: displayValueRight,\n      diff: getValueWithUnit(data, data.valueDisplayProcessor(item.valueRight! - valueLeft)),\n    },\n    {\n      rowId: '3',\n      label: 'Samples',\n      baseline: formatWithSuffix(valueLeft, shortValFormat),\n      comparison: formatWithSuffix(item.valueRight!, shortValFormat),\n      diff: formatWithSuffix(item.valueRight! - valueLeft, shortValFormat),\n    },\n  ];\n};\n\nfunction getValueWithUnit(data: FlameGraphDataContainer, displayValue: DisplayValue) {\n  let unitValue = displayValue.text + displayValue.suffix;\n\n  const unitTitle = data.getUnitTitle();\n  if (unitTitle === 'Count') {\n    if (!displayValue.suffix) {\n      // Makes sure we don't show 123undefined or something like that if suffix isn't defined\n      unitValue = displayValue.text;\n    }\n  }\n  return unitValue;\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n  tooltipContainer: css({\n    title: 'tooltipContainer',\n    overflow: 'hidden',\n  }),\n  tooltipContent: css({\n    title: 'tooltipContent',\n    fontSize: theme.typography.bodySmall.fontSize,\n    width: '100%',\n  }),\n  tooltipName: css({\n    title: 'tooltipName',\n    marginTop: 0,\n    wordBreak: 'break-all',\n  }),\n  lastParagraph: css({\n    title: 'lastParagraph',\n    marginBottom: 0,\n  }),\n  name: css({\n    title: 'name',\n    marginBottom: '10px',\n  }),\n\n  tooltipTable: css({\n    title: 'tooltipTable',\n    maxWidth: '400px',\n  }),\n});\n\nexport default FlameGraphTooltip;\n"],"names":["useStyles2","jsx","InteractiveTable","jsxs","Portal","VizTooltipContainer","data","getValueFormat","css"],"mappings":"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"}