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.

Tuesday, June 10, 2008

CalculatedMeasures in Flex OLAP

I wrote a small sample which shows how a Custom Aggregator can be written and used to simulate a Calculated measure in Flex OLAP. Of-course, this solution may not work for all requirements but can be used atleast in some scenarios. The source is here.

Sunday, June 1, 2008

Here is a GroupingCollection with good performance !

I created a new GroupingCollection2 (by tweaking the default implemenation) which has better performance compared to the GroupingCollection. Please find the swc here.

Replace the GroupingCollection instance in any application with GroupingCollection2 and check the performance. When I tested it with 8K records with 4 grouping fields it was able to group in 5 seconds which seems to be good (in comparsion).

Please note this has not gone through extensive testing. I would be glad to fix any bugs found.

If you are one of those who doesn't have patience to build and test an app, here is the one I built. Here is the source.

If you think it is worth your time drop a note about your findings !!

Wednesday, May 28, 2008

Grouping XML data using GroupingCollection

I was under the impression this doesn't require any sample as it should be very easy to write one. But frequent questions on the forums have resulted in this post.

There is not much to describe so :

<mx:XML id="inputData" >
 <Tulokset>
 <Tulos id="xxx" group="xx" />
 <Tulos id="xxx" group="xx" />
 <Tulos id="xxx" group="xx" />
 </Tulokset>
</mx:XML> 
 
<mx:AdvancedDataGrid creationComplete="gc.refresh()">
 <mx:dataProvider>
  <mx:GroupingCollection source="{inputData.Tulos}" id="gc">
   <mx:Grouping>
    <mx:GroupingField name="@group" />
   </mx:Grouping>
  </mx:GroupingCollection>
 </mx:dataProvider>
 <mx:columns>
  <mx:AdvancedDataGridColumn dataField="@id" />
 </mx:columns>
</mx:AdvancedDataGrid>

The source is here.

Update: The below example shows how to use grouping when the data is in child nodes instead of attributes. This is a bit tricky because GroupingCollection is derived from HierarchicalData which treats child nodes as children by default. This leads to problems when we try to display the data after grouping. The trick is to make use of the childrenField property and point it to something like "undefined".

<mx:XML id="inputData" >
 <Tulokset>
  <Tulos>
     <id>xx1</id>
     <group>xxx</group>
  </Tulos>
  <Tulos>
     <id>xx2</id>
     <group>xxx</group>
  </Tulos>
  <Tulos>
     <id>xx3</id>
     <group>xxx</group>
  </Tulos>
 </Tulokset>
</mx:XML> 
 
<mx:AdvancedDataGrid creationComplete="gc.refresh()">
 <mx:dataProvider>
  <mx:GroupingCollection source="{inputData.Tulos}" id="gc" childrenField="undefined">
   <mx:Grouping>
    <mx:GroupingField name="group"  />
   </mx:Grouping>
  </mx:GroupingCollection>
 </mx:dataProvider>
 <mx:columns>
  <mx:AdvancedDataGridColumn dataField="id" />
 </mx:columns>
</mx:AdvancedDataGrid>

The source is here.

Please note that childrenField is also helpful when we are trying to display XML data with data and children as child nodes. Use it to point to the proper node name which contains the children. In the following example we need to set childrenField="details" to work properly.


<mx:XML id="special">
<rows>
<row>
  <name>A</name>
  <fund>100</fund>
  <details>
   <row>
   <name>a</name>
   <fund>20</fund>
   </row>
   <row>
   <name>b</name>
   <fund>80</fund>
   </row>
  </details>
</row>
<row>
  <name>C</name>
  <fund>200</fund>
  <details>
   <row>
   <name>a</name>
   <fund>80</fund>
   </row>
   <row>
   <name>b</name>
   <fund>80</fund>
   </row>
   <row>
   <name>c</name>
   <fund>40</fund>
   </row>
  </details>
</row>
</rows> 
</mx:XML>

<mx:AdvancedDataGrid >
   <mx:dataProvider>
       <mx:HierarchicalData source="{special.row}" childrenField="details" >
       </mx:HierarchicalData>
   </mx:dataProvider>
 <mx:columns>
  <mx:AdvancedDataGridColumn dataField="name" />
  <mx:AdvancedDataGridColumn dataField="fund" />
 </mx:columns>
</mx:AdvancedDataGrid>

Object/Array and ObjectProxy/ArrayCollection binding problems

Take a look at discussion here.

Many seems to be stumble upon this problem. Very similar to Object not dispatching any event for property value changes Array also doesn't dispatch any event for items added/deleted from it. Due to this when an object or array is used in the dataProvider of a list based control or comboBox etc any updates to the object or array would not get reflected in the UI.

The following sample should make it clear.

The first DG is fed with a ArrayCollection of Objects and the second DG has ObjectProxies. Select a item in the DGs and edit the values displayed in the text inputs. To complete the editing hit "Enter". Notice that in the first DG the values don't get reflected immediately where as in second DG it does.

To support Object based dataProviders the list based controls in Flex make a explicit call to ICollectionView.itemUpdated() to force a change event. This is the reason edits in list based controls get propagated to other list based controls when both of them are using the same colletion as input.

The source is here.

As noted in the forum discussion, when HierarchicalData is built using Objects/Arrays (to represent children) the changes to the Array would not get propagated to ADG. Hence it is necessary to construct the HierarchicalData using ObjectProxies and ArrayCollections.

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>