Recently I began a collaboration with amCharts, writing some tutorials for their blog. This is my first contribution, and you can find the original post in amCharts blog.

http://blog.amcharts.com/2011/03/amcharts-javascript-tutorials-part-3.html

I hope you’ll enjoy my first tutorial about this great graphs library! And, of course, feedback is wellcomed!

In this tutorial we will enhance our previous example in order to parse dates. This will allow us to obtain date-based graphs displaying their data points using relative distance to each other and not placing them at regular spaces.

We will apply some modifications to our previous example from Part 2, so if you haven’t read that part, you should at least get the example source code that you can find at the end of the tutorial. Furthermore, you will need amCharts package. Once you’ll have it unzipped, you have to copy amcharts/javascript folder to your working directory (the rest of directories are not needed for this example).

Now we are ready. Let’s start!

HANDLING DATES IN OUR DATA SOURCE

The very first step we need to accomplish in this tutorial is to create a function that converts date strings into Date objects. This could be achieved with the following code, where we define a function which requires a string with YYYY-MM-DD date format as first parameter, and returns a Date object created from that date string:

// method which parses a date string in the format YYYY-MM-DD and creates a Date object
function parseDate(dateString) {
     // split the string get each field
     var dateArray = dateString.split("-");
     // now lets create a new Date instance, using year, month and day as parameters
     // month count starts with 0, so we have to convert the month number
     var date = new Date(Number(dateArray[0]), Number(dateArray[1]) - 1, Number(dateArray[2]));
     return date;
}

Next we have to locate the exact point in our previous example where this conversion should be done. If you remember, in Part 2 we set up a handler called parseCSV to manage data loaded via an XMLHttpRequest. This is the perfect place to convert the date strings into javascript Date objects (I have removed some lines of code in order to focus on the changes):

