The canvas tag offers raster image controls inside an HTML document and I've been experimenting with it over the last few days as a possibility of using it for chart controls. I've modified the excellent Chart by Emil Eklund to suit my own purposes. Redraw and smoother graphics have been added.

Introduction

There are a number of applications for charting controls, and this is realised by the web-industry as a wide range of charting programs and scripts are available. Out of interest, and for my cricket scoring project, I started to look into the options that are available. My needs, I thought, are fairly simple: I need a charting tool which will update on-the-fly as my data changes, it must also provide multiple graph types (i.e. line + stacked + bar) and it should look cool (web 2.0 and all that...).

A number of web-based technologies exist which lend themselves to charting options. The most obvious is Adobe's Flex with it's charting tool. The control over the graphs along with the slick animated transitions is perfect, assuming of course that you are willing to spend the money on it ($749.US), which I am not. However there are many other Flash based charting options available, many of which are free including FusionCharts and amCharts. Both are slick and offer a wide range of controls, but to get charts which will update on-the-fly you need to buy their expensive commercial products. SVG of course is another viable option and there are several implementations of SVG charts including Dojo's library. Unfortunately most of these look like Excel 97 charts. Then there is the implementations using the Canvas tag. Of those available, Emil Eklund's Chart appeared to be the closest to fitting the bill, but still lacking a few features I needed, so I present them here.

There are a number of decisions which I have made during the course of the modifications that should be explained. The most important of these is my decision to use the canvas element and not include support for SVG etc, which is actually in Emil Eklund's original software. While I realise that Canvas visuals can't be seen by the majority of internet users (IE users), support for the tag is growing, and it enjoys particularly good support in WebKit (due to the fact that it was introduced by Apple of course). Due to that fact that I plan to use this chart control for my cricket scoring software, I can say that I will specifically target WebKit. The reason behind this is I am interested in using Adobe Apollo to deploy the software as this not only gives a tightly controlled environment, but also offline storage abilities (I realise that Firefox 3 will offer this as well - but I fancy experimenting here...). Furthermore, I have not explicitly included support for animation in the chart as this is not something I want to spend time on right now. It is possible to animate that chart due to the redraw ability I've added, but as this redraws the whole chart for every frame, it's fairly slow. While I might add animation in future, it will likely be a ground up redesign rather than a modification of an existing script.

Usage

To include a chart on a web-page is a very simple process. First you need to download the source files which are available at the bottom of this page. Unzip the downloaded file and upload the files to the locations you wish on your web-server. There are a handful of files which must be included, and then a number of JavaScript functions which must be called in order to initialise the chart, set up the data and then draw it. The following code must be present in the HTML head tag:








In the body tag an element (mostly likely a div) will need to be present which will have the chart rendered into it. This div can be styled as required, with width, height, position etc. It must have an ID applied to the tag such that the chart can be created for that specific tag:

At this point you are now in a position to initialise a chart object, set it's default type and other global initialisation parameters
// Chart initialisation
chChart = new Chart('chart');

chChart.setDefaultType (CHART_AREA | CHART_STACKED);
chChart.setGridDensity (7, 8);
chChart.setVerticalRange (0, 35);
chChart.setHorizontalLabels (['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']);
Line by line:
  • 2. Initialise a chart object in the variable chChart
  • 4. Set the default chart type to be a stacked area chart
  • 5. Set the number of x-axis ticks (data points) to be 7, and the y-axis ticks to be 8
  • 6. Set the y-axis range to be 0 to 50
  • 7. Set the x-axis labels
Now the basics of the chart are in place, you can show data on the chart by adding series using the add method:
// Add data
chChart.add ('Spam', '#4040FF', [ 4, 5, 8, 12, 8, 4, 12 ]);
chChart.add ('Innocent', '#8080FF', [ 1, 2, 3, 4, 3, 4, 3 ]);
chChart.add ('Missed Spam', '#A5A5FF', [ 2, 3, 6, 5, 3, 4, 7 ]);
chChart.add ('False Positives', '#DEDEFF', [ 2, 3, 6, 5, 3, 4, 7 ]);
Finally now draw the graph on the page using the draw method:
// Draw chart
chChart.draw();
This results in a graph which looks like that shown below:

Examples

In the following section I present two examples of the types of charts that this script can draw, and some of the facilities that are available to the developer.

The first example is a chart which will read information from text boxes where you can input different values, and the chart will redraw on the page (which is the whole point of this). The information shown is a line chart of the number of runs scored by a sub-set of English batsmen during the 2007 world cup (statistics from How Stat). Increase their numbers if you want to make it look good...

