Scrollable and Touch-Friendly Flex Charts

After I posted Flex Charts on the iPad, a few people asked me how to enable some specific gestures on these charts to make them small screen-friendly. One specific question was: “How can we make a chart scrollable to show a lot of data on a smaller screen while making sure the vertical axis is always visible?”. Here is a very simple implementation. You can customize and polish it in many different ways. For example, you could use AnimateProperty on the Axis minimum and maximum properties to animate the scrolling.

Use the mouse to scroll the chart columns left and right. On a touch screen, you can do the same thing using gestures.

Here is the code (I’ll have to do something about the pink!):

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   creationComplete="completeHandler()">

	<fx:Script>
		<![CDATA[
			protected var lastX:Number = 0;

			[Bindable] protected var viewportMax:Number = 10;

			protected function completeHandler():void
			{
				// Simulate values
				var results:Array = [];
				for (var i:int=0; i<50; i++)
				{
					results[i] = Math.random() * 100;
				}
				chart.dataProvider = results;
			}

			protected function mouseDownHandler(event:MouseEvent):void
			{
				lastX = event.stageX;
				systemManager.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
				systemManager.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			}

			protected function mouseMoveHandler(event:MouseEvent):void
			{
				var delta:Number = (lastX - event.stageX) / chart.width * viewportMax;
				if (hAxis.minimum + delta < 0)
				{
					hAxis.minimum = 0;
					hAxis.maximum = viewportMax;
				}
				else if (hAxis.maximum + delta  > chart.dataProvider.length - 1)
				{
					hAxis.maximum = chart.dataProvider.length - 1;
					hAxis.minimum = hAxis.maximum - viewportMax;
				}
				else
				{
					hAxis.minimum += delta;
					hAxis.maximum += delta;
				}
				lastX = event.stageX;
			}

			protected function mouseUpHandler(event:MouseEvent):void
			{
				systemManager.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
				systemManager.removeEventListener(MouseEvent.MOUSE_MOVE, mouseUpHandler);
			}

		]]>
	</fx:Script>

	<mx:ColumnChart id="chart" top="10" left="10" right="10" bottom="10"
					mouseDown="mouseDownHandler(event)">
		<mx:series>
			<mx:ColumnSeries />
		</mx:series>

		<mx:horizontalAxis>
			<mx:LinearAxis id="hAxis" minimum="0" maximum="{viewportMax}"/>
		</mx:horizontalAxis>

	</mx:ColumnChart>

</s:Application>

Show Comments

Hide Comments

Comments are closed.