|
@@ -33,120 +33,141 @@ function createRow(table, cellName, items) {
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
-function showProfile(path, cutoff = 0.05) {
|
|
|
- requestGet(path, {}, function(data) {
|
|
|
- var table = document.createElement('table');
|
|
|
- table.className = 'popup-table';
|
|
|
-
|
|
|
- data.records['total'] = data.total;
|
|
|
- var keys = Object.keys(data.records).sort(function(a, b) {
|
|
|
- return data.records[b] - data.records[a];
|
|
|
+function createVisualizationTable(data, cutoff = 0, sort = "") {
|
|
|
+ var table = document.createElement('table');
|
|
|
+ table.className = 'popup-table';
|
|
|
+
|
|
|
+ var keys = Object.keys(data);
|
|
|
+ if (sort === "number") {
|
|
|
+ keys = keys.sort(function(a, b) {
|
|
|
+ return data[b] - data[a];
|
|
|
});
|
|
|
- var items = keys.map(function(x) {
|
|
|
- return {key: x, parts: x.split('/'), time: data.records[x]};
|
|
|
+ } else {
|
|
|
+ keys = keys.sort();
|
|
|
+ }
|
|
|
+ var items = keys.map(function(x) {
|
|
|
+ return {key: x, parts: x.split('/'), value: data[x]};
|
|
|
+ });
|
|
|
+ var maxLength = items.reduce(function(a, b) {
|
|
|
+ return Math.max(a, b.parts.length);
|
|
|
+ }, 0);
|
|
|
+
|
|
|
+ var cols = createRow(
|
|
|
+ table,
|
|
|
+ 'th',
|
|
|
+ [
|
|
|
+ cutoff === 0 ? 'key' : 'record',
|
|
|
+ cutoff === 0 ? 'value' : 'seconds'
|
|
|
+ ]
|
|
|
+ );
|
|
|
+ cols[0].colSpan = maxLength;
|
|
|
+
|
|
|
+ function arraysEqual(a, b) {
|
|
|
+ return !(a < b || b < a);
|
|
|
+ }
|
|
|
+
|
|
|
+ var addLevel = function(level, parent, hide) {
|
|
|
+ var matching = items.filter(function(x) {
|
|
|
+ return x.parts[level] && !x.parts[level + 1] && arraysEqual(x.parts.slice(0, level), parent);
|
|
|
});
|
|
|
- var maxLength = items.reduce(function(a, b) {
|
|
|
- return Math.max(a, b.parts.length);
|
|
|
- }, 0);
|
|
|
-
|
|
|
- var cols = createRow(table, 'th', ['record', 'seconds']);
|
|
|
- cols[0].colSpan = maxLength;
|
|
|
-
|
|
|
- function arraysEqual(a, b) {
|
|
|
- return !(a < b || b < a);
|
|
|
+ if (sort === "number") {
|
|
|
+ matching = matching.sort(function(a, b) {
|
|
|
+ return b.value - a.value;
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ matching = matching.sort();
|
|
|
}
|
|
|
+ var othersTime = 0;
|
|
|
+ var othersList = [];
|
|
|
+ var othersRows = [];
|
|
|
+ var childrenRows = [];
|
|
|
+ matching.forEach(function(x) {
|
|
|
+ var visible = (cutoff === 0 && !hide) || (x.value >= cutoff && !hide);
|
|
|
+
|
|
|
+ var cells = [];
|
|
|
+ for (var i = 0; i < maxLength; i++) {
|
|
|
+ cells.push(x.parts[i]);
|
|
|
+ }
|
|
|
+ cells.push(cutoff === 0 ? x.value : x.value.toFixed(3));
|
|
|
+ var cols = createRow(table, 'td', cells);
|
|
|
+ for (i = 0; i < level; i++) {
|
|
|
+ cols[i].className = 'muted';
|
|
|
+ }
|
|
|
|
|
|
- var addLevel = function(level, parent, hide) {
|
|
|
- var matching = items.filter(function(x) {
|
|
|
- return x.parts[level] && !x.parts[level + 1] && arraysEqual(x.parts.slice(0, level), parent);
|
|
|
- });
|
|
|
- var sorted = matching.sort(function(a, b) {
|
|
|
- return b.time - a.time;
|
|
|
- });
|
|
|
- var othersTime = 0;
|
|
|
- var othersList = [];
|
|
|
- var othersRows = [];
|
|
|
- var childrenRows = [];
|
|
|
- sorted.forEach(function(x) {
|
|
|
- var visible = x.time >= cutoff && !hide;
|
|
|
-
|
|
|
- var cells = [];
|
|
|
- for (var i = 0; i < maxLength; i++) {
|
|
|
- cells.push(x.parts[i]);
|
|
|
- }
|
|
|
- cells.push(x.time.toFixed(3));
|
|
|
- var cols = createRow(table, 'td', cells);
|
|
|
- for (i = 0; i < level; i++) {
|
|
|
- cols[i].className = 'muted';
|
|
|
- }
|
|
|
-
|
|
|
- var tr = cols[0].parentNode;
|
|
|
- if (!visible) {
|
|
|
- tr.classList.add("hidden");
|
|
|
- }
|
|
|
-
|
|
|
- if (x.time >= cutoff) {
|
|
|
- childrenRows.push(tr);
|
|
|
- } else {
|
|
|
- othersTime += x.time;
|
|
|
- othersList.push(x.parts[level]);
|
|
|
- othersRows.push(tr);
|
|
|
- }
|
|
|
-
|
|
|
- var children = addLevel(level + 1, parent.concat([x.parts[level]]), true);
|
|
|
- if (children.length > 0) {
|
|
|
- var cell = cols[level];
|
|
|
- var onclick = function() {
|
|
|
- cell.classList.remove("link");
|
|
|
- cell.removeEventListener("click", onclick);
|
|
|
- children.forEach(function(x) {
|
|
|
- x.classList.remove("hidden");
|
|
|
- });
|
|
|
- };
|
|
|
- cell.classList.add("link");
|
|
|
- cell.addEventListener("click", onclick);
|
|
|
- }
|
|
|
- });
|
|
|
+ var tr = cols[0].parentNode;
|
|
|
+ if (!visible) {
|
|
|
+ tr.classList.add("hidden");
|
|
|
+ }
|
|
|
|
|
|
- if (othersTime > 0) {
|
|
|
- var cells = [];
|
|
|
- for (var i = 0; i < maxLength; i++) {
|
|
|
- cells.push(parent[i]);
|
|
|
- }
|
|
|
- cells.push(othersTime.toFixed(3));
|
|
|
- cells[level] = 'others';
|
|
|
- var cols = createRow(table, 'td', cells);
|
|
|
- for (i = 0; i < level; i++) {
|
|
|
- cols[i].className = 'muted';
|
|
|
- }
|
|
|
+ if (cutoff === 0 || x.value >= cutoff) {
|
|
|
+ childrenRows.push(tr);
|
|
|
+ } else {
|
|
|
+ othersTime += x.value;
|
|
|
+ othersList.push(x.parts[level]);
|
|
|
+ othersRows.push(tr);
|
|
|
+ }
|
|
|
|
|
|
+ var children = addLevel(level + 1, parent.concat([x.parts[level]]), true);
|
|
|
+ if (children.length > 0) {
|
|
|
var cell = cols[level];
|
|
|
- var tr = cell.parentNode;
|
|
|
var onclick = function() {
|
|
|
- tr.classList.add("hidden");
|
|
|
cell.classList.remove("link");
|
|
|
cell.removeEventListener("click", onclick);
|
|
|
- othersRows.forEach(function(x) {
|
|
|
+ children.forEach(function(x) {
|
|
|
x.classList.remove("hidden");
|
|
|
});
|
|
|
};
|
|
|
-
|
|
|
- cell.title = othersList.join(", ");
|
|
|
cell.classList.add("link");
|
|
|
cell.addEventListener("click", onclick);
|
|
|
+ }
|
|
|
+ });
|
|
|
|
|
|
- if (hide) {
|
|
|
- tr.classList.add("hidden");
|
|
|
- }
|
|
|
+ if (othersTime > 0) {
|
|
|
+ var cells = [];
|
|
|
+ for (var i = 0; i < maxLength; i++) {
|
|
|
+ cells.push(parent[i]);
|
|
|
+ }
|
|
|
+ cells.push(othersTime.toFixed(3));
|
|
|
+ cells[level] = 'others';
|
|
|
+ var cols = createRow(table, 'td', cells);
|
|
|
+ for (i = 0; i < level; i++) {
|
|
|
+ cols[i].className = 'muted';
|
|
|
+ }
|
|
|
|
|
|
- childrenRows.push(tr);
|
|
|
+ var cell = cols[level];
|
|
|
+ var tr = cell.parentNode;
|
|
|
+ var onclick = function() {
|
|
|
+ tr.classList.add("hidden");
|
|
|
+ cell.classList.remove("link");
|
|
|
+ cell.removeEventListener("click", onclick);
|
|
|
+ othersRows.forEach(function(x) {
|
|
|
+ x.classList.remove("hidden");
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ cell.title = othersList.join(", ");
|
|
|
+ cell.classList.add("link");
|
|
|
+ cell.addEventListener("click", onclick);
|
|
|
+
|
|
|
+ if (hide) {
|
|
|
+ tr.classList.add("hidden");
|
|
|
}
|
|
|
|
|
|
- return childrenRows;
|
|
|
- };
|
|
|
+ childrenRows.push(tr);
|
|
|
+ }
|
|
|
+
|
|
|
+ return childrenRows;
|
|
|
+ };
|
|
|
|
|
|
- addLevel(0, []);
|
|
|
+ addLevel(0, []);
|
|
|
+
|
|
|
+ return table;
|
|
|
+}
|
|
|
|
|
|
+function showProfile(path, cutoff = 0.05) {
|
|
|
+ requestGet(path, {}, function(data) {
|
|
|
+ data.records['total'] = data.total;
|
|
|
+ const table = createVisualizationTable(data.records, cutoff, "number");
|
|
|
popup(table);
|
|
|
});
|
|
|
}
|