No project description provided
Project description
fh-echarts
Install
pip install fh-echarts
Or install latest from GitHub:
pip install git+https://github.com/markkvdb/fh-echarts.git
Quick Start
Add echarts_header() to your FastHTML app headers, then use EChart()
to render charts:
from fasthtml.common import *
from fh_echarts.core import echarts_header, EChart
app, rt = fast_app(hdrs=(echarts_header(),))
@rt('/')
def get():
options = {
"xAxis": {"type": "category", "data": ["Mon", "Tue", "Wed", "Thu", "Fri"]},
"yAxis": {"type": "value"},
"series": [{"data": [120, 200, 150, 80, 70], "type": "bar"}]
}
return Titled("My Chart", EChart(options))
serve()
Features
Basic Bar Chart
Pass an ECharts option dict to EChart(). Use preview_echart() to
preview charts in notebooks.
options = {
"xAxis": {"type": "category", "data": ["Mon", "Tue", "Wed", "Thu", "Fri"]},
"yAxis": {"type": "value"},
"series": [{"data": [120, 200, 150, 80, 70], "type": "bar"}]
}
preview_echart(EChart(options, chart_id="idx_bar"))
Dark Theme
Pass theme="dark" (or "light") to use ECharts’ built-in themes.
options_dark = {
"title": {"text": "Dark Theme"},
"xAxis": {"data": ["A", "B", "C", "D"]},
"yAxis": {},
"series": [{"type": "bar", "data": [10, 25, 15, 30]}]
}
preview_echart(EChart(options_dark, chart_id="idx_dark", theme="dark"))
JavaScript Functions with JSFunc
ECharts uses JavaScript functions for custom tooltips, axis labels, etc.
Normally
json.dumps
would turn these into literal strings. Wrap them in JSFunc() and
they’ll be revived as real JS functions in the browser.
options_fmt = {
"title": {"text": "Custom Tooltip"},
"tooltip": {
"formatter": JSFunc("function(p) { return '<b>' + p.name + '</b>: $' + p.value.toLocaleString(); }")
},
"xAxis": {"data": ["Shirts", "Sweaters", "Hats", "Shoes"]},
"yAxis": {"axisLabel": {
"formatter": JSFunc("function(v) { return '$' + v; }")
}},
"series": [{"type": "bar", "data": [500, 2000, 360, 1200]}]
}
preview_echart(EChart(options_fmt, chart_id="idx_fmt", theme="dark"))
Line and Pie Charts
Any ECharts chart type works — just set "type" in the series.
line_opts = {
"title": {"text": "Temperature (°C)"},
"xAxis": {"type": "category", "data": ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]},
"yAxis": {"type": "value", "axisLabel": {
"formatter": JSFunc("function(v) { return v + '°C'; }")
}},
"series": [{"type": "line", "data": [2, 5, 12, 18, 24, 28], "smooth": True}]
}
preview_echart(EChart(line_opts, chart_id="idx_line"))
pie_opts = {
"title": {"text": "Browser Share", "left": "center"},
"tooltip": {
"formatter": JSFunc("function(p) { return p.name + ': ' + p.percent + '%'; }")
},
"series": [{
"type": "pie", "radius": "60%",
"data": [
{"value": 65, "name": "Chrome"},
{"value": 18, "name": "Safari"},
{"value": 10, "name": "Firefox"},
{"value": 7, "name": "Other"}
]
}]
}
preview_echart(EChart(pie_opts, chart_id="idx_pie"))
HTMX Click Integration
Turn chart clicks into server requests with hx_get_click. When a user
clicks a data point, an HTMX GET request is fired with name, value,
and seriesName as query parameters.
@rt('/')
def get():
options = {
"xAxis": {"data": ["Jan", "Feb", "Mar"]},
"yAxis": {},
"series": [{"name": "Revenue", "type": "bar", "data": [100, 200, 150]}]
}
return Div(
EChart(options,
hx_get_click="/bar-clicked",
hx_target_click="#result"),
Div(id="result")
)
@rt('/bar-clicked')
def get(name: str, value: int, seriesName: str):
return P(f"Clicked {name} ({seriesName}): {value}")
Dynamic Updates with EChartUpdate
Update an existing chart without re-creating it. Return an
EChartUpdate from a route to merge new options into the chart.
import random
@rt('/')
def get():
options = {
"xAxis": {"data": ["A", "B", "C"]},
"yAxis": {},
"series": [{"type": "bar", "data": [10, 20, 30]}]
}
return Div(
EChart(options, chart_id="updatable"),
Button("Randomize", hx_get="/randomize", hx_target="#update-slot"),
Div(id="update-slot")
)
@rt('/randomize')
def get():
new_data = [random.randint(5, 100) for _ in range(3)]
return EChartUpdate("updatable", {"series": [{"data": new_data}]})
Set merge=False to replace all options instead of merging.
Memory Cleanup
When HTMX removes a chart from the DOM (e.g. navigating tabs or swapping
content), the ECharts instance and ResizeObserver are automatically
disposed via the htmx:beforeCleanupElement event. No extra code
needed.
API Reference
| Function | Description |
|---|---|
echarts_header(version) |
CDN script tag for ECharts (default v5.5.0) |
EChart(options, ...) |
Render a chart with optional theme, hx_get_click, hx_target_click |
EChartUpdate(chart_id, options, merge) |
Update an existing chart instance |
JSFunc(js_string) |
Mark a string as raw JavaScript (for formatters, callbacks, etc.) |
preview_echart(echart, height) |
Preview a chart in a notebook via iframe |
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fh_echarts-0.2.1.tar.gz.
File metadata
- Download URL: fh_echarts-0.2.1.tar.gz
- Upload date:
- Size: 10.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
82dc94ece731037bcb5593d1e384983aecc30c0becdf1fb443b3660c3d588a58
|
|
| MD5 |
d420155a6dc27dcc1c76bc8a60189000
|
|
| BLAKE2b-256 |
35bdf8c28b72bdff0200c1947d5ed367293d3a3aa69921f2648e944327a3fcfb
|
File details
Details for the file fh_echarts-0.2.1-py3-none-any.whl.
File metadata
- Download URL: fh_echarts-0.2.1-py3-none-any.whl
- Upload date:
- Size: 10.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3caac7fd2b783068d44902aaf1ebbc8b53dd1a28b2cb9cc805bd2efe36b0d782
|
|
| MD5 |
28886055336c522cc9154adbcceb184a
|
|
| BLAKE2b-256 |
6b455fa194c59f68f7c82ea86bd6bd54053fef7f84c453ea2332de38813fd7d9
|