Showing posts with label Flex. Show all posts
Showing posts with label Flex. Show all posts

Wednesday, January 20, 2010

New GroupingCollection2 class with improved perforamnce

Rather than repeat the same thing : Sameer talks about the new GroupingCollection to in data visualization swc of Flex.

Give it a try !

Thursday, December 24, 2009

4 items to check if a Flex 4 Application is leaking memory !

I have been working with Flash Builder profiler for past few months. After looking at few applications and memory leaks in them I came up with following 4 items which can cause a Flex application to leak memory.

If you don't like to read lot of text the gist is to use weak references where ever possible.

1. addEventListener is being called with the default value of false for its useWeakReference flag.

2. bindProperty and bindSetter methods of BindingUtils are called with default value of false for its useWeakReference flag.

Please note: I don't know what is the equivalent thing in Flex 3.

3. ChangeWatcher.watch method is being called with default value of false for its useWeakReference flag.

Please note: I don't know what is the equivalent thing in Flex 3.

4. Dictionaries are being used with weakKeys flag in the constructor set to false.

Items 3 and 4 can cause some hidden links to be formed and memory to leak. More on that soon.

Thursday, August 13, 2009

Friday, June 19, 2009

Tweaking OLAPCell and OLAPDataGrid to display custom formatted values

Displaying custom formatted data in OLAPDataGrid is a bit tricky because OLAPDataGrid doesn't use the OLAPCell.formattedValue at all due to a bug in its implementation.

However the tweaks I am going to mention are simple and can be used to get this to work. After the tweaks don't forget to build the datavisualization.swc using the steps I have described in one of the earlier posts.

Modifing OLAPCell.as file : Modify the constructor to set a formatted value into the _formattedValue property

public function OLAPCell(value:Number, formattedValue:String=null)

{

_value = value;

_formattedValue = insert any custom formatting logic using value ;

}

Modify OLAPDataGrid.as : Somewhere around line 769 we can find the following line

label = cell && !isNaN(cell.value) ? String(cell.value) : defaultCellString;

Modify this to read as follows

label = cell && !isNaN(cell.value) ? String(cell.formattedValue) : defaultCellString;

Build the swc and use it in your app to get custom formatting. Of-course some more tweaking it required to make this generic and supply a Flex formatter directly to OLAPDataGrid. I am sure it can be easily figured out !

Monday, June 8, 2009

CallResponders explained..

Here is some explanation about CallResponders by Tom Lane. I thought this would be useful to many developers who want to understand more about them so that it becomes easy to work with them.

"Let me take a shot at explaining asynchronous calls. Most PHP developers are used to calling functions in one way only: synchronously. In ActionScript a sychronous function call looks like this:

var stuff = getStuff();

Pretty straightforward. It's how you expect functions to work: you call them, and then immediately on line #2 of this example you have a value in the stuff variable to work with.

But when it comes to calling remote functions on services sitting on a server somewhere, Flex calls them asynchronously. This is so that the Flex client can continue working while the request is pending. An aync call looks more like this (at least, the first part):

responder.token = getStuffFromService();

What this means is, "stuff" does not come back right away as the result of the function. Instead, what it returns is a kind of ticket. Sort of like ordering some food from a lunch counter and getting a receipt with a number on it. You don't get your food right away. Instead, you go hang out or do some other stuff while your order is pending, and then your number is called when it's ready. And then you "respond" to your number.

Well, that's what a CallResponder is. When you "place your order", you hook up a CallResponder to it. When your order is ready (data comes back from the service call), the responder kicks into action. It fires a result event (or a fault if something went wrong), and it updates its bindable lastResult property.

So, if you want to work with data from an async call, you can't simply do it on line #2 of the above snippet. You have to wait until the CallResponder for that call gets its result. If you create a databinding to lastResult, that will automatically update when the result is ready. But since you want to run some script on the result, you have to trigger that script from the CallResponder's result event handler.

Hope this helps!

Saturday, June 6, 2009

Showing different icons in each cell of OLAPDataGrid based on the cell value

I have been getting few queries on how to show different icons based on the cell value in a OLAPDataGrid.

Here is a screen shot of how it looks:

Here are the source files.

