jQuery SVG Demo

A jQuery plugin that lets you interact with an SVG canvas. If you find this plugin useful please vote for it on the jQuery site.

The current version is 1.4.3 and is available under the GPL and MIT licences. For more detail see the documentation reference page, or the graphing reference or plotting reference pages. Or see a minimal page that you could use as a basis for your own investigations.

Introduction

SVG (Scalable Vector Graphics) is a modularized language for describing two-dimensional vector and mixed vector/raster graphics in XML. It is a W3C Recommendation currently at version 1.1.

SVG is a language for describing two-dimensional graphics in XML. SVG allows for three types of graphic objects: vector graphic shapes (e.g., paths consisting of straight lines and curves), images and text. Graphical objects can be grouped, styled, transformed and composited into previously rendered objects. The feature set includes nested transformations, clipping paths, alpha masks, filter effects and template objects.

SVG is implemented in Firefox natively from version 1.5, Opera natively from version 8.5, Safari natively from version 3.0, and in IE from Windows 98 onwards via the Adobe SVG viewer or the Renesis Player. Not every SVG construct is supported by these implementations.

This plugin allows you to manipulate the SVG from JavaScript. For more details see the reference documentation, or the graphing reference or plotting reference pages.

Download and include the jQuery SVG CSS and JavaScript in the head section of your page.

<style type="text/css">@import "jquery.svg.css";</style>
<script type="text/javascript" src="jquery.svg.js"></script>

Alternatively, you can use the packed or minified versions of the code: jquery.svg.pack.js (14.6K vs 54.3K) or jquery.svg.min.js (18.8K, 5.8K when zipped).

Attach an SVG canvas to a <div>.

$('#svgintro').svg({onLoad: drawIntro});

Then respond to the load completion and start working with it.

function drawIntro(svg) {
	svg.circle(75, 75, 50,
		{fill: 'none', stroke: 'red', strokeWidth: 3});
	var g = svg.group({stroke: 'black', strokeWidth: 2});
	svg.line(g, 15, 75, 135, 75);
	svg.line(g, 75, 15, 75, 135);
}

You can remove the SVG functionality if you no longer need it.

$('#remove').toggle(function() {
		$(this).text('Re-attach');
		$('#svgintro').svg('destroy');
	},
	function() {
		$(this).text('Remove');
		$('#svgintro').svg({onLoad: drawIntro});
	});

For IE, a blank SVG document is initially loaded that registers itself with the plugin and allows access to its internal structure. This is the blank.svg document. Because of this requirement, you must wait for the document to be loaded before accessing the SVG instance and using it. Use the onLoad setting to be notified when loading is complete. The callback is not necessary for the other browsers, but its use provides a consistent access pattern for them all.

Processed divisions are marked with a class of hasSVG and are not re-processed if targetted a second time.

Extension Plugins

As well as the basic SVG functionality, the plugin allows for extending its abilities via additional packages. In this way you can avoid loading code that you are not going to use. Most extensions add an entry point object to the SVG manager object, returned by $(selector).svg('get'), from which you can access its functionality.

Currently the following extensions are available:

PackageEntry pointFunctionality
jquery.svganim.js- Support for jQuery animation of SVG attributes. Since 1.1.0.
jquery.svgdom.js- Support for jQuery/SVG DOM compatibility. Since 1.4.0.
jquery.svgfilter.jssvg.filter Support for SVG filter element and filter definitions.
jquery.svggraph.jssvg.graph Support for basic graphing using SVG.
jquery.svgplot.jssvg.plot Support for plotting functions using SVG. Since 1.3.0.

To use these extensions just load them after the main jQuery SVG Javascript in the head section of your page.

<script type="text/javascript" src="jquery.svg.js"></script>
<script type="text/javascript" src="jquery.svggraph.js"></script>

Each extension registers itself with the SVG framework as shown, indicating the name of its entry point and the class (function) that encapsulates its functionality:

$.svg.addExtension('graph', SVGGraph);

Attach an SVG canvas and retrieve the SVG instance as before. Then access the new functionality through its entry point:

$('div selector').svg();
var svg = $('div selector').svg('get');
svg.graph.addSeries('Firefox', [0.00, 4.06, 8.13, 9.95],
	'lightgreen', 'green', 3);

SVG Examples

