positionIndicatorRenderer.tsx 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import {mat3} from 'gl-matrix';
  2. import {Rect} from 'sentry/utils/profiling/speedscope';
  3. import {FlamegraphTheme} from '../flamegraph/flamegraphTheme';
  4. import {getContext} from '../gl/utils';
  5. class PositionIndicatorRenderer {
  6. canvas: HTMLCanvasElement;
  7. context: CanvasRenderingContext2D;
  8. theme: FlamegraphTheme;
  9. constructor(canvas: HTMLCanvasElement, theme: FlamegraphTheme) {
  10. this.canvas = canvas;
  11. this.theme = theme;
  12. this.context = getContext(this.canvas, '2d');
  13. }
  14. draw(configView: Rect, configSpace: Rect, configSpaceToPhysicalSpace: mat3): void {
  15. if (configView.equals(configSpace)) {
  16. // User is not zoomed in or entire chart fits in view,
  17. // then we dont need to draw anything.
  18. return;
  19. }
  20. // Transform both views to their respective physical spaces
  21. const physicalConfigViewRect = Rect.From(configView).transformRect(
  22. configSpaceToPhysicalSpace
  23. );
  24. const physicalConfigRect = Rect.From(configSpace).transformRect(
  25. configSpaceToPhysicalSpace
  26. );
  27. const offsetRectForBorderWidth: [number, number, number, number] = [
  28. physicalConfigViewRect.x - this.theme.SIZES.MINIMAP_POSITION_OVERLAY_BORDER_WIDTH,
  29. physicalConfigViewRect.y,
  30. physicalConfigViewRect.width +
  31. this.theme.SIZES.MINIMAP_POSITION_OVERLAY_BORDER_WIDTH,
  32. physicalConfigViewRect.height,
  33. ];
  34. // What we do to draw the "window" that the user is currently watching is we draw two rectangles, the
  35. // zoomed in view and the zoomed out view. The zoomed out view is the full view of the flamegraph, and the zoom
  36. // in view is whatever the user is currently looking at. Because the zoomed in view is a subset of the zoomed,
  37. // we just need to use the evenodd fill rule to paint inbetween the two rectangles.
  38. this.context.fillStyle = this.theme.COLORS.MINIMAP_POSITION_OVERLAY_COLOR;
  39. this.context.strokeStyle = this.theme.COLORS.MINIMAP_POSITION_OVERLAY_BORDER_COLOR;
  40. this.context.lineWidth = this.theme.SIZES.MINIMAP_POSITION_OVERLAY_BORDER_WIDTH;
  41. this.context.beginPath();
  42. this.context.rect(0, 0, physicalConfigRect.width, physicalConfigRect.height);
  43. this.context.rect(...offsetRectForBorderWidth);
  44. this.context.fill('evenodd');
  45. this.context.strokeRect(...offsetRectForBorderWidth);
  46. }
  47. }
  48. export {PositionIndicatorRenderer};