diff --git a/htrace-webapp/src/main/web/app/search_results_view.js b/htrace-webapp/src/main/web/app/search_results_view.js index 3f009d4..81197c3 100644 --- a/htrace-webapp/src/main/web/app/search_results_view.js +++ b/htrace-webapp/src/main/web/app/search_results_view.js @@ -96,6 +96,17 @@ htrace.SearchResultsView = Backbone.View.extend({ this.draw(); }, + handleDblclick: function(e) { + e.preventDefault(); + this.widgetManager.handle({ + type: "dblclick", + x: this.getCanvasX(e), + y: this.getCanvasY(e), + raw: e + }); + this.draw(); + }, + render: function() { console.log("SearchResultsView#render."); $(this.el).html(_.template($("#search-results-view-template").html())); @@ -259,6 +270,10 @@ htrace.SearchResultsView = Backbone.View.extend({ $("#resultsCanvas").on("mousemove", function(e) { view.handleMouseMove(e); }); + $("#resultsCanvas").off("dblclick"); + $("#resultsCanvas").on("dblclick", function(e) { + view.handleDblclick(e); + }); $("#resultsCanvas").off("contextmenu"); $("#resultsCanvas").on("contextmenu", function(e) { return false; @@ -269,7 +284,10 @@ htrace.SearchResultsView = Backbone.View.extend({ $(window).off("resize"); $("#resultsCanvas").off("mousedown"); $("#resultsCanvas").off("mouseup"); + $("#resultsCanvas").off("mouseout"); $("#resultsCanvas").off("mousemove"); + $("#resultsCanvas").off("dblclick"); + $("#resultsCanvas").off("contextmenu"); Backbone.View.prototype.remove.apply(this, arguments); }, diff --git a/htrace-webapp/src/main/web/app/span_widget.js b/htrace-webapp/src/main/web/app/span_widget.js index e06c8b4..1ef402c 100644 --- a/htrace-webapp/src/main/web/app/span_widget.js +++ b/htrace-webapp/src/main/web/app/span_widget.js @@ -19,7 +19,7 @@ var htrace = htrace || {}; -htrace.fillSpanDetailsView = function(span) { +htrace.showSpanDetails = function(span) { var info = { spanID: span.get("spanID"), begin: htrace.dateToString(span.get("begin"), 10), @@ -94,17 +94,12 @@ htrace.fillSpanDetailsView = function(span) { for (i = 0; i < len; i++) { // Make every other row grey to improve visibility. var colorString = ((i%2) == 1) ? "#f1f1f1" : "#ffffff"; - h += _.template('' + - '<%- key %>' + - '<%- val %>' + - "")({key: keys[i], val: info[keys[i]]}); + h += _.template($("#table-row-template").html())( + {bgcolor: colorString, key: keys[i], val: info[keys[i]]}); } h += ''; - $("#spanDetails").html(h); -}; - -htrace.clearSpanDetailsView = function() { - $("#spanDetails").html(""); + htrace.showModal(_.template($("#modal-table-template").html())( + {title: "Span Details", body: h})); }; // Widget containing the trace span displayed on the canvas. @@ -182,6 +177,17 @@ htrace.SpanWidget = function(params) { // ", begin=" + this.span.get('begin') + ", end=" + this.span.get('end')); this.ctx.fillRect(beginX, this.y0 + gapY, endX - beginX, this.ySize - (gapY * 2)); + + // Draw a dots showing time points where annotations are. + var annotations = this.span.get('timeAnnotations'); + var annotationY = this.y0 + gapY; + var annotationW = 4; + var annotationH = (this.ySize - (gapY * 2)) / 2; + this.ctx.fillStyle="#419641"; + for (var i = 0; i < annotations.length; i++) { + this.ctx.fillRect(this.timeToPosition(annotations[i].t), annotationY, + annotationW, annotationH); + } } // Draw description text @@ -209,45 +215,40 @@ htrace.SpanWidget = function(params) { return true; } if (e.raw.ctrlKey) { - // If the control key is pressed, we can unselect the current - // selection, or create multiple selections. + // If the control key is pressed, we toggle the current selection. + // The user can create multiple selections this way. if (this.span.get("selected")) { this.span.set("selected", false); } else { this.span.set("selected", true); } - var selection = null; - var multipleSelections = false; - this.manager.searchResultsView.applyToAllSpans(function(span) { - if (span.get("selected")) { - if (selection == null) { - selection = span; - } else { - multipleSelections = true; - } - } - }); - if (multipleSelections) { - selection = null; - } - if (selection == null) { - htrace.clearSpanDetailsView(); - } else { - htrace.fillSpanDetailsView(selection); - } } else { + var that = this; this.manager.searchResultsView.applyToAllSpans(function(span) { - if (span.get("selected")) { + // Note: we don't want to set the selection state unless we need + // to. Setting the state (even to the same thing it already is) + // triggers a full re-render, if the span is one in the results + // collection. A full re-render slows us down and disrupts events + // like double-clicking. + if (that.span === span) { + if (!span.get("selected")) { + span.set("selected", true); + } + } else if (span.get("selected")) { span.set("selected", false); } }); - this.span.set("selected", true); - htrace.fillSpanDetailsView(this.span); } return true; case "draw": this.draw(); return true; + case "dblclick": + if (htrace.inBoundingBox(e.x, e.y, + this.x0, this.xF, this.y0, this.yF)) { + htrace.showSpanDetails(this.span); + } + return true; } }; @@ -303,5 +304,6 @@ htrace.SpanWidget = function(params) { }); } this.manager.register("mouseDown", this); + this.manager.register("dblclick", this); return this; }; diff --git a/htrace-webapp/src/main/web/app/widget_manager.js b/htrace-webapp/src/main/web/app/widget_manager.js index 5f393b0..ae14b2b 100644 --- a/htrace-webapp/src/main/web/app/widget_manager.js +++ b/htrace-webapp/src/main/web/app/widget_manager.js @@ -32,6 +32,7 @@ htrace.WidgetManager = function(params) { "mouseUp": [], "mouseMove": [], "mouseOut": [], + "dblclick": [], "draw": [], }; diff --git a/htrace-webapp/src/main/web/index.html b/htrace-webapp/src/main/web/index.html index 0e8e6c3..77cbe09 100644 --- a/htrace-webapp/src/main/web/index.html +++ b/htrace-webapp/src/main/web/index.html @@ -92,14 +92,6 @@
-

Span Details

-
-
-
-
-
-
-

Search

@@ -197,6 +189,33 @@
+ + + +