zen of coding

amCharts with CakePHP

There is a very slick flash charting tool out there called amCharts (www.amcharts.com). If you are in need of some reporting or charting UI for your application, I strongly recommend it.

This is a quick guide on how to get it working with CakePHP.

For this example, I’ll show you how to get the amLine setup, but the rest (amPie, amColumn, etc.) are pretty similar.

1. First create a directory in your webroot called ‘amcharts’.
2. Next, download the zip with Line and Area chart.
3. There should be two folders in the archive (amline and examples).
4. Extract the following files into your ‘amcharts’ directory:
– amline.swf
– amline_settings.xml
5. The rest you really don’t need to worry about for right now.
6. Also, extract the ‘plugins’ and ‘fonts’ folders right into your ‘amcharts’ directory.

So basically you should have something like this:

amcharts
|- fonts (directory with fonts)
|- plugins (directory with value_indicator.swf)
|
|- amline.swf
|- amline_settings.xml

Now create an empty file called amcharts_key.txt and place it in your ‘amcharts’ directory (it will save you some headache in the future). This file is required to hold the key if you purchsase a license for your charts (otherwise you’ll see a tiny text along the lines of ‘chart by amcharts.com’), without this file present I ran into all sorts of silly problems, the cause of which wasn’t very obvious.

Lastly, extract the swfobject.js file into your ‘js’ directory (in your webroot, where you keep all your JavaScript includes).

Let’s say that you already have a model and a controller setup (if not, you shoud create some for testing).
Let’s create a view and call it chart.ctp. You will need to include the swfobject.js, so at the top of view do:

[sourcecode language=’php’] link(‘swfobject’, false); ?> [/cc]

Now, in the view you will need to include the amCharts code, here’s a sample:

[sourcecode language=’php’]

You need to upgrade your Flash Player



[/cc]

Couple of things to note here… You’ll notice the echo microtime() after the amline_settings.xml, this little trick will ensure that whenever you update the settings file, amCharts will use a fresh copy (rather than the one you have in cache, leaving your wondering why none of your changes are taking effect).

Then you’ve got $seriesXML and $valuesXML variables. This is actual data to be displayed on the chart. Of course, these variables will have to come from your controller as XML strings.

So, what kind of data are we going to display on this chart? Well, for the sake of example let’s say we will display the date on X-axis (our series) and the number of log-ins into your application on the y-axis (our values).

You did your ‘find’ in the controller and now you have an array that looks something like this:

[0] => Array
(
[thedate] => Apr 4, 2008
[count] => 375
)

[1] => Array
(
[thedate] => Apr 5, 2008
[count] => 412
)

[2] => Array
(
[thedate] => Apr 6, 2008
[count] => 407
)

[3] => Array
(
[thedate] => Apr 7, 2008
[count] => 415
)

… and so on…

You will now need to step through this array and convert it to simple XML strings, then pass the resulting strings to the view as $seriesXML and $valuesXML. (Remember those variables in the view you’ve setup earlier?)

Setup this function in the controller:

[sourcecode language=’php’]
function __buildXMLstring ($data, $type) {
$counter = 0;
$xmlString = ”;

foreach($data as $key => $value) {
$xmlString .= ‘‘.$value[$type].’‘;
$counter++;
}

return $xmlString;
}
[/cc]

So you’ve already used the ‘find’ method and got the data (in the format as the array above) stored in the $myData array variable.

$this->set(‘seriesXML’,$this->__buildXMLstring($myData, ‘thedate’));
$this->set(‘valuesXML’,$this->__buildXMLstring($myData, ‘count’));

Note, that as a second parameter you are passing the array key, so that correct values will be used for both axis of your graph.

This will generate the appropriate XML for your data array that should now display nicely in your chart.

Note, that if you are displaying huge amounts of data, it might be best to write it to a file instead of passing it to the view. Anything passed to the view will be rendered by the browser and if you’ve got thousands of rows of data it could cause some serious problems with performance.

There are a lot great features in amCharts, but you’ll have to dig around the documentation to get the full benefits. Good news is that it’s relatively easy to follow once you get the basics down.

Good luck!

  • So, is amCharts commercial?

    Meaning not free?

  • teknoid

    @ emaconline

    You can use amCharts for free, but then there will be a tiny text saying ‘charts by amCharts.com’. The single domain license is relatively cheap.

    Considering the quality of product, I feel it’s a fair deal.

  • Thanks, it will be even great if you could also write a helper for it ;)
    something clean like: $charts->pie($settings);

  • teknoid

    @ Abhimanyu Grover

    Not a bad idea, I’ll try to at least get started on it this week…

  • Jeremy Hicks

    Do you have an example that uses a dynamic page for the data_file to create the xml? I’m trying to do this and passing it a couple of parameters to dynamically create the xml. Can’t seem to get anything back.

    I’ve created a “dummy” controller (doesn’t have a model) called ChartsController and it just has on action, index, which takes two parameters. So in my view, I’m doing this to try and get the xml back:

    so.addVariable(“data_file”, escape(“url(‘/charts/index/firsttitle/secondtitle’); ?>”));

    I also had to create a “blank” layout and that gets set at the top of the view. However, even with a blank layout, I still get the basic structure of the html page returned with the xml where the $content_for_layout gets displayed.

    Any recommendations?

  • teknoid

    @Jeremy Hicks

    I don’t have an example, but take a look at the File class in the CakePHP API.

    Basically the steps are:
    – Prepare the XML data
    – Write it to some file on your server
    – Point the amCharts path to that data file

    Hope that sets you on the right track…

  • majic3

    Great article, very informative

    I am blending this together with debuggable’s webscraping google analytics datasource. I have the charts working thanks to this article (displaying the wrong data – due to a issue displaying mismatched data )

    amcharts are cool work so well with flash too

  • teknoid

    @majic3

    Thanks, glad it was of some help. And yes, amCharts is a great package.

  • Pingback: Recent Links Tagged With "amcharts" - JabberTags()

  • There is a PHP tag in the javascript block that sets up the AmCharts that is missing the ‘php’ part. It reads:

    Since one normally takes for granted these things, I spent some time figuring out why the data was not showing.

  • @Y.O. Morales

    Thank you. I’ve fixed up the post. I guess you don’t have php short tags enabled, which is just another reminder that it is a good reason why one should not use them.

  • I also had to create a “blank” layout and that gets set at the top of the view.

%d bloggers like this: