Commit 780e1e93 authored by Ken Hawkins's avatar Ken Hawkins
Browse files

organise and seperate out reusable code

parent 0f3bf5ec
// Store result data as an object.
// Right now we don't use this for anything, but we could. Maybe we even save this data as a file in seperate process to the viewing...
var analyticsResults = new Object();
// various reusable icons
// var iconWarning = '<span class="icon icon-generic is-invalid-label" data-icon="l"> </span>',
var iconPrefix = '<span class="icon-indicator">',
iconSuffix = '</span><br/>';
var iconWarning = iconPrefix + '🤔' + iconSuffix,
iconSoSo = iconPrefix + '😇' + iconSuffix,
iconSuccess = iconPrefix + '🎉' + iconSuffix;
// Reusable utility functions for the analytics display
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
// allow the user to change the query
function enableUserDatePicking() {
// set a default date
document.getElementById("originDate").value = moment().format('YYYY-MM-DD');
// update the report on date change
function userChangedDate() {
console.log('Change requested, refreshing...');
render_queue_time = 1; // reset the processing throttle
$('tbody.top-stories').html(''); // empty the results
var requestDate = moment(document.getElementById("originDate").value, 'YYYY-MM-DD');
bootstrapCustomEBIAnalytics(requestDate);
}
// delay the invokation of the date change to not hammer the GAPI
var userChangedDateTimeoutID;
$('#originDate').change( function () {
window.clearTimeout(userChangedDateTimeoutID); // delete any pending change that occured before the timeout cleared
userChangedDateTimeoutID = window.setTimeout(userChangedDate, 750);
});
}
// check if the request has expired (that is: the user changed the params)
function requestIsExpired(requestDate) {
// console.log(moment(requestDate).format('YYYY-MM-DD'),document.getElementById("originDate").value);
if (moment(requestDate).format('YYYY-MM-DD') != document.getElementById("originDate").value) {
// console.log('expired');
return true; // if the dates are out of sync, request has expired
}
return false; // request is still valid
}
// GA...
// Load the Embed API library.
(function(w,d,s,g,js,fs){
g=w.gapi||(w.gapi={});g.analytics={q:[],ready:function(f){this.q.push(f);}};
js=d.createElement(s);fs=d.getElementsByTagName(s)[0];
js.src='https://apis.google.com/js/platform.js';
fs.parentNode.insertBefore(js,fs);js.onload=function(){g.load('analytics');};
}(window,document,'script'));
// == NOTE ==
// This code uses ES6 promises. If you want to use this code in a browser
// that doesn't supporting promises natively, you'll have to include a polyfill.
function analyticsAuthorize(clientid) {
// Authorize the user immediately if the user has already granted access.
// If no access has been created, render an authorize button inside the
// element with the ID "embed-api-auth-container".
gapi.analytics.auth.authorize({
container: 'embed-api-auth-container',
clientid: clientid
});
}
/**
* Extend the Embed APIs `gapi.analytics.report.Data` component to
* return a promise the is fulfilled with the value returned by the API.
* @param {Object} params The request parameters.
* @return {Promise} A promise.
*/
function query(params) {
return new Promise(function(resolve, reject) {
var data = new gapi.analytics.report.Data({query: params});
data.once('success', function(response) { resolve(response); })
.once('error', function(response) { reject(response); })
.execute();
});
}
// Charting...
/**
* Create a new canvas inside the specified element. Set it to be the width
* and height of its container.
* @param {string} id The id attribute of the element to host the canvas.
* @return {RenderingContext} The 2D canvas context.
*/
function makeCanvas(id) {
var container = document.getElementById(id);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
container.innerHTML = '';
canvas.width = container.offsetWidth;
canvas.height = container.offsetHeight;
container.appendChild(canvas);
return ctx;
}
/**
* Create a visual legend inside the specified element based off of a
* Chart.js dataset.
* @param {string} id The id attribute of the element to host the legend.
* @param {Array.<Object>} items A list of labels and colors for the legend.
*/
function generateLegend(id, items) {
var legend = document.getElementById(id);
legend.innerHTML = items.map(function(item) {
var color = item.color || item.strokeColor;
var label = item.label;
return '<li><i style="background:' + color + '"></i>' + label + '</li>';
}).join('');
}
function setChartDefaults(){
// Set some global Chart.js defaults.
Chart.defaults.global.animationSteps = 60;
Chart.defaults.global.animationEasing = 'easeInOutQuart';
Chart.defaults.global.responsive = true;
Chart.defaults.global.maintainAspectRatio = false;
}
\ No newline at end of file
/**
* Create a new canvas inside the specified element. Set it to be the width
* and height of its container.
* @param {string} id The id attribute of the element to host the canvas.
* @return {RenderingContext} The 2D canvas context.
*/
function makeCanvas(id) {
var container = document.getElementById(id);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
container.innerHTML = '';
canvas.width = container.offsetWidth;
canvas.height = container.offsetHeight;
container.appendChild(canvas);
return ctx;
}
/**
* Create a visual legend inside the specified element based off of a
* Chart.js dataset.
* @param {string} id The id attribute of the element to host the legend.
* @param {Array.<Object>} items A list of labels and colors for the legend.
*/
function generateLegend(id, items) {
var legend = document.getElementById(id);
legend.innerHTML = items.map(function(item) {
var color = item.color || item.strokeColor;
var label = item.label;
return '<li><i style="background:' + color + '"></i>' + label + '</li>';
}).join('');
}
// Set some global Chart.js defaults.
Chart.defaults.global.animationSteps = 60;
Chart.defaults.global.animationEasing = 'easeInOutQuart';
Chart.defaults.global.responsive = true;
Chart.defaults.global.maintainAspectRatio = false;
\ No newline at end of file
// In short: fetches data from google API, show on dashboard
// you need to authenticate in your local JS
// Store the data as an object.
// Right now we don't use this for anything, but we could. Maybe we even save this data as a file in seperate process to the viewing...
var analyticsResults = new Object();
// various reusable icons
// var iconWarning = '<span class="icon icon-generic is-invalid-label" data-icon="l"> </span>',
var iconPrefix = '<span class="icon-indicator">',
iconSuffix = '</span><br/>';
// shared paramaters for all charts
var shared = [];
shared['filters'] = 'ga:pagePath!=/index.php;ga:pagePath!@/category/';
shared['datePeriods'] = ['day','month','year'];
shared['dayRange'] = 8; // the number of days you wish to get results for. Make this value +1 (1 week = 8 days, 2 wks = 15 days)
shared['viewID'] = ['ga:91186979']; //The GA property we want to view: www.ebi.ac.uk
shared['clientid'] = '1025857412047-p3jieogi7mgkhb0dre41rm2ge3r8jn0s.apps.googleusercontent.com'; // get at https://console.developers.google.com/apis/credentials
$(document).ready(function() {
// Initialise all the queries.
// This gets invoke when google is ready and when the user calls a refresh by selecting a date
// requestedOriginDate = YYYYMMDD format, ie: 20170122
function bootstrapCustomEBIAnalytics(requestedOriginDate) {
shared['originDate'] = moment(requestedOriginDate, "YYYYMMDD"); // we allow user to specify an origin date
analyticsAuthorize(shared['clientid']);
// Render traffic overview graph
render_queue('traffic-overview',0);
// Render all the of charts for this view.
render_queue('overview-list',0);
// $("#table-report").tablesorter();
}
var iconWarning = iconPrefix + '🤔' + iconSuffix,
iconSoSo = iconPrefix + '😇' + iconSuffix,
iconSuccess = iconPrefix + '🎉' + iconSuffix;
// when the GAPI is ready, run the process
gapi.analytics.ready(function() {
var defaultDateNow = moment().format('YYYYMMDD');
bootstrapCustomEBIAnalytics(defaultDateNow);
enableUserDatePicking();
});
});
// extract the pub date from the url
function parsePublicationDate(url) {
......@@ -24,33 +45,6 @@ function parsePublicationDate(url) {
return month + '/' + year;
}
// == NOTE ==
// This code uses ES6 promises. If you want to use this code in a browser
// that doesn't supporting promises natively, you'll have to include a polyfill.
function analyticsAuthorize(clientid) {
// Authorize the user immediately if the user has already granted access.
// If no access has been created, render an authorize button inside the
// element with the ID "embed-api-auth-container".
gapi.analytics.auth.authorize({
container: 'embed-api-auth-container',
clientid: clientid
});
}
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
// check if the request has expired (that is: the user changed the params)
function requestIsExpired(requestDate) {
// console.log(moment(requestDate).format('YYYY-MM-DD'),document.getElementById("originDate").value);
if (moment(requestDate).format('YYYY-MM-DD') != document.getElementById("originDate").value) {
// console.log('expired');
return true; // if the dates are out of sync, request has expired
}
return false; // request is still valid
}
var render_queue_time = 1;
// Queue up the requests to not exceed GA's requests per second (10 per second, per IP), 50,000 a day
// https://developers.google.com/analytics/devguides/config/mgmt/v3/limits-quotas#general_api
......@@ -159,6 +153,7 @@ function fetch_traffic_overview(target,dimensions,metrics,filters,shared) {
};
new Chart(makeCanvas('chart-1-container')).Line(data);
setChartDefaults();
generateLegend('legend-1-container', data.datasets);
// $('#chart-1-container').prepend('<div class="label">text</div>');
......@@ -198,6 +193,12 @@ function fetch_overview(target,dimensions,metrics,filters,shared) {
analyticsResults[row]['clicks'] = new Object(); // we'll use later
analyticsResults[row]['referals'] = new Object(); // we'll use later
// now that we no the top stories, we can make queries about them
render_queue('page-detail',row);
render_queue('ui-regions',row);
render_queue('page-time',row);
render_queue('leave-rate',row);
// meets the pageviews target?
var success = iconSuccess;
if (analyticsResults[row].pageViews < 250) {
......@@ -218,11 +219,6 @@ function fetch_overview(target,dimensions,metrics,filters,shared) {
'<td>' + success + analyticsResults[row].pageViews +
'</td><td class="tr-referals small"></td><td class="tr-ui-regions"></td><td class="tr-time-on-page"></td><td class="tr-leave-rate"></td></tr>');
// now that we no the top stories, we can make queries about them
render_queue('page-detail',row);
render_queue('ui-regions',row);
render_queue('page-time',row);
render_queue('leave-rate',row);
}
});
......@@ -260,7 +256,6 @@ function fetch_page_detail(target,dimensions,metrics,filters,shared,resultPositi
Promise.all([localQuery]).then(function(results) {
var receivedData = results[0].rows;
// $(target).append('<td class=""></td>');
// save the data
for (var i = 0; i < receivedData.length; i++) {
......@@ -268,6 +263,7 @@ function fetch_page_detail(target,dimensions,metrics,filters,shared,resultPositi
}
// sort
// make a list of which keys have the most referals
var dataSorted = Object.keys(analyticsResults[resultPosition]['referals']).sort(function(a,b){return analyticsResults[resultPosition]['referals'][b]-analyticsResults[resultPosition]['referals'][a]});
// output the data
......@@ -394,7 +390,7 @@ function fetch_leave_rate(target,dimensions,metrics,filters,shared,resultPositio
// update table sorting
// $("#table-report").trigger('update');
console.log(analyticsResults[resultPosition]);
// console.log(analyticsResults[resultPosition]);
// add pie graph
var uniqueID = Math.floor(Math.random() * 1000);
......@@ -422,18 +418,3 @@ function fetch_leave_rate(target,dimensions,metrics,filters,shared,resultPositio
}
/**
* Extend the Embed APIs `gapi.analytics.report.Data` component to
* return a promise the is fulfilled with the value returned by the API.
* @param {Object} params The request parameters.
* @return {Promise} A promise.
*/
function query(params) {
return new Promise(function(resolve, reject) {
var data = new gapi.analytics.report.Data({query: params});
data.once('success', function(response) { resolve(response); })
.once('error', function(response) { reject(response); })
.execute();
});
}
......@@ -9,7 +9,28 @@
<script src="//www.ebi.ac.uk/web_guidelines/EBI-Framework/v1.1/libraries/tablesorter/dist/js/jquery.tablesorter.min.js"></script>
<script src="../vendor/html2canvas/html2canvas.js"></script>
<script src="../vendor/html2canvas/html2canvas.svg.js"></script>
<script src="../common/screenshot.js"></script>
<script src="../common/utilities.js"></script>
<script defer="defer" src="../common/screenshot.js"></script>
<!-- Load the components and their dependencies. -->
<!-- This demo uses the Chart.js graphing library and Moment.js to do date
formatting and manipulation. -->
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script> -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.2/moment.min.js"></script>
<!-- Include the ViewSelector2 component script. -->
<!-- <script src="https://ga-dev-tools.appspot.com/public/javascript/embed-api/components/view-selector2.js"></script> -->
<!-- Include the DateRangeSelector component script. -->
<script src="https://ga-dev-tools.appspot.com/public/javascript/embed-api/components/date-range-selector.js"></script>
<!-- Include the ActiveUsers component script. -->
<!-- <script src="https://ga-dev-tools.appspot.com/public/javascript/embed-api/components/active-users.js"></script> -->
<!-- Include the CSS that styles the charts. -->
<!-- <link rel="stylesheet" href="https://ga-dev-tools.appspot.com/public/css/chartjs-visualizations.css"> -->
<!-- charting stuff -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>
<link rel="stylesheet" href="https://ga-dev-tools.appspot.com/public/css/chartjs-visualizations.css">
<!-- Write the dashboard code -->
<script defer="defer" src="ebiAnalyticsDashboard-newsstories.js"></script>
</head>
<body>
<div id="content" role="main" class="row">
......@@ -21,7 +42,7 @@
<li><a href="//github.com/ebiwd/analytics-dashboards">EMBL-EBI Analytics dashboards</a></li>
<!-- <li class="disabled">Disabled</li> -->
<li>
<span class="show-for-sr">Current: </span> This page
<span class="show-for-sr">Current: </span> EMBL News weekly dashbaord
</li>
</ul>
</nav>
......@@ -73,16 +94,6 @@
<!-- Via: https://ga-dev-tools.appspot.com/embed-api/third-party-visualizations/ -->
<!-- Load the Embed API library. -->
<script>
(function(w,d,s,g,js,fs){
g=w.gapi||(w.gapi={});g.analytics={q:[],ready:function(f){this.q.push(f);}};
js=d.createElement(s);fs=d.getElementsByTagName(s)[0];
js.src='https://apis.google.com/js/platform.js';
fs.parentNode.insertBefore(js,fs);js.onload=function(){g.load('analytics');};
}(window,document,'script'));
</script>
<!-- A few misc style tweaks -->
<style>
td.tr-referals {
......@@ -98,19 +109,6 @@
}
</style>
<!-- Load the components and their dependencies. -->
<!-- This demo uses the Chart.js graphing library and Moment.js to do date
formatting and manipulation. -->
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script> -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.2/moment.min.js"></script>
<!-- Include the ViewSelector2 component script. -->
<!-- <script src="https://ga-dev-tools.appspot.com/public/javascript/embed-api/components/view-selector2.js"></script> -->
<!-- Include the DateRangeSelector component script. -->
<script src="https://ga-dev-tools.appspot.com/public/javascript/embed-api/components/date-range-selector.js"></script>
<!-- Include the ActiveUsers component script. -->
<!-- <script src="https://ga-dev-tools.appspot.com/public/javascript/embed-api/components/active-users.js"></script> -->
<!-- Include the CSS that styles the charts. -->
<!-- <link rel="stylesheet" href="https://ga-dev-tools.appspot.com/public/css/chartjs-visualizations.css"> -->
<!-- Add HTML containers to host the dashboard components. -->
......@@ -146,94 +144,25 @@
</ul>
</div>
<table id="table-report" class="hover tablesorter">
<thead>
<tr>
<th width="">Story</th>
<th width="">Views</th>
<th width="">Referers</th>
<th width="">Engagement</th>
<th width="">Time on page (min)</th>
<th width="">Bounce %</th>
</tr>
</thead>
<tbody class="top-stories">
<!-- <tr class="goal overall"> -->
</tbody>
</table>
<div class="referer-test"></div>
<!-- charting stuff -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>
<link rel="stylesheet" href="https://ga-dev-tools.appspot.com/public/css/chartjs-visualizations.css">
<script src="charting-newstories.js"></script>
<!-- Write the dashboard code -->
<script src="ebiAnalyticsDashboard-newsstories.js"></script>
<script>
// shared paramaters for all charts
var shared = [];
shared['filters'] = 'ga:pagePath!=/index.php;ga:pagePath!@/category/';
shared['datePeriods'] = ['day','month','year'];
shared['dayRange'] = 8; // the number of days you wish to get results for. Make this value +1 (1 week = 8 days, 2 wks = 15 days)
shared['viewID'] = ['ga:91186979']; //The GA property we want to view: www.ebi.ac.uk
shared['clientid'] = '1025857412047-p3jieogi7mgkhb0dre41rm2ge3r8jn0s.apps.googleusercontent.com'; // get at https://console.developers.google.com/apis/credentials
$(document).ready(function() {
// Initialise all the queries.
// This gets invoke when google is ready and when the user calls a refresh by selecting a date
// requestedOriginDate = YYYYMMDD format, ie: 20170122
function bootstrapCustomEBIAnalytics(requestedOriginDate) {
shared['originDate'] = moment(requestedOriginDate, "YYYYMMDD"); // we allow user to specify an origin date
analyticsAuthorize(shared['clientid']);
// Render traffic overview graph
render_queue('traffic-overview',0);
// Render all the of charts for this view.
render_queue('overview-list',0);
// $("#table-report").tablesorter();
}
// allow the user to change the query
function enableUserDatePicking() {
// set a default date
document.getElementById("originDate").value = moment().format('YYYY-MM-DD');
// update the report on date change
function userChangedDate() {
console.log('Change requested, refreshing...');
render_queue_time = 1; // reset the processing throttle
$('tbody.top-stories').html(''); // empty the results
var requestDate = moment(document.getElementById("originDate").value, 'YYYY-MM-DD');
bootstrapCustomEBIAnalytics(requestDate);
}
// delay the invokation of the date change to not hammer the GAPI
var userChangedDateTimeoutID;
$('#originDate').change( function () {
window.clearTimeout(userChangedDateTimeoutID); // delete any pending change that occured before the timeout cleared
userChangedDateTimeoutID = window.setTimeout(userChangedDate, 750);
});
}
// when the GAPI is ready, run the process
gapi.analytics.ready(function() {
var defaultDateNow = moment().format('YYYYMMDD');
bootstrapCustomEBIAnalytics(defaultDateNow);
enableUserDatePicking();
});
<table id="table-report" class="hover tablesorter">
<thead>
<tr>
<th width="">Story</th>
<th width="">Views</th>
<th width="">Referers</th>
<th width="">Engagement</th>
<th width="">Time on page (min)</th>
<th width="">Bounce %</th>
</tr>
</thead>
<tbody class="top-stories">
<!-- <tr class="goal overall"> -->
</tbody>
</table>
<div class="referer-test"></div>
});
</script>
</div>
</section>
</div><!-- /.container -->
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment