饼图

在本节中,我们将:

  • 创建一个饼图

  • 添加 formatter 属性

  • 通过 data provider 绑定数据

饼图配置

我们将集成饼图组件,以显示不同入职状态中的用户分布情况,以便了解组织内人员的入职进度。

单击 user-list-view.xml 中的 formLayout 元素。

下一步,在操作面板中选择 Add Component,找到并选择 Chart 项。配置 idheightwidth 属性,如下所示。

<charts:chart id="pie" width="40em" height="80%" minHeight="30em" alignSelf="STRETCH">

在图表组件中添加 pie:选择 chart 元素,然后选择 Add → Series → Pie。按下面的配置为饼图添加 name 属性:Onboarding Status,以及 radius 属性配置饼图的大小:

<charts:pie name="Onboarding Status" radius="50% 80%">

格式化值

饼图系列中的 formatter 属性支持通过字符串模板和回调函数来格式化数据。

如需在饼图的每片区中显示入职状态和处于该状态的用户百分比,选择 label 元素,然后选择 Add → Label

label 元素中的 formatter 属性设置为 "{b} : %{d}",其中:

  • {b}:表示数据项(类别)的名称 - 在此图表中,即入职状态,如 "Not Started"、"In Progress" 或 "Completed"。

  • {d}:表示此数据项(类别)所占总数的百分比。

<charts:series>
    <charts:pie name="Onboarding Status" radius="50% 80%">
        <charts:label formatter="{b} : {d}%"/>
    </charts:pie>
</charts:series>

数据绑定

饼图中需要显示各个入职状态的百分比。数据并不是直接来自某个实体属性,而是需要根据用户状态进行聚合计算。

这就是为什么需要一个 data provider 将聚合数据传给控制器中的 DataSet

选择 Controller 导航到控制器类代码,并将 pie 组件注入类中,下面我们以编程方式与图表组件进行交互。

@ViewComponent
protected Chart pie;

如需在视图初始化时处理数据,创建 InitEvent 的处理方法。

onInit 方法中,根据用户的入职状态查询用户数量,并将结果传递给 DataSet 类。

使用 DataManager 加载每个入职状态中的用户总数,如下所示:

final Integer notStarted = dataManager.loadValue(
                "select count(u) from User u where u.onboardingStatus = :onboardingStatus",
                Integer.class
        )
        .parameter("onboardingStatus", OnboardingStatus.NOT_STARTED)
        .one();

final Integer inProgress = dataManager.loadValue(
                "select count(u) from User u where u.onboardingStatus = :onboardingStatus",
                Integer.class
        )
        .parameter("onboardingStatus", OnboardingStatus.IN_PROGRESS)
        .one();


final Integer completed = dataManager.loadValue(
                "select count(u) from User u where u.onboardingStatus = :onboardingStatus",
                Integer.class
        )
        .parameter("onboardingStatus", OnboardingStatus.COMPLETED)
        .one();

接下来,创建 ListChartItems,用于存储图表数据。为每个入职状态创建 MapDataItem 实例,其中保存状态名称和数量的键值对。

将准备好的数据项绑定到饼图。与 XML 中的 dataSet 元素一样,定义 categoryField 定义为状态名称,valueField 为数量。

以下是方法的具体内容:

@Subscribe
public void onInit(final InitEvent event) {
    final Integer notStarted = dataManager.loadValue(
                    "select count(u) from User u where u.onboardingStatus = :onboardingStatus",
                    Integer.class
            )
            .parameter("onboardingStatus", OnboardingStatus.NOT_STARTED)
            .one();

    final Integer inProgress = dataManager.loadValue(
                    "select count(u) from User u where u.onboardingStatus = :onboardingStatus",
                    Integer.class
            )
            .parameter("onboardingStatus", OnboardingStatus.IN_PROGRESS)
            .one();


    final Integer completed = dataManager.loadValue(
                    "select count(u) from User u where u.onboardingStatus = :onboardingStatus",
                    Integer.class
            )
            .parameter("onboardingStatus", OnboardingStatus.COMPLETED)
            .one();
    ListChartItems<MapDataItem> items = new ListChartItems<>(
            new MapDataItem(Map.of("category", "Completed", "value", notStarted)),
            new MapDataItem(Map.of("category", "Not Started", "value", inProgress)),
            new MapDataItem(Map.of("category", "In Progress", "value", completed))
        );


    pie.setDataSet(
            new DataSet()
                    .withSource(
                            new DataSet.Source<MapDataItem>()
                                    .withDataProvider(items)
                                    .withCategoryField("category")
                                    .withValueField("value")
                    )
    );
}

此饼图显示入职状态和每个状态中员工数量百分比的可视化结果。

pie res