diff --git a/Samples-Typescript/MoveAndResize/MoveAndResize.trex b/Samples-Typescript/MoveAndResize/MoveAndResize.trex
new file mode 100644
index 00000000..42f1032e
--- /dev/null
+++ b/Samples-Typescript/MoveAndResize/MoveAndResize.trex
@@ -0,0 +1,19 @@
+
+
+
+ en_US
+
+ MoveAndResize Sample
+
+ 1.7
+
+ http://localhost:8765/Samples-Typescript/MoveAndResize/moveandresize.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==
+
+
+
+ MoveAndResize Sample
+
+
+
\ No newline at end of file
diff --git a/Samples-Typescript/MoveAndResize/moveAndResize.tsx b/Samples-Typescript/MoveAndResize/moveAndResize.tsx
new file mode 100644
index 00000000..71c74f9f
--- /dev/null
+++ b/Samples-Typescript/MoveAndResize/moveAndResize.tsx
@@ -0,0 +1,83 @@
+import { Dashboard, DashboardObject, Size } from '@tableau/extensions-api-types';
+import * as React from 'react';
+import * as ReactDOM from 'react-dom';
+
+// Wrap everything in an anonymous function to avoid polluting the global namespace
+(async () => {
+
+ interface IDashboardObjectPositionAndSizeUpdate {
+ dashboardObjectID: number;
+ height: number;
+ width: number;
+ y: number;
+ x: number;
+ }
+
+// Utilizes DashboardObjectPositionAndSizeUpdate to store resizeable dashboard objects (must be floating and visible)
+// Calls moveAndResizeDashboardObjects to resize and reposition objects stored in the array
+ class MoveAndResize extends React.Component {
+
+ public static async initialize() {
+ console.log('Initializing extension API');
+ await tableau.extensions.initializeAsync();
+ ReactDOM.render(
+ , document.getElementById('moveAndResizeExample'));
+ }
+
+ private moveAndResizeDashboardObjects(dashboardSize: Size): IDashboardObjectPositionAndSizeUpdate[] {
+ const dashboardObjectPositionAndSizeUpdateArray: IDashboardObjectPositionAndSizeUpdate[] = [];
+ const dashboardObjects: DashboardObject[] = tableau.extensions.dashboardContent.dashboard.objects;
+ const floatingItems = this.getFloatingAndVisibleItemsCount(dashboardObjects);
+ const squareSize: number = Math.ceil(Math.sqrt(floatingItems));
+ const heightSize: number = Math.floor(dashboardSize.height / squareSize);
+ const widthSize: number = Math.floor(dashboardSize.width / squareSize);
+ let currentX: number = 0;
+ let currentY: number = 0;
+
+ dashboardObjects.forEach((dashboardObject) => {
+ if (dashboardObject.isFloating && dashboardObject.isVisible) {
+ const dashboardObjectPositionAndSizeUpdate: IDashboardObjectPositionAndSizeUpdate = {
+ dashboardObjectID: dashboardObject.id,
+ height: heightSize,
+ width: widthSize,
+ x: currentX * widthSize,
+ y: currentY * heightSize
+ };
+ dashboardObjectPositionAndSizeUpdateArray.push(dashboardObjectPositionAndSizeUpdate);
+ currentX++;
+ if (currentX >= squareSize) {
+ currentX = 0;
+ currentY++;
+ }
+ }
+ });
+
+ return dashboardObjectPositionAndSizeUpdateArray;
+ }
+
+ private getFloatingAndVisibleItemsCount(dashboardObjects: DashboardObject[]): number {
+ let totalFloatingItems: number = 0;
+ dashboardObjects.forEach((dashboardObject: DashboardObject) => {
+ if (dashboardObject.isFloating && dashboardObject.isVisible) {
+ totalFloatingItems++;
+ }
+ });
+
+ return totalFloatingItems;
+ }
+
+ private handleClickAndResizeZones = (): void => {
+ const dashboard: Dashboard = tableau.extensions.dashboardContent.dashboard;
+ const positionAndSizeUpdateArray = this.moveAndResizeDashboardObjects(dashboard.size);
+ dashboard.moveAndResizeDashboardObjectsAsync(positionAndSizeUpdateArray);
+ }
+
+ public render(): JSX.Element {
+ return ;
+ }
+ }
+
+ await MoveAndResize.initialize();
+})();
diff --git a/Samples-Typescript/MoveAndResize/moveandresize.html b/Samples-Typescript/MoveAndResize/moveandresize.html
new file mode 100644
index 00000000..8cd3ae62
--- /dev/null
+++ b/Samples-Typescript/MoveAndResize/moveandresize.html
@@ -0,0 +1,31 @@
+
+
+
+
+ Tableau MoveAndResize Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Tableau Move And Resize Sample
+
Dashboard objects must be floating and visible in order to be moved or resized
+
+
+
+
\ No newline at end of file
diff --git a/Samples-Typescript/ReplayAnimation/ReplayAnimation.trex b/Samples-Typescript/ReplayAnimation/ReplayAnimation.trex
new file mode 100644
index 00000000..7672f7d1
--- /dev/null
+++ b/Samples-Typescript/ReplayAnimation/ReplayAnimation.trex
@@ -0,0 +1,19 @@
+
+
+
+ en_US
+
+ Replay Animation Sample
+
+ 1.1
+
+ http://localhost:8765/Samples-Typescript/ReplayAnimation/replayanimation.html
+
+ iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAAB3RJTUUH4QgLDTYEcBRoeAAABp9JREFUeNrlm01sHEUWx//vVbs79gThjAd2iflIAkEcEARfEciBSYLEbbV8SJaDEpIAMQgkViuirA8IskKcdiEJX3G0C5dNpAVxQLIyiYw4YYIQBw4RBoMgBBIbCRtnOsx0vbcHd9sTZ3r8ge2p2bQ0B/+7unp+1dX/eX71ivL5TgAwAAQAxR/rsiYidvv2btq6ddcqVRwE8JCqgoigqgAAIvpKVbf29v51cHDwUxWRav2pWbdujcH04cUnPFc1EZGOjtv5hRdebv3tt9I+IupWVSaiGBxgJqhqlpnPj42NnchmsxpFUbX+mJORiE9E8eigorEzmohEHR23U1/fO63j47/+nYh2qqpJ4CcHgKEKMPOxIPBfef75PeUwDNPuoclozGxgXdMq4X/5ZWwfEe1Q1crZO/UKENGxIPCfKBbD4U2bNvo17qEeAHYJNA3+jjtuW2x4TgbAAmhyATRNy+XauK/vndaxsfEXFwk+0SIv/kNR/d2rOzwAc+TIu5ExnCeiR2vA9weB3zNXeM/zImutSUzQWfgYUpnNlapa6eCVP3slIjoShheGN2++Z1b4q6/+Q3T69Jng7Nlz0hAmODFxhq+4ol1S4AHAF5Fe3286u2PH1v5Dh9724nOX9Hf8+IfllpaWm8Mw3E2Eo4wGMMGVK1cLM6fBJ9q6cjna39W1c0tX14PW9/2q8JlMy01hGL4C4GlV/IsxHRnVHTRNi2G5BnyirbPWHty+vSe/YcOt5Pv+JfDFYrgfwBYAUNX1jGkTrDtoLU1E7CzwybEWwBsvvfSPe9evvxHGsKbAg4imwk1yBRTVTRCe5xlr7WzwibYGwOsHDry1O4qi/pnwAMDMEBEkL5YToGlaGP7E1tpaJlhNW2ut3e953rZiMfxnJXxlu4aIBJub/1gyxngiMlf4RLvRWnsQgF+tHRGp8yZYKAyUgiC4RVW75gmfaCtQ3UDLqnrUaRMsFAZKK1asuKVcLr+pqncuAD5NswAONzc3P+lsJDgD/q5Fhu/L5bJ/C8Nw1EkTXHr4tr3nzo2Obtx4NzlngssDPzKaz3d6xrBbJriM8E00mUayzvw7vEB4JaL3VfUDZjYARERgjGFrrY01FZGJtrZsoQI+ua9xIhJcKDwzHWU2T5dKpbP9/e/RNdes1h9++J7b26+TH388QwBw/fVrdGjoFJ869aXOgPcQJ0TQyPDd3Q+Pbtq0sQnTma0IF2e4Es2bCY965wQXA/67777nBX4XBlA/E6wzvEG8SFIXE3QAPtGWPyfoELyH+BXAZQq/vCboIPzymaCD8Mtngo7CJ9rSmqDj8Etrgg0Av3Qm2CDwS2OCDQK/NCbYQPCJtngm2IDwi2eCDQq/OCbYwPC/3wQbGD7dBEUkuuqqHHd0bLDbtj0iJ09+wu3t15XiFFM0mXY6zfff/+dSc3PDwieaoXy+M6mgrKzGWjU+Pp5nNq1xchEAWESsMcZYa4WZPVXtmseKjWvwF+cEK+vwkmosa22yNj8FlSxRz3Oh0kl4JCY4nyLEBWiuwk+a4PnzRXsZwk+ZIKlaam1dtSquvb1c4BONiJmzqvoiEe26zOA9ABER0X+I8CfVqcWE3wsPZnqf2ezq7n74Z5fhEQdCD4poNXgBcGEhAyKiH5TL5XOOwzMAZlWli+vtpwuPmflxAF/PdzYwM6dVajqkEQDLafBB4PdYa//d1OQ9parDc4WPD4n7dQG0lmbiJ6Uz4Z8oFsPhzZvv8ffs+Uu/MaYHwDdzhIeIYGLijFOFFymaXlQ9NbPeXkSijz/+xPT07DxGRI8T0bdzeRWMMbxy5WpxCDTdBIloSCR9s4G1loaGvsZzzz1zAsBjyUyoNRustXZGdUa9QWua4CPM/Krvp282KJVK3ueff6GHDx84bozZDWB4FhN0CbR2JLhly708PPytd+21qyNjTM2LiAiFwkDZ87xt1trXAATVZgMz77LWvpXPd85l20pdI0G21uratTfMCg8AhcJAOZNpucla+0AaPIBIRCYGB080hAl6ACAis15UreS8CrwFcLitLXu8UPgw2YvoAmjNSHDWJzUP+L5crm3vyMjoyMDAR67DT5ogZskJzhe+SilavUFrR4KYzglectGzzz4ZZTKZm4vF8NX/M/hEq7owwgCQybREvb37gmKxuBvAfcD0NpNKwwNwKJfLTpWfVoHnKl/CFU05fvoUN9D4ExWLIZ88+dkFIjoK4KsEXkSmBkBV/xsEwd6RkZ9H8/lOJiKN+7mkP1e1/wFtM6PWK/V/BwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wOC0xMVQxMzo1NDowNC0wNDowMMrC9wEAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDgtMTFUMTM6NTQ6MDQtMDQ6MDC7n0+9AAAAAElFTkSuQmCC
+
+
+
+ Replay Animation Sample
+
+
+
\ No newline at end of file
diff --git a/Samples-Typescript/ReplayAnimation/replayAnimation.tsx b/Samples-Typescript/ReplayAnimation/replayAnimation.tsx
new file mode 100644
index 00000000..3a3e2870
--- /dev/null
+++ b/Samples-Typescript/ReplayAnimation/replayAnimation.tsx
@@ -0,0 +1,65 @@
+import { ReplaySpeedType } from '@Tableau/extensions-api-types';
+import * as React from 'react';
+import * as ReactDOM from 'react-dom';
+
+// Wrap everything in an anonymous function to avoid polluting the global namespace
+(async () => {
+ interface IReplayAnimationState {
+ speed: ReplaySpeedType;
+ }
+
+// Calls replayAnimationSync to toggle dashboard animation speed (0.5x, 1.0x, 2.0x) using ReplaySpeedType
+ class ReplayAnimation extends React.PureComponent<{}, IReplayAnimationState> {
+ constructor(props = {}) {
+ super(props);
+ this.state = { speed: tableau.ReplaySpeedType.Normal };
+ this.handleChange = this.handleChange.bind(this);
+ }
+
+ public static async initialize(): Promise {
+ console.log('Initializing extension API');
+ await tableau.extensions.initializeAsync();
+ ReactDOM.render(, document.getElementById('replaySelector'));
+ }
+
+ public render(): JSX.Element {
+ return (
+ <>
+
+
+
+
+ >
+ );
+ }
+
+ private handleChange = (event) => {
+ switch (event.target.value) {
+ case tableau.ReplaySpeedType.Slow: {
+ this.setState({ speed: tableau.ReplaySpeedType.Slow });
+ break;
+ }
+ case tableau.ReplaySpeedType.Normal: {
+ this.setState({ speed: tableau.ReplaySpeedType.Normal });
+ break;
+ }
+ case tableau.ReplaySpeedType.Fast: {
+ this.setState({ speed: tableau.ReplaySpeedType.Fast });
+ break;
+ }
+ }
+ }
+
+ private replayAnimation = () => {
+ tableau.extensions.dashboardContent.dashboard.replayAnimationAsync(this.state.speed).then(() => {
+ console.log('done');
+ });
+ }
+ }
+
+ await ReplayAnimation.initialize();
+})();
diff --git a/Samples-Typescript/ReplayAnimation/replayanimation.html b/Samples-Typescript/ReplayAnimation/replayanimation.html
new file mode 100644
index 00000000..674d1d17
--- /dev/null
+++ b/Samples-Typescript/ReplayAnimation/replayanimation.html
@@ -0,0 +1,30 @@
+
+
+
+
+ Replay Animation Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Replay Animation Sample
+
+
+
+
\ No newline at end of file
diff --git a/Samples/MoveAndResize/MoveAndResize.trex b/Samples/MoveAndResize/MoveAndResize.trex
new file mode 100644
index 00000000..0583a8d2
--- /dev/null
+++ b/Samples/MoveAndResize/MoveAndResize.trex
@@ -0,0 +1,19 @@
+
+
+
+ en_US
+
+ MoveAndResize Sample
+
+ 1.7
+
+ http://localhost:8765/Samples/MoveAndResize/moveandresize.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==
+
+
+
+ MoveAndResize Sample
+
+
+
\ No newline at end of file
diff --git a/Samples/MoveAndResize/moveAndResize.js b/Samples/MoveAndResize/moveAndResize.js
new file mode 100644
index 00000000..7863450d
--- /dev/null
+++ b/Samples/MoveAndResize/moveAndResize.js
@@ -0,0 +1,74 @@
+'use strict';
+var React;
+var ReactDOM;
+
+// Wrap everything in an anonymous function to avoid polluting the global namespace
+(async () => {
+// Utilizes DashboardObjectPositionAndSizeUpdate to store resizeable dashboard objects (must be floating and visible)
+// Calls moveAndResizeDashboardObjects to resize and reposition objects stored in the array
+ class MoveAndResize extends React.Component {
+ constructor () {
+ super(...arguments);
+ this.handleClickAndResizeZones = () => {
+ const dashboard = tableau.extensions.dashboardContent.dashboard;
+ const positionAndSizeUpdateArray = this.moveAndResizeDashboardObjects(dashboard.size);
+ dashboard.moveAndResizeDashboardObjectsAsync(positionAndSizeUpdateArray);
+ };
+ }
+ static async initialize () {
+ console.log('Initializing extension API');
+ await tableau.extensions.initializeAsync();
+ ReactDOM.render(React.createElement(MoveAndResize, null),
+ document.getElementById('moveAndResizeExample'));
+ }
+
+ render () {
+ return React.createElement('button', { className: 'btn btn-primary',
+ onClick: this.handleClickAndResizeZones }, 'Click to resize');
+ }
+
+ moveAndResizeDashboardObjects (dashboardSize) {
+ const dashboardObjectPositionAndSizeUpdateArray = [];
+ const dashboardObjects = tableau.extensions.dashboardContent.dashboard.objects;
+ const floatingItems = this.getFloatingAndVisibleItemsCount(dashboardObjects);
+ const squareSize = Math.ceil(Math.sqrt(floatingItems));
+ const heightSize = Math.floor(dashboardSize.height / squareSize);
+ const widthSize = Math.floor(dashboardSize.width / squareSize);
+ let currentX = 0;
+ let currentY = 0;
+
+ dashboardObjects.forEach((dashboardObject) => {
+ if (dashboardObject.isFloating && dashboardObject.isVisible) {
+ const dashboardObjectPositionAndSizeUpdate = {
+ dashboardObjectID: dashboardObject.id,
+ height: heightSize,
+ width: widthSize,
+ x: currentX * widthSize,
+ y: currentY * heightSize
+ };
+ dashboardObjectPositionAndSizeUpdateArray.push(dashboardObjectPositionAndSizeUpdate);
+ currentX++;
+ if (currentX >= squareSize) {
+ currentX = 0;
+ currentY++;
+ }
+ }
+ });
+
+ return dashboardObjectPositionAndSizeUpdateArray;
+ }
+
+ getFloatingAndVisibleItemsCount (dashboardObjects) {
+ let totalFloatingItems = 0;
+ dashboardObjects.forEach((dashboardObject) => {
+ if (dashboardObject.isFloating && dashboardObject.isVisible) {
+ totalFloatingItems++;
+ }
+ });
+
+ return totalFloatingItems;
+ }
+ }
+
+ await MoveAndResize.initialize();
+})();
diff --git a/Samples/MoveAndResize/moveandresize.html b/Samples/MoveAndResize/moveandresize.html
new file mode 100644
index 00000000..6d33ae6b
--- /dev/null
+++ b/Samples/MoveAndResize/moveandresize.html
@@ -0,0 +1,36 @@
+
+
+
+
+ Tableau MoveAndResize Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Tableau Move And Resize Sample
+
Dashboard objects must be floating and visible to move or resize
+
+
+
+
\ No newline at end of file
diff --git a/Samples/ReplayAnimation/ReplayAnimation.trex b/Samples/ReplayAnimation/ReplayAnimation.trex
new file mode 100644
index 00000000..1eb4f638
--- /dev/null
+++ b/Samples/ReplayAnimation/ReplayAnimation.trex
@@ -0,0 +1,19 @@
+
+
+
+ en_US
+
+ Replay Animation Sample (Javascript)
+
+ 1.1
+
+ http://localhost:8765/Samples/ReplayAnimation/replayanimation.html
+
+ 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
+
+
+
+ Replay Animation Sample (Javascript)
+
+
+
\ No newline at end of file
diff --git a/Samples/ReplayAnimation/replayAnimation.js b/Samples/ReplayAnimation/replayAnimation.js
new file mode 100644
index 00000000..bc348945
--- /dev/null
+++ b/Samples/ReplayAnimation/replayAnimation.js
@@ -0,0 +1,57 @@
+'use strict';
+var React;
+var ReactDOM;
+
+(async () => {
+// Calls replayAnimationSync to toggle dashboard animation speed (0.5x, 1.0x, 2.0x) using ReplaySpeedType
+ class ReplayAnimation extends React.PureComponent {
+ constructor (props = {}) {
+ super(props);
+ this.handleChange = (event) => {
+ switch (event.target.value) {
+ case tableau.ReplaySpeedType.Slow: {
+ this.setState({ speed: tableau.ReplaySpeedType.Slow });
+ break;
+ }
+ case tableau.ReplaySpeedType.Normal: {
+ this.setState({ speed: tableau.ReplaySpeedType.Normal });
+ break;
+ }
+ case tableau.ReplaySpeedType.Fast: {
+ this.setState({ speed: tableau.ReplaySpeedType.Fast });
+ break;
+ }
+ }
+ };
+
+ this.replayAnimation = () => {
+ tableau.extensions.dashboardContent.dashboard.replayAnimationAsync(this.state.speed).then(() => {
+ console.log('done');
+ });
+ };
+ this.state = { speed: tableau.ReplaySpeedType.Normal };
+ this.handleChange = this.handleChange.bind(this);
+ }
+
+ static async initialize () {
+ console.log('Initializing extension API');
+ await tableau.extensions.initializeAsync();
+ ReactDOM.render(React.createElement(ReplayAnimation, null), document.getElementById('replaySelector'));
+ }
+
+ render () {
+ return (React.createElement(React.Fragment, null,
+ React.createElement('div', null,
+ React.createElement('select', { value: this.state.speed, onChange: this.handleChange },
+ React.createElement('option', { value: tableau.ReplaySpeedType.Slow }, 'Slow'),
+ React.createElement('option', { value: tableau.ReplaySpeedType.Normal }, 'Normal'),
+ React.createElement('option', { value: tableau.ReplaySpeedType.Fast }, 'Fast')),
+ React.createElement('button', { className: 'btn btn-secondary btn-sm', onClick: this.replayAnimation }, 'Replay')
+ )
+ ));
+ }
+ }
+
+ console.log('Initializing Replay Animation extension.');
+ await ReplayAnimation.initialize();
+})();
diff --git a/Samples/ReplayAnimation/replayanimation.html b/Samples/ReplayAnimation/replayanimation.html
new file mode 100644
index 00000000..0b6742bc
--- /dev/null
+++ b/Samples/ReplayAnimation/replayanimation.html
@@ -0,0 +1,35 @@
+
+
+
+
+ Replay Animation Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Replay Animation Sample
+
+
+
+
+
\ No newline at end of file
diff --git a/webpack.config.js b/webpack.config.js
index 91a521ca..657e8159 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -8,8 +8,10 @@ module.exports = {
datasources: './Samples-Typescript/DataSources/datasources.ts',
filtering: './Samples-Typescript/Filtering/filtering.ts',
formatting: './Samples-Typescript/Formatting/formatting.tsx',
+ moveAndResize: './Samples-Typescript/MoveAndResize/moveAndResize.tsx',
parameters: './Samples-Typescript/Parameters/parameters.ts',
dashboardObjectVisibility: './Samples-Typescript/DashboardObjectVisibility/dashboardObjectVisibility.tsx',
+ replayAnimation: './Samples-Typescript/ReplayAnimation/replayAnimation.tsx',
vizImage: './Samples-Typescript/VizImage/vizImage.ts',
},
mode: 'production',
@@ -34,5 +36,10 @@ module.exports = {
optimization: {
minimize: false
},
- devtool: 'inline-source-map'
+ devtool: 'inline-source-map',
+ performance: {
+ hints: false,
+ maxEntrypointSize: 370,
+ maxAssetSize: 370
+ }
};