{"version":3,"file":"FlameGraph.mjs","sources":["../../../src/FlameGraph/FlameGraph.tsx"],"sourcesContent":["// This component is based on logic from the flamebearer project\n// https://github.com/mapbox/flamebearer\n\n// ISC License\n\n// Copyright (c) 2018, Mapbox\n\n// Permission to use, copy, modify, and/or distribute this software for any purpose\n// with or without fee is hereby granted, provided that the above copyright notice\n// and this permission notice appear in all copies.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\n// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS\n// OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\n// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\n// THIS SOFTWARE.\nimport { css, cx } from '@emotion/css';\nimport { useEffect, useState } from 'react';\nimport * as React from 'react';\n\nimport { Icon } from '@grafana/ui';\n\nimport { PIXELS_PER_LEVEL } from '../constants';\nimport { ClickedItemData, ColorScheme, ColorSchemeDiff, SelectedView, TextAlign } from '../types';\n\nimport FlameGraphCanvas from './FlameGraphCanvas';\nimport { GetExtraContextMenuButtonsFunction } from './FlameGraphContextMenu';\nimport FlameGraphMetadata from './FlameGraphMetadata';\nimport { CollapsedMap, FlameGraphDataContainer, LevelItem } from './dataTransform';\n\ntype Props = {\n  data: FlameGraphDataContainer;\n  rangeMin: number;\n  rangeMax: number;\n  matchedLabels?: Set<string>;\n  setRangeMin: (range: number) => void;\n  setRangeMax: (range: number) => void;\n  style?: React.CSSProperties;\n  onItemFocused: (data: ClickedItemData) => void;\n  focusedItemData?: ClickedItemData;\n  textAlign: TextAlign;\n  sandwichItem?: string;\n  onSandwich: (label: string) => void;\n  onFocusPillClick: () => void;\n  onSandwichPillClick: () => void;\n  colorScheme: ColorScheme | ColorSchemeDiff;\n  showFlameGraphOnly?: boolean;\n  getExtraContextMenuButtons?: GetExtraContextMenuButtonsFunction;\n  collapsing?: boolean;\n  selectedView: SelectedView;\n  search: string;\n  collapsedMap: CollapsedMap;\n  setCollapsedMap: (collapsedMap: CollapsedMap) => void;\n};\n\nconst FlameGraph = ({\n  data,\n  rangeMin,\n  rangeMax,\n  matchedLabels,\n  setRangeMin,\n  setRangeMax,\n  onItemFocused,\n  focusedItemData,\n  textAlign,\n  onSandwich,\n  sandwichItem,\n  onFocusPillClick,\n  onSandwichPillClick,\n  colorScheme,\n  showFlameGraphOnly,\n  getExtraContextMenuButtons,\n  collapsing,\n  selectedView,\n  search,\n  collapsedMap,\n  setCollapsedMap,\n}: Props) => {\n  const styles = getStyles();\n\n  const [levels, setLevels] = useState<LevelItem[][]>();\n  const [levelsCallers, setLevelsCallers] = useState<LevelItem[][]>();\n  const [totalProfileTicks, setTotalProfileTicks] = useState<number>(0);\n  const [totalProfileTicksRight, setTotalProfileTicksRight] = useState<number>();\n  const [totalViewTicks, setTotalViewTicks] = useState<number>(0);\n\n  useEffect(() => {\n    if (data) {\n      let levels = data.getLevels();\n      let totalProfileTicks = levels.length ? levels[0][0].value : 0;\n      let totalProfileTicksRight = levels.length ? levels[0][0].valueRight : undefined;\n      let totalViewTicks = totalProfileTicks;\n      let levelsCallers = undefined;\n\n      if (sandwichItem) {\n        const [callers, callees] = data.getSandwichLevels(sandwichItem);\n        levels = callees;\n        levelsCallers = callers;\n        // We need this separate as in case of diff profile we want to compute diff colors based on the original ticks.\n        totalViewTicks = callees[0]?.[0]?.value ?? 0;\n      }\n      setLevels(levels);\n      setLevelsCallers(levelsCallers);\n      setTotalProfileTicks(totalProfileTicks);\n      setTotalProfileTicksRight(totalProfileTicksRight);\n      setTotalViewTicks(totalViewTicks);\n    }\n  }, [data, sandwichItem]);\n\n  if (!levels) {\n    return null;\n  }\n\n  const commonCanvasProps = {\n    data,\n    rangeMin,\n    rangeMax,\n    matchedLabels,\n    setRangeMin,\n    setRangeMax,\n    onItemFocused,\n    focusedItemData,\n    textAlign,\n    onSandwich,\n    colorScheme,\n    totalProfileTicks,\n    totalProfileTicksRight,\n    totalViewTicks,\n    showFlameGraphOnly,\n    collapsedMap,\n    setCollapsedMap,\n    getExtraContextMenuButtons,\n    collapsing,\n    search,\n    selectedView,\n  };\n  let canvas = null;\n\n  if (levelsCallers?.length) {\n    canvas = (\n      <>\n        <div className={styles.sandwichCanvasWrapper}>\n          <div className={styles.sandwichMarker}>\n            Callers\n            <Icon className={styles.sandwichMarkerIcon} name={'arrow-down'} />\n          </div>\n          <FlameGraphCanvas\n            {...commonCanvasProps}\n            root={levelsCallers[levelsCallers.length - 1][0]}\n            depth={levelsCallers.length}\n            direction={'parents'}\n            // We do not support collapsing in sandwich view for now.\n            collapsing={false}\n          />\n        </div>\n\n        <div className={styles.sandwichCanvasWrapper}>\n          <div className={cx(styles.sandwichMarker, styles.sandwichMarkerCalees)}>\n            <Icon className={styles.sandwichMarkerIcon} name={'arrow-up'} />\n            Callees\n          </div>\n          <FlameGraphCanvas\n            {...commonCanvasProps}\n            root={levels[0][0]}\n            depth={levels.length}\n            direction={'children'}\n            collapsing={false}\n          />\n        </div>\n      </>\n    );\n  } else if (levels?.length) {\n    canvas = (\n      <FlameGraphCanvas {...commonCanvasProps} root={levels[0][0]} depth={levels.length} direction={'children'} />\n    );\n  }\n\n  return (\n    <div className={styles.graph}>\n      <FlameGraphMetadata\n        data={data}\n        focusedItem={focusedItemData}\n        sandwichedLabel={sandwichItem}\n        totalTicks={totalViewTicks}\n        onFocusPillClick={onFocusPillClick}\n        onSandwichPillClick={onSandwichPillClick}\n      />\n      {canvas}\n    </div>\n  );\n};\n\nconst getStyles = () => ({\n  graph: css({\n    label: 'graph',\n    overflow: 'auto',\n    flexGrow: 1,\n    flexBasis: '50%',\n  }),\n  sandwichCanvasWrapper: css({\n    label: 'sandwichCanvasWrapper',\n    display: 'flex',\n    marginBottom: `${PIXELS_PER_LEVEL / window.devicePixelRatio}px`,\n  }),\n  sandwichMarker: css({\n    label: 'sandwichMarker',\n    writingMode: 'vertical-lr',\n    transform: 'rotate(180deg)',\n    overflow: 'hidden',\n    whiteSpace: 'nowrap',\n  }),\n  sandwichMarkerCalees: css({\n    label: 'sandwichMarkerCalees',\n    textAlign: 'right',\n  }),\n  sandwichMarkerIcon: css({\n    label: 'sandwichMarkerIcon',\n    verticalAlign: 'baseline',\n  }),\n});\n\nexport default FlameGraph;\n"],"names":["levels","totalProfileTicks","totalProfileTicksRight","totalViewTicks","levelsCallers"],"mappings":"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"}