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

More »

 

Download
Get the latest version of RGraph (version 6.20, 1st December 2024) 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 »

Accessible text

Disappointed by the quality of the text that's rendered on a canvas, RGraph has the option to use accessible, dom text positioned over the canvas instead of native canvas rendered text.

The html5 canvas tag is a bitmap (not a vector) - so the quality of anything - including text - will degrade as you increase the zoom - similar to how an image becomes blockier the more you zoom in.

Using dom text instead of native canvas text skirts this issue - and text retains its quality regardless of the level of zoom. Try zooming your page (CTRL & + and CTRL & -) when you're using it and you'll see.


<script>
    new RGraph.Bar({
        id: 'cvs',
        data: [45,49,43,46,32],
        options: {
            tooltips: '<b>%{property:xaxisLabels[%{index}]}</b>: {value}%',
            xaxisLabels: ['Monday','Tuesday','Wednesday','Thursday','Friday'],

            // textAccessible: true,
            // textAccessibleOverflow: true,
            // textAccessiblePointerevents: true,

            textSize: 14,
            titleSize: 20,
            titleBold: true, // Default
            title: 'An example chart using accessible text',
            yaxisScaleMax: 100,
            colors: ['Gradient(#fcc:red:red)'],
            shadowOffsetx: 1,
            shadowOffsety: 1,
            shadowBlur: 5,
            marginLeft: 5,
            marginRight: 5,
            marginTop: 50,
            marginBottom: 5,
            yaxisScaleUnitsPost: '%',
            colorsStroke: 'transparent',
            xaxis: false,
            yaxis: false,
            backgroundGridVlines: false,
            backgroundGridBorder: false,
            clearto: 'white'
        }
    }).wave();
</script>

Caveats with accessible text

There are caveats-a-plenty with accessible text - mainly with interactive features. Things that aren't mentioned here may or may not work!

Adding your own event handlers

Being standard dom nodes you can work with them as such. References to the span tags are kept in the RGraph.text.domNodeCache array. The first key in that array is the canvas id and then you could use the for/in loop shown below to loop through the text nodes that pertain to that canvas tag. If you wanted to you could, in that loop, add them to a numerically indexed array, which you might then find easier to work with.

<script>
    // Loop through all of the accessible text nodes and add them to a one dimension,
    // numerically indexed array
    texts = RGraph.text.domNodeCache['cvs']; // Use the canvas id here
    arr   = new Array();

    for (var i in texts) {
        arr.push(texts[i]);
    }
    
    
    
    // This is an example of the sort of thing that you could then add
    arr[1].onmouseover = function (e)
    {
        e.target.style.padding         = '2px';
        e.target.style.backgroundColor = 'red';
        e.target.style.border          = '2px solid black';
        e.target.style.borderRadius    = '5px';
    
        e.target.onmouseout = function (e)
        {
            e.target.style.padding         = '';
            e.target.style.backgroundColor = '';
            e.target.style.border          = '';
            e.target.style.borderRadius    = '';
            e.target.style.cursor          = 'default';
        };
    }





    // And this is how to get the length of the text array
    len = Object.keys(RGraph.text.domNodeCache['cvs']).length;
</script>

Performance advantages with accessible text

Drawing text on canvas has, in the past, been called slow. Whether it is still slow is open to discussion. It most certainly won't be as fast though as simply not drawing text at all. And that is evident in the demo charts in the download archive in the smoothness of the animation.

By using accessible text that is essentially what is happening. If the dom nodes were created and trashed for every frame of an animation then there would be no performance gain and a massive performance loss. But they're not.

The dom text nodes are created and then the nodes are kept in the RGraph.text.domNodeCache array. It's a cache so that the nodes aren't created over and over again. By doing this all of the text on the canvas is created once and reused for each frame of an animation. By repeatedly using the same text the text drawing part of the chart rendering is eliminated.

Accessibility advantages with accessible text

When it comes to accessibility with canvas - essentially it's an impenetrable black box. Anything drawn on it is unknown to the browser - much like an image. So by using accessible text you make the text as accessible as the other text on your page. The text can gain focus and can be read by screen readers just like normal text. It also responds to zoom operations like other text on your page.

Dealing with text that moves (in animation effects)

If you have text that moves in your chart - in an animated Bar chart or a Horizontal Bar chart with the labelsAbove option enabled - then this can slow down accessible text. This is because new dom nodes need to be created for each bit of moving text on each frame of the animation. This can be worked around in some cases though by only enabling the text once the animation has finished. You can do this by using an animation-complete callback function. The Bar chart and Horizontal Bar chart both accommodate the labelsAbove text already. You can use the callback function like this:

.grow(null, function (obj)
{
    obj.set('labelsAbove', true);
    RGraph.redraw();
});