Tuesday, July 19, 2011

High Performance "Christmas Tree" DataGrids


The DataGrid component displays its dataProvider IList of "items" as grid rows.  Each GridColumn can be mapped to an arbitrary aspect of an item: it may display one item property, or several item properties, or the value of some computation based on one or more item properties, etc.

The DataGrid detects changes in its dataProvider by listening for CollectionEvents.  The CollectionEvents notify listeners about list structural changes, like items being added or removed, and they can also report that an item's value has been changed.  This is called a collection "update" event. What collection update events can not report is which grid columns were affected by an item's change.  In other words, CollectionEvents don't provide a way to notify the DataGrid that the contents of an individual grid cell have changed.

Applications can notify the DataGrid of changes to individual cells by calling the DataGrid invalidateCell() method.

invalidateCell(rowIndex:int, columnIndex:int)

The DataGrid's layout handles cell invalidations efficiently by only redisplaying the item renderer at the specified location, and only if it's actually visible. Multiple calls to invalidateCell() are batched up and deferred until the next layout phase, just like calls to invalidateSize() or invalidateDisplayList().

This example demonstrates the use of the DataGrid invalidateCell() method. Pressing the "Run" button starts a timer that updates DataGrid cells at the rate specified with the slider.
Here's the source code for the example.

This "Christmas Tree" DataGrid example displays a dataProvider with items whose substructure is constantly changing.  Each dataProvider item has one object valued property per column, and each of those properties has an object value that defines what's displayed in a single cell.  To keep things simple the column properties are just called "C0", "C1", ... and the value of each property is an object itself, with "color" and "index" properties, like {color:NN, index:NN}. So the data for the cell at rowIndex=10, columnIndex=5:

dataGrid.dataProvider.getItemAt(10)["C5"] => {color:0xFF6C0D, index:4}

The DataGrid has no way of knowing when the color,index data for a cell has been updated so the developer must call invalidateCell(rowIndex, columnIndex) to let the DataGrid know that the specified cell must be redisplayed.  When the "Run" button is toggled on, updateTimerHandler() method  below is called up to 64 times/second and each time it updates a single random cell's color and index properties and then calls invalidateCell().  Calling invalidateCell() only causes the (one) corresponding item renderer to redisplay, so long as doing so doesn't invalidate the corresponding row's height.  That can occur if variableRowHeight=true and if it does, the entire DataGrid is redisplayed.

The CPU load produced by applications like this one is only proportional to the update rate and the renderers' complexity, so long as the overall grid layout isn't affected by the cell updates.  Using fixed height rows with variableRowHeight="false" (the default), simple item renderers, and not dynamically changing column widths, are good ways to ensure that the CPU load is minimized.

24 comments:

  1. Nice example! Your link to the source code is wrong though. It should be DataGridInvalidateCellExample.mxml instead of DataGridWrapExample.mxml

    ReplyDelete
  2. Thanks, I've corrected the link.

    ReplyDelete
  3. Hi Hans, that's a great example, but it completely bypasses the CollectionEvent notification mechanism you mention at the start. And since the Spark DataGrid's CollectionEvent handler is private (unlike the MX one, which was protected) you can't override it and turn it off.

    So how would you integrate the use of invalidateCell() (where the data source pushes changes to the control) with the event mechanism used for the MVC pattern, so that the model can change its data without having to know all the parts of the view that depend on it?

    Or is there another mechanism for getting around the DataGrid's ludicrous "oh no, the dataProvider has been updated, I must wipe and repaint the entire grid" behaviour? Or is that my fault for using custom item renderers? This is very frustrating...

    ReplyDelete
  4. This example does not bypass the "CollectionEvent notification mechanism", no events of any kind are automatically generated as a consequence of changing the value of a dynamic object property. And, as you can see, there's no penalty for using a custom item renderer.

    You may want to look at the follow-up blog I published yesterday: "The Truth About ArrayList, DataGrid, and Christmas Trees". It covers the ArrayList special case where PropertyChangeEvents dispatched by dataProvider items are automatically converted to "update" CollectionEvents. The blog demonstrates one approach for overcoming the performance problems that can stem from the DataGrid's intrinsic CollectionEvent handling and the fact that CollectionEvents can't always uniquely identify the grid column[s] affected by an item update.

    ReplyDelete
  5. Christmas is not a time nor a season, but a state of mind. To cherish peace and goodwill, to be plenteous in mercy, is to have the real spirit of Christmas.
    Christmas quotes

    ReplyDelete
  6. Hi Hans, I have the same requirement as John has mentioned, i.e I have to update only articular cell instead of the whole Spark datagrid or column or rows, when the dataprovider changes. This update should happen automatically without the user user clicking on Run buttoan as mentioned in the example. How can I do that? what methods to be overridden or events to be handled. Please throw some light on this. New DataGrid is a bit confusing to me.

    ReplyDelete
    Replies
    1. The key is using invalidateCell() to tell the DataGrid when (just) an individual cell needs to be redisplayed. This topic is covered in some detail here: http://hansmuller-flex.blogspot.com/2011/07/truth-about-arraylist-datagrid-and.html in the followup blog called "The Truth About ArrayList, DataGrid, and Christmas Trees".

      Delete
  7. This blog contains a lot of informative data and news which i first time read from here. Thanks for writing about this important topic.
    best facebook status

    ReplyDelete
  8. Way cool, some valid points! I appreciate you making this article available, the rest of the site is also high quality. Have a fun.
    funny facebook quotes , best facebook statuses

    ReplyDelete
  9. This internet page is certainly wonderful thus is the place where the problem had been grown. I want a number of the comments in the process despite the fact that I may want people maintain it again with niche if you want increase the value of the subject.
    quotes for facebook status , funny facebook statuses

    ReplyDelete
  10. This is absolutely a commendable post indeed. You share splendid piece of information here. Thank you for attributing this informative post.
    nicki minaj quotes , quotes for facebook

    ReplyDelete
  11. I have been reading all the replies here, i had a great deal of info, some significant most are not. But i shall say it very active page.
    Lil Wayne quotes , facebook statuses

    ReplyDelete
  12. Sometimes I sound like I’m arguing, when I’m actually not. I just have a way of putting my posts stronger than intended.It’s easier to keep out of the conversation and not take the chance of being misunderstood.
    cute quotes , valentines day quotes

    ReplyDelete
  13. Excellent insight into a fascinating topic, thanks for sharing this with us all. Please continue to contribute further information, I look forward to the prospect.
    funny facebookstatus

    ReplyDelete
  14. Thanks for taking the time to discuss this, I feel strongly about it and love learning more on this topic. If possible, as you gain expertise, would you mind updating your blog with more information?
    facebook status

    ReplyDelete
  15. I love to surf and my initial source for information is the blogs which have always helped me in my education. This blog is one of them.
    faith quotes

    ReplyDelete
  16. very funny hahaha

    ReplyDelete
  17. Your Htc desire sustainabletacomapierce.org mobile phone is the most sophisticated of the a few brand-new produces and also provides new FriendStream request which usually organises htc touch pro 3 release date every one of the consumers friends reputation improvements on social networking sites, sms as well as e-mail into one continuous line of data

    ReplyDelete
  18. This comment has been removed by the author.

    ReplyDelete
  19. Thanks for such an amazing placement, as it is what most of the people are seeking for. Hope that it will give benefit to the seekers. Keep placing more and more stuff in the future for our help.

    dogwoodhillslogcabin

    ReplyDelete
  20. This blog contains a lot of informative data and news which i first time read from here. Thanks for writing about this important topic.
    http://appempirebookreview.com
    http://officialiqtest.net
    http://averageiqscore.com

    ReplyDelete
  21. Hope that it will give benefit to the seekers. Keep placing more and more stuff in the future for our help. Alat Dapur | Peralatan Dapur | Jual Alat Dapur

    ReplyDelete