Index: polymer_1.0.4/bower_components/google-analytics/google-analytics-chart.html |
diff --git a/polymer_1.0.4/bower_components/google-analytics/google-analytics-chart.html b/polymer_1.0.4/bower_components/google-analytics/google-analytics-chart.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..dc2b156511269e3abb2d6dda9c9b1dc3332a6dd7 |
--- /dev/null |
+++ b/polymer_1.0.4/bower_components/google-analytics/google-analytics-chart.html |
@@ -0,0 +1,431 @@ |
+<link rel="import" href="../polymer/polymer.html"> |
+<link rel="import" href="../google-chart/google-chart.html"> |
+<link rel="import" href="../promise-polyfill/promise-polyfill-lite.html"> |
+<link rel="import" href="google-analytics-query.html"> |
+<link rel="import" href="google-analytics-loader.html"> |
+ |
+<!-- |
+Element for displaying the results of a Google Analytics query in a |
+Google Chart. |
+ |
+##### Example |
+ |
+ <google-analytics-chart |
+ type="column" |
+ ids="ga:1174" |
+ metrics="ga:sessions" |
+ dimensions="ga:country" |
+ sort="-ga:sessions" |
+ maxResults="5"> |
+ </google-analytics-chart> |
+ |
+@element google-analytics-chart |
+@demo |
+--> |
+ |
+<dom-module is="google-analytics-chart"> |
+ <template> |
+ <google-analytics-loader all-ready="{{setupReady}}"></google-analytics-loader> |
+ <google-analytics-query id="query" |
+ loading="{{loading}}" |
+ get-data-response-handler="{{_boundResponseHandler}}" |
+ data="{{data}}" |
+ ids="{{ids}}" |
+ start-date="{{startDate}}" |
+ end-date="{{endDate}}" |
+ metrics="{{metrics}}" |
+ dimensions="{{dimensions}}" |
+ sort="{{sort}}" |
+ filters="{{filters}}" |
+ segment="{{segment}}" |
+ sampling-level="{{samplingLevel}}" |
+ start-index="{{startIndex}}" |
+ max-results="{{maxResults}}" |
+ output="dataTable" |
+ src-param="gwc-ga-chart" |
+ ></google-analytics-query> |
+ <content select="header,h1,h2,h3,h4,h5,h6"></content> |
+ <google-chart id="chart" |
+ type="{{type}}" |
+ width="{{width}}" |
+ height="{{height}}" |
+ data="{{data.dataTable}}"> |
+ </google-chart> |
+ <content select="footer"></content> |
+ </template> |
+</dom-module> |
+ |
+<script> |
+ |
+ (function() { |
+ |
+ 'use strict'; |
+ |
+ Polymer({ |
+ |
+ is: 'google-analytics-chart', |
+ |
+ properties: { |
+ |
+ /** |
+ * Sets the type of the chart. |
+ * |
+ * Should be one of: |
+ * - `area`, `bar`, `column`, `line`, `pie`, `geo`. |
+ * |
+ * @attribute type |
+ * @default 'area' |
+ * @type string |
+ */ |
+ type: { |
+ type: String, |
+ value: 'area' |
+ }, |
+ |
+ /** |
+ * Sets the width of the chart on the page. |
+ * |
+ * @attribute width |
+ * @default 480 |
+ * @type number of string |
+ */ |
+ width: { |
+ type: Number, |
+ value: 480 |
+ }, |
+ |
+ /** |
+ * Sets the height of the chart on the page. |
+ * |
+ * @attribute height |
+ * @default 320 |
+ * @type number or string |
+ */ |
+ height: { |
+ type: Number, |
+ value: 320, |
+ }, |
+ |
+ /** |
+ * Sets the options for the chart. |
+ * |
+ * Example: |
+ * <pre>{ |
+ * title: "Chart title goes here", |
+ * hAxis: {title: "Categories"}, |
+ * vAxis: {title: "Values", minValue: 0, maxValue: 2}, |
+ * legend: "none" |
+ * };</pre> |
+ * See <a href="https://google-developers.appspot.com/chart/interactive/docs/gallery">Google Visualization API reference (Chart Gallery)</a> |
+ * for the options available to each chart type. |
+ * |
+ * @attribute options |
+ * @default null |
+ * @type object |
+ */ |
+ options: { |
+ type: Object, |
+ value: function() { return null; } |
+ }, |
+ |
+ /** |
+ * True after the chart has been rendered for the first time. |
+ * |
+ * @attribute rendered |
+ * @type boolean |
+ */ |
+ rendered: { |
+ type: Boolean, |
+ value: false, |
+ notify: true, |
+ reflectToAttribute: true |
+ }, |
+ |
+ /** |
+ * True if the chart is currently loading data. |
+ * |
+ * @attribute loading |
+ * @type boolean |
+ */ |
+ loading: { |
+ type: Boolean, |
+ value: false, |
+ notify: true, |
+ reflectToAttribute: true |
+ }, |
+ |
+ /** |
+ * True if setup is ready |
+ * |
+ * @attribute setupReady |
+ * @type Boolean |
+ */ |
+ setupReady: { |
+ type: Boolean, |
+ observer: 'setupReadyChanged' |
+ }, |
+ |
+ /** |
+ * google-analytics-query passthrough properties |
+ * See google-analytics-query for documentation |
+ * startDate, endDate, data, ids, metrics, dimensions, sort, filters, segment, samplingLevel, startIndex, maxResults |
+ */ |
+ startDate: { |
+ type: String, |
+ }, |
+ |
+ endDate: { |
+ type: String |
+ }, |
+ |
+ data: { |
+ type: Object |
+ }, |
+ |
+ ids: { |
+ type: String |
+ }, |
+ |
+ metrics: { |
+ type: String |
+ }, |
+ |
+ dimensions: { |
+ type: String |
+ }, |
+ |
+ sort: { |
+ type: String |
+ }, |
+ |
+ filters: { |
+ type: String |
+ }, |
+ |
+ segment: { |
+ type: String |
+ }, |
+ |
+ samplingLevel: { |
+ type: String |
+ }, |
+ |
+ startIndex: { |
+ type: Number |
+ }, |
+ |
+ maxResults: { |
+ type: Number |
+ } |
+ |
+ }, |
+ |
+ ready: function() { |
+ this._boundResponseHandler = this.handleResponse.bind(this); |
+ merge(this.$.chart.options, getChartOptions(this.type), this.options); |
+ }, |
+ |
+ setupReadyChanged: function(newVal, oldVal) { |
+ if (newVal) { |
+ metadata.get(); |
+ } |
+ }, |
+ |
+ handleResponse: function(response) { |
+ this.rendered = true; |
+ |
+ metadata.get().then(function(map) { |
+ switchApiNamesToDisplayNames(response.dataTable, map); |
+ ensureProperDataTableTypes(response.dataTable); |
+ this.$.query.setData(response); |
+ }.bind(this)); |
+ } |
+ }); |
+ |
+ /** |
+ * @module metadata |
+ */ |
+ var metadata = (function() { |
+ var promise; |
+ function queryMetadataAPI() { |
+ if (!gapi || !gapi.client || !gapi.client.analytics) { |
+ console.warn("Library not loaded yet!"); |
+ return; |
+ } |
+ return new Promise(function(resolve, reject) { |
+ gapi.client.analytics |
+ gapi.client.analytics.metadata.columns |
+ .list({ |
+ reportType: 'ga', |
+ _src: 'gwc-ga-chart' |
+ }) |
+ .execute(function(response) { |
+ if (response.error) { |
+ reject(response.error); |
+ } |
+ else { |
+ var map = {}; |
+ response.items.forEach(function(item) { |
+ map[item.id] = item.attributes.uiName; |
+ }); |
+ resolve(map); |
+ } |
+ }); |
+ }); |
+ } |
+ return { |
+ /** |
+ * Return the `queryMetadataAPI` promise. If the promise exists, |
+ * return it to avoid multiple requests. If the promise does not |
+ * exist, initiate the request and cache the promise. |
+ */ |
+ get: function() { |
+ promise = promise || queryMetadataAPI(); |
+ return promise.catch(function(err) { |
+ console.error(err.stack || err); |
+ }); |
+ } |
+ }; |
+ }()); |
+ |
+ /** |
+ * Return an options object for the specified chart type. |
+ * These are options suitable to pass to a Google Chart instance. |
+ * @return {Object} The chart options. |
+ */ |
+ function getChartOptions(type) { |
+ var chartOptions = { |
+ base: { |
+ fontSize: 11, |
+ chartArea: { |
+ width: '100%' |
+ }, |
+ legend: { |
+ position: 'top', |
+ alignment: 'start' |
+ } |
+ }, |
+ area: { |
+ pointSize: 6, |
+ lineWidth: 4, |
+ areaOpacity: 0.1, |
+ colors: ['#058dc7', '#aadff3'], |
+ hAxis: { |
+ format: 'MMM d', |
+ gridlines: { |
+ color: 'transparent' |
+ }, |
+ baselineColor: 'transparent' |
+ }, |
+ vAxis: { |
+ gridlines: { |
+ color: '#e8e8e8', |
+ logScale: true, |
+ count: 3 |
+ }, |
+ textPosition: 'in' |
+ } |
+ }, |
+ bar: { |
+ colors: ['#058dc7', '#50b432', '#ed561b'], |
+ hAxis: { |
+ gridlines: { |
+ color: '#e8e8e8' |
+ } |
+ }, |
+ vAxis: { |
+ textPosition: 'in', |
+ textStyle: { |
+ strokeWidth: 4, |
+ } |
+ } |
+ }, |
+ column: { |
+ colors: ['#058dc7', '#50b432', '#ed561b'], |
+ hAxis: { |
+ gridlines: { |
+ color: 'transparent' |
+ }, |
+ baselineColor: 'transparent' |
+ }, |
+ vAxis: { |
+ gridlines: { |
+ color: '#e8e8e8', |
+ }, |
+ textPosition: 'in' |
+ }, |
+ |
+ }, |
+ geo: { |
+ colorAxis: { |
+ minValue: 0, |
+ colors: ['#aadff3', '#058dc7'] |
+ } |
+ } |
+ }; |
+ return merge({}, chartOptions.base, chartOptions[type]); |
+ } |
+ |
+ /** |
+ * Use data from the Metadata API to change api names |
+ * (e.g. `ga:sessions`) to their display names (e.g. "Sessions"). |
+ * @param {Object} dataTable - The dataTable data. |
+ * @param {Object} map - A key/value store where the keys are the |
+ * api names and the values are the display names. |
+ */ |
+ function switchApiNamesToDisplayNames(dataTable, map) { |
+ dataTable.cols.forEach(function(col) { |
+ col.label = map[col.id] || col.label; |
+ }); |
+ } |
+ |
+ /** |
+ * The analytics api erroneously return some values as strings that are |
+ * supposed to be numbers. This function fixes that. |
+ * @param {Object} dataTable - The dataTable data. |
+ */ |
+ function ensureProperDataTableTypes(dataTable) { |
+ for (var i = 0; i < dataTable.rows.length; i++) { |
+ var row = dataTable.rows[i]; |
+ for (var j = 0; j < row.c.length; j++) { |
+ if (dataTable.cols[j].type === 'number') { |
+ row.c[j].v = Number(row.c[j].v); |
+ } |
+ } |
+ } |
+ } |
+ |
+ /** |
+ * Merge the source objects, in order, onto the destination object. |
+ * Recursively merge nested, plain objects, everything else copy by |
+ * reference. |
+ * @param {Object} target - The object to receive the merged values. |
+ * @param {...Object} source - The object(s) to provide values to the |
+ * target. Later sources override previous sources. |
+ * @return {Object} The merged target object. |
+ */ |
+ function merge(target) { |
+ var sources = Array.prototype.slice.call(arguments, 1); |
+ sources.forEach(function(source) { |
+ // Only merge objects. |
+ if (!(source && typeof sources == 'object')) return; |
+ |
+ Object.keys(source).forEach(function(key) { |
+ // If the source's key is a 'plain' object, recursively merge. |
+ if (typeof source[key] == 'object' && |
+ Object.getPrototypeOf(source[key]) == Object.prototype) { |
+ target[key] = target[key] == null ? |
+ merge({}, source[key]) : merge(target[key], source[key]); |
+ } |
+ // Otherwise just copy by reference. |
+ else if (typeof source[key] != 'undefined') { |
+ target[key] = source[key]; |
+ } |
+ }); |
+ }); |
+ return target; |
+ } |
+ }()); |
+ |
+</script> |
+ |