About
RGraph is a JavaScript charts library based on HTML5 SVG and canvas. RGraph is mature (over 15 years old) and has a wealth of features making it an ideal choice to show charts on your website.

More »

 

License
RGraph can be used for free under the GPL or if that doesn't suit your situation there's an inexpensive (£99) commercial license available.

More »

 

Download
Get the latest version of RGraph (version 6.17) from the download page. There's also older versions available, minified files and links to cdnjs.com hosted libraries.

More »

Integration with server-side scripting

This is an easy process, as easy as sending html to the browser. All you need to do is make the data variable (as in the example below) contain the data you want to be displayed.

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

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

<script>
    data = [78,16,26,23,25,51,34,64,84,84];

    line = new RGraph.Line({
        id: "cvs",
        data: data,
        options: {
            xaxisLabels: ["Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov"]
        }
    }).draw();
</script>

To get the above using php you could do this:

<?php
    // Makes the code a bit clearer
    define('LF', "\n");
    
    // This 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>' . LF);
    print('<script src="RGraph.line.js"></script>' . LF);
    print('<canvas id="cvs" width="600" height="200">[No canvas support]</canvas>' . LF . LF);
    print('<script>' . LF);
    print('    data = [' . $myData . '];' . LF . LF);
    print('    line = new RGraph.Line({' . LF);
    print('        id: "cvs",' . LF);
    print('        data: data,' . LF);
    print('        options: {' . LF);
    print('            xaxisLabels: ["Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov"],' . LF);
    print('        }' . LF);
    print('    }).draw();' . LF);
    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 use it as the var keyword will make the variable local, and not global. So doing that will help prevent naming clashes. An svg version of the above code is shown below:

SVG
<?php
    // Makes the code a bit clearer
    define('LF', "\n");
    
    // This 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.svg.common.core.js"></script>' . LF);
    print('<script src="RGraph.svg.line.js"></script>' . LF);
    print('<div style="width: 750px; height: 300px" id="cc"></div>' . LF . LF);
    print('<script>' . LF);
    print('    data = [' . $myData . '];' . LF . LF);
    print('    line = new RGraph.SVG.Line({' . LF);
    print('        id: "cc",' . LF);
    print('        data: data,' . LF);
    print('        options: {' . LF);
    print('            xaxisLabels: ["Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov"],' . LF);
    print('        }' . LF);
    print('    }).draw();' . LF);
    print('</script>');
?>

Integration with PHP and MySQL using the MySQL extension

This is a 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_database):

#
# 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);
CANVAS
<?php
    //
    // Change these to your own credentials
    //
    $hostname = "localhost";
    $username = "root";
    $password = "PASSWORD";
    $database = "RGraph_example_database";
    
    $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) . "]";         // [124,95,64,94,75,98,84]
        $labels_string = "['" . join("', '", $labels) . "']"; // ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
    } else {
        print('MySQL query failed with error: ' . mysql_error());
    }
?>
<html>
<head>

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

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

</head>
<body>
    
    <canvas id="cvs" width="600" height="250">[No canvas support]</canvas>
    <script>
        chart = new RGraph.Line({
            id: 'cvs',
            data: <?php print($data_string) ?>,
            options: {
                marginLeft: 35,
                marginRight: 5,
                marginInner: 10,
                tickmarksStyle: 'endcircle',
                xaxisLabels: <?php print($labels_string) ?>
            }
        }).draw()
    </script>

</body>
</html>

This php code provides the data in two strings - $labels_string and $data_string. These two variables are then used in the RGraph code to provide the data and the labels. Here's an svg version of the code:

SVG
<?php
    //
    // Change these to your own credentials
    //
    $hostname = "localhost";
    $username = "root";
    $password = "PASSWORD";
    $database = "RGraph_example_database";
    
    $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) . "]";         // [124,95,64,94,75,98,84]
        $labels_string = "['" . join("', '", $labels) . "']"; // ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
    } else {
        print('MySQL query failed with error: ' . mysql_error());
    }
?>
<html>
<head>

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

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

</head>
<body>
    
    <div style="width: 750px; height: 300px" id="cc"></div>

    <script>
        chart = new RGraph.SVG.Line({
            id: 'cc',
            data: <?php print($data_string) ?>,
            options: {
                marginLeft: 35,
                marginRight: 5,
                marginInner: 10,
                tickmarksStyle: 'endcircle',
                xaxisLabels: <?php print($labels_string) ?>
            }
        }).draw();
    </script>

</body>
</html>

Remember:

Integration with PHP and MySQL using the MySQLi extension

Here's a similar example to the above but using the up-to-date mysqli php extension instead of the older mysql php extension