The technique is simple. Create a custom itemRenderer which can display a icon and text or anything to suite your needs. Make sure it implements the IDropInListItemRenderer interface. In the setter of listData add the logic to change the icon based on the value. Set this as itemRenderer of the OLAPDataGrid.

The sample shows this using a renderer derived from Canvas with a image control and embedded image files. You can use other light weight techniques like coloring a sprite and using UIComponent as base. If you are adventurous you can try tweaking or deriving from OLAPDataGridItemRenderer itself.

Blogs on Data Centric Development workflows in FlashBuilder 4 for PHP, HTTPService, ColdFusion and WebService

Here are some great blogs on how to use DCD feature in FlashBuilder 4:

Howto: Connect a flex application to database (for PHP developers)

Howto: Use createItem method of the generated sample PHP file

Howto: Use the update and delete methods of the generated sample code

Howto: Enable Automatic Paging in Flex Applications for Any Kind of Service

A list of many articles on Sujit's blog

BlazeDS support

Using web-services with DCD workflow

Thursday, March 5, 2009

Flex OLAP aggregating strings.

I recently got many queries about support for String aggregation in Flex OLAP. The current implementation available out of the box doesn't support this.

Here are the changes to source files required to support this. The files need to be unzipped into the fbpro directory and the datavisulization.swc needs to be build using the steps mentioned here.

The result would look something like this.

The sample project has a StringAggreator implementation which can be used as a starting point to build your own logic into the StringAggregator. The sample one appends the strings to each other.

Here is the sample project.

Of-course I might have missed something while testing. So let me know if you find any bugs !

Monday, January 19, 2009

How to build datavisualization.swc from the source ?

Here are steps to build datavisualization.swc from the source that gets unzipped into a fbpro directory in FlexBuilder when a valid license is provided.

Setup

1. Download ant1.7.0.

2. Download a version of jdk 1.6.

3. Download cygwin, an open source unix shell for Windows.

4. Set environment variables. Go to Control Panels > System > Advanced > Environment Variables

• Set JAVA_HOME to the path to the jdk directory. Add path of ant1.7 to PATH. For example, C:\ant1.7.0\bin (you will already have a PATH, multiple entries are separated by semicolons)

• Add path of cygwin to PATH. For example, C:\cygwin\bin

Steps:

1. Add files build.properties and build.xml(attached) to location of datavisualization directory. For example, C:\Program Files\Adobe\Flex Builder 3\sdks\3.2.0\fbpro\projects.

2. Add the flex builder license to build.xml file (location: C:\Program Files\Adobe\Flex Builder 3\sdks\3.2.0\fbpro\projects\build.xml) . Replace by license key.

3. Unzip inside_ datavisualization.zip. The build.xml and build.properties files should be copied inside datavisualization folder.For example, C:\Program Files\Adobe\Flex Builder 3\sdks\3.2.0\fbpro\projects\datavisualization.

4. Make changes regarding location of sdk and output swcs to files build.properties and datavisualization\build.properties.

5. At the cygwin prompt, go to the datavisualization. For example C:\Program Files\Adobe\Flex Builder 3\sdks\3.2.0\fbpro\projects\ datavisualization.

6. Run ant main to build datavisualisation.swc and datavisualization_rb.swc for en_US .

7. Run ant main_with_ja_JP to build datavisualisation.swc and datavisualization_rb.swc for en_US and ja_JP.

Note: Place the datavisualization.swc at sdk\frameworks\libs and datavisualization_rb.swc at sdk\frameworks\locale.

Thursday, May 15, 2008

Fixing itemRenderer memory leak in AdvancedDataGrid on columns change

Please read the discussion about memory leak here.

I think I found the workaround for this issue. We need to override the set columns method in a extended ADG class and add the code to free the dictionary holding on to the itemRenderers. Here is the code.

<?xml version="1.0" encoding="utf-8"?>
<mx:AdvancedDataGrid xmlns:mx="http://www.adobe.com/2006/mxml">
 <mx:Script>
  <![CDATA[
   override public function set columns(value:Array):void
   {
    super.columns = value;
    itemRendererToFactoryMap = new Dictionary(false);
   }
  ]]>
 </mx:Script>
</mx:AdvancedDataGrid>

Wednesday, April 9, 2008

Using Flex OLAP/OLAPDataGrid for doing Pivoting computations

