How to turn a label into a link (SVG version)

Summary
This HOWTO document details how you can utilise jQuery to get hold of a text label (could be any text) and then convert that text into a hyperlink.

Being DOM based instead a simple bitmap, SVG has certain advantages over canvas. One of those is the relative ease in adding links to your chart. This HOWTO document shows you how to change a regular label into one that's actually a link that your users will be able to click. The chart here shows a single link in the labels (June) which you can click and be taken to Google (you can link to other places of course).

The full source code

Here's the full source code - and underneath it's broken down into sections and described.

<script>
    // 1. First - create the SVG Bar chart
    bar = new RGraph.SVG.Bar({
        id: 'cc',
        data: [4,8,6,3,5,9,4],
        options: {
            xaxisLabels: ['Harry','Paula','Bill','Lucy','May','June','Fred']
        }
    }).draw();

    // 2. Get hold of the relevant label by using jQuery. Remember that this
    // will be a jQuery object - not a DOM node
    var $label = $('div#cc svg text:contains(June)');
    
    // 3. Create an SVG link tag that we'll wrap the label in
    var a = RGraph.SVG.create({
        svg: bar.svg,
        type: 'a',
        parent: bar.svg.all,
        attr: {
           'xlink:href': 'https://www.google.com#q=june',
           target: '_blank'
        }
    });
    
    // 4. Using the jQuery wrap() function - wrap the label using the 
    // we've just created
    $label.wrap(a);
    
    // 5. Get hold of the SVG text node that we've just wrapped in the link
    var svgnode = $label.get(0);
    
    // 6. Add some formatting to the text tag to make it look like a
    // regular HTML link
    svgnode.setAttribute('fill', 'blue')
    svgnode.setAttribute('font-weight', 'bold');
</script>

Create the SVG Bar chart

Nothing strange here - simply a basic Bar chart is being created.

// 1. First - create the SVG Bar chart
bar = new RGraph.SVG.Bar({
    id: 'cc',
    data: [4,8,6,3,5,9,4],
    options: {
        xaxisLabels: ['Harry','Paula','Bill','Lucy','May','June','Fred']
    }
}).draw();

Get a reference to the label

Next thing to do is get hold of the SVG text node that we want to wrap in a link. By using jQuery it makes it very easy to get the correct node - as you can see the selector string $('div#cc svg text:contains(June)') is quite specific and uses the jQuery :contains() selector. This results in the correct SVG <text> node being assigned to the $label variable (though remember - it's not the pure SVG node - it's a jQuery object that consists of the <text> node).

// 2. Get hold of the relevant label by using jQuery. Remember that this
// will be a jQuery object - not a DOM node
var label = $('div#cc svg text:contains(June)');

Create an SVG link tag

The SVG <a> tag is very similar to a regular HTML tag except that it also has a different attribute name for the href: xlink:href="https://www.google.com#q=june" You can use the RGraph.SVG.create() function to create such a tag.

// 3. Create an SVG link tag that we'll wrap the label in
var a = RGraph.SVG.create({
    svg: bar.svg,
    type: 'a',
    parent: bar.svg.all,
    attr: {
       'xlink:href': 'https://www.google.com#q=june',
       target: '_blank'
    }
});

Wrap the label in the link

Now, again using jQuery, we wrap the <a> tag around the <text> node - making it clickable.The jQuery .wrap() function makes this very easy.

// 4. Using the jQuery wrap() function - wrap the label using the <a>
// we've just created
$label.wrap(a);

Get hold of the SVG text node

Now, technically, that is the absolute minimum required to make a link out of the SVG <text> node. But this will result in the link being the same color as the rest of the text - and thus it won't stand out and won't be immediately obvious to the user that it's a link that they can click on. So the best thing to do here would be to make it the same color as normal HTML links - which by default is blue.

So the first thing to do is to get the SVG node that the jQuery object contains. This is done using the jQuery get() function. You could also use the jQuery square brackets notation here - but it makes no difference in this case.

// 5. Get hold of the SVG text node that we've just wrapped in the link
var svgnode = $label.get(0);
// var svgnode = $label[0];

Add some formatting to the text tag

So now we have the node we can use that to add some formatting to it so that it stands out and is obvious to the user that it's a link.

// Add some formatting to the text tag to make it look like a
// regular HTML link
svgnode.setAttribute('fill', 'blue');        // Color it blue
svgnode.setAttribute('font-weight', 'bold'); // Make it bold

Conclusion

So not difficult then is it? With SVG redrawing things for you automatically - you don't have to make the link constantly (ie use the ondraw RGraph event) like you would with the canvas libraries. I may add an RGraph.SVG.link() function if there's enough demand to make this even easier.