flamegraphOptionsMenu.tsx 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import {Fragment, useMemo} from 'react';
  2. import Button from 'sentry/components/button';
  3. import CompositeSelect from 'sentry/components/compositeSelect';
  4. import {IconSliders} from 'sentry/icons';
  5. import {t} from 'sentry/locale';
  6. import {CanvasPoolManager} from 'sentry/utils/profiling/canvasScheduler';
  7. import {FlamegraphPreferences} from 'sentry/utils/profiling/flamegraph/flamegraphStateProvider/reducers/flamegraphPreferences';
  8. import {useFlamegraphPreferences} from 'sentry/utils/profiling/flamegraph/hooks/useFlamegraphPreferences';
  9. import {useDispatchFlamegraphState} from 'sentry/utils/profiling/flamegraph/hooks/useFlamegraphState';
  10. interface FlamegraphOptionsMenuProps {
  11. canvasPoolManager: CanvasPoolManager;
  12. }
  13. function FlamegraphOptionsMenu({
  14. canvasPoolManager,
  15. }: FlamegraphOptionsMenuProps): React.ReactElement {
  16. const {colorCoding, xAxis} = useFlamegraphPreferences();
  17. const dispatch = useDispatchFlamegraphState();
  18. const options = useMemo(() => {
  19. return [
  20. {
  21. label: t('X Axis'),
  22. value: 'x axis',
  23. defaultValue: xAxis,
  24. options: Object.entries(X_AXIS).map(([value, label]) => ({
  25. label,
  26. value,
  27. })),
  28. onChange: value =>
  29. dispatch({
  30. type: 'set xAxis',
  31. payload: value,
  32. }),
  33. },
  34. {
  35. label: t('Color Coding'),
  36. value: 'by symbol name',
  37. defaultValue: colorCoding,
  38. options: Object.entries(COLOR_CODINGS).map(([value, label]) => ({
  39. label,
  40. value,
  41. })),
  42. onChange: value =>
  43. dispatch({
  44. type: 'set color coding',
  45. payload: value,
  46. }),
  47. },
  48. ];
  49. // If we add color and xAxis it updates the memo and the component is re-rendered (losing hovered state)
  50. // Not ideal, but since we are only passing default value I guess we can live with it
  51. // eslint-disable-next-line react-hooks/exhaustive-deps
  52. }, [dispatch]);
  53. return (
  54. <Fragment>
  55. <Button size="xs" onClick={() => canvasPoolManager.dispatch('reset zoom', [])}>
  56. {t('Reset Zoom')}
  57. </Button>
  58. <CompositeSelect
  59. triggerLabel={t('Options')}
  60. triggerProps={{
  61. icon: <IconSliders size="xs" />,
  62. size: 'xs',
  63. }}
  64. position="bottom-end"
  65. sections={options}
  66. />
  67. </Fragment>
  68. );
  69. }
  70. const X_AXIS: Record<FlamegraphPreferences['xAxis'], string> = {
  71. standalone: t('Standalone'),
  72. transaction: t('Transaction'),
  73. };
  74. const COLOR_CODINGS: Record<FlamegraphPreferences['colorCoding'], string> = {
  75. 'by symbol name': t('By Symbol Name'),
  76. 'by library': t('By Package'),
  77. 'by system / application': t('By System / Application'),
  78. 'by recursion': t('By Recursion'),
  79. 'by frequency': t('By Frequency'),
  80. };
  81. export {FlamegraphOptionsMenu};