Tweet about RGraph
Follow for HTML5 news
Bookmark and share:

# RGraph: HTML5 canvas graph library - Documentation

The following documentation is available:

#### Chart types

- Bar chart
- Bi-polar chart
- Donut chart
- Funnel chart
- Gantt chart
- Horizontal bar chart
- Horizontal progress bar
- LED Grid
- Line chart
- Meter
- Odometer
- Pie chart
- Rose chart
- Radial scatter chart
- Scatter graph
- Traditional radar chart
- Vertical progress bar

#### Features

- Updating your graphs dynamically
- Retrieving a PNG of your graph
- DOMContentLoaded example
- Custom RGraph events
- Adjusting your graphs interactively
- Using tooltips
- Resizing your graphs
- Microsoft Internet Explorer support
- Asynchronous processing
- Zooming your graphs
- Annotating your graphs
- Combining charts
- Integrating RGraph with external libraries (ModalDialog)
- Animating your graphs
- Available CSS classes
- About canvas color definitions
- Context menus
- Miscellaneous documentation
- Common issues
- API Documentation

#### Miscellaneous

- Licensing FAQs
- The changelog
- Backwards compatibility breaks

#### On this page:

- Benefits of HTML5 canvas graphs
- Browser support
- Improving the performance of your graphs
- Implementing RGraph
- Suggested structure for RGraph
- Integration with server side scripting
  - Integration with PHP & MySQL
  - Making AJAX requests
- Support forum

## Benefits of HTML5 canvas graphs

HTML5 introduces a new HTML element - the CANVAS tag. This tag allows for two dimensional drawing easily using Javascript. This makes it perfect for producing graphs. Because Javascript runs on your users computer, none of the stress on your server normally associated with producing graphs is incurred. Not only that but because of the greater processing power that is typically available on users' computers, they will be much faster. And, because the code can be both compressed (for example if you're using Apache, mod_gzip will do this automatically for you) and cached, bandwidth usage can be massively reduced. This makes it economically attractive to employ, (ie it can save you money...).

Imagine, you are creating 100,000 graphs a day and the data is such that the resulting graphs cannot be cached. With the RGraph library you can reduce that figure to zero. All the processing and graph creation is done by each individual client, much like rendering the HTML you send to them. So you don't have to send any images, you simply send them the Javascript libraries once. So, much lower bandwidth bills and far less strain on your webserver.

And if that wasn't enough, because the graphs are created using Javascript, they will work offline if you view a .html page on your own PC. Download the archive and see! Useful if you need to do a presentation for example and want to use the same graph(s) as your website.

- Cross browser support.
- 17 Different base graph types (Examples).
- Graphs work on and off-line.
- Interactive features.

- Graphs are created on the client - no server overhead.
- Very easy setup (see Implementing RGraph).
- Fully documented.
- Very easy to learn.

## Browser support

Since the graphs are produced using HTML5 features (the new canvas tag), client support is currently:

- Mozilla Firefox 3.0+
- Google Chrome 1+
- Apple Safari 3+
- Opera 9.5+
- Microsoft Internet Explorer 8+ (see note)
- iPhone (text support from iOS v4+)
- iPad (text support from iOS v4.2+)

The HTML5 canvas tag is part of the HTML5 specification, and all of the above browsers have some sort of support for it.

Canvas & Microsoft Internet Explorer (MSIE)
Microsoft Internet Explorer 8 doesn't natively support the HTML5 <canvas> tag. To support MSIE 8 you will need to use either Google Chrome Frame or ExCanvas from Google (which is included in the RGraph archive). Read more about Internet Explorer compatibility here.

Starting with preview 3 Microsoft Internet Explorer 9 has full support for <canvas>. You can view some screenshots here. MSIE 6 and 7 are supported by way of Google Chrome Frame.

RGraph and older browsers
Older browsers (eg Chrome 1, Firefox 3, Safari 3, Opera 9.5) are supported, however if they don't support the canvas shadow or text APIs, these will naturally be unavailable. Earlier versions of these browsers may work, but are untested.

## Improving the performance of your graphs

