devexpress-diagram
Version:
DevExpress Diagram Control
125 lines (116 loc) • 4.81 kB
text/typescript
enum LoggerDisplayMode {
Disabled = 0,
Console = 1,
Document = 2
}
export class Diagnostics {
static mode: LoggerDisplayMode = LoggerDisplayMode.Document;
static optimizeUsingRAF = true;
static optimizeLayers = true;
static timers: { [key: number]: TimerInfo } = {};
static lastCreatedTimer: TimerInfo;
static lastAverageGroupName: string;
static enableLogsAndTimers = false;
static beginAverage(groupName: string) {
if(!this.enableLogsAndTimers) return;
this.lastAverageGroupName = groupName;
}
static endAverage() {
if(!this.enableLogsAndTimers) return;
this.lastAverageGroupName = null;
}
private static tryLogAverage(groupName: string) {
if(this.lastAverageGroupName === groupName) return;
const sameGroupTimers = Object.keys(this.timers)
.map(t => this.timers[t])
.filter(t => t.groupName === groupName);
if(!sameGroupTimers.filter(t => !t.endTime).length) {
const average = sameGroupTimers.reduce((acc, t) => acc + (t.endTime - t.startTime), 0) / sameGroupTimers.length;
this.log(`average: ${average}`);
}
}
static timer(message: string) {
if(!this.enableLogsAndTimers) return;
this.lastCreatedTimer = {
message: message,
startTime: performance.now(),
groupName: this.lastAverageGroupName
};
}
static endTimer() {
if(!this.enableLogsAndTimers) return;
const timer = this.lastCreatedTimer;
const timeoutID = setTimeout(() => {
timer.endTime = performance.now();
this.showMessage(`timer "${timer.message}": ${timer.endTime - timer.startTime}`);
timer.groupName && this.tryLogAverage(timer.groupName);
}, 0);
this.timers[timeoutID] = timer;
this.lastCreatedTimer = null;
}
static logPerfInfo() {
const nodesCount = document.querySelector(".dxdi-control > svg").querySelectorAll("*").length;
const memory = performance["memory"];
this.log(`nodes: ${nodesCount.toLocaleString()}${memory ? " memory: " : ""}${memory ? memory["usedJSHeapSize"].toLocaleString() : ""}`);
}
static log(message: any) {
this.showMessage(message);
}
static lastMessage: string;
private static showMessage(message: any) {
switch(Diagnostics.mode) {
case LoggerDisplayMode.Console:
console.log(message);
break;
case LoggerDisplayMode.Document: {
const existText = this.getElement().value;
if(this.lastMessage === message) {
let lastLineLength = existText.indexOf("\r\n");
if(lastLineLength < 0)
lastLineLength = existText.indexOf("\n");
let lastLine = existText.substr(0, lastLineLength);
const regex = /( \()([0-9]+)(\))$/;
if(regex.test(lastLine))
lastLine = lastLine.replace(/( \()([0-9]+)(\))$/, (str, before, val, after) => before + (++val) + after);
else
lastLine += " (1)";
this.getElement().value = lastLine + existText.substr(lastLineLength);
}
else {
this.getElement().value = message + "\r\n" + existText;
this.lastMessage = message;
}
}
}
}
private static el: HTMLTextAreaElement;
private static getElement(): HTMLTextAreaElement {
if(!this.el) {
this.el = document.createElement("textarea");
this.el.style.top = "0px";
this.el.style.right = "0px";
this.el.style.position = "fixed";
this.el.style.background = "transparent";
this.el.style.fontSize = "11px";
this.el.style.fontFamily = "monospace";
this.el.style.overflow = "auto";
this.el.style.width = "400px";
document.body.appendChild(this.el);
const clr = document.createElement("button");
clr.innerHTML = "x";
clr.addEventListener("click", () => { this.el.value = ""; this.lastMessage = ""; });
clr.style.top = "0px";
clr.style.right = "400px";
clr.style.position = "fixed";
clr.style.opacity = "0.1";
document.body.appendChild(clr);
}
return this.el;
}
}
interface TimerInfo {
startTime: number;
message: string;
endTime?: number;
groupName?: string;
}