N. Zealand Canada Kenya Ireland Sri Lanka Australia Bangladesh S. Africa W. Indies
I. Bell
A. Flintoff
P. Collingwood

The second example is the same as Emil Eklund's example, but now with nice graphics. Some of these nicer graphics will only be visible in Safari/WebKit, although the chart will draw just fine in Firefox and Opera. This is because Gecko does not support drop shadow on canvas elements. Hopefully it will for Firefox 3.

Download and license

The charting software presented here is freely available, under an MIT style license which is available with the downloaded files. Please make use of this as you wish, but I would be interested to know where and how it gets used. So please drop me a line if you do plan on using it. To get the software, simply download the ZIP file below and unzip it to your computer/server.

Enjoy!

Article image

API

  • object void:Chart ( string ) - chart object
    • parameter string:el
      Element ID to be made into a Chart
    • method void:draw ()
      Draw the chart into the selected HTML element
    • method void:setDefaultType ( flag )
      Set the chart default type
      • parameter flag:
        • CHART_LINE
        • CHART_AREA
        • CHART_BAR
        • CHART_STACKED
    • method void:setGridDensity ( int, int )
      Set the number of x and y axis ticks
      • parameter int:horizontal
      • parameter int:vertical
    • method void:setVerticalRange ( int, int )
      Set y-axis range
      • parameter int:min
      • parameter int:max
    • method void:setHorizontalLabels ( array )
      Set the x-axis labels
      • parameter array:labels
    • method void:setLabelPrecision ( int )
      Set the rounding precision to be used
      • parameter array:precision
    • method void:setShowLegend ( boolean )
      Show the legend or not
      • parameter boolean:b
    • method void:setBarWidth ( int )
      Set the width of an individual bar in px
      • parameter int:width
    • method void:setBarDistance ( int )
      Separation between bars in px
      • parameter int:distance
    • method void:setStyle ( function, function, string )
      Set the style of an element with the name of the value of string, using anon functions
      • parameter function:fn
        Anonymous function (passed a canvas variable) which can be used to set an elements style
      • parameter function:fnClear
        Anonymous function (passed a canvas variable) which must clear the style set using the first parameter
      • parameter string:sSeries
        The name of the series to be modified
    • method void:setBorder ( string, int, string )
      Set the border of an element - applies to bar chart series only
      • parameter string:sSeries
        The name of the series to be modified
      • parameter int:iWidth
        Width of the border to be applied
      • parameter string:sColour
        Colour of the border, in hex (with leading hash) or CSS defined
    • method void:setGrid ( string, int )
      Set the style of the background grid in the chart
      • parameter string:sColour
        Colour of the grid lines, in hex (with leading hash) or CSS defined
      • parameter int:iSize
        Width of the chart grid to be applied
    • method void:setBackground ( string )
      Set the style of the background grid in the chart
      • parameter string:sColour
        Background colour, in hex (with leading hash) or CSS defined
    • method void:setBorderColour ( string )
      Set the colour of the border surrounding the chart
      • parameter string:sColour
        Border colour, in hex (with leading hash) or CSS defined
    • method void:add ( string, string, array, flags, function, function )
      Add a new series to the chart
      • parameter string:label
        Label of the series, for the key
      • parameter string:color
        Colour the series data will be drawn with, in hex (with leading hash) or CSS defined
      • parameter array:values
        The list of values that are to be applied
      • parameter flags:flags
        Set the series chart type
        • CHART_LINE
        • CHART_AREA
        • CHART_BAR
        • CHART_STACKED
      • parameter function:fnStyle
        Anonymous function (passed a canvas variable) which can be used to set an elements style
      • parameter function:fnStyleClear
        Anonymous function (passed a canvas variable) which must clear the style set using the first parameter
    • method void:changeSeriesValue ( string, int|array[, int|array] )
      Change the values of a particular series on-the-fly using either a single value for all entries, changing a specific entry at a specific index, changing several entries at different indexes or changing all entries
      • parameter string:sSeriesName
        Border colour, in hex (with leading hash) or CSS defined
      • parameter int|array:mValues
        New values to be changed to
        • int && mIndexes not passed - all values in series set to mValues
        • int && mIndexes passed as int - value of index mIndexes is changed
        • array && mIndexes not passed - full range of values changed in series
        • array && mIndexes passed as array - value of indexes mIndexes changed sequentially
      • parameter string:mIndexes - optional
        Indexes to change