An SVG Bar chart that's clickable

There's a canvas HOWTO document that shows a demo of what's being done here - it's less code which means less to both understand and maintain. You can find that here.

This goes in the documents header:
<script src="RGraph.svg.common.core.js"></script>
<script src="RGraph.svg.common.ajax.js"></script>
<script src="RGraph.svg.bar.js"></script>
Put this where you want the chart to show up:
<div style="width: 750px; height: 300px" id="chart-container"></div>
This is the code that generates the chart:
<script>
    state2 = localStorage['state2'] ? JSON.parse(localStorage['state2']) : {selected: []};

    new RGraph.SVG.Bar({
        id: 'cc',
        data: [14,39,-32,-12,8,6,-5],
        options: {
            yaxisMax: 40,
            yaxisMin: -40,
            yaxis: false,
            xaxis: false,
            backgroundGridVlines: false,
            backgroundGridBorder: false
        }
    }).on('draw', function (obj)
    {
        // Loop through all the bars
        for (var i=0; i<obj.coords.length; ++i) {
            (function (index, rect)
            {
                // Change the pointer when hovering over the rect
                rect.addEventListener('mousemove', function (e)
                {
                    e.target.style.cursor = 'pointer';
                }, false);




                //
                // Do this when the rect is clicked
                //
                rect.addEventListener('click', function (e)
                {
                    if (!state2.selected[index]) {

                        // Add the highlight
                        highlight(obj, rect, index);

                        state2.selected[index] = true;

                        // The notify function simply tells the server what 
                        // bars are selected
                        //
                        notify();

                    } else {
                        state2.selected[index] = null;
                    }
                }, false);
            })(i, obj.coords[i].object);
        }

        // Read the state2 variable and cover the relevant bars
        for (var i=0; i<obj.data.length; ++i) {
            if (state2.selected[i]) {
                highlight(obj, obj.coords[i].object, i);
            }
        }
    }).draw();




    //
    // Sends notification to the server
    //
    function notify()
    {
        // Save the state2 to localStorage
        localStorage['state2'] = JSON.stringify(state2);

        // Generate an AJAX request
        RGraph.SVG.AJAX.POST('?', {state2: state2.selected}, function (str)
        {
            // Handle the AJAX response here
        });
    }




    //
    // Highlights a bar by adding a rect on top of it
    //
    function highlight(obj, rect, index)
    {
        rect.rgraph_highlight = RGraph.SVG.create({
            svg: obj.svg,
            type: 'rect',
            parent: obj.svg.all,
            attr: {
                x:              rect.getAttribute('x'),
                y:              rect.getAttribute('y'),
                width:          rect.getAttribute('width'),
                height:         rect.getAttribute('height'),
                fill:           'rgba(255,255,255,0.7)',
                stroke:         'black',
                'stroke-width': 3
            }
        });


        //
        // When the highlight is clicked - get rid of it and call
        // the notify() function to update the server.
        //
        rect.rgraph_highlight.onclick = function (e)
        {
            obj.svg.all.removeChild(rect.rgraph_highlight);
            rect.rgraph_highlight  = null;
            state2.selected[index] = null;
            
            notify();
        }

        rect.rgraph_highlight.style.cursor = 'pointer';
    }
</script>

« Back