OLD | NEW |
(Empty) | |
| 1 <link rel="import" href="../polymer/polymer.html"> |
| 2 <link rel="import" href="../iron-ajax/iron-ajax.html"> |
| 3 <link rel="import" href="../google-apis/google-legacy-loader.html"> |
| 4 |
| 5 <!-- |
| 6 `google-chart` encapsulates Google Charts as a web component, allowing you to ea
sily visualize |
| 7 data. From simple line charts to complex hierarchical tree maps, the chart eleme
nt provides a |
| 8 number of ready-to-use chart types. |
| 9 |
| 10 <google-chart |
| 11 type='pie' |
| 12 options='{"title": "Distribution of days in 2001Q1"}' |
| 13 cols='[{"label":"Month", "type":"string"}, {"label":"Days", "type":"number
"}]' |
| 14 rows='[["Jan", 31],["Feb", 28],["Mar", 31]]'> |
| 15 </google-chart> |
| 16 |
| 17 Height and width are specified as style attributes: |
| 18 |
| 19 google-chart { |
| 20 height: 300px; |
| 21 width: 50em; |
| 22 } |
| 23 |
| 24 Data can be provided in one of three ways: |
| 25 |
| 26 - Via the `cols` and `rows` attributes: |
| 27 |
| 28 cols='[{"label":"Mth", "type":"string"}, {"label":"Days", "type":"number"}
]' |
| 29 rows='[["Jan", 31],["Feb", 28],["Mar", 31]]' |
| 30 |
| 31 - Via the `data` attribute, passing in the data directly: |
| 32 |
| 33 data='[["Month", "Days"], ["Jan", 31], ["Feb", 28], ["Mar", 31]]' |
| 34 |
| 35 - Via the `data` attribute, passing in the URL to a resource containing the |
| 36 data, in JSON format: |
| 37 |
| 38 data='http://example.com/chart-data.json' |
| 39 @demo |
| 40 --> |
| 41 <dom-module id="google-chart"> |
| 42 <link rel="import" type="css" href="google-chart.css"> |
| 43 <template> |
| 44 <iron-ajax id="ajax" handle-as="json" url="{{data}}" |
| 45 on-response="_externalDataLoaded"></iron-ajax> |
| 46 <div id="chartdiv"></div> |
| 47 <google-legacy-loader on-api-load="_readyForAction"></google-legacy-loader> |
| 48 </template> |
| 49 </dom-module> |
| 50 |
| 51 <script> |
| 52 (function() { |
| 53 "use strict"; |
| 54 |
| 55 Polymer({ |
| 56 |
| 57 is: 'google-chart', |
| 58 |
| 59 /** |
| 60 * Fired when the graph is displayed. |
| 61 * |
| 62 * @event google-chart-render |
| 63 */ |
| 64 |
| 65 /** |
| 66 * Fired when the user makes a selection in the chart. |
| 67 * |
| 68 * @event google-chart-select |
| 69 * @param {object} detail |
| 70 * @param {array} detail.selection The user-defined selection. |
| 71 */ |
| 72 |
| 73 properties: { |
| 74 /** |
| 75 * Sets the type of the chart. |
| 76 * |
| 77 * Should be one of: |
| 78 * - `area`, `bar`, `bubble`, `candlestick`, `column`, `combo`, `geo`, |
| 79 * `histogram`, `line`, `pie`, `scatter`, `stepped-area` |
| 80 * |
| 81 * See <a href="https://google-developers.appspot.com/chart/interactive/do
cs/gallery">Google Visualization API reference (Chart Gallery)</a> for details. |
| 82 * |
| 83 */ |
| 84 type: { |
| 85 type: String, |
| 86 value: 'column', |
| 87 observer: '_typeChanged' |
| 88 }, |
| 89 |
| 90 /** |
| 91 * Sets the options for the chart. |
| 92 * |
| 93 * Example: |
| 94 * <pre>{ |
| 95 * title: "Chart title goes here", |
| 96 * hAxis: {title: "Categories"}, |
| 97 * vAxis: {title: "Values", minValue: 0, maxValue: 2}, |
| 98 * legend: "none" |
| 99 * };</pre> |
| 100 * See <a href="https://google-developers.appspot.com/chart/interactive/do
cs/gallery">Google Visualization API reference (Chart Gallery)</a> |
| 101 * for the options available to each chart type. |
| 102 * |
| 103 */ |
| 104 options: { |
| 105 type: Object, |
| 106 value: function() { return {}; } |
| 107 }, |
| 108 |
| 109 /** |
| 110 * Sets the data columns for this object. |
| 111 * |
| 112 * When specifying data with `cols` you must also specify `rows`, and |
| 113 * not specify `data`. |
| 114 * |
| 115 * Example: |
| 116 * <pre>[{label: "Categories", type: "string"}, |
| 117 * {label: "Value", type: "number"}]</pre> |
| 118 * See <a href="https://google-developers.appspot.com/chart/interactive/do
cs/reference#DataTable_addColumn">Google Visualization API reference (addColumn)
</a> |
| 119 * for column definition format. |
| 120 * |
| 121 * @attribute cols |
| 122 * @type array |
| 123 */ |
| 124 cols: { |
| 125 type: Array, |
| 126 value: function() { return []; } |
| 127 }, |
| 128 /** |
| 129 * Sets the data rows for this object. |
| 130 * |
| 131 * When specifying data with `rows` you must also specify `cols`, and |
| 132 * not specify `data`. |
| 133 * |
| 134 * Example: |
| 135 * <pre>[["Category 1", 1.0], |
| 136 * ["Category 2", 1.1]]</pre> |
| 137 * See <a href="https://google-developers.appspot.com/chart/interactive/do
cs/reference#addrow">Google Visualization API reference (addRow)</a> |
| 138 * for row format. |
| 139 * |
| 140 * @attribute rows |
| 141 * @type array |
| 142 */ |
| 143 rows: { |
| 144 type: Array, |
| 145 value: function() { return []; } |
| 146 }, |
| 147 |
| 148 /** |
| 149 * Sets the entire dataset for this object. |
| 150 * Can be used to provide the data directly, or to provide a URL from |
| 151 * which to request the data. |
| 152 * |
| 153 * The data format can be a two-dimensional array or the DataTable format |
| 154 * expected by Google Charts. |
| 155 * See <a href="https://google-developers.appspot.com/chart/interactive/do
cs/reference#DataTable">Google Visualization API reference (DataTable constructo
r)</a> |
| 156 * for data table format details. |
| 157 * |
| 158 * When specifying data with `data` you must not specify `cols` or `rows`. |
| 159 * |
| 160 * Example: |
| 161 * <pre>[["Categories", "Value"], |
| 162 * ["Category 1", 1.0], |
| 163 * ["Category 2", 1.1]]</pre> |
| 164 * |
| 165 * @attribute data |
| 166 * @type array, object, or string |
| 167 */ |
| 168 data: { |
| 169 type: Object, // or array, or object |
| 170 value: function() { return []; } |
| 171 }, |
| 172 |
| 173 /** |
| 174 * Selected datapoint(s) in the map. |
| 175 * |
| 176 * An array of objects, each with a numeric row and/or column property. |
| 177 * `row` and `column` are the zero-based row or column number of an item |
| 178 * in the data table to select. |
| 179 * |
| 180 * To select a whole column, set row to null; |
| 181 * to select a whole row, set column to null. |
| 182 * |
| 183 * Example: |
| 184 * <pre> |
| 185 * [{row:0,column:1}, {row:1, column:null}] |
| 186 * </pre> |
| 187 * |
| 188 * @attribute selection |
| 189 * @type array |
| 190 */ |
| 191 selection: { |
| 192 type: Array, |
| 193 value: function() { return []; }, |
| 194 observer: '_selectionChanged' |
| 195 }, |
| 196 }, |
| 197 |
| 198 observers: [ |
| 199 '_loadData(rows, cols, data)' |
| 200 ], |
| 201 |
| 202 _packages: null, |
| 203 |
| 204 _chartObject: null, |
| 205 |
| 206 _isReady: false, |
| 207 |
| 208 _canDraw: false, |
| 209 |
| 210 _dataTable: null, |
| 211 |
| 212 _chartTypes: null, |
| 213 |
| 214 _readyForAction: function(e, detail, sender) { |
| 215 this._loadPackageByChartType(); |
| 216 |
| 217 google.load("visualization", "1", { |
| 218 packages: this._packages[this.type], |
| 219 callback: function() { |
| 220 this._isReady = true; |
| 221 this._loadChartTypes(); |
| 222 this._loadData(); |
| 223 }.bind(this) |
| 224 }); |
| 225 }, |
| 226 |
| 227 _typeChanged: function() { |
| 228 // Invalidate current chart object. |
| 229 this._chartObject = null; |
| 230 this._loadData(); |
| 231 }, |
| 232 |
| 233 _selectionChanged: function() { |
| 234 if (this._chartObject && this.setSelection) { |
| 235 this._chartObject.setSelection(this.selection); |
| 236 } |
| 237 }, |
| 238 |
| 239 /** |
| 240 * Draws the chart. |
| 241 * |
| 242 * Called automatically on first load and whenever one of the attributes |
| 243 * changes. Can be called manually to handle e.g. page resizes. |
| 244 * |
| 245 * @method drawChart |
| 246 * @return {Object} Returns null. |
| 247 */ |
| 248 drawChart: function() { |
| 249 if (this._canDraw) { |
| 250 if (!this.options) { |
| 251 this.options = {}; |
| 252 } |
| 253 if (!this._chartObject) { |
| 254 var chartClass = this._chartTypes[this.type]; |
| 255 if (chartClass) { |
| 256 this._chartObject = new chartClass(this.$.chartdiv); |
| 257 } |
| 258 } |
| 259 if (this._chartObject) { |
| 260 google.visualization.events.addOneTimeListener(this._chartObject, |
| 261 'ready', function() { |
| 262 this.fire('google-chart-render'); |
| 263 }.bind(this)); |
| 264 |
| 265 google.visualization.events.addListener(this._chartObject, |
| 266 'select', function() { |
| 267 this.selection = this._chartObject.getSelection(); |
| 268 this.fire('google-chart-select', |
| 269 { selection: this._chartObject.getSelection() }); |
| 270 }.bind(this)); |
| 271 |
| 272 |
| 273 this._chartObject.draw(this._dataTable, this.options); |
| 274 |
| 275 if (this._chartObject.setSelection){ |
| 276 this._chartObject.setSelection(this.selection); |
| 277 } |
| 278 } else { |
| 279 this.$.chartdiv.innerHTML = 'Undefined chart type'; |
| 280 } |
| 281 } |
| 282 return null; |
| 283 }, |
| 284 |
| 285 _loadChartTypes: function() { |
| 286 this._chartTypes = { |
| 287 'area': google.visualization.AreaChart, |
| 288 'bar': google.visualization.BarChart, |
| 289 'bubble': google.visualization.BubbleChart, |
| 290 'candlestick': google.visualization.CandlestickChart, |
| 291 'column': google.visualization.ColumnChart, |
| 292 'combo': google.visualization.ComboChart, |
| 293 'geo': google.visualization.GeoChart, |
| 294 'histogram': google.visualization.Histogram, |
| 295 'line': google.visualization.LineChart, |
| 296 'pie': google.visualization.PieChart, |
| 297 'scatter': google.visualization.ScatterChart, |
| 298 'stepped-area': google.visualization.SteppedAreaChart, |
| 299 'table': google.visualization.Table, |
| 300 'gauge': google.visualization.Gauge |
| 301 }; |
| 302 }, |
| 303 |
| 304 _loadPackageByChartType: function() { |
| 305 this._packages = { |
| 306 'area': 'corechart', |
| 307 'bar': 'corechart', |
| 308 'bubble': 'corechart', |
| 309 'candlestick': 'corechart', |
| 310 'column': 'corechart', |
| 311 'combo': 'corechart', |
| 312 'geo': 'corechart', |
| 313 'histogram': 'corechart', |
| 314 'line': 'corechart', |
| 315 'pie': 'corechart', |
| 316 'scatter': 'corechart', |
| 317 'stepped-area': 'corechart', |
| 318 'table': 'table', |
| 319 'gauge': 'gauge' |
| 320 }; |
| 321 }, |
| 322 |
| 323 _loadData: function() { |
| 324 this._canDraw = false; |
| 325 if (this._isReady) { |
| 326 if (typeof this.data == 'string' || this.data instanceof String) { |
| 327 // Load data asynchronously, from external URL. |
| 328 this.$.ajax.generateRequest(); |
| 329 } else { |
| 330 var dataTable = this._createDataTable(); |
| 331 this._canDraw = true; |
| 332 if (dataTable) { |
| 333 this._dataTable = dataTable; |
| 334 this.drawChart(); |
| 335 } |
| 336 } |
| 337 } |
| 338 }, |
| 339 |
| 340 _externalDataLoaded: function(e) { |
| 341 var dataTable = this._createDataTable(e.detail.response); |
| 342 this._canDraw = true; |
| 343 this._dataTable = dataTable; |
| 344 this.drawChart(); |
| 345 }, |
| 346 |
| 347 _createDataTable: function(data) { |
| 348 var dataTable = null; |
| 349 |
| 350 // If a data object was not passed to this function, default to the |
| 351 // chart's data attribute. Passing a data object is necessary for |
| 352 // cases when the data attribute is a URL pointing to an external |
| 353 // data source. |
| 354 if (!data) { |
| 355 data = this.data; |
| 356 } |
| 357 if (!data) |
| 358 data = []; |
| 359 |
| 360 if (this.rows && this.rows.length > 0 && this.cols && |
| 361 this.cols.length > 0) { |
| 362 // Create the data table from cols and rows. |
| 363 dataTable = new google.visualization.DataTable(); |
| 364 dataTable.cols = this.cols; |
| 365 |
| 366 for (var i = 0; i < this.cols.length; i++) { |
| 367 dataTable.addColumn(this.cols[i]); |
| 368 } |
| 369 |
| 370 dataTable.addRows(this.rows); |
| 371 } else { |
| 372 // Create dataTable from the passed data or the data attribute. |
| 373 // Data can be in the form of raw DataTable data or a two |
| 374 // dimensional array. |
| 375 if (data.rows && data.cols) { |
| 376 dataTable = new google.visualization.DataTable(data); |
| 377 } else if (data.length > 0) { |
| 378 dataTable = google.visualization.arrayToDataTable(data); |
| 379 } |
| 380 } |
| 381 |
| 382 return dataTable; |
| 383 } |
| 384 }); |
| 385 })(); |
| 386 </script> |
OLD | NEW |