-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathEmbedding Tableau interactive workbook into webpage using JavaScript.txt
More file actions
249 lines (214 loc) · 13.9 KB
/
Embedding Tableau interactive workbook into webpage using JavaScript.txt
File metadata and controls
249 lines (214 loc) · 13.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
Tableau Embedded In A WebPage
http://onlinehelp.tableau.com/samples/en-us/js_api/tutorial.htm
http://onlinehelp.tableau.com/samples/en-us/js_api/tutorial.js
1. Create the Viz
Create the Viz
As you build your web application, the first step is to create, or instantiate the view. To do this, you create a new Viz object, passing the required parentElement (document.getElementByID) and url parameters, along with any options, such as hideTabs and hideToolbar. Here's the code:
function initializeViz() {
var placeholderDiv = document.getElementById("tableauViz");
var url = "http://public.tableau.com/views/WorldIndicators/GDPpercapita";
var options = {
width: placeholderDiv.offsetWidth,
height: placeholderDiv.offsetHeight,
hideTabs: true,
hideToolbar: true,
onFirstInteractive: function () {
workbook = viz.getWorkbook();
activeSheet = workbook.getActiveSheet();
}
};
viz = new tableau.Viz(placeholderDiv, url, options);
}
Run this code
You should now see a view with which you can interact, just like you can with views on Tableau Server. If you don't see a view above, it may need a few more moments to load, or you may need to use a different web browser.
In the code above, the constructor for the Viz object handles loading the view. Specifying a function in the onFirstInteractive option allows you to perform actions once the view has finished loading. In this case, the function caches the workbook and activeSheet variables so they can be used later on. These two variables were declared as global variables in the actual script. Typically you'll want to create the view when the page has finished loading and the browser is ready. If you're using jQuery, this can be done using jQuery's ready handler:
$(initializeViz);
/******************************************************************/
2.Filter
e2. Filter3. Tabs4. Select5. Chain Calls6. Sheets7. Toolbar8. Events
Filter Values
Filtering is a core capability of Tableau Server. In the view above, there are already Region and Year quick filter controls, but you can use the API to more tightly control what gets filtered. This is done using the applyFilterAsync method on a Worksheet object, which was cached in the activeSheet variable in step 1.
The following code filters the "Region" field to show only "The Americas":
function filterSingleValue() {
activeSheet.applyFilterAsync(
"Region",
"The Americas",
tableau.FilterUpdateType.REPLACE);
}
Run this code
You should now see that the view is filtered and only "The Americas" check box is selected under the Region quick filter.
The next code sample shows you how to add two more values to the filter, using the same syntax but instead specifying an array of values instead of a single value. Also note that ADD is used instead of REPLACE, which instructs the view to add additional criteria to the filter instead of replacing the values that are currently filtered:
function addValuesToFilter() {
activeSheet.applyFilterAsync(
"Region",
["Europe", "Middle East"],
tableau.FilterUpdateType.ADD);
}
Run this code
Similarly, you can remove values from the filter by using REMOVE:
function removeValuesFromFilter() {
activeSheet.applyFilterAsync(
"Region",
"Europe",
tableau.FilterUpdateType.REMOVE);
}
Run this code
You can also include all values in the filter by using ALL.
The filters you've seen so far have all had associated quick filters in the view. However, you can also create new filters. For example, you can create a filter for the x-axis, the "F: GDP per capita (curr $)" field, and specify that you only want to see countries where the GDP is greater than $40K, but less than $60K. To do this, you use the applyRangeFilter method, using a range of values as the criteria:
function filterRangeOfValues() {
activeSheet.applyRangeFilterAsync(
"F: GDP per capita (curr $)",
{
min: 40000,
max: 60000
},
tableau.FilterUpdateType.REPLACE);
}
Run this code
Finally, you can clear the filters. For example:
function clearFilters() {
activeSheet.clearFilterAsync("Region");
activeSheet.clearFilterAsync("F: GDP per capita (curr $)");
}
/**************************************************/
4.Select
Select Values
Filtering a view is useful when you want to focus the user's attention on a specific set of values by removing all other values not matching the filter criteria. However, sometimes it's useful to select values instead. This still focuses the user's attention on specific values, but the context of other values remains in the view. To do this, you use the selectMarksAsync method. The syntax is very similar to the applyFilterAsync method that you used previously. For example, the following code selects all of the marks in the "Asia" region:
function selectSingleValue() {
workbook.getActiveSheet().selectMarksAsync(
"Region",
"Asia",
tableau.SelectionUpdateType.REPLACE);
}
Run this code
The only change between the code above and the filter code you used earlier is that tableau.SelectionUpdateType was specified instead of tableau.FilterUpdateType. Also, notice that workbook.getActiveSheet() is used instead of the activeSheet global variable because the sheets were switched in step 3 and the global variable wasn't updated to point to the new active sheet.
In the following code sample, Africa and Oceania are added to the previous selection:
function addValuesToSelection() {
workbook.getActiveSheet().selectMarksAsync(
"Region",
["Africa", "Oceania"],
tableau.FilterUpdateType.ADD);
}
Run this code
Again, the code should look familiar since the syntax is almost identical to filtering. At this point, you've selected Asia, Africa, and Oceania. The next code sample will demonstrate how to remove. In this case, you will remove countries that have a GDP less than $5,000. To do this, you use a range just like you did for filtering, except you'll only specify a max value:
function removeFromSelection() {
workbook.getActiveSheet().selectMarksAsync(
"AVG(F: GDP per capita (curr $))",
{
max: 5000
},
tableau.FilterUpdateType.REMOVE);
}
Run this code
Clearing the selection is just as easy as clearing a filter, using the clearSelectedMarksAsync method:
function clearSelection() {
workbook.getActiveSheet().clearSelectedMarksAsync();
}
/***************************************************/
5.Chain Method Calls
Chain Method Calls
You may have noticed a naming pattern with the methods used thus far. They all end with the Async suffix, which stands for asynchronous. Programming on the web involves communicating with servers, which usually take time to compute and return a value. To avoid locking up the user's browser while you're waiting for a response from the server, you instruct the user's browser to notify your code when the server has sent a response to your original request.
The Tableau JavaScript API uses Promises (specifically the Promises/A specification) to notify your code when an operation is complete. This allows you to chain method calls using an easy syntax. Each method that ends with Async returns a Promise object, containing three methods:
then(successCallback, errorCallback) - the successCallback function is called when the operation is successful, and likewise the errorCallback function is called when there is an error. Both parameters are optional.
otherwise(errorCallback) - called when an error occurs
always(callback) - always called, whether the operation was successful or not
The following code sample demonstrates how you can use some of the methods you've learned thus far to chain a series of commands. First you switch to the "GDP per capita by region" sheet. After that has finished, you apply a range filter. Once Tableau Server has applied the filter, you select some marks.
function switchTabsThenFilterThenSelectMarks() {
workbook.activateSheetAsync("GDP per capita by region")
.then(function (newSheet) {
activeSheet = newSheet;
// It's important to return the promise so the next link in the chain
// won't be called until the filter completes.
return activeSheet.applyRangeFilterAsync(
"Date (year)",
{
min: new Date(Date.UTC(2002, 1, 1)),
max: new Date(Date.UTC(2008, 12, 31))
},
tableau.FilterUpdateType.REPLACE);
})
.then(function (filterFieldName) {
return activeSheet.selectMarksAsync(
"AGG(GDP per capita (weighted))",
{
min: 20000
},
tableau.SelectionUpdateType.REPLACE);
});
}
Run this code
There are several important things to point out with the above code:
Inside of a then function it does a return of another Promise object. This ensures that the next link in the chain will not get run until the current link finishes.
Notice how the result of an operation is handled. The function inside the first then callback takes a single newSheet parameter, since that's the promised return value from the activateSheetAsync method. Similarly, the second then function gets a filterFieldName parameter, which is the name of the field for the filter that was just applied. A full explanation of the promised return values for each Async method is in the JavaScript API Reference.
Before moving on to the next step, let's take a look at how errors are handled inside a chain. The code below intentionally causes an error to happen by leaving out some required parameters to the applyFilterAsync method:
function triggerError() {
workbook.activateSheetAsync("GDP per capita by region")
.then(function (newSheet) {
// Do something that will cause an error: leave out required parameters.
return activeSheet.applyFilterAsync("Date (year)");
})
.otherwise(function (err) {
alert("We purposely triggered this error to show how error handling happens with chained calls.\n\n " + err);
});
}
/*****************************************************************/
6. work with sheets
Work with Sheets
Workbooks created in Tableau Desktop contain worksheets and, sometimes, one or more dashboards. The dashboards themselves typically contain one or more worksheets. This is why, in the API, the concept of "sheet" encompasses both worksheets and dashboards. Worksheet and dashboard objects do not have the same set of actions, however. Worksheets are the only entry point for acting on both worksheet and dashboard objects. You can't act directly on a dashboard object.
The code samples below illustrate how this works. The first code sample demonstrates how you would query all of a workbook's sheets. After you click Run this code the dialog that appears lists workbook's sheets:
function querySheets() {
var sheets = workbook.getPublishedSheetsInfo();
var text = getSheetsAlertText(sheets);
text = "Sheets in the workbook:\n" + text;
alert(text);
}
Run this code
Here's how you would query worksheets in a dashboard. Notice that the filter is still applied to the "GDP per region" worksheet in the dashboard, but the marks are not selected:
function queryDashboard() {
workbook.activateSheetAsync("GDP per Capita Dashboard")
.then(function (dashboard) {
var worksheets = dashboard.getWorksheets();
var text = getSheetsAlertText(worksheets);
text = "Worksheets in the dashboard:\n" + text;
alert(text);
});
}
Run this code
You'll notice that there are scrollbars on the viz. This is because the fixed size specified in the Viz constructor (step 1) is different than the fixed size specified for this dashboard by the workbook author. To see the entire dashboard, you can change the size behavior to AUTOMATIC, which tells the viz to fit the available space. This removes the scrollbars at the expense of making each Worksheet in the dashboard slightly smaller.
function changeDashboardSize() {
workbook.activateSheetAsync("GDP per Capita Dashboard")
.then(function (dashboard) {
dashboard.changeSizeAsync({
behavior: tableau.SheetSizeBehavior.AUTOMATIC
});
});
}
Run this code
Now, here's how you select filters and change settings on multiple sheets within a dashboard. The code sample applies to a dashboard with two worksheets:
var dashboard, mapSheet, graphSheet;
workbook.activateSheetAsync("GDP per Capita Dashboard")
.then(function (sheet) {
dashboard = sheet;
mapSheet = dashboard.getWorksheets().get("Map of GDP per capita");
graphSheet = dashboard.getWorksheets().get("GDP per capita by region");
return mapSheet.applyFilterAsync("Region", "Middle East", tableau.FilterUpdateType.REPLACE);
})
.then(function () {
// Do these two steps in parallel since they work on different sheets.
mapSheet.applyFilterAsync("YEAR(Date (year))", 2010, tableau.FilterUpdateType.REPLACE);
return graphSheet.clearFilterAsync("Date (year)");
})
.then(function () {
return graphSheet.selectMarksAsync("YEAR(Date (year))", 2010, tableau.SelectionUpdateType.REPLACE);
});
}
/***************************************************************/
7. Control Toolbar Commands
/*******************************************************/
3. Switch Tabs
Switch Tabs
Sometimes a single sheet in a workbook doesn't convey all of the information that you'd like your user to see. You can use the API to switch from the current sheet to another published sheet within the same workbook (note that the workbook must have been published to the server with Show Sheets as Tabs enabled). To switch sheets, you use the activateSheetAsync method on a Workbook object, which was cached in a global workbook variable in step 1. Here's how you switch the sheet to a map worksheet named "GDP per capita map".
function switchToMapTab() {
workbook.activateSheetAsync("GDP per capita map");
}
/*****************************************************/