The Callers tree table is working. :)

This commit is contained in:
Kaelin Hooper
2016-07-13 17:10:09 -07:00
parent 2dcc374bf5
commit 040e253796
5 changed files with 129 additions and 68 deletions
@@ -80,7 +80,7 @@ namespace PerfDataService.Controllers
[HttpGet]
[Route("/api/[controller]/stackviewer/callertree")]
public string GetCallers([FromQuery]string filename, [FromQuery]string name, [FromQuery]string stackType, [FromQuery]int numNodes = 10)
public string GetCallers([FromQuery]string filename, [FromQuery]string name, [FromQuery]string stackType, [FromQuery]int numNodes = 10, [FromQuery]string path="")
{
// Ensure the required properties are present
if (string.IsNullOrEmpty(filename) || string.IsNullOrEmpty(stackType) || string.IsNullOrEmpty(name))
@@ -94,7 +94,8 @@ namespace PerfDataService.Controllers
var url = "http://localhost:50001/stackviewer/callertree?filename=" + filename
+ "&name=" + name
+ "&stacktype=" + stackType
+ "&numNodes=" + numNodes;
+ "&numNodes=" + numNodes
+ "&path=" + path;
System.Diagnostics.Debug.WriteLine("\n\n\nURL: " + url + "\n\n\n");
var json = client.DownloadString(url);
return json;
@@ -39,6 +39,7 @@
function addJsTreeEventListeners() {
// Directory/File Click Event
$(self.treeDivID).on('activate_node.jstree', function (event, node) {
nodeObject = node.node.original; // JSTree has a node within a node.. Weird.
@@ -59,10 +60,10 @@
console.log(url);
console.log(json);
// Attach data to current (parent) window so that the new window can access it on load (via window.opener.stackData)
// Attach data to current (parent) window so that the new window can access it on load (via window.opener.summaryStackData)
window.filename = filename;
window.stackType = stackType;
window.stackData = json;
window.summaryStackData = json;
// Create and open the new window
var stackViewerWindow = window.open(self.domain + "/Views/static/stackviewer.html");
@@ -1,8 +1,8 @@
function StackDelegate(filename, stackType, stackData) {
function StackDelegate(filename, stackType, summaryStackData) {
var self = this;
self.filename = filename;
self.stackType = stackType;
self.stackData = stackData;
self.summaryStackData = summaryStackData;
self.domain = "http://localhost:5000";
self.currentNode = "";
self.defaultNumNodes = 10;
@@ -11,56 +11,33 @@ function StackDelegate(filename, stackType, stackData) {
$("#statusBar span").text(status);
};
// TODO: If By Name row was selected, change to callers tree
$(document).dblclick("#tree tbody tr", function (row) {
var name = row.target.childNodes[1].data; // Get the name of the node
if (name !== undefined) {
self.getCallers(self.filename, name, self.stackType, self.defaultNumNodes);
}
});
//$('#tabs').foundation('selectTab', $("#caller-callee"));
$('#tabs').on('change.zf.tabs', function (event, tab) {
console.log(tab);
//console.log(tab);
});
self.getCallers = function getCallers(filename, name, stackType, numNodes) {
var url = self.domain + "/api/data/stackviewer/callertree?filename=" + filename + "&name=" + name + "&stacktype=" + stackType + "&numNodes=" + numNodes;
self.getCallerTree = function getCallerTree(name, path, callback) {
var url = self.domain + "/api/data/stackviewer/callertree?filename=" + self.filename
+ "&name=" + name
+ "&stacktype=" + self.stackType
+ "&numNodes=" + self.defaultNumNodes
+ "&path=" + path;
$.get(url, function (response, status) {
json = JSON.parse(response);
console.log(json);
// Log the completed work out
//self.log("Completed: Get Callers for " + name);
//self.log("Completed: Get Callers for " + name + " at path: " + path);
path = path != "" && path != undefined ? "/" + path : path;
console.log("Completed: Get Callers for " + name + path);
callback(json);
});
}
//self.httpGet = function httpGet(url, callback) {
// url = self.domain + url;
// var xmlHttp = new XMLHttpRequest();
// xmlHttp.onreadystatechange = function () {
// if (xmlHttp.readyState == 4) {
// if (xmlHttp.status == 200) {
// self.log("GET " + url + " Complete");
// callback(JSON.parse(xmlHttp.responseText));
// } else {
// self.log("GET " + url + " " + xmlHttp.status);
// }
// }
// };
// xmlHttp.open("GET", url, true);
// xmlHttp.send(null);
//};
}
var filename = window.opener.filename;
var stackType = window.opener.stackType;
var stackData = window.opener.stackData;
var summaryStackData = window.opener.summaryStackData;
var stackDelegate = new StackDelegate(filename, stackType, stackData);
var stackDelegate = new StackDelegate(filename, stackType, summaryStackData);
@@ -15,12 +15,12 @@ tr:nth-child(even) {
background-color: #dddddd;
}
#stackData table.treetable .collapsed td span.indenter a {
#callersTree .branch td span.indenter a {
background-image: url("../static/images/right-arrow.png");
background-size: 16px;
}
#stackData table.treetable .expanded td span.indenter a {
#callersTree .expanded td span.indenter a {
background-image: url("../static/images/down-arrow.png");
background-size: 16px;
}
@@ -9,6 +9,7 @@
<link href="../static/stackviewer.css" rel="stylesheet" type="text/css" />
</head>
<body>
<ul class="tabs" data-tabs id="tabs">
<li class="tabs-title is-active"><a href="#by-name" aria-selected="true">By Name</a></li>
<li class="tabs-title"><a href="#caller-callee">Caller-Callee</a></li>
@@ -20,27 +21,37 @@
<div class="tabs-content" data-tabs-content="tabs">
<div class="tabs-panel is-active" id="by-name">
<div id="stackData">
<table id="tree">
<table id="by-name-list">
<thead>
<tr>
<th>Name</th>
<th>Exc %</th>
<th>Exc</th>
<th>Inc %</th>
<th>Inc</th>
<th>Fold</th>
<th>When</th>
<th>First</th>
<th>Last</th>
</tr>
</thead>
</table>
</div>
</div>
<div class="tabs-panel" id="caller-callee">
<p>Suspendisse dictum feugiat nisl ut dapibus. Vivamus hendrerit arcu sed erat molestie vehicula. Ut in nulla enim. Phasellus molestie magna non est bibendum non venenatis nisl tempor. Sed auctor neque eu tellus rhoncus ut eleifend nibh porttitor.</p>
<div class="tabs-panel" id="callers">
<table id="callersTree">
<thead>
<tr>
<th>Name</th>
<th>Exc %</th>
<th>Exc</th>
<th>Inc %</th>
<th>Inc</th>
<th>Fold</th>
<th>First</th>
<th>Last</th>
</tr>
</thead>
</table>
</div>
</div>
@@ -60,33 +71,41 @@
<script>
$(document).ready(function () {
// Get metadata and stack json from parent window
//var filename = window.opener.filename;
//var stackType = window.opener.stackType;
//var stackData = window.opener.stackData;
// Get tree ready
var indenterTemplate = "<span class=\"indenter\"><a href=\"#\">&nbsp;</a></span>";
// Initiate tree table with said properties
$("#tree").treetable({
// Initialize by-name-list with said properties
$("#by-name-list").treetable({
expandable: true,
indenterTemplate: indenterTemplate,
clickableNodeNames: true,
onNodeExpand: function () {
var node = this;
console.log(node);
}
});
console.log(stackDelegate.stackData);
updateTree(stackDelegate.stackData);
// Initialize callersTree with said properties
$("#callersTree").treetable({
expandable: true,
indenterTemplate: indenterTemplate,
onNodeExpand: function () {
var node = this;
callersTreeNodeExpanded(node);
}
});
updateTreeTable("#by-name-list", null, stackDelegate.summaryStackData);
});
function updateTree(stackData) {
/*_____________________________________*/
/*_______ Tab Updater Functions _______*/
/*_____________________________________*/
function updateTreeTable(treeTableId, parentNode, stackData) {
console.log(parentNode);
var rowsToAppend = "";
// Iterate through each row
@@ -99,9 +118,22 @@
var exclusiveFoldedCount = stackData[i].exclusiveFoldedCount;
var firstTimeRelativeMSec = stackData[i].firstTimeRelativeMSec;
var lastTimeRelativeMSec = stackData[i].lastTimeRelativeMSec;
var parentContextId = stackData[i].parentContextId;
var contextId = stackData[i].contextId;
var hasChildren = stackData[i].hasChildren;
var rowsToAppend = rowsToAppend + "<tr data-tt-id=\"" + i + "\" data-tt-branch>\
<td>" + name + "</td>\
// TODO: Wrap this up in a function or something nicer
if (parentNode != null && parentNode != undefined) {
var childNodeAlreadyPresent = false;
for (var j = 0; j < parentNode.children.length; ++j) {
if (parentNode.children[j].id == contextId) { childNodeAlreadyPresent = true; }
}
if (childNodeAlreadyPresent) { continue; }
}
rowsToAppend = rowsToAppend + "<tr data-tt-id=\"" + contextId + "\" data-tt-parent-id=\"" + parentContextId + "\" data-tt-branch=\"" + hasChildren + "\">";
rowsToAppend = rowsToAppend + "<td>" + name + "</td>\
<td>" + exclusiveMetricPercent + "</td>\
<td>" + exclusiveMetric + "</td>\
<td>" + inclusiveMetricPercent + "</td>\
@@ -111,8 +143,58 @@
<td>" + lastTimeRelativeMSec + "</td>\
</tr>";
}
$("#tree").treetable("loadBranch", null, rowsToAppend);
$(treeTableId).treetable("loadBranch", parentNode, rowsToAppend); // treetable treats a null node parameter as meaning root
}
/*_____________________________________*/
/*__________ Event Listeners __________*/
/*_____________________________________*/
// by-name-list click event
$(document).on("dblclick", "#by-name-list tbody tr", function (row) {
var name = row.currentTarget.children[0].innerText.trim(); // Get the name of the clicked node
if (name !== undefined) {
stackDelegate.getCallerTree(name, "", function (callersStackData) {
// Switch to Callers tab
$('#tabs').foundation('selectTab', $("#callers"));
// Place data in Callers tab
updateTreeTable("#callersTree", null, callersStackData);
});
}
});
// callersTree node expand event
//$(document).on("dblclick", "#callersTree tbody tr", function (row) {
function callersTreeNodeExpanded(node) {
// Get the nodeId (contains the name and path) of the row the user just clicked on
// Split the name from the path
var nameAndPath = node.id.split("/");
var name = nameAndPath[0];
// Get the path, if there is one
var path = "";
// Check if there is actually a path component
if (nameAndPath.length > 1) {
// There is, so let's reconstruct it
for (var i = 1; i < nameAndPath.length - 1; ++i) {
path += nameAndPath[i] + "/";
}
path += nameAndPath[nameAndPath.length - 1];
}
if (name !== undefined) {
stackDelegate.getCallerTree(name, path, function (callersStackData) {
// Place data under clicked node
updateTreeTable("#callersTree", node, callersStackData);
});
}
}
//});
</script>