SupersetDashboard 组件

SupersetDashboard UI 组件可以将 Apache Superset 配置的仪表板嵌入应用程序的视图中。

用法

项目中安装了扩展组件之后,可以在 Studio 视图设计器Add Component 工具箱中找到 SupersetDashboard 组件。

该组件需要配置 idheightwidth 等属性,并指定从 Apache Superset 获取的 embeddedId。示例:

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

另外,也可以将组件注入控制器通过编程式的方式进行交互:

@ViewComponent
private SupersetDashboard dashboard;

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

XML 属性

chartControlsVisible

设置图表控制组件的可见性。

chart controls example

embeddedId

嵌入的仪表板 ID。可以在 Superset 的仪表板配置中获取该 ID。参阅 开始使用 向导中 dashboard.adoc#create-dashboard 时启用嵌入功能的的示例。

启用嵌入功能时,别忘了需要在 Superset 配置中设置 EMBEDDED_SUPERSET 功能标签。参阅 configuration.adoc#enable-embedding-dashboards

嵌入 ID 在获取 访客 token 和加载仪表板时会用到。如果嵌入 ID 发生了变化,组件会重新加载仪表板。如果没有配置嵌入 ID,在会显示一个占位图片。

filtersExpanded

设置是否展开过滤器栏。

titleVisible

设置标题栏的可见性。

title visible example

数据集约束

Superset 中的仪表板可以包含多个图表,这些图表显示来自不同数据集的数据。SupersetDashboard 组件可以对这些数据集设置约束。约束可以在组件的 XML 元素中静态定义,也可以在运行时动态计算。

提供约束时,需要定义数据集的 ID 并编写可以添加到数据集查询语句的 WHERE 子句中的原生 SQL 条件。

从 Superset UI 中不是很容易找到数据集 ID。当从数据集列表中打开数据集时,地址栏 URL 的 datasource_id 参数就是数据集 ID。

静态约束

现在我们考虑在 开始使用 章节创建的 Employees' salaries 仪表板中使用静态数据集约束。数据集加载了员工、部门和薪资。假设我们需要限制薪资的下限,比如 80,000

约束在 dashboard 组件内的 datasetConstraint 元素中定义。Studio Add 操作或在 XML 中手动添加。

所需的约束定义如下所示:

<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 是数据集的列。

动态约束

数据集约束可以在运行时动态计算,并在打开仪表板时传递给 Superset。因此,可以根据当前用户权限或任何其他的条件筛选出仪表板所需要的数据。

数据集约束由 DatasetConstraint Java 类表示。约束列表可以通过以下方式为 SupersetDashboard 组件提供:

  • 在视图中创建一个 datasetConstraintsProvider 处理方法,返回约束列表。

  • 创建一个实现了 DatasetConstraintsProvider 接口的 Spring bean,使用 setDatasetConstraintsProvider() 方法将其传递给组件。

假设有以下需求:部门经理只能查看自己部门薪资的信息。数据集约束可以支持当前用户的行级角色。

在下面的示例中使用了第一种方法,视图中带有 datasetConstraintsProvider 处理方法,具体的实现逻辑放到常规的 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();
    }
}

Bean 用在了 datasetConstraintsProvider 方法中,这个方法可以通过 Jmix UI 属性面板生成:

@Autowired
private DepartmentDatasetConstraintProvider departmentDatasetConstraintProvider;

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