SAPUI5 SmartChart with CDSView Annotations is not Displayed - sapui5

I am pretty new to the SAP environment and couldn't find a suitable solution to the following problem in the community forum or using the samples/templates/API docs or SAP books, thus I am asking this question.
My Problem: I created a CDS-View with Annotations (for a table and a chart) and linked it using my service to an own SAPUI5 application. While the SmartTable is created without any problems, the SmartChart is giving me the following error:
TypeError: can't convert undefined to object RoleFitter.js
I looked up the error and it seems like something is not correct in the annotations file. However, I couldn't find an error and since it is auto-generated from the CDS-View Annotations I am a little confused (the SmartTable is working and I can add/change UserText Annotations without any problem).
Furthermore, when I use the created CDSView wit a standard SAP template (e.g. in cards in an Overview Page Template) it works just fine.
For any solutions or hints I am super thankful since this is bothering me a lot and I don't understand why the SmartTable is working but the chart isn't.
Thanks in advance!
CDSView:
#AbapCatalog.sqlViewName: 'ZYSS20MSGITEST3'
#AbapCatalog.compiler.compareFilter: true
#AccessControl.authorizationCheck: #NOT_REQUIRED
#EndUserText.label: 'Test view 3'
#UI: {headerInfo: {
typeName:'Test3',
title:{
type: #STANDARD,
label: 'Suche'
}
}
}
#UI.chart: [{
qualifier: 'OccupiedSeats',
chartType: #COLUMN,
dimensions: [ 'FlightCode' ],
measures: [ 'MaximumCapacity', 'EconomyOccupiedSeats', 'BusinessOccupiedSeats', 'FirstOccupiedSeats' ]
}]
define view ZY_SS20_MSGI_TEST3
as select from sflight
{
#UI.lineItem: [ { position: 10 } ]
key concat(carrid, connid) as FlightCode,
#UI.lineItem: [ { position: 30 } ]
seatsmax as MaximumCapacity,
#UI.lineItem: [ { position: 40 } ]
seatsocc as EconomyOccupiedSeats,
#UI.lineItem: [ { position: 50 } ]
seatsocc_b as BusinessOccupiedSeats,
#UI.lineItem: [ { position: 60 } ]
seatsocc_f as FirstOccupiedSeats
}
Dashboard.controller.js:
sap.ui.define([
"sap/ui/core/mvc/Controller"
], function(Controller) {
"use strict";
return Controller.extend("ZY_SS20_MSGI_TESTN.controller.Dashboard", {
onInit: function() {
this._oModel = new sap.ui.model.odata.ODataModel("/sap/opu/odata/sap/ZY_SS20_MSGPROGRESSSRV_SRV/", true);
this.getView().setModel(this._oModel);
}
});
Dashboard.view.xml:
<mvc:View controllerName="ZY_SS20_MSGI_TESTN.controller.Dashboard" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc" xmlns:smartChart="sap.ui.comp.smartchart"
xmlns:data="http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1" xmlns:smartFilterBar="sap.ui.comp.smartfilterbar" xmlns:smartTable="sap.ui.comp.smarttable"
displayBlock="true" xmlns="sap.m">
<App>
<pages>
<Page title="{i18n>title}">
<content>
<VBox fitContainer="true">
<smartFilterBar:SmartFilterBar
id="smartFilterBar" entitySet="ZY_SS20_MSGI_TEST3" />
<smartTable:SmartTable id="mySmartTable"
entitySet="ZY_SS20_MSGI_TEST3" smartFilterId="smartFilterBar"
tableType="Table" useExportToExcel="true"
useVariantManagement="false" useTablePersonalisation="false"
header="Throughput" showRowCount="true" enableAutoBinding="true"
initiallyVisibleFields="FlightCode,MaximumCapacity,EconomyOccupiedSeats,BusinessOccupiedSeats,FirstOccupiedSeats">
</smartTable:SmartTable>
<smartChart:SmartChart entitySet="ZY_SS20_MSGI_TEST3"
enableAutoBinding="true" id="mySmartChart" useVariantManagement="false"
useChartPersonalisation="false" header="Test"></smartChart:SmartChart>
</VBox>
</content>
</Page>
</pages>
</App>
</mvc:View>

The problem seems to be that you are providing a qualifier to the chart annotation but not specifying the same to the SmartChart control. Try adding this property to your SmartChart tag:
data:chartQualifier="OccupiedSeats"

Related

Adding a SimplePlanningCalendar to a UI5 app fails with `getKey` error

When I add a SimplePlanningCalendar to my app, I got the following Error.
I added the calendar with a minimal configuration to my app.
<IconTabBar xmlns="sap.m"
id="idCategoryMenu"
selectedKey="Home"
headerMode="Inline"
stretchContentHeight="true"
applyContentPadding="false"
select=".onSelectCategory"
items="{
path: 'backend>/CategorySet',
parameters: {
expand: 'Reports'
},
sorter: {
path: 'Sort'
},
templateShareable: true
}">
<items>
<IconTabFilter id="myIconTabFilter" key="{backend>Uuid}" text="{backend>Name}">
<!-- ... -->
<SinglePlanningCalendar>
<appointments>
<unified:CalendarAppointment xmlns:unified="sap.ui.unified"
title="{title}"
startDate="{startDate}"
endDate="{endDate}"
/>
</appointments>
</SinglePlanningCalendar>
<!-- ... -->
</IconTabFilter>
</items>
</IconTabBar>
When I debug the app, I come to the following line inside the SinglePlanningCalendar.js where a key from the given vView parameter is requested, but the parameter only holds a string.
Anyone else had this problem before and knows why or how to solve this?
The problem is caused by the control implementation itself in the current version (1.71.21) I use for my development.
The fix in the commit 45696fe is available as of UI5 1.75.x.
Since I cannot change my version, I implemented the given solution in my package:
{ // Controller
onInit: function () {
// ...
this.calendarTemporaryFix(); // Not needed since UI5 1.75
},
calendarTemporaryFix: function () {
// SinglePlanningCalendar required from "sap/m/SinglePlanningCalendar"
const fnSetSelectedView = SinglePlanningCalendar.prototype.setSelectedView;
SinglePlanningCalendar.prototype.setSelectedView = function (vView) {
if (typeof vView === "string") {
vView = sap.ui.getCore().byId(vView);
}
return fnSetSelectedView.call(this, vView);
};
},
// ...
}

SAPUI5 Smartable not showing the inital fields

I am trying to build a simple smarttable, using a CDS with annotation, I expect the columns to be displayed automatically but no column or selection field are displayed automatically. When I try to create a report with fiori element it is working fine but not with my freestyle app and smarttable. What is missing ?
#AbapCatalog.sqlViewName: 'ZTEST_CDS_SHP'
#AbapCatalog.compiler.compareFilter: true
#AbapCatalog.preserveKey: true
#AccessControl.authorizationCheck: #CHECK
#EndUserText.label: 'Test Shipment view'
#VDM.viewType: #CONSUMPTION
#VDM.private:false
#Search.searchable: true
#UI.headerInfo: { typeName: 'Order', typeNamePlural: 'Orders' }
#OData.publish: true
define view ZTESTV_CDS_SHP as select from ZRDCV_CDS_SHIPMENT
association [0..1] to ZTESTV_CDS_DCHELP as _DCValueHelp on $projection.DcSite = _DCValueHelp.Werks
association [0..1] to makt as _ArticleValueHelp on $projection.Article = _ArticleValueHelp.matnr and _ArticleValueHelp.spras = $session.system_language
{
#Search.defaultSearchElement: true
#UI.selectionField: [ { position: 10 } ]
#UI.lineItem: [ { position: 10, importance: #HIGH } ]
key shipment as Shipment,
#UI.selectionField: [ { position: 20 } ]
#UI.lineItem: [ { position: 20, importance: #HIGH } ]
key exidv as Hu,
....
here is the XML view
<mvc:View
controllerName="ns.shipment1.controller.Worklist"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc"
xmlns:semantic="sap.f.semantic"
xmlns:smartFilterBar="sap.ui.comp.smartfilterbar"
xmlns:app="http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1"
xmlns:smartTable="sap.ui.comp.smarttable">
<semantic:SemanticPage
id="page"
headerPinnable="false"
toggleHeaderOnTitleClick="false">
<semantic:titleHeading>
<Title
text="{i18n>worklistTitle}"
level="H2"/>
</semantic:titleHeading>
<semantic:content>
<!-- use this to make the table occupy the available screen height -->
<VBox fitContainer="true">
<!-- FILTER BAR ******************************************** -->
<smartFilterBar:SmartFilterBar
id="smartFilterBar"
entitySet="ZTESTV_CDS_SHP"
persistencyKey="SmartFilter_Explored"
basicSearchFieldName="Shipment"
enableBasicSearch="true"
visible="true"
considerSelectionVariants="true"
showFilterConfiguration="true">
</smartFilterBar:SmartFilterBar>
<!-- SMART TABLE ******************************************** -->
<smartTable:SmartTable
id="ShipmentTable"
entitySet="ZTESTV_CDS_SHP"
smartFilterId="smartFilterBar"
tableType="Table"
useExportToExcel="true"
beforeExport="onBeforeExport"
useVariantManagement="true"
useTablePersonalisation="true"
header="Shipment Items"
showRowCount="true"
persistencyKey="SmartTableAnalytical_Explored"
enableAutoBinding="true"
class="sapUiResponsiveContentPadding"
editTogglable="false"
app:useSmartField="true"
app:useSmartToggle="true">
</smartTable:SmartTable>
</VBox>
Actually, I found the Annotation model in /IWFND/MAINT_SERVICE transaction, by selecting the service, then service implemetation button and annotation model button.
I have added the annotations property in settings with the reference to the array which contains the annotation model. Note that in my case, annotation model is ZTESTV_CDS_SHP_CDS_VAN, when it usually ends by ANNO_MDL.
{
"dataSources": {
"mainService": {
"uri": "/sap/opu/odata/sap/ZTESTV_CDS_SHP_CDS/",
"type": "OData",
"settings": {
"odataVersion": "2.0",
"annotations": [
"ZTESTV_CDS_SHP_CDS_ANNOTATION"
],
"localUri": "localService/metadata.xml"
}
},
"ZTESTV_CDS_SHP_CDS_ANNOTATION": {
"uri": "/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/Annotations(TechnicalName='ZTESTV_CDS_SHP_CDS_VAN',Version='0001')/$value/",
"type": "ODataAnnotation"
}
}
}
Screenshot of the manifest:

sap.ui.layout.SplitPane Doesn't Apply SplitterLayoutData

I am trying to set the size on sap.ui.layout.SplitPane on the left side as following:
<Page title="Where used">
<l:ResponsiveSplitter defaultPane="default">
<l:PaneContainer>
<l:SplitPane requiredParentWidth="400">
<l:layoutData>
<l:SplitterLayoutData size="20%"/>
</l:layoutData>
<Panel height="100%">
<Label text="Hello"/>
</Panel>
</l:SplitPane>
<l:SplitPane requiredParentWidth="400">
<Panel height="100%">
<Label text="Hello"/>
</Panel>
</l:SplitPane>
</l:PaneContainer>
</l:ResponsiveSplitter>
</Page>
As you can see on the code, I tried to achieve with
<l:SplitterLayoutData size="20%"/>
But the size does not apply at all. What am I doing wrong?
I looked at this example: https://github.com/SAP/openui5/blob/master/src/sap.ui.layout/test/sap/ui/layout/ResponsiveSplitter.html#L106, [Result]
Update: The fix should be available as of UI5 version 1.60. Otherwise, please keep reading..
Just figured out that it only works if the aggregation <l:layoutData> comes after the default aggregation.
<l:SplitPane requiredParentWidth="400">
<Panel height="100%">
<Label text="Panel 1"/>
</Panel>
<l:layoutData>
<l:SplitterLayoutData size="20%"/>
</l:layoutData>
</l:SplitPane>
.. which shouldn't actually matter. I'll analyse the source code why it matters and update the answer later.[1] But this is how you can "fix" it so that it works for now.
Source: https://embed.plnkr.co/0yo35xOiSmF5eG6R?show=V.view.xml,preview
[1]: It turns out that SplitPane has an overwritten mutator for the layoutData aggregation:
SplitPane.prototype.setLayoutData = function(oLayoutdata) {
var oContent = this.getContent();
if (oContent) {
return oContent.setLayoutData(oLayoutdata);
} else {
return this;
}
};
source
As you can see, it applies the layout data not to itself but to its content. If the content doesn't exist at that moment, the <layoutData> is just ignored. And since XML nodes are evaluated sequentially one by one, the Panel (content) had to come first before the SplitterLayoutData.
IMO this is clearly a bug in the framework since the framework has to assure that the outcome is always the same no matter in which order aggregations were defined (content <--> layoutData).
Please check this: JS Fiddle
oResponsiveSplitter = new sap.ui.layout.ResponsiveSplitter({
defaultPane: "defaultPane",
rootPaneContainer: [
new sap.ui.layout.PaneContainer({
orientation: "Horizontal",
panes: [
new sap.ui.layout.PaneContainer({
// orientation: "Horizontal",
panes: [
new sap.ui.layout.SplitPane({
demandPane: true,
content: new sap.m.Panel({
headerText: "1",
content: new sap.m.Text({text: lorem + lorem})
}),
requiredParentWidth: 400
}),
new sap.ui.layout.SplitPane({
demandPane: false,
content: new sap.m.Panel({
headerText: "2",
content: new sap.m.Text({text: lorem + lorem})
}),
requiredParentWidth: 400,
layoutData: new sap.ui.layout.SplitterLayoutData({
size: "20%"
})
}),
new sap.ui.layout.SplitPane({
demandPane: true,
content: new sap.m.Panel({
headerText: "3",
content: new sap.m.Text({text: lorem + lorem})
}),
requiredParentWidth: 400,
}),
]
})
]
})
]
});
I think it answers your problem.
Also, I understand that here SplitterLayoutData size works as expected when the layout is horizontal.

SAP UI 5 XML-Templating / Preprocessing

I try to use the template:if for my XML View.
As an example i have this:
<mvc:View controllerName="Test_Start.controller.View"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:mvc="sap.ui.core.mvc"
xmlns:temp="http://schemas.sap.com/sapui5/extension/sap.ui.core.template/1"
displayBlock="true" xmlns="sap.m">
<App>
<pages>
<Page title="{i18n>title}">
<content>
<temp:if test="{= ${Data>Enable1} === 'X'}">
<Text text="Hallo"/>
</temp:if>
</content>
</Page>
</pages>
</App>
</mvc:View>
and my Component.js looks like this:
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/Device",
"Test_Start/model/models",
"sap/ui/model/odata/v2/ODataModel",
"sap/ui/core/util/XMLPreprocessor"
], function(UIComponent, Device, models, ODataModel, XMLPreprocessor) {
"use strict";
return UIComponent.extend("Test_Start.Component", {
metadata: {
manifest: "json"
},
/**
* The component is initialized by UI5 automatically during the startup of the app and calls the init method once.
* #public
* #override
*/
init: function() {
// call the base component's init function
UIComponent.prototype.init.apply(this, arguments);
// set the device model
this.setModel(models.createDeviceModel(), "device");
},
onBeforeRendering: function(){
var oModel = new ODataModel("/sap/opu/odata/SAP/ZPFO_CKPT_ODATA_DYN_SRV/"),
oMetaModel = oModel.getMetaModel(),
sPath = "/DataSet";
oMetaModel.loaded().then(function() {
var oTemplateView = sap.ui.view({
preprocessors: {
xml: {
bindingContexts : {
meta : oMetaModel.getMetaContext(sPath)
},
models: {
meta: oMetaModel
}
}
},
type : sap.ui.core.mvc.ViewType.XML,
viewName: "Test_Start.view.View"
});
oTemplateView.setModel(oModel);
oTemplateView.bindElement(sPath);
});
}
});
});
Now, when I try to run my App, i get the following error:
XMLTemplateProcessor-dbg.js:53 Uncaught Error: failed to load
'http://schemas/sap/com/sapui5/extension/sap/ui/core/template/1/if.js'
from
../../resources/http://schemas/sap/com/sapui5/extension/sap/ui/core/template/1/if.js:
404 - Not Found
I did some research and found out, that i probably load the preprocessor at the wrong time, but I seem to can't find the right place to load it.
I use this SAPUI5 SDK example for my work.
Edit
I found a solution for my problem:
instead of an "onBeforeRendering" function, now i'm using a "createContent" function. Also i deleted the "init" completly.
In adition to that, I implemented an oViewContainer, like it is used in the sample.
Also controller name "Test_Start.Component" doesn't match the controllerName attribute in the view "Test_Start.controller.View".

