diff --git a/avenger-python/avenger/altair_utils.py b/avenger-python/avenger/altair_utils.py index 764464d..d22686b 100644 --- a/avenger-python/avenger/altair_utils.py +++ b/avenger-python/avenger/altair_utils.py @@ -1,5 +1,5 @@ from ._avenger import SceneGraph - +import copy def avenger_png_renderer(spec: dict, **kwargs) -> dict: """ @@ -29,6 +29,71 @@ def avenger_png_renderer(spec: dict, **kwargs) -> dict: return {"image/png": sg.to_png(scale=kwargs.get("scale", None))} +def avenger_html_renderer(spec: dict, **kwargs) -> dict: + """ + Altair renderer plugin that uses Avenger to render interactive charts + + This function is registered as avenger-html in the altair.vegalite.v5.renderer + entry point group. It may be enabled in Altair using: + + >>> import altair as alt + >>> alt.renderers.enable('avenger-html') + + See https://altair-viz.github.io/user_guide/custom_renderers.html + for more information + """ + from altair.utils.mimebundle import spec_to_mimebundle + from altair import VEGA_VERSION, VEGALITE_VERSION, VEGAEMBED_VERSION + import jinja2 + + template = jinja2.Template( + """\ + + +
+ + + + + + + +""" + ) + + embed_options = copy.deepcopy(kwargs.get("embed_options", {})) + embed_options["renderer"] = "avenger" + bundle = spec_to_mimebundle( + spec, + format="html", + mode="vega-lite", + template=template, + embed_options=embed_options, + vega_version=VEGA_VERSION, + vegaembed_version=VEGAEMBED_VERSION, + vegalite_version=VEGALITE_VERSION, + ) + return bundle + + def chart_to_png(chart, scale=1) -> bytes: """ Convert an altair chart to a png image bytes diff --git a/avenger-python/pyproject.toml b/avenger-python/pyproject.toml index e186baa..1c0c237 100644 --- a/avenger-python/pyproject.toml +++ b/avenger-python/pyproject.toml @@ -16,3 +16,4 @@ module-name = "avenger._avenger" [project.entry-points."altair.vegalite.v5.renderer"] avenger-png = "avenger.altair_utils:avenger_png_renderer" +avenger-html = "avenger.altair_utils:avenger_html_renderer" diff --git a/pixi.lock b/pixi.lock index ebcec39..6a6168b 100644 --- a/pixi.lock +++ b/pixi.lock @@ -690,8 +690,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/vega_datasets-0.9.0-pyhd3deb0d_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/vegafusion-1.6.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/vegafusion-python-embed-1.6.1-py312h5280bc4_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/vegafusion-1.6.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/vegafusion-python-embed-1.6.7-py312h5280bc4_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/vl-convert-python-1.2.2-py312he37b823_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-1.13-pyhd8ed1ab_0.conda @@ -3419,8 +3419,8 @@ packages: - kind: pypi name: greenlet version: 3.0.3 - url: https://files.pythonhosted.org/packages/63/0f/847ed02cdfce10f0e6e3425cd054296bddb11a17ef1b34681fa01a055187/greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - sha256: 881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230 + url: https://files.pythonhosted.org/packages/17/14/3bddb1298b9a6786539ac609ba4b7c9c0842e12aa73aaa4d8d73ec8f8185/greenlet-3.0.3.tar.gz + sha256: 43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491 requires_dist: - sphinx ; extra == 'docs' - furo ; extra == 'docs' @@ -3430,8 +3430,8 @@ packages: - kind: pypi name: greenlet version: 3.0.3 - url: https://files.pythonhosted.org/packages/17/14/3bddb1298b9a6786539ac609ba4b7c9c0842e12aa73aaa4d8d73ec8f8185/greenlet-3.0.3.tar.gz - sha256: 43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491 + url: https://files.pythonhosted.org/packages/63/0f/847ed02cdfce10f0e6e3425cd054296bddb11a17ef1b34681fa01a055187/greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + sha256: 881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230 requires_dist: - sphinx ; extra == 'docs' - furo ; extra == 'docs' @@ -9824,8 +9824,8 @@ packages: - kind: pypi name: playwright version: 1.43.0 - url: https://files.pythonhosted.org/packages/8b/5c/fe3e42ea46038ec69a0c0fd4b8f8d9a633577f5b3c0368b67d73ee33e910/playwright-1.43.0-py3-none-manylinux1_x86_64.whl - sha256: 50d9a5c07c76456945a2296d63f78fdf6eb11aed3e8d39bb5ccbda760a8d6d41 + url: https://files.pythonhosted.org/packages/62/10/f0638cbcd25d2e5d06e23aa55f4a575b062e6f35670a46adc53dd5ebcc63/playwright-1.43.0-py3-none-macosx_10_13_x86_64.whl + sha256: b03b12bd4da9c2cfb78dff820deac8b52892fe3c2f89a4d95d6f08c59e41deb9 requires_dist: - greenlet==3.0.3 - pyee==11.1.0 @@ -9833,8 +9833,8 @@ packages: - kind: pypi name: playwright version: 1.43.0 - url: https://files.pythonhosted.org/packages/62/10/f0638cbcd25d2e5d06e23aa55f4a575b062e6f35670a46adc53dd5ebcc63/playwright-1.43.0-py3-none-macosx_10_13_x86_64.whl - sha256: b03b12bd4da9c2cfb78dff820deac8b52892fe3c2f89a4d95d6f08c59e41deb9 + url: https://files.pythonhosted.org/packages/8b/5c/fe3e42ea46038ec69a0c0fd4b8f8d9a633577f5b3c0368b67d73ee33e910/playwright-1.43.0-py3-none-manylinux1_x86_64.whl + sha256: 50d9a5c07c76456945a2296d63f78fdf6eb11aed3e8d39bb5ccbda760a8d6d41 requires_dist: - greenlet==3.0.3 - pyee==11.1.0 @@ -12459,31 +12459,6 @@ packages: - pkg:pypi/vega-datasets size: 183450 timestamp: 1606414171959 -- kind: conda - name: vegafusion - version: 1.6.1 - build: pyhd8ed1ab_0 - subdir: osx-arm64 - noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/vegafusion-1.6.1-pyhd8ed1ab_0.conda - sha256: f9d0ed7fb31c86461e50a015bf8c72896a05175a340c673f203337d26427e8f1 - md5: 9ee62af730f460753bf8aee3c6730d0f - depends: - - altair >=4.2.0 - - pandas - - protobuf - - psutil - - pyarrow >=6 - - python >=3.7 - - vegafusion-python-embed >=1.0 - arch: aarch64 - platform: osx - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/vegafusion - size: 49207 - timestamp: 1704850581143 - kind: conda name: vegafusion version: 1.6.7 @@ -12507,26 +12482,6 @@ packages: - pkg:pypi/vegafusion size: 52227 timestamp: 1712919893713 -- kind: conda - name: vegafusion-python-embed - version: 1.6.1 - build: py312h5280bc4_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/vegafusion-python-embed-1.6.1-py312h5280bc4_0.conda - sha256: 946e37ed95f4399729a67fdc316719558e1c90b6c8cafdaaa67a8cc7c293758e - md5: 8fe134243a591f2ac735122f3e0ed5a3 - depends: - - python >=3.12,<3.13.0a0 - - python >=3.12,<3.13.0a0 *_cpython - - python_abi 3.12.* *_cp312 - arch: aarch64 - platform: osx - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/vegafusion-python-embed - size: 13666950 - timestamp: 1704852841946 - kind: conda name: vegafusion-python-embed version: 1.6.7 @@ -12565,6 +12520,26 @@ packages: - pkg:pypi/vegafusion-python-embed size: 17404143 timestamp: 1712921355318 +- kind: conda + name: vegafusion-python-embed + version: 1.6.7 + build: py312h5280bc4_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/vegafusion-python-embed-1.6.7-py312h5280bc4_0.conda + sha256: 9b2a3a30015b2d1342045d083d4cb52d5f7d3a1576149b600e5abcf3e715fc3f + md5: 2bb652bc7b8cdc7b42ace6a5e1752fca + depends: + - python >=3.12,<3.13.0a0 + - python >=3.12,<3.13.0a0 *_cpython + - python_abi 3.12.* *_cp312 + constrains: + - __osx >=11.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/vegafusion-python-embed + size: 14390209 + timestamp: 1712922749831 - kind: conda name: vegafusion-python-embed version: 1.6.7 diff --git a/pixi.toml b/pixi.toml index cbdec58..541b8b5 100644 --- a/pixi.toml +++ b/pixi.toml @@ -64,8 +64,8 @@ pip = ">=23.3.2,<23.4" vl-convert-python = ">=1.2.2,<1.3" altair = ">=5.2.0,<5.3" vega_datasets = ">=0.9.0,<0.10" -vegafusion = ">=1.6.1,<1.7" -vegafusion-python-embed = ">=1.6.1,<1.7" +vegafusion = "1.6.7.*" +vegafusion-python-embed = "1.6.7.*" click = ">=8.1.7,<8.2" toml = ">=0.10.2,<0.11" nodejs = "20.*"