it uses the same table structure, data and query as above so the only thing that has changed is the mysql extension.

#
# 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);
CANVAS
<?php
    $hostname = "localhost";
    $username = "root";
    $password = "PASSWORD";
    $database = "RGraph_example_database";
    
    // Create the PHP MySQLi object
    $mysqli = new MySQLi($hostname, $username, $password, $database);

    // Check for any connection errors
    if ($mysqli->connect_errno) {
        echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
    }


    // Make the query
    $result = $mysqli->query("SELECT st_day, st_statistics FROM daily_statistics");

    if ($result) {
        
        $labels = array();
        $data   = array();
    
        $result->data_seek(0);
        while ($row = $result->fetch_assoc()) {
            $labels[] = $row["st_day"];
            $data[]   = $row["st_statistics"];
        }

        // Now you can aggregate all the data into one string
        $data_string = "[" . join(", ", $data) . "]";         // [124,95,64,94,75,98,84]
        $labels_string = "['" . join("', '", $labels) . "']"; // ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
    } else {
        print('MySQL query failed with error: ' . $mysqli->error);
    }
?>
<html>
<head>

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

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

</head>
<body>
    
    <canvas id="cvs" width="600" height="250">[No canvas support]</canvas>
    <script>
        chart = new RGraph.Line({
            id: 'cvs',
            data: <?php print($data_string) ?>,
            options: {
                marginLeft: 35,
                marginRight: 5,
                marginInner: 10,
                tickmarksStyle: 'endcircle',
                xaxisLabels: <?php print($labels_string) ?>
            }
        }).draw()
    </script>

</body>
</html>
SVG
<?php
    $hostname = "localhost";
    $username = "root";
    $password = "PASSWORD";
    $database = "RGraph_example_database";
    
    // Create the PHP MySQLi object
    $mysqli = new MySQLi($hostname, $username, $password, $database);

    // Check for any connection errors
    if ($mysqli->connect_errno) {
        echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
    }


    // Make the query
    $result = $mysqli->query("SELECT st_day, st_statistics FROM daily_statistics");

    if ($result) {
        
        $labels = array();
        $data   = array();
    
        $result->data_seek(0);
        while ($row = $result->fetch_assoc()) {
            $labels[] = $row["st_day"];
            $data[]   = $row["st_statistics"];
        }

        // Now you can aggregate all the data into one string
        $data_string = "[" . join(", ", $data) . "]";         // [124,95,64,94,75,98,84]
        $labels_string = "['" . join("', '", $labels) . "']"; // ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
    } else {
        print('MySQL query failed with error: ' . $mysqli->error);
    }
?>
<html>
<head>

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

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

</head>
<body>
    
    <div style="width: 700px; height: 300px" id="cc"></div>
    
    <script>
        chart = new RGraph.SVG.Line({
            id: 'cc',
            data: <?php print($data_string) ?>,
            options: {
                marginLeft: 35,
                marginRight: 5,
                marginInner: 10,
                tickmarksStyle: 'endcircle',
                xaxisLabels: <?php print($labels_string) ?>
            }
        }).draw()
    </script>

</body>
</html>

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

Remember:

Integration with PHP and MySQL using the PDO extension

Here's a similar example to the above but using the up-to-date pdo php extension instead of the older mysql php extension

It uses the same table structure, data and query as above so the only thing that has changed is the mysql extension.

#
# 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);
CANVAS
<?php

    $db = new PDO(
        'mysql:host=localhost;dbname=RGraph_example_database;charset=utf8',
        'root',
        'PASSWORD'
    );

    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    
    try {
        $labels = array();
        $data   = array();

        $result = $db->query('SELECT st_day, st_statistics FROM daily_statistics');
        $rows = $result->fetchAll(PDO::FETCH_ASSOC);
    
        // No need to check the result because we're using exceptions for
        // error handling
    
        foreach ($rows as $r) {
            $labels[] = $r["st_day"];
            $data[]   = $r["st_statistics"];
        }
    
        // Now you can aggregate all the data into one string
        $data_string = "[" . join(", ", $data) . "]";         // [124,95,64,94,75,98,84]
        $labels_string = "['" . join("', '", $labels) . "']"; // ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
    
    } catch(PDOException $e) {
        
        // Show a user friendly message
        echo "An Error occured!";
        
        // log($e->getMessage());
    }
?>
<html>
<head>

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

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

</head>
<body>
    
    <canvas width="600" height="250" id="cvs"></canvas>
    
    <script>
        chart = new RGraph.Line({
            id: 'cvs',
            data: <?php print($data_string) ?>,
            options: {
                marginLeft: 35,
                marginRight: 5,
                marginInner: 10,
                tickmarksStyle: 'endcircle',
                xaxisLabels: <?php print($labels_string) ?>
            }
        }).draw()
    </script>

