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 »

 

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 »

 

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 »

Examples of infographic charts

Written by Richard Heyes, RGraph author, on 22nd July 2020

Customised Bar chart

View example on CodePen

The first chart that we have is a grouped Bar chart where the standard rect function has been redefined so that the normal rectangle is drawn with rounded corners at the top.

Update: Now you don't have to redefine anything as there's a corners option for the Bar chart.

There are actually two Bar charts drawn here - one for the faint dark coloured bars at the back and then one for the main pink and blue Bar chart. The custom A and B labels are added using the RGraph.text api function.

    
//////////////////////////////////////////////////////////////////////////
// This updated fillRect function can go in a library file if you wish. //
//////////////////////////////////////////////////////////////////////////


window.roundedCorners = 15;

//
// This adds a roundedRect(x, y, width, height, radius) function to the drawing context.
// The radius argument dictates by how much the corners are rounded.
// 
// @param number x      The X coordinate
// @param number y      The Y coordinate
// @param number width  The width of the rectangle
// @param number height The height of the rectangle
// @param number radius The radius of the corners. Bigger values mean more rounded corners
//
CanvasRenderingContext2D.prototype.fillRect = function (x, y, width, height)
{
    this.beginPath();

    var radius = window.roundedCorners;

    // Because the function is added to the context prototype
    // the 'this' variable is actually the context
    
    // Save the existing state of the canvas so that it can be restored later
    this.save();
    
        // Translate to the given X/Y coordinates
        this.translate(x, y);

        // Move to the center of the top horizontal line
        this.moveTo(width / 2,0);
        
        // Draw the rounded corners. The connecting lines in between them are drawn automatically
        this.arcTo(width,0,width,height, Math.min(height / 2, radius));
        this.arcTo(width, height, 0, height, Math.min(width / 2, 0));
        this.arcTo(0, height, 0, 0, Math.min(height / 2, 0));
        this.arcTo(0, 0, radius, 0, Math.min(width / 2, radius));

        // Draw a line back to the start coordinates
        this.lineTo(width / 2,0);

    // Restore the state of the canvas to as it was before the save()
    this.restore();

    this.fill();
};






//////////////////////////////////////////
// End of the updated fillRect function //
//////////////////////////////////////////






//  This Bar chart is the faint background bars that are darkened. It's drawn first so that it
// appears at the back of the other chart.
bar1 = new RGraph.Bar({
    id: 'cvs',
    data: [[79,68],[82,72],[59,78],[65,79]],
    options: {
        yaxisScaleMax: 100,
        marginInner: 25,
        marginInnerGrouped: 5,
        backgroundGrid: false,
        colors: ['#53245B'],
        axesColor: '#AB86B1',
        xaxisColor: '#AB86B1',
        yaxisColor: '#AB86B1',
        xaxisTickmarksCount: 0,
        yaxisTickmarksCount: 0,
        yaxisLabelsColor: '#B57FBD',
        yaxisLabelsSize: 10,
        xaxisLabelsSize: 14,
        xaxisLabelsBold: true,
        xaxisLabels: ['Dave','Alan','Harry','Joe'],
        xaxisLabelsColor: '#B57FBD'
    }
}).draw();

// This is the main chart that's pink and blue
bar2 = new RGraph.Bar({
    id: 'cvs',
    data: [[59,55],[48,52],[45,59],[59,58]],
    options: {
        yaxisScaleMax: 100,
        marginInner: 25,
        marginInnerGrouped: 5,
        backgroundGrid: false,
        colors: [
            'Gradient(#2892FF:#39A3FF)',
            'Gradient(#FF4AD5:#FF7FF8)'
        ],
        xaxis: false,
        yaxis: false
    }
}).draw();



// Add the A and B labels at the bottom of the Bars. This is a simple "for" loop that
// goes through the coordinates for the Bar chart and uses them together with the
// RGraph.text() API function to add the text.
for (var i=0; i<bar1.coords.length; ++i) {
    RGraph.text({
        object: bar1,
        x:      bar1.coords[i][0] + (bar1.coords[i][2] / 2),
        y:      bar1.coords[i][1] + bar1.coords[i][3],
        text:   i % 2 === 0 ? 'A' : 'B',
        color:  'white',
        bold:   true,
        halign: 'center',
        accessible: false
    });
}

