From 6b691996a866968725022229c12fa0757c06ee87 Mon Sep 17 00:00:00 2001 From: smontesdeoca Date: Wed, 8 Sep 2021 16:52:25 -0700 Subject: [PATCH 1/5] working viz for sample --- Samples/VizImage/VizImage.trex | 19 ++++++++++++ Samples/VizImage/vizImage.html | 29 ++++++++++++++++++ Samples/VizImage/vizImage.js | 54 ++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 Samples/VizImage/VizImage.trex create mode 100644 Samples/VizImage/vizImage.html create mode 100644 Samples/VizImage/vizImage.js diff --git a/Samples/VizImage/VizImage.trex b/Samples/VizImage/VizImage.trex new file mode 100644 index 00000000..684f9612 --- /dev/null +++ b/Samples/VizImage/VizImage.trex @@ -0,0 +1,19 @@ + + + + en_US + + Viz Image Sample + + 1.6 + + http://localhost:8765/Samples/VizImage/vizImage.html + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAlhJREFUOI2Nkt9vy1EYh5/3bbsvRSySCZbIxI+ZCKsN2TKtSFyIrV2WuRCJuBiJWxfuxCVXbvwFgiEtposgLFJElnbU1SxIZIIRJDKTrdu+53Uhra4mce7Oe57Pcz7JOULFisViwZ+29LAzOSjQYDgz1ZcCvWuXV11MJpN+OS/lm6179teqH0yDqxPTCyKSA8DcDsyOmOprnCaeP7459pdgy969i0LTC3IO/RQMyoHcQN+3cnljW3dNIFC47qDaK3g7BwdTkwBaBELT4ZPOUVWgKl4ZBnjxJPUlMDnTDrp0pmr6RHFeEjjcUUXPDGeSEwDN0Xg8sivxMhJNjGzbHd8PkM3eHRfkrBM5NkcQaY2vUnTlrDIA0NoaX+KLXFFlowr14tvVpqb2MICzmQcKqxvbumv+NAhZGCCIPwEw6QWXKYRL/VUXO0+rAUJiPwAk5MIlgVfwPjjHLCL1APmHN94ZdqeYN+NW/mn6I4BvwQYchcLnwFhJMDiYmlRxAzjpKWZkYkUCcZ2I61wi37tLbYyjiN0fHk5Oz3nGSLSzBbNHCF35R7f6K1/hN9PRhek11FrymfQQQKB4+Gl05P2qNRtmETlXW7e+b2z01dfycGNbfFMAbqNyKp9Jp4rzOT8RYFs0njJkc2iqsCObvTsOsDWWqA5C1uFy+Uz/oXJeKwVT4h0RmPUXhi79vuC0Ku6yOffTK3g9lfxfDQAisY516sg5kfOCiJk7HoLt2cf9b/9LANAc7dznm98PagG1fUOZ9IP5uMB8Q4CPoyNvausapkTt3rNMuvdf3C/o6+czhtdwmwAAAABJRU5ErkJggg== + + + + Viz Image Sample + + + diff --git a/Samples/VizImage/vizImage.html b/Samples/VizImage/vizImage.html new file mode 100644 index 00000000..be660556 --- /dev/null +++ b/Samples/VizImage/vizImage.html @@ -0,0 +1,29 @@ + + + + + + + Viz Image Sample + + + + + + + + + + + + + + + +
+
+ +
+
+ + diff --git a/Samples/VizImage/vizImage.js b/Samples/VizImage/vizImage.js new file mode 100644 index 00000000..dbec54a0 --- /dev/null +++ b/Samples/VizImage/vizImage.js @@ -0,0 +1,54 @@ +'use strict'; + +// Wrap everything in an anonymous function to avoid polluting the global namespace +(function () { + // Building the input specification object that is used to create the viz image. + // Data values used in the viz image are prefilled. + const vizInputSpec = { + description: "A sample viz", // optional parameter + title: "Sales By Region", // optional parameter + size: {width: 400, height: 300}, + data: { + values: [ + {"Product": "Paper", "Sales": 28, "Region": "Central", "Employees": 100}, + {"Product": "Pens", "Sales": 45, "Region": "East", "Employees": 200}, + {"Product": "Rulers", "Sales": 35, "Region": "East", "Employees": 200}, + {"Product": "Rulers", "Sales": 43, "Region": "South", "Employees": 350}, + {"Product": "Paper", "Sales": 50, "Region": "West", "Employees": 500}, + {"Product": "Pens", "Sales": 56, "Region": "West", "Employees": 500} + ] + }, + mark: tableau.MarkType.Bar, + markcolor: "#FFED5F", // may not get used in viz if color is encoded in viz + encoding: { + columns: {field: "Region", type: tableau.VizImageEncodingType.Discrete, hidden: "true"}, + rows: {field: "Sales", type: tableau.VizImageEncodingType.Continuous}, + color: {field: "Product", type: tableau.VizImageEncodingType.Discrete, palette: "tableau20_10_0"}, + size: {field: "Employees", type: tableau.VizImageEncodingType.Continuous}, + } + }; + + $(document).ready(function () { + tableau.extensions.initializeAsync().then(function () { + addVizImage(); + }); + }); + + // This function uses the input specifications to create a viz image, the returned + // SVG image is then displayed on the extension. + function addVizImage () { + tableau.extensions.createVizImageAsync(vizInputSpec).then(function (svg) { + console.log(svg); + var blob = new Blob([svg], { type: 'image/svg+xml' }); + var url = URL.createObjectURL(blob); + var image = document.createElement('img'); + image.src = url; + image.style.maxWidth = '100%'; + var vizApiElement = document.getElementById('viz-container'); + vizApiElement.appendChild(image); + image.addEventListener('load', function () { return URL.revokeObjectURL(url); }, { once: true }); + }, function (err) { + console.log(err); + }); + } +})(); \ No newline at end of file From a28e78f57504f99f9753325ffabdbda5bcaae95f Mon Sep 17 00:00:00 2001 From: smontesdeoca Date: Thu, 9 Sep 2021 14:27:34 -0700 Subject: [PATCH 2/5] javascript sample finished --- Samples/VizImage/vizImage.html | 25 +++++++++-- Samples/VizImage/vizImage.js | 80 ++++++++++++++++++++++------------ 2 files changed, 73 insertions(+), 32 deletions(-) diff --git a/Samples/VizImage/vizImage.html b/Samples/VizImage/vizImage.html index be660556..f093da43 100644 --- a/Samples/VizImage/vizImage.html +++ b/Samples/VizImage/vizImage.html @@ -21,9 +21,28 @@
-
- -
+