</body>
</html>
SVG
<?php

    $db = new PDO(
        'mysql:host=localhost;dbname=RGraph_example_database;charset=utf8',
        'root',
        'PASSWORD'
    );

    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    
    try {
        $labels = array();
        $data   = array();

        $result = $db->query('SELECT st_day, st_statistics FROM daily_statistics');
        $rows = $result->fetchAll(PDO::FETCH_ASSOC);
    
        // No need to check the result because we're using exceptions for
        // error handling
    
        foreach ($rows as $r) {
            $labels[] = $r["st_day"];
            $data[]   = $r["st_statistics"];
        }
    
        // Now you can aggregate all the data into one string
        $data_string = "[" . join(", ", $data) . "]";         // [124,95,64,94,75,98,84]
        $labels_string = "['" . join("', '", $labels) . "']"; // ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
    
    } catch(PDOException $e) {
        
        // Show a user friendly message
        echo "An Error occured!";
        
        // log($e->getMessage());
    }
?>
<html>
<head>

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

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

</head>
<body>
    
    <div style="width: 700px; height: 300px" id="cc"></div>
    
    <script>
        chart = new RGraph.SVG.Line({
            id: 'cc',
            data: <?php print($data_string) ?>,
            options: {
                marginLeft: 35,
                marginRight: 5,
                marginInner: 10,
                tickmarksStyle: 'endcircle',
                xaxisLabels: <?php print($labels_string) ?>
            }
        }).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:

Making AJAX requests

Warning
It is important that you're careful with types when making ajax requests. Since the response is initially text and your ajax function/library may not do conversions for you, you may need to convert this text to numbers. To do this you can use the Number or parseInt functions. For example:
<script>
    num = Number('23');
    num = parseInt('43');
</script>

A simple function for making ajax requests is now included in the RGraph common library:

<script>
    //
    // This callback function is called when the data is ready. As of April 2012 you don't
    // need to check the readyState or status - they're checked for you.
    //
    RGraph.AJAX('http://www.example.com/getdata.php', function ()
    {
        alert(this.responseText);
    });

</script>

There's an example here that shows updating your chart dynamically and a more complete example of fetching data with AJAX here. There are also basic examples in the download archive that maybe worth looking at.

The June 2013 release added a few new ajax functions that may help you when dealing with type issues (ie strings vs numbers). You could also use jquery to fetch data from your server.

There's a documentation page here which tells you about the new ajax functions.

Saving the chart as an image on the server

RGraph runs in the browser and as it's html5 canvas/svg based there are no images involved.

You can however save the chart as an image on the server when using the canvas libraries by using jquery and a little server side scripting.

Here's a user submitted example using php:

Here's the javascript that posts the canvas to the server just after drawing the chart:

<script>
    //
    // The toDataURL() is a standard canvas method. Assume that the myChart variable is your RGraph object.
    //
    image_data = myChart.canvas.toDataURL("image/png");
    $.post("save_chart.php", { src: image_data } );
</script>

And here's the server side php code that takes the data and writes it to a file:

<?php
    // You need to adjust this to suit
    $filename = '/tmp/myChart.png';

    $src     = $_POST['src'];
    $src     = substr($src, strpos($src, ",") + 1);
    $decoded = base64_decode($src);
    
    $fp = fopen($filename,'wb');
    fwrite($fp, $decoded);
    fclose($fp);
?>

Note about accessible text

You cannot use accessible text When fetching the canvas as a png image. This is because the text is dom text (like virtually all other text in the browser) that's positioned above the canvas and is not part of the canvas itself. So when you fetch a png representation of the canvas the text will not be included.

From version 6.08 onwards the accessible text feature is not enabled by default as it was in previous versions - so you may not need to be concerned by this.

If for any reason you do want to specifically disable it you can do so with this option:

textAccessible: false

Note about setting the background color

When saving the canvas you will probably want to set the background color to white. By default, the background color of the canvas is transparent and because the default background color of the webpage is white this is what it appears to be.

However, when you get a png representation of the canvas it will show up as black unless you set it to white. You can set it to white by using the backgroundColor option.

Using the CSV reader to read server based data

One option that you have to integrate with a database is to use the csv reader. By using this you can have a server based php file that instead of outputting html outputs csv data (ie comma separated values). Which looks like this sample CSV file.

Then by using the CSV reader you can read that file and subsequently create your chart.

There are both canvas and svg versions of the csv reader (though there's no difference between the two.

Rendering charts without a browser

If you wish to make charts without a browser or user involved (eg from a scheduled task) there is something called PhantomJS that you can use to generate png images from webpages automatically.