Posts Tagged “Flex”

Yesterday afternoon my client team presented their redesign work to their senior executive, and it was quite well received. One of the suggestions coming out of the meeting, and something we’d already thought a little bit about, was producing a dashboard for all the major indicators. Last night I had a bit of a play and got something working, and today I’ve refined it a little.

The idea is that the user will be able to choose which graphs in the dashboard are displayed, and that the layout scales to fully utilise the screen real-estate. Flex has some built-in Container objects that have some smarts for this sort of thing but none quite did what I wanted. VBox and HBox are the closest, but only allow one column or row (respectively) of objects. Tile looked promising but they don’t dynamically scale particularly well. There’s a whole heap of dashboard libraries available online, but they seemed like overkill for what is really a fairly simple task.

In the end I went with a simple solution: two HBoxes in a VBox, and code to move objects in and out of the HBoxes based on how the objects need to be displayed.

Now that I’ve got the UI working fairly well, I need to go back and clean up a lot of the code to make the adding of graphs more dynamic (currently it’s all hard coded). Then without too much more work I think it would be possible to put the whole config for the dashboard into an XML doc, resulting in a dynamic, re-usable dashboard. Sweet.

It’s also rather nice that I didn’t need to change any of the graph-building code to get this to work - justifies some of the refactoring decisions I made recently.

I thought it might be nice if my dashboard allowed users to double-click on an graph and have it ‘maximised’, then double-click again to restore the previous view. That seems simple enough, and in the end it wasn’t too difficult. But for some reason I managed to spend way too long going about things all wrong. In part, it’s because Flex/ActionScript doesn’t have a particularly useful Hashtable equivalent, and in part because I was just overthinking things.

You can use an Object as an associative array for key/value pair type data, but that’s not particularly feature rich. In particular it’s difficult (or impossible) to get a key based on the object you have. When looking for workarounds I came across DevelopmentArc, a company that have released a library of useful stuff under the very open MIT license. Thankfully, this includes an implementation of a hashtable that’s quite nice (although reverse-lookups are still a little bit of work).

Here’s a screenshot of the dashboard so far. At a later date I’ll put up the most interesting bits of the code. Keep in mind the UI-gurus haven’t had a play with this yet, so it’s nowhere near pretty.

dashboard

Comments No Comments »

In the FlexBuilder IDE using javadoc-style comments (/** …… */ ) behaves as it does for Java, but there’s nowhere in the FlexBuilder settings to specify that documentation should be produced. After a little investigation, it seems that ASDoc is a command line tool that has not yet been integrated with FlexBuilder.

Viewing the Adobe help for ASDoc doesn’t really give you the impression that it’s all that easy to use - it recommends running ASDoc from FlexBuilder’s bin directory, passing the location of your source folder as a parameter. If you want to create doco for all of your classes, you have to pass the location a second time. Annoyingly, the output is also created in the bin folder. Ugh.

After a small amount of fiddling I worked out an easier way. Create a Windows batch file and put the following line in it:

"C:\Program Files\Adobe\Flex Builder 3 Plug-in\sdks\3.0.0\bin\asdoc" -source-path . -doc-sources .

You can copy and paste this batch file into any of your source folders, run it, and the ASDoc output will be created in the src folder.

NB: in order to get ASDoc to work at all I had to use my admin ID to elevate the priveledges of my normal ID so that it had write access to the C:\Program Files\Adobe\FlexBuilder folder - ASDoc seems to update a config file there, and will fail if it doesn’t have access to do so.

On the bright side, the output from ASDoc is quite nice, and well worth the small amount of hassle to create.

 

Update To make life even easier you can import the batch file into your Flex project, then run it by double-clicking it

Comments 1 Comment »

I’ve found some interesting behaviour when attempting to control the rendering of the vertical axis in a Flex chart. As with most UI elements in Flex, you can create charts either using MXML or ActionScript. Surprisingly, the properties of the chart are different depending on how they’re created.

The ActionScript generated graph is fairly logical to deal with: nothing is pre-created so you need to do it yourself:

var vAxisRenderer:AxisRenderer = new AxisRenderer();
vAxisRenderer.axis = vAxis;
vAxisRenderer.placement = "right";

_lineChart.verticalAxisRenderers.push(vAxisRenderer);

It’s worth noting that only need to instantiate your own axis renderer if you want to set non-default values, otherwise you can ignore it all together. At this point it’s worth noting that MXML is transformed into ActionScript at compile time. This is important in understanding the next part.

