问题描述
我想显示一个图表(sap.viz.ui5.controls.VizFrame
),以可视化OData服务中的数据。但是,必须对服务的数据进行操作。请参见下面的示例:
Main.view.xml
<mvc:View controllerName="demo.chart.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m">
<Shell id="shell">
<App id="app">
<pages>
<Page id="page" title="Chart Demo">
<content></content>
</Page>
</pages>
</App>
</Shell>
</mvc:View>
Chart.fragment.xml
<c:FragmentDeFinition xmlns:c="sap.ui.core" xmlns:viz="sap.viz.ui5.controls" xmlns:viz.data="sap.viz.ui5.data"
xmlns:viz.Feeds="sap.viz.ui5.controls.common.Feeds">
<viz:VizFrame uiConfig="{applicationSet:'fiori'}" vizType='donut'>
<viz:dataset>
<viz.data:FlattenedDataset data="{manipulatedData>/}">
<viz.data:dimensions>
<viz.data:DimensionDeFinition name="Gender" value="{manipulatedData>gender}"/>
</viz.data:dimensions>
<viz.data:measures>
<viz.data:MeasureDeFinition name="Amount" value="{manipulatedData>amount}"/>
</viz.data:measures>
</viz.data:FlattenedDataset>
</viz:dataset>
<viz:Feeds>
<viz.Feeds:FeedItem uid="color" type="Dimension" values="Gender"/>
<viz.Feeds:FeedItem uid="size" type="Measure" values="Amount"/>
</viz:Feeds>
</viz:VizFrame>
</c:FragmentDeFinition>
Main.controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller","sap/ui/model/json/JSONModel","sap/ui/core/Fragment"
],function (Controller,JSONModel,Fragment) {
"use strict";
return Controller.extend("demo.chart.controller.Main",{
onInit: function () {
const mDefault = this.getownerComponent().getModel();
const mManipulatedData = new JSONModel([{
gender: "F",amount: 0
},{
gender: "M",{
gender: "X",amount: 12
}]);
this.getView().setModel(mManipulatedData,"manipulatedData");
console.log(this.getView().getModel("manipulatedData"));
mDefault.read("/ContactSet",{
success: oData => {
const aManipulatedData = mManipulatedData.getData();
oData.results.forEach(entry => {
aManipulatedData.forEach(type => {
if (entry.Sex === type.gender) {
type.amount++
}
})
});
Fragment.load({
name: "demo.chart.view.Chart",controller: this
}).then(oFragment => {
this.getView().addDependent(oFragment);
this.byId("page").addContent(oFragment);
});
}
})
}
});
});
服务的结构(GWSAMPLE_BASIC/ContactSet
)
{
"d": {
"results": [
{
"__Metadata": {
"id": "https://sapes5.sapdevcenter.com/sap/opu/odata/IWBEP/GWSAMPLE_BASIC/ContactSet(guid'0050568c-901d-1eda-bcae-e8394de7e116')","uri": "https://sapes5.sapdevcenter.com/sap/opu/odata/IWBEP/GWSAMPLE_BASIC/ContactSet(guid'0050568c-901d-1eda-bcae-e8394de7e116')","type": "GWSAMPLE_BASIC.Contact"
},"Address": {
"__Metadata": {
"type": "GWSAMPLE_BASIC.CT_Address"
},"City": "Walldorf","PostalCode": "69190","Street": "Robert-Koch-Straße","Building": "1","Country": "DE","Addresstype": "02"
},"ContactGuid": "0050568c-901d-1eda-bcae-e8394de7e116","BusinessPartnerID": "0100000000","Title": "","FirstName": "Karl","MiddleName": "","LastName": "Müller","Nickname": "","Initials": "","Sex": "M","PhoneNumber": "0622734567","Faxnumber": "0622734004","EmailAddress": "do.not.reply@sap.com","Language": "EN","DateOfBirth": null,"ToBusinessPartner": {
"__deferred": {
"uri": "https://sapes5.sapdevcenter.com/sap/opu/odata/IWBEP/GWSAMPLE_BASIC/ContactSet(guid'0050568c-901d-1eda-bcae-e8394de7e116')/ToBusinessPartner"
}
}
}
]
}
}
因此,如您所见,我只对Sex
属性的聚合值感兴趣。我当前的解决方案是遍历实体集的所有条目,并在自定义JSON模型中增加属性。这不仅表现不佳,因为您需要在客户端进行繁重的工作,而且还要求您立即了解图表中显示的数据的所有可能值。是否可以通过OData查询来执行此操作,还是必须在SAP系统中使用已编译的数据创建一个新的实体集?
解决方法
OData应该能够进行计数和分组,如以下问题所述:OData v4 groupby with $count
但是我怀疑您的SAP OData服务在大多数情况下不会实现完整的OData规范。
您可以通过不使用两个嵌套的for循环来改善js,如下所示:
mGender = {};
oData.results.forEach(entry => {
if (!mGender[entry.Sex])
{mGender[entry.Sex] = 0
}
mGender[entry.Sex]++
});