Skip to main content

Echarts5 custom component for Streamlit

Project description

Streamlit - ECharts5

This is a fork repo of streamlit_echarts. Major changes to upstream:

  1. rename package to streamlit-echarts5, you need to rename all import namespaces`
  2. bump echarts to v5.5.1
  3. bump react to v18
  4. bump react-scripts to v5.0.1
  5. remove React.useCallback since it is out of rules of hooks,it not recommend in loop or conditional. use normal callback to events ,but with React.memo(EchartsChart) to avoid event failling. It's seems good for all demo now,but not tested yet when event callback and props really change at the same time
  6. React.memo component for performance, since streamlit.setComponentValue always rerender parent,and give a set props to a new object,but props not changed actually,React shallow compare treat a new object not equal to old one even their values are equal.egprops = {...props} will call rerender. No rerender in the two examples about events。
  7. add notMerge param to func, mannually handle this,but with default value True
  8. update python build system, use pyproject.toml to manage info, use pdm as venv manager.

Since I Changed too much deps , versions, mechanism, it's not tested egnough and not easy to be accepted by origin Repo. I won't create pull request to origin repo recently,but publish to pypi as streamlit-echarts5.
I won't frequently update this repository. If you have new feature request,try fork this repo when no response from issues

Streamlit App

A Streamlit component to display ECharts.

Install

pip install streamlit-echarts5

Usage

This library provides 2 functions to display echarts :

  • st_echarts to display charts from ECharts json options as Python dicts
  • st_pyecharts to display charts from Pyecharts instances

Check out the demo and source code for more examples.

st_echarts example

from streamlit_echarts5 import st_echarts

options = {
    "xAxis": {
        "type": "category",
        "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
    },
    "yAxis": {"type": "value"},
    "series": [
        {"data": [820, 932, 901, 934, 1290, 1330, 1320], "type": "line"}
    ],
}
st_echarts(options=options)

st_pyecharts example

from pyecharts import options as opts
from pyecharts.charts import Bar
from streamlit_echarts5 import st_pyecharts

b = (
    Bar()
    .add_xaxis(["Microsoft", "Amazon", "IBM", "Oracle", "Google", "Alibaba"])
    .add_yaxis(
        "2017-2018 Revenue in (billion $)", [21.2, 20.4, 10.3, 6.08, 4, 2.2]
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(
            title="Top cloud providers 2018", subtitle="2017-2018 Revenue"
        ),
        toolbox_opts=opts.ToolboxOpts(),
    )
)
st_pyecharts(b)

API

st_echarts API

st_echarts(
    options: Dict
    theme: Union[str, Dict]
    events: Dict[str, str]
    notMerge: bool = True
    height: str
    width: str
    renderer: str
    map: Map
    key: str
)
  • options : Python dictionary that resembles the JSON counterpart of echarts options. For example the basic line chart in JS :
// JS code
option = {
  xAxis: {
    type: "category",
    data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
  },
  yAxis: { type: "value" },
  series: [{ data: [820, 932, 901, 934, 1290, 1330, 1320], type: "line" }],
};

is represented in Python :

# Python code
option = {
    "xAxis": {
        "type": "category",
        "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
    },
    "yAxis": { "type": "value" },
    "series": [
        {"data": [820, 932, 901, 934, 1290, 1330, 1320], "type": "line" }
    ],
}
  • theme : echarts theme. You can specify built-int themes or pass over style configuration as a Python dict.
  • events : Python dictionary which maps an event to a Js function as string. For example :
{
    "click": "function(params) { console.log(params.name) }"
}

will get mapped to :

myChart.on("click", function (params) {
  console.log(params.name);
});

Return values from events are sent back to Python, for example:

option = {
    "xAxis": {
        "type": "category",
        "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
    },
    "yAxis": { "type": "value" },
    "series": [
        {"data": [820, 932, 901, 934, 1290, 1330, 1320], "type": "line" }
    ],
}
events = {
    "click": "function(params) { console.log(params.name); return params.name }",
    "dblclick":"function(params) { return [params.type, params.name, params.value] }"
}
value = st_echarts(option, events=events)
st.write(value)  # shows name on bar click and type+name+value on bar double click

The JS code needs to be a one-liner. You can use Javascript minifiers like https://javascript-minifier.com/ or https://www.minifier.org/ to transform your Javascript code to a one-liner.

  • height / width : size of the div wrapper
  • map : register a map using the dedicated Map class
from streamlit_echarts5 import Map
with open("USA.json", "r") as f:
    map = Map(
        "USA",
        json.loads(f.read()),
        {
            "Alaska": {"left": -131, "top": 25, "width": 15},
            "Hawaii": {"left": -110, "top": 28, "width": 5},
            "Puerto Rico": {"left": -76, "top": 26, "width": 2},
        },
    )
options = {...}
st_echarts(options, map=map)

You'll find a lot of GeoJSON data inside the source code of echarts-countries-js.

  • renderer : SVG or canvas
  • key : assign a fixed identity if you want to change its arguments over time and not have it be re-created.

st_pyecharts API

def st_pyecharts(
    chart: Base
    theme: Union[str, Dict]
    events: Dict[str, str]
    height: str
    width: str
    renderer: str
    map: Map
    key: str
)
  • chart : Pyecharts instance

The docs for the remaining inputs are the same as its st_echarts counterpart.

Development

Install

  • JS side
cd frontend
npm install
  • Python side
conda create -n streamlit-echarts5 python=3.12
conda activate streamlit-echarts5
pip install -e .

Run

Both webpack dev server and Streamlit need to run for development mode.

  • JS side
cd frontend
npm run dev
  • Python side

Demo example is on https://github.com/andfanilo/streamlit-echarts-demo. But you need to change all import module from streamlit_echarts to streamlit_echarts5

git clone https://github.com/andfanilo/streamlit-echarts-demo
cd streamlit-echarts-demo/
# After you replace the import module,then run next shell
streamlit run app.py

build package

  • Build frontend
cd frontend
npm run build
  • Build wheel
# cd to project root
# ensure python env have 'build' installed
python -m build

Caveats

Theme definition

  • Defining the theme in Pyecharts when instantiating chart like Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT)) does not work, you need to call theme in st_pyecharts(c, theme=ThemeType.LIGHT).

On Javascript functions

This library also provides the JsCode util class directly from pyecharts.

This class is used to indicate javascript code by wrapping it with a specific placeholder. On the custom component side, we parse every value in options looking for this specific placeholder to determine whether a value is a JS function.

As such, if you want to pass JS functions as strings in your options, you should use the corresponding JsCode module to wrap code with this placeholder :

  • In Python dicts representing the JSON option counterpart, wrap any JS string function with streamlit_echarts.JsCode by calling JsCode(function).js_code. It's a smaller version of pyecharts.commons.utils.JsCode so you don't need to install pyecharts to use it.
series: [
    {
        type: 'scatter', // this is scatter chart
        itemStyle: {
            opacity: 0.8
        },
        symbolSize: JsCode("function (val) { return val[2] * 40;}").js_code,
        data: [["14.616","7.241","0.896"],["3.958","5.701","0.955"],["2.768","8.971","0.669"],["9.051","9.710","0.171"],["14.046","4.182","0.536"],["12.295","1.429","0.962"],["4.417","8.167","0.113"],["0.492","4.771","0.785"],["7.632","2.605","0.645"],["14.242","5.042","0.368"]]
    }
]
  • In Pyecharts, use pyecharts.commons.utils.JsCode directly, JsCode automatically calls .js_code when dumping options.
.set_series_opts(
        label_opts=opts.LabelOpts(
            position="right",
            formatter=JsCode(
                "function(x){return Number(x.data.percent * 100).toFixed() + '%';}"
            ),
        )
    )

Note: you need the JS string to be on one-line. You can use Javascript minifiers like https://javascript-minifier.com/ or https://www.minifier.org/ to transform your Javascript code to a one-liner.

st_pyecharts VS using pyecharts with components.html

While this package provides a st_pyecharts method, if you're using pyecharts you can directly embed your pyecharts visualization inside st.html by passing the output of the chart's .render_embed().

from pyecharts.charts import Bar
from pyecharts import options as opts
import streamlit.components.v1 as components

c = (Bar()
    .add_xaxis(["Microsoft", "Amazon", "IBM", "Oracle", "Google", "Alibaba"])
    .add_yaxis('2017-2018 Revenue in (billion $)', [21.2, 20.4, 10.3, 6.08, 4, 2.2])
    .set_global_opts(title_opts=opts.TitleOpts(title="Top cloud providers 2018", subtitle="2017-2018 Revenue"),
                     toolbox_opts=opts.ToolboxOpts())
    .render_embed() # generate a local HTML file
)
components.html(c, width=1000, height=1000)

Using st_pyecharts is still something you would want if you need to change data regularly without remounting the component, check for examples examples/app_pyecharts.py for Chart with randomization example.

Credits

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

streamlit_echarts5-1.0.0.tar.gz (3.1 MB view details)

Uploaded Source

Built Distribution

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

streamlit_echarts5-1.0.0-py3-none-any.whl (3.1 MB view details)

Uploaded Python 3

File details

Details for the file streamlit_echarts5-1.0.0.tar.gz.

File metadata

  • Download URL: streamlit_echarts5-1.0.0.tar.gz
  • Upload date:
  • Size: 3.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.4

File hashes

Hashes for streamlit_echarts5-1.0.0.tar.gz
Algorithm Hash digest
SHA256 62c9dade22e0e280ced036cab8bdc820b481de4282e1c46be8be019f12fd651d
MD5 66c63c0f9ec91577ad01ca2eb50934ae
BLAKE2b-256 6b168139e1209ad86c2b84590171155d853c5277b6d6dab6f6dc3da3942fe242

See more details on using hashes here.

File details

Details for the file streamlit_echarts5-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for streamlit_echarts5-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 071c5fdca18dae37ae32e95d057f091f0861ce49da83fc194b871c7a7b588e1d
MD5 21a0b1595d0bcdb1a574677a18d9da4b
BLAKE2b-256 ecb35f356205ee71b92dc32c8cab965dce807475b56c29e39f65570df4cdb27b

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