Charts generated with MXML seem to set several properties, despite actually setting them to the same value as the object’s default. That can be somewhat confusing - if for example you try to add an AxisRenderer to an MXML-generated chart (as you would for an AS-generated one) you end up with two axes displayed. Although marginally annoying, the solution is simple: rather than creating a new property object you get a handle on the existing one and modify that.

Unfortunately it seems that in the case of AxisRenderers (at least on the LineChart object) the MXML transformation process uses a depricated property object - LineChart.verticalAxisRenderer:AxisRenderer (rather than LineChart.verticalAxisRenderers:Array). In order to manipulate the current renderer, first you get a handle on it:

var vAxisRenderer:AxisRenderer = _lineChart.verticalAxisRenderer as AxisRenderer;

Then proceed as normal. Because the verticalAxisRenderer property is depricated you will end up with a compiler warning.

The bottom line: don’t always assume that the MXML transformation to ActionScript works as you would expect it to. Despite the apparent ease of using MXML as shorthand, it’s often less hassle in the long run to use ActionScript from the outset.

Comments No Comments »

One of the few annoyances I’ve come across with Flex is ActionScript’s lack of support for some common OO constructs like abstract classes, private constructors and enums. 

Creating your own enum class, which gives you compile-time type safety, is pretty trivial:

public class MyEnum{
	public static const SOMETHING:MyEnum = new MyEnum("SOMETHING");
	public static const SOMETHING_ELSE:MyEnum = new MyEnum("SOMETHING_ELSE");
	
	public var enumName:String;
	public function MyEnum(name:String){
		enumName = name;
	}
}

You then use it as expected:

public class myClass{
	public function myClass(enum:MyEnum){...}
}
public class myOtherClass{
	...
	var mc:MyClass = new MyClass(MyEnum.SOMETHING);
}

You could of course forgo the enumName property and still get type safety. However when debugging it’s handy to be able easily see the name of the enum, which the property allows.

Some quick Googling will turn up a raft of different ways to do this - many of them implementing an Enum base class that you can extend. I’m quite happy with my simple solution though - 3 lines of code in each enum class is not too onerous.

Comments No Comments »

As mentioned previously, I’m creating a UI to allow ‘normal users’ to configure the Flex graph templates. My idea was to have the users enter the required info, then generate the config and dump it locally along with the SWF and a simple HTML page. This would allow them to easily preview the graph before it was released.

One small problem though: Flex/Flash sandboxing prevents access to local files, even when the SWF itself is local, which means that it can’t read the config file. The net-usage flag allows you to compile the app with local file access, but only if you relinquish network access. Full access is possible, but only by modifying the Flash settings on each users’s PC to set up trust. And of course, in our locked down desktop environment, users’s don’t have access to do that.

So I’m left with a couple of options. I could try and auto-deploy it to a webserver, but this is somewhat tricky as it needs to cater for concurrent users, and also requires the users to have access to the webserver.

Another option is to use the UI app to pull down all the network files locally, and run in local trusted mode. That may work - needs investigation.

Alternatively I could try and either get our desktop environment changed, but I don’t like my chances.

Update

I decided to go with deploying the config file to the webserver, because after some thought I realised that it was pretty easy. I’m using Notes for the client UI, which makes it fairly trivial to use the actual document the clients fills in as the config file. Modifying the Flex app to take the location of its config file as a parameter was also pretty easy - just using the FlashVars parameter when embedding the object.

So now, I’m hosting the Flex graph in the Notes DB, along with the config documents. Then whenever a user wants to preview the graph, a local HTML file is generated that embeds the SWF from the server and passes the location of that user’s config file to the SWF. That, mostly, works quite well.

The problem now is that I’ve been somewhat protected by the dev environment. It seems that (and it’s logical) the bin-debug directory is one of those special ‘full trust’ Flash locations, so any SWF in that dir can access local files and network resources. Now that I’m running on a server though, the SWF cannot access network resources that are in a different domain (see livedocs). So to get around this, I’ll need to create a simple proxy script/agent/servlet to wrap the external server calls.

In a way it was good to find this now, as the call to the Excel2XML servlet would certainly have broken for the same reason once I had tried to deploy.

Hopefully tomorrow I’ll get the proxy sorted, which will mean the bulk of the functionality for the client UI will be done, other than prettifying and cleaning up.

Comments No Comments »