Customised Rose charts

View example on CodePen

Here's a set of two Rose charts that have had circles drawn in the center and then text added to those holes. Both of the charts have keys and the color of the stroke matches the background so it gives the effect of segment separation.

//
// Draw the blue Rose chart. This is a normal (albeit a non-equi-angular) Rose chart.
//
rose1 = new RGraph.Rose({
    id: 'cvs2',
    data: [[5,5],[8,5],[6,7],[5,2],[6,3],[7,5],[8,7],[5,4],[7,3],[8,3],[6,7]],
    options: {
        variant: 'non-equi-angular',
        margin: 0,
        scale: false,
        backgroundGridColor: 'rgba(0,0,0,0)',
        colors: ['white','#66f','#aaf','blue','#90BCD0','white','#66f','#aaf','blue','#90BCD0','#aaf'],
        colorsSequential: true,
        colorsStroke: '#3D0149',
        linewidth: 2,
        labelsAxes: '',
        marginLeft:0,
        marginRight:0,
        marginTop:0,
        marginBottom:0,
        key: ['Lorem','Ipsum','Delore','Byzan','Corem','Desis','Hool','Pinco','Sysum','Zizzi','Elsy'],
        keyBackground: 'rgba(0,0,0,0)',
        keyLabelsColor: 'white',
        keyColorShape: 'circle',
        keyPositionY: 50,
        keyLinewidth: 0.01
    }
}).draw();

// Use the path() function to draw a circle at the center X/Y coordinates using
// the same color as the background. This makes it look like the Rose chart has a big
// hole in the center.
rose1.path(
    'b a % % 40 0 6.29, false f #390148',
    rose1.centerx, rose1.centery
);

// Use the RGraph.text() API function to add some text at the center of the chart. 
RGraph.text({
    object: rose1,
    x:      rose1.centerx,
    y:      rose1.centery,
    text:   'A',
    size:   30,
    color:  '#aaa',
    valign: 'center',
    halign: 'center',
    accessible: false
});





//
// Draw the yellow Rose chart. This Rose chart is much the same as the prior Rose
// chart albeit with different data and colors.
rose2 = new RGraph.Rose({
    id: 'cvs3',
    data: [[5,2],[8,3],[6,8],[5,5],[6,4],[7,9],[8,9],[5,6],[7,7],[8,6],[6,5]],
    options: {
        variant: 'non-equi-angular',
        margin: 0,
        scale: false,
        backgroundGridColor: 'rgba(0,0,0,0)',
        colors: ['red','brown','#f0f','#a00','orange','yellow','brown','#f0f','#a00','pink','#faf'],
        colorsSequential: true,
        colorsStroke: '#3D0149',
        linewidth: 2,
        labelsAxes: '',
        marginLeft:0,
        marginRight:0,
        marginTop:0,
        marginBottom:0,
        key: ['Lorem','Ipsum','Delore','Byzan','Corem','Desis','Hool','Pinco','Sysum','Zizzi','Elsy'],
        keyBackground: 'rgba(0,0,0,0)',
        keyLabelsColor: 'white',
        keyColorShape: 'circle',
        keyPositionY: 50,
        keyBorderColor:'white',
        keyLinewidth: 0.01
    }
}).on('draw', function (obj)
    {
    // This time use the draw event to make the big hole at the center. If you use dynamic
    // features (eg tooltips) you'll need to do this so that the hole at the center gets redrawn
    // along with the chart.
    obj.path(
        'b a % % 40 0 6.29, false f #390148',
        obj.centerx, obj.centery
    );
}).draw();

// Again, draw some text at the center of the Rose chart.
RGraph.text({
    object: rose2,
    x:      rose2.centerx,
    y:      rose2.centery,
    text:   'B',
    size:   30,
    color:  '#aaa',
    valign: 'center',
    halign: 'center',
    accessible: false
});

Another customised Bar chart

View example on CodePen

This is another customised Bar chart that instead of Bars uses custom draw event code to draw lines in their place. There's a demo in the download archive that has the un-customised Bar chart version of this "over and under" Bar chart. This one however has had its colors set to transparent and then the coordinates are used to draw lines to represent the Bars.

