Flex : ItemRenderer For blue/red font number color in advanceddatagrid causing grid to slow .

In flex I have an advancedatagrid which has around 30 columns and 1000 rows data. The data gets updated every 10 seconds. Out of the 30 columns 29 columns are numbers. The numbers are shown in blue if positive and red if negative. I am using itemrenderer to do that. Below is the item renderer code


( got this code from internet and modified a bit )
package  {
      
      import mx.controls.Label;
      import mx.controls.dataGridClasses.*;
      
      public class RedBlueColorRenderer extends Label {
            override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
                  
                  super.updateDisplayList( unscaledWidth, unscaledHeight  ) ;
                  
                  if ( data && listData && isNaN(data[DataGridListData(listData).dataField]) ) {
                        
                  } else if ( data && listData && data[DataGridListData(listData).dataField] < 0 ) {
                        setStyle ( "color", "red" ) ;
                  } else if ( data && listData && data[DataGridListData(listData).dataField] >= 0 ) {
                      setStyle ( "color", "blue" ) ;  
                  }  
            }
      }
}

The way I use in advanceddatagird is shown below

<mx:AdvancedDataGrid id="dGridId" width="100%" height="100%"  horizontalScrollPolicy="auto" verticalScrollPolicy="auto" showScrollTips="true" headerWordWrap="true"   selectable="true" cachePolicy="off"  sortExpertMode="true" liveScrolling="false" headerHeight="50" wordWrap="true"  dataProvider="{dp}"   >
             
    <mx:columns>
        <mx:AdvancedDataGridColumn dataField="Name"  itemRenderer="ascripts.ColorRenderer"/>
        <mx:AdvancedDataGridColumn dataField="avg"  sortable="true" formatter="{zeroPrecisionFormatter}" itemRenderer="RedBlueColorRenderer" sortCompareFunction="sortCompareFunc"/>


and the columns list goes on exactly similar.

The problem is that when I try to scroll to right or up/down the datagrid becomes very slow. When I remove the itemrenderer it works reallly smooth. Is there a way I can achieve this without slowing the performance of the app. I tried using the styleFunction and it has the same problem.

Can you please show me the code on how to do this.

Thx.

DeveloperLearningAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sunsonmaheshCommented:
Hi

try to reduce the itemRenderers as much as possible....
suggestions:
1. if ( data && listData){if(){}else if(){}else{}}
2.set global color for whole column and change style only when positive or negative

--mahe
0
DeveloperLearningAuthor Commented:
Mahe, I want to reduce the usage of ItemRenderer but don't know how I can achive this. If you can post the code, it would be helpful. I don't know how I can do this without using ItemRenderer.
0
mr-caxCommented:
You shouldn't put your code in updateDisplayList (which is called whenever the display object is drawn, particularly when scrolling) but rather in data setter (overriding function set data). However it's probably even not necessary to write a custom renderer. You could probably do something like the attached code. I'm sorry but I was not able to test it because I haven't got access to flex builder right now. Apply one these two solutions and you'll really get faster results (I've already done this in the past and had no performance problem at all).


<mx:AdvancedDataGridColumn dataField="avg" sortable="true" formatter="{zeroPrecisionFormatter}" sortCompareFunction="sortCompareFunc">
    <mx:itemRenderer>
          <mx:Component>
                 <mx:Label color="{data[DataGridListData(listData).dataField] < 0 ? 'red' : 'blue'}" />
          </mx:Component>
     </mx:itemRenderer>
</mx:AdvancedDataGridColumn>

Open in new window

0
The Ultimate Tool Kit for Technolgy Solution Provi

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy for valuable how-to assets including sample agreements, checklists, flowcharts, and more!

mr-caxCommented:
In the last comment I gave it would be more readable to write 'data[DataGridListData(listData).dataField] < 0' as 'data.avg < 0'
<mx:AdvancedDataGridColumn dataField="avg" sortable="true" formatter="{zeroPrecisionFormatter}" sortCompareFunction="sortCompareFunc">
    <mx:itemRenderer>
          <mx:Component>
                 <mx:Label color="{data.avg < 0 ? 'red' : 'blue'}" />
          </mx:Component>
     </mx:itemRenderer>
</mx:AdvancedDataGridColumn>

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
DeveloperLearningAuthor Commented:
mr-cax. Thx a lot for the solution.
I was able to implement it using below format.
 <mx:Label color="{data.avg>0?255*256*256:255*256}"/>
When I use
 <mx:Label color="{data.avg < 0 ? 'red' : 'blue'}" />, I get error saying '<' not allowed .

One question . I have around 30 columns and it's going to be really very difficult to do this for 30 columns. Is there a way, this can be done only once and implemented  for all columns . .
 
0
mr-caxCommented:
I didn't know there was 30 columns. As I said you could use your original idea (special itemRenderer) but you'll need to define it as follow :
package
{
	import mx.controls.Label;
	import mx.controls.dataGridClasses.DataGridListData;

	public class RedBlueColorRenderer extends Label
	{
		public override function set data(value:Object) : void {
			super.data = value;
			
			if (value[DataGridListData(listData).dataField] < 0)
				setStyle("color", "red");
			else
				setStyle("color", "blue");					
		}		
	}
}

Open in new window

0
DeveloperLearningAuthor Commented:
Mr-cax , I tried using your solution as below

<mx:AdvancedDataGridColumn dataField="avg" itemRenderer="RedBlueColorRenderer" />

and I get error at line 11 of the code

 if (value[DataGridListData(listData).dataField] < 0)

as

TypeError: Error #1009: Cannot access a property or method of a null object reference.
      at ascripts::ColorRenderer/set data()[\src\RedBlueColorRenderer.as:12]
      at mx.controls::AdvancedDataGridBaseEx/http://www.adobe.com/2006/flex/mx/internal::setupRendererFromData()[C:\work\flex\dmv_automation\projects\datavisualisation\src\mx\controls\AdvancedDataGridBaseEx.as:2047]
      at mx.controls::AdvancedDataGridBaseEx/measureItems()[C:\work\flex\dmv_automation\projects\datavisualisation\src\mx\controls\AdvancedDataGridBaseEx.as:7058]
      at mx.controls::AdvancedDataGridBaseEx/commitProperties()[C:\work\flex\dmv_automation\projects\datavisualisation\src\mx\controls\AdvancedDataGridBaseEx.as:1993]
      at mx.controls::AdvancedDataGrid/commitProperties()[C:\work\flex\dmv_automation\projects\datavisualisation\src\mx\controls\AdvancedDataGrid.as:2276]
      at mx.core::UIComponent/validateProperties()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:5807]
      at mx.managers::LayoutManager/validateProperties()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:539]
      at mx.managers::LayoutManager/doPhasedInstantiation()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:659]
      at Function/http://adobe.com/AS3/2006/builtin::apply()
      at mx.core::UIComponent/callLaterDispatcher2()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:8628]
      at mx.core::UIComponent/callLaterDispatcher()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:8568]


0
mr-caxCommented:
Sorry for the late answer. The most probable reason is that dataField is not properly set for the column (because data setter should not be called when listData is null). Try changing the line to something like :  
if (DataGridListData(listData).dataField && value[DataGridListData(listData).dataField] < 0)

If it's not working try running your code in debug mode. When the crash occurs, just look for the values of all members of the expression to see which one is null and correct the test accordingly.
0
DeveloperLearningAuthor Commented:
It works by adding the  line
if (!value) return;
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Adobe Flash

From novice to tech pro — start learning today.