Skip to main content

Exporting Vizly Charts to HTML, JSON, and Images

Vizly charts export in three forms: self-contained HTML for sharing and embedding, a plain JSON option for APIs and SPAs, and images rendered from the browser for reports and slides. Each export path serves a different need.

Self-contained HTML

to_html() returns a full HTML document with vendored ECharts inlined. It works offline, has no CDN dependency, and opens in any browser.

import vizly as vz

chart = vz.bar(data, x="region", y="sales", title="Sales")
html = chart.to_html()

# Or write it to a file directly
chart.render("sales.html")

JSON option dicts

to_option() returns the resolved ECharts option as a plain dict. This is the format for APIs, SPAs, and AI agents that render charts themselves.

option = chart.to_option()      # dict
json_string = chart.to_json() # JSON string, optionally indented
json_string = chart.to_json(indent=2)

from_option() does the reverse: it wraps an existing ECharts option dict as a Vizly chart so you can theme and export it through the same pipeline.

chart = vz.from_option({...})

Browser-rendered images

Images come from the browser that already rendered the chart, via ECharts getDataURL. Vizly does not ship a server-side Chromium. After a chart is embedded, grab the chart id and call the image helpers.

const id = document.querySelector(".vizly-chart").id;
window.__vizly[id].toDataURL({ type: "png", pixelRatio: 2 });
window.__vizly[id].downloadImage("chart.png");

You can also enable the built-in toolbox save button so users export without any JavaScript.

chart.merge_option({
"toolbox": {
"feature": {
"saveAsImage": {"type": "png"},
},
},
})

Headless batch export

For scheduled reports and automated pipelines, render the HTML in headless Chromium. Vizly does not bundle a browser, so use Playwright (or similar) on the output of chart.to_html().

import asyncio
from playwright.async_api import async_playwright

async def export_png(chart, path: str) -> None:
html = chart.to_html()
async with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page()
await page.set_content(html)
await page.wait_for_selector(".vizly-chart")
await page.locator(".vizly-chart").screenshot(path=path)
await browser.close()

asyncio.run(export_png(chart, "report.png"))

Choosing an export path

NeedExport
Share a file or open in a browserchart.render("out.html")
Embed in a page or appchart.to_html() / chart.to_html(fragment=True)
Send options to an API or SPAchart.to_option() / chart.to_json()
PNG, JPEG, or SVG for reportsBrowser toDataURL / downloadImage, or toolbox saveAsImage
Scheduled batch imagesPlaywright on chart.to_html()

Tips

TipDetail
No server-side renderingVizly does not bundle Chromium. Browser export uses the page that already rendered the chart.
Screenshots need a waitWait for the .vizly-chart element before screenshotting so GL and animations settle.
JSON skips GeoJSONto_option() returns the ECharts option only. Maps register GeoJSON in the HTML path.
Emails like imagesFor email reports, render PNG via Playwright rather than embedding live HTML.