Vizro - display dataframe that has json format on the card and allow user to download it

Hello!
I am trying to display dynamic payloads coming from an application on to a card and allows user to download it as well. The payload is in JSON format. I am unable to display formatted JSON and could not figure out how to download in Vizro. Please review the code below and provide your inputs.

Thank you :slight_smile:

"""Example app to show all features of Vizro."""
import json

import pandas as pd
import vizro.models as vm
from vizro import Vizro
from vizro.models.types import capture

# GLOBALS --------------------------------------------------------------------->
DROPDOWN_LINK_OPTIONS = [
    {
        "label": "Google",
        "value": "google",
    },
    {
        "label": "Vizro GitHub",
        "value": "github",
    },
    {
        "label": "Vizro Docs",
        "value": "docs",
    },
    {
        "id": "0001",
        "type": "donut",
        "name": "Cake",
        "ppu": 0.55,
        "batters":
            {
                "batter":
                    [
                        {"id": "1001", "type": "Regular"},
                        {"id": "1002", "type": "Chocolate"},
                        {"id": "1003", "type": "Blueberry"},
                        {"id": "1004", "type": "Devil's Food"}
                    ]
            },
        "topping":
            [
                {"id": "5001", "type": "None"},
                {"id": "5002", "type": "Glazed"},
                {"id": "5005", "type": "Sugar"},
                {"id": "5007", "type": "Powdered Sugar"},
                {"id": "5006", "type": "Chocolate with Sprinkles"},
                {"id": "5003", "type": "Chocolate"},
                {"id": "5004", "type": "Maple"}
            ]
    }
]

# incorporating data frame
dropdown_options = pd.DataFrame()
dropdown_options = dropdown_options._append(DROPDOWN_LINK_OPTIONS, ignore_index=True)


# CUSTOM COMPONENTS ---------------------------------------------------------->
@capture("action")
def display_selection(dropdown_value):
    text = 'did not selected Google'
    if dropdown_value == 'Google':
        dropdown_options_str = json.loads(json.dumps(dropdown_options.to_dict()))
        text = dropdown_options_str
    print(text)
    return text


# CUSTOM ACTION ------------------------------------------------------------->
vm.Page.add_type("components", vm.Dropdown)

# PAGE ----------------------------------------------------------------------->
page = vm.Page(
    title="Page Title",
    layout=vm.Layout(grid=[
        [0, 1]
    ]),
    components=[
        vm.Dropdown(
            id='custom_dropdown',
            options=['Google', 'Vizro Docs', 'Vizro GitHub'],
            value='Vizro Docs',
            multi=False,
            actions=[
                vm.Action(
                    function=display_selection(),
                    inputs=["custom_dropdown.value"],
                    outputs=["display.children"],
                )
            ],

        ),
        vm.Card(id="display",
                text="""json goes here when you select google in dropdown"""
                ),
    ],
)

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

if __name__ == "__main__":
    Vizro().build(dashboard).run()

1 Like

Hi @sumitmehta12 :wave:

You can use dcc.Dropdown wrapped in a Vizro custom component.

Here’s an example that I hope helps: :crossed_fingers:

"""Example Vizro app to show JSON data displaying and downloading."""
import json
from dash import dcc
from typing import Literal

import vizro.models as vm
from vizro import Vizro
from vizro.models.types import capture


# GLOBALS --------------------------------------------------------------------->
JSON_DATA = {
    "Google": {
        "name": "Google",
        "url": "https://www.google.com",
        "description": "Google is a search engine.",
        "example_list": [1, 2, 3, 4, 5],
        "example_dict": {
            "key1": "value1",
            "key2": [1, 2, 3, 4, 5],
        }
    },
    "Vizro Docs": {
        "name": "Vizro Docs",
        "url": "https://vizro.readthedocs.io/en/stable/",
        "description": "Vizro Docs is a documentation site.",
        "example_list": [1, 2, 3, 4, 5],
        "example_dict": {
            "key1": "value1",
            "key2": [1, 2, 3, 4, 5],
        }
    },
    "Vizro GitHub": {
        "name": "Vizro GitHub",
        "url": "https://github.com/mckinsey/vizro",
        "description": "Vizro GitHub is a repository.",
        "example_list": [1, 2, 3, 4, 5],
        "example_dict": {
            "key1": "value1",
            "key2": [1, 2, 3, 4, 5],
        }
    }
}


# CUSTOM ACTION ------------------------------------------------------------->
@capture("action")
def display_selection(dropdown_value):
    """Display the selected value in the dropdown."""
    text = json.dumps(JSON_DATA[dropdown_value], indent=4)
    return f"```json\n{text}\n```"


@capture("action")
def download_json(dropdown_value):
    """Download the selected value in the dropdown."""
    return dcc.send_bytes(json.dumps(JSON_DATA[dropdown_value], indent=4).encode(), f"{dropdown_value}.json")


# CUSTOM COMPONENTS ---------------------------------------------------------->
class DownloadComponent(vm.VizroBaseModel):
    type: Literal["download_component"] = "download_component"

    def build(self):
        return dcc.Download(id=self.id)


vm.Page.add_type("components", vm.Dropdown)
vm.Page.add_type("components", DownloadComponent)


# PAGE ----------------------------------------------------------------------->
page = vm.Page(
    title="Page Title",
    layout=vm.Layout(grid=[
        [0, 1],
        [2, 1],
        [3, 1],
    ]),
    components=[
        vm.Dropdown(
            id='custom_dropdown',
            options=['Google', 'Vizro Docs', 'Vizro GitHub'],
            value='Vizro Docs',
            multi=False,
            actions=[
                vm.Action(
                    function=display_selection(),
                    inputs=["custom_dropdown.value"],
                    outputs=["display_card.children"],
                )
            ],

        ),
        vm.Card(
            id="display_card",
            text="""json goes here when you select google in dropdown"""
        ),
        vm.Button(
            text="Download JSON",
            actions=[
                vm.Action(
                    function=download_json(),
                    inputs=["custom_dropdown.value"],
                    outputs=["download_component_id.data"],
                )
            ]
        ),
        DownloadComponent(id="download_component_id")
    ],
)

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

if __name__ == "__main__":
    Vizro().build(dashboard).run()
3 Likes

Thank you @petar-pejovic ! This indeed worked and I am able to implement my whole page with the desired functionality! Thank you for the amazing code and your time!

1 Like