Upcoming 3.3 release - Responsive DataGrids

clock December 24, 2015 00:28 by author Flexicious

Readers of our blog know that the past few weeks have seen tremendous development activity on the product. The upcoming 3.3 release adds a highly requested feature : Support for Responsive DataGrid (Responsive Datatables)

Displaying data across various different screen sizes and resolutions has been a challenge few have been able to solve effectively. There are many solutions online, but we have gone a step further by taking Flexicious Ultimate, which is arguably among the most powerful DataGrid component for Flex applications, and added support for responsive rendering. We wanted to give you flexibility over how you want the grid to behave, so we have implemented 3 (THREE!!) different responsive modes:

1.   API to show or hide the scroll bar on basis of the screen width. Below a certain pre-configured screen width, a scroll appears, and allows the user to scroll through all the columns. Above this screen width, there is no scrollbar.

2.     An API for a priority model, where each column can be assigned a priority and the columns appear or be hidden on basis of screen width.

3.     A new column type, TransposedColumn added to accommodate smaller screens, below a certain pre-configured width, all the columns in the grid are replaced by the Transposed Column which contains, within a single cell, all the information that was held in the
previous cells in a transposed manner.

That said, lets talk about each of these modes and what they mean:

1)                      The Scrollbar mode - ResponsiveBehavior.SCROLL_BAR_  : This mode basically says, below a certain threshold (scrollBarWidthTreshhold – default 1000px), the grid will display no scrollbar. But above this width, a scrollbar is shown. This is distinct from the horizontalScrollPolicy=auto. As some of you may know, column widths are a highly nuanced topic. The widths work very differently when horizontal scrollbar exists vs not [You set this via the horizontalScrollPolicy on the grid]. There is also the additional complexity of the columnWidthMode attribute on each column that makes this further nuanced. The one thing to keep in mind is that the responsive mode does not really ‘change’ the behaviors associated with horizontal scroll policy. It merely flips the horizontal scroll policy to on or off on basis of the width of the grid in comparison to the scrollBarWidthThreshold. The behavior of individual columns in this mode still respects the original behavior. There is a lot more information about how each column is sized in each horizontal scroll policy mode, which is clarified here : http://www.flexicious.com/resources/docs29/com/flexicious/nestedtreedatagrid/FlexDataGridColumn.html#columnWidthMode

2)                      The Priority mode - ResponsiveBehavior.COLUMN_PRIORITY_MODE : This mode will show or hide columns on basis of the priority associated with them, and the threshold set on the behavior. There are 5 priority modes. Below are the settings for each priority modes – Please note, these are default values and can be configured to whatever values you like.

/**

*  The width below which columns with priority 1 are not visible.

* @type {number}

*/

this.columnPriority1WidthTreshold = 1120;

/**

*  The width below which columns with priority 2 are not visible.

* @type {number}

*/

this.columnPriority2WidthTreshold = 960;

/**

*  The width below which columns with priority 3 are not visible.

* @type {number}

*/

this.columnPriority3WidthTreshold = 800;

/**

*  The width below which columns with priority 4 are not visible.

* @type {number}

*/

this.columnPriority4WidthTreshold = 640;

/**

*  The width below which columns with priority 5 are not visible.

* @type {number}

*/

this.columnPriority5WidthTreshold = 480;

3)                      The Transposition mode - ResponsiveBehavior.TRANSPOSED_COLUMN_MODE : Similar to the scrollbar mode, this mode will show or hide a transposed column on basis of the current width of the grid in comparison to the value defined for the transposedColumnTreshold (default 450). Below this threshold value, all the columns disappear, and a single column appears which is a transposed version of all the columns in the grid. The advantage of this mode is that all the information rendered in all columns is visible. This mode currently only works with flat data (not hierarchical data). The biggest disadvantage obviously is that you loose the sorting capability across all columns, but you can enable the muticolumn sort and that allows you to modify the sort using the sort popup.

As with any newly added feature, we are hoping to make this seamlessly integrate across all other features (for example, the print/export currently does not work with Transposed columns). We are actually looking for feedback on how this will work in general, so please feel free to share your thoughts

 

Wondering what this looks like?.

1) Here is the default grid (notice the large number of columns)


 

2) Here is the same grid, smaller width, with scrollbar responsive mode (notice the scrollbar at the bottom, which was not there prior to the grid being resized)

3) Here is the same grid, with the priority responsive mode (notice not all columns are visible) the ones with lower priority are hidden.

4) Finally, Here is the same grid, with the transposition responsive mode.


As may have been obvious from the slew of posts about our upcoming features, we have been hard at work trying to make the product even better, if you have not renewed your subscription, show us your support and now would be the time to do it!

 