Satish has developed a new PivotComponent using OLAPDataGrid and OLAP which can be used to perform pivot analysis of data.

The sample can be found here. Drag and drop one or more dimensions into the column and row fields. The results would get displayed as soon as the drop happens. Drag and drop more dimensions into column, row or slicer fields. Use the drop down attached to dimension button to pick specific members of the dimension to do slicing. The sample uses OLAPChart and OLAPDataGrid extensions to display the OLAPResult generated.

Description and source

Monday, April 7, 2008

Custom Aggregator sample for Flex OLAP

Here is a sample which shows a percent custom aggregator used for OLAP. The sample shows computation of percentage of values to the total value. The total value is assumed to be known before hand.

The PercentAgg class implements the IOLAPCustomAggregator interface. The constructor takes the total value as input and uses it to compute the percentage of values in the computeEnd and computeObjectEnd functions.

The sample also shows how OLAPAttribute class can be extended to OLAPTotal to replace the "(All)" value with a custom name "Total".

The sample also shows how OlapDataGrid can be created in AS and itemRendererProviders can be supplied to it and values displayed in ODG can be styled. Here is the complete source.

Writing a Custom Aggregator for Flex OLAP

Writing a custom aggregator for OLAP involves implementing the IOLAPCustomAggregator interface. It is easy to write a custom one based on the default ones. The default SUM, AVARAGE, MIN, MAX and COUNT aggregators source can be found in the mx.olap.aggregators directory.

The SUM, MIN, MAX and COUNT aggregators are all simple and acutally doesn't require any special handling as they are linear. The AVARAGE aggregator is special because avarage of avarages wouldn't give the correct result and hence we need to maintain proper information to arrive at the correct result.

The following sample shows how this is achieved.

IOLAPCustomAggregator has 6 functions can they can be divided into two sets.

1. computeBegin,computeLoop and computeEnd. These functions are called to initialize, compute and return the simple aggregation value.

Suppose 1..8 are the input values and they need to avaraged as two different sets 1..5 and 6..8. The sequence of function calls is one computeBegin, one or many calls to computeLoop and one call to computeEnd. 1. computeBegin can be used to prepare for a fresh computation. 2. computeLoop is the place where the acutal computation takes place. This function would get called repeatedly to add new input values to the aggregation. 3. computeEnd is supposed to return the value of the computation. This is called when cube decides that no new input values would get added to this aggregation and it is ready to receive the final value.

2. computeObjectBegin, computeObjectLoop, computeObjectEnd. These functions are called to initialize, compute and return the aggregation of aggregations.

The second set of calls would be, one call to computeObjectBegin, one or many calls to computeObjectLoop (depending on the number of aggregated values) and one call to computeObjectEnd.

As shown in the image these functions are supposed to compute the avarage of avarages. As the first set of functions saved the sum and count values separately the task is easy. We need just compute the sum of both these values from each avarage object.

In computeObjectBegin the first value to start the computation is passed. In computeObjectLoop the the computation is carried forward with additional values. In computeObjectEnd the result of the computation should be returned. Hope this helps!

Sunday, April 6, 2008

AdvancedDataGrid performance poll

Hello AdvancedDataGrid users !

I have added two polls to the end of my blog. One for suggesting in what areas should ADG performance improve. Second one for overall performance of ADG in your projects/apps.

Please spare some time out of your busy schedule and take the polls.

I would urge you take both the polls because just taking one poll many not deliver the exact picture. For example if you say vertical scrolling performance needs to be improved we don't know whether the app is hurt by its performance or it is that it would do better with a performance boost.

Thanks for your time !

Of-course if you would like to send me a sample showing poor performance in a particular/general context please do by sending a mail