Viz Image Sample

+
+ + + +
+
+
diff --git a/Samples/VizImage/vizImage.js b/Samples/VizImage/vizImage.js index dbec54a0..cbf6e2f4 100644 --- a/Samples/VizImage/vizImage.js +++ b/Samples/VizImage/vizImage.js @@ -2,49 +2,71 @@ // Wrap everything in an anonymous function to avoid polluting the global namespace (function () { - // Building the input specification object that is used to create the viz image. - // Data values used in the viz image are prefilled. - const vizInputSpec = { - description: "A sample viz", // optional parameter - title: "Sales By Region", // optional parameter - size: {width: 400, height: 300}, - data: { - values: [ - {"Product": "Paper", "Sales": 28, "Region": "Central", "Employees": 100}, - {"Product": "Pens", "Sales": 45, "Region": "East", "Employees": 200}, - {"Product": "Rulers", "Sales": 35, "Region": "East", "Employees": 200}, - {"Product": "Rulers", "Sales": 43, "Region": "South", "Employees": 350}, - {"Product": "Paper", "Sales": 50, "Region": "West", "Employees": 500}, - {"Product": "Pens", "Sales": 56, "Region": "West", "Employees": 500} - ] - }, - mark: tableau.MarkType.Bar, - markcolor: "#FFED5F", // may not get used in viz if color is encoded in viz - encoding: { - columns: {field: "Region", type: tableau.VizImageEncodingType.Discrete, hidden: "true"}, - rows: {field: "Sales", type: tableau.VizImageEncodingType.Continuous}, - color: {field: "Product", type: tableau.VizImageEncodingType.Discrete, palette: "tableau20_10_0"}, - size: {field: "Employees", type: tableau.VizImageEncodingType.Continuous}, - } - }; - $(document).ready(function () { tableau.extensions.initializeAsync().then(function () { - addVizImage(); + addVizImage(tableau.MarkType.Bar, "tableau20_10_0"); + + let markSelector = $('#mark-select'); + markSelector.prop('disabled', false); + + let colorSelector = $('#color-select'); + colorSelector.prop('disabled', false); + + // updating viz images with new values upon a selector change + markSelector.change(function () { + addVizImage(markSelector.val(),colorSelector.val()); + }); + colorSelector.change(function () { + addVizImage(markSelector.val(),colorSelector.val()); + }); }); }); // This function uses the input specifications to create a viz image, the returned // SVG image is then displayed on the extension. - function addVizImage () { + function addVizImage (markType, colorPalette) { + // Building the input specification object that is used to create the viz image. + // Data values used in the viz image are prefilled. + const vizInputSpec = { + description: "A sample viz", // optional parameter + size: {width: 400, height: 300}, + data: { + values: [ + {"Product": "Paper", "Sales": 28, "Region": "Central"}, + {"Product": "Pens", "Sales": 45, "Region": "East"}, + {"Product": "Rulers", "Sales": 35, "Region": "East"}, + {"Product": "Rulers", "Sales": 43, "Region": "South"}, + {"Product": "Paper", "Sales": 50, "Region": "West"}, + {"Product": "Pens", "Sales": 56, "Region": "West"} + ] + }, + mark: markType, + markcolor: "#FFED5F", // may not get used in viz if color is encoded in viz + encoding: { + columns: {field: "Region", type: tableau.VizImageEncodingType.Discrete}, + rows: {field: "Sales", type: tableau.VizImageEncodingType.Continuous}, + color: {field: "Product", type: tableau.VizImageEncodingType.Discrete, palette: colorPalette}, + } + }; + + // defaulting values if undefined + if (markType == undefined) { + vizInputSpec.mark = "bar"; + } + if (colorPalette == undefined) { + vizInputSpec.encoding.color.palette = "tableau20_10_0"; + } + tableau.extensions.createVizImageAsync(vizInputSpec).then(function (svg) { - console.log(svg); var blob = new Blob([svg], { type: 'image/svg+xml' }); var url = URL.createObjectURL(blob); var image = document.createElement('img'); image.src = url; image.style.maxWidth = '100%'; + image.style.maxHeight = '100%'; + image.className = 'center-block'; var vizApiElement = document.getElementById('viz-container'); + vizApiElement.innerHTML = ''; vizApiElement.appendChild(image); image.addEventListener('load', function () { return URL.revokeObjectURL(url); }, { once: true }); }, function (err) { From a59f1d9c3f4633574cc0d857e9c07677ace8593a Mon Sep 17 00:00:00 2001 From: Sean Mann Date: Thu, 9 Sep 2021 14:58:54 -0700 Subject: [PATCH 3/5] update tabextsandbox version --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 57670803..2fe90cc1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -92,9 +92,9 @@ } }, "@tableau/tabextsandbox": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@tableau/tabextsandbox/-/tabextsandbox-1.1.0.tgz", - "integrity": "sha512-uWo+JsyCHhBg2bNBt6Y47Drv1AM7CuOZ0veTy88tu+dMYTI3SApL0J/eWajJmSz9EAs+ZLxYzQLO0auTb2nnGw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@tableau/tabextsandbox/-/tabextsandbox-1.2.1.tgz", + "integrity": "sha512-psZ8OVb1fcJvcQnSbZXW2LzDBivr5YYUTrt+6H8iiRepILmuC19HYvuPXTu2JFKliUD9fnVrsm/wRrMn6NhXrQ==", "dev": true, "requires": { "ejs": "^2.6.1", diff --git a/package.json b/package.json index 5cb7edef..3692fdc4 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ }, "devDependencies": { "@tableau/extensions-api-types": "1.6.0", - "@tableau/tabextsandbox": "^1.1.0", + "@tableau/tabextsandbox": "^1.2.1", "@types/jquery": "^3.3.29", "concurrently": "^6.2.1", "semistandard": "^11.0.0", From f2e0f69901176fa44046c00706e01b98dfdea926 Mon Sep 17 00:00:00 2001 From: smontesdeoca Date: Thu, 9 Sep 2021 16:41:45 -0700 Subject: [PATCH 4/5] typescript sample added --- Samples-Typescript/VizImage/VizImage.trex | 19 +++++ Samples-Typescript/VizImage/vizImage.html | 48 ++++++++++++ Samples-Typescript/VizImage/vizImage.ts | 92 +++++++++++++++++++++++ Samples/VizImage/vizImage.html | 4 +- Samples/VizImage/vizImage.js | 53 ++++++------- webpack.config.js | 1 + 6 files changed, 189 insertions(+), 28 deletions(-) create mode 100644 Samples-Typescript/VizImage/VizImage.trex create mode 100644 Samples-Typescript/VizImage/vizImage.html create mode 100644 Samples-Typescript/VizImage/vizImage.ts diff --git a/Samples-Typescript/VizImage/VizImage.trex b/Samples-Typescript/VizImage/VizImage.trex new file mode 100644 index 00000000..fdddc5f3 --- /dev/null +++ b/Samples-Typescript/VizImage/VizImage.trex @@ -0,0 +1,19 @@ + + + + en_US + + Viz Image Sample + + 1.6 + + http://localhost:8765/Samples-Typescript/VizImage/vizImage.html + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAlhJREFUOI2Nkt9vy1EYh5/3bbsvRSySCZbIxI+ZCKsN2TKtSFyIrV2WuRCJuBiJWxfuxCVXbvwFgiEtposgLFJElnbU1SxIZIIRJDKTrdu+53Uhra4mce7Oe57Pcz7JOULFisViwZ+29LAzOSjQYDgz1ZcCvWuXV11MJpN+OS/lm6179teqH0yDqxPTCyKSA8DcDsyOmOprnCaeP7459pdgy969i0LTC3IO/RQMyoHcQN+3cnljW3dNIFC47qDaK3g7BwdTkwBaBELT4ZPOUVWgKl4ZBnjxJPUlMDnTDrp0pmr6RHFeEjjcUUXPDGeSEwDN0Xg8sivxMhJNjGzbHd8PkM3eHRfkrBM5NkcQaY2vUnTlrDIA0NoaX+KLXFFlowr14tvVpqb2MICzmQcKqxvbumv+NAhZGCCIPwEw6QWXKYRL/VUXO0+rAUJiPwAk5MIlgVfwPjjHLCL1APmHN94ZdqeYN+NW/mn6I4BvwQYchcLnwFhJMDiYmlRxAzjpKWZkYkUCcZ2I61wi37tLbYyjiN0fHk5Oz3nGSLSzBbNHCF35R7f6K1/hN9PRhek11FrymfQQQKB4+Gl05P2qNRtmETlXW7e+b2z01dfycGNbfFMAbqNyKp9Jp4rzOT8RYFs0njJkc2iqsCObvTsOsDWWqA5C1uFy+Uz/oXJeKwVT4h0RmPUXhi79vuC0Ku6yOffTK3g9lfxfDQAisY516sg5kfOCiJk7HoLt2cf9b/9LANAc7dznm98PagG1fUOZ9IP5uMB8Q4CPoyNvausapkTt3rNMuvdf3C/o6+czhtdwmwAAAABJRU5ErkJggg== + + + + Viz Image Sample + + + diff --git a/Samples-Typescript/VizImage/vizImage.html b/Samples-Typescript/VizImage/vizImage.html new file mode 100644 index 00000000..77062d2e --- /dev/null +++ b/Samples-Typescript/VizImage/vizImage.html @@ -0,0 +1,48 @@ + + + + + + + Viz Image Sample + + + + + + + + + + + + + + + +
+