Finally, below is the sample code used to implement this. (You will need the latest 3.3 release - we have a pre-release available if you want to take it for a spin)

Responsive.zip (274.47 kb)



Upcoming 3.3 release - Pure Native PDF!

clock December 21, 2015 19:54 by author Flexicious

One of the most exciting features to be added to 3.3 and one that we think a lot of you are going to be able to use immediately is the support for native PDF. As most of you are aware the current PDF mechanism basically grabs screen shots of the grid and adds to the page. This works great and most scenarios but the biggest drawback of this mechanism is the quality of the PDF. This is because a screenshot is at the end of the day a bitmap image. It is not a vector and it doesn't scale.

In this release we're basically changing how the AlivePDFPrinter works. Conceptually if you think about our print mechanism what we do is we basically just render the grid to either the printer or the PDF. The grid already takes care of the complex mechanism of figuring out the page size, identifying which rows belong to which page how much data can be fit within a single page and all of that good stuff. So far all we did is let the grid take care of the rendering mechanism and then capture the screen shot of the grid. In this release what we're doing is extending the printer to instead of capturing the screenshot of the grid we basically take the rendering information from the grid and then use that to render native PDF objects.

From design standpoint our PDF pages basically include a report header, page header, the grid area, the page footer and the report footer.  The report header and a report footer are on the first page and the last page respectively. The page header and page footers exists on all pages.  Report headers footers and page headers footers are always a fixed size. You define the sizes when you define these renderers.  Once the sizes for these fixed areas is allocated the grid then takes up the remaining size and on basis of the size of the grid on each page we have to identify which cells in which rows exist on each page. We do all of these calculations up front and then use that information to build the preview. What we can do now with this release is use the same information to render out natural PDF using the API provided by the PDF library which is our case, Alive PDF.

Now that you understand technically what the change means let's talk about what it means to you from a code change perspective. the most obvious change to  enable this behavior is to basically said a flag on the PDF options object.

/**

        * Flag added in 3.3 to enable passing an image to the pdf printer as opposed to the

        * actual display object. Defaults to true, because currently we just add a snapshot of the

        * current view to the PDF page. If this flag is set to false, we will pass the actual display object

    * (and not the image snapshot) to the pdf printer. The pdf printer then has to be smart enough to

        * parse through the Display Object, and call the appropriate APIs on the pdf library to convert

        * the Display Object to PDF version of it.

        * */   

        public var pdfUseScreenShot:Boolean=true;



And then set this flag to false:

protected function vbox1_creationCompleteHandler(event:FlexEvent):void

              {

                    grid.pdfOptions.pdfUseScreenShot = false;

                   

              }

When you set this flag to false what it tells the grid  is that instead of capturing the screenshot of the grid what we want is to capture the information from the page itself.  All of this work is done in the printer.


The next thing you have to do is to use the updated version of the printer you can download this here:

 

The final caveat to keep in mind is that there are two modes for the printer - there's a wrap mode and the no wrap mode.  On the screen if the text with the the cell is larger than the area of the cell in other words if there's not enough space to render the entire content of the cell we usually just cut off the part of the cell text that cannot fit within the area. We can replicate that same behavior in the printer or we can try to fit as much as possible by wrapping the text.  The advantage of not wrapping is that the PDF looks cleaner but the disadvantage is that the information is cut off.  On the other hand if you set the wrap mode to true we'll be able to fit more information but it looks a little cramped. Below are sample outputs - Before, After with wrap, and After No Wrap.

You can flip the wrap setting using the following line of code in AlivePDFPrinter:

           private var pdfWrapText:Boolean=false;

 

To Summarize:

  1. This release includes pure native pdf exports as opposed to the older screenshot based pdf

  2. Now PDF’s can be scaled, they are no longer bitmap images

  3. You can select and copy text from generated PDF files

  4. PDFPrinter supports wrap and no wrap modes (example outputs follow)

  5. To use, set the flag on pdfOptions, and use the new AlivePDF Printer

  6. If you have customized report/page header/footer, modify the AlivePDFPrinter to account for that.

  7. Help us improve this feature by providing feedback!


 

 

 

Enjoy!

Before / After documents : 

Older Screenshot based PDF.pdf (108.29 kb) (Flexicious 3.2 or earlier)

Pure Native PDF With Wrap.pdf (498.74 kb) (Flexicious 3.3)

Pure Native PDF No Wrap.pdf (491.82 kb) (Flexicious 3.3)

Alive PDF Printer Class : AlivePdfPrinter.as (18.18 kb)

Sample Project: OnePager.zip (172.25 kb)



