indent process_id based on hierarchy and popup timeline annotaations on mouseover.
diff --git a/htrace-hbase/src/main/webapps/htrace/spans.js b/htrace-hbase/src/main/webapps/htrace/spans.js
index 4dd6d3b..df59660 100644
--- a/htrace-hbase/src/main/webapps/htrace/spans.js
+++ b/htrace-hbase/src/main/webapps/htrace/spans.js
@@ -21,8 +21,11 @@
spans.map(function(s) {
s.start = parseInt(s.start);
s.stop = parseInt(s.stop);
+ if (s.timeline) {
+ s.timeline.forEach(function(t) { t.time = parseInt(t.time); });
+ }
});
- var rootid = 477902;
+ var rootid = "477902";
var margin = {top: 50, right: 500, bottom: 50, left: 50};
var barheight = 20;
var width = 800;
@@ -32,15 +35,17 @@
var tmax = d3.max(spans, function(s) { return s.stop; });
var xscale = d3.time.scale()
.domain([new Date(tmin), new Date(tmax)]).range([0, width]);
+
var byparent = d3.nest()
- .sortValues(function(a, b) {
- return a.start < b.start ? -1 : a.start > b.start ? 1 : 0;
- })
.key(function(e) {return e.parent_id})
.map(spans, d3.map);
addchildren(byparent.get(rootid), byparent);
- var sortedspans = [];
- traverse(byparent.get(rootid), function(e) { sortedspans.push(e); });
+
+ var tree = d3.layout.tree()
+ .sort(function(a, b) {
+ return a.start < b.start ? -1 : a.start > b.start ? 1 : 0;
+ });
+ var sortedspans = tree.nodes(byparent.get(rootid)[0]);
var svg = d3.select("body").append("svg")
.attr("width", width + gleftmargin + margin.left + margin.right)
@@ -61,12 +66,19 @@
.append("g")
.attr("transform", function(s, i) {
return "translate(0, " + (i * barheight + 5) + ")";
+ })
+ .classed("timeline", function (d) {
+ return d.timeline;
});
span_g.append("text")
- .text(function(s){ return s.process_id; })
+ .text(function(s){
+ return s.process_id;
+ })
.style("alignment-baseline", "hanging")
- .attr("transform", "translate(" + (- gleftmargin) + ", 0)");
+ .attr("transform", function(s) {
+ return "translate(" + (s.depth * 10 - gleftmargin) + ", 0)";
+ });
var rect_g = span_g.append("g")
.attr("transform", function(s) {
@@ -78,7 +90,8 @@
.attr("width", function (s) {
return (width * (s.stop - s.start)) / (tmax - tmin) + 1;
})
- .style("fill", "lightblue");
+ .style("fill", "lightblue")
+ .attr("class", "span")
rect_g.append("text")
.text(function(s){ return s.description; })
@@ -91,6 +104,46 @@
.style("font-size", "10px")
.attr("transform", function(s, i) { return "translate(0, 10)"; });
+ bars.selectAll("g.timeline")
+ .selectAll("rect.timeline")
+ .data(function(s) { return s.timeline; })
+ .enter()
+ .append("rect")
+ .style("fill", "red")
+ .attr("height", 8)
+ .attr("width", 8)
+ .attr("transform", function(t) {
+ return "translate(" + xscale(t.time) + ", 11)";
+ })
+ .classed("timeline");
+
+ var popup = d3.select("body")
+ .append("div")
+ .attr("class", "popup")
+ .style("opacity", 0);
+
+ bars.selectAll("g.timeline")
+ .on("mouseover", function(d) {
+ popup.transition()
+ .duration(300)
+ .style("opacity", .95);
+ var text = "<table>";
+ d.timeline.forEach(function (t) {
+ text += "<tr><td>" + (t.time - tmin) + "</td>";
+ text += "<td> : " + t.message + "<td/></tr>";
+ });
+ text += "</table>"
+ popup.html(text)
+ .style("left", "30px")
+ .style("top", "30px")
+ .style("width", "700px")
+ .style("background", "orange")
+ .style("position", "absolute");
+ })
+ .on("mouseout", function(d) {
+ popup.transition().duration(200).style("opacity", 0);
+ });
+
var axis = d3.svg.axis()
.scale(xscale)
.orient("top")
@@ -111,12 +164,3 @@
}
});
}
-
-function traverse (children, func) {
- children.forEach(function(e) {
- func(e);
- if (e.children) {
- traverse (e.children, func);
- }
- });
-}