Update:I am seeing more number of votes on Bad than expected :(

I would appreciate if you leave a comment as to which particular area of ADG you found the performance to be so poor that it forced you turn it down. I am asking this because votes are also going in favor of Good and OK. It would be of great help if I get a pointer in that direction so that we can study that area of the code more and see what performance improvements can be done. Thanks!

Thursday, March 27, 2008

Documentation about Creating a Automation delegate for custom components in Flex

Documentation and sammple about how to go about creating an automation delegate for custom components in Flex is detailed here

It also has step by step description of delegate creation for the RandomWalk component created by Ely.

Hope it helps!

Wednesday, March 19, 2008

AdvancedDataGrid, Charts and OLAP source gets unziped in FlexBuilder Pro version

What I thought is a known fact seems not so widely known. Hence posting it.

When FlexBuilder Pro version is bought and a valid licensce key is entered the source code for the complete datavisulation.swc would get unzipped and get placed under

<FlexBuilder installation direcotry>sdk/3.0.0/fbpro/...

directory. Which means users would get access to AdvancedDataGrid, Charts and OLAP source code.

It is not open-source but source is available for you to take a look and override functions with more confidence and knowledge of the internal workings. And of-course suggest/complain !

Enjoy !

Thursday, March 13, 2008

Introducing OLAPTimeDimension for OLAP

In this sample though the data contained date information we didn't use it while building the OLAP cube. The reason was simple. The default OLAP implmentation in Flex 3 cannot handle dates in that format. It requires the date to be broken down into its components like year and month. If half year and quarter information is required that needs to be added to the flat data. That is a great pain point.

Here is OLAPTimeDimension to the rescue. It can be introduced as any other dimension in the OLAPCube schema and then configured to return year, half year, quarter, month and day in any combination.

<mx:OLAPCube id="salesCube" >

 <mx:OLAPDimension name="SalesData" >
   <mx:OLAPAttribute name="Company" dataField="company" />
   <mx:OLAPAttribute name="Region" dataField="region" />
   <mx:OLAPAttribute name="Market" dataField="market" />
   <mx:OLAPAttribute name="Product" dataField="product" />
    
   <mx:OLAPHierarchy name="Region-Market-Store" >
    <mx:OLAPLevel attributeName="Company" />
    <mx:OLAPLevel attributeName="Region" />
    <mx:OLAPLevel attributeName="Market" />
    <mx:OLAPLevel attributeName="Product" />
   </mx:OLAPHierarchy>
 </mx:OLAPDimension>
  
 <local:OLAPTimeDimension name="Years" dataField="date" />
  
 <mx:OLAPMeasure name="Revenue" dataField="revenue" />
  
</mx:OLAPCube>

Using this we get the following result where in we can query revenue for different years.

It can be easily extended to query quarters and months by setting includeQuarter and includeMonth to true on OLAPTimeDimension. The source is here.

Simple uses of OLAP

In Flex 3 OLAP APIs were introduced. And here is a sample showing how it can be used in simple data processing.

The sample shows how a companys product revenue over regions and markets can be compared. Click the "Create cube" button to process the input data which looks like this

<row>
  <company>Fiction</company>
  <region>Asia</region>
  <market>Digital publishing</market>
  <product>Frames</product>
  <date>3/31/2005</date>
  <revenue>10</revenue>
</row>

and build the OLAP cube. Clicking on the "Query Revenue with Product by Region" button would display the result in OLAPDataGrid. The query returns the total revenue comparing product by region across all years (2005 and 2006 in the sample data case). The last row and last column display the totals by product and totals by region respectively.

Now different markets can be selected from the ComboBox and revenues from different markets can be compared.

The source can be found here.

Wednesday, March 12, 2008

Creating OLAPCube in AS

In Flex 3 OLAP APIs were introduced and there have been many queries about how to create a OLAPCube in AS instead of defining it in MXML. Here is a sample :

private var salesCube:OLAPCube;

private function createCube():void
{
 salesCube = new OLAPCube();

 var dim1:OLAPDimension = new OLAPDimension("SalesData");

 //add attributes to the dimension
 var attr1:OLAPAttribute = new OLAPAttribute("Region");
 attr1.dataField = "region";

 var attr2:OLAPAttribute = new OLAPAttribute("Market");
 attr2.dataField = "market";

 var attr3:OLAPAttribute = new OLAPAttribute("Store");
 attr3.dataField = "store";

 var attr4:OLAPAttribute = new OLAPAttribute("LineOfBusiness");
 attr4.dataField = "line_of_business";

 var attr5:OLAPAttribute = new OLAPAttribute("Model");
 attr5.dataField = "model";

 dim1.attributes = new ArrayCollection([ attr1, attr2, attr3, attr4, attr5 ]);

 //add a user defined hierarchy   
 var regionHierarchy:OLAPHierarchy = new OLAPHierarchy("Region-Market-Store");

 //define the levels of the hierarchy
 var level1:OLAPLevel = new OLAPLevel();
 level1.attributeName = "Region" ;

 var level2:OLAPLevel = new OLAPLevel();
 level2.attributeName = "Market" ;

 var level3:OLAPLevel = new OLAPLevel();
 level3.attributeName = "Store" ;

 var level4:OLAPLevel = new OLAPLevel();
 level4.attributeName = "LineOfBusiness" ;

 var level5:OLAPLevel = new OLAPLevel();
 level5.attributeName = "Model" ;

  //add levels to the hierarchy
  regionHierarchy.levels = new ArrayCollection([ level1, level2, level3, level4, level5 ]);

  //add hierarchy to the dim
 dim1.hierarchies = new ArrayCollection([ regionHierarchy ]);

 //more dimensions can be defined here

 var measure:OLAPMeasure = new OLAPMeasure("Revenue");
 measure.dataField = "revenue" ;

 //more measures can be defined here

 //add the dimensions and measures to the cube.
 salesCube.elements = [ dim1, measure ];
}
This creates the same OLAPCube as the following in MXML
<mx:OLAPCube id="salesCube" >

 <mx:OLAPDimension name="SalesData" >
   <mx:OLAPAttribute name="Region" dataField="region" />
   <mx:OLAPAttribute name="Market" dataField="market" />
   <mx:OLAPAttribute name="Store" dataField="store" />
   <mx:OLAPAttribute name="LineOfBusiness" dataField="line_of_business" />
   <mx:OLAPAttribute name="Model" dataField="model" />
    
   <mx:OLAPHierarchy name="Region-Market-Store" >
    <mx:OLAPLevel attributeName="Region" />
    <mx:OLAPLevel attributeName="Market" />
    <mx:OLAPLevel attributeName="Store" />
    <mx:OLAPLevel attributeName="LineOfBusiness" />
    <mx:OLAPLevel attributeName="Model" />
   </mx:OLAPHierarchy>
 </mx:OLAPDimension>
  
 <mx:OLAPMeasure name="Revenue" dataField="revenue" />
  
</mx:OLAPCube>

Monday, March 10, 2008

DateChooser with support for backgroundColoring some dates

I got a query recently asking whether it is possible to have the DateChooser highlight certain special dates with a different background color. The query was accompanided by a DateChooser code which achieved this by using the TexField.backgroud and TexField.backgroudColor properties (similar to my other posts for DG row background coloring). But the draw back of the approach was that selection and roll over feedback was not working.

I took a look at DateChooser and CalendarLayout and realized that with the current design/implmentation it was not possible to add the backgroundColor support. The selection and rollOver indicators were lower in z order than date UITextFields.

I modified the CalenderLayout code to have three layers (UIComponents). One for background, second for indicators and third one for the dates. After modifying the addChild* and removeChild calls refer to the appropriate layers, the remaining work was to add "speicalDates" and "specialDatesColor" property and wire them up at appropirate places (commitProperties and updateDisplayList) to achive the following result :

I have randomnly generated the special dates in the above sample to keep the sample live on any day it is viewed!

I have added a alpha value of 0.7 in DateChooserIndicator to make the selection indicator show through the backgroundColor. Feel free to tweak this value to your flavor.

The project source to build the Flex3Ex.swc is here. It contains the modified DateChooser and CalendarLayout classes. I posted the complete Flex project here because Travis pointed out that it is difficult for newbies to understand how to use the component source files. Thanks Travis!

The source for the sample app is here.

The components can be further enhanced to support multiple specialDates (array of array of dates) and multiple specialDatesColors.

Update: I got to implement this. Source is available here.

Update: I have updated the source to support the following:

Now dates can be specified as strings "06/01/2009" (for 1st June 2009) but make sure that it succeeds to pass through Date.parse function and returns a valid Date.

Date ranges can be specified as follows:

{ rangeStart:"06/01/2009", rangeEnd:"06/05/2009" }

Update: There seems to be some problem with library path handling etc due to which a swc is not getting picked up properly in FB. The work around I came up for this is to include the Flex3Ex/src directory in the source path of the project as shown here