| OLD | NEW |
| (Empty) |
| 1 <!-- | |
| 2 # Copyright 2015 The LUCI Authors. All rights reserved. | |
| 3 # Use of this source code is governed under the Apache License, Version 2.0 | |
| 4 # that can be found in the LICENSE file. | |
| 5 | |
| 6 --> | |
| 7 | |
| 8 <!-- | |
| 9 @group Swarming Elements | |
| 10 | |
| 11 `stats-chart-base' encapsulates a 'google-chart' element and data formating | |
| 12 utility functions. | |
| 13 | |
| 14 @element stats-chart-base | |
| 15 --> | |
| 16 | |
| 17 | |
| 18 <link rel="import" href="bower_components/polymer/polymer.html"> | |
| 19 <link rel="import" href="bower_components/google-apis/google-jsapi.html"> | |
| 20 <link rel="import" href="bower_components/google-chart/google-chart.html"> | |
| 21 | |
| 22 <polymer-element name="stats-chart-base"> | |
| 23 <template> | |
| 24 <style> | |
| 25 google-chart { | |
| 26 width: 100%; | |
| 27 height: 250px; | |
| 28 } | |
| 29 </style> | |
| 30 <google-chart | |
| 31 id="chart" | |
| 32 type="line" | |
| 33 options='{"title": "", "animation": {"duration": 500, "easing": "out"}, "l
egend": {"position": "bottom"} }'> | |
| 34 </google-chart> | |
| 35 <google-jsapi on-api-load="{{readyForAction}}"></google-jsapi> | |
| 36 </template> | |
| 37 <script> | |
| 38 | |
| 39 (function() { | |
| 40 function formatToIsoUnit(val) { | |
| 41 for (var n = 0; val >= 1000; n++) { | |
| 42 val /= 1000; | |
| 43 } | |
| 44 // Enforce 2 decimals. | |
| 45 if (n > 0) { | |
| 46 val = val.toFixed(2); | |
| 47 } | |
| 48 return val + ISO_SUFFIXES[n]; | |
| 49 } | |
| 50 | |
| 51 var p = { | |
| 52 dataTable: null, | |
| 53 isReady: false, | |
| 54 resolution: 'hours', | |
| 55 titleText: '', | |
| 56 | |
| 57 observe: { | |
| 58 'data': 'loadData' | |
| 59 }, | |
| 60 | |
| 61 ready: function() { | |
| 62 // FIXME: I tried option='{"title": "{{titleText}}"" }'' | |
| 63 this.$.chart.options.title = this.titleText; | |
| 64 }, | |
| 65 | |
| 66 attachView: function(view) { | |
| 67 this.$.chart.setAttribute('data', view.toDataTable().toJSON()); | |
| 68 }, | |
| 69 | |
| 70 getKeyFormatter: function() { | |
| 71 if (this.resolution == 'days') { | |
| 72 return new google.visualization.DateFormat({pattern: 'yyyy/MM/dd'}); | |
| 73 } else { | |
| 74 return new google.visualization.DateFormat({pattern: 'MM/dd HH:mm'}); | |
| 75 } | |
| 76 }, | |
| 77 | |
| 78 formatDataColumnToIsoUnit: function(column) { | |
| 79 for (var i = 0; i < this.dataTable.getNumberOfRows(); i++) { | |
| 80 this.dataTable.setFormattedValue( | |
| 81 i, column, formatToIsoUnit(this.dataTable.getValue(i, column))); | |
| 82 } | |
| 83 }, | |
| 84 | |
| 85 populate: function() { | |
| 86 // override by subclass | |
| 87 }, | |
| 88 | |
| 89 readyForAction: function(e, detail, sender) { | |
| 90 google.load("visualization", "1", { | |
| 91 packages: ['corechart'], | |
| 92 callback: function() { | |
| 93 this.isReady = true; | |
| 94 this.loadData(); | |
| 95 }.bind(this) | |
| 96 }); | |
| 97 }, | |
| 98 | |
| 99 // Makes sure ALL custom formatting is removed. | |
| 100 resetFormattedData: function() { | |
| 101 for (var i = 0; i < this.dataTable.getNumberOfColumns(); i++) { | |
| 102 this.resetFormattedDataColumn(i); | |
| 103 } | |
| 104 }, | |
| 105 | |
| 106 // Makes sure custom formatting is removed for a specific column. | |
| 107 resetFormattedDataColumn: function(column) { | |
| 108 for (var i = 0; i < this.dataTable.getNumberOfRows(); i++) { | |
| 109 this.dataTable.setFormattedValue(i, column, null); | |
| 110 } | |
| 111 }, | |
| 112 | |
| 113 loadData: function() { | |
| 114 if (this.isReady && this.data) { | |
| 115 this.dataTable = new google.visualization.DataTable(this.data); | |
| 116 this.populate(); | |
| 117 } | |
| 118 } | |
| 119 }; | |
| 120 | |
| 121 Polymer('stats-chart-base', p); | |
| 122 })(); | |
| 123 | |
| 124 </script> | |
| 125 </polymer-element> | |
| OLD | NEW |