mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
115 lines
3.4 KiB
TypeScript
115 lines
3.4 KiB
TypeScript
import type {mat3} from 'gl-matrix';
|
|
|
|
import type {Rect} from 'sentry/utils/profiling/speedscope';
|
|
import {computeInterval} from 'sentry/utils/profiling/speedscope';
|
|
|
|
import type {FlamegraphTheme} from '../flamegraph/flamegraphTheme';
|
|
import {getContext, measureText} from '../gl/utils';
|
|
|
|
export function getIntervalTimeAtX(logicalSpaceToConfigView: mat3, x: number): number {
|
|
const vector = logicalSpaceToConfigView[0] * x + logicalSpaceToConfigView[6];
|
|
|
|
if (vector > 1) {
|
|
return Math.round(vector);
|
|
}
|
|
|
|
return Math.round(vector * 10) / 10;
|
|
}
|
|
|
|
class GridRenderer {
|
|
canvas: HTMLCanvasElement;
|
|
context: CanvasRenderingContext2D;
|
|
theme: FlamegraphTheme;
|
|
|
|
formatter: (value: number) => string;
|
|
|
|
constructor(
|
|
canvas: HTMLCanvasElement,
|
|
theme: FlamegraphTheme,
|
|
formatter: (value: number) => string
|
|
) {
|
|
this.canvas = canvas;
|
|
this.theme = theme;
|
|
this.formatter = formatter;
|
|
|
|
this.context = getContext(canvas, '2d');
|
|
}
|
|
|
|
draw(
|
|
configViewSpace: Rect,
|
|
physicalViewRect: Rect,
|
|
configViewToPhysicalSpace: mat3,
|
|
logicalSpaceToConfigView: mat3,
|
|
drawGridTicks: boolean = true
|
|
): void {
|
|
this.context.font = `${
|
|
this.theme.SIZES.LABEL_FONT_SIZE * window.devicePixelRatio
|
|
}px ${this.theme.FONTS.FONT}`;
|
|
this.context.textBaseline = 'top';
|
|
this.context.lineWidth = this.theme.SIZES.GRID_LINE_WIDTH / 2;
|
|
|
|
// Draw the background of the top timeline
|
|
this.context.fillStyle = this.theme.COLORS.GRID_FRAME_BACKGROUND_COLOR;
|
|
this.context.fillRect(
|
|
0,
|
|
0,
|
|
physicalViewRect.width,
|
|
this.theme.SIZES.TIMELINE_HEIGHT * window.devicePixelRatio
|
|
);
|
|
|
|
// Draw top timeline lines
|
|
this.context.fillStyle = this.theme.COLORS.GRID_LINE_COLOR;
|
|
this.context.fillRect(
|
|
0,
|
|
0,
|
|
physicalViewRect.width,
|
|
this.theme.SIZES.GRID_LINE_WIDTH / 2
|
|
);
|
|
this.context.fillRect(
|
|
0,
|
|
this.theme.SIZES.TIMELINE_HEIGHT * window.devicePixelRatio,
|
|
physicalViewRect.width,
|
|
this.theme.SIZES.GRID_LINE_WIDTH / 2
|
|
);
|
|
|
|
if (drawGridTicks) {
|
|
const intervals = computeInterval(
|
|
configViewSpace,
|
|
logicalSpaceToConfigView,
|
|
getIntervalTimeAtX
|
|
);
|
|
|
|
for (let i = 0; i < intervals.length; i++) {
|
|
// Compute the x position of our interval from config space to physical
|
|
const physicalIntervalPosition = Math.round(
|
|
intervals[i] * configViewToPhysicalSpace[0] + configViewToPhysicalSpace[6]
|
|
);
|
|
|
|
// Format the label text
|
|
const labelText = this.formatter(intervals[i]);
|
|
|
|
this.context.fillStyle = this.theme.COLORS.LABEL_FONT_COLOR;
|
|
// Subtract width of the text and padding so that the text is align to the left of our interval
|
|
this.context.fillText(
|
|
labelText,
|
|
physicalIntervalPosition -
|
|
measureText(labelText, this.context).width -
|
|
this.theme.SIZES.LABEL_FONT_PADDING * window.devicePixelRatio,
|
|
this.theme.SIZES.LABEL_FONT_PADDING * window.devicePixelRatio
|
|
);
|
|
|
|
// Draw the vertical grid line
|
|
this.context.strokeStyle = this.theme.COLORS.GRID_LINE_COLOR;
|
|
this.context.strokeRect(
|
|
physicalIntervalPosition - this.theme.SIZES.GRID_LINE_WIDTH / 2,
|
|
physicalViewRect.y,
|
|
this.theme.SIZES.GRID_LINE_WIDTH / 2,
|
|
physicalViewRect.height
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export {GridRenderer};
|