Skip to content

Commit 77cf415

Browse files
authored
Merge pull request #410 from tableau/smontesdeoca/viz-samples
smontesdeoca/viz-samples merge to dev
2 parents 7fd1583 + d5490ec commit 77cf415

File tree

7 files changed

+304
-0
lines changed

7 files changed

+304
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest manifest-version="0.1" xmlns="http://www.tableau.com/xml/extension_manifest">
3+
<dashboard-extension id="com.tableau.extensions.samples.vizImage" extension-version="0.1.0">
4+
<default-locale>en_US</default-locale>
5+
<name resource-id="name"/>
6+
<description>Viz Image Sample</description>
7+
<author name="tableau" email="[email protected]" organization="tableau" website="https://www.tableau.com"/>
8+
<min-api-version>1.6</min-api-version>
9+
<source-location>
10+
<url>http://localhost:8765/Samples-Typescript/VizImage/vizImage.html</url>
11+
</source-location>
12+
<icon>iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAlhJREFUOI2Nkt9vy1EYh5/3bbsvRSySCZbIxI+ZCKsN2TKtSFyIrV2WuRCJuBiJWxfuxCVXbvwFgiEtposgLFJElnbU1SxIZIIRJDKTrdu+53Uhra4mce7Oe57Pcz7JOULFisViwZ+29LAzOSjQYDgz1ZcCvWuXV11MJpN+OS/lm6179teqH0yDqxPTCyKSA8DcDsyOmOprnCaeP7459pdgy969i0LTC3IO/RQMyoHcQN+3cnljW3dNIFC47qDaK3g7BwdTkwBaBELT4ZPOUVWgKl4ZBnjxJPUlMDnTDrp0pmr6RHFeEjjcUUXPDGeSEwDN0Xg8sivxMhJNjGzbHd8PkM3eHRfkrBM5NkcQaY2vUnTlrDIA0NoaX+KLXFFlowr14tvVpqb2MICzmQcKqxvbumv+NAhZGCCIPwEw6QWXKYRL/VUXO0+rAUJiPwAk5MIlgVfwPjjHLCL1APmHN94ZdqeYN+NW/mn6I4BvwQYchcLnwFhJMDiYmlRxAzjpKWZkYkUCcZ2I61wi37tLbYyjiN0fHk5Oz3nGSLSzBbNHCF35R7f6K1/hN9PRhek11FrymfQQQKB4+Gl05P2qNRtmETlXW7e+b2z01dfycGNbfFMAbqNyKp9Jp4rzOT8RYFs0njJkc2iqsCObvTsOsDWWqA5C1uFy+Uz/oXJeKwVT4h0RmPUXhi79vuC0Ku6yOffTK3g9lfxfDQAisY516sg5kfOCiJk7HoLt2cf9b/9LANAc7dznm98PagG1fUOZ9IP5uMB8Q4CPoyNvausapkTt3rNMuvdf3C/o6+czhtdwmwAAAABJRU5ErkJggg==</icon>
13+
</dashboard-extension>
14+
<resources>
15+
<resource id="name">
16+
<text locale="en_US">Viz Image Sample</text>
17+
</resource>
18+
</resources>
19+
</manifest>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<title>Viz Image Sample</title>
8+
9+
<!-- jQuery -->
10+
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
11+
12+
<!-- Bootstrap -->
13+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" >
14+
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" ></script>
15+
16+
<!-- Extensions Library (this will be hosted on a CDN eventually) -->
17+
<script src="../../lib/tableau.extensions.1.latest.js"></script>
18+
19+
<!-- Our extension's code -->
20+
<script src="../../dist/vizImage.js"></script>
21+
</head>
22+
<body>
23+
<div class="container">
24+
<h4>Viz Image Sample</h4>
25+
<div id="viz-options">
26+
<select id="mark-select" class="form-select" aria-label="Default select example" disabled="true">
27+
<option selected disabled>Mark Type</option>
28+
<option value="bar">Bar</option>
29+
<option value="line">Line</option>
30+
<option value="area">Area</option>
31+
<option value="square">Square</option>
32+
<option value="circle">Circle</option>
33+
<option value="text">Text</option>
34+
</select>
35+
<!-- See all color palettes available: https://tableau.github.io/extensions-api/docs/trex_tableau_viz_ref.html -->
36+
<select id="color-select" class="form-select" aria-label="Default select example" disabled="true">
37+
<option selected disabled>Color Palette</option>
38+
<option value="tableau20_10_0">Tableau 20</option>
39+
<option value="summer_10_0">Summer</option>
40+
<option value="winter_10_0">Winter</option>
41+
<option value="color_blind_10_0">Color Blind</option>
42+
</select>
43+
</div>
44+
<hr>
45+
<div id="viz-container"></div>
46+
</div>
47+
</body>
48+
</html>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { MarkType } from '@tableau/extensions-api-types';
2+
3+
// Wrap everything in an anonymous function to avoid polluting the global namespace
4+
(async () => {
5+
class VizImage {
6+
// Avoid globals.
7+
constructor(private _$: JQueryStatic) { }
8+
9+
/**
10+
* Initializes the extension
11+
*/
12+
public async initialize() {
13+
console.log('Waiting for DOM ready');
14+
await this._$.ready;
15+
console.log('Initializing extension API');
16+
await tableau.extensions.initializeAsync();
17+
18+
await this.addVizImage(tableau.MarkType.Bar, 'tableau20_10_0');
19+
20+
const markSelector = this._$('#mark-select');
21+
const colorSelector = this._$('#color-select');
22+
23+
markSelector.prop('disabled', false);
24+
colorSelector.prop('disabled', false);
25+
26+
// updating viz images with new values upon a selector change
27+
markSelector.change(() => {
28+
this.addVizImage(markSelector.val() as MarkType, colorSelector.val() as string);
29+
});
30+
colorSelector.change(() => {
31+
this.addVizImage(markSelector.val() as MarkType, colorSelector.val() as string);
32+
});
33+
}
34+
35+
/**
36+
* Builds the input specifications and displays the created viz image
37+
* @param markType
38+
* @param colorPalette
39+
*/
40+
private async addVizImage(markType: MarkType, palette: string) {
41+
// Building the input specification object that is used to create the viz image
42+
// Data values used in the viz image are prefilled
43+
const vizInputSpec = {
44+
data: {
45+
values: [
46+
{Product: 'Paper', Sales: 28, Region: 'Central'},
47+
{Product: 'Pens', Sales: 45, Region: 'East'},
48+
{Product: 'Rulers', Sales: 35, Region: 'East'},
49+
{Product: 'Rulers', Sales: 43, Region: 'South'},
50+
{Product: 'Paper', Sales: 50, Region: 'West'},
51+
{Product: 'Pens', Sales: 56, Region: 'West'}
52+
]
53+
},
54+
description: 'A sample viz', // optional parameter
55+
encoding: {
56+
color: {field: 'Product', type: tableau.VizImageEncodingType.Discrete, palette},
57+
columns: {field: 'Region', type: tableau.VizImageEncodingType.Discrete},
58+
rows: {field: 'Sales', type: tableau.VizImageEncodingType.Continuous}
59+
},
60+
mark: markType,
61+
markcolor: '#FFED5F', // may not get used in viz if color is encoded in viz
62+
size: {width: 400, height: 300}
63+
};
64+
65+
// defaulting values if null
66+
if (markType === null) {
67+
vizInputSpec.mark = tableau.MarkType.Bar;
68+
}
69+
if (palette === null) {
70+
vizInputSpec.encoding.color.palette = 'tableau20_10_0';
71+
}
72+
73+
const svg = await tableau.extensions.createVizImageAsync(vizInputSpec);
74+
// making call to create viz image from the input specifications
75+
const blob = new Blob([svg], { type: 'image/svg+xml' });
76+
const url = URL.createObjectURL(blob);
77+
const image = document.createElement('img');
78+
image.src = url;
79+
image.style.maxWidth = '100%';
80+
image.style.maxHeight = '100%';
81+
image.className = 'center-block';
82+
const vizApiElement = document.getElementById('viz-container');
83+
// clearing UI and adding in new viz
84+
vizApiElement.innerHTML = '';
85+
vizApiElement.appendChild(image);
86+
image.addEventListener('load', () => URL.revokeObjectURL(url), { once: true });
87+
}
88+
}
89+
90+
console.log('Initializing VizImage extension.');
91+
await new VizImage($).initialize();
92+
})();