Vizframe - Stacked column chart category axis

I'm trying to create stacked column chart as on the picture attached, but I would like to remove "Effort" text highlighted in yellow.
The chart should display (per day) how many hours people worked on the project.
Stacked column chart
I have and XML view:
<core:View controllerName="sap.ui.demo.myFiori.view.Main"
xmlns:core="sap.ui.core" xmlns:viz="sap.viz.ui5.controls"
xmlns:viz.feeds="sap.viz.ui5.controls.common.feeds" xmlns:viz.data="sap.viz.ui5.data"
xmlns="sap.m">
<App>
<Page title="Reporting">
<viz:VizFrame xmlns:viz="sap.viz.ui5.controls" id="idVizFrame"
uiConfig="{applicationSet:'fiori'}" vizType="stacked_column" width="100%">
<viz:dataset>
<dataSet:FlattenedDataset xmlns:dataSet="sap.viz.ui5.data" data="{/Time}">
<dataSet:dimensions>
<dataSet:DimensionDefinition name="Date" value="{date}">
</dataSet:DimensionDefinition>
<dataSet:DimensionDefinition name="Name" value="{name}">
</dataSet:DimensionDefinition>
</dataSet:dimensions>
<dataSet:measures>
<dataSet:MeasureDefinition name="Effort" value="{real_effort}">
</dataSet:MeasureDefinition>
</dataSet:measures>
</dataSet:FlattenedDataset>
</viz:dataset>
<viz:feeds>
<feed:FeedItem xmlns:feed="sap.viz.ui5.controls.common.feeds"
uid="valueAxis" type="Measure" values="Effort"/>
<feed:FeedItem xmlns:feed="sap.viz.ui5.controls.common.feeds"
uid="categoryAxis" type="Dimension" values="Date" />
<feed:FeedItem xmlns:feed="sap.viz.ui5.controls.common.feeds"
uid="color" type="Dimension" values="Name" />
</viz:feeds>
</viz:VizFrame>
</Page>
</App>
</core:View>
In the controller in the onInit function I tried to set vizProperties. But when I set hidSubLevels of label of categoryAxis to true, then dates disappear. I don't understand why "Effort" is displayed as category, because it is defined as measure, not category. Could someone please advise how to do such chart without category "Effort" (yellow-highlighted on the picture attached)?
var oVizFrame = this.getView().byId("idVizFrame");
oVizFrame.setVizProperties({
interaction: {
behaviorType: null
},
plotArea: {
dataLabel: {
visible: false
}
},
valueAxis: {
title: {
visible: true,
},
},
categoryAxis: {
title: {
visible: false,
text: 'Category text'
},
label: {
hideSubLevels: false
},
},
title: {
visible: true,
text: 'Project'
},
tooltip: {
visible: true,
}
});
Setting the visibility of the categoryAxis to false seems like the correct approach. I took your code and put it into a Plunker and it works there.
Can you please remove as many as other possible configurations and try it again. If that doesn't help, can you please update my Plunker and create a runnable version of your issue? Maybe it's also a UI5 version issue. You could also try out to upgrade to a newer version.
Here's my Plunker:
https://embed.plnkr.co/td2ANcu0F2lZVgd7dfTC/