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.



Drag Drop Grouping - Header Text Function

clock September 23, 2015 16:13 by author Flexicious

Recently a request came in to be able to customize the text used in the grouping drag drop bar for grids that support drag drop grouping. A new property has been added to support this :

grid.dragDropGroupingBehavior.dragBarTextFunction

protected function hbox1_creationCompleteHandler(event:FlexEvent):void

                        {

                              //grid.dataProvider = FlexiciousMockGenerator.instance().getFlatOrgList();

                              grid.dragDropGroupingBehavior.dragBarTextFunction = myFunction;

                        }

                        private function myFunction(col:FlexDataGridColumn):String{

                              return col.headerText + '123';

 

                        }

 

Attached is a complete example

OnePager.mxml (6.68 kb)

 



Few FAQs

clock August 7, 2015 05:46 by author Flexicious

Below are a few questions that have come up in the past few days that are actually asked quite frequently. So wanted to post it up here for quick reference.

Question : We are setting the errorString to the FlexDataGrid by calling dataGrid.setErrorByObject method. This is disabling the entire row. We don't want the row to be disabled we just want cell to show the errorString.  Currently the behavior is datagrid row is getting disabled and errorString is appearing. Since the row is disabled we are not able to hover, select the row any more.We tried calling rowDisabledFunction and returning null but that is not working rows are still disabled.

Answer : So the rows are not actually disabled, just that the rollover colors are not applied. The way the grid works, is if there is a row in error state, the errorBackgroundColor style is always applied. This works fine, since it is unusual to have all rows in error as appears in your example

If you want the grid to have rollover error cells, you can always define a custom rowBackgroundColorFunction, as demonstrated in the attached example.

                  public function myrowBackgroundColorFunction(cell:IFlexDataGridCell):*{

                        if(grid.currentCell.rowInfo==cell.rowInfo){

                              return cell.getStyleValue("rollOverColor");

                        }else if(cell.level.isItemSelected(cell.rowInfo.data)){

                              return cell.getStyleValue("selectionColor");

                        }

                        return null;

 

                  }

 

Question : We have a requirement to perform cancel edit when enter is pressed on the last row.For some odd reason, when grid.destroyItemEditor() is called, the blue rectangle is still drawn, unlike when escape is pressed.This blue edit border is still there even after the user click the cell next to it. Is there a workaround to force the editor border not to be drawn when destroItemEditor() is called?

Answer : For this issue, please try calling grid.getCurrentEditor().drawFocus(false); focusManager.setFocus(grid); before calling destroyItemEditor.

 

Question : We need to perform certain action each time the user moves/tabs out from an editable cell of the datagrid. Is there any focus out handler for the same?
Answer : Please use itemEditCancel

 

Question : How to make certain columns picked up excel report and ignored the others? 
 Answer : You can set excludeFromExport=true for the colums you want to exclude from the export.

 

      Question : 

Hi,

I used
multiColumnSortNumberStyleName for the columnGroup and sortIcon for the column sortArrowSkin="mx.skins.spark.DataGridSortArrow"
Below is my style

.multiColumnSortNumberStyle
{
    fontFamily: AmplitudeEmbedded;
    color: #FFFFFF;
    rollOverColor: #FFFFFF;
    fontSize: 14px;
    gap: 3;
    paddingTop: 0;
    paddingBottom: 0;
    paddingLeft: 5;
    paddingRight: 0;
    dataCellEmbeddedFonts: true;
    backgroundColor: aqua;
}

Sort Numbers are getting visible with Grey color where i have given color as white. But when i rollover on to the column header sort numbers are disappearing. When i rollout sort numbers are visible.
I  tried to change the backgroundColor for multiSortColumn but still it is taking the column header color only.

Can you please send me an example where
columHeaderColors, multiColumnSortNumberStyleName and sortArrowSkin are used.

Answer : Please see below:


 

 