Samples/VizImage/VizImage.trex

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest manifest-version="0.1" xmlns="http://www.tableau.com/xml/extension_manifest">
3+
<dashboard-extension id="com.tableau.extensions.samples.vizImage" extension-version="0.1.0">
4+
<default-locale>en_US</default-locale>
5+
<name resource-id="name"/>
6+
<description>Viz Image Sample</description>
7+
<author name="tableau" email="[email protected]" organization="tableau" website="https://www.tableau.com"/>
8+
<min-api-version>1.6</min-api-version>
9+
<source-location>
10+
<url>http://localhost:8765/Samples/VizImage/vizImage.html</url>
11+
</source-location>
12+
<icon>iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAlhJREFUOI2Nkt9vy1EYh5/3bbsvRSySCZbIxI+ZCKsN2TKtSFyIrV2WuRCJuBiJWxfuxCVXbvwFgiEtposgLFJElnbU1SxIZIIRJDKTrdu+53Uhra4mce7Oe57Pcz7JOULFisViwZ+29LAzOSjQYDgz1ZcCvWuXV11MJpN+OS/lm6179teqH0yDqxPTCyKSA8DcDsyOmOprnCaeP7459pdgy969i0LTC3IO/RQMyoHcQN+3cnljW3dNIFC47qDaK3g7BwdTkwBaBELT4ZPOUVWgKl4ZBnjxJPUlMDnTDrp0pmr6RHFeEjjcUUXPDGeSEwDN0Xg8sivxMhJNjGzbHd8PkM3eHRfkrBM5NkcQaY2vUnTlrDIA0NoaX+KLXFFlowr14tvVpqb2MICzmQcKqxvbumv+NAhZGCCIPwEw6QWXKYRL/VUXO0+rAUJiPwAk5MIlgVfwPjjHLCL1APmHN94ZdqeYN+NW/mn6I4BvwQYchcLnwFhJMDiYmlRxAzjpKWZkYkUCcZ2I61wi37tLbYyjiN0fHk5Oz3nGSLSzBbNHCF35R7f6K1/hN9PRhek11FrymfQQQKB4+Gl05P2qNRtmETlXW7e+b2z01dfycGNbfFMAbqNyKp9Jp4rzOT8RYFs0njJkc2iqsCObvTsOsDWWqA5C1uFy+Uz/oXJeKwVT4h0RmPUXhi79vuC0Ku6yOffTK3g9lfxfDQAisY516sg5kfOCiJk7HoLt2cf9b/9LANAc7dznm98PagG1fUOZ9IP5uMB8Q4CPoyNvausapkTt3rNMuvdf3C/o6+czhtdwmwAAAABJRU5ErkJggg==</icon>
13+
</dashboard-extension>
14+
<resources>
15+
<resource id="name">
16+
<text locale="en_US">Viz Image Sample</text>
17+
</resource>
18+
</resources>
19+
</manifest>

