You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@htrace.apache.org by cm...@apache.org on 2015/03/17 01:09:23 UTC
incubator-htrace git commit: HTRACE-131. Port spans.js in
htrace-hbase to htraced (Masatake Iwasaki via Colin P. McCabe)
Repository: incubator-htrace
Updated Branches:
refs/heads/master 2f86d169e -> 8f2c9576c
HTRACE-131. Port spans.js in htrace-hbase to htraced (Masatake Iwasaki via Colin P. McCabe)
Project: http://git-wip-us.apache.org/repos/asf/incubator-htrace/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-htrace/commit/8f2c9576
Tree: http://git-wip-us.apache.org/repos/asf/incubator-htrace/tree/8f2c9576
Diff: http://git-wip-us.apache.org/repos/asf/incubator-htrace/diff/8f2c9576
Branch: refs/heads/master
Commit: 8f2c9576cb5eb4cff11a640c132cc9b835430936
Parents: 2f86d16
Author: Colin Patrick Mccabe <cm...@cloudera.com>
Authored: Mon Mar 16 17:06:13 2015 -0700
Committer: Colin P. Mccabe <cm...@apache.org>
Committed: Mon Mar 16 17:09:17 2015 -0700
----------------------------------------------------------------------
htrace-core/src/web/app/setup.js | 13 +-
.../src/web/app/views/details/details.js | 8 +
.../src/web/app/views/swimlane/swimlane.js | 178 +++++++++++++++++++
htrace-core/src/web/index.html | 13 ++
4 files changed, 211 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/8f2c9576/htrace-core/src/web/app/setup.js
----------------------------------------------------------------------
diff --git a/htrace-core/src/web/app/setup.js b/htrace-core/src/web/app/setup.js
index d210ea6..90915e3 100644
--- a/htrace-core/src/web/app/setup.js
+++ b/htrace-core/src/web/app/setup.js
@@ -29,7 +29,9 @@ var Router = Backbone.Marionette.AppRouter.extend({
"routes": {
"": "init",
"!/search(/:query)": "search",
- "!/spans/:id": "span"
+ "!/spans/:id": "span",
+ "!/swimlane/:id": "swimlane",
+ "!/swimlane/:id:?:lim": "swimlane"
},
"initialize": function() {
@@ -131,6 +133,15 @@ var Router = Backbone.Marionette.AppRouter.extend({
"el": top.content.$el[0],
"id": "span-" + id
}));
+ },
+
+ "swimlane": function(id, lim) {
+ var top = new app.SwimlaneView();
+ app.root.app.show(top);
+ top.swimlane.show(new app.SwimlaneGraphView({
+ "spanId": id,
+ "lim": lim
+ }));
}
});
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/8f2c9576/htrace-core/src/web/app/views/details/details.js
----------------------------------------------------------------------
diff --git a/htrace-core/src/web/app/views/details/details.js b/htrace-core/src/web/app/views/details/details.js
index 2a2b9f4..2f79e1b 100644
--- a/htrace-core/src/web/app/views/details/details.js
+++ b/htrace-core/src/web/app/views/details/details.js
@@ -35,5 +35,13 @@ app.SpanDetailsView = Backbone.Marionette.ItemView.extend({
};
context["span"]["duration"] = this.model.duration();
return context;
+ },
+
+ "events": {
+ "click": "swimlane"
+ },
+ "swimlane": function() {
+ Backbone.history.navigate("!/swimlane/" + this.model.get("spanId"),
+ {"trigger": true});
}
});
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/8f2c9576/htrace-core/src/web/app/views/swimlane/swimlane.js
----------------------------------------------------------------------
diff --git a/htrace-core/src/web/app/views/swimlane/swimlane.js b/htrace-core/src/web/app/views/swimlane/swimlane.js
new file mode 100644
index 0000000..878e2d0
--- /dev/null
+++ b/htrace-core/src/web/app/views/swimlane/swimlane.js
@@ -0,0 +1,178 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+app.SwimlaneView = Backbone.Marionette.LayoutView.extend({
+ "template": "#swimlane-layout-template",
+ "regions": {
+ "swimlane": "div[role='complementary']",
+ "content": "div[role='main']"
+ }
+});
+
+app.SwimlaneGraphView = Backbone.Marionette.View.extend({
+ className: "swimlane",
+
+ initialize: function() {
+ this.spans = this.getSpans(0, [],
+ this.getJsonSync("/span/" + this.options.spanId),
+ this.options.lim || "lim=100",
+ this.getJsonSync);
+ },
+
+ render: function() {
+ this.appendSVG(this.spans);
+ },
+
+ getSpans: function getSpans(depth, spans, span, lim, getJSON) {
+ span.depth = depth;
+ spans.push(span);
+ var children = [];
+ getJSON("/span/" + span.s + "/children?" + lim).forEach(function(childId) {
+ children.push(getJSON("/span/" + childId));
+ });
+ children.sort(function(x, y) {
+ return x.b < y.b ? -1 : x.b > y.b ? 1 : 0;
+ });
+ children.forEach(function(child) {
+ spans = getSpans(depth + 1, spans, child, lim, getJSON);
+ });
+ return spans;
+ },
+
+ getJsonSync: function getJsonSync(url) {
+ return $.ajax({
+ type: "GET",
+ url: url,
+ async: false,
+ dataType: "json"
+ }).responseJSON;
+ },
+
+ appendSVG: function appendSVG(spans) {
+ const height_span = 20;
+ const width_span = 700;
+ const size_tl = 6;
+ const margin = {top: 50, bottom: 50, left: 20, right: 1000, process: 300};
+
+ var height_screen = spans.length * height_span;
+ var dmax = d3.max(spans, function(s) { return s.depth; });
+ var tmin = d3.min(spans, function(s) { return s.b; });
+ var tmax = d3.max(spans, function(s) { return s.e; });
+ var xscale = d3.time.scale()
+ .domain([new Date(tmin), new Date(tmax)]).range([0, width_span]);
+
+ var svg = d3.select("div[role='main']").append("svg")
+ .attr("width", width_span + margin.process + margin.left + margin.right)
+ .attr("height", height_screen + margin.top + margin.bottom)
+ .append("g")
+ .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
+
+ var bars = svg.append("g")
+ .attr("id", "bars")
+ .attr("width", width_span)
+ .attr("height", height_screen)
+ .attr("transform", "translate(" + (10 * dmax + margin.process) + ", 0)");
+
+ var span_g = bars.selectAll("g.span")
+ .data(spans)
+ .enter()
+ .append("g")
+ .attr("transform", function(s, i) {
+ return "translate(0, " + (i * height_span + 5) + ")";
+ })
+ .classed("timeline", function(d) { return d.t; });
+
+ span_g.append("text")
+ .text(function(s) { return s.r; })
+ .style("alignment-baseline", "hanging")
+ .style("font-size", "14px")
+ .attr("transform", function(s) {
+ return "translate(" + (s.depth * 10 - margin.process - 10 * dmax) + ", 0)";
+ });
+
+ var rect_g = span_g.append("g")
+ .attr("transform", function(s) {
+ return "translate(" + xscale(new Date(s.b)) + ", 0)";
+ });
+
+ rect_g.append("rect")
+ .attr("height", height_span - 1)
+ .attr("width", function (s) {
+ return (width_span * (s.e - s.b)) / (tmax - tmin) + 1;
+ })
+ .style("fill", "lightblue")
+ .attr("class", "span")
+
+ rect_g.append("text")
+ .text(function(s){ return s.d; })
+ .style("alignment-baseline", "hanging")
+ .style("font-size", "14px");
+
+ rect_g.append("text")
+ .text(function(s){ return s.e - s.b; })
+ .style("alignment-baseline", "baseline")
+ .style("text-anchor", "end")
+ .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.t; })
+ .enter()
+ .append("rect")
+ .style("fill", "red")
+ .attr("height", size_tl)
+ .attr("width", size_tl)
+ .attr("transform", function(t) {
+ return "translate(" + xscale(t.t) + "," + (height_span - 1 - size_tl) + ")";
+ })
+ .classed("timeline");
+
+ var popup = d3.select("div[role='main']").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.t.forEach(function (t) {
+ text += "<tr><td>" + (t.t - tmin) + "</td>";
+ text += "<td> : " + t.m + "<td/></tr>";
+ });
+ text += "</table>"
+ popup.html(text)
+ .style("left", (document.body.scrollLeft + 50) + "px")
+ .style("top", (document.body.scrollTop + 70) + "px")
+ .style("width", "700px")
+ .style("background", "orange")
+ .style("position", "absolute");
+ })
+ .on("mouseout", function(d) {
+ popup.transition().duration(300).style("opacity", 0);
+ });
+
+ var axis = d3.svg.axis()
+ .scale(xscale)
+ .orient("top")
+ .tickValues(xscale.domain())
+ .tickFormat(d3.time.format("%x %X.%L"))
+ .tickSize(6, 3);
+
+ bars.append("g").attr("class", "axis").call(axis);
+ }
+});
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/8f2c9576/htrace-core/src/web/index.html
----------------------------------------------------------------------
diff --git a/htrace-core/src/web/index.html b/htrace-core/src/web/index.html
index ecb0d7e..bcfea19 100644
--- a/htrace-core/src/web/index.html
+++ b/htrace-core/src/web/index.html
@@ -164,6 +164,18 @@
</table>
</script>
+ <script id="swimlane-layout-template" type="text/html">
+ <div class="container-fluid" id="list" role="application">
+ <div class="row">
+ <div class="col-md-12" role="main"></div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-12" role="complementary"></div>
+ </div>
+ </div>
+ </script>
+
<script src="lib/js/jquery-2.1.3.min.js" type="text/javascript"></script>
<script src="lib/js/d3-3.5.5.js" type="text/javascript"></script>
<script src="lib/bootstrap-3.3.1/js/bootstrap.min.js" type="text/javascript"></script>
@@ -182,6 +194,7 @@
<script src="app/views/search/field.js" type="text/javascript"></script>
<script src="app/views/search/search.js" type="text/javascript"></script>
<script src="app/views/details/details.js" type="text/javascript"></script>
+ <script src="app/views/swimlane/swimlane.js" type="text/javascript"></script>
<script src="app/setup.js" type="text/javascript"></script>
</body>
</html>