Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Problem with Group Summary not displaying for User Formulas

    Hi there,

    We are seeing a problem where user formulas are showing grid summaries but not group summaries when the formula contains a field that doesn't calculate a summary value itself.

    Use the Custom Columns example:
    http://www.smartclient.com/#customColumns

    Use the code below.

    Click Show Formula Builder. Add a formula of A+B for Population + Area and click Save.

    The New Field will display a Grid Summary value but no Group Summary value. In our application, if we change the fields in the formula to fields that do calculate their own summary stats, it seems to fix the issue. But, in this example, the formula never displays group summary values so not sure why there is that inconsistency. Also, if you click "recreate from state" in the example, it seems to fix the issue for some reason? Hopefully this gives you enough to investigate the problem.


    Code:
    var ds = isc.DataSource.get("countryDS");
    
    isc.VLayout.create({
    	ID:"layout",
    	width:500, height:250,
    	members: [
    		isc.HLayout.create({
    			ID:"buttonLayout",
    			width:"*", height:30,
    			membersMargin: 10,
    			members: [
    				isc.IButton.create({
    				    ID: "formulaButton",
    				    autoFit: true,
    				    title: "Show Formula Builder",
    				    click: "countryList.addFormulaField();"
    				}),
    				isc.IButton.create({
    				    ID: "summaryButton",
    				    autoFit: true,
    				    title: "Show Summary Builder",
    				    click: "countryList.addSummaryField();"
    				}),
    				isc.IButton.create({
    				    ID: "stateButton",
    				    autoFit: true,
    				    title: "Recreate from State",
    				    click: function () {
    				        var state = countryList.getFieldState(true);
    						countryList.destroy();
    						recreateListGrid();
    				        countryList.setFieldState(state);
    				    }
    				})
    			]
    		})
    	]
    });
    
    recreateListGrid();
    
    function recreateListGrid() {
    	layout.addMember(isc.ListGrid.create({
    	    ID: "countryList",
    	    width:"100%", height:"*",
    	    alternateRecordStyles:true, cellHeight:22,
    	    dataSource: ds,
    	    autoFetchData: true,
    	    canAddFormulaFields: true,
                showGroupSummary:true,
                showGridSummary:true,
    	    canAddSummaryFields: true,
    	    fields:[
    	        {name:"countryCode", title:"Flag", width:50, type:"image", imageURLPrefix:"flags/16/", 
    	            imageURLSuffix:".png"
    	        },
    	        {name:"countryName", title:"Country"},
    	        {name:"capital", title:"Capital"},
    	        {name:"population", title:"Population", formatCellValue:"isc.NumberUtil.toUSString(value)",summaryFunction:"return null;"},
    	        {name:"area", title:"Area (km²)", formatCellValue:"isc.NumberUtil.toUSString(value)"},
    	        {name:"gdp", formatCellValue:"isc.NumberUtil.toUSString(value)"}
    	    ]
    	}));
    
          countryList.groupBy('countryName');
    
    }

    #2
    Thanks for the notification. We've made a change to address this issue which will be present in the next nightly build (9.0 and 9.12 branches)

    Regards
    Isomorphic Software

    Comment


      #3
      Hi, the original problem I sent you is resolved. But, I've found another similar problem when there are null values.


      Using the same example:
      http://www.smartclient.com/#customColumns

      But use the code below that blanks out a population value. Add a Formula like "A+B" and you'll see that Group summaries are not calculated for the formula for the first group because a Population value is null. Looks like the gird summary is also blank because of this null value as well.


      Code:
      var ds = isc.DataSource.get("countryDS");
      
      isc.VLayout.create({
      	ID:"layout",
      	width:500, height:250,
      	members: [
      		isc.HLayout.create({
      			ID:"buttonLayout",
      			width:"*", height:30,
      			membersMargin: 10,
      			members: [
      				isc.IButton.create({
      				    ID: "formulaButton",
      				    autoFit: true,
      				    title: "Show Formula Builder",
      				    click: "countryList.addFormulaField();"
      				}),
      				isc.IButton.create({
      				    ID: "summaryButton",
      				    autoFit: true,
      				    title: "Show Summary Builder",
      				    click: "countryList.addSummaryField();"
      				}),
      				isc.IButton.create({
      				    ID: "stateButton",
      				    autoFit: true,
      				    title: "Recreate from State",
      				    click: function () {
      				        var state = countryList.getFieldState(true);
      						countryList.destroy();
      						recreateListGrid();
      				        countryList.setFieldState(state);
      				    }
      				})
      			]
      		})
      	]
      });
      
      recreateListGrid();
      
      function recreateListGrid() {
      	layout.addMember(isc.ListGrid.create({
      	    ID: "countryList",
      	    width:"100%", height:"*",
      	    alternateRecordStyles:true, cellHeight:22,
      	    dataSource: ds,
      	
      	    canAddFormulaFields: true,
                  showGroupSummary:true,
                  showGridSummary:true,
      	    canAddSummaryFields: true,
      	    fields:[
      	        {name:"countryCode", title:"Flag", width:50, type:"image", imageURLPrefix:"flags/16/", 
      	            imageURLSuffix:".png"
      	        },
      	        {name:"countryName", title:"Country"},
      	        {name:"capital", title:"Capital"},
      	        {name:"population",  title:"Population", formatCellValue:"isc.NumberUtil.toUSString(value)",summaryFunction:"return null;"},
      	        {name:"area",  title:"Area (km²)", formatCellValue:"isc.NumberUtil.toUSString(value)"},
      	        {name:"gdp", formatCellValue:"isc.NumberUtil.toUSString(value)"}
      	    ]
      	}));
      
            
            countryList.fetchData(null,"data[0].population=null;countryList.groupBy('continent');countryList.groupTree.openAll()");
      
      
      
      }

      Comment


        #4
        Hi there, I'm hoping you can take a look at this latest problem I found sometime soon because it is impacting our production users.

        We recently upgraded our production app to 9.0 and this wasn't happening in 8.3 so it is a regression. I confirmed that the test case works fine on your 8.3 Feature Explorer as well at http://www.smartclient.com/docs/8.3/a/system/reference/SmartClient_Explorer.html#customColumns

        Comment


          #5
          This is has been addressed - please retest with a build dated October 5 or later

          Comment


            #6
            Hi, we've found some more problems still affecting our production users and I've recreated them with your a recent nightly build of Smartclient 9.0.

            Using this sample but in a recent SDK for both issues below: http://www.smartclient.com/#customColumns


            1. Run the sample and apply the code below. Then add a formula field with formula of A+B for population + area. Because United States row has a population value, it should definitely be showing a Group Summary (for north america group) and Grid summary value for the formula. But, it is not. If you take the sample code below and remove the summaryFunction:"return null;" from the population field definition, it then works. So, there is an issue where the component fields of the formula apparently have to be displaying summary values on their own for the formula values to display summary values and that shouldn't be necessary. Additionally, when you do remove the summaryFunction:"return null" from the population column, the group summaries are showing values but the grid summary is showing as 0. Finally, the group summary values for the Formula look correct but the individual cells are not showing the values in each row for the formula. Ideally when A+B executes for each row, it should be able to substitute a 0 for the null so they work at the cell level. It appears that is what is happening at the group summary level. Then again the grid summary is showing 0 so there is inconsistent behavior in between the cells, the group summary, and the grid summary Hopefully all of that makes sense.


            Code:
            var ds = isc.DataSource.get("countryDS");
            
            isc.VLayout.create({
                 ID:"layout",
                 width:500, height:250,
                 members: [
                      isc.HLayout.create({
                           ID:"buttonLayout",
                           width:"*", height:30,
                           membersMargin: 10,
                           members: [
                                isc.IButton.create({
                                    ID: "formulaButton",
                                    autoFit: true,
                                    title: "Show Formula Builder",
                                    click: "countryList.addFormulaField();"
                                }),
                                isc.IButton.create({
                                    ID: "summaryButton",
                                    autoFit: true,
                                    title: "Show Summary Builder",
                                    click: "countryList.addSummaryField();"
                                }),
                                isc.IButton.create({
                                    ID: "stateButton",
                                    autoFit: true,
                                    title: "Recreate from State",
                                    click: function () {
                                        var state = countryList.getFieldState(true);
                                          countryList.destroy();
                                          recreateListGrid();
                                        countryList.setFieldState(state);
                                    }
                                })
                           ]
                      })
                 ]
            });
            
            recreateListGrid();
            
            function recreateListGrid() {
                 layout.addMember(isc.ListGrid.create({
                     ID: "countryList",
                     width:"100%", height:"*",
                     alternateRecordStyles:true, cellHeight:22,
                     dataSource: ds,
                  applyFormulaAfterSummary:true,
                     canAddFormulaFields: true,
                        showGroupSummary:true,
                        showGridSummary:true,
                     canAddSummaryFields: true,
                     fields:[
                         {name:"countryCode", title:"Flag", width:50, type:"image", imageURLPrefix:"flags/16/", 
                             imageURLSuffix:".png"
                         },
                         {name:"countryName", title:"Country"},
                         {name:"capital", title:"Capital"},
                         {name:"population",  title:"Population", formatCellValue:"isc.NumberUtil.toUSString(value)",summaryFunction:"return null;"},
                         {name:"area",  title:"Area (km²)", formatCellValue:"isc.NumberUtil.toUSString(value)"},
                         {name:"gdp", formatCellValue:"isc.NumberUtil.toUSString(value)"}
                     ]
                 }));
            
                  
                  countryList.fetchData(null,"var undefinedVar;data.setProperty('population',null);data[0].population=1000;countryList.groupBy('continent');countryList.groupTree.openAll()");
            
            
            
            }

            Comment


              #7
              another example of problem with a registered function

              Hi, just to make sure this further use case is covered by your review as well, the following example is also a problem. The code below registers a function called doublePopulation. If you run the sample and then create a formula field with the formula doublePopulation(record), then you'll see that there is no group summary values unless you also display a group summary for population since population is referenced in the doublePopulation function.

              Finally, I mentioned in the previous post that null should possibly be converted to 0 but I see we've talked about this in the past and decided that nulls should not be converted to zero so you can ignore that comment.

              Code:
              var ds = isc.DataSource.get("countryDS");
              
              isc.VLayout.create({
                   ID:"layout",
                   width:500, height:250,
                   members: [
                        isc.HLayout.create({
                             ID:"buttonLayout",
                             width:"*", height:30,
                             membersMargin: 10,
                             members: [
                                  isc.IButton.create({
                                      ID: "formulaButton",
                                      autoFit: true,
                                      title: "Show Formula Builder",
                                      click: "countryList.addFormulaField();"
                                  }),
                                  isc.IButton.create({
                                      ID: "summaryButton",
                                      autoFit: true,
                                      title: "Show Summary Builder",
                                      click: "countryList.addSummaryField();"
                                  }),
                                  isc.IButton.create({
                                      ID: "stateButton",
                                      autoFit: true,
                                      title: "Recreate from State",
                                      click: function () {
                                          var state = countryList.getFieldState(true);
                                            countryList.destroy();
                                            recreateListGrid();
                                          countryList.setFieldState(state);
                                      }
                                  })
                             ]
                        })
                   ]
              });
              
              recreateListGrid();
              
              function recreateListGrid() {
                   layout.addMember(isc.ListGrid.create({
                       ID: "countryList",
                       width:"100%", height:"*",
                       alternateRecordStyles:true, cellHeight:22,
                       dataSource: ds,
                    applyFormulaAfterSummary:true,
                       canAddFormulaFields: true,
                          showGroupSummary:true,
                          showGridSummary:true,
                       canAddSummaryFields: true,
                       fields:[
                           {name:"countryCode", title:"Flag", width:50, type:"image", imageURLPrefix:"flags/16/", 
                               imageURLSuffix:".png"
                           },
                           {name:"countryName", title:"Country"},
                           {name:"capital", title:"Capital"},
                           {name:"population",  title:"Population", formatCellValue:"isc.NumberUtil.toUSString(value)",summaryFunction:"return null;"},
                           {name:"area",  title:"Area (km²)", formatCellValue:"isc.NumberUtil.toUSString(value)"},
                           {name:"gdp", formatCellValue:"isc.NumberUtil.toUSString(value)"}
                       ]
                   }));
              
                    
                    countryList.fetchData(null,"var undefinedVar;data.setProperty('population',null);data[0].population=1000;countryList.groupBy('continent');countryList.groupTree.openAll()");
              
              
              
              }
              
              
              
              var testFunction={jsFunction:function(record){if(record.population!=null){return record.population*2;}else{return null;}},name:"doublePopulation",description:"doublePopulation"};
              isc.MathFunction.registerFunction(testFunction);

              Comment


                #8
                This is slated to be looked at today. We'll follow up when we have more information

                Regards
                Isomorphic Software

                Comment


                  #9
                  Hi senordhuff,

                  Several question / issues in here. We've split them up and responded below:

                  From post #6:
                  1. Run the sample and apply the code below.
                  Then add a formula field with formula of A+B for population + area.
                  Because United States row has a population value, it should definitely be showing a Group Summary (for north america group) and Grid summary value for the formula. But, it is not.
                  If you take the sample code below and remove the summaryFunction:"return null;" from the population field definition, it then works.
                  So, there is an issue where the component fields of the formula apparently have to be displaying summary values on their own for the formula values to display summary values and that shouldn't be necessary.
                  Setting the summaryFunction to return null for the population field correctly suppresses the summary values from showing in the "Population" field in either group or grid summary rows.
                  The formula field is calculating its value per row - in other words, for the group summary row and the grid summary row it's looking at the value of the "Population" field (null) and the "Area" field and adding them together. Since the "Population" field is empty, it's an invalid formula (nothing to show).
                  It sounds like what you're expecting is that the group / grid summary row would actually show a sum of the calculated formula values from the group [or grid], rather than looking applying the formula to the calculated values on the summary row. This is controlled by the applyFormulaAfterSummary attribute. If you leave the summaryFunction:"return null" in place, and change this attribute to be false rather than true, and then add the formula field, the grid/group summary row will show a summary value for the formula row (in other words will be non-null even though within the summary row the "Population" field is empty).

                  Additionally, when you do remove the summaryFunction:"return null" from the population column, the group summaries are showing values but the grid summary is showing as 0.
                  We're not seeing this on our end. If you are still seeing this, perhaps you have local changes to the data set which is somehow responsible, or similar. Can you try downloading a fresh, latest nightly build, unzip, run the "start-embedded-server" script and launch a fresh browser with a clear cache / go through the steps to reproduce and let us know if you're still seeing it?

                  Finally, the group summary values for the Formula look correct but the individual cells are not showing the values in each row for the formula.
                  Ideally when A+B executes for each row, it should be able to substitute a 0 for the null so they work at the cell level.
                  Skipping this one as you answered your own comment in Post #7 - nulls aren't treated as zeros.

                  From Post #7:
                  Hi, just to make sure this further use case is covered by your review as well, the following example is also a problem. The code below registers a function called doublePopulation. If you run the sample and then create a formula field with the formula doublePopulation(record), then you'll see that there is no group summary values unless you also display a group summary for population since population is referenced in the doublePopulation function.
                  This is the same as the first issue - you need "applyFormulaAfterSummary" to be false to get this behavior.


                  Regards
                  Isomorphic Software

                  Comment

                  Working...
                  X