1 <!DOCTYPE html> 2 <!-- 3 Copyright 2016 The Chromium Authors. All rights reserved. 4 Use of this source code is governed by a BSD-style license that can be 5 found in the LICENSE file. 6 --> 7 <!-- 8 The chart-tooltip element is the box that is shown when you hover over or click 9 on a point on a graph. It shows more detailed information about the point that 10 was just clicked. 11 --> 12 13 <link rel="import" href="/components/paper-dialog/paper-action-dialog.html"> 14 15 <link rel="import" href="/dashboard/elements/alert-remove-box.html"> 16 <link rel="import" href="/dashboard/elements/bisect-button.html"> 17 <link rel="import" href="/dashboard/elements/trace-button.html"> 18 <link rel="import" href="/dashboard/elements/triage-dialog.html"> 19 20 <polymer-element 21 name="chart-tooltip" 22 attributes="testPath value bugId pointId revisions links alerts xsrfToken"> 23 <template> 24 <style> 25 #container { 26 position: absolute; 27 margin: 20px; 28 } 29 30 #tooltip { 31 position: relative; 32 margin: 0px; 33 padding: 0px; 34 } 35 </style> 36 37 <div id="container"> 38 <triage-dialog id="triage" 39 xsrfToken="{{xsrfToken}}" 40 alerts="{{alerts}}"></triage-dialog> 41 42 <paper-action-dialog id="tooltip" layered="false" autoCloseDisabled="true"> 43 <style> 44 #test-name { 45 width : 300px; 46 word-wrap: break-word; 47 } 48 49 div:not(:last-of-type) { 50 margin-bottom: 15px; 51 } 52 </style> 53 54 <!-- TODO(qyearsley): Either (1) Display alert details on mouse-over as 55 well as click (The alerts attribute is only set currently on click, 56 not on hover) OR (2) Display alert details in the triage dialog. --> 57 <template bind repeat="{{alerts}}"> 58 <div class="important"> 59 <b>Alert information:</b><br> 60 Median of segment before: {{median_before_anomaly}}<br> 61 Median of segment after: {{median_after_anomaly}}<br> 62 Relative change: {{percent_changed}}<br> 63 </div> 64 </template> 65 66 <div id="test-name"> 67 Test: {{parentPath}}/<b>{{seriesName}}</b> 68 </div> 69 70 <div> 71 Value: <b>{{value}}</b> <span hidden?={{!stddev}}>( {{stddev}})</span> 72 </div> 73 74 <div> 75 <span hidden?={{!pointId}}>Point ID: {{pointId}}</span><br> 76 <span hidden?={{!timestamp}}>Time added: {{timestamp}}</span> 77 </div> 78 79 <template bind if="{{bugId}}"> 80 <div> 81 <span hidden?={{alertInvalidOrIgnored}}>Bug ID: 82 <b><a target="_blank" href="http://crbug.com/{{bugId}}">{{bugId}}</a></b> 83 </span> 84 85 <span hidden?="{{bugId != -1}}">Invalid alert</span> 86 <span hidden?="{{bugId != -2}}">Ignored alert</span> 87 <span hidden?="{{!recovered}}">Recovered alert</span> 88 <alert-remove-box key="{{alertKey}}" xsrfToken="{{xsrfToken}}" on-untriaged="{{onUntriaged}}"> 89 </alert-remove-box><br> 90 <a href="/group_report?keys={{alertKey}}">View alert graph</a> 91 </div> 92 </template> 93 94 <div> 95 <template repeat={{revisions}}> 96 {{name}}<template bind if="{{start}}"> range</template>: 97 <b> 98 <a href="{{url}}" on-click="{{onRevisionRangeClick}}"> 99 <template bind if="{{start}}">{{displayStart}} - </template> 100 {{displayEnd}} 101 </a> 102 </b><br> 103 </template> 104 </div> 105 106 <div> 107 <template repeat={{links}}> 108 <span class="annotation-link"><a href="{{url}}" target="_blank">{{text}}</a></span><br /> 109 </template> 110 </div> 111 112 <bisect-button affirmative xsrfToken="{{xsrfToken}}" 113 bugId="{{bugId}}" 114 bisectInfo="{{bisectInfo}}"></bisect-button> 115 <trace-button affirmative xsrfToken="{{xsrfToken}}" 116 bugId="{{bugId}}" 117 traceInfo="{{bisectInfo}}"></trace-button> 118 119 </paper-action-dialog> 120 </div> 121 </template> 122 <script> 123 'use strict'; 124 Polymer('chart-tooltip', { 125 traceName: null, 126 value: null, 127 stddev: null, 128 hideStddev: true, 129 bugId: null, 130 stdioUri: null, 131 hideStdioUri: true, 132 revisions: [], 133 134 ready: function() { 135 // This allows tooltip to show beyond the current window size. 136 // Our tooltip size is determined by 'sizingTarget' which is default to 137 // the window size. Here we set it to '#scroller' which is the 138 // content's container. 139 // 'core-overlay' API: 140 // https://github.com/Polymer/core-overlay/blob/master/core-overlay.html 141 // 142 // Note: Though this deep shadow DOM selector was deprecated, it was 143 // a solution in Polymer 0.5 to customize elements. This can be done 144 // using custom CSS properties when migrating to Polymer 1.0. 145 this.$.tooltip.sizingTarget = document.querySelector( 146 'html /deep/ paper-action-dialog::shadow #scroller'); 147 148 // We're going to call 'open' tooltip and hide it's container on 149 // 'ready' to avoid 'core-overlay' initial element focus which causes 150 // the page to jump. 151 // TODO(chrisphan): Figure out a better way to do this. 152 this.$.container.hidden = true; 153 this.$.tooltip.open(); 154 }, 155 156 testPathChanged: function() { 157 if (this.testPath) { 158 var parts = this.testPath.split('/'); 159 this.seriesName = parts.pop(); 160 this.parentPath = parts.join('/'); 161 } 162 }, 163 164 /** 165 * Shows the CL descriptions for the given revision range. 166 */ 167 onRevisionRangeClick: function(event, detail, sender) { 168 window.open(sender.href, 'changelog', 'width=1000,height=1000'); 169 event.preventDefault(); 170 }, 171 172 /** 173 * Updates the display of the triage-dialog. 174 * This method is called whenever the value of this.alerts changes, 175 * e.g. by chart-container when an alert is triaged. 176 */ 177 alertsChanged: function() { 178 // The triage-dialog should be shown when there is some non-triaged 179 // alert, and hidden otherwise. 180 if (this.alerts && this.alerts.length) { 181 this.$.triage.show(); 182 } else { 183 this.$.triage.close(); 184 } 185 }, 186 187 /** 188 * Fires a 'triaged' event, which should be caught in chart-container. 189 */ 190 onUntriaged: function(event, detail, sender) { 191 this.fire('triaged', { 192 'alerts': this.triagedAlerts, 193 'bugid': null 194 }); 195 }, 196 197 open: function() { 198 if (this.closeTooltipJob) { 199 this.closeTooltipJob.stop(); 200 } 201 this.$.tooltip.open(); 202 this.$.container.hidden = false; 203 }, 204 205 close: function() { 206 // Add a short delay before closing as a workaround for a bug in 207 // core-overlay where core-overlay is opened and closed too frequent. 208 // See: https://github.com/dart-lang/paper-elements/issues/83" 209 this.closeTooltipJob = this.job( 210 this.closeTooltipJob, 211 function() { 212 this.$.container.hidden = true; 213 }, 214 200); 215 }, 216 217 setPosition: function(top, left) { 218 this.$.container.style.top = top + 'px'; 219 this.$.container.style.left = left + 'px'; 220 } 221 }); 222 </script> 223 </polymer-element> 224