github.com/grafana/pyroscope@v1.18.0/public/app/components/FlameGraphWrapper.tsx (about)

     1  import React from 'react';
     2  import { createTheme } from '@grafana/data';
     3  import { FlameGraph } from '@grafana/flamegraph';
     4  import { Button, Tooltip } from '@grafana/ui';
     5  
     6  import useColorMode from '@pyroscope/hooks/colorMode.hook';
     7  import ExportData from '@pyroscope/components/ExportData';
     8  import type { Profile } from '@pyroscope/legacy/models';
     9  import useExportToFlamegraphDotCom from '@pyroscope/components/exportToFlamegraphDotCom.hook';
    10  
    11  import { isExportToFlamegraphDotComEnabled } from '@pyroscope/util/features';
    12  
    13  import { flamebearerToDataFrameDTO } from '@pyroscope/util/flamebearer';
    14  
    15  type Props = {
    16    profile?: Profile;
    17    dataTestId?: string;
    18    vertical?: boolean;
    19    timelineEl?: React.ReactNode;
    20    diff?: boolean;
    21  };
    22  
    23  export function FlameGraphWrapper(props: Props) {
    24    const { colorMode } = useColorMode();
    25    const exportToFlamegraphDotComFn = useExportToFlamegraphDotCom(props.profile);
    26  
    27    const dataFrame = props.profile
    28      ? flamebearerToDataFrameDTO(
    29          props.profile.flamebearer.levels,
    30          props.profile.flamebearer.names,
    31          props.profile.metadata.units,
    32          Boolean(props.diff)
    33        )
    34      : undefined;
    35  
    36    let extraEl = <></>;
    37  
    38    // This is a bit weird but the typing is not great. It seems like flamegraph assumed profile can be undefined
    39    // but then ExportData won't work so not sure if the profile === undefined could actually happen.
    40    if (props.profile) {
    41      extraEl = (
    42        <ExportData
    43          flamebearer={props.profile}
    44          exportPNG
    45          exportJSON
    46          exportPprof
    47          exportHTML
    48          exportFlamegraphDotCom={isExportToFlamegraphDotComEnabled}
    49          exportFlamegraphDotComFn={exportToFlamegraphDotComFn}
    50          buttonEl={({ onClick }) => {
    51            return (
    52              <Tooltip content={'Export Data'}>
    53                <Button
    54                  // Ugly hack to go around globally defined line height messing up sizing of the button.
    55                  // Not sure why it happens even if everything is display: Block. To override it would
    56                  // need changes in Flamegraph which would be weird so this seems relatively sensible.
    57                  style={{ marginTop: -7 }}
    58                  icon={'download-alt'}
    59                  size={'sm'}
    60                  variant={'secondary'}
    61                  fill={'outline'}
    62                  onClick={onClick}
    63                />
    64              </Tooltip>
    65            );
    66          }}
    67        />
    68      );
    69    }
    70  
    71    return (
    72      <>
    73        {props.timelineEl}
    74        <FlameGraph
    75          getTheme={() => createTheme({ colors: { mode: colorMode } })}
    76          data={dataFrame}
    77          extraHeaderElements={extraEl}
    78          vertical={props.vertical}
    79          disableCollapsing={true}
    80        />
    81      </>
    82    );
    83  }