These examples are taken from the SVG 1.1 specification to show how they might be implemented using this package.

Select one of the examples taken from the SVG specification that demonstrates how the functionality might be produced using this package. Both the original SVG document and the jQuery SVG code are shown below.

 

SVG Source Document

SVG jQuery Code

 

SVG Load

The SVG component may be updated with inline SVG elements, be cleared of all content, or be loaded with external SVG documents. In the latter case, you may pass additional settings to add to any existing content (addTo: true) or automatically clear it first (addTo: false - the default).

You can also specify a callback function (onLoad: loadDone) to be notified when the external document (loaded asynchronously) has completed. The function receives the current SVG wrapper object as a parameter, and an additional message parameter if there was an error. The this object is the SVG container division.

This came from an inline SVG fragment
<svg:svg id="svginline">
  <svg:g>
    <svg:rect width="350" height="50" x="20" y="90" fill="blue"></svg:rect>
    <svg:text x="40" y="120" fill="white" font-weight="bold">
      This came from an inline SVG fragment</svg:text>
  </svg:g>
</svg:svg>
$('#svgload').svg();

$('#addInline').click(function() {
	var svg = $('#svgload').svg('get');
	svg.add($('#svginline'));
	resetSize(svg);
});

$('#clear1').click(function() {
	$('#svgload').svg('get').clear();
});

$('#loadExternal').click(function() {
	var svg = $('#svgload').svg('get');
	svg.load($('#loadURL').val(), {addTo: $('#addTo')[0].checked,
		changeSize: false, onLoad: loadDone});
	resetSize(svg);
});

// Callback after loading external document
function loadDone(svg, error) {
	svg.text(10, 20, error || 'Loaded into ' + this.id);
}

SVG Attribute Animations

By adding the jquery.svganim.js extension to your page you can easily animate several of the attributes of the various SVG elements using the standard jQuery animate function.

All attributes must be prefixed by 'svg' to identify them as SVG settings and are written in camelCase, e.g. svgStrokeWidth. Many of the values may be expressed as exact pixels or as percentages. You can also use the '+=' or '-=' prefixes for relative values.

var myrect = svg.rect(25, 25, 150, '25%', 10, 10,
	{fill: 'none', stroke: 'blue', strokeWidth: 3,
	transform: 'rotate(0, 100, 75)'});
$(myrect).animate({svgWidth: 200, svgHeight: '30%',
	svgStroke: 'aqua', svgStrokeWidth: '+=7',
	svgTransform: 'rotate(60, 100, 75)'}, 2000);

Animate

or a combination of effects  

$('#svganim').svg({onLoad: drawAnim});
		
var current = {};

$('#animGo').click(function() {
	var opt = $('#animShape').val();
	$('#animBetween').text(
		'between ' + values[opt][0] + ' and ' + values[opt][1]);
	current[opt] = 1 - (current[opt] || 0);
	var parts = opt.split(':');
	var params = {};
	params['svg' + parts[1]] = values[opt][current[opt]];
	$(shapes[parts[0]]).animate(params, 2000);
});

$('#animCombo').toggle(function() {
		$(shapes['rect']).animate(
			{svgWidth: '30%', svgStrokeWidth: 10,
			svgTransform: 'rotate(45 100 75) translate(20 40)'}, 2000);
		$(shapes['circle']).animate({svgR: 100, svgStroke: 'pink'}, 2000);
	}, function() {
		$(shapes['rect']).animate(
			{svgWidth: '25%', svgStrokeWidth: 3,
			svgTransform: 'rotate(0 100 75) translate(0 0)'}, 2000);
		$(shapes['circle']).animate({svgR: 50, svgStroke: 'red'}, 2000);
	});

The attributes that can be animated are summarised below. For more information see the documentation reference animation page

