Note
Go to the end to download the full example code.
Tree#
A minimal Dash app showing how to use the Tree
component.
See the Tree page in the User Guide for the full reference documentation.
Note
Run this file directly to launch the app:
pip install ansys-solutions-dash-super-components
python example_tree.py
Then open http://localhost:8050 in your browser.
To test with a URL path prefix:
REQUESTS_PATHNAME_PREFIX=/myapp/ python example_tree.py
Then open http://localhost:8050/myapp in your browser.
Set up the Dash application#
MantineProvider must wrap the entire layout
for Mantine-based components to render correctly. The React version must also
be set before importing the component library — this is a Dash Mantine
Components requirement when using Dash 2.x.
The optional REQUESTS_PATHNAME_PREFIX environment variable lets you test the
app behind a URL path prefix. See the Adding external scripts with a URL path prefix
section of the Getting Started page for details.
import os
from typing import Any
from ansys.solutions.dash_super_components import Tree, add_super_components_assets
from dash import _dash_renderer
from dash_extensions.enrich import DashProxy, Input, Output, callback, html
import dash_mantine_components as dmc
# Required only for Dash 2.x to use Mantine-based components
_dash_renderer._set_react_version("18.2.0")
# Set REQUESTS_PATHNAME_PREFIX to test the app with a URL prefix.
# For example: REQUESTS_PATHNAME_PREFIX="myapp"
_url_prefix = os.getenv("REQUESTS_PATHNAME_PREFIX", "").strip("/")
_url_base_pathname = f"/{_url_prefix}/" if _url_prefix else "/"
app = DashProxy(__name__, url_base_pathname=_url_base_pathname)
add_super_components_assets(app)
Define the tree data#
The items prop accepts a list of item dictionaries.
The full schema for each item dictionary is documented in the Tree structure definition
section in the User Guide.
The tree below models a three-stage CFD workflow with three levels of nesting:
Pre-processing is expanded on load (
"expanded": True) so the user immediately sees its child nodes Geometry and Mesh.Solving and Post-processing are collapsed. Post-processing has no children (a leaf node).
Icons for the tree items are given through their
iconvalues, which use Iconify icon identifiers and require the app to have internet access to load the icons from the Iconify CDN. For alternatives that work in offline environments, see theTreeIcons section in the User Guide.The Geometry node is preselected further below via
selected_item.
TREE_ITEMS = [
{
"id": "pre-processing",
"text": "Pre-processing",
"icon": "mdi:file-settings-outline",
"expanded": True,
"disabled": False,
"description": "Geometry and mesh",
"children": [
{
"id": "geometry",
"text": "Geometry",
"icon": "mdi:vector-square",
"expanded": False,
"disabled": False,
"description": "CAD geometry",
},
{
"id": "mesh",
"text": "Mesh",
"icon": "mdi:grid",
"expanded": False,
"disabled": False,
"description": "Volume mesh",
},
],
},
{
"id": "solving",
"text": "Solving",
"icon": "mdi:play-circle-outline",
"expanded": False,
"disabled": False,
"description": "Solver settings and execution",
"children": [
{
"id": "solver-settings",
"text": "Solver settings",
"icon": "mdi:tune",
"expanded": False,
"disabled": False,
"description": "Physics and numerics",
},
{
"id": "run",
"text": "Run",
"icon": "mdi:rocket-launch-outline",
"expanded": False,
"disabled": False,
"description": "Submit the job",
},
],
},
{
"id": "post-processing",
"text": "Post-processing",
"icon": "mdi:chart-line",
"expanded": False,
"disabled": False,
"description": "Results and visualisation",
},
]
Build the layout#
The tree lives in the left column. Clicking a node updates the text in the
right column. Pass selected_item to preselect a node on first render.
app.layout = dmc.MantineProvider(
html.Div(
[
dmc.Title("Tree", order=2, mb="md"),
dmc.Text(
"Click a node to select it. The node ID is shown on the right.",
c="dimmed",
mb="xl",
),
dmc.Grid(
[
dmc.GridCol(
Tree(
aio_id="nav-tree",
items=TREE_ITEMS,
selected_item="geometry",
),
span=4,
),
dmc.GridCol(
dmc.Paper(
dmc.Text(id="active-node-display", p="md"),
withBorder=True,
radius="md",
p="md",
),
span=8,
),
]
),
],
style={"maxWidth": 900, "margin": "40px auto", "padding": "0 16px"},
)
)
Add a callback#
Tree.ids.selected_item returns the ID of the
Store sub-component that holds the
currently selected node. Its data property is a dict with an index
key containing the node ID string.
@callback(
Output("active-node-display", "children"),
Input(Tree.ids.selected_item("nav-tree"), "data"),
)
def show_active_node(selected_item: dict[str, Any]) -> str:
"""Display the currently selected tree node."""
if not selected_item:
return "No node selected."
try:
node_id = Tree.ids.get_index_from_navlink_item_id(selected_item)
if node_id is None:
return "No node selected."
except ValueError:
return "Invalid selection."
return f"Active node ID: {node_id}"
Run the app#
if __name__ == "__main__":
app.run()