Archive for the ‘Demos’ Category

Data visualization in Flex 4.5 with Kolbert – Radar to Petal Chart

Wednesday, December 14th, 2011

Sometimes the data displayed in a Radar Chart can be difficult to intuitively analyse. I read a good article on alternatives to radar charts and wanted to apply the “Petal Chart” in Flex. When you look at the result, you would’nt think that both charts visualize the same data!

I used Kap Labs’ Kolbert API to generate a regular Radar Chart, and edited the data source and axis items to create a Flex Petal Chart. The two different data source CSV files can be seen if you right-click, View Source, and go to assets folder.

Radar and Petal Chart - Flex 4.5 using Kolbert

Flex 4.6 Mobile Running on Web (desktop browser)

Wednesday, December 14th, 2011

For those who have not yet tried out the Flex 4.6 mobile components, I have put together a collection of samples from the Adobe Help website that are runnable from a desktop web browser. I think the SplitViewNavigator looks really cool. Links to the code snippets used in the examples are below. View Source enabled!

Enjoy!

Flex 4.6 Mobile UI Running on Web (view source enabled)

Note:

Holly Schinsky has a good tutorial on getting mobile components running in  a Flex web app or desktop Air app.

Code Snippet Links:

Multiple Panes in a Mobile Application – Adobe Help

Date Spinners – Adobe Help

Spinner List with Embedded Images – Adobe Help

Flex 4.5 Mobile Paged/Stepper List

Thursday, October 13th, 2011

This mobile component converts a regular Flex mobile Horizontal List into a stepped/paged list.

It uses a custom skin for the list and a custom skin for the list’s scrollbar. The previous and next buttons are seperate from the list, and trigger the custom scrollbar’s changeValueByPage() function to move up and down the list. The two lists are use double binding as a visual aid for demo purposes, and I have used the lists ensureIndexIsVisible() function to ensure the selected index is always visible (now that’s intuitive function naming Mr. Adobe).

The paged list also employs the gestureSwipe event, but this cant be seen on the online demo. Thanks to Steven from Flexponential for his brilliant post that I based this component on. If you see any ways to improve it, please let me know.

Note: the demo runs just as it would on a mobile phone, as I have embedded mobilecomponents.swc and imported the mobile theme (see prev post to see how this is achieved).

Click the image below to view the mobile demo online! (right click for View Source)

Mobile Paged/Stepper Horizontal List (click to run demo)

Flex 4.5 Mobile Alert Box & Always Visible Scrollbars (with Mobile App in Browser Demo!)

Tuesday, September 6th, 2011

I created a nice Flex Mobile Alert popup based on a DevGirl.org tutorial, but improved it so that it can be called from anywhere in the code, and will popup centered in the currently active view (in the web demo it will be off centre, but on a mobile device its fine). I have also added functionality (based on Flexponential.com article) so that the text area of the Alert will have scrollbars that are always visible (a dumb-ass limitation of the current Flex 4.5.1 SDK build – now fixed in Flex 6).

Always Visible ScrollBar

Check out the Mobile App demo (click picture below) – its the Flex mobile app running in the browser (use Firefox/Chrome – doesnt look quite right in IE yet) – this was based on a brilliant post by riagora.com. Will upload the source at some point, but the AlertBox code is in the full article, along with direct links to the tutorials.

Mobile App in Browser (Click to run Demo)

Read the rest of this article…………….

Flex app with GoogleMaps API & GeoNames WebService

Wednesday, August 24th, 2011

This is a demo application I made for viewing country statistics and locations using the Google Maps API and GeoNames webservice (if GeoNames is unavailable – which happens occasionally – it loads a local copy of the country xml).

The app also uses a moveable/draggable canvas and has a clever implementation of multiple filters for the autocomplete and and combo box.

Click the image below to run the demo: ViewSource enabled (right click on the app)

Stat Map App (click to launch - ViewSource enabled)

1 million row DataGrid: ZendAMF, Flex data-paging, MySql

Wednesday, March 16th, 2011

Recently saw James Wards’ example of data paging in Flex 4,  and Mihai Corlans ZendAMF/PHP remoting tutorial on his blog.

To further explore the use of the very speedy AMF remoting (which I think we could use on some projects in work), I created a demo app with a Flex 4 DataGrid that displays the top 1 million ranked websites.

I have stored the data on a MySQL database, access it using remote procedure calls via ZendAMF/PHP, and use Flex AsyncListView and James Wards PagedList for data-paging. The demo has variable paging sizes (hit Reset All to clear the grid and reset page size), and a tracker to show the queued and completed remote procedure calls.

Flex ZendAMF DataPaging (View Source enabled)

The website rankings data was downloaded from www.alexa.com

