Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » NatTable » How to make GroupBy and Summary layer work together(Discussion about GroupBy and Summary layer )
How to make GroupBy and Summary layer work together [message #1705379] Fri, 14 August 2015 10:50 Go to next message
André Forberg is currently offline André ForbergFriend
Messages: 8
Registered: July 2015
Junior Member
Hi all,

this time I want to provide a solution instead of asking a question Smile

It's about the experience I made with the GroupBy and Summary layer.
For everyone unfamiliar with this have a look at the examples: Tutorial Examples -> Integration -> SortableGroupByFilterColumnGroupAndFreezeExample.

In this example you can group by a specific column, e.g. 'Gender' or 'Married'.
The SummaryProvider provides the correct result of the summary / the the average of 'Money'. So far, so good.

The 'collapse all' button now collapses the tree nodes. Either immediately or after resizing one column the summary cache is cleared, which invokes a recalculation of the values.
But now, the average age is 'Avg: NaN' and the Money is 0.0, although we see clearly the sub summary (I never had to use this word before!) is greater zero.

Why is this so?

-> The summation provider iterates over the entire list and adds a value to the summary, but only if the Object at the row is a java.lang.Number.
If it's just grouped by the 'Gender' property, there are 2 rowObjects visible, both are instances of a GroupByObject, so the above mentioned condition is never true.

How to solve this problem?

You need a special summary provider, which works on grouped data. I guess you all know how to register the summary provider, so I won't explain this.


At first, you need the GroupByDataLayer.
There you get all the information needed, the rowCount (in the above mentioned example it is 2) and the provided data.
Second, you need the ColumnPropertyAccessor for the cells (since you use a GroupByDataLayer, this will be an GroupByColumnAccessor).

Use the rowCount to iterate above the list, row by row.

int rowCount = groupByDataLayer.getRowCount();
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
    //here will happen the calculation
}


Now check if the Object at the cell position is an instanceof GroupByObject.
If so, go get the FilterList:

for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
    //Step 1: get the filterlist
    Object erg = groupByDataLayer.getDataValue(columnIndex, rowIndex); //column and row index are provided as method parameters
    if (erg instanceof GroupByObject) {
        FilterList<T> elementsInGroup = groupByDataLayer.getElementsInGroup((GroupByObject) erg);

        //summation will happen here
    }
}

Now you got all the Objects under the tree node. And now?

My approach was to summarize just all the root node sub summaries, because the sub summary calculation is done before by another instance, which I don't care about right now.
Otherwise I will do the same calculation twice (once by the sub summary SummationProvider, once again by myself)

Example*:

  • Firstname Lastname Age Money
  • * MALE [5] - (5) 59 3296.38
  • Timothy Flanders 74 382.54
  • Timothy Smithers 95 950.05
  • Homer Lovejoy 58 727.67
  • Homer Simpson 16 501.16
  • Homer Krabappel 55 734.96

-> The result of the subsummary calculation is 3296.38 (provided by the sub summary SummationProvider).
-> elementsInGroup contains all this entries, the sum would be 3296.38, so why summarize them again? It was already calculated.


for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
    Object erg = groupByDataLayer.getDataValue(columnIndex, rowIndex);

    if (erg instanceof GroupByObject) {
        FilterList<T> elementsInGroup = groupByDataLayer.getElementsInGroup((GroupByObject) erg);

        boolean isRootNode = groupByDataLayer.getTreeRowModel().depth(rowIndex) == 0;

        if(isRootNode) {
                for (T rowObject : elementsInGroup) {
                        Object dataValue = columnPropertyAccessor.getDataValue(rowObject, columnIndex);
                        if (dataValue instanceof Number) {
                                //cast to you desired Number subclass (Double, BigDecimal, etc.)
                                //add dataValue to summary
                        }
                }
        }
}


If there is no isRootNode check, every tree node would be used for the calculation, which would lead to a miscalculation.
Short Example*: The table is grouped by Gender -> Firstname -> Lastname and filtered by Firstname = 'Homer' and Lastname = 'Krabappel'

  • Firstname Lastname Age Money
  • * MALE [1] - (1) 55 734.96
  • ** Homer [1] - (1) 55 734.96
  • *** Krabappel [1] - (1) 55 734.96
  • Homer Krabappel 55 734.96


Every sub summary would be used for calculation:
734.96 (Result of tree node MALE -> Homer -> Krabappel)
+ 734.96 (Result of tree node MALE -> Homer)
+ 734.96 (Result of tree node MALE)
________________________________
= 2204.88 (This would be displayed at the summary row, which is obviously wrong)

And if there is no group criteria?

Well, then there is no GroupByObject available, but you can use a normal summary provider now, since the values are not grouped anymore, no entry is hidden (at least not by the GroupBy layer).


That's it, folks.

The discussion is now open, you can add additional code / examples / or point out, which disadvantage this solution might have.

I thought it is my turn to give something back to the community, since there was always a quick response to all of my questions / bug reports and there is example data and tutorials (which is not always the case).

Thank you all for working on it, especially Mr. Dirk Fauth, thank you for helping us all!


Best Regards

André



*By the way: It is hard to show tables within a entry, maybe someone can allow HTML code so we could at last add html tables.

[Updated on: Fri, 14 August 2015 13:54]

Report message to a moderator

Re: How to make GroupBy and Summary layer work together [message #1705382 is a reply to message #1705379] Fri, 14 August 2015 12:39 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2803
Registered: July 2012
Senior Member
Hi,

at first, thanks for sharing your experience with us. I just have two questions regarding your post:

a) Why are you referring to the SortableGroupByFilterColumn? It doesn't contain a summary row, so it means you added it yourself. Wouldn't the GroupBySummarySummaryRowExample be a better matching example? It already contains the solution for your use cases AFAICS.
b) Your solution is correct and in the GroupBySummarySummaryRowExample the average summary providers are using the same approach. But that example also shows a little trick to use the default summary provider in such a use case. It simply creates an additional IDataProvider based on an underlying list instead of the GroupByDataProvider. This way you should not have to deal with the GroupByObjects as they are added to the TreeList on the tree transformation. Below the snippet from that example:

// create a new IDataProvider that operates on the basic underlying list
// this is necessary because the IDataProvider in the body layer stack
// is operating on the TreeList, and on collapsing a node, the children
// will be not visible, which has effect on the summary value.
final IDataProvider summaryDataProvider = new ListDataProvider(bodyLayerStack.getSortedList(), columnPropertyAccessor);
this.sumMoneySummaryProvider = new SummationSummaryProvider(summaryDataProvider, false);


Note: This doesn't mean that your results are not correct. As I already said, your investigation results are correct. I just wanted to show a different approach to achieve the same and show that there is a tutorial for that case (just because you complained that there is not an example for every use case)
Re: How to make GroupBy and Summary layer work together [message #1705390 is a reply to message #1705382] Fri, 14 August 2015 13:54 Go to previous messageGo to next message
André Forberg is currently offline André ForbergFriend
Messages: 8
Registered: July 2015
Junior Member
Hello Dirk,

it was the SortableGroupByFilterColumnGroupAndFreezeExample I was referring to, but I didn't get the full name. The Sash is not resizeable, and there was just a 'SortableGroupByFilterCol...', and maybe I thought, it can only end with 'umn' Smile I will correct it in my first post.

To be honest, I didn't have a look at the GroupBySummarySummaryRowExample. I don't know why. It was right in front of me, and I didn't see it. Shame on me.

The trick is brilliant, I would have never come to this solution! I definitly will have a look at the example this time, maybe it will be also work faster and more stable than my solution.

And of course I didn't mean to complain about the missing tutorials of the NatTable! I was tring to say, that OTHER products don't come in with a whole bunch of examples. Please don't get me wrong. I'm glad that there is an example for every possilbe configuration.

I'm not sure, if you read my last sentence. Is it possible to add html code tags for tables? Or is there another way of displaying a table in here (other than creating a screenshot)?

Thanks in advance and have a nice weekend!
Re: How to make GroupBy and Summary layer work together [message #1705403 is a reply to message #1705390] Fri, 14 August 2015 17:14 Go to previous message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2803
Registered: July 2012
Senior Member
I don't know a way to render a table in the forum. You need to ask the webmaster for such a requirement.

Maybe it is more stable, but I'm not sure. We recently came across a multi-threading issue regarding the summary calculation. I will try to fix this for 1.4.
Previous Topic:Cell Combo,Checkbox editor
Next Topic:ColumnOverrideAccumulator to ColumnGroupHeaderLayer or ColumnGroupGroupHeaderLayer
Goto Forum:
  


Current Time: Thu Mar 04 01:16:23 GMT 2021

Powered by FUDForum. Page generated in 0.01442 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top