Archive for June, 2007
Task Scheduler Chart using AdvancedDataGrid (moxie)
Jun 28th
Few days back I had posted an example of a Gantt chart component developed using the AdvancedDataGrid of moxie. I was playing around with the component for the horizontal scrolling performance analysis and finally ended up writing this small component.
This is a simple engineering work items display which shows the tasks for each engineering role with drill down capabilities. Double Clicking the quarter information column will drill down the data for that column (double click to collapse) . Clicking on the month info will get you the day-wise breakdown of the tasks. (double click the top column to collapse). I intend to develop this as a full fledged component once I am done with my current commitments at work. Watch out this space for more updates and also source code. For the time being, check out the application here.
Tips & Tricks : AdvancedDataGrid – grouping & summary rows
Jun 14th
This is the first among the series of articles that I intend to write about the new AdvancedDataGrid control of Flex 3.0 (moxie). You would require Flex 3 beta 1 to compile and run this example. If you dont have moxie yet, download it here
Displaying grouped (hierarchical) data & summary rows in AdvancedDataGrid
One of the key features of the new AdvancedDataGrid (will be referred to as ADG from hereafter) is its inbuilt capablility to display hierarchical data. This is made possible through the new set of collections classes that have been added. The following example helps you learn two things:
- How to create a grouped data from the flat data that is supplied to ADG
- Create summary rows based on the data.
Lets now look at the example
The example in this article has an ADG which display the quarterly revenue details of companies and the number of licences sold by each one of them stored as an XMLList. This XMLList is supplied as the dataProvider for the ADG. (This is all similar to what you would do in the DataGrid).
Now, Lets try and group this data based on the field quarter. Lets look at the code that will let us do that
//Make a grouping collection
var mygroup:GroupingCollection=new GroupingCollection();
//Set the source to the array collection (this case dataProvider)
mygroup.source = colgrouped_adg.dataProvider;
//Create a new grouping
var group:Grouping = new Grouping();
//Group on Quarter
var gf:GroupingField = new GroupingField(”Quarter”);
//Set the fields to the grouping
group.fields = [gf];
//Finally, Set the group to the grouping property of groupedCollection
mygroup.grouping = group;
//Refresh the group
mygroup.refresh();
//Set the dataProvider to the grouping collection
colgrouped_adg.dataProvider = mygroup
//Call validateNow() to redraw the dg.
colgrouped_adg.validateNow()
The steps are as follows:
- create a grouping collection
- set the source to a flat collection (this case the ADG DataProvider)
- create an instance of grouping
- create a grouping field and pass the field that you want the data to be grouped on
- set the fields property of the grouping to the groupField
- set the grouping property of the grouping collection to grouping instance
- refresh the grouping collection
- set the dataProvider of ADG to the grouping collection
- call validateNow() on ADG to update the display
Now, Lets write some code to calculate the summary of the total number of licences sold by *ALL* companies. Here we go!
var sr:SummaryRow = new SummaryRow();
//Set the summaryObjectFunction
//This function tells ADG to add a summary row in addition to the existing data
sr.summaryObjectFunction = objFunc;
//Set the summary field. The field on which the summary will be calculated.
var sf:SummaryField = new SummaryField(”Licenses”);
//Summary Function – the function that calculates the summary row display
sf.summaryFunction = func;
//set the summary rows fields property to summaryField
sr.fields = [sf];
//Place the summary row (Last means data First, summary Last!)
sr.summaryPlacement = “last”;
//Group on Quarter
var gf:GroupingField = new GroupingField(”Quarter”);
//set the summary row(s) to groupingField
gf.summaries=[sr]
Thats fairly straight forward. Here are the steps you need to follow to get a summary row in your ADG.
- Create a summary row instance
- Set the summaryObjectFunction to include a summary in your ADG data
- Create a summary field, the field on to which the summary calculation formula needs to be applied.
- Write a summary function which contains the logic to calculate the summary
- set the summaryField to the fields propety of summary row
- Define summaryPlacement “First / Last” First will put summary before data, last will add it after the data
- Finally set the summary rows to the groupingField.
The SummaryObjectFunction looks like this: (This method returns a SummaryObject)
private function objFunc():SummaryObject
{
var obj:SummaryObject = new SummaryObject();
obj.summary = true;
return obj;
}
Finally, the summary function. summaryFunction accepts 3 parameters (its a callback, you may never have to pass params to it, but be sure that you write the signature correctly) an iterator,a field and an operation. (operations include build-in methods like ADD).
private function func(itr:IViewCursor,field:String, str:String=null):Object
{
var sum:Number=0
while(!itr.afterLast)
{
//trace(itr.current)
var value:Number = Number(itr.current.Licenses);
if(!isNaN(value))
{
sum+= value
}
itr.moveNext()
}
return sum
}
Thats it! We are done and what we get will look like this ![]()
I have included the sample application as well as full source code for this example. Do take a look at it. I hope this one was useful for all those who are exploring the new ADG. Do look out for more tutorials on this topic.
Do check out my Simple Gantt chart built on AdvancedDataGrid
Simple GanttChart using AdvancedDataGrid of Flex 3.0 (Moxie)
Jun 13th
Flex 3.0 (Moxie) beta is out and I am sure most of you would have started playing around with the cool new features of Moxie. <mx:AdvancedDataGrid> is the new, improved DataGrid – a super cool component in moxie. Its a very exciting moment for me because I was part of the engineering team that designed and developed this control
. I spent a few hours yesterday to see if I can use this control to write a simple Gantt chart, given the fact that the AdvancedDataGrid lets you have column spanned itemRenderers , groupedColumns and hierarchical display. I took a similar approach to what Doug had done in his example of a gantt chart.
This is what I got!! ![]()
This is a rough prototype that I wrote and I sure dint spend much time designing this application. I will try and get this one as a component when I have a little more of free time.
Things I loved about AdvancedDataGrid doing this small app
- AdvancedDataGrid Rocks!
- The new groupingCollection APIs make hierarchical display of data Child’s play
- The rendererProviders property and the column spanning lets you customize itemRenderers in a much advanced way than DataGrid
- <mx:AdvancedDataGridColumnGroup> lets you group the columns seamlessly!
The horizontal scrolling is a little slow, but we are sure working on it to get it a lot faster than what it is now! (hey, its just a beta!)
You can download the source code from here.[Adobe Share] If you cant figure out much from the data, its just a timeline of set of tasks and their respective percentages. Red shows delayed. Orange shows delayed start, green shows timely completion, grey - not yet started and blue – in progress.
The code that I have written requires many rounds of cleaning up before I can share it publicly :p (I will do that soon!). In the meanwhile, do check this space for a new series of tips & tricks and tutorials on working with the new AdvancedDataGrid.
All of ya keep flexing your “moxie” till then!
Tips & Tricks – adding a combobox to a datagrid header as headerRenderer
Jun 7th
I am sure many of you would have tried dropping a ComboBox as a headerRenderer to a DataGrid. Well, if you try to directly drop in a ComboBox you will get an RTE and the ComboBox just doesn’t work! I got this request from one of the flex users here that they need to drop a ComboBox on a datagridcolumn to provide a UI for filtering the data in the datagrid.
After looking at the code for a while, I figured out that the set data method of the combobox checks if it is dropped in as an itemRenderer and what’s more, it sets the data irrespective of whether the value recieved in the set data is a datagrid column or not. In the case of dropping the ComboBox, the data setter sets the data to the DataGridColumn and when the program progresses it throws an RTE which says it couldnt find the property name on the headerRenderer instance.
The solution:
I subclassed the ComboBox control to make MyComboBox and wrote an override for the data Setter. I just added the following type check before the data setter in the super is called
if(value is DataGridColumn)
{
//do not call super; that is it!!
}
else
{
super.data = value
}
Thats pretty much it! The ComboBox will now correctly display in the header. I have written a simple example that has a ComboBox on the Datagrid column header which can be used to filter data. Note: I have turned off sortable columns and draggable columns in this example.
Disclaimer: This sample contains a small example of the concept, the application in itself has not been tested for bugs. People copy pasting the whole code and urged to exercise Download Source
Report: Flex APAC Seminar – 06/07
Jun 6th
The session on introducing ActionScript 3.0 on the Flex APAC seminar was a great success. We had 67 developers from different parts of India joining us and we had some great participation from all the members. This session was a great learning experience for me, and I enjoyed the whole 1 hour of the seminar thoroughly. Raghu joined me as a co-presenter and did a fabulous job in explaining the Flex builder debugger in just 10 minutes. Overall a wonderful start for the series and hoping to see more and more flex enthusiasts joining in for th forthcoming sessions.
Just in case if you missed the session, you can view the recording of the seminar here
APAC flex wednesdays: Inroducing AS 3.0 – Part I (06/07)
Jun 5th
Tomorrow (06/06) we have the APAC flex wednesday where I will be talking about AS 3.0, and some key concepts of AS 3.0 for AS 2.0 as well as java developers. The talk is scheduled at 4:00PM IST. Details as follows:
APAC Flex Wednesday Series – Session II
Topic : Introducing ActionScript 3.0 (Part I)
Date : 6th June 2007
Time: 4:00 PM IST
Connect URL : http://my.adobe.acrobat.com/flexapacseminar/
See you all tomorrow!
Tips & Tricks – ItemEditors – III
Jun 4th
In the earlier articles (I, II) , we saw how to use itemEditors on a flex datagrid and also how to validate data that is entered in the itemEditor. Lets take the example in the previous article and improve it a little further.Lets look at the doValidation() method again: We were comparing if the entered value is greater than the upperBound and throw an error message as an Alert in the example. Flex comes with some really cool built in validators that provide a much more usable user experience than throwing an Alert box to the user when an error has occured. In this example, lets try to incorporate a NumberValidator to do the same validation that we were doing earlier using the if conditional.
The code
Well, things havent changed too much from our earlier example, except for the following method – doValidation()
//Validate the data entered / stepped in the itemEditor
private function doValidation(event:DataGridEvent):void
{//Storing the selection made in the itemEditor to a variable
var selectedData:Object = CustomNumericStepper(datagrid.itemEditorInstance).value
//Store the upper bound to compare
var upperBound:Number = event.target.selectedItem.value;
//create a number validator instance. This can be extended to any validators
nv = new NumberValidator()
//specify the source – in this case the itemEditor instance
nv.source = CustomNumericStepper(datagrid.itemEditorInstance);
//Set the property to validate against. NOTE: always set this, or the validator will throw RTE
nv.property = “value”
//Set the maxvalue to the upperBound
nv.maxValue = upperBound;
//Call validate and take the return value. NOTE: validate() method sends two events valid / invalid based on the validation.
//val contains an event reference
var val:* = nv.validate(selectedData);
//check if validator returned invalid.
if(val.type == “invalid”)
{
//Prevent default action.
event.preventDefault();
}}
So, whats different here? We are creating a new instance of a NumberValidator (nv) here. Then the source property of the validator is assigned to the control, whose data we are interested in validating. In our case, its the itemEditorInstance – the custom numeric stepper. Important point to note here – once you have set the source property, always set the “property” property (this is NOT redundant typing, there is a property called property for a validator
) of the validator to the property that we are validating against. Set the maxValue of the validator to the upperBound and call validate(value:Object) method on the validator. The validate() method accepts the value that we are validating.
When you run the example, you can see that the validator puts a red box around the wrongly entered field and when you move the mouse over, you can see that the error message is displayed as a red tooltip. Isn’t that cool? Do look up the documentation for the validators, there are many more properties that can be used to customize the validation parameters, error messages etc.