Samples/VizImage/vizImage.html

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<title>Viz Image Sample</title>
8+
9+
<!-- jQuery -->
10+
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
11+
12+
<!-- Bootstrap -->
13+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" >
14+
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" ></script>
15+
16+
<!-- Extensions Library (this will be hosted on a CDN eventually) -->
17+
<script src="../../lib/tableau.extensions.1.latest.js"></script>
18+
19+
<!-- Our extension's code -->
20+
<script src="./vizImage.js"></script>
21+
</head>
22+
<body>
23+
<div class="container">
24+
<h4>Viz Image Sample</h4>
25+
<div id="viz-options">
26+
<select id="mark-select" class="form-select" aria-label="Default select example" disabled="true">
27+
<option selected disabled>Mark Type</option>
28+
<option value="bar">Bar</option>
29+
<option value="line">Line</option>
30+
<option value="area">Area</option>
31+
<option value="square">Square</option>
32+
<option value="circle">Circle</option>
33+
<option value="text">Text</option>
34+
</select>
35+
<!-- See all color palettes available: https://tableau.github.io/extensions-api/docs/trex_tableau_viz_ref.html -->
36+
<select id="color-select" class="form-select" aria-label="Default select example" disabled="true">
37+
<option selected disabled>Color Palette</option>
38+
<option value="tableau20_10_0">Tableau 20</option>
39+
<option value="summer_10_0">Summer</option>
40+
<option value="winter_10_0">Winter</option>
41+
<option value="color_blind_10_0">Color Blind</option>
42+
</select>
43+
</div>
44+
<hr>
45+
<div id="viz-container"></div>
46+
</div>
47+
</body>
48+
</html>

