Skip to main content

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. By default, name, value, and seriesName are sent as query parameters.

EChart(options, hx_get_click="/bar-clicked", hx_target_click="#result")

@rt('/bar-clicked')
def get(name: str, value: int, seriesName: str):
    return P(f"Clicked {name} ({seriesName}): {value}")

Use hx_click_vals to select which fields to extract from the click event (useful for multi-series charts):

EChart(options, hx_get_click="/clicked",
       hx_click_vals=["name", "seriesIndex", "dataIndex", "data"])

For full control, pass a JS callback via hx_click_cb that receives params and returns a values dict:

EChart(options, hx_get_click="/clicked",
       hx_click_cb=JSFunc("function(params) { return {x: params.data[0], y: params.data[1]}; }"))

### 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.

```python
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.

Run Arbitrary JS with EChartJS

Execute any JavaScript against a chart instance. The callback receives (chart, el) — the ECharts instance and the DOM element.

# Blur a chart
EChartJS("mychart", "function(chart, el) { el.style.filter = 'blur(4px)'; }")

# Stash current data on the DOM element
EChartJS("mychart", "function(chart, el) { el._loadData = chart.getOption().series[0].data; }")

# Append data to a streaming time series
EChartJS("mychart", """function(chart, el) {
    var opt = chart.getOption();
    opt.xAxis[0].data.push('6s');
    opt.series[0].data.push(42);
    chart.setOption(opt);
}""")

OOB Updates with EChartOOB

Wrap chart scripts in an HTMX out-of-band swap container. Useful when returning chart updates alongside other HTML from a route.

@rt('/update')
def get():
    return Div(
        P("Data updated!"),
        EChartOOB(
            EChartUpdate("mychart", {"series": [{"data": new_data}]}),
            EChartJS("mychart", "function(chart, el) { el.style.filter = ''; }")
        )
    )

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.

Pandas Time Series with ts_options

Use ts_options from fh_echarts.helpers to turn a Pandas DataFrame into a time-series chart with minimal code. It auto-detects datetime columns, numeric series, and handles NaNs. The result is a plain dict you can customise before passing to EChart.

from fh_echarts.helpers import ts_options
import pandas as pd, numpy as np

dates = pd.date_range("2024-01-01", periods=30, freq="D")
df = pd.DataFrame({"date": dates,
                    "temperature": 20 + 5 * np.random.randn(30).cumsum() * 0.1,
                    "humidity": 60 + 3 * np.random.randn(30).cumsum() * 0.1})

opts = ts_options(df, x="date")
opts["title"] = {"text": "Weather Station"}
opts["legend"] = {"show": True}
EChart(opts)

Works with DataFrames, DatetimeIndex, individual Series, and you can select specific y columns:

ts_options(df, x="date", y="temperature")
ts_options(df.set_index("date"))
ts_options(df.set_index("date")["temperature"])

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, hx_click_vals, hx_click_cb
EChartUpdate(chart_id, options, merge) Update an existing chart instance
EChartJS(chart_id, js_func) Run arbitrary JS against a chart instance; callback receives (chart, el)
EChartOOB(*scripts, sink_id) Wrap scripts in an OOB-swappable Div for HTMX responses
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
ts_options(data, x, y, kind) Convert a Pandas DataFrame/Series into an ECharts time-series options dict

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

fh_echarts-0.3.1.tar.gz (12.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fh_echarts-0.3.1-py3-none-any.whl (13.1 kB view details)

Uploaded Python 3

File details

Details for the file fh_echarts-0.3.1.tar.gz.

File metadata

  • Download URL: fh_echarts-0.3.1.tar.gz
  • Upload date:
  • Size: 12.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fh_echarts-0.3.1.tar.gz
Algorithm Hash digest
SHA256 157178fdfffe27c83d3aea1f6c72e90566362c16f13190553f1f7ddbd323aecf
MD5 dd371dca56e36c952a067948a007ba3c
BLAKE2b-256 e51c2a9d67676758baed9f3fecb9c820d212f6425b20af2d325fd678a394f83d

See more details on using hashes here.

File details

Details for the file fh_echarts-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: fh_echarts-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 13.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fh_echarts-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 76a3e876a75bc3ab685b2c6c8eb662987cc1d7bf91a23e8f2dedcc816a5e234c
MD5 12a5371ac36c64f91dfd170823ff613f
BLAKE2b-256 1694e95ddbc9a658537da0c170f2b2b888b3b129851642a7b63bd2449c7d9bfe

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page