mckinsey / vizro

Vizro is a toolkit for creating modular data visualization applications.
https://vizro.readthedocs.io/en/stable/
Apache License 2.0
2.46k stars 109 forks source link

iframe or pure html #533

Open vks2 opened 1 week ago

vks2 commented 1 week ago

Question

hello!

  1. is there's a way to paste regular html code in vizro?
  2. is there's a way to paste an iframe in vizro?
  3. is there's a way to paste custom js-code? in dash it's not so obvious, js code may be run in css only. use case for 1-2 (dash code):
import dash_core_components as dcc
import dash_html_components as html

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(children=[
    html.H1(children='Hello Dash'),

    html.Div(children='''
        Dash: A web application framework for Python.
    '''),

    dcc.Graph(
        id='example-graph',
        # figure=fig  # commented out to make the example runnable
    ),

    html.Iframe(src="https://www.ons.gov.uk/visualisations/dvc914/map/index.html",
                style={"height": "1067px", "width": "100%"})
])

if __name__ == '__main__':
    app.run_server(debug=True, port=8049, host='127.0.0.1')

please note, that even importing [dbc.themes.BOOTSTRAP] breaks some bootstrap overrides that vizro uses :((

thanks much and sorry for tons of questions

Code/Examples

No response

Other information

No response

Which package?

None

Package version

No response

Python version

No response

OS

No response

Code of Conduct

huong-li-nguyen commented 1 week ago

Hey @vks2,

There's no need to feel sorry! 👍 Reading your questions helps us understand where people might have open questions when trying to translate Dash to Vizro, so it's really helpful for us!

Here again, custom components are the way to go 😄 If you want to add any dash component (HTML, dcc, dbc, mantine, etc.) unavailable in our library, you can always add it using custom components!

In your case, it would look like the one below. I've updated the layout in this example as well. From a visual perspective, adding text to your screen using the vm.Card might be a better solution. In this case, you also wouldn't need a custom component 👍

from typing import Literal

import vizro.models as vm
import vizro.plotly.express as px
from dash import html
from vizro import Vizro

iris = px.data.iris()

class CustomHTML(vm.VizroBaseModel):
    """New custom component `CustomHTML`."""

    type: Literal["html"] = "html"

    def build(self):
        return html.Div(
            children="""
                    Dash: A web application framework for Python.
                """
        )

class IFrame(vm.VizroBaseModel):
    """New custom component `Iframe`."""

    type: Literal["iframe"] = "iframe"

    def build(self):
        return html.Iframe(
            src="https://www.ons.gov.uk/visualisations/dvc914/map/index.html",
            style={"height": "1067px", "width": "100%"},
        )

vm.Page.add_type("components", CustomHTML)
vm.Page.add_type("components", IFrame)

page = vm.Page(
    title="Hello Dash",
    layout=vm.Layout(grid=[[0]] +
                           [[1]] * 4 +
                           [[2]] * 4),
    components=[CustomHTML(), vm.Graph(figure=px.bar(iris, x="sepal_width", y="sepal_length", color="species")), IFrame()],
)
dashboard = vm.Dashboard(pages=[page], theme="vizro_light")
Vizro().build(dashboard).run() 

Screenshot 2024-06-18 at 10 26 41

One thing I wanted to mention because I am unsure if it's clear, is that Vizro().build(dashboard) returns you the Dash app object. So, there is always the possibility of appending dash components directly there as well. The limitation of this approach is that it will always append to the existing content, so with the first approach, you have better control over the layout, which I recommend using.

app = Vizro().build(dashboard)
app.dash.layout.children.append(html.Div("hello"))
app.run()

To your last question: You can add js code by creating an assets folder and inserting your js files in there, as explained here: https://vizro.readthedocs.io/en/stable/pages/user-guides/assets/

Hope that helps! 🍀

vks2 commented 1 week ago

thanks much. your final note gives flexibility that i really need working with the framework. about js code - could you please provide a working example with 'console.log('hi from Vizro') on document.load? i've played around customizing css (trying to change footer, etc.) it's not so straight forward... thanks much again! even in commercial projects we often see not such a responsive support like here in mckinsey!

nadijagraca commented 1 week ago

Hi @vks2, Adding custom js code is very similar to adding custom css code, more information can be found on : Vizro assets docs. Any js files in the assets folder that is in the root of your app directory will be picked up automatically via the external_scripts argument of Dash. I hope this helps, but let me know if you have any difficulties.

nadijagraca commented 1 week ago

Code to reproduce the example:

  1. Add custom.js file to the assets folder. assets/js/custom.js

  2. Add js code to the custom.js file: console.log('Hi from Vizro')

import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro

df = px.data.gapminder()
page_one = vm.Page(
    title="JS example",
    components=[
        vm.Card(text="Using custom js script with Vizro."),
    ],
)

dashboard = vm.Dashboard(pages=[page_one])

if __name__ == "__main__":
    Vizro().build(dashboard).run()
Screenshot 2024-06-18 at 17 09 50