Mutually Exclusive Shared ComboBox – Flex 4

Wednesday, March 16th, 2011

This custom component I developed extends ComboBox, and allows a number of ComboBox based components to be added to the stage (dynamically or statically), and they are all linked via a shared DataProvider.

In essence, the ComboBox components are shared, and selecting an item in one comboBox removes that item as a selectable option in any other ComboBox. Inversely, if a ComboBox is removed, its selected item becomes available to the others again.

Shared ComboBox demo (right click to view source)

  • IoC to inject a class with a static xmlList into the ComboBox components
  • getQualifiedClassName() and getDefinitionByName() to create Class references on the fly
  • Use of weak reference event listeners and custom events
  • Custom Spark Button class and button Skin
  • Forced garbage collection using the following:
/**
* Forces a garbage collection to occur. More reliable
* than System.gc();
*/
private function garbageCollectionHack():void{

   try {
       new LocalConnection().connect('foo');

       new LocalConnection().connect('foo');

     } catch (e:*) {}
}

In you add a change event handler, you can reference the sharedComboBox.ownedItem (this is handy if you passed in objects – in xml form – to your dataProvider)

Flex 4 Dependency Injection Example

Wednesday, February 9th, 2011

Joel Hooks wrote a good article on the advantages of dependency injection a.k.a. inversion of control (IoC) in ActionScript3. I thought the most informative paragaph was as follows:

“When dependencies aren’t injected, when they are created internally by the object using the new Object() syntax, the class is internally bound to the dependency. When this dependency is provided to the class externally the responsibility of creating the dependency is removed from the class. The advantages of this approach are even more significant when we use interfaces instead of specific implementations for our class dependencies. When interfaces are used, the class doesn’t care about the specific implementations provided as dependencies as long as they conform to a specific interface.”

Ive used the RobotLegs and Swiz micro-architectures before on small projects, but I have  also used IoC quite extensively outside of these frameworks. I put together a little visual demo of IoC being used in Flex 4 (view source enabled). Click pic for running example.

Click to view SWF

Easing/tweened Flex Scrolling Canvas

Tuesday, July 27th, 2010

I was looking to add some acceleration/easing to the scrolling of a Flex container.

I used Tweener API and applied it to a Flex Canvas (the canvas has its scrolling policies turned off, and scrolling is provided with an external/floating scrollbar).

Click to run the swf (view source enabled)

You can see the Tweener trainsitions on their online documentation here (click on ‘transition types’).

I have tweener.swc in my libs folder.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
	creationComplete="init()">

	<mx:Script>
		<![CDATA[
			import mx.effects.Glow;
			import mx.controls.Button;
			import mx.events.IndexChangedEvent;
			import mx.controls.Label;
			import caurina.transitions.Tweener;
			import mx.effects.Tween;
			import mx.events.ScrollEvent;
			import mx.controls.scrollClasses.ScrollBar;
			import mx.graphics.GradientEntry;
			import mx.graphics.LinearGradient;

			private function init():void{

				addItemsToCanvas();
				scrollControlCanvas.addEventListener(ScrollEvent.SCROLL, onCanvasScroll);
			}

			private function onCanvasScroll(event:ScrollEvent):void{
				event.stopImmediatePropagation();

				switch (event.direction) {
					case "horizontal":
						Tweener.addTween(viewCanvas,
							{horizontalScrollPosition:scrollControlCanvas.horizontalScrollPosition,
											time:0.6, transition:"linear"});
						break;
					case "vertical":
						// If you need a vertical tween add it here
						break;
				}
			}

			public function addItemsToCanvas():void{

				gradientCanvas(contentCanvas, 0x55D4FF, 0xFFD400, 0); //FF00000

				var button:Button;
				var dividerWidth:Number = 100;
				var numDividers:int = Math.floor(contentCanvas.width/dividerWidth);

				for(var i:int = 0; i < numDividers; i++){
					button = new Button;
					button.width = 40;
					button.setStyle("fontSize", 10);
					button.label = i.toString();
					button.x = ((i+1)*dividerWidth) - (dividerWidth/2) - (button.width/2) ;
					button.y = contentCanvas.height/2 - 50;
					contentCanvas.addChild(button);

					contentCanvas.graphics.beginFill(0xFFFFFF, 0.5);
					contentCanvas.graphics.drawRect((i+1)*dividerWidth, 0,
											3, contentCanvas.height);
					contentCanvas.graphics.endFill();
				}
			}

			public function gradientCanvas (cnv:Canvas, color1:uint, color2:uint, angle:int):void
			{
				var w:Number = cnv.width;
				var h:Number = cnv.height;
				var g:Graphics = cnv.graphics;

				g.clear();

				var fill:LinearGradient = new LinearGradient();
				var g1:GradientEntry = new GradientEntry(color1,0,1);
				var g2:GradientEntry = new GradientEntry(color2,1,1);

				fill.entries = [g1,g2];
				fill.angle = angle;
				g.moveTo(0,0);
				fill.begin(g,new Rectangle(0,0,w,h));
				g.lineTo(w,0);
				g.lineTo(w,h);
				g.lineTo(0,h);
				g.lineTo(0,0);
				fill.end(g);
			}
		]]>
	</mx:Script>

	<!-- The canvas you actually see. NOTE: scroll is off-->
	<mx:Canvas x="74" y="69" width="441" height="203" id="viewCanvas"
		 horizontalScrollPolicy="off" verticalScrollPolicy="off">
		<mx:Canvas x="0" y="0" id="contentCanvas" height="100%" width="3000">
		</mx:Canvas>
	</mx:Canvas>

	<!-- This canvas acts only as the scrollBar - NOTE: the dummyCanvas is empty,
		 but is exactly the same dimensions as the viewCanvas -->
	<mx:Canvas x="74" y="280" width="441" height="30" id="scrollControlCanvas"
		 verticalScrollPolicy="off">
		<mx:Canvas x="0" y="0" id="dummyCanvas" height="{contentCanvas.height}"
			width="{contentCanvas.width}">
		</mx:Canvas>
	</mx:Canvas>