new RGraph.Bar({
    id: 'cvs',
    data: [6,5,5,8,5,8,9,5,6,8,5,8],
    options: {
        key: ['Profits', 'Investments'],
        keyBackground: 'rgba(0,0,0,0)',
        keyPosition: 'margin',
        keyColors: ['orange','red'],
        keyLabelsOffsety: 2,
        keyLabelsBold: true,
        colors: ['rgba(0,0,0,0)'],
        xaxisPosition: 'center',
        marginInnerGrouped: 5,
        backgroundGrid: false,
        axesColor: '#AB86B1',
        xaxisColor: '#AB86B1',
        yaxisColor: '#AB86B1',
        xaxisTickmarksCount: 0,
        yaxisTickmarksCount: 0,
        yaxisLabelsSize: 10,
        xaxisLabelsSize: 14,
        xaxisLabelsBold: true,
        xaxisLabels: ['Dave','Alan','Harry','Joe'],
        textColor: '#999'
    }
}).on('draw', function (obj)
{
    // This draw event code utilises the RGraph path function to draw the vertical
    // lines that you see on the chart instead of the Bars. The color of the Bars
    // is set to transparent so you only see the lines. This code only draws half of the
    // coordinates - the other half is drawn by the other chart.
    for (var i=0; i<obj.coords.length; ++i) {
        obj.path(
            'lw 5 lc round b m % % l % % s orange',
            obj.coords[i][0] + (obj.coords[i][2] / 2), obj.coords[i][1],
            obj.coords[i][0] + (obj.coords[i][2] / 2), obj.coords[i][1] + obj.coords[i][3] - 10
        );
    }
}).draw();

new RGraph.Bar({
    id: 'cvs',
    data: [-4,-2,-8,-5,-9,-5,-6,-5,-4,-2,-9,-7],
    options: {
        colors: ['transparent'],
        xaxisPosition: 'center',
        marginInnerGrouped: 5,
        backgroundGrid: false,
        axesColor: '#AB86B1',
        xaxisColor: '#AB86B1',
        yaxisColor: '#AB86B1',
        xaxisTickmarksCount: 0,
        yaxisTickmarksCount: 0,
        yaxisScaleColor: 'white',
        yaxisLabelsSize: 10,
        xaxisLabelsSize: 14,
        xaxisLabelsBold: true,
        xaxisLabels: ['Dave','Alan','Harry','Joe'],
        textColor: '#999'
    }
}).draw().on('draw', function (obj)
{
    // This draw event code utilises the RGraph path function to draw the vertical
    // lines that you see on the chart instead of the Bars. The color of the Bars
    // is set to transparent so you only see the lines. This code only draws half of the
    // coordinates - the other half is drawn by the other chart.
    for (var i=0; i<obj.coords.length; ++i) {
        obj.path(
            'lw 5 lc round b m % % l % % s red',
            obj.coords[i][0] + (obj.coords[i][2] / 2), obj.coords[i][1] + 10,
            obj.coords[i][0] + (obj.coords[i][2] / 2), obj.coords[i][1] + obj.coords[i][3]
        );
    }
}).draw();

Customised Donut chart

View example on CodePen

This Donut chart has simple customisations to it that give it a segmented appearance and as well as that some text is added to the center of the chart using the RGraph.text api function. The draw event is not being used here because there aren't any charts on the page using dynamic features (eg tooltips or adjusting) so the chart isn't being redrawn.

// Draw the Pie chart using the number one as each data piece (of which there are twelve).
// This means that each segment will be equal in size and also there are twelve colors - one for
// each segment.
pie = new RGraph.Pie({
    id:'cvs',
    data: [1,1,1,1,1,1,1,1,1,1,1,1],
    options: {
        colors: [
            '#dd0','#dd0','#dd0','#dd0','#dd0','#dd0',
            'red','red','red','red','red','#dd0'
        ],
        colorsStroke: 'white',
        variant: 'donut',
        variantDonutWidth: 25,
        shadow: false
    }
}).draw();

