| OLD | NEW |
| (Empty) |
| 1 <!-- | |
| 2 Copyright 2014 The Chromium Authors. All rights reserved. | |
| 3 Use of this source code is governed by a BSD-style license that can be | |
| 4 found in the LICENSE file. | |
| 5 --> | |
| 6 | |
| 7 <link rel="import" href="../lib/dygraph.html"> | |
| 8 <link rel="import" href="../lib/log.html"> | |
| 9 <link rel="import" href="../model/cq-graph-item.html"> | |
| 10 <link rel="import" href="./tom-cq-graph-item.html"> | |
| 11 | |
| 12 <polymer-element name="tom-cq-graph" attributes="graph"> | |
| 13 <template> | |
| 14 <style> | |
| 15 ul, .loading { | |
| 16 font-weight: bold; | |
| 17 } | |
| 18 tom-cq-graph-item { | |
| 19 font-weight: normal; | |
| 20 } | |
| 21 #graphContainer { | |
| 22 position: relative; | |
| 23 height: 200px; | |
| 24 } | |
| 25 #graphDiv { | |
| 26 position: absolute; | |
| 27 left: 0; | |
| 28 top: 0; | |
| 29 right: 0; | |
| 30 bottom: 0; | |
| 31 } | |
| 32 </style> | |
| 33 <h2>{{ graph.heading }}</h2> | |
| 34 <template if="{{ _hasAlerts() }}"> | |
| 35 Alert thresholds: {{ _alertText() }} | |
| 36 </template> | |
| 37 <div id="graphContainer"><div id="graphDiv"></div></div> | |
| 38 <ul> | |
| 39 <template if="{{ _list.length }}"> | |
| 40 Worst patches between {{ _listBegin }} and {{ _listEnd }}: | |
| 41 </template> | |
| 42 <template repeat="{{ item in _list }}"> | |
| 43 <tom-cq-graph-item item="{{ item }}"></tom-cq-graph-item> | |
| 44 </template> | |
| 45 </ul> | |
| 46 <template if="{{ _loading }}"><span class="loading">Loading...</span></templ
ate> | |
| 47 </template> | |
| 48 <script> | |
| 49 (function() { | |
| 50 Polymer({ | |
| 51 ready: function() { | |
| 52 this._list = []; | |
| 53 this._loading = true; | |
| 54 this._dygraph = null; | |
| 55 var self = this; | |
| 56 this.graph.data.get().then(function(data) { | |
| 57 self._loading = false; | |
| 58 self._drawGraph(data); | |
| 59 }).catch(log); | |
| 60 this.$.graphDiv.addEventListener('click', | |
| 61 this._onGraphClick.bind(this)); | |
| 62 }, | |
| 63 _drawGraph: function(data) { | |
| 64 this._dygraph = new Dygraph(this.$.graphDiv, data.rows, { | |
| 65 labels: data.cols, | |
| 66 legend: 'always', | |
| 67 highlightSeriesOpts: { | |
| 68 strokeWidth: 3, | |
| 69 highlightCircleSize: 4, | |
| 70 }, | |
| 71 highlightSeriesBackgroundAlpha: 1, | |
| 72 hideOverlayOnMouseOut: false, | |
| 73 ylabel: this.graph.unit, | |
| 74 strokeWidth: 2, | |
| 75 colors: ['purple', 'orange', 'lightblue', 'green', 'black'], | |
| 76 underlayCallback: this._onGraphDrawUnderlay.bind(this), | |
| 77 }); | |
| 78 // Overwrite default white legend background to be translucent. | |
| 79 var legend = this.$.graphDiv.querySelector('.dygraph-legend'); | |
| 80 legend.style.backgroundColor = 'rgba(255, 255, 255, 0.8)'; | |
| 81 }, | |
| 82 _onGraphClick: function() { | |
| 83 if (!this._dygraph || !this.graph.data.rowItemsAvailable) { | |
| 84 return; | |
| 85 } | |
| 86 this._list = []; | |
| 87 var row = this._dygraph.getSelection(); | |
| 88 if (row !== -1) { | |
| 89 this._loading = true; | |
| 90 var self = this; | |
| 91 this.graph.data.rowItems(row).then(function(rowItems) { | |
| 92 self._loading = false; | |
| 93 self._list = rowItems.items.map(function(item) { | |
| 94 var itemValue = item[0]; | |
| 95 var itemRef = item[1]; | |
| 96 return new CQGraphItem(itemValue, self.graph.itemUnit, | |
| 97 itemRef.issue, itemRef.patchset, | |
| 98 self.graph.itemAlertThreshold); | |
| 99 }); | |
| 100 self._listBegin = rowItems.begin; | |
| 101 self._listEnd = rowItems.end; | |
| 102 }).catch(log); | |
| 103 } | |
| 104 }, | |
| 105 _onGraphDrawUnderlay: function(context, area, dygraph) { | |
| 106 var self = this; | |
| 107 Object.keys(this.graph.alerts, function(col, threshold) { | |
| 108 self.graph.breachedItems(col, threshold).then(function(items) { | |
| 109 context.strokeStyle = 'red'; | |
| 110 context.lineWidth = 5; | |
| 111 context.lineCap = 'round'; | |
| 112 context.beginPath(); | |
| 113 var radius = 6; | |
| 114 items.forEach(function(item) { | |
| 115 var x = dygraph.toDomXCoord(item.timestamp); | |
| 116 var valueY = dygraph.toDomYCoord(item.value); | |
| 117 var thresholdY = Math.max( | |
| 118 dygraph.toDomYCoord(threshold), valueY + radius); | |
| 119 context.moveTo(x, thresholdY); | |
| 120 context.lineTo(x, valueY + radius); | |
| 121 context.arc(x, valueY, radius, Math.PI * 0.5, Math.PI * 2.5); | |
| 122 }); | |
| 123 context.stroke(); | |
| 124 }); | |
| 125 }); | |
| 126 }, | |
| 127 _hasAlerts: function() { | |
| 128 return Object.keys(this.graph.alerts).length > 0; | |
| 129 }, | |
| 130 _alertText: function() { | |
| 131 var items = []; | |
| 132 var unit = this.graph.unit; | |
| 133 Object.keys(this.graph.alerts, function(col, threshold) { | |
| 134 items.push('{1} ≥ {2} {3}'.assign(col, threshold, unit)); | |
| 135 }); | |
| 136 return items.join(', '); | |
| 137 }, | |
| 138 }); | |
| 139 })(); | |
| 140 </script> | |
| 141 </polymer-element> | |
| OLD | NEW |