SVG AttributeAnimation AttributeTypeElements
xsvgXnumeric svg, rect, text
ysvgYnumeric svg, rect, text
widthsvgWidthnumeric svg, rect
heightsvgHeightnumeric svg, rect
cxsvgCxnumeric circle, ellipse
cysvgCynumeric circle, ellipse
rsvgRnumeric circle
rxsvgRxnumeric rect, ellipse
rysvgRynumeric rect, ellipse
x1svgX1numeric line
y1svgY1numeric line
x2svgX2numeric line
y2svgY2numeric line
opacitysvgOpacitynumeric 0.0-1.0 group, rect, circle, ellipse, line, polyline, polygon, path, text
fontSizesvgFontSizenumeric group, text
fillsvgFillcolour group, rect, circle, ellipse, polygon, path, text
fillOpacitysvgFillOpacitynumeric 0.0-1.0 group, rect, circle, ellipse, polygon, path, text
strokesvgStrokecolour group, rect, circle, ellipse, line, polyline, polygon, path, text
strokeWidthsvgStrokeWidthnumeric group, rect, circle, ellipse, line, polyline, polygon, path, text
strokeOpacitysvgStrokeOpacitynumeric 0.0-1.0 group, rect, circle, ellipse, line, polyline, polygon, path, text
transformsvgTransformstring group, rect, circle, ellipse, line, polyline, polygon, path, text
viewBoxsvgViewBoxstring svg, symbol, marker, pattern

Sketchpad

Select a shape and its appearance and then drag in the panel to create it.

 
Shape Fill
Stroke width Stroke
 
var drawNodes = [];
var sketchpad = null;
var start = null;
var outline = null;
var offset = null;

$('#svgsketch').svg({onLoad: function(svg) {
		sketchpad = svg;
		var surface = svg.rect(0, 0, '100%', '100%', {id: 'surface', fill: 'white'});
		$(surface).mousedown(startDrag).mousemove(dragging).mouseup(endDrag);
		resetSize(svg, '100%', '100%');
	}
});

// Remember where we started
function startDrag(event) {
	offset = ($.browser.msie ? {left: 0, top: 0} : $('#svgsketch').offset());
	if (!$.browser.msie) {
		offset.left -= document.documentElement.scrollLeft || document.body.scrollLeft;
		offset.top -= document.documentElement.scrollTop || document.body.scrollTop;
	}
	start = {X: event.clientX - offset.left, Y: event.clientY - offset.top};
	event.preventDefault();
}

// Provide feedback as we drag
function dragging(event) {
	if (!start) {
		return;
	}
	if (!outline) {
		outline = sketchpad.rect(0, 0, 0, 0,
			{fill: 'none', stroke: '#c0c0c0', strokeWidth: 1, strokeDashArray: '2,2'});
		$(outline).mouseup(endDrag);
	}
	sketchpad.change(outline, {x: Math.min(event.clientX - offset.left, start.X),
		y: Math.min(event.clientY - offset.top, start.Y),
		width: Math.abs(event.clientX - offset.left - start.X),
		height: Math.abs(event.clientY - offset.top - start.Y)});
	event.preventDefault();
}

// Draw where we finish
function endDrag(event) {
	if (!start) {
		return;
	}
	$(outline).remove();
	outline = null;
	drawShape(start.X, start.Y,
		event.clientX - offset.left, event.clientY - offset.top);
	start = null;
	event.preventDefault();
}

// Draw the selected element on the canvas
function drawShape(x1, y1, x2, y2) {
	var left = Math.min(x1, x2);
	var top = Math.min(y1, y2);
	var right = Math.max(x1, x2);
	var bottom = Math.max(y1, y2);
	var settings = {fill: $('#fill').val(), stroke: $('#stroke').val(),
		strokeWidth: $('#swidth').val()};
	var shape = $('#shape').val();
	var node = null;
	if (shape == 'rect') {
		node = sketchpad.rect(left, top, right - left, bottom - top, settings);
	}
	else if (shape == 'circle') {
		var r = Math.min(right - left, bottom - top) / 2;
		node = sketchpad.circle(left + r, top + r, r, settings);
	}
	else if (shape == 'ellipse') {
		var rx = (right - left) / 2;
		var ry = (bottom - top) / 2;
		node = sketchpad.ellipse(left + rx, top + ry, rx, ry, settings);
	}
	else if (shape == 'line') {
		node = sketchpad.line(x1, y1, x2, y2, settings);
	}
	else if (shape == 'polyline') {
		node = sketchpad.polyline([[(x1 + x2) / 2, y1], [x2, y2],
			[x1, (y1 + y2) / 2], [x2, (y1 + y2) / 2], [x1, y2],
			[(x1 + x2) / 2, y1]], $.extend(settings, {fill: 'none'}));
	}
	else if (shape == 'polygon') {
		node = sketchpad.polygon([[(x1 + x2) / 2, y1], [x2, y1], [x2, y2],
			[(x1 + x2) / 2, y2], [x1, (y1 + y2) / 2]], settings);
	}
	drawNodes[drawNodes.length] = node;
	$(node).mousedown(startDrag).mousemove(dragging).mouseup(endDrag);
	$('#svgsketch').focus();
};