Although performance is excellent, (traditionally your webserver has been producing all of your graphs, and now the client produces them, and typically only one at a time), you may still want to tune RGraph further. The biggest thing you can do is use compression, which reduces the initial download time of the libraries, but there are a number of things you can do:

- Compression
  HTTP compression can dramatically reduce your bandwidth bills and increase the speed of your website. The RGraph.common.core.js file for example used to be over 100k, but with compression this was reduced to around 17k. Less than a fifth of the original size! If you do only one thing to aid performance, then it should be this.

  To achieve this with Apache you have a few options:

  - You can use the Apache module mod_gzip which compresses the libraries on the fly.
  - You can compress the libraries manually using the gzip command, rename them to remove the .gz suffix and add the header using an Apache directive (eg AddEncoding gzip .js). If you have some sort of release process/script, it would make sense to add this to it to automate the procedure.

- Minification
  Minification reduces the size of the library before compression takes effect, removing unnecessary spaces and comments etc. A combination of minification and compression will give superb results. For example, before being split up into seperate files, minification combined with compression reduced the common library from over 100k to roughly 10k (!). There is a PHP shell script that you can use to minify the libraries in the scripts directory.

  You can get pre-minified versions of the libraries here.

- Pre-emptive caching
  Slightly different to caching itself, is pre-emptive caching. This involves downloading the libraries before the page that requires them is shown. This way, they're already in the users browser cache and the graph will subsequently appear to be much much quicker. An example of this would be having the library included at the bottom of your index page of your website (optionally with the defer="defer" attribute). The script can be downloaded at will because the page doesn't actually use it, but for subsequent pages it will already be in the users browser cache.

- Caching
  Since the libraries you're using won't change that often, you can set distant Expires: headers on them, or appropriate Cache-Control: headers, and the client will not even have to contact your server for it. When you want to make sure the library is re-downloaded (eg. you update the library), then simply change the filename.

- Script tag placement
  According to Yahoo! guidelines placing the <SCRIPT> tag at the bottom of the page can increase the percieved load time. If you do this, then your graphs should be created in the window.onload event, otherwise the browser may try to create them without the library having been loaded, and will therefore subsequently fail.

  You should also consider the effect that this has when your page is rather weighty. If the page is weighty there will be a small delay before the onload event fires, and therefore creates the graph. This might not be so bad if the graph is not immediately visible, however if it is then you should carefully consider using the onload event. You may wish to load the library in the page header, define the canvas tag and then immediately define the javascript that creates the graph. This way the graph will be created and shown, and then the rest of the page loads. The end result is that your graph appears to be faster.

  Between the onload event, asychronous Javascript and careful tag placement, you will need to experiment to get the right result for you.
- Document structure
  The structure of your document can have a significant impact on how fast your graphs are displayed. If, for example, you use tables for layout, this can delay the display of elements that are affected by the size of the table. Where possible, you should consider trying to convert your layout to DIVs. An example of this is the front page of this website. The graphs were right aligned using a table as a container. This caused a visible delay when showing them. In this case it was a simple matter to convert the page to use DIVs, and the page subsequently displays much faster.

