1. #1
    Sencha User
    Join Date
    Oct 2011
    Posts
    20
    Vote Rating
    0
    nstokoe is on a distinguished road

      0  

    Default Unanswered: Override calcuate method for Summary Row to handle Dates

    Unanswered: Override calcuate method for Summary Row to handle Dates


    I have a grid similar patterned after the Live Group Summary example in the 3.x showcase. Two of my columns contain dates and I would like to be able to have the latest date from each column appear in the summary row for each group. I wrote this code to override the caculate method:

    Code:
    SummaryColumnConfig<GranuleThroughputByProduct, Date> lastIngestedCol = new SummaryColumnConfig<GranuleThroughputByProduct, Date>(
                    props.lastIngestedTime(), 100, "Last Ingested Time");
            lastIngestedCol.setCell(new DateCell(DateTimeFormat.getFormat(CommonConstants.DATE_TIME_ISO8601)));
            lastIngestedCol.setSummaryType(new SummaryType<GranuleThroughputByProduct, Date, Number>() {
                @Override
                public Number calculate(
                        List<GranuleThroughputByProduct> m,
                        ValueProvider<GranuleThroughputByProduct, Date> valueProvider) { 
                    int dummyVal = 21;
                    Date latest = null;
                    for (int i = 0; i < m.size(); i++) {
                        GranuleThroughputByProduct t = m.get(i);
                         if (latest == null) {
                             latest = t.getLastIngestedTime();
                         } else if (latest.before(t.getLastIngestedTime())) {
                             latest = t.getLastIngestedTime();
                         }
                    }
                    return dummyVal;
                }  
            });
    When I do this I get the error:
    Code:
    Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number
        at com.sencha.gxt.widget.core.client.grid.GroupSummaryView.calculate(GroupSummaryView.java:90)
    Now the calculate method itself doesn't tip you off that it needs to return a Number but the render method obviously needs to take a Number to work correctly. This is where I assume the problem lies.

    Is there anyway to get this to work? It seems that Summary columns should be compatible with more date types than just Numbers since it is a fairly common query to ask for the latest date (for example in a SQL query or excel spreadsheet).

  2. #2
    Sencha User PhiLho's Avatar
    Join Date
    Nov 2011
    Location
    Near Paris, France
    Posts
    140
    Vote Rating
    1
    Answers
    2
    PhiLho is on a distinguished road

      0  

    Default


    I discover this (interesting) feature, so I don't know if my remarks can be helpful.
    I don't understand how your code is related to your description and how the error message is related to your code. (Probably my fault.)

    From what I see in SummaryType description, you can define the input type and the output type. Apparently, you need that both be dates. So perhaps your code could look like:
    Code:
    lastIngestedCol.setSummaryType(new SummaryType<GranuleThroughputByProduct, Date, Date>() {
      @Override
      public Date calculate(
          List<GranuleThroughputByProduct> m,
          ValueProvider<GranuleThroughputByProduct, Date> valueProvider) { 
        Date latest = null;
        for (GranuleThroughputByProduct t : m) {
          if (latest == null || latest.before(t.getLastIngestedTime())) {
            latest = t.getLastIngestedTime();
          }
        }
        return latest;
      }  
    });
    Obviously untested...

  3. #3
    Sencha User
    Join Date
    Oct 2011
    Posts
    20
    Vote Rating
    0
    nstokoe is on a distinguished road

      0  

    Default No Luck

    No Luck


    Unfortuately I have already tried your exact suggestion several times, each resulting with the following error:

    Code:
    Caused by: java.lang.ClassCastException: java.util.Date cannot be cast to java.lang.Number
        at com.sencha.gxt.widget.core.client.grid.GroupSummaryView.calculate(GroupSummaryView.java:90)
        at com.sencha.gxt.widget.core.client.grid.GroupSummaryView.renderGroupSummary(GroupSummaryView.java:156)
        at com.sencha.gxt.widget.core.client.grid.GroupingView.renderGroup(GroupingView.java:542)
    The problem is that the renderGroupSummary method that calls the overriden calculate method is expecting a Number. Unfortuately it appears there is no way to override the renderGroupSummary (and the renderSummary) method for just a single column.

  4. #4
    Sencha User
    Join Date
    Oct 2011
    Posts
    20
    Vote Rating
    0
    nstokoe is on a distinguished road

      0  

    Default Got it

    Got it


    So I figured it out. I wouldn't have got it if I didn't go back to the code today after seeing your reply so thanks!

    Basically I knew I had to work within the confines of the provided method signatures of calculate and render when setting new SummaryTypes and SummaryRenders. Essentially in calculate I find the latest date, but then return it as a long using the Date.getTime() method. Then in render I had to take that long and convert it back to a Date before formatting it as a String.

    Code:
    SummaryColumnConfig<GranuleThroughputByProduct, Date> lastIngestedCol = new SummaryColumnConfig<GranuleThroughputByProduct, Date>(
                    props.lastIngestedTime(), 100, "Last Ingested Time");
            lastIngestedCol.setCell(new AbstractCell<Date>() {
                @Override
                public void render(com.google.gwt.cell.client.Cell.Context context,
                        Date value, SafeHtmlBuilder sb) {
                    sb.appendHtmlConstant((DateTimeFormat.getFormat(CommonConstants.DATE_TIME_ISO8601).format(value)));
                }
            });
            lastIngestedCol.setSummaryType(new SummaryType<GranuleThroughputByProduct, Date, Long>() {
                @Override
                public Long calculate(
                        List<GranuleThroughputByProduct> m,
                        ValueProvider<GranuleThroughputByProduct, Date> valueProvider) {
                    Date latest = null;
                    for (GranuleThroughputByProduct t : m) {
                        if (latest == null || latest.before(t.getLastIngestedTime())) {
                            latest = t.getLastIngestedTime();
                        }
                    }
        
                    return latest.getTime();
                }
            });
            lastIngestedCol.setSummaryRenderer(new SummaryRenderer<GranuleThroughputByProduct>() {
    
                @Override
                public SafeHtml render(
                        Number value,
                        Map<ValueProvider<GranuleThroughputByProduct, ?>, Number> data) {
                    
                    Date  latest = new Date(value.longValue());
                    
                    return SafeHtmlUtils.fromTrustedString((DateTimeFormat.getFormat(CommonConstants.DATE_TIME_ISO8601).format(latest)));
                }
            });
    I can't believe I didn't try this sooner. In retrospect the answer is so obvious.

Thread Participants: 1

Tags for this Thread