How it works
- You generate a card with your data via Tako’s Visualize API as usual and receive a
card_id
and avisualization_data
object. - To render: you have two options:
- Option A: use the
TakoZDREmbed
widget to create an iframe and POST thevisualization_data
for you, or - Option B: POST the
visualization_data
directly to the embed URL with an HTML<form>
that targets an<iframe>
.
- Option A: use the
- Data is not stored by Tako; it exists only in your request and the user’s browser.
Option A: Use the ZDR Embed widget
- Include the widget in your app (serve the file from your app or a CDN):
Copy
Ask AI
<script src="zdr_embed_widget.js"></script>
- Create a container where the chart will render:
Copy
Ask AI
<div id="my-zdr-chart"></div>
- Render using your
card_id
andvisualization_data
:
Copy
Ask AI
const chart = window.TakoZDREmbed.render({
containerId: "my-zdr-chart",
takoUrl: "https://trytako.com", // or your self-hosted Tako URL
cardId: "YOUR_CARD_ID",
visualizationData: {
viz_config: { /* chart config */ },
data: { /* chart data */ }
},
width: "100%",
height: "600px"
});
Full ZDR Embed Widget
Full ZDR Embed Widget
Copy
Ask AI
/**
* Tako ZDR Chart Embed Widget
*
* A standalone JavaScript snippet for embedding Tako charts with Zero Data Retention (ZDR).
* This widget allows you to embed charts without storing sensitive data on Tako's servers.
*
* Usage:
*
* <div id="my-chart"></div>
* <script>
* TakoZDREmbed.render({
* containerId: 'my-chart',
* takoUrl: 'https://trytako.com',
* cardId: 'ABC123xyz',
* visualizationData: {
* viz_config: { ... },
* data: { ... }
* }
* });
* </script>
*/
(function (window) {
"use strict";
const TakoZDREmbed = {
/**
* Render a ZDR chart embed
*
* @param {Object} options - Configuration options
* @param {string} options.containerId - DOM element ID where the chart will be embedded
* @param {string} options.takoUrl - Base URL of your Tako instance (e.g., 'https://trytako.com')
* @param {string} options.cardId - The chart card ID returned from the visualize API
* @param {Object} options.visualizationData - The visualization_data object containing viz_config and data
* @param {Object} options.visualizationData.viz_config - The chart configuration
* @param {Object} options.visualizationData.data - The chart data
* @param {number} [options.width] - Width of the iframe (default: '100%')
* @param {number} [options.height] - Height of the iframe (default: '600px')
* @param {Function} [options.onLoad] - Callback function called when chart loads
* @param {Function} [options.onError] - Callback function called if there's an error
*
* @returns {Object} - Object with iframe element and destroy method
*/
render: function (options) {
// Validate required options
if (!options.containerId) {
throw new Error("TakoZDREmbed: containerId is required");
}
if (!options.takoUrl) {
throw new Error("TakoZDREmbed: takoUrl is required");
}
if (!options.cardId) {
throw new Error("TakoZDREmbed: cardId is required");
}
if (!options.visualizationData) {
throw new Error("TakoZDREmbed: visualizationData is required");
}
if (!options.visualizationData.viz_config) {
throw new Error(
"TakoZDREmbed: visualizationData.viz_config is required"
);
}
if (!options.visualizationData.data) {
throw new Error("TakoZDREmbed: visualizationData.data is required");
}
// Get container element
const container = document.getElementById(options.containerId);
if (!container) {
throw new Error(
"TakoZDREmbed: Container element not found: " + options.containerId
);
}
// Set default dimensions
const width = options.width || "100%";
const height = options.height || "600px";
// Create embed URL
const embedUrl =
options.takoUrl.replace(/\/$/, "") + "/embed/" + options.cardId + "/";
// Create iframe
const iframeName = "tako-zdr-embed-" + options.cardId + "-" + Date.now();
const iframe = document.createElement("iframe");
iframe.name = iframeName;
iframe.id = iframeName;
iframe.style.width = width;
iframe.style.height = height;
iframe.style.border = "none";
iframe.setAttribute("scrolling", "no");
iframe.setAttribute("frameborder", "0");
// Add load handler
if (options.onLoad) {
iframe.addEventListener("load", function () {
options.onLoad(iframe);
});
}
// Add iframe to container
container.innerHTML = "";
container.appendChild(iframe);
// Create and submit form to iframe
try {
const form = document.createElement("form");
form.method = "POST";
form.action = embedUrl;
form.target = iframeName;
form.style.display = "none";
// Create hidden input with visualization_data
const input = document.createElement("input");
input.type = "hidden";
input.name = "visualization_data";
input.value = JSON.stringify(options.visualizationData);
form.appendChild(input);
document.body.appendChild(form);
// Submit form
form.submit();
// Clean up form after a short delay
setTimeout(function () {
if (form.parentNode) {
document.body.removeChild(form);
}
}, 100);
} catch (error) {
if (options.onError) {
options.onError(error);
} else {
console.error("TakoZDREmbed: Error creating embed:", error);
}
}
// Return object with iframe reference and destroy method
return {
iframe: iframe,
destroy: function () {
if (iframe.parentNode) {
iframe.parentNode.removeChild(iframe);
}
},
update: function (newVisualizationData) {
// Re-render with new data
TakoZDREmbed.render({
containerId: options.containerId,
takoUrl: options.takoUrl,
cardId: options.cardId,
visualizationData: newVisualizationData,
width: width,
height: height,
onLoad: options.onLoad,
onError: options.onError,
});
},
};
},
/**
* Render multiple charts at once
*
* @param {Array} charts - Array of chart configuration objects
* @returns {Array} - Array of chart instances
*/
renderMultiple: function (charts) {
return charts.map(function (chartConfig) {
return TakoZDREmbed.render(chartConfig);
});
},
};
// Expose to global scope
window.TakoZDREmbed = TakoZDREmbed;
})(window);
Option B: Direct POST to the embed (no widget)
Use this minimal helper to POSTvisualization_data
into the Tako embed iframe.
Copy
Ask AI
// ============================================
// Tako Embed - Minimal Integration Snippet
// ============================================
// CONFIGURATION
const TAKO_EMBED_ID = 'YOUR_EMBED_ID'; // Replace with your Tako embed ID
const TAKO_URL = 'https://staging.trytako.com'; // Or production URL
// Your visualization data
const VISUALIZATION_DATA = {
viz_config: {
// Your viz_config object here
}
};
// ============================================
/**
* Load Tako embed into an iframe with POST data
* @param {string} iframeId - The ID of your iframe element
* @param {string} embedId - Your Tako embed ID
* @param {object} visualizationData - Your visualization data object
* @param {string} takoUrl - Tako base URL (default: staging)
*/
function loadTakoEmbed(iframeId, embedId, visualizationData, takoUrl = 'https://staging.trytako.com') {
const iframe = document.getElementById(iframeId);
if (!iframe) {
console.error(`Iframe with id "${iframeId}" not found`);
return;
}
// Create form for POST submission
const form = document.createElement('form');
form.method = 'POST';
form.action = `${takoUrl}/embed/${embedId}/`;
form.target = iframe.name || iframeId;
form.style.display = 'none';
// Add visualization data as hidden input
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'visualization_data';
input.value = JSON.stringify(visualizationData);
form.appendChild(input);
// Submit form to iframe
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
}
// USAGE EXAMPLE:
// 1. Add an iframe to your page: <iframe id="tako-embed" name="tako-embed"></iframe>
// 2. Call: loadTakoEmbed('tako-embed', TAKO_EMBED_ID, VISUALIZATION_DATA, TAKO_URL);
End-to-end flow
- Call
POST /v1/beta/visualize
with your data and query. - Extract
card_id
andvisualization_data
from the response. - Render with either the widget or direct form-post approach shown above.