Follow by Email

Saturday, 6 August 2016

ADF UI- Show DVT Chart inside af:table and other collection components


Hello All

This post is about showing a chart inside  ADF Faces Collection component like af:table or af:listView

This is a simple task to create normal chart but in case if we have to show table row record as a chart or graph then we have to change chart value and chart item value references so that it doesn't show all record but only values of that row

This post talks about these two requirements

1. Show same viewObject values as chart in af:table or af:listView
2. Show child viewObject values as chart in af:table or af:listView


For First Case I am using a query based viewObject that has Department wise Minimum, Maximum and Average Salary and using this viewObject I'll create a list view and graph in it

SELECT ROUND(AVG(B.SALARY),2) AVG_SAL,MIN(B.SALARY) MIN_SAL,MAX(B.SALARY) MAX_SAL,B.DEPARTMENT_ID,A.DEPARTMENT_NAME, 
A.MANAGER_ID,C.FIRST_NAME ||' '|| C.LAST_NAME AS MANAGER_NAME 
FROM DEPARTMENTS A, EMPLOYEES B ,EMPLOYEES C 
WHERE A.DEPARTMENT_ID=B.DEPARTMENT_ID  
AND A.MANAGER_ID=C.EMPLOYEE_ID 
GROUP BY B.DEPARTMENT_ID,A.DEPARTMENT_NAME,A.MANAGER_ID,C.FIRST_NAME ||' '|| C.LAST_NAME

Drop this viewObject as listView on page and drop bar chart from components window in list view,



Now right click on dvt:barChart and select insert inside bar and select dataStamp facet


After that add dvt:chartDataItem in dataStamp facet


Here I am using Manager Name to group chart data


In same manner added 3 <dvt:chartDataItem> for all 3 values (Minimum, Maximum, Average Salary)

See af:listView XML source with barChart in it

<af:listView value="#{bindings.DepartmentDet1.collectionModel}" var="item"
                                 emptyText="#{bindings.DepartmentDet1.viewable ? 'No data to display.' : 'Access Denied.'}"
                                 fetchSize="#{bindings.DepartmentDet1.rangeSize}" id="lv1"
                                 inlineStyle="width:500px;height:400px;">
                        <af:listItem id="li1">
                            <af:panelGridLayout id="pgl1">
                                <af:gridRow marginTop="5px" height="auto" marginBottom="5px" id="gr1">
                                    <af:gridCell marginStart="5px" width="50%" id="gc1" valign="middle">
                                        <af:panelGroupLayout id="pgl2" halign="center" layout="vertical">
                                            <af:outputText value="#{item.DepartmentName}" id="ot1"
                                                           inlineStyle="font-size:medium;color:navy;font-weight:bold;"/>
                                            <af:panelGroupLayout id="pgl3" layout="horizontal">
                                                <af:outputText value="Manager:  " id="ot2"/>
                                                <af:spacer width="2" height="0" id="s1"/>
                                                <af:outputText value="#{item.ManagerName}" id="ot3"
                                                               inlineStyle="color:red;"/>
                                            </af:panelGroupLayout>
                                        </af:panelGroupLayout>
                                    </af:gridCell>
                                    <af:gridCell marginStart="5px" width="50%" marginEnd="5px" id="gc2">
                                        <dvt:barChart id="chart1" value="#{item}" var="row"
                                                      inlineStyle="width:250px;height:100px;">
                                            <f:facet name="dataStamp">
                                                <af:group id="g2">
                                                    <dvt:chartDataItem group="#{row.ManagerName}" id="cdi1"
                                                                       value="#{row.MinSal}" series="Min Sal"/>
                                                    <dvt:chartDataItem group="#{row.ManagerName}" id="cdi2"
                                                                       value="#{row.AvgSal}" series="Average Sal"/>
                                                    <dvt:chartDataItem group="#{row.ManagerName}" id="cdi3"
                                                                       value="#{row.MaxSal}" series="Max Sal"/>
                                                </af:group>
                                            </f:facet>
                                        </dvt:barChart>
                                    </af:gridCell>
                                </af:gridRow>
                            </af:panelGridLayout>
                        </af:listItem>
                    </af:listView>

You can see highlighted code is of barChart and see it's configuration , It refers it's value from var attribute of listView (this var attribute presents a row of collection) and further chartItem refers it's value from barChart's var attribute

This graph show ManagerName and Min,Max,Avg Salary for each Departments , It looks like this on page :)