// Use the RGraph.text() API function to add the text in the center of the Pie chart
RGraph.text({
    object: pie,
    x: pie.centerx,
    y: pie.centery,
    text: '42%',
    halign: 'center',
    valign: 'center',
    size: 75,
    accessible: false
});

More custom Donut charts

View example on CodePen

These Meter charts are simple to produce. They use two Pie chart objects each with a slightly different radius and donut width - which gives you the overlap effect. The text at the center is drawn using the RGraph Drawing api Text object. They're all drawn on the same canvas and use the centerx property to position them.

// This draws the first "Meter" - using one Pie chart for the gray background ring and
// a second for the yellow indicator bar. The text indicator in the center is drawn
// using the RGraph.text() API function.

// This Pie chart becomes the gray background ring
pie1 = new RGraph.Pie({
    id:'cvs',
    data: [1],
    options: {
        colors: ['gray'],
        colorsStroke: 'white',
        variant: 'donut',
        variantDonutWidth: 20,
        shadow: false,
        linewidth: 0.0001,
        centerx: 150
    }
}).draw();

// This Pie chart is the yellow indicator bar
pie2 = new RGraph.Pie({
    id:'cvs',
    data: [63,37],
    options: {
        colors: ['#dd0','transparent'],
        colorsStroke: 'white',
        variant: 'donut',
        variantDonutWidth: 45,
        shadow: false,
        radius: pie1.radius + 12.5,
        centerx: 150
    }
}).draw();

// Add the text to the center of the "Meter"
RGraph.text({
    object: pie1,
    x:      pie1.centerx,
    y:      pie1.centery,
    text:   '63%',
    size:   60,
    halign: 'center',
    valign: 'center',
    accessible: false
});






// Draw the second red "Meter" As before two Pie charts and the RGraph.text() API function are used.
pie3 = new RGraph.Pie({
    id:'cvs',
    data: [1],
    options: {
        colors: ['gray'],
        colorsStroke: 'white',
        variant: 'donut',
        variantDonutWidth: 20,
        shadow: false,
        linewidth: 0.0001,
        centerx: 450
    }
}).draw();

pie4 = new RGraph.Pie({
    id:'cvs',
    data: [87,13],
    options: {
        colors: ['red','transparent'],
        colorsStroke: 'white',
        variant: 'donut',
        variantDonutWidth: 45,
        shadow: false,
        radius: pie3.radius + 12.5,
        centerx: 450
    }
}).draw();

RGraph.text({
    object: pie3,
    x:      pie3.centerx,
    y:      pie3.centery,
    text:   '87%',
    size:   60,
    halign: 'center',
    valign: 'center',
    accessible: false
});







// And finally draw the third "Meter" using the same technique
pie5 = new RGraph.Pie({
    id:'cvs',
    data: [1],
    options: {
        colors: ['gray'],
        colorsStroke: 'white',
        variant: 'donut',
        variantDonutWidth: 20,
        shadow: false,
        linewidth: 0.0001,
        centerx: 750
    }
}).draw();

pie6 = new RGraph.Pie({
    id:'cvs',
    data: [47,53],
    options: {
        colors: ['blue','transparent'],
        colorsStroke: 'white',
        variant: 'donut',
        variantDonutWidth: 45,
        shadow: false,
        radius: pie5.radius + 12.5,
        centerx: 750
    }
}).draw();

RGraph.text({
    object: pie5,
    x:      pie5.centerx,
    y:      pie5.centery,
    text:   '47%',
    size:   60,
    halign: 'center',
    valign: 'center',
    accessible: false
});

A Bar chart using a pattern fill

View example on CodePen

