diff --git a/app/js/directives/timeline-details.js b/app/js/directives/timeline-details.js index 02a23c5..98e0f0e 100644 --- a/app/js/directives/timeline-details.js +++ b/app/js/directives/timeline-details.js @@ -11,34 +11,12 @@ function timelineDetails() { * @ngInject */ var controller = function($scope) { - $scope.item = null; - - $scope.$watch('hoveredItem', function(value) { - if (value && !$scope.selectedItem) { - $scope.item = value; - } else if (!value && !$scope.selectedItem) { - $scope.item = null; - } - }); - - $scope.$watch('selectedItem', function(value) { - if (value) { - $scope.item = value; - } else { - if ($scope.hoveredItem) { - $scope.item = $scope.hoveredItem; - } else { - $scope.item = null; - } - } - }); }; return { restrict: 'EA', scope: { - 'hoveredItem': '=', - 'selectedItem': '=' + 'item': '=' }, controller: controller, templateUrl: 'directives/timeline-details.html' diff --git a/app/js/directives/timeline-viewport.js b/app/js/directives/timeline-viewport.js index 67d86f1..81cfae4 100644 --- a/app/js/directives/timeline-viewport.js +++ b/app/js/directives/timeline-viewport.js @@ -54,6 +54,14 @@ function timelineViewport($document) { .style('text-anchor', 'middle') .style('font', '9px sans-serif'); + var cursorItemText = cursorGroup.append('text') + .attr('x', 0) + .attr('y', -22) + .attr('dy', '-.5ex') + .style('text-anchor', 'middle') + .style('font', '12px sans-serif') + .style('font-weight', 'bold'); + var selectedRect = null; var color = function(rect, color) { @@ -79,26 +87,24 @@ function timelineViewport($document) { }; var rectMouseOver = function(d) { - if (selectedRect !== null) { - return; - } - timelineController.setHover(d); scope.$apply(); - color(d3.select(this), statusColorMap.hover); + if (!timelineController.selection + || d !== timelineController.selection.item) { + color(d3.select(this), statusColorMap.hover); + } }; var rectMouseOut = function(d) { - if (selectedRect !== null) { - return; - } - timelineController.clearHover(); scope.$apply(); - var self = d3.select(this); - uncolor(d3.select(this)); + if (!timelineController.selection + || d !== timelineController.selection.item) { + var self = d3.select(this); + uncolor(d3.select(this)); + } }; var rectClick = function(d) { @@ -240,6 +246,26 @@ function timelineViewport($document) { .attr('transform', 'translate(' + relX + ', 0)'); cursorText.text(d3.time.format('%X')(currentTime)); + + if (timelineController.hover) { + var name = timelineController.hover.name.split('.').pop(); + cursorItemText.text(name); + + var width = cursorItemText.node().getComputedTextLength(); + var leftEdge = margin.left; + var rightEdge = timelineController.width + margin.left; + + if (px + (width / 2) > rightEdge) { + cursorItemText.attr('dx', -(px - (rightEdge - width / 2))); + } else if (px - (width / 2) < leftEdge) { + cursorItemText.attr('dx', (leftEdge + width / 2) - px); + } else { + cursorItemText.attr('dx', 0); + } + } else { + cursorItemText.text(''); + cursorItemText.attr('dx', 0); + } } }); diff --git a/app/js/directives/timeline.js b/app/js/directives/timeline.js index 091d2a1..cf51b1e 100644 --- a/app/js/directives/timeline.js +++ b/app/js/directives/timeline.js @@ -42,7 +42,7 @@ function timeline($log, datasetService) { self.dataRaw = []; self.dstat = []; - self.margin = { top: 20, right: 10, bottom: 10, left: 80 }; + self.margin = { top: 40, right: 10, bottom: 10, left: 80 }; self.width = 0; self.height = 550 - this.margin.top - this.margin.bottom; diff --git a/app/views/directives/timeline-details.html b/app/views/directives/timeline-details.html index 2cd4e48..0033f2d 100644 --- a/app/views/directives/timeline-details.html +++ b/app/views/directives/timeline-details.html @@ -1,13 +1,27 @@ -<div class="panel-body" ng-if="!item"> - <i>Hover over a timeline item for details.</i> +<div ng-if="!item" class="panel panel-default"> + <div class="panel-heading"> + <h3 class="panel-title">Test Details</h3> + </div> + <div class="panel-body"> + <i>Select a test above for details.</i> + </div> </div> -<div class="panel-body" ng-if="!!item"> +<div ng-if="!!item" + class="panel" + ng-class="{'panel-success': item.status == 'success', 'panel-info': item.status == 'skip', 'panel-danger': item.status == 'fail'}"> + <div class="panel-heading"> + <h3 class="panel-title"> + Details: {{item.name | split:'.' | pickRight:1}} + <span class="label label-success" + ng-if="item.status == 'success'">success</span> + <span class="label label-info" + ng-if="item.status == 'skip'">skip</span> + <span class="label label-danger" + ng-if="item.status == 'fail'">fail</span> + </h3> + </div> <table class="table table-bordered table-hover table-striped"> - <tr> - <td>Name</td> - <td>{{item.name | split:'.' | pickRight:1}}</td> - </tr> <tr> <td>Class</td> <td>{{item.name | split:'.' | pickRight:2}}</td> @@ -15,17 +29,27 @@ <td>Module</td> <td>{{item.name | split:'.' | slice:0:-2 | join:'.'}}</td> </tr> - <tr> - <td>Status</td> - <td>{{item.status}}</td> - </tr> <tr> <td>Tags</td> <td>{{item.tags | join:', '}}</td> </tr> <tr> <td>Duration</td> - <td>{{item.duration}} seconds</td> + <td>{{item.duration | number:1}} seconds</td> + </tr> + <tr> + <td>Start</td> + <td>{{item.startDate | date:'medium'}}</td> + </tr> + <tr> + <td>End</td> + <td>{{item.endDate | date:'medium'}}</td> </tr> </table> + <div class="panel-footer clearfix"> + <div class="btn-group pull-right"> + <a type="button" + class="btn btn-default">Details</a> + </div> + </div> </div> diff --git a/app/views/timeline.html b/app/views/timeline.html index af17282..9d03a5e 100644 --- a/app/views/timeline.html +++ b/app/views/timeline.html @@ -16,12 +16,11 @@ </div> </div> <div class="row" ng-if="!timeline.error"> - <div class="col-lg-8"> + <div class="col-lg-12"> <div class="panel panel-default"> <div class="panel-heading"> - <h3 class="panel-title"><fa name="clock-o" fw></fa> Timeline</h3> + <h3 class="panel-title">Timeline</h3> </div> - <timeline class="panel-body" dataset="timeline.dataset" hovered-item="timeline.hoveredItem" @@ -33,15 +32,11 @@ </timeline> </div> </div> - <div class="col-lg-4"> - <div class="panel panel-default"> - <div class="panel-heading"> - <h3 class="panel-title"><fa name="info" fw></fa> Details</h3> - </div> - - <timeline-details hovered-item="timeline.hoveredItem" - selected-item="timeline.selectedItem"></timeline-details> - </div> + </div> + <div class="row"> + <div class="col-lg-12"> + <a name="details"></a> + <timeline-details item="timeline.selectedItem"></timeline-details> </div> </div> </div>