flamegraphRendererDOM.tsx 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import {mat3} from 'gl-matrix';
  2. import {Flamegraph} from 'sentry/utils/profiling/flamegraph';
  3. import {FlamegraphSearch} from 'sentry/utils/profiling/flamegraph/flamegraphStateProvider/reducers/flamegraphSearch';
  4. import {FlamegraphTheme} from 'sentry/utils/profiling/flamegraph/flamegraphTheme';
  5. import {FlamegraphFrame} from 'sentry/utils/profiling/flamegraphFrame';
  6. import {
  7. DEFAULT_FLAMEGRAPH_RENDERER_OPTIONS,
  8. FlamegraphRenderer,
  9. FlamegraphRendererOptions,
  10. } from 'sentry/utils/profiling/renderers/flamegraphRenderer';
  11. import {Rect} from 'sentry/utils/profiling/speedscope';
  12. // Convert color component from 0-1 to 0-255 range
  13. function colorComponentsToRgba(color: number[]): string {
  14. return `rgba(${Math.floor(color[0] * 255)}, ${Math.floor(color[1] * 255)}, ${Math.floor(
  15. color[2] * 255
  16. )}, ${color[3] ?? 1})`;
  17. }
  18. export class FlamegraphRendererDOM extends FlamegraphRenderer {
  19. container: HTMLElement;
  20. constructor(
  21. canvas: HTMLCanvasElement,
  22. flamegraph: Flamegraph,
  23. theme: FlamegraphTheme,
  24. options: FlamegraphRendererOptions = DEFAULT_FLAMEGRAPH_RENDERER_OPTIONS
  25. ) {
  26. super(canvas, flamegraph, theme, options);
  27. const newContainer = document.createElement('div');
  28. canvas.parentElement?.appendChild(newContainer);
  29. this.container = newContainer;
  30. }
  31. draw(configViewToPhysicalSpace: mat3) {
  32. if (!this.container) {
  33. throw new Error('No container to render into');
  34. }
  35. const newContainer = document.createElement('div');
  36. this.canvas.parentElement?.appendChild(newContainer);
  37. this.container = newContainer;
  38. const queue: FlamegraphFrame[] = [...this.flamegraph.frames];
  39. while (queue.length > 0) {
  40. const frame = queue.pop()!;
  41. const rect = new Rect(
  42. frame.start,
  43. frame.depth,
  44. frame.end - frame.start,
  45. 1
  46. ).transformRect(configViewToPhysicalSpace);
  47. const colors =
  48. this.colorMap.get(frame.key) ?? this.theme.COLORS.FRAME_GRAYSCALE_COLOR;
  49. const color = colorComponentsToRgba(colors);
  50. const div = document.createElement('div');
  51. div.style.pointerEvents = 'absolute';
  52. div.style.left = `${rect.x}px`;
  53. div.style.top = `${rect.y}px`;
  54. div.style.width = `${rect.width}px`;
  55. div.style.height = `${rect.height}px`;
  56. div.style.backgroundColor = color;
  57. div.innerHTML = frame.frame.name;
  58. div.setAttribute('data-test-id', 'flamegraph-frame');
  59. this.container.appendChild(div);
  60. }
  61. }
  62. setSearchResults(
  63. _query: string,
  64. _searchResults: FlamegraphSearch['results']['frames']
  65. ) {
  66. // @TODO for now just dont do anything as it will throw in tests
  67. }
  68. }