Skip to content

ChartJS

ChartJS is an optional Chart.js integration for teams that want the Chart.js ecosystem while keeping Faststrap's core package lightweight.

Core Faststrap still ships Chart. Use ChartJS when you specifically want Chart.js configuration, plugins, or behavior.

Install

pip install faststrap

The chartjs extra is intentionally dependency-free in the Python package. The integration loads Chart.js from a CDN unless you pass your own asset URL, so no additional Python dependency is required.

Faststrap exposes CHARTJS_VERSION and CHARTJS_CDN_URL when you need to inspect or reuse the default pinned asset. ChartJSType is the type alias for supported Chart.js chart kinds.

Import

from faststrap import ChartJS, add_chartjs

Add Assets

app, rt = fast_app()
add_chartjs(app)

Basic Usage

ChartJS(
    "revenue-chart",
    type="bar",
    data={
        "labels": ["Jan", "Feb", "Mar"],
        "datasets": [
            {"label": "Revenue", "data": [120, 180, 240]},
        ],
    },
)

With Options

ChartJS(
    "conversion-chart",
    type="line",
    data={
        "labels": ["Mon", "Tue", "Wed"],
        "datasets": [{"label": "Conversion", "data": [4.2, 5.1, 4.8]}],
    },
    options={
        "plugins": {"legend": {"display": False}},
        "scales": {"y": {"beginAtZero": True}},
    },
    height=260,
)

Parameters

Param Type Description
chart_id str Canvas element ID. Must be unique on the page.
type ChartJSType Chart.js chart type.
data dict | None Chart.js data config.
options dict | None Chart.js options config.
height int | None Canvas height.
width int | None Canvas width.
responsive bool Adds Chart.js responsive option.

faststrap.integrations.chartjs.chartjs_assets(*, version=CHARTJS_VERSION, cdn_url=None, defer=True)

Return script tags required by Chart.js.

Source code in src/faststrap/integrations/chartjs.py
def chartjs_assets(
    *,
    version: str = CHARTJS_VERSION,
    cdn_url: str | None = None,
    defer: bool = True,
) -> tuple[Any, ...]:
    """Return script tags required by Chart.js."""
    source = cdn_url or f"https://cdn.jsdelivr.net/npm/chart.js@{version}/dist/chart.umd.min.js"
    return (Script(src=source, defer=defer),)

faststrap.integrations.chartjs.add_chartjs(app, *, version=CHARTJS_VERSION, cdn_url=None, defer=True)

Attach Chart.js assets to a FastHTML app once.

Source code in src/faststrap/integrations/chartjs.py
def add_chartjs(
    app: Any,
    *,
    version: str = CHARTJS_VERSION,
    cdn_url: str | None = None,
    defer: bool = True,
) -> None:
    """Attach Chart.js assets to a FastHTML app once."""
    if getattr(app, "_faststrap_chartjs_loaded", False):
        return
    app.hdrs.extend(chartjs_assets(version=version, cdn_url=cdn_url, defer=defer))
    app._faststrap_chartjs_loaded = True

faststrap.integrations.chartjs.ChartJS(chart_id, *, type='line', data=None, options=None, height=None, width=None, responsive=True, **kwargs)

Render a Chart.js canvas and initialization script.

Source code in src/faststrap/integrations/chartjs.py
def ChartJS(
    chart_id: str,
    *,
    type: ChartJSType = "line",
    data: dict[str, Any] | None = None,
    options: dict[str, Any] | None = None,
    height: int | None = None,
    width: int | None = None,
    responsive: bool = True,
    **kwargs: Any,
) -> Div:
    """Render a Chart.js canvas and initialization script."""
    user_cls = kwargs.pop("cls", "")
    attrs: dict[str, Any] = {
        "cls": merge_classes("faststrap-chartjs position-relative", user_cls),
        "data_fs_chartjs": "true",
    }
    attrs.update(convert_attrs(kwargs))

    chart_data = data or {"labels": [], "datasets": []}
    chart_options = {"responsive": responsive, **(options or {})}
    config = {"type": type, "data": chart_data, "options": chart_options}
    config_json = json.dumps(config, separators=(",", ":"))
    script = f"""
(() => {{
  const init = () => {{
    const canvas = document.getElementById({chart_id!r});
    if (!canvas || !window.Chart || canvas.dataset.fsChartjsInit === "true") return;
    canvas.dataset.fsChartjsInit = "true";
    new window.Chart(canvas, {config_json});
  }};
  if (document.readyState === "loading") {{
    document.addEventListener("DOMContentLoaded", init);
  }} else {{
    init();
  }}
  document.addEventListener("htmx:afterSwap", init);
}})();
"""

    canvas_attrs: dict[str, Any] = {"id": chart_id}
    if height is not None:
        canvas_attrs["height"] = height
    if width is not None:
        canvas_attrs["width"] = width

    return Div(Canvas(**canvas_attrs), Script(NotStr(script)), **attrs)