Samples/VizImage/vizImage.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
'use strict';
2+
3+
// Wrap everything in an anonymous function to avoid polluting the global namespace
4+
(function () {
5+
$(document).ready(function () {
6+
tableau.extensions.initializeAsync().then(function () {
7+
addVizImage(tableau.MarkType.Bar, 'tableau20_10_0');
8+
9+
let markSelector = $('#mark-select');
10+
let colorSelector = $('#color-select');
11+
12+
markSelector.prop('disabled', false);
13+
colorSelector.prop('disabled', false);
14+
15+
// updating viz images with new values upon a selector change.
16+
markSelector.change(function () {
17+
addVizImage(markSelector.val(), colorSelector.val());
18+
});
19+
colorSelector.change(function () {
20+
addVizImage(markSelector.val(), colorSelector.val());
21+
});
22+
});
23+
});
24+
25+
// This function creates and displays a viz image.
26+
function addVizImage (markType, palette) {
27+
// Building the input specification object that is used to create the viz image.
28+
// Data values used in the viz image are prefilled.
29+
const vizInputSpec = {
30+
description: 'A sample viz', // optional parameter.
31+
size: {width: 400, height: 300},
32+
data: {
33+
values: [
34+
{'Product': 'Paper', 'Sales': 28, 'Region': 'Central'},
35+
{'Product': 'Pens', 'Sales': 45, 'Region': 'East'},
36+
{'Product': 'Rulers', 'Sales': 35, 'Region': 'East'},
37+
{'Product': 'Rulers', 'Sales': 43, 'Region': 'South'},
38+
{'Product': 'Paper', 'Sales': 50, 'Region': 'West'},
39+
{'Product': 'Pens', 'Sales': 56, 'Region': 'West'}
40+
]
41+
},
42+
mark: markType,
43+
markcolor: '#FFED5F', // may not get used in viz if color is encoded in viz.
44+
encoding: {
45+
columns: {field: 'Region', type: tableau.VizImageEncodingType.Discrete},
46+
rows: {field: 'Sales', type: tableau.VizImageEncodingType.Continuous},
47+
color: {field: 'Product', type: tableau.VizImageEncodingType.Discrete, palette}
48+
}
49+
};
50+
51+
// defaulting values if null.
52+
if (markType === null) {
53+
vizInputSpec.mark = tableau.MarkType.Bar;
54+
}
55+
if (palette === null) {
56+
vizInputSpec.encoding.color.palette = 'tableau20_10_0';
57+
}
58+
59+
// making call to create viz image from the input specifications.
60+
tableau.extensions.createVizImageAsync(vizInputSpec).then(function (svg) {
61+
var blob = new Blob([svg], { type: 'image/svg+xml' });
62+
var url = URL.createObjectURL(blob);
63+
var image = document.createElement('img');
64+
image.src = url;
65+
image.style.maxWidth = '100%';
66+
image.style.maxHeight = '100%';
67+
image.className = 'center-block';
68+
var vizApiElement = document.getElementById('viz-container');
69+
// clearing UI and adding in new viz.
70+
vizApiElement.innerHTML = '';
71+
vizApiElement.appendChild(image);
72+
image.addEventListener('load', function () { return URL.revokeObjectURL(url); }, { once: true });
73+
}, function (err) {
74+
console.log(err);
75+
});
76+
}
77+
})();

webpack.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module.exports = {
77
datasources: './Samples-Typescript/DataSources/datasources.ts',
88
filtering: './Samples-Typescript/Filtering/filtering.ts',
99
parameters: './Samples-Typescript/Parameters/parameters.ts',
10+
vizImage: './Samples-Typescript/VizImage/vizImage.ts',
1011
},
1112
mode: 'production',
1213
output: {

0 commit comments

Comments
 (0)