canvas has the ability to use patterns as the fill color. This is done by creating a new canvas tag using javascript (but not adding it to the page so you can't see it) and drawing the desired pattern onto it. You can use the createPattern function to use this canvas as a pattern and then give that pattern to RGraph as one of the colors. In the case of this chart two patterns are created - one for each bar - each being a different color.

// Create a canvas (that isn't added to the page) and draw a pattern  on it - 
// this is then used as the color
canvas        = document.createElement('canvas');
canvas.width  = 10;
canvas.height = 10;

// Create the second canvas onto which the blue pattern will be drawn
canvas2        = document.createElement('canvas');
canvas2.width  = 10;
canvas2.height = 10;

// Now get the contexts from the canvas tags that have just been created
context  = canvas.getContext('2d');
context2 = canvas2.getContext('2d');

// Draw the patterns onto the canvas tags using the RGraph.path() function
RGraph.path(context,'b lc square lw 7 m 5 5 l 5 5 s #F80183');
RGraph.path(context2,'b lc square lw 7 m 5 5 l 5 5 s #25BADE');

// Create the Bar chart as normal
bar = new RGraph.Bar({
    id: 'cvs',
    data: [[3,1],[2,4],[5,3],[4,5],[6,3],[6,5],[4,8]],
    options: {
        marginBottom: 5,
        marginInner: 10,
        xaxis: false,
        yaxis: false,
        backgroundGrid: false,
        colors: ['#F80183','#25BADE'],
        labelsAbove: true,
        labelsAboveColor: '#bbb',
        labelsAboveUnitsPost: '%'
    }
}).draw().on('draw', function (obj)
{
    RGraph.text({
        object: obj,
        x:      350,
        y:      45,
        text:   '2018',
        color:  '#F80183',
        size:   28,
        halign: 'right',
        accessible: false
    });

    RGraph.text({
        object: obj,
        x:      360,
        y:      45,
        text:   ' - 2019',
        color:  '#25BADE',
        size:   28,
        halign: 'left',
        accessible: false
    });
});

// Create the patterns using the canvas tags createPattern() function
pattern  = bar.context.createPattern(canvas, 'repeat');
pattern2 = bar.context.createPattern(canvas2, 'repeat');

// Set the pattern on the Bar chart as the colors of the bars and redraw the canvas
bar.set('colors', [pattern, pattern2]);
RGraph.redraw();

Simple Thermometer charts

View example on CodePen

Thermometer charts are essentially a variation of the Vertical Progress Bar. Though it doesn't support multiple values like the Vertical Progress bar does. Here are a few examples of how it can be configured with a simple two-tone appearance that may be suited to your site's aesthetic better than a progress bar.

// Draw the Thermometer charts. They\'re essentially basic Thermometer charts with a two-tone appearance.
// Only a small amount of configuration is required for each.
// Draw the Thermometer charts. They're essentially basic Thermometer charts with a two-tone appearance.
// Only a small amount of configuration is required for each.
new RGraph.Thermometer({
    id: 'cvs',
    min: 0,
    max: 100,
    value: 56,
    options: {
        colors: ['red'],
        linewidth: 15,
        colorsStroke: 'white',
        shadow: false,
        labelsValue: false,
        tickmarksCount: 0,
        marginLeft: 25,
        marginRight: 925
    }
}).draw();

new RGraph.Thermometer({
    id: 'cvs',
    min: 0,
    max: 100,
    value: 62,
    options: {
        colors: ['blue'],
        linewidth: 15,
        colorsStroke: 'white',
        shadow: false,
        labelsValue: false,
        tickmarksCount: 0,
        marginLeft: 125,
        marginRight: 825
    }
}).draw();

new RGraph.Thermometer({
    id: 'cvs',
    min: 0,
    max: 100,
    value: 6,
    options: {
        colors: ['green'],
        linewidth: 15,
        colorsStroke: 'white',
        shadow: false,
        labelsValue: false,
        tickmarksCount: 0,
        marginLeft: 225,
        marginRight: 725
    }
}).draw();

new RGraph.Thermometer({
    id: 'cvs',
    min: 0,
    max: 100,
    value: 86,
    options: {
        colors: ['purple'],
        linewidth: 15,
        colorsStroke: 'white',
        shadow: false,
        labelsValue: false,
        tickmarksCount: 0,
        marginLeft: 325,
        marginRight: 625
    }
}).draw();

new RGraph.Thermometer({
    id: 'cvs',
    min: 0,
    max: 100,
    value: 16,
    options: {
        colors: ['#aaaaaa'],
        linewidth: 15,
        colorsStroke: 'white',
        shadow: false,
        labelsValue: false,
        tickmarksCount: 0,
        marginLeft: 425,
        marginRight: 525
    }
}).draw();