<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css" />
<link rel="stylesheet" href="style.css" />
</head>
<body ng-app="app" ng-controller="Main as ctrl" ng-cloak="">
<div class="container">
<h1>Tableau 10.0 WDC 2.0 Sample</h1>
<section class="container top-buffer">
<p>Copy the following URL, please paste to the Tableau WDC.</p>
<p><input type="text" ng-model="ctrl.siteUrl" disabled="disabled" /></p>
</section>
<section class="container top-buffer">
<button class="btn btn-danger" ng-click="ctrl.buttonClickHandler()">AMZN & GOOGL</button>
</section>
</div>
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script src="//connectors.tableau.com/libs/tableauwdc-2.0.0-beta.js"></script>
<script src="script.js"></script>
</body>
</html>
(function() {
'use strict';
angular.module('app', [], function(){})
.config(function($httpProvider) {
if (!$httpProvider.defaults.headers.get) {
$httpProvider.defaults.headers.get = {};
}
$httpProvider.defaults.headers.get['If-Modified-Since'] = (new Date(0)).toUTCString();
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
})
.controller('Main', function($scope) {
var buildUri = function(tickerSymbol, startDate, endDate) {
var startDateStr = getFormattedDate(startDate);
var endDateStr = getFormattedDate(endDate);
var queryStatement = 'select * from yahoo.finance.historicaldata where symbol = "' +
tickerSymbol +
'" and startDate = "' + startDateStr +
'" and endDate = "' + endDateStr + '"';
return '//query.yahooapis.com/v1/public/yql?q=' +
encodeURIComponent(queryStatement) +
'&diagnostics=true&env=store://datatables.org/alltableswithkeys&format=json';
};
var makeTwoDigits = function(num) {
return num < 9 ? '0' + num.toString() : num.toString();
};
var getFormattedDate = function getFormattedDate(date) {
return date.getUTCFullYear() +
'-' +
makeTwoDigits(date.getUTCMonth() + 1) +
'-' +
makeTwoDigits(date.getUTCDate());
};
var myWDC = tableau.makeConnector();
myWDC.getSchema = function(schemaCallback) {
var cols = [{
'id' : 'ticker',
'alias' : 'ticker',
'dataType' : tableau.dataTypeEnum.string
}, {
'id' : 'day',
'alias' : 'day',
'dataType' : tableau.dataTypeEnum.date
}, {
'id' : 'open',
'alias' : 'open',
'dataType' : tableau.dataTypeEnum.float
}, {
'id' : 'close',
'alias' : 'close',
'dataType' : tableau.dataTypeEnum.float
}, {
'id' : 'high',
'alias' : 'high',
'dataType' : tableau.dataTypeEnum.float
}, {
'id' : 'low',
'alias' : 'low',
'dataType' : tableau.dataTypeEnum.float
}];
var tableInfoAmzn = {
'id' : 'amzn',
'alias' : 'AMZN Table',
'columns' : angular.copy(cols)
};
var tableInfoGoogl = {
'id' : 'googl',
'alias' : 'GOOGL Table',
'columns' : angular.copy(cols)
};
schemaCallback([tableInfoAmzn, tableInfoGoogl]);
};
myWDC.getData = function(table, doneCallback) {
var tableData = [];
var endDate = new Date();
var startDate = new Date();
startDate.setYear(endDate.getFullYear() - 1);
var connectionUri = buildUri(table.tableInfo.id, startDate, endDate);
$.ajax({
'url' : connectionUri,
'dataType' : 'json'
})
.done(function (result) {
if (result.query.results) {
var quotes = result.query.results.quote;
angular.forEach(quotes, function(quote, key) {
tableData.push({
'ticker': quote.Symbol,
'day' : quote.Date,
'open' : quote.Open,
'close' : quote.Close,
'high' : quote.High,
'low' : quote.Low
});
});
table.appendRows(tableData);
doneCallback();
}
})
.fail(function (data, textStatus, jqXHR) {
tableau.log('Connection error: ' + data.responseText + '\n' + jqXHR);
tableau.abortWithError('Error while trying to connect to the Yahoo stock data source.');
});
};
tableau.registerConnector(myWDC);
var ctrl = this;
ctrl.siteUrl = window.location.href;
ctrl.buttonClickHandler = function() {
tableau.connectionName = 'Stock Data for AMZN & GOOGL';
tableau.submit();
};
});
}());
button {
margin-right : 10px;
width : 200px;
}
input {
width : 430px;
}