Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions Samples-Typescript/MoveAndResize/MoveAndResize.trex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest manifest-version="0.1" xmlns="http://www.tableau.com/xml/extension_manifest">
<dashboard-extension id="com.tableau.extensions.samples.moveAndResize" extension-version="0.1.0">
<default-locale>en_US</default-locale>
<name resource-id="name"/>
<description>MoveAndResize Sample</description>
<author name="tableau" email="projectfrelard@tableau.com" organization="tableau" website="https://www.tableau.com"/>
<min-api-version>1.7</min-api-version>
<source-location>
<url>http://localhost:8765/Samples-Typescript/MoveAndResize/moveandresize.html</url>
</source-location>
<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>
</dashboard-extension>
<resources>
<resource id="name">
<text locale="en_US">MoveAndResize Sample</text>
</resource>
</resources>
</manifest>
83 changes: 83 additions & 0 deletions Samples-Typescript/MoveAndResize/moveAndResize.tsx
Original file line number Diff line number Diff line change
@@ -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(
<MoveAndResize />, 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 <button className='btn btn-primary' onClick={this.handleClickAndResizeZones}>
Click to resize
</button>;
}
}

await MoveAndResize.initialize();
})();
31 changes: 31 additions & 0 deletions Samples-Typescript/MoveAndResize/moveandresize.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<style>
.container {
position: relative;
display: block;
}
</style>
<head>
<title>Tableau MoveAndResize Demo</title>

<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>

<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<script src="../../lib/tableau.extensions.1.latest.js"></script>

<!-- Our webpack'd extension's code -->
<script src="../../dist/moveAndResize.js"></script>
</head>
<body>
<div class="container">
<h2>Tableau Move And Resize Sample</h2>
<p>Dashboard objects must be floating and visible in order to be moved or resized</p>
<div id="moveAndResizeExample"></div>
</div>
</body>
</html>
19 changes: 19 additions & 0 deletions Samples-Typescript/ReplayAnimation/ReplayAnimation.trex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest manifest-version="0.1" xmlns="http://www.tableau.com/xml/extension_manifest">
<dashboard-extension id="com.tableau.extensions.samples.replayAnimation" extension-version="0.1.0">
<default-locale>en_US</default-locale>
<name resource-id="name"/>
<description>Replay Animation Sample</description>
<author name="tableau" email="projectfrelard@tableau.com" organization="tableau" website="https://www.tableau.com"/>
<min-api-version>1.1</min-api-version>
<source-location>
<url>http://localhost:8765/Samples-Typescript/ReplayAnimation/replayanimation.html</url>
</source-location>
<icon>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</icon>
</dashboard-extension>
<resources>
<resource id="name">
<text locale="en_US">Replay Animation Sample</text>
</resource>
</resources>
</manifest>
65 changes: 65 additions & 0 deletions Samples-Typescript/ReplayAnimation/replayAnimation.tsx
Original file line number Diff line number Diff line change
@@ -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<void> {
console.log('Initializing extension API');
await tableau.extensions.initializeAsync();
ReactDOM.render(<ReplayAnimation></ReplayAnimation>, document.getElementById('replaySelector'));
}

public render(): JSX.Element {
return (
<>
<div>
<select value={this.state.speed} onChange={this.handleChange}>
<option value={tableau.ReplaySpeedType.Slow}>Slow</option>
<option value={tableau.ReplaySpeedType.Normal}>Normal</option>
<option value={tableau.ReplaySpeedType.Fast}>Fast</option>
</select>
<button className='btn btn-secondary btn-sm' onClick={this.replayAnimation}>Replay</button>
</div>
</>
);
}

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();
})();
30 changes: 30 additions & 0 deletions Samples-Typescript/ReplayAnimation/replayanimation.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html>
<style>
.container-header {
position: relative;
display: block;
}
</style>
<head>
<title>Replay Animation Demo</title>

<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>

<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<script src="../../lib/tableau.extensions.1.latest.js"></script>

<!-- Our extension's code -->
<script src="../../dist/replayAnimation.js"></script>
</head>
<body>
<div class="container">
<h2>Replay Animation Sample</h2>
<div id="replaySelector"></div>
</div>
</body>
</html>
19 changes: 19 additions & 0 deletions Samples/MoveAndResize/MoveAndResize.trex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest manifest-version="0.1" xmlns="http://www.tableau.com/xml/extension_manifest">
<dashboard-extension id="com.tableau.extensions.samples.moveandresize" extension-version="0.1.0">
<default-locale>en_US</default-locale>
<name resource-id="name"/>
<description>MoveAndResize Sample</description>
<author name="tableau" email="github@tableau.com" organization="tableau" website="https://www.tableau.com"/>
<min-api-version>1.7</min-api-version>
<source-location>
<url>http://localhost:8765/Samples/MoveAndResize/moveandresize.html</url>
</source-location>
<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>
</dashboard-extension>
<resources>
<resource id="name">
<text locale="en_US">MoveAndResize Sample</text>
</resource>
</resources>
</manifest>
74 changes: 74 additions & 0 deletions Samples/MoveAndResize/moveAndResize.js
Original file line number Diff line number Diff line change
@@ -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();
})();
36 changes: 36 additions & 0 deletions Samples/MoveAndResize/moveandresize.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<style>
.container {
position: relative;
display: block;
}

</style>
<head>
<title>Tableau MoveAndResize Demo</title>

<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>

<!-- React -->
<script src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>

<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<script src="../../lib/tableau.extensions.1.latest.js"></script>

<!-- Our extension's code -->
<script src="./moveAndResize.js"></script>
</head>
<body>
<div class="container">
<h2>Tableau Move And Resize Sample</h2>
<p>Dashboard objects must be floating and visible to move or resize</p>
<div id="moveAndResizeExample"></div>
</div>
</body>
</html>
Loading