// method which parses csv data
function parseCSV(data){
     // ...
     // loop through all rows
     for (var i = 0; i < rows.length; i++){
          // this line helps to skip empty rows
          if (rows[i]) {
               // our columns are separated by comma
               var column = rows[i].split(",");
               // column is array now
               // first item is date
               var date = parseDate(column[0]);

     // ...

Now the data provider contains Date objects instead of strings. Next step is to configure the category axis of the chart to properly manage Date objects: this is achieved setting the property parseDates of the axis to true:

var catAxis = chart.categoryAxis;
catAxis.parseDates = true;

These lines have to be added to the createChart function, just like this:

// method which creates chart
function createChart(){
     // chart variable is declared in the top
     chart = new AmCharts.AmSerialChart();
     // here we tell the chart name of category
     // field in our data provider.
     // we called it "date" (look at parseCSV method)
     chart.categoryField = "date";
     // now we have to set up the category axis to parse dates
     var catAxis = chart.categoryAxis;
     catAxis.parseDates = true;

     // chart must have a graph
     var graph = new AmCharts.AmGraph();
     // graph should know at what field from data
     // provider it should get values.
     // let&#39;s assign value1 field for this graph
     graph.valueField = "value1";
     // and add graph to the chart
     chart.addGraph(graph);
     // &#39;chartdiv&#39; is id of a container
     // where our chart will be
     chart.write(&#39;chartdiv&#39;);
}

If we launch our HTML file in the browser, we should get the following result:

Hey, wait a moment! Our graph has changed! That’s because our data has different size time gaps between data points, and now amCharts is able to understand dates in our data, rendering them in their relative position.

If we want to draw a graph like the previous one (using regular intervals between data points), we have to set to true the property equalSpacing of the category Axis:

// now we have to set up the category axis to parse dates
var catAxis = chart.categoryAxis;
catAxis.parseDates = true;
catAxis.equalSpacing = true;

And now the resulting graph looks more like the one we got in Part 2 of this tutorial series, but now the labels on the category axis are displayed using a date format, instead of using directly the string from our data:

MAKING-UP OUR CHART

To finish this Part 3 of our amChart Javascript turorials, we will style-up our chart to get a fancier one. All the following code has to be added to the already defined createChart function.

First of all we will apply some general styles to the chart so we can set up margins, set a general color and add an initial animation:

// styles applied to the chart
// default general color used in the chart
chart.color = "#AAAAAA";
// length of the animation
chart.startDuration = 2;
// margins between graph and canvas border
chart.marginLeft = 15;
chart.marginRight = 80;
chart.marginBottom = 40;

Then we will style both axes. We will set our category axis to use bluish colors for the axis and grid lines:

// styles applied to the category axis
// color of the axis line
catAxis.axisColor = "#2d66bb";
// color of the grid lines
catAxis.gridColor = "#2d66bb";

To set up the value axis, we need an instance of ValueAxis, but we haven’t created one until now, so our first step is to get a fresh instance. Then, in a similar way as before, we will set our value axis using also bluish colors but this time we don’t want to show the grid lines, just the background colors. Finally, we add our new styled value axis to the chart:

// styles applied to value axis
// we haven&#39;t set up a value axis until now,
// so we create one and apply styles to it
var valAxis = new AmCharts.ValueAxis();
// we want to display the value axis on the right side
valAxis.position = "right";
// color of the axis line
valAxis.axisColor = "#2d66bb";
// as we set fillAlpha, and fillColor we don&#39;t want grid to be visible
valAxis.gridAlpha = 0;
// each second gap between grid lines will be filled with this color
valAxis.fillColor = "#2d66bb";
// fill alpha
valAxis.fillAlpha = 0.1;
// length of each dash
valAxis.dashLength = 3;
// and finally we add the value axis to the chart
chart.addValueAxis(valAxis);

Last step is to apply some styles to our graph line:

// styles applied to the graph line
// color of the graph line
graph.lineColor = "#3a81ec";
// thicknes of the graph line
graph.lineThickness = 2;
// show round bullets for each point
graph.bullet = "round";
// length of each dash
graph.dashLength = 1;

And the resulting chart should look like this one:

Here you have full source code as it should look like once all changes we have talked about in this tutorial have been applied:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>amCharts Example</title>
        <link rel="stylesheet" href="style.css" type="text/css">
        <script src="javascript/amcharts.js" type="text/javascript"></script>
        <script src="javascript/raphael.js" type="text/javascript"></script>
        <script type="text/javascript">
        // declaring variables
        var chart;
        var dataProvider;
        // this method called after all page contents are loaded
        window.onload = function() {
            createChart();
            loadCSV("data.txt");
        }
        // method which loads external data
        function loadCSV(file) {
            if (window.XMLHttpRequest) {
                // IE7+, Firefox, Chrome, Opera, Safari
                var request = new XMLHttpRequest();
            }
            else {
                // code for IE6, IE5
                var request = new ActiveXObject(&#39;Microsoft.XMLHTTP&#39;);
            }
            // load
            request.open(&#39;GET&#39;, file, false);
            request.send();
            parseCSV(request.responseText);
        }
          // method which parses a date string in the format YYYY-MM-DD and creates a Date object
          function parseDate(dateString) {
               // split the string get each field
               var dateArray = dateString.split("-");
               // now lets create a new Date instance, using year, month and day as parameters
               // month count starts with 0, so we have to convert the month number
               var date = new Date(Number(dateArray[0]), Number(dateArray[1]) - 1, Number(dateArray[2]));
               return date;
          }
        // method which parses csv data
        function parseCSV(data){
            //replace UNIX new line
            data = data.replace (/rn/g, "n");
            //replace MAC new lines
            data = data.replace (/r/g, "n");
            //split into rows
            var rows = data.split("n");
            // create array which will hold our data:
            dataProvider = [];
            // loop through all rows
            for (var i = 0; i < rows.length; i++){
                // this line helps to skip empty rows
                if (rows[i]) {
                    // our columns are separated by comma
                    var column = rows[i].split(",");
                    // column is array now
                    // first item is date
                    var date = parseDate(column[0]);
                    // second item is value of the second column
                    var value1 = column[1];
                    // third item is value of the fird column
                    var value2 = column[2];
                    // create object which contains all these items:
                    var dataObject = {date:date, value1:value1, value2:value2};
                    // add object to dataProvider array
                    dataProvider.push(dataObject);
                }
            }
            // set data provider to the chart
            chart.dataProvider = dataProvider;
            // this will force chart to rebuild using new data
            chart.invalidateData();
        }
        // method which creates chart
        function createChart(){
            // chart variable is declared in the top
            chart = new AmCharts.AmSerialChart();
            // here we tell the chart name of category
            // field in our data provider.
            // we called it "date" (look at parseCSV method)
            chart.categoryField = "date";
            // styles applied to the chart
            // default general color used in the chart
            chart.color = "#AAAAAA";
            // length of the animation
            chart.startDuration = 2;
            // margins between graph and canvas border
            chart.marginLeft = 15;
            chart.marginRight = 80;
            chart.marginBottom = 40;
            // now we have to set up the category axis to parse dates
            var catAxis = chart.categoryAxis;
            catAxis.parseDates = true;
            //catAxis.equalSpacing = true;
            // styles applied to the category axis
            // color of the axis line
            catAxis.axisColor = "#2d66bb";
            // color of the grid lines
            catAxis.gridColor = "#2d66bb";
            // styles applied to value axis
            // we haven&#39;t set up a value axis until now,
            // so we create one and apply styles to it
            var valAxis = new AmCharts.ValueAxis();
            // we want to display the value axis on the right side
            valAxis.position = "right";
            // color of the axis line
            valAxis.axisColor = "#2d66bb";
            // as we set fillAlpha, and fillColor we don&#39;t want grid to be visible
            valAxis.gridAlpha = 0;
            // each second gap between grid lines will be filled with this color
            valAxis.fillColor = "#2d66bb";
            // fill alpha
            valAxis.fillAlpha = 0.1;
            // length of each dash
            valAxis.dashLength = 3;
            // and finally we add the value axis to the chart
            chart.addValueAxis(valAxis);
            // chart must have a graph
            var graph = new AmCharts.AmGraph();
            // graph should know at what field from data
            // provider it should get values.
            // let&#39;s assign value1 field for this graph
            graph.valueField = "value1";
            // and add graph to the chart
            // styles applied to the graph line
            // color of the graph line
            graph.lineColor = "#3a81ec";
            // thicknes of the graph line
            graph.lineThickness = 2;
            // show round bullets for each point
            graph.bullet = "round";
            // length of each dash
            graph.dashLength = 1;
            chart.addGraph(graph);
            // &#39;chartdiv&#39; is id of a container
            // where our chart will be
            chart.write(&#39;chartdiv&#39;);
        }
        </script>
    </head>
    <body style="background-color:#EEEEEE">
        <div id="chartdiv" style="width:600px; height:400px; background-color:#FFFFFF"></div>
    </body>
</html>