McsStyle.mxml (853.00 bytes)



Customization of the Right Click functionality - Ultimate Flex DataGrid

clock January 30, 2015 11:21 by author Flexicious

Recently got a few good questions about how to customize the right click functionality:

 

  • Is there a build in mechanism to disable and “grey out” certain menu items of the “CustomContextMenu” ?
  • Moreover: is it possible to add Icons before the menu item?
  • Is there a possibility to rename the build in menu items?
  • Moreover I’d like to provide my custom menu items at first, can I reorder this?

The answer to the first three questions is yes, and it is fairly straight forward to do so. The grid exposes a customContentMenuItems array, which is nothing but a data provider used to populate the customContextMenu (also exposed as a public property btw). So all that needs to be done is to provide a menu item that has a enabled=false flag. Same applies to the second question, all that needs to be done is to provide a icon property. Here is the code:

 

protected function flexdatagrid1_itemRightClickHandler(event:FlexDataGridEvent):void{
   grid.customContextMenuItems = [{type:'Separator'}
     ,{type:'Disabled Item',caption:'This is a disabled item',enabled:false}
     ,{type:'Item with icon',caption:'This is item with icon',icon:previous}
     ,"Custom Column Action: " + event.cell.column.headerText];}

 

 


For the built in items, there are 5 properties exposed as can be seen in the following code:

 

 

  1. copyCellMenuText
  2. copySelectedRowMenuText
  3. copyAllRowsMenuText
  4. copySelectedRowsMenuText
  5. copySelectedCellsMenuText

 

 

Finally, the fourth question unfortunately requires a little extension. You can create custom extension to FlexDataGrid and override onRightClick method.

Below is default implementation,

          

            /**
            * If enable custom right click is true, we handle it in this function.
            */        
            protected function onRightClick(event:MouseEvent):void            {
                   if(ToolTipManager.currentToolTip){
                        ToolTipManager.destroyToolTip(ToolTipManager.currentToolTip);
                        ToolTipManager.currentToolTip=null;
                   }
               //we are over a column header
                  var items:Array=[];
                  if(currentCell is IFlexDataGridCell ){
                        //contextMenu.customItems=cmis;
                        items.push({caption:this.copyCellMenuText});
                        items.push({caption:this.copySelectedRowMenuText});
                        items.push({caption:this.copyAllRowsMenuText});
                        items.push({caption:this.isRowSelectionMode?copySelectedRowsMenuText:copySelectedCellsMenuText});
                  }
                  if(currentCell)
                  {
                        var evt:FlexDataGridEvent = new FlexDataGridEvent(FlexDataGridEvent.ITEM_RIGHT_CLICK, this, currentCell.level, currentCell.column, currentCell, currentCell.rowInfo.data,event);
                        dispatchEvent(evt);
                  }

                  for each(var rightClickItem:Object in customContextMenuItems)
                  {
                        if(rightClickItem is String)
                        {
                              items.push({caption:rightClickItem});     
                        }
                        else
                        {
                              items.push(rightClickItem);
                        }                                        

                  }
                  if(items.length>0){
                        //UIUtils.addPopUp(menu,FlexGlobals.topLevelApplication as DisplayObject,false);
                        customContextMenu.labelField = "caption";
                        customContextMenu.dataProvider=items;                    

                        if(customContextMenu.visible){
                              customContextMenu.hide();
                        }
                        customContextMenu.show(event.stageX,event.stageY);
                        cellUnderRightClick=currentCell;
                  }
            }     

Finally, below is the screenshot and the code:


 

 

RightClick.mxml (3.22 kb)



Show a filter image in Datagrid header when a filter is applied

clock January 29, 2015 05:17 by author Flexicious

Just got an interesting question from a customer :

"It is a way to show a filter image() in my Datagrid header when a filter is applied"?

This is actually possible if you use a custom header renderer. Basically, the idea is that when the grid renders, it calls the set data method on each renderer, including header renderers. Armed with this knowledge, it is easy to accomplis this. 

Lets take a look at the markup required to do this

<?xml version="1.0" encoding="utf-8"?>

<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300" xmlns:grids="com.flexicious.grids.*" xmlns:columns="com.flexicious.grids.columns.*">

      

       <grids:ExtendedAdvancedDataGrid dataProvider="{Font.enumerateFonts(true)}" enableFilters="true"
filterPageSortChange="grid.invalidateList()"

id="grid">
              <grids:columns>
                     <columns:ExtendedAdvancedDataGridColumn dataField="fontName" filterControl="TextInput">
                           <columns:headerRenderer>
                                  <fx:Component>
                                         <mx:HBox verticalScrollPolicy="off" horizontalScrollPolicy="off">
                                                <fx:Script>
                                                       <![CDATA[                                                            

                                                              import mx.controls.advancedDataGridClasses.AdvancedDataGridListData;                                                             

                                                              [Bindable]
                                                              [Embed(source="/../assets/images/16x16/filterShowHide.png")]
                                                              private var previous:Class;

                                                             

                                                              [Bindable]
                                                              [Embed(source="/../assets/images/16x16/filterShowHideInverted.png")]
                                                              private var next:Class;

                                                              public override function set data(val:Object):void{
                                                                     super.data=val;
                                                                     img.source=outerDocument.grid.getFilterValue('fontName')?previous:next;
                                                             }
                                                       ]]>
                                                </fx:Script>
                                                <mx:Label text="Font Name"/>
                                                <mx:Image id="img" />
                                         </mx:HBox>
                                  </fx:Component>
                           </columns:headerRenderer>
                     </columns:ExtendedAdvancedDataGridColumn>
                     <columns:ExtendedAdvancedDataGridColumn dataField="fontType" filterControl="TextInput"/>             
              </grids:columns>
       </grids:ExtendedAdvancedDataGrid>
</s:Group>

HeaderWithFilterImage.mxml (1.71 kb)



Drag Drop Grouping For Ultimate Flex DataGrid

clock January 26, 2015 22:56 by author Flexicious

In the upcoming release, we have added support for Drag Drop Grouping. This is an exciting new feature that a number of you have asked for, and it is finally being added. As a part of this release, there is a new component, a DragGroupingBar, which will work hand in hand with the grid to make it simple for you to enable Drag and Drop grouping. All you have to do is to drop the grouping bar on the screen and wire it up to the grid like below:

 

      <grouping:GroupingDragBar id="groupByTestButton">

      </grouping:GroupingDragBar>

      <nestedtreedatagrid:FlexDataGrid groupingDragBar="{groupByTestButton}" styleName="myGridStyle" id="grid" width="100%" height="100%" enablePrint="true" enablePreferencePersistence="true"

 

                                                       enableExport="true" enableCopy="true" preferencePersistenceKey="simpleGrid"

And the grid will take care of the rest!

Below is a screenshot:


 

And here is a video of the grouping in action:

https://www.youtube.com/watch?v=2TL_EFfxcGs



Custom Chart Painters and Customization

clock January 17, 2015 21:40 by author Flexicious

We recently had an interesting query from a company evaluating our software. 

"We would need to show 6 values on a candle, while here only 4 values are available(Open, Close, High, Low). (the 6 values we use are: minimum, average, maximum, maximum for 95% of the data, maximum for 75% of the data and maximum for 50% of the data).   We are interested in getting all the 6 values into the same dashboard block. These are statistic values related to an attribute.  For example for a Line chart we would need only one vertical line with 6 values. "

