MENU
.net Powerful JavaScript charts
About
RGraph is a JavaScript charts library based on HTML5 SVG and canvas. RGraph is mature (over 17 years old) and has a wealth of features making it an ideal choice to use for showing charts on your website.

More »

 

Version 7 released
Version 7 (released in August 2025) is the latest version of RGraph and brings with it a big improvement in the quality of the text that's rendered on canvas charts. This new improvement in text rendering is the major focus in this release. Read more about the new scaling feature at the link below.

More »

 

New HTML datagrid
In the April 2025 release a new datagrid object was added. This makes it easy to add static or dynamic data tables to your pages. It can be used whether you use the canvas or SVG libraries or entirely standalone.

Read more »

 

Download
Get the latest version of RGraph (version 7.00, 12th August 2025) from the download page. You can read the changelog here. There's also older versions available, minified files and links to cdnjs.com hosted libraries.

Download »

 

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

More »

HOWTO: Create a Bar with interactive multiple select

Introduction

You can, relatively simply, create a Bar chart that permits the selection of bars - and which then sends that information back to the server.

This allows you to select bars on the Bar chart and have that information recorded by the server so that when the Bar chart is shown again the same bars are selected.

Optionally, you can also have the selection control something else based on the selection (also by using ajax and communicating with your server - the possibilities are down to you).

And by using the local storage api - ie the window.localData variable) you can have the data persist on just the client - so no sending it back to the server with ajax.

Here's an example of the code that's necessary to get the basic multiple selection up and running.

<script>
    //
    // This state variable remembers the state of the bars and whether they're selected or not
    //
    state = {
        selected: []
    };

    //
    // Create and configure the Bar chart
    //
    bar = new RGraph.Bar({
        id: 'cvs',
        data: [4,8,6,3,5,8,9],
        options: {
            marginInner: 30,
            backgroundGridVlines: false,
            backgroundGridBorder: false,
            yaxis: false,
            xaxis: false,
            xaxisLabels: ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'],
            title: 'A Bar chart with multiple select enabled',
            titleBold: true,
            titleSize: 16,
            events: {

                //
                // The mousemove event just returns true so that the
                // pointer is changed when it's over the bars. If
                // you want to you can make it even shorter by using
                // an arrow function.
                //
                mousemove: function (e, shape)
                {
                    return true;
                },
                
                //
                // This function uses the index of the bar (which
                // is the same as the dataset property) that was
                // clicked (it can be found in the shape object)
                // and toggles that index between true and false
                // in the state array.
                //
                click: function (e, shape)
                {
                    state.selected[shape.dataset] = !state.selected[shape.dataset];
            
                    RGraph.redraw();
                },
                
                //
                // This function uses the RGraph draw event to draw
                // highlighting over the relevant bars.
                //
                draw: function (obj)
                {
                    for (var i=0; i<obj.data.length; ++i) {
                        if (state.selected[i]) {
                        
                            var coords = obj.coords[i];
                        
                            obj.path(
                                'lw 3 b r % % % % f rgba(255,255,255,0.8) s #a00 lw 1',
                                coords[0],
                                coords[1],
                                coords[2],
                                coords[3]
                            );
                        }
                    }
                }
            }
        }
    }).draw();
</script>

Persisting state with the localData variable (HTML5 local storage)

The html5 Storage api can be used to enable persistent state. ie The selected bars are remembered across page refreshes. This doesn't communicate the information back to the server though - so the usefulness of this is limited.

If what you need the persistence for is client-side though - this will work fine.

By using the ajax option below - you can communicate the selection back to the server.

<script>
    // Initialise the state1 variable if it doesn't exist
    if (!localStorage['state1']) {
        state1 = [];
    } else {
        state1 = JSON.parse(localStorage['state1']);
    }



    bar1 = new RGraph.Bar({
        id: 'cvs1',
        data: [4,8,6,3,5,8,9],
        options: {
            backgroundGridVlines: false,
            backgroundGridBorder: false,
            yaxis: false,
            xaxis: false,
            xaxisLabels: ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'],
            title: 'A Bar chart with multiple select enabled',
            events: {
                // Again, the mousemove event just returns
                // true so that the pointer is changed
                mousemove: function (e, shape)
                {
                    return true;
                },

                click: function (e, shape)
                {
                    var idx = shape.dataset;

                    // Update the state2 variable with the
                    // new status
                    state1[idx] = !state1[idx];
                    
                    // Save the state1 variable to
                    // localStorage
                    localStorage['state1'] = JSON.stringify(state1);
            
                    RGraph.redraw();
                },
                
                // Draw the highlight over the relevant bars
                draw: function (obj)
                {
                    for (var i=0; i<obj.data.length; ++i) {
                        if (state1[i]) {
            
                            var coords = obj.coords[i];
            
                            obj.path(
                                'lw 3 b r % % % % f rgba(255,255,255,0.8) s #a00 lw 1',
                                coords[0],
                                coords[1],
                                coords[2],
                                coords[3]
                            );
                        }
                    }
                }
            }
        }
    }).draw();
</script>
    

Persisting state with AJAX

This is a far more useful example that is very similar to the one above but with one key difference - whenever you select or unselect a bar the current state of whatever is highlighted is sent back to the server via an ajax post request.

The RGraph.AJAX.post function is used to send the ajax request.

The callback function is a simple one - it just shows the output of the server-side script (which is an array of the state of the bars) using an alert dialog.

The code is very similar to the above example - the difference is highlighted in red.

<script>
    // Initialise the localData variable if need be
    if (!localStorage['state2']) {
        state2 = [];
    } else {
        state2 = JSON.parse(localStorage['state2']);
    }



    bar2 = new RGraph.Bar({
        id: 'cvs2',
        data: [4,8,6,3,5,8,9],
        options: {
            backgroundGridVlines: false,
            backgroundGridBorder: false,
            yaxis: false,
            xaxis: false,
            xaxisLabels: ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'],
            title: 'A Bar chart with multiple select enabled (plus AJAX)',
            events: {
                mousemove: function (e, shape)
                {
                    return true;
                },
                click: function (e, shape)
                {
                    var idx = shape.dataset;
            
                    // Update the state variable
                    state2[idx] = !state2[idx];
                    
                    /// Save the state to localStorage
                    localStorage['state2'] = JSON.stringify(state2);
                    
                    // Send the state information to the server so it can be saved
                    // (the question mark ensures that this page is the one
                    // that's requested. There's no need to serialise the state2
                    // variable as the RGraph.AJAX.post() function does that for you. The only
                    // thing that's done in the AJAX callback function is that the
                    // output of the AJAX request is displayed.
                    RGraph.AJAX.post('?', {state: state2}, function (str)
                    {
                        alert('This is the output of the AJAX request:\n\n' + str);
                    }
                    
                    RGraph.redraw();
                },
                
                draw: function (obj)
                {
                    for (var i=0; i<obj.data.length; ++i) {
                        if (state2[i]) {
            
                            var coords = obj.coords[i];
            
                            obj.path(
                                'lw 3 b r % % % % f rgba(255,255,255,0.8) s #a00 lw 1',
                                coords[0],
                                coords[1],
                                coords[2],
                                coords[3]
                            );
                        }
                    }
                }
            }
        }
    }).draw();
</script>