- Creating your graphs asynchronously
  Where possible, you may wish to create your graphs asynchronously. This allows the browser to continue rendering the page immediately after getting to the code that creates the graph. This might not be perceptible if you don't have a lot of graphs, or your page is small. You can read a little more about this and see example code here.

  Note that recent releases of Google Chrome (from a dev release of version 4) have had an issue with creating graphs asynchronously, which presents itself by not drawing text sometimes (it's not consistent). Simply not using asynchronous graph production in this case resolves the issue.
- DOMContentLoaded event
  Using this event can speed up the display of your graphs signifcantly compared to the more well known onload event. It is supported by Chrome, Gecko based browsers (ie Firefox), Safari, Opera and Internet Explorer 9. This event fires when the structure of the page is loaded, but not necessarily the images or CSS. This means that if your page is laden with images, this event will fire before the onload event, thus creating your graphs quicker. The effect can be very noticeable.

      function addListener(func)
      {
          if(window.addEventListener) {
              window.addEventListener('DOMContentLoaded', func, false);
          } else {
              document.attachEvent("onDOMContentLoaded", func);
          }
      }

  You can read more about the DOMContentLoaded event on the Mozilla site, here, and the Microsoft site here. There's an example here.

- AJAX requests
  If you can take advantage of AJAX, you can use this method to retrieve data from your server. If, for example, you have a graph that shows ongoing information, instead of simply refreshing the entire page, you could use an AJAX request to just retrieve the data that you want and update the graph that way. This reduces the amount of data needed to be transferred, thus reducing the bandwidth used, and will be quicker than a full page refresh, particularly if your page is weighty. There's a simple AJAX function that you can use below.

- Combining libraries
  If your performance requirements are extreme, then you may wish to consider combining the libraries into a single file. This won't save on the size of the individual libraries, but will save on the headers that are sent as part of the response. If a typical response sends 500 bytes worth of headers, and you send four graph libraries, then combining the libraries would save 1500 bytes. Multiple factors need to be considered though, including things like caching, which can circumvent the unneccessary repeated downloading of the libraries.

  Another effect of combining libraries is reducing the amount of HTTP connections needed to retrieve them. Most browsers have a limit on how many connections they can create simultaneously, so if they're not being used to retrieve your graph libraries, they can be used for something else. Reducing the number of HTTP connections also eliminates the time spent setting up those connections.

A reasonable performance strategy

Although there's a lot you can do in regards to performance, a few of the points here will suffice for most websites:

- Compression
- Minification
- Pre-emptive caching
- Caching

The number one thing you should do is compress your libraries. This has multiple benefits and provides by far the most gain, effectively for free. Secondly, use the minified libraries. Since you can download them here, you might as well use them. Then we have pre-emptive caching. Since most websites won't show graphs on the front page or will have a login page that is shown before any graphs, this effectively eliminates the graph library download. And lastly caching should be done as a matter of course. There's no reason to keep downloading the same library so even caching for only 30 minutes (or the duration of an average visit to your website) will produce results.

## Implementing RGraph

Getting RGraph up and running is very easy and consists of three steps. If you're having trouble I suggest you get hold of a copy of Firefox along with Firebug - its Javascript error console will make debugging your issue much easier. Many problems are down to a library not having been included or not using the onload event when you need to. You might also benefit from using the Web Developer toolbar for Firefox. This allows you to easily disable caching, thus eliminating any problems that that causes. You could equally use the Chrome developer tools (CTRL+SHIFT+J), optionally in docked mode, which also provides a good quality Javascript console.

1. Include the libraries (put this in your documents <HEAD>):

       <script src="RGraph.common.core.js"></script>

       <script src="RGraph.common.adjusting.js"></script> <!-- Just needed for adjusting -->
       <script src="RGraph.common.annotate.js"></script>  <!-- Just needed for annotating -->
       <script src="RGraph.common.context.js"></script>   <!-- Just needed for context menus -->
       <script src="RGraph.common.resizing.js"></script>  <!-- Just needed for resizing -->
       <script src="RGraph.common.tooltips.js"></script>  <!-- Just needed for tooltips -->
       <script src="RGraph.common.zoom.js"></script>      <!-- Just needed for zoom -->

       <script src="RGraph.bar.js"></script>              <!-- Just needed for bar graphs -->
       <script src="RGraph.bipolar.js"></script>          <!-- Just needed for bi-polar graphs -->
       <script src="RGraph.funnel.js"></script>           <!-- Just needed for funnel charts -->
       <script src="RGraph.gantt.js"></script>            <!-- Just needed for gantt charts -->
       <script src="RGraph.hbar.js"></script>             <!-- Just needed for horizontal bar charts -->
       <script src="RGraph.hprogress.js"></script>        <!-- Just needed for horizontal progress bars -->
       <script src="RGraph.led.js"></script>              <!-- Just needed for LED charts -->
       <script src="RGraph.line.js"></script>             <!-- Just needed for line graphs -->
       <script src="RGraph.meter.js"></script>            <!-- Just needed for meter charts -->
       <script src="RGraph.odo.js"></script>              <!-- Just needed for odometers -->
       <script src="RGraph.pie.js"></script>              <!-- Just needed for pie AND donut charts -->
       <script src="RGraph.rose.js"></script>             <!-- Just needed for rose charts -->
       <script src="RGraph.rscatter.js"></script>         <!-- Just needed for rscatter charts -->
       <script src="RGraph.scatter.js"></script>          <!-- Just needed for scatter graphs -->
       <script src="RGraph.tradar.js"></script>           <!-- Just needed for traditional radar charts -->
       <script src="RGraph.vprogress.js"></script>        <!-- Just needed for vertical progress bars -->

2. Add the canvas tag (put it where you want the graph to appear):

       <canvas id="myCanvas" width="600" height="250">[No canvas support]</canvas>

3. Create the graph (since it is using the onload event, you can put this anywhere):

       <script>
           window.onload = function ()
           {
               var data = [280, 45, 133, 166, 84, 259, 266, 960, 219, 311, 67, 89];

               var bar = new RGraph.Bar('myCanvas', data);
               bar.Set('chart.labels', ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']);
               bar.Set('chart.gutter', 35);
               bar.Draw();
           }
       </script>

There's also a very basic example of using RGraph, that does very little. It can be helpful to illustrate how you can get RGraph up and running.

#### Common library split (17th April 2010)

The common library has now been split into separate files. This was because the single common library had become far too large. If you don't use any of the dynamic features, then you still need to change your code, as RGraph.common.js is now called RGraph.common.core.js.

## Suggested structure for RGraph

The suggested layout structure for the RGraph libraries is shown on the right. The www.example.com folder represents the root/top level of your website with the javascript directory beneath that. The css and images folders are shown for illustrative purposes only. If you follow this layout then your URLs to the RGraph libraries would be:

/javascript/rgraph/RGraph.common.core.js
/javascript/rgraph/RGraph.bar.js
etc

By using this structure you make RGraph easy to update should you need to, and also keep all the RGraph libraries in one, easy to find, place.

## Integration with server side scripting

This is a very easy process, as easy as sending content to the browser. All you need to do is make the data variable contain the data you want to be displayed. Eg:

    <script src="RGraph.common.core.js"></script>
    <script src="RGraph.line.js"></script>

    <canvas id="myCanvasTag" width="600" height="200">[No canvas support]</canvas>

    <script>
        var data = [78,16,26,23,25,51,34,64,84,84];
        var line = new RGraph.Line("myCanvasTag", data);
        line.Set("chart.labels", ["Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov"]);
        line.Draw();
    </script>

To get the above using PHP you could do this:

    <?php
        // This simply makes a string out of the array of data
        $myData = join(',', array(78,16,26,23,25,51,34,64,84,84));

        // This prints out the required HTML markup
        print('<script src="RGraph.common.core.js"></script>' . "\n");
        print('<script src="RGraph.line.js"></script>' . "\n\n");
        print('<canvas id="myCanvasTag" width="600" height="200">[No canvas support]</canvas>' . "\n\n");
        print('<script>' . "\n");
        print('    var data = [' . $myData . '];' . "\n");
        print('    var line = new RGraph.Line("myCanvasTag", data);' . "\n");
        print('    line.Set("chart.labels", ["Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov"]);' . "\n");
        print('    line.Draw();' . "\n");
        print('</script>');
    ?>

Strictly speaking the var isn't necessary, however if you put the code inside a function (like window.onload), it's probably best to do so as using var will make the variable local, and not global. So doing so will help prevent naming clashes.

#### Integration with PHP & MySQL

This is a simple matter of formatting what you get back from MySQL into a string, as the MySQL dump and PHP code below shows (it's based on a database called RGraph_example):

    #
    # Table structure for table `daily_statistics`
    #

    CREATE TABLE `daily_statistics` (
      `st_day` char(9) NOT NULL,
      `st_statistics` tinyint(4) NOT NULL,
      UNIQUE KEY `st_day` (`st_day`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1;

    #
    # Dumping data for table `daily_statistics`
    #

    INSERT INTO `daily_statistics` VALUES ('Mon', 124);
    INSERT INTO `daily_statistics` VALUES ('Tue', 95);
    INSERT INTO `daily_statistics` VALUES ('Wed', 64);
    INSERT INTO `daily_statistics` VALUES ('Thu', 94);
    INSERT INTO `daily_statistics` VALUES ('Fri', 75);
    INSERT INTO `daily_statistics` VALUES ('Sat', 98);
    INSERT INTO `daily_statistics` VALUES ('Sun', 84);

    <?php
        /**
        * Change these to your own credentials
        */
        $hostname = "localhost";
        $username = "root";
        $password = "PASSWORD";
        $database = "RGraph_example";

        $connection = mysql_connect($hostname, $username, $password) OR die('Could not connect to MySQL: ' . mysql_error());
        mysql_select_db($database);

        $result = mysql_query("SELECT st_day, st_statistics FROM daily_statistics");
        if ($result) {

            $labels = array();
            $data   = array();

            while ($row = mysql_fetch_assoc($result)) {
                $labels[] = $row["st_day"];
                $data[]   = $row["st_statistics"];
            }

            // Now you can aggregate all the data into one string
            $data_string = "[" . join(", ", $data) . "]";
            $labels_string = "['" . join("', '", $labels) . "']";
        } else {
            print('MySQL query failed with error: ' . mysql_error());
        }
    ?>
    <html>
    <head>

        <!-- Don't forget to update these paths -->

        <script src="libraries/RGraph.common.core.js" ></script>
        <script src="libraries/RGraph.line.js" ></script>

    </head>
    <body>

        <canvas id="cvs" width="600" height="250">[No canvas support]</canvas>
        <script>
            graph = new RGraph.Line('cvs', <?php print($data_string) ?>);
            graph.Set('chart.background.grid.autofit', true);
            graph.Set('chart.gutter', 17);
            graph.Set('chart.hmargin', 10);
            graph.Set('chart.tickmarks', 'endcircle');
            graph.Set('chart.labels', <?php print($labels_string) ?>);

            graph.context.translate(12, 0);

            graph.Draw();
        </script>

    </body>
    </html>

This PHP code provides the data in two strings - $labels_string and $data_string. These variables are then used in the RGraph code to provide the data and the labels.

Remember:

- Change the database hostname/username/password/database to match your own.
- Ensure you have the correct paths to the RGraph libraries.

#### Making AJAX requests

Note: It is important that you're careful with types when making AJAX requests. Since the response is initially a string, and your AJAX function/library may not do conversions for you, you may need to convert these strings to numbers. To do this you can use the Number() or parseInt() functions. For example:

    <script>
        num = Number('23');
        num = parseInt('43');
    </script>

Here is a simple function that you could use to get data from your server using AJAX:

    <script>
        /**
        * Makes an AJAX call. It calls the given callback (a function) when ready
        *
        * @param string   url      The URL to retrieve
        * @param function callback A function object that is called when the response is ready, there's an example below
        *                          called "myCallback".
        */
        function AjaxCall (url, callback)
        {
            // Mozilla, Safari, ...
            if (window.XMLHttpRequest) {
                var httpRequest = new XMLHttpRequest();

            // MSIE
            } else if (window.ActiveXObject) {
                var httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
            }

            httpRequest.onreadystatechange = callback;

            httpRequest.open('GET', url, true);
            httpRequest.send();
        }

        /**
        * This sample callback function is called when the data is ready (readyState=4)
        */
        function myCallback ()
        {
            if (this.readyState == 4 && this.status == 200) {
                // Everything is good, the response is received
                alert(this.responseText);
            }
        }
    </script>

And you would use it like this:

    <script>
        AjaxCall('http://www.example.com/getSomething.php', myCallback);
    </script>

There's an example here that shows updating your graph dynamically.

## Support forum

Subscribe to RGraph support
Email:
Visit this group

Support is available via a Google Groups forum. If you think that the issue you have is common, try the issues page first, and then try searching the forum in case your question has been answered previously. If that all yields nothing, post a question to the forum.

If you want to keep up-to-date on RGraph, then subscribe to the group, as I post update notifications here. You can also follow me on Twitter. I post update notifications here along with HTML5 related news.