Since our drawing mechanism is extensible for all our charts, this is possible, if you know the right extension points. For this example, we chose the HLOCChart, since it draws 4 values, we just need to repurpose it to draw 6. Although the HLOCCharrt has a specific purpose (Drawing stock charts), its quite easy to extend the drawing mechanism for it. In this case the user just wants 6 dots in a line. Turns out, not that hard to do:

  1. Extend the HLOCChart initialize the ExtendedHLOCPainter.
  2. Extend the HLOCPainter, implement the painting code on basis of the built in painting code.
  3. Extend the HLOCSeries, add the 2 fields.

The whole thing took about 15 minutes to do!

The code is attached at the bottom of this post, and here is the result:

 

ExtendedHLOCChart.as (1.62 kb)

ExtendedHLOCChartPainter.as (4.31 kb)

ExtendedHLOCSeries.as (1.73 kb)

HLOCCharts.mxml (3.21 kb)



Some recent FAQs

clock January 8, 2015 04:45 by author Flexicious

Recently, quite a few of you have asked some common questions which we wanted to summarize here:

 

Q : I would like to allow multiple row selection only by clicking any cell and using the control key (enableStickyControlKeySelection="true") OR by using the "FlexDataGridCheckBoxColumn" without using the control key.

A : We have added this behavior to the upcoming 3.3 release. Please request a build.


Q: For Spark DataGrid, if I define a custom skin, the filters are not visible.

A: The Flexicious Spark DataGrid (ExtendedSparkDataGrid) has its own skin. Moreover, the skin is also different if you use Apache Flex 4.10 + vs Flex 4.5 - 4.9. All of these skins are attached below.

For SDK 4.10 + : ExtendedSparkDataGridSkin.mxml (16.96 kb)

 

Q : I have a data provider as an ArrayCollection (not hierarchical collection) and also multi level footers.I am trying to control the outcome of the footer values in footerLabelFunction2. I cannot use columnLevel of cell to determine levels because at the time of export it would fail since there is no cell at that point.

A : You are correct, during export, there is no cell so footerLabelFunction2 (and labelFunction2) both will not work, since the cell parameter will be null. In that case, you can refer to grid.recordBeingExported (this was added in a recent release).

 

Q: In the MultiSelectCombBox, if I selected one item and press Ok button, I cannot disselect this item. 

A: We have added additional flag–

      <controls:MultiSelectComboBox allowNoneSelection="true" id="mcboGrade" label="Grade" dataProvider="{gradeList}" dataField="GradeCode" labelField="GradeName" height="26" minWidth="100"

                                                 />

Q:  I know how to remove header text via  hideHeaderText  but  that is not the effect I want. How can I disable headers completely for Child rows

A: Set headerHeight=0

 

 Q: For the DateComboBoxFilter, your grid component gives (All,This Quarter,Last Quarter etc.) I want to add more filters (Current date, Last Week, Last Month , Last 15 Days etc.) 

A: In a recent release, we have added support for registering custom date ranges. Please request a build, the sample code now includes an example that adds custom date ranges.

 

Q : I've just found that the build in "Copy Selected Rows" feature doesn't work with a Tree grid with “Dynamic levels”. 

A :This was fixed in the upcoming 3.3 release, please request a build.

 

Q : We use Flexicious MultiSelectComboBox Filter , but some fields content is not working.

For example, If the field's content is "", then this value can be filterred after choosing filter= [None]. 
However, if the field's content is null, then this value can't be filterred after choosing filter=[None]. 

 A : Use the useLabelFunctionForFilterCompare   flag : <flxs:FlexDataGridColumn dataField="zipCode" filterControl="MultiSelectComboBox" filterComboBoxBuildFromGrid="true" useLabelFunctionForFilterCompare="true"/>

 

Q : We need to show some keywords in different colors within one grid's cell.  How can we do that?

For example, one cell's content is "Today is Sunday !".  The keyword: "Sunday" should be in red color, the rest words should be in black color. 

 A : Create an ItemRenderer, that extends from label, override the text setter and set htmlText instead. Make sure the data has HTML. Example code for both above questions is below

HTMLLabel.as (235.00 bytes)