Dashboard Component

The dashboard component shows content in a grid of widgets. The grid changes the number of columns to fit the available width. A widget can span several columns and rows, and widgets can be grouped into sections that users can collapse. In the editable mode, users move, resize, and remove widgets themselves.

XML Element

dashboard

Java Class

JmixDashboard

Basics

First, install the add-on. Then add the component using the Add Component palette of the Studio View Designer. The component is in the Vaadin Commercial category.

If you add the component manually, declare the dashb namespace in the view descriptor:

<view xmlns="http://jmix.io/schema/flowui/view"
      xmlns:dashb="http://jmix.io/schema/vaadin-dashboard/ui"
      title="msg://dashboardBasicsView.title">

The simplest dashboard contains the dashboard element with a few dashboardWidget elements inside:

<dashb:dashboard id="dashboard" width="100%">
    <dashb:dashboardWidget id="revenueWidget" title="msg://revenueWidget.title">
        <dashb:content>
            <h3 id="revenueValue" text="1,204,500"/>
        </dashb:content>
    </dashb:dashboardWidget>

    <dashb:dashboardWidget id="ordersWidget" title="msg://ordersWidget.title">
        <dashb:content>
            <h3 id="ordersValue" text="3,182"/>
        </dashb:content>
    </dashb:dashboardWidget>
</dashb:dashboard>

Widgets

A widget is declared by the dashboardWidget element. It requires an id and contains one component in the nested content element. The title attribute sets the text shown in the widget header and accepts a message key:

<dashb:dashboardWidget id="revenueWidget" title="msg://revenueWidget.title">
    <dashb:content>
        <vbox id="revenueBox" padding="false">
            <h3 id="revenueValue" text="1,204,500"/>
            <span id="revenueCaption" text="msg://revenueWidget.caption"/>
        </vbox>
    </dashb:content>
</dashb:dashboardWidget>

The content element accepts any component available in the view. To show several components in one widget, put them into a layout, as in the example above.

Widget Header

Besides the title, a widget can have the headerContent element. Its component is shown in the widget header. Use it for a refresh button, a filter, or a status badge:

<dashb:dashboardWidget id="ordersWidget" title="msg://ordersWidget.title">
    <dashb:content>
        <h3 id="ordersValue" text="3,182"/>
    </dashb:content>
    <dashb:headerContent>
        <button id="refreshOrdersBtn" icon="REFRESH" themeNames="tertiary-inline"/>
    </dashb:headerContent>
</dashb:dashboardWidget>

Both content and headerContent must contain exactly one element. If you declare more, the application throws a development exception when the view opens.

Widget Size

By default, a widget takes one cell of the grid. The colspan and rowspan attributes make it span several columns and rows:

<dashb:dashboardWidget id="salesWidget" title="msg://salesWidget.title"
                       colspan="2" rowspan="2">
    <dashb:content>
        <vbox id="salesBox" width="100%" height="100%">
            <span id="salesValue" text="msg://salesWidget.caption"/>
        </vbox>
    </dashb:content>
</dashb:dashboardWidget>

A widget never takes more columns than the grid has. On a narrow screen, a wide widget shrinks to the number of columns available.

Creating Widgets Programmatically

You can create and add widgets at runtime. Create the widget and its content with the UiComponents factory:

@Autowired
private UiComponents uiComponents;

private DashboardWidget createWidget(String title, String value) {
    DashboardWidget widget = uiComponents.create(DashboardWidget.class);
    widget.setTitle(title);

    H3 valueLabel = uiComponents.create(H3.class);
    valueLabel.setText(value);
    widget.setContent(valueLabel); // a widget holds one component; use a layout for several

    return widget;
}

@Subscribe
public void onInit(final InitEvent event) {
    dashboard.add(createWidget("Revenue", "1,204,500"),
            createWidget("Orders", "3,182"));
}

You can also set the position of a new widget, and remove widgets one by one or all together:

DashboardWidget widget = createWidget("Visitors", "18,420");
dashboard.addWidgetAtIndex(0, widget);
dashboard.removeAll();

Sections

The dashboardSection element groups widgets under a common heading. Users can collapse a section and hide all its widgets at once:

<dashb:dashboard id="dashboard" width="100%">
    <dashb:dashboardWidget id="totalsWidget" title="msg://totalsWidget.title">
        <dashb:content>
            <h3 id="totalsValue" text="1,204,500"/>
        </dashb:content>
    </dashb:dashboardWidget>

    <dashb:dashboardSection id="regionsSection" title="msg://regionsSection.title">
        <dashb:dashboardWidget id="northWidget" title="msg://northWidget.title">
            <dashb:content>
                <h3 id="northValue" text="612,100"/>
            </dashb:content>
        </dashb:dashboardWidget>
        <dashb:dashboardWidget id="southWidget" title="msg://southWidget.title">
            <dashb:content>
                <h3 id="southValue" text="592,400"/>
            </dashb:content>
        </dashb:dashboardWidget>
    </dashb:dashboardSection>
</dashb:dashboard>

Like a widget, a section requires an id. A section can contain only dashboardWidget elements, and you cannot put a section inside another section. Widgets declared directly in the dashboard element and widgets inside sections can be mixed in any order.

Creating Sections Programmatically

To create a section, use the addSection() methods, then add widgets to it, for example with the createWidget() method from Creating Widgets Programmatically. When you remove a section, its widgets are removed too:

DashboardSection regionsSection = dashboard.addSection("Regions");
regionsSection.add(createWidget("North", "612,100"),
        createWidget("South", "592,400"));

Responsive Grid

The dashboard calculates the number of columns from its own width and from the column width limits. Columns never become narrower than the minimumColumnWidth value. When the dashboard becomes narrower, the number of columns is reduced instead. The maximumColumnCount attribute sets the maximum number of columns on wide screens:

<dashb:dashboard id="dashboard"
                 width="100%"
                 maximumColumnCount="4"
                 minimumColumnWidth="18em"
                 maximumColumnWidth="32em"
                 minimumRowHeight="12em"
                 gap="1em"
                 padding="1em"
                 denseLayout="true"
                 themeNames="shaded-background elevated-widgets">

The denseLayout attribute changes how the grid fills gaps. If it is true, smaller widgets move up into the empty space left by larger ones, and the declared order is not kept.

All these attributes have setters, so you can change the grid at runtime:

dashboard.setMaximumColumnCount(3);
dashboard.setMinimumColumnWidth("18em");
dashboard.setMaximumColumnWidth("32em");
dashboard.setMinimumRowHeight("10em");
dashboard.setGap("1em");
dashboard.setPadding("1em");
dashboard.setDenseLayout(true);

Editable Mode

By default, users see the widgets exactly as they are declared. If you set the editable attribute to true, users can move, resize, and remove widgets and change the order of sections:

<dashb:dashboard id="dashboard" width="100%" editable="true">

In this mode, each widget shows a drag handle, a resize handle, and a remove button. The same actions are available from the keyboard. A user selects a focused widget for editing and then moves or resizes it with the arrow keys.

You can switch the editable mode at runtime, for example with a Customize button:

@ViewComponent
private JmixDashboard dashboard;

@Subscribe("customizeBtn")
public void onCustomizeBtnClick(final ClickEvent<JmixButton> event) {
    dashboard.setEditable(!dashboard.isEditable());
}

The dashboard sends an event for every change made by the user. See Handlers.

Localizing Edit Controls

Tooltips and accessible names of the edit mode controls come from the standard Jmix messages, so they are translated together with the rest of the application. To change the default texts, define the following keys in the main message bundle of your project:

dashboard.i18n.selectSection=Select section for editing
dashboard.i18n.selectWidget=Select widget for editing

dashboard.i18n.remove=Remove
dashboard.i18n.resize=Resize
dashboard.i18n.resizeApply=Apply
dashboard.i18n.resizeShrinkWidth=Shrink width
dashboard.i18n.resizeGrowWidth=Grow width
dashboard.i18n.resizeShrinkHeight=Shrink height
dashboard.i18n.resizeGrowHeight=Grow height

dashboard.i18n.move=Move
dashboard.i18n.moveApply=Apply
dashboard.i18n.moveForward=Move Forward
dashboard.i18n.moveBackward=Move Backward

See Message Bundles for details on overriding messages defined in add-ons.

Theme Variants

Use the themeNames attribute to set a component theme.

Variant Description

shaded-background

Adds a shaded background to the dashboard, so that widgets stand out.

elevated-widgets

Shows widgets with a shadow.

flat-widgets

Shows widgets without borders and shadows.

You can add custom CSS class names to the dashboard, its sections, and its widgets with the classNames attribute.

Attributes

The following attributes are specific to dashboard:

Name Description Default

denseLayout

If true, smaller widgets move up to fill the gaps left by larger ones, and the declared order is not kept. See Responsive Grid.

false

editable

If true, users can move, resize, and remove widgets and change the order of sections. See Editable Mode.

false

gap

The space between widgets, as a CSS length, for example 1em.

maximumColumnCount

The maximum number of columns, whatever the width of the dashboard is. If not set, the number of columns depends only on minimumColumnWidth.

maximumColumnWidth

The maximum width of a column, as a CSS length.

minimumColumnWidth

The minimum width of a column, as a CSS length. Columns never become narrower than this value. Instead, their number is reduced. See Responsive Grid.

minimumRowHeight

The minimum height of a row, as a CSS length. A row becomes higher if its content needs more space.

padding

The space between the dashboard border and its widgets, as a CSS length.

rootHeadingLevel

The heading level for the titles of root-level items in the generated markup. It affects accessibility only.

2

The following shared attributes are supported by dashboard:

Handlers

Common handlers are configured in the same way for all components. The following handlers are specific to dashboard. Their event classes belong to the com.vaadin.flow.component.dashboard package.

To generate a handler stub in Jmix Studio, use the Handlers tab of the Jmix UI inspector panel or the Generate Handler action available in the top panel of the view class and through the CodeGenerate menu (Alt+Insert / Cmd+N).

Name Description

DashboardItemMovedEvent

Sent when a widget or a section is moved to a new position. The getItem() method returns the moved item, and getSection() returns its section.

DashboardItemMoveModeChangedEvent

Sent when an item enters or leaves the keyboard move mode.

DashboardItemRemovedEvent

Sent when the user removes a widget or a section.

DashboardItemResizedEvent

Sent when a widget is resized.

DashboardItemResizeModeChangedEvent

Sent when an item enters or leaves the keyboard resize mode.

DashboardItemSelectedChangedEvent

Sent when an item is selected or deselected for keyboard editing.

The following shared handlers are supported by dashboard:

Elements

A dashboard can include dashboardWidget and dashboardSection as its nested elements.