// Remove the last drawn element
$('#undo').click(function() {
	if (!drawNodes.length) {
		return;
	}
	sketchpad.remove(drawNodes[drawNodes.length - 1]);
	drawNodes.splice(drawNodes.length - 1, 1);
});

// Clear the canvas
$('#clear2').click(function() {
	while (drawNodes.length) {
		$('#undo').trigger('click');
	}
});

Graphing

Use the graphing extension to make it easier to create SVG graphs.

Add the jQuery SVG graphing extension in the head section of your page.

<script type="text/javascript" src="jquery.svggraph.js"></script>

Then access the extra functionality via the graph object within the SVG root. As well as the series and their formatting, you can control the graph title, axes, gridlines, labels, and legend.

with legend and background  

Options:

This is the code behind the graphing.

$('#svggraph').svg(initGraph);
		
var chartAreas = [[0.1, 0.1, 0.95, 0.9], [0.2, 0.1, 0.95, 0.9],
	[0.1, 0.1, 0.8, 0.9], [0.1, 0.25, 0.9, 0.9], [0.1, 0.1, 0.9, 0.8]];
var legendAreas = [[0.0, 0.0, 0.0, 0.0], [0.005, 0.1, 0.125, 0.5],
	[0.85, 0.1, 0.97, 0.5], [0.2, 0.1, 0.8, 0.2], [0.2, 0.9, 0.8, 0.995]];
var fills = [['lightblue', 'url(#fadeBlue)'], ['pink', 'url(#fadeRed)'],
	['lightgreen', 'url(#fadeGreen)']];

function initGraph(svg) {
	var defs = svg.defs();
	svg.linearGradient(defs, 'fadeBlue',
		[[0, 'lightblue'], [1, 'blue']]);
	svg.linearGradient(defs, 'fadeRed', [[0, 'pink'], [1, 'red']]);
	svg.linearGradient(defs, 'fadeGreen',
		[[0, 'lightgreen'], [1, 'green']]);
	svg.graph.noDraw().title('Browser Usage', 'blue').
		addSeries('IE', [95.97, 91.80, 88.16, 86.64],
			'lightblue', 'blue', 3).
		addSeries('Netscape', [3.39, 2.83, 1.61, 0.00],
			'pink', 'red', 3).
		addSeries('Firefox', [0.00, 4.06, 8.13, 9.95],
			'lightgreen', 'green', 3).
		format('ivory', 'gray').
		gridlines({stroke: 'gray', strokeDashArray: '2,2'}, 'gray');
	svg.graph.xAxis.title('Year', 'green').scale(0, 3).
		ticks(1, 0).labels(['2002', '2004', '2005', '2006']);
	svg.graph.yAxis.title('Percentage').ticks(10, 5);
	svg.graph.legend.settings({fill: 'lightgoldenrodyellow',
		stroke: 'gray'});
	svg.graph.status(showGraphStatus);
}

// Draw a new graph with the selected options
$('#graphIt').click(function() {
	var chartType = $('#chartType').val();
	var chartLegend = parseInt($('#chartLegend').val(), 10);
	var seriesFill = ($('#seriesFill').val() == 'plain' ? 0 : 1);
	var svg = $('#svggraph').svg('get');
	svg.graph.noDraw().
		legend.show(chartLegend).area(legendAreas[chartLegend]).end().
		series(0).format(fills[0][seriesFill]).end().
		series(1).format(fills[1][seriesFill]).end().
		series(2).format(fills[2][seriesFill]).end().
		area(chartAreas[chartLegend]).
		type(chartType, {explode: 2, explodeDist: 10}).redraw();
	chartType = $.svg.graphing.chartTypes()[chartType];
	$('#graphDesc').text(chartType.description());
	var options = '';
	for (var i = 0; i < chartType.options().length; i++) {
		options += '<li>' + chartType.options()[i] + '</li>';
	}
	$('#graphOptions').html(options || '<li>None</li>');
	resetSize(svg);
});