Now for Second Case I am using Departments and Employees tables of HR Schema , here Employees viewObject is child of Departments viewObject

Next I have dropped Departments viewObject as table on page and in binding section you can see a tree bindng for Departments viewObject, To show Employees record in chart for Each Department we have to add Employees viewObject binding in pagedef

Open pageEditor and click on Bindings tab at botom of page and then edit Departments tree binding , add Employees ViewObject from tree rules (click on green plus icon to see available rules)


Now add a column in af:table and drop barChart and ChartItem and here after adding tree binding for child viewObject now we can access it from master table's var attribute

See af:table XML source with barChart in it

<af:table value="#{bindings.Departments1.collectionModel}" var="row"
                              rows="#{bindings.Departments1.rangeSize}"
                              emptyText="#{bindings.Departments1.viewable ? 'No data to display.' : 'Access Denied.'}"
                              rowBandingInterval="1"
                              selectedRowKeys="#{bindings.Departments1.collectionModel.selectedRow}"
                              selectionListener="#{bindings.Departments1.collectionModel.makeCurrent}"
                              rowSelection="single" fetchSize="#{bindings.Departments1.rangeSize}" id="t1"
                              styleClass="AFStretchWidth" columnStretching="last" inlineStyle="height:400px;"
                              autoHeightRows="-1" width="800">
                        <af:column sortProperty="#{bindings.Departments1.hints.DepartmentId.name}" sortable="true"
                                   headerText="#{bindings.Departments1.hints.DepartmentId.label}" id="c1">
                            <af:outputText value="#{row.DepartmentId}"
                                           shortDesc="#{bindings.Departments1.hints.DepartmentId.tooltip}" id="ot4">
                                <af:convertNumber groupingUsed="false"
                                                  pattern="#{bindings.Departments1.hints.DepartmentId.format}"/>
                            </af:outputText>
                        </af:column>
                        <af:column sortProperty="#{bindings.Departments1.hints.DepartmentName.name}" sortable="true"
                                   headerText="#{bindings.Departments1.hints.DepartmentName.label}" id="c2">
                            <af:outputText value="#{row.DepartmentName}"
                                           shortDesc="#{bindings.Departments1.hints.DepartmentName.tooltip}" id="ot5"/>
                        </af:column>
                        <af:column sortProperty="#{bindings.Departments1.hints.ManagerId.name}" sortable="true"
                                   headerText="#{bindings.Departments1.hints.ManagerId.label}" id="c3">
                            <af:outputText value="#{row.ManagerId}"
                                           shortDesc="#{bindings.Departments1.hints.ManagerId.tooltip}" id="ot6">
                                <af:convertNumber groupingUsed="false"
                                                  pattern="#{bindings.Departments1.hints.ManagerId.format}"/>
                            </af:outputText>
                        </af:column>
                        <af:column sortProperty="#{bindings.Departments1.hints.LocationId.name}" sortable="true"
                                   headerText="#{bindings.Departments1.hints.LocationId.label}" id="c4">
                            <af:outputText value="#{row.LocationId}"
                                           shortDesc="#{bindings.Departments1.hints.LocationId.tooltip}" id="ot7">
                                <af:convertNumber groupingUsed="false"
                                                  pattern="#{bindings.Departments1.hints.LocationId.format}"/>
                            </af:outputText>
                        </af:column>
                        <af:column id="c5">
                            <dvt:barChart id="barChart1" var="var" value="#{row.Employees}"
                                          inlineStyle="width:250px;height:100px;">
                                <f:facet name="dataStamp">
                                    <af:group id="g1">
                                        <dvt:chartDataItem id="di1" group="#{var.FirstName} #{var.LastName}"
                                                           value="#{var.Salary}" series="Salary"/>
                                        <dvt:chartDataItem id="di2" group="#{var.FirstName} #{var.LastName}"
                                                           value="#{var.CommissionPct}" series="Commission"/>
                                    </af:group>
                                </f:facet>
                            </dvt:barChart>
                        </af:column>
                    </af:table>

The only difference here is that barChart refers it's value from master's var attribute and using that it aceess child collection model - #{row.Employees} and rest is same

This grpah shows salary of all Employee of a Department row wise


Sample ADF Application (Jdeveloper 12.1.3)- Download
Cheers :) Happy Learning

2 comments :

  1. Hi Ashish,

    Thanks a ton for the post. Exactly what I was looking for :)

    -Sapna

    ReplyDelete