123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- import {mat3} from 'gl-matrix';
- import clamp from 'sentry/utils/number/clamp';
- // Computes the transformation matrix that is used to render scaled
- // elements to the DOM and draw the view.
- export class TraceView {
- // Represents the space of the entire trace, for example
- // a trace starting at 0 and ending at 1000 would have a space of [0, 1000]
- to_origin: number = 0;
- trace_space: DOMView = DOMView.Empty();
- // The view defines what the user is currently looking at, it is a subset
- // of the trace space. For example, if the user is currently looking at the
- // trace from 500 to 1000, the view would be represented by [x, width] = [500, 500]
- trace_view: DOMView = DOMView.Empty();
- // Represents the pixel space of the entire trace - this is the container
- // that we render to. For example, if the container is 1000px wide, the
- // pixel space would be [0, 1000]
- trace_physical_space: DOMView = DOMView.Empty();
- // the encapsulating container that the entire view is rendered to
- trace_container_physical_space: DOMView = DOMView.Empty();
- public readonly MAX_ZOOM_PRECISION_MS = 1;
- setTracePhysicalSpace(
- container_space: [x: number, y: number, width: number, height: number],
- space: [x: number, y: number, width: number, height: number]
- ) {
- this.trace_container_physical_space = new DOMView(
- 0,
- 0,
- container_space[2],
- container_space[3]
- );
- this.trace_physical_space = new DOMView(0, 0, space[2], space[3]);
- }
- setTraceSpace(space: [x: number, y: number, width: number, height: number]) {
- this.to_origin = space[0];
- this.trace_space = new DOMView(0, 0, space[2], space[3]);
- this.trace_view = new DOMView(0, 0, space[2], space[3]);
- }
- setTraceView(view: {width?: number; x?: number}) {
- // In cases where a trace might have a single error, there is no concept of a timeline
- if (this.trace_view.width === 0) {
- return;
- }
- const x = view.x ?? this.trace_view.x;
- const width = view.width ?? this.trace_view.width;
- this.trace_view.x = clamp(
- x,
- 0,
- Math.max(this.trace_space.width - width, this.MAX_ZOOM_PRECISION_MS)
- );
- this.trace_view.width = clamp(
- width,
- this.MAX_ZOOM_PRECISION_MS,
- this.trace_space.width - this.trace_view.x
- );
- }
- getSpanToPxForSpace(space: [number, number]): mat3 {
- const view = new DOMView(space[0], 0, space[1], 0);
- const traceViewToSpace = this.trace_space.between(view);
- const tracePhysicalToView = this.trace_physical_space.between(this.trace_space);
- return mat3.multiply(mat3.create(), traceViewToSpace, tracePhysicalToView);
- }
- getConfigSpaceCursor(cursor: {x: number; y: number}): [number, number] {
- const left_percentage = cursor.x / this.trace_physical_space.width;
- const left_view = left_percentage * this.trace_view.width;
- return [this.trace_view.x + left_view, 0];
- }
- }
- /**
- * Helper class that handles computing transformations between different views to and from DOM space
- */
- class DOMView {
- public x: number;
- public y: number;
- public width: number;
- public height: number;
- constructor(x: number, y: number, width: number, height: number) {
- this.x = x;
- this.y = y;
- this.width = width;
- this.height = height;
- }
- static From(view: DOMView): DOMView {
- return new DOMView(view.x, view.y, view.width, view.height);
- }
- static Empty(): DOMView {
- return new DOMView(0, 0, 1000, 1);
- }
- serialize() {
- return [this.x, this.y, this.width, this.height];
- }
- between(to: DOMView): mat3 {
- return mat3.fromValues(
- to.width / this.width,
- 0,
- 0,
- to.height / this.height,
- 0,
- 0,
- to.x - this.x * (to.width / this.width),
- to.y - this.y * (to.height / this.height),
- 1
- );
- }
- transform(mat: mat3): [number, number, number, number] {
- const x = this.x * mat[0] + this.y * mat[3] + mat[6];
- const y = this.x * mat[1] + this.y * mat[4] + mat[7];
- const width = this.width * mat[0] + this.height * mat[3];
- const height = this.width * mat[1] + this.height * mat[4];
- return [x, y, width, height];
- }
- get center() {
- return this.x + this.width / 2;
- }
- get left() {
- return this.x;
- }
- get right() {
- return this.x + this.width;
- }
- get top() {
- return this.y;
- }
- get bottom() {
- return this.y + this.height;
- }
- }
|