</mx:Application>

Inspired by a Flash solution from Soundstep, and a more complex (than my method) animated canvas by Vladimir Tsvetkov.

Example multidimensional / 3D indexed array in Flex AS3

Monday, July 26th, 2010

Scenario: I recently created a Flex component that extended the Canvas, and was split into a large number of ‘cells’ using constraint rows/columns. In each of these cells could be placed any number of UIComponents.

Problem: At any time I could tell what cell I was mousing over e.g.  (0,1), but I also needed to get an array of the components in that cell. It was not optimal iterating accross all the UIComponents on the canvas to check their constraint row/column id’s to find the relevant ones.

Solution: Created a 3D indexed array with references to each cell’s UIComponents. To retrieve the components from cell (3, 5) I would simply use: resultsArray = _cellComponents[rowNum][columnNum];

The image below represents a basic 3D array, with each cell containing just random objects: ints, strings and an image object. The sample app code that follows shows you how to create and populate a 3D array, and has a simple interface so you can test retrieving the stored objects.

3D array visual

Simple UI for 3D Array


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">
	<mx:Script>
		<![CDATA[
			import mx.controls.Image;
			import mx.controls.Button;
			import mx.events.IndexChangedEvent;

			private var _array3D:Array = new Array();
			private var _numRows:int = 2;
			private var _numColumns:int = 4;

			private function init():void{

				for(var i:int = 0; i < _numRows; i++){

					var rowArray:Array = new Array();
					_array3D.push(rowArray);

					// Create a 3d array (basically a 2d array of array objects)
					for(var j:int = 0; j < _numColumns; j++){

						var columnArray:Array = new Array();
						_array3D[i].push(columnArray);
					}
				}

				// Populate a 3d array
				_array3D[0][0].push(1, 2, 3, 4);
				_array3D[0][3].push("A", "B", "C", "D");
				_array3D[1][0].push(5, 6, 7);
				_array3D[1][1].push(8);
				_array3D[1][2].push(9, 10);
				// You can add any type of Object to the array.
				var image:Image = new Image();
				image.name = "arrayImage";
				_array3D[1][3].push(image);

			}

			private function getValues(row:String, col:String):void{

				var r:int = parseInt(row);
				var c:int = parseInt(col);

				var cell:Array = _array3D[r]1;
				var output:String = "";

				if(cell != null){

					for(var i:int = 0; i <cell.length; i++){
						output = output + " " + cell[i].toString();
					}

					if(output == ""){
						outputText.text = "No data in cell"
					}
					else{
						outputText.text = output;
					}
				}
				else{
					outputText.text = "Not a valid row/column";
				}
			}

		]]>
	</mx:Script>

	<mx:Canvas id="myCanvas" x="65" y="49" width="308" height="99" backgroundColor="#FFFFFF">
		<mx:ApplicationControlBar x="0" y="0" width="100%">
			<mx:Label text="Row"/>
			<mx:TextInput id="row" width="56"/>
			<mx:Label text="Col."/>
			<mx:TextInput id="col" width="56"/>
			<mx:Button label="Get Values" click="getValues(row.text, col.text)"/>
		</mx:ApplicationControlBar>
		<mx:Text id="outputText" x="0" y="52" width="100%" textAlign="center"/>
	</mx:Canvas>
</mx:Application>