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.0.tar.gz (12.2 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.0-py3-none-any.whl (13.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: fh_echarts-0.3.0.tar.gz
  • Upload date:
  • Size: 12.2 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.0.tar.gz
Algorithm Hash digest
SHA256 03dd931ee80a51555d258fd99172ba65c7238592fbe8b2d1dd5959c8e0f42ce5
MD5 67e91970bbb15348561ab83291095b67
BLAKE2b-256 270f4d71afea1d29122634537a69c638916e514c37bf6baefcf46079ddef9683

See more details on using hashes here.

File details

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

File metadata

  • Download URL: fh_echarts-0.3.0-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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 563ff5ec78171b22a9af0856e564eee2e0c86f3e43da9cf4106452c699820ad2
MD5 5e6f3b8fe769c932b1dfc0016e34acec
BLAKE2b-256 94a87ada5d7bd2a843e65bef95c6273824255037505ecd7f6968f1e8dc2d345b

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