SupersetDashboard Component

The SupersetDashboard UI component is designed for embedding dashboards configured in Apache Superset into application views.

Usage

The SupersetDashboard component is available in the Add Component palette of the Studio View Designer as soon as you install the add-on in your project.

You should configure attributes like id, height, width, and specify the embeddedId obtained from the Apache Superset, for example:

<superset:dashboard id="dashboard" width="100%" height="100%"
                    embeddedId="b6f53731-1da2-4768-b545-fff4fd2659c6"/>

Also, you can inject the component into the controller and interact with it programmatically:

@ViewComponent
private SupersetDashboard dashboard;

@Subscribe
public void onInit(final InitEvent event) {
    dashboard.setEmbeddedId("1aec5c74-f143-4051-818b-fcf9d77c8501");
}

Attributes

chartControlsVisible

Sets the visibility of chart controls.

chart controls example

embeddedId

The embedded dashboard ID. You can take this ID from dashboard settings in Superset. See an example of how to enable embedding in the Create Dashboard section of the Getting Started guide.

To enable embedding dashboards, do not forget to set the EMBEDDED_SUPERSET feature flag in Superset configuration. See Embedded Dashboards.

The embedded ID is required for fetching a guest token and loading the dashboard. After the embedded ID is changed, the component reloads the dashboard. Without an embedded ID, the component will show a stub image.

filtersExpanded

Sets whether the filters bar is expanded or not.

titleVisible

Sets the visibility of the title bar.

title visible example

Dataset Constraints

A dashboard in Superset can contain multiple charts that show data from different datasets. The SupersetDashboard component provides the ability to set constraints on these datasets. Constraints can be defined statically in the component’s XML element or calculated dynamically at runtime.

To provide a constraint, you need to define the ID of the dataset and write a native SQL condition that will be appended to the WHERE clause of the dataset query.

It is not obvious from the Superset UI where to find a dataset ID. You can get it from the datasource_id parameter of the URL displayed in the address bar when you open the dataset from the datasets list.

Static Dataset Constraints

Let’s consider usage of static dataset constraints in the Employees' salaries dashboard created in the Getting Started section. It uses the dataset that loads employees, departments and salaries. Suppose that you need to limit the salary lower bound, e.g. by 80,000.

Constraints are defined in the datasetConstraint nested elements of the dashboard component. They can be added using Studio Add action available for the component or manually in XML.

The required constraint definition will look as follows:

<superset:dashboard id="dashboard"
                    width="100%"
                    height="100%"
                    embeddedId="940f36ff-6c97-4a35-a4ff-4e4aeee3a9c7">
    <superset:datasetConstraints>
        <superset:datasetConstraint datasetId="24">
            <![CDATA[salary >= 80000]]>
        </superset:datasetConstraint>
    </superset:datasetConstraints>
</superset:dashboard>

salary here is the column of the dataset.

Dataset Constraints Provider

Dataset constraints can be calculated dynamically at runtime and passed to Superset when the dashboard is opened in the Jmix application. This allows you to filter out dashboard data based on the current user privileges or any other criteria.

A dataset constraint is represented by the DatasetConstraint Java class. You can provide a list of constraints to the SupersetDashboard component in the following ways:

  • Create a datasetConstraintsProvider handler in the view and return the list of constraints from it.

  • Create a Spring bean implementing the DatasetConstraintsProvider interface and pass it to the component using the setDatasetConstraintsProvider() method.

Let’s consider the following requirement: a department manager can see information about salaries only in their own department. A dataset constraint may take into account a row-level role assigned to the current user.

In the example below uses the first approach with datasetConstraintsProvider handler in the view, but the logic is extracted to a regular Spring bean:

package com.company.supersetsample.app;

import com.company.supersetsample.entity.Department;
import com.company.supersetsample.entity.User;
import com.company.supersetsample.security.DepartmentConstraintRole;
import io.jmix.core.security.CurrentAuthentication;
import io.jmix.security.SecurityProperties;
import io.jmix.supersetflowui.component.dataconstraint.DatasetConstraint;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class DepartmentDatasetConstraintProvider {

    private final CurrentAuthentication currentAuthentication;
    private final SecurityProperties securityProperties;

    public DepartmentDatasetConstraintProvider(CurrentAuthentication currentAuthentication,
                                               SecurityProperties securityProperties) {
        this.currentAuthentication = currentAuthentication;
        this.securityProperties = securityProperties;
    }

    public List<DatasetConstraint> getConstraints() {
        Department department = getDepartment();
        if (hasDepartmentConstraintRole() && department != null) {
            return List.of(new DatasetConstraint(24, "department_name = '" + department.getName() + "'"));
        }
        return List.of();
    }

    private boolean hasDepartmentConstraintRole() {
        Authentication authentication = currentAuthentication.getAuthentication();
        return authentication.getAuthorities().stream()
                .anyMatch(grantedAuthority ->
                        grantedAuthority.getAuthority().equals(
                                securityProperties.getDefaultRowLevelRolePrefix() + DepartmentConstraintRole.CODE));
    }

    private Department getDepartment() {
        User user = (User) currentAuthentication.getUser();
        return user.getDepartment();
    }
}

The bean is used in the datasetConstraintsProvider handler that can be generated from the Jmix UI inspector panel:

@Autowired
private DepartmentDatasetConstraintProvider departmentDatasetConstraintProvider;

@Install(to = "dashboard", subject = "datasetConstraintsProvider")
private List<DatasetConstraint> dashboardDatasetConstraintsProvider() {
    return departmentDatasetConstraintProvider.getConstraints();
}