Viz Image Sample

+
+ + + +
+
+
+
+ + diff --git a/Samples-Typescript/VizImage/vizImage.ts b/Samples-Typescript/VizImage/vizImage.ts new file mode 100644 index 00000000..53e02b46 --- /dev/null +++ b/Samples-Typescript/VizImage/vizImage.ts @@ -0,0 +1,92 @@ +import { MarkType } from '@tableau/extensions-api-types'; + +// Wrap everything in an anonymous function to avoid polluting the global namespace +(async () => { + class VizImage { + // Avoid globals. + constructor(private _$: JQueryStatic) { } + + /** + * Initializes the extension + */ + public async initialize() { + console.log('Waiting for DOM ready'); + await this._$.ready; + console.log('Initializing extension API'); + await tableau.extensions.initializeAsync(); + + await this.addVizImage(tableau.MarkType.Bar, 'tableau20_10_0'); + + const markSelector = this._$('#mark-select'); + const colorSelector = this._$('#color-select'); + + markSelector.prop('disabled', false); + colorSelector.prop('disabled', false); + + // updating viz images with new values upon a selector change + markSelector.change(() => { + this.addVizImage(markSelector.val() as MarkType, colorSelector.val() as string); + }); + colorSelector.change(() => { + this.addVizImage(markSelector.val() as MarkType, colorSelector.val() as string); + }); + } + + /** + * Builds the input specifications and displays the created viz image + * @param markType + * @param colorPalette + */ + private async addVizImage(markType: MarkType, palette: string) { + // Building the input specification object that is used to create the viz image. + // Data values used in the viz image are prefilled. + const vizInputSpec = { + data: { + values: [ + {Product: 'Paper', Sales: 28, Region: 'Central'}, + {Product: 'Pens', Sales: 45, Region: 'East'}, + {Product: 'Rulers', Sales: 35, Region: 'East'}, + {Product: 'Rulers', Sales: 43, Region: 'South'}, + {Product: 'Paper', Sales: 50, Region: 'West'}, + {Product: 'Pens', Sales: 56, Region: 'West'} + ] + }, + description: 'A sample viz', // optional parameter + encoding: { + color: {field: 'Product', type: tableau.VizImageEncodingType.Discrete, palette}, + columns: {field: 'Region', type: tableau.VizImageEncodingType.Discrete}, + rows: {field: 'Sales', type: tableau.VizImageEncodingType.Continuous} + }, + mark: markType, + markcolor: '#FFED5F', // may not get used in viz if color is encoded in viz + size: {width: 400, height: 300} + }; + + // defaulting values if null + if (markType === null) { + vizInputSpec.mark = tableau.MarkType.Bar; + } + if (palette === null) { + vizInputSpec.encoding.color.palette = 'tableau20_10_0'; + } + + const svg = await tableau.extensions.createVizImageAsync(vizInputSpec); + // making call to create viz image from the input specifications + const blob = new Blob([svg], { type: 'image/svg+xml' }); + const url = URL.createObjectURL(blob); + const image = document.createElement('img'); + image.src = url; + image.style.maxWidth = '100%'; + image.style.maxHeight = '100%'; + image.className = 'center-block'; + const vizApiElement = document.getElementById('viz-container'); + // clearing UI and adding in new viz + vizApiElement.innerHTML = ''; + vizApiElement.appendChild(image); + image.addEventListener('load', () => URL.revokeObjectURL(url), { once: true }); + } + } + + console.log('Initializing VizImage extension.'); + await new VizImage($).initialize(); +})(); diff --git a/Samples/VizImage/vizImage.html b/Samples/VizImage/vizImage.html index f093da43..df3d5ade 100644 --- a/Samples/VizImage/vizImage.html +++ b/Samples/VizImage/vizImage.html @@ -24,7 +24,7 @@

Viz Image Sample