function showGraphStatus(label, value) {
	$('#svggraph').attr('title', (label ? label + ' ' + value : ''));
}

Plotting

Use the plotting extension to display the plots of numeric functions on a grid.

Add the jQuery SVG plotting extension in the head section of your page.

<script type="text/javascript" src="jquery.svgplot.js"></script>

Then access the extra functionality via the plot object within the SVG root. As well as the functions and their formatting, you can control the plot title, axes, gridlines, labels, and legend.

Zoom with x/y units and legend  

This is the code behind the plotting.

$('#svgplot').svg(initPlot);
		
var plotZooms = [[-2, 2, -1.5, 1.5], [-10, 10, -10, 10]];
var chartAreas = [[0.1, 0.1, 0.95, 0.9], [0.2, 0.1, 0.95, 0.9],
	[0.1, 0.1, 0.8, 0.9], [0.1, 0.25, 0.9, 0.9], [0.1, 0.1, 0.9, 0.8]];
var legendAreas = [[0.0, 0.0, 0.0, 0.0], [0.005, 0.1, 0.125, 0.5],
	[0.85, 0.1, 0.97, 0.5], [0.2, 0.1, 0.8, 0.2], [0.2, 0.9, 0.8, 0.995]];
	
function initPlot(svg) {
	svg.plot.noDraw().title('Functions', 'blue').
		addFunction('Sine', Math.sin, 'blue', 3).
		addFunction('Cosine', Math.cos,
			[-Math.PI, Math.PI], 20, 'red', 3).
		addFunction('Decaying', decay, 'green', 3).
		format('ivory', 'gray').
		gridlines({stroke: 'gray', strokeDashArray: '2,2'}, 'gray');
	svg.plot.xAxis.scale(-1, 3.5).ticks(1, 0.2);
	svg.plot.yAxis.scale(-1.5, 1.5).ticks(1, 0.2);
	svg.plot.legend.settings({fill: 'lightgoldenrodyellow',
		stroke: 'gray'});
	svg.plot.status(showPlotStatus);
}

// Plot a new function with the selected options
$('#plotIt').click(function() {
	var plotZoom = parseInt($('#plotZoom').val(), 10);
	var plotEqual = parseInt($('#plotEqual').val(), 10);
	var plotLegend = parseInt($('#plotLegend').val(), 10);
	var svg = $('#svgplot').svg('get');
	svg.plot.noDraw().
		legend.show(plotLegend).area(legendAreas[plotLegend]).end().
		xAxis.scale(plotZooms[plotZoom][0], plotZooms[plotZoom][1]).end().
		yAxis.scale(plotZooms[plotZoom][2], plotZooms[plotZoom][3]).end().
		area(chartAreas[plotLegend]).equalXY(plotEqual).redraw();
	resetSize(svg);
});

// Decaying sine wave
function decay(x) {
	return Math.exp(-0.4 * x) * Math.sin(x);
}

function showPlotStatus(label) {
	$('#svgplot').attr('title', label);
}

Mixture of Graphs/Plots/etc.

You can combine graphs, plots, and other SVG elements in the one document. A default container (embedded <svg>) is created for each of a graph and a plot. You can change the settings for these or specify a new container and size and position it appropriately.

This is the code behind the mixture.

$('#svgmix').svg({onLoad: drawMixture});

function drawMixture(svg) {
	var g = svg.group({'font-weight': 'bold'});
	svg.text(g, 600, 100, 'This graph is in its');
	svg.text(g, 600, 120, 'own <svg> element');
	svg.text(g, 150, 450, 'As is this plot');
	// Graph
	svg.change(svg.graph.container(),
		{width: 600, height: 350, 'font-size': 12});
	svg.graph.noDraw().
		title('Browser Usage').type('column').area([0.1, 0.1, 0.9, 0.8]).
		addSeries('IE', [95.97, 91.80, 88.16, 86.64],
			'lightblue', 'blue', 3).
		addSeries('Netscape', [3.39, 2.83, 1.61, 0.00], 'pink', 'red', 3).
		addSeries('Firefox', [0.00, 4.06, 8.13, 9.95],
			'lightgreen', 'green', 3).
		format('ivory', 'gray').
		gridlines({stroke: 'gray', strokeDashArray: '2,2'}, 'gray').
		xAxis.title('Year', 30).scale(0, 3).
		ticks(1, 0).labels(['2002', '2004', '2005', '2006']).end().
		yAxis.title('Percentage').ticks(10, 5).end().
		legend.show(true).area([0.2, 0.9, 0.8, 0.995]).
		settings({fill: 'lightgoldenrodyellow', stroke: 'gray'}).end().
		redraw();
	// Plot
	svg.plot.noDraw().container(svg.svg(300, 350, 400, 350)).
		title('Functions').area([0.1, 0.1, 0.9, 0.8]).equalXY(true).
		addFunction('Sine', Math.sin, 'blue', 3).
		addFunction('Cosine', Math.cos, [-Math.PI, Math.PI], 20, 'red', 3).
		addFunction('Decaying', decay, 'green', 3).
		format('ivory', 'gray').
		gridlines({stroke: 'gray', strokeDashArray: '2,2'}, 'gray').
		xAxis.scale(-1, 3.5).ticks(1, 0.2).end().
		yAxis.scale(-1.5, 1.5).ticks(1, 0.2).end().
		legend.show(true).area([0.1, 0.9, 0.9, 0.995]).
		settings({fill: 'lightgoldenrodyellow', stroke: 'gray'}).end().
		redraw();
	resetSize(svg, 800, 700);
}

// Decaying sine wave
function decay(x) {
	return Math.exp(-0.4 * x) * Math.sin(x);
}

SVG DOM

The SVG DOM is different to the HTML DOM for which jQuery was designed. In particular, any attributes that can be animated are stored as objects instead of plain strings. This includes the class attribute. Thus, jQuery's functions that work with classes don't work on SVG nodes.

To overcome this problem you can use the jQuery SVG DOM extension. Add the extension in the head section of your page.

<script type="text/javascript" src="jquery.svgdom.js"></script>

Then just use jQuery's class and attribute functions on SVG nodes as well: addClass, removeClass, toggleClass, hasClass, attr, and removeAttr.

Use the power of jQuery to select nodes in the SVG document with this extension. Provide the SVG root element as the context for your selections:

$(selector, svg.root())...

Unfortunately, there are some small modifications needed to the base jQuery code for IE that cannot be overridden in the extension. A modified jQuery 1.4.2 is available for download. A modified jQuery 1.3.2 is also available for download. Show mods

In the event.add function (line 1644, v1.4.2):

if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
	// Bind the global event handler to the element
	try { // SVG
		elem.addEventListener(type, eventHandle, false);
	}
	catch(e) {
		if (elem.attachEvent)
			elem.attachEvent("on" + type, eventHandle);
	}
}

In the event.remove function (line 1770, v1.4.2):

if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
	try { // SVG
		elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
	}
	catch (e) {
		if (elem.detachEvent)
			elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
	}
}

In the Sizzle function (line 2741, v1.4.2):

if ( toString.call(checkSet) === "[object Array]" ) {
	if ( !prune ) {
		results.push.apply( results, checkSet );
	} else if ( context && context.nodeType === 1 ) {
		for ( var i = 0; checkSet[i] != null; i++ ) {
			if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
				results.push( set[i] || set.item(i) ); // SVG
			}
		}
	} else {
		for ( var i = 0; checkSet[i] != null; i++ ) {
			if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
				results.push( set[i] || set.item(i) ); // SVG
			}
		}
	}
} else {...

In the fallback for the Sizzle makeArray function (line 3346, v1.4.2):

if ( toString.call(array) === "[object Array]" ) {
	Array.prototype.push.apply( ret, array );
} else {
	if ( typeof array.length === "number" ) {
		for ( var i = 0, l = array.length; i < l; i++ ) {
			ret.push( array[i] || array.item(i) ); // SVG
		}
	} else {
		for ( var i = 0; array[i]; i++ ) {
			ret.push( array[i] );
		}
	}
}

The structure of the sample SVG document below is as follows:

Select

and fill with  

or or click/mouseover 

$('#svgselect').svg({onLoad: function(svg) {
		svg.rect(10, 20, 150, 100, {id: 'rect1',
			fill: 'red', stroke: 'black', strokeWidth: 3});
		svg.circle(100, 150, 75, {id: 'circle1',
			fill: 'yellow', stroke: 'black', strokeWidth: 3});
		var g = svg.group({transform: 'translate(200,20)'});
		svg.circle(g, 100, 100, 75, {id: 'circle2', class_: 'grouped',
			fill: 'yellow', stroke: 'black', strokeWidth: 3});
		svg.rect(g, 10, 150, 150, 100, {id: 'rect2', class_: 'grouped',
			fill: 'red', stroke: 'black', strokeWidth: 3});
		resetSize(svg, '100%', '100%');
	}
});

$('#selectPath').change(function() {
	$('#selector').val($(this).val());
});

$('#fillButton').click(function() {
	var svg = $('#svgselect').svg('get');
	$($('#selector').val(), svg.root()).attr('fill', $('#selectColour').val());
});

$('#eventButton').click(function() {
	var svg = $('#svgselect').svg('get');
	if ($('#selectEventAdd').is(':checked')) {
		$($('#selector').val(), svg.root()).bind('click', svgClicked).
			bind('mouseover', svgOver).bind('mouseout', svgOut);
	}
	else {
		$($('#selector').val(), svg.root()).
			unbind('click mouseover mouseout');
	}
});

function svgClicked() {
	alert('This is a ' + $(this).attr('fill') + ' ' + this.nodeName);
}

function svgOver() {
	$(this).attr('stroke', 'lime');
}

function svgOut() {
	$(this).attr('stroke', 'black');
}

Tips and Tricks

In the Wild

This tab highlights examples of this plugin in use "in the wild".

To add another example, please contact me (kbwood{at}iinet.com.au) and provide the plugin name, the URL of your site, its title, and a short description of its purpose and where/how the plugin is used.

Quick Reference

A list of available fields and functions. For more detail see the documentation reference page.

$(selector).svg({
	loadURL: '', // External document to load
	onLoad: null, // Callback once loaded
	settings: {}}) // Additional settings for SVG element
$(selector).svg(loadURL)
$(selector).svg(onLoad)
$(selector).svg('get') // Retrieve SVG wrapper
$(selector).svg('destroy') // Remove SVG functionality

$.svg.addExtension(name, extClass) // Extend SVG functionality

svg.root()
svg.configure(settings, clear)
svg.getElementById(id)
svg.change(element, settings)
svg.title(parent, text, settings)
svg.describe(parent, text, settings)
svg.defs(parent, id, settings)
svg.symbol(parent, id, x1, y1, width, height, settings)
svg.marker(parent, id, refX, refY, mWidth, mHeight, orient, settings)
svg.style(parent, styles, settings)
svg.script(parent, script, type, settings)
svg.linearGradient(parent, id, stops, x1, y1, x2, y2, settings)
svg.radialGradient(parent, id, stops, cx, cy, r, fx, fy, settings)
svg.pattern(parent, id, x, y, width, height, vx, vy, vwidth, vheight, settings)
svg.mask(parent, id, x, y, width, height, settings)
svg.createPath()
svg.createText()
svg.svg(parent, x, y, width, height, vx, vy, vwidth, vheight, settings)
svg.group(parent, id, settings)
svg.use(parent, x, y, width, height, ref, settings)
svg.link(parent, ref, settings)
svg.image(parent, x, y, width, height, ref, settings)
svg.path(parent, path, settings)
svg.rect(parent, x, y, width, height, rx, ry, settings)
svg.circle(parent, cx, cy, r, settings)
svg.ellipse(parent, cx, cy, rx, ry, settings)
svg.line(parent, x1, y1, x2, y2, settings)
svg.polyline(parent, points, settings)
svg.polygon(parent, points, settings)
svg.text(parent, x, y, value, settings)
svg.textpath(parent, path, value, settings)
svg.other(parent, name, settings)
svg.add(parent, node)
svg.load(url, settings)
svg.remove(node)
svg.clear(attrsToo)
svg.toSVG(node)

path.reset()
path.move(x, y, relative)
path.line(x, y, relative)
path.horiz(x, relative)
path.vert(y, relative)
path.curveC(x1, y1, x2, y2, x, y, relative)
path.smoothC(x2, y2, x, y, relative)
path.curveQ(x1, y1, x, y, relative)
path.smoothQ(x, y, relative)
path.arc(rx, ry, xRotate, large, clockwise, x, y, relative)
path.close()
path.path()

text.reset()
text.string(value)
text.span(value, settings)
text.ref(id, settings)
text.path(id, value, settings)

Comments

Great work. Congratulations! I am excited to see your good work.

Felipe Sanches

Love the jquery svg extension you've written. Stunningly neat.

Murray

Thanks for this plugin and it's documentation filled with examples. Learning by example was always my preferred way to learn.

Michel

We have been long-time SVG advocates and active with Inkscape. So love the idea of an easy to use SVG ajax plugin.

Miles Togoe

This is an amazing plugin! It has so many applications.

James Revillini

I am still amazed how quickly I have put something together using your plugin and the flexibility of SVG's.

Mark Flewellen

Contact Keith Wood at kbwood{at}iinet.com.au with comments or suggestions.

Change History

VersionDateChanges
1.4.323 Jan 2010
  • Allow wrapping of inline SVG
  • Allow parent in many calls to be a jQuery object
  • Clear corresponding style attribute when animating
  • Corrected retrieval of transform attribute
  • Corrected handling of style attributes
  • Graph and plot status no longer need to be global functions
1.4.205 Sep 2009
  • Added colour option to graph titleand graph axis labels and title functions
  • Allow explode option for pie charts to be a single number
  • Added colour option to plot title and plot axis format and title functions
1.4.118 Jul 2009
  • Added jQuery selector support for SVG DOM
  • Added jQuery event support for SVG DOM
  • Deprecated path functions moveTo, lineTo, horizTo, vertTo, curveCTo, smoothCTo, curveQTo, smoothQTo, and arcTo in favour of move, line, horiz, vert, curveC, smoothC, curveQ, smoothQ, and arc
1.4.006 Jun 2009
  • SVG attributes containing dashes (-) should now be specified in camel-case, e.g. strokeWidth instead of 'stroke-width'
  • SVG attributes that are JavaScript reserved words should have a following underscore (_), e.g. class_ instead of 'class'
  • Allowed simplified attachment with an onLoad function
  • Allowed simplified load with an onLoad function
  • Allowed load from text
  • Fixed animation initialisation
  • Separated jQuery/SVG DOM compatibility into an extension
  • Added jQuery attribute compatibility: attr and removeAttr
1.3.228 Mar 2009
  • Sped up document load (except IE)
  • Handled matrix transformations in svg-transform animations
  • Corrected error in animation of scale transform
  • Restored Renesis compatibility
1.3.124 Jan 2009
  • Allowed graphs and plots to have a specified container, so they can be combined with other SVG elements
  • Changed graphs and plots containers from group to svg elements
  • Replaced IDs on graph and plot elements with classes
  • Added node parameter to toSVG function
  • Added change function
  • Corrected custom label drawing for graphs
  • Added Google Chrome compatibility for graphs and plots
  • Corrected SVG ability recognition
  • Added fallback for CDATA sections in loaded documents
1.3.013 Dec 2008
  • Added SVG plotting plugin
  • Deprecated graph functions chartArea, chartFormat, chartOptions, and chartType in favour of area, format, options, and type
  • Added an index to graph series function to target individual series
  • Added end functions to graph series, axes, and legend
  • Added svg-viewBox animation
  • Added support for SVG nodes with jQuery addClass, removeClass, toggleClass, and hasClass
1.2.123 Aug 2008
  • Parent may be omitted if null in all function calls
  • Fixed addition of script elements
  • Fixed addition of style elements in Opera
1.2.019 Jul 2008
  • Internal changes for instance values
  • Renamed SVGRoot to SVGWrapper
  • Added initPath setting for initial loading of SVG in IE
  • Added root function to provide access to the SVG root element
  • Updated to work in Safari 3.1.1+
1.1.114 Jun 2008
  • Fixed bug in load external document in IE
  • Enhanced load with changeSize and onLoad settings
  • add, load, remove, and clear functions now return a reference to the SVG root object
1.1.007 Jun 2008
  • Updated interface to conform to jQuery UI standards
  • Added 'destroy' command
  • Added optional rounding attributes to rect function and removed roundrect function
  • Changed handling of settings with '-' in SVG or reserved words in JavaScript
  • Corrected error in other function
  • Other minor bug fixes
  • Support for Renesis Player in IE
  • Added SVG attribute animations plugin
  • Added 1.0.1 compatibility plugin
1.0.105 May 2008
  • Updated to work in FF 3
1.0.014 Sep 2007
  • Initial release

Valid XHTML 1.1