Interactive Visualization
Deploy single-file interactive HTML to a live HTTPS URL using Cloudflare Workers temporary deploy. No account, no login, no server to run. The user taps the link, it opens in Telegram's in-app browser, full interactivity.
When to use
- Quiz / assessment. Choices, instant feedback, score (like ChatGPT interactive widgets)
- What-if explorer. Sliders/selections drive live causal results (like Gemini visualizations: "if X changes, Y becomes…")
- Decision tree. Step-by-step choices leading to leaf outcomes
- Custom. Any self-contained interactive HTML the agent writes from scratch
Two modes
1. Template mode (preferred when a template fits)
Call viz_create with a template type and a config object. The tool injects your config into the template engine and writes a ready-to-deploy HTML file. You never touch HTML directly.
viz_create(template="quiz", config={
title: "...",
description: "...",
questions: [
{ q: "...", options: ["A","B","C","D"], answer: 0, explain: "..." },
...
],
passRatio: 0.7,
passText: "...",
failText: "..."
})
Templates available:
| template |
use case |
config shape |
quiz |
multiple-choice quiz with scoring |
{title, description, questions:[{q, options[], answer, explain}], passRatio, passText, failText} |
causal |
sliders/selects drive live outputs |
{title, description, inputs:[{id, label, type:"range"|"select", min, max, step, default, unit, options[]}], outputs:[{id, label}], evaluate:"JS function body as string"}, select options can be ["단리","복리"] (strings) or [{v:"a",l:"A"},{v:"b",l:"B"}] (objects). tier in evaluate return must be one of: "good", "warn", "bad", "neutral". |
decision-tree |
branching choices lead to leaf results |
{title, description, start, nodes:{id:{type:"question"|"leaf", text, choices:[{label,next}], detail}}} |
causal evaluate: the evaluate field is a string of JS function body. It receives s (a state object mapping each input id to its value) and returns an object that maps each output id to {value, tier, trace}. Example:
evaluate: "const r = Math.min(0.95, 0.3 + s.hours * 0.05); return { retention: {value: Math.round(r*100)+'%', tier: r>0.7?'good':'bad', trace: 'hours=' + s.hours} };"
2. Custom mode
When no template fits, write a complete self-contained HTML file with file_patch:
- Inline all CSS in
<style>, all JS in <script>.
- No external resources (no CDN, no fonts, no images via URL).
- Dark theme, mobile-first, touch-friendly (Telegram in-app browser).
- Keep under 5 MiB (Cloudflare Workers static asset limit).
Deploy
After viz_create (or writing custom HTML), deploy with terminal_run:
mkdir -p /tmp/viz-deploy && cp <output-path> /tmp/viz-deploy/index.html
Create wrangler.toml:
name = "viz-<short-hash>"
compatibility_date = "2024-09-01"
[assets]
directory = "."
Deploy:
cd /tmp/viz-deploy && npx wrangler deploy --temporary
Output contains the live URL:
Deployed viz-xxxx triggers https://viz-xxxx.workers.dev
Send that URL to the user in your reply as a clickable link.
Important notes
- 60-minute expiry: unclaimed temporary deployments are deleted after 60 minutes. For conversational visual aids, temporary is exactly right.
- Rate limits: Cloudflare limits how quickly temporary accounts can be created. If you hit a rate limit, wait and retry.
- Account caching: Wrangler caches the temporary account and reuses it for subsequent
--temporary deploys within the same session.
- No login required:
--temporary explicitly bypasses all auth. If wrangler says "rerun with --temporary", add the flag.
--temporary errors if already authenticated: If wrangler login was previously run, --temporary returns an error. In that case just use wrangler deploy normally.
Workflow summary
viz_create(template, config) → terminal_run(wrangler deploy --temporary) → reply with URL
Behavior rules
- Always verify the deploy succeeded. Check wrangler output for the
https://*.workers.dev URL before telling the user it's live.
- Include the URL in your reply as a clickable link:
[퀴즈 풀러 가기](https://viz-xxxx.workers.dev).
- One visualization per deploy. Don't cram multiple unrelated widgets into one HTML file.
- Keep config realistic. Use real content from the conversation, not placeholder text.
- Korean content. If the user's language is
ko, write UI text in Korean. The templates default to Korean UI labels.
- Mobile-first. Telegram in-app browser is mobile. Tap targets ≥ 44px, no hover-only interactions, no horizontal scroll.
1---2name: visualization3description: Deploy interactive HTML visualizations (quiz, what-if explorer, decision tree, or custom) to a live URL via Cloudflare Workers. Use when the user needs an interactive, clickable visual aid such as choices, buttons, sliders, causal "if this then that" explorers, or step-by-step decision flows. Not for plain charts or static images.4metadata:5 source: https://skillmd.com/skills/gpdir16/visualization6---78# Interactive Visualization910Deploy single-file interactive HTML to a live HTTPS URL using **Cloudflare Workers temporary deploy**. No account, no login, no server to run. The user taps the link, it opens in Telegram's in-app browser, full interactivity.1112## When to use1314- **Quiz / assessment.** Choices, instant feedback, score (like ChatGPT interactive widgets)15- **What-if explorer.** Sliders/selections drive live causal results (like Gemini visualizations: "if X changes, Y becomes…")16- **Decision tree.** Step-by-step choices leading to leaf outcomes17- **Custom.** Any self-contained interactive HTML the agent writes from scratch1819## Two modes2021### 1. Template mode (preferred when a template fits)2223Call **`viz_create`** with a `template` type and a `config` object. The tool injects your config into the template engine and writes a ready-to-deploy HTML file. You never touch HTML directly.2425```26viz_create(template="quiz", config={27 title: "...",28 description: "...",29 questions: [30 { q: "...", options: ["A","B","C","D"], answer: 0, explain: "..." },31 ...32 ],33 passRatio: 0.7,34 passText: "...",35 failText: "..."36})37```3839Templates available:4041| template | use case | config shape |42| --------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |43| `quiz` | multiple-choice quiz with scoring | `{title, description, questions:[{q, options[], answer, explain}], passRatio, passText, failText}` |44| `causal` | sliders/selects drive live outputs | `{title, description, inputs:[{id, label, type:"range"\|"select", min, max, step, default, unit, options[]}], outputs:[{id, label}], evaluate:"JS function body as string"}`, select `options` can be `["단리","복리"]` (strings) or `[{v:"a",l:"A"},{v:"b",l:"B"}]` (objects). `tier` in evaluate return must be one of: `"good"`, `"warn"`, `"bad"`, `"neutral"`. |45| `decision-tree` | branching choices lead to leaf results | `{title, description, start, nodes:{id:{type:"question"\|"leaf", text, choices:[{label,next}], detail}}}` |4647**`causal` evaluate**: the `evaluate` field is a string of JS function body. It receives `s` (a state object mapping each input id to its value) and returns an object that maps each output id to `{value, tier, trace}`. Example:4849```50evaluate: "const r = Math.min(0.95, 0.3 + s.hours * 0.05); return { retention: {value: Math.round(r*100)+'%', tier: r>0.7?'good':'bad', trace: 'hours=' + s.hours} };"51```5253### 2. Custom mode5455When no template fits, write a complete self-contained HTML file with `file_patch`:5657- Inline all CSS in `<style>`, all JS in `<script>`.58- No external resources (no CDN, no fonts, no images via URL).59- Dark theme, mobile-first, touch-friendly (Telegram in-app browser).60- Keep under 5 MiB (Cloudflare Workers static asset limit).6162## Deploy6364After `viz_create` (or writing custom HTML), deploy with `terminal_run`:6566```bash67mkdir -p /tmp/viz-deploy && cp <output-path> /tmp/viz-deploy/index.html68```6970Create `wrangler.toml`:7172```toml73name = "viz-<short-hash>"74compatibility_date = "2024-09-01"7576[assets]77directory = "."78```7980Deploy:8182```bash83cd /tmp/viz-deploy && npx wrangler deploy --temporary84```8586Output contains the live URL:8788```89Deployed viz-xxxx triggers https://viz-xxxx.workers.dev90```9192**Send that URL to the user** in your reply as a clickable link.9394### Important notes9596- **60-minute expiry**: unclaimed temporary deployments are deleted after 60 minutes. For conversational visual aids, temporary is exactly right.97- **Rate limits**: Cloudflare limits how quickly temporary accounts can be created. If you hit a rate limit, wait and retry.98- **Account caching**: Wrangler caches the temporary account and reuses it for subsequent `--temporary` deploys within the same session.99- **No login required**: `--temporary` explicitly bypasses all auth. If wrangler says "rerun with --temporary", add the flag.100- **`--temporary` errors if already authenticated**: If `wrangler login` was previously run, `--temporary` returns an error. In that case just use `wrangler deploy` normally.101102## Workflow summary103104```105viz_create(template, config) → terminal_run(wrangler deploy --temporary) → reply with URL106```107108## Behavior rules1091101. **Always verify the deploy succeeded.** Check wrangler output for the `https://*.workers.dev` URL before telling the user it's live.1112. **Include the URL in your reply** as a clickable link: `[퀴즈 풀러 가기](https://viz-xxxx.workers.dev)`.1123. **One visualization per deploy.** Don't cram multiple unrelated widgets into one HTML file.1134. **Keep config realistic.** Use real content from the conversation, not placeholder text.1145. **Korean content.** If the user's language is `ko`, write UI text in Korean. The templates default to Korean UI labels.1156. **Mobile-first.** Telegram in-app browser is mobile. Tap targets ≥ 44px, no hover-only interactions, no horizontal scroll.