Dashboards allow you to create a page layout containing a collection of components. The user can move and resize panels within the dashboard.
from deephaven import ui
my_dash = ui.dashboard(
ui.row(
ui.column(ui.panel("A"), ui.panel("C")),
ui.column(ui.panel("B"), ui.panel("D")),
)
)- Dashboards must have one and only one child, typically a row or column.
- Height and width of panels are summed to 100% within a row or column.
Four main children make up a dashboard: row, column, stack, and panels.
- Row: A container used to group elements horizontally. Each element is placed to the right of the previous one.
- Column: A container used to group elements vertically. Each element is placed below the previous one.
- Stack: A container used to group elements into a stack of tabs. Each element gets its own tab, with only one element visible at a time.
- Panel: A container used to group and label elements.
Your dashboard must start with a row or column, which is the "top" of the layout tree. Columns should go inside rows and rows should go inside columns
Note: Nesting rows within rows or columns within columns will sub-divide the row or column.
Stacks and panels are considered the "bottom" of the layout tree. Once added, the layout in that section is considered complete. For layouts within a panel, see tabs, flex, grid, view and nested dashboards.
Children are implicitly wrapped when necessary, so the entire layout does not need to be explicitly defined.
End to end example: dashboard([t1, t2]) would become dashboard(column(stack(panel(t1)), stack(panel(t2)))).
Automatic wrapping is applied by the following rules:
- Dashboard: wrap in row/column if no single node is the default (e.g.,
[t1, t2]as the child to the dashboard would becomerow(t1, t2)). - Row/Column:
- If there are children that are rows/columns, wrap the non-wrapped children with the same element (e.g.,
row(col(t1), t2)becomesrow(col(t1), col(t2))). - If none of the children are wrapped by rows/columns, they are wrapped in stacks (e.g.,
row(col(t1), col(t2))from above becomesrow(col(stack(t1)), col(stack(t2)))).
- If there are children that are rows/columns, wrap the non-wrapped children with the same element (e.g.,
- Stacks: wrap non-panel children in panels (e.g.,
row(col(stack(t1)), col(stack(t2)))becomesrow(col(stack(panel(t1))), col(stack(panel(t2))))).
Rows can have a specified height, while columns can have a specified width.
Stacks directly within a column can have a height or a width if they are within a row. Setting the other dimension will be ignored.
from deephaven import ui
dash_row_heights = ui.dashboard(
[
ui.row(ui.stack(ui.panel("A", title="A")), ui.panel("B", title="B"), height=70),
ui.row(ui.stack(ui.panel("C", title="C")), ui.panel("D", title="D")),
]
)from deephaven import ui
dash_column_widths = ui.dashboard(
[
ui.column(
ui.stack(ui.panel("A", title="A")), ui.panel("C", title="C"), width=70
),
ui.column(ui.stack(ui.panel("B", title="B")), ui.panel("D", title="D")),
]
)from deephaven import ui
dash_stack_widths = ui.dashboard(
ui.row(ui.stack(ui.panel("A", title="A"), width=70), ui.panel("B", title="B"))
)from deephaven import ui
dash_stack_heights = ui.dashboard(
ui.column(ui.stack(ui.panel("A", title="A"), height=70), ui.panel("B", title="B"))
)from deephaven import ui
dash_2x1 = ui.dashboard(ui.row(ui.panel("A", title="A"), ui.panel("B", title="B")))from deephaven import ui
dash_1x2 = ui.dashboard(ui.column(ui.panel("A", title="A"), ui.panel("B", title="B")))from deephaven import ui
dash_2x2 = ui.dashboard(
ui.row(
ui.column(ui.panel("A", title="A"), ui.panel("C", title="C")),
ui.column(ui.panel("B", title="B"), ui.panel("D", title="D")),
)
)from deephaven import ui
dash_3x1 = ui.dashboard(
ui.row(ui.panel("A", title="A"), ui.panel("B", title="B"), ui.panel("C", title="C"))
)from deephaven import ui
dash_stack = ui.dashboard(
ui.stack(
ui.panel("A", title="A"), ui.panel("B", title="B"), ui.panel("C", title="C")
)
)from deephaven import ui
dash_stack_active = ui.dashboard(
ui.stack(
ui.panel("A", title="A"),
ui.panel("B", title="B"), # shown as active item
ui.panel("C", title="C"),
active_item_index=1,
)
)from deephaven import ui
dash_stack = ui.dashboard(
ui.stack(
ui.panel(
ui.tabs(ui.tab("A1 content", title="A1"), ui.tab("A2 content", title="A2")),
title="A",
),
ui.panel(
ui.tabs(ui.tab("B1 content", title="B1"), ui.tab("B2 content", title="B2")),
title="B",
),
)
)from deephaven import ui
dash_layout_stack = ui.dashboard(
ui.row(
ui.stack(
ui.panel("A", title="A"), ui.panel("B", title="B"), ui.panel("C", title="C")
),
ui.panel("D", title="D"),
ui.panel("E", title="E"),
)
)from deephaven import ui
dash_holy_grail = ui.dashboard(
ui.column(
ui.panel("Header", title="Header"),
ui.row(
ui.panel("Left Sidebar", title="Left Sidebar"),
ui.stack(ui.panel("Main Content", title="Main Content"), width=70),
ui.panel("Right Sidebar", title="Right Sidebar"),
),
ui.panel("Footer", title="Footer"),
)
)By default, each panel in a dashboard displays a header bar with the panel title and controls. Setting show_headers=False removes all panel headers, giving a cleaner, borderless appearance useful for presentation-style dashboards.
from deephaven import ui
dash_no_headers = ui.dashboard(
ui.row(
ui.panel("A", title="A"),
ui.panel("B", title="B"),
),
show_headers=False,
)Note
When show_headers=False, users will not be able to drag panels to rearrange the layout or change to other panels in a ui.stack, since the header is the target and drag handle.
Dashboards can be nested inside panels to create complex layouts with isolated drag-and-drop regions. Each nested dashboard creates its own independent layout that users can rearrange without affecting the parent dashboard.
Note
Nested dashboards will not appear in your Panels list, or in your Shared Dashboards list on Enterprise. They are only accessible through the parent dashboard that contains them. To have them appear in your Panels list or Shared Dashboards list, a dashboard must be assigned to a variable at the top level.
from deephaven import ui
dash_nested_basic = ui.dashboard(
ui.row(
ui.panel(
ui.dashboard(
ui.row(
ui.panel("Nested A", title="A"),
ui.panel("Nested B", title="B"),
)
),
title="Nested Dashboard",
),
ui.panel("Main Content", title="Main"),
)
)Unlike root-level dashboards, nested dashboards can be returned from @ui.component functions:
from deephaven import ui
@ui.component
def nested_dashboard_component():
return ui.panel(
ui.dashboard(
ui.row(
ui.panel("A", title="A"),
ui.panel("B", title="B"),
)
),
title="Nested Dashboard",
)
dash_nested_component = ui.dashboard(
ui.row(
nested_dashboard_component(),
ui.panel("Main Content", title="Main"),
)
)Dashboards can be nested arbitrarily deep, with each level creating its own isolated layout:
from deephaven import ui
dash_deeply_nested = ui.dashboard(
ui.row(
ui.panel(
ui.dashboard(
ui.column(
ui.panel("Level 1 - A", title="L1-A"),
ui.panel(
ui.dashboard(
ui.row(
ui.panel("Level 2 - A", title="L2-A"),
ui.panel("Level 2 - B", title="L2-B"),
)
),
title="Level 2 Dashboard",
),
)
),
title="Level 1 Dashboard",
),
ui.panel("Root Content", title="Root"),
)
)Nested dashboards can manage their own state within a @ui.component:
from deephaven import ui
@ui.component
def stateful_nested_dashboard():
count, set_count = ui.use_state(0)
return ui.panel(
ui.dashboard(
ui.row(
ui.panel(
ui.button(f"Count: {count}", on_press=lambda: set_count(count + 1)),
title="Counter",
),
ui.panel(f"Current count is {count}", title="Display"),
)
),
title="Stateful Dashboard",
)
dash_nested_state = ui.dashboard(
ui.row(
stateful_nested_dashboard(),
ui.panel("Main Content", title="Main"),
)
)Note
Panels within a nested dashboard can only be dragged within that nested dashboard. Cross-dashboard drag-and-drop is not supported.
By hoisting state management to the dashboard component, interacting and sharing data between the child components is much easier to maintain and debug.
from deephaven import ui
@ui.component
def layout():
message, set_message = ui.use_state("Hello world!")
return ui.row(
ui.panel(ui.text_field(value=message, on_change=set_message, width="100%")),
ui.panel(message),
)
dash_simple_state = ui.dashboard(layout())from deephaven import ui, time_table
from deephaven.ui import use_memo, use_state
from deephaven.plot.figure import Figure
def use_wave_input():
"""
Demonstrating a custom hook.
Creates an input panel that controls the amplitude, frequency, and phase for a wave
"""
amplitude, set_amplitude = use_state(1.0)
frequency, set_frequency = use_state(1.0)
phase, set_phase = use_state(1.0)
input_panel = ui.flex(
ui.slider(
label="Amplitude",
default_value=amplitude,
min_value=-100.0,
max_value=100.0,
on_change=set_amplitude,
step=0.1,
),
ui.slider(
label="Frequency",
default_value=frequency,
min_value=-100.0,
max_value=100.0,
on_change=set_frequency,
step=0.1,
),
ui.slider(
label="Phase",
default_value=phase,
min_value=-100.0,
max_value=100.0,
on_change=set_phase,
step=0.1,
),
direction="column",
)
return amplitude, frequency, phase, input_panel
@ui.component
def multiwave():
amplitude, frequency, phase, wave_input = use_wave_input()
tt = use_memo(lambda: time_table("PT1s").update("x=i"), [])
t = use_memo(
lambda: tt.update(
[
f"y_sin={amplitude}*Math.sin({frequency}*x+{phase})",
f"y_cos={amplitude}*Math.cos({frequency}*x+{phase})",
f"y_tan={amplitude}*Math.tan({frequency}*x+{phase})",
]
),
[amplitude, frequency, phase],
)
p_sin = use_memo(
lambda: Figure().plot_xy(series_name="Sine", t=t, x="x", y="y_sin").show(), [t]
)
p_cos = use_memo(
lambda: Figure().plot_xy(series_name="Cosine", t=t, x="x", y="y_cos").show(),
[t],
)
p_tan = use_memo(
lambda: Figure().plot_xy(series_name="Tangent", t=t, x="x", y="y_tan").show(),
[t],
)
return ui.column(
ui.row(
ui.stack(
ui.panel(wave_input, title="Wave Input"),
ui.panel(t, title="Wave Table"),
active_item_index=0,
),
height=25,
),
ui.row(
ui.stack(ui.panel(p_sin, title="Sine"), width=50),
ui.stack(ui.panel(p_cos, title="Cosine"), width=30),
ui.stack(ui.panel(p_tan, title="Tangent")),
),
)
dash_complex_state = ui.dashboard(multiwave()).. dhautofunction:: deephaven.ui.dashboard
.. dhautofunction:: deephaven.ui.row
.. dhautofunction:: deephaven.ui.column
.. dhautofunction:: deephaven.ui.stack