Upcoming 3.3 release - Drag & Drop Grouping within Nested Tables

clock December 15, 2015 08:31 by author Flexicious

For those of you reading our blog regularly, you are probably aware this release is heavy on performance and memory optimization. 

But that does not mean we did not enhance/add features. This blog post covers an interesting use case that we added support for.

You may have read our announcement from ealier this year that we added drag and drop grouping support : http://blog.flexicious.com/post/Drag-Drop-Grouping-For-Ultimate-Flex-DataGrid.aspx 

One of our customers wanted to extend this drag and drop grouping support to inner level tables. Now we realize this is a edge case, but since we already had all the code for grouping at the top level ready, we could easily extend that to accomplish the scenario this specfic customer was looking for.

Basically, what they asked for was this:

3)      We need to ask you to add the following features to the Flexicious Ultimate DataGrid :

a.      Dynamic Group in combination with nested tables. We need to be able to Dynamic Group any column of any table (no matter its nested level). Of course that the grouping  will take place in the nested tabled related to the field being grouped.

So we did this. Below is the screenshot of this feature:

 

 

Below is the sample code used. Please note, to run this, you need to have the latest version (upcoming 3.3) of the Flexicious library. If you have a valid subscription, please request a build or if you wish to evalualte, please download a trial.

 

Sample.zip (134.27 kb)



Upcoming 3.3 release - Memory Improvements

clock December 15, 2015 06:43 by author Flexicious

The latest release has added quite a few things on the performance front. Especially performance while scrolling. More information here : http://blog.flexicious.com/post/Upcoming-33-release-Performance-Improvements.aspx 

An additional improvement that was made was in regards to memory management. This is something that goes deep into the internals of the grid, so most of you have not had to care about this, but the data area of the grid uses a very lightweight FlexSprite that contains a primitive TextField instance to draw out the data cells. This makes the grid perform well. However, you may ask, why have both FlexSprite AND TextField. The basic problem is this – each cell in the grid is responsible for drawing its own borders as well as backgrounds. , we need the FlexSprite to draw the border and background, and TextField to display text. This is because FlexSprite cannot display text by itself, and TextField cannot draw borders and backgrounds (it does not have a graphics object). So we have a text field wrapped inside a FlexSprite. This allows us to provide features like nested tables, column and row spans, inner level footers/filters/toolbars and a lot more.

However, for plain vanilla grids, this may be a little bit of a overkill. So in those situations, you might be better served using this new flag we recently added – enableFTEDataRenderer – This accomplishes two things – First, it uses the native UIFTETextField introduced in Flex 4. So if you are using custom fonts, you don’t have to include both embedAsCff true and false versions. Second, the UIFTETextField is capable of BOTH rendering text AND drawing graphics. Although ultimately it still wraps a text primitive within it, you may observe lower memory usage with UIFTETextField. We have found this to be a hit or a miss, because UIFTETextField does add some of its own complexity, but in some situations where you see the grid taking up more memory than ideal, try setting enableFTEDataRenderer="true"

Note that the default for this is false, it has to be explicitly enabled.

 

 



Upcoming 3.3 release - Performance Improvements

clock December 14, 2015 23:10 by author Flexicious

In every release of the our product, the one thing that we consistently focus on is how to improve performance. This release is no different. We carefully profile our code to eliminate redundancies, and optimize our routines to make our code more performant. Over the years, this has made our product extremely well performant in most cases, but in we continue to make it better.

In this release, we have targeted one area in particular – scrolling. Now this does not make a lot of difference if your grid does not occupy a large percentage of your screen. However, if you have grids that span across your entire screen, the time it takes to paint that many cells as you scroll is sometimes more than ideal. So, we have introduced a new property, enableStyleCache – this will cache a number of style calculations required to render each cell. This will not work if you have grids that use col spans or row spans, or some other edge cases, so switch it back to false if you see rendering issues. But for the most common scenarios, setting this property to true should get you atleast a 50% improvement in scrolling performance, as well as a slight improvement in initial rendering performance.

This can be demonstrated by some hard numbers like shown in the screenshot below.

 

 

As you can see, the amount of work being done as you scroll has been significantly reduced because of the caching introduced.


That said, many times performance issues arise due to very specific configuration settings that we may not have encountered in our settings. So if you run into any of this, please don’t hesitate to get back to us if you notice any other areas that could use performance improvements – please send us a sample that we can run and profile to understand the issues better a'nd help you achieve better performance out of the product.

Note that this behavior can be disabled by setting enableStyleCache="false" (The default is true). If you observe any rendering issues, please send us a test case, and you can disable this new performance enhancement by setting the enableStyleCache back to false.