diff --git a/blank.svg b/blank.svg deleted file mode 100644 index 81783d3..0000000 --- a/blank.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/jquery.svg.css b/jquery.svg.css index 9430c62..a9e3867 100644 --- a/jquery.svg.css +++ b/jquery.svg.css @@ -1,14 +1,9 @@ /* http://keith-wood.name/svg.html - SVG for jQuery v1.4.5. - Written by Keith Wood (kbwood{at}iinet.com.au) August 2007. - Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and - MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. - Please attribute the author if you use it. */ - + SVG for jQuery v1.5.0. + Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.*/ svg\:svg { display: none; } - .svg_error { color: red; font-weight: bold; diff --git a/jquery.svg.js b/jquery.svg.js index 6a6a9b3..acb4db1 100644 --- a/jquery.svg.js +++ b/jquery.svg.js @@ -1,52 +1,41 @@ /* http://keith-wood.name/svg.html - SVG for jQuery v1.4.5. + SVG for jQuery v1.5.0. Written by Keith Wood (kbwood{at}iinet.com.au) August 2007. - Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and - MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. + Available under the MIT (http://keith-wood.name/licence.html) license. Please attribute the author if you use it. */ (function($) { // Hide scope, no $ conflict -/* SVG manager. - Use the singleton instance of this class, $.svg, - to interact with the SVG functionality. */ +/** The SVG manager. +

Use the singleton instance of this class, $.svg, + to interact with the SVG functionality.

+

Expects HTML like:

+
<div></div>
+ @module SVGManager */ function SVGManager() { this._settings = []; // Settings to be remembered per SVG object this._extensions = []; // List of SVG extensions added to SVGWrapper // for each entry [0] is extension name, [1] is extension class (function) // the function takes one parameter - the SVGWrapper instance this.regional = []; // Localisations, indexed by language, '' for default (English) - this.regional[''] = {errorLoadingText: 'Error loading', - notSupportedText: 'This browser does not support SVG'}; + this.regional[''] = {errorLoadingText: 'Error loading'}; this.local = this.regional['']; // Current localisation this._uuid = new Date().getTime(); - this._renesis = detectActiveX('RenesisX.RenesisCtrl'); + this._ie = !!window.ActiveXObject; } -/* Determine whether a given ActiveX control is available. - @param classId (string) the ID for the ActiveX control - @return (boolean) true if found, false if not */ -function detectActiveX(classId) { - try { - return !!(window.ActiveXObject && new ActiveXObject(classId)); - } - catch (e) { - return false; - } -} - -var PROP_NAME = 'svgwrapper'; - $.extend(SVGManager.prototype, { - /* Class name added to elements to indicate already configured with SVG. */ + /** Class name added to elements to indicate already configured with SVG. */ markerClassName: 'hasSVG', + /** Name of the data property for instance settings. */ + propertyName: 'svgwrapper', - /* SVG namespace. */ + /** SVG namespace. */ svgNS: 'http://www.w3.org/2000/svg', - /* XLink namespace. */ + /** XLink namespace. */ xlinkNS: 'http://www.w3.org/1999/xlink', - /* SVG wrapper class. */ + /** SVG wrapper class. */ _wrapperClass: SVGWrapper, /* Camel-case versions of attribute names containing dashes or are reserved words. */ @@ -82,15 +71,15 @@ $.extend(SVGManager.prototype, { /* Add the SVG object to its container. */ _attachSVG: function(container, settings) { - var svg = (container.namespaceURI == this.svgNS ? container : null); + var svg = (container.namespaceURI === this.svgNS ? container : null); var container = (svg ? null : container); if ($(container || svg).hasClass(this.markerClassName)) { return; } - if (typeof settings == 'string') { + if (typeof settings === 'string') { settings = {loadURL: settings}; } - else if (typeof settings == 'function') { + else if (typeof settings === 'function') { settings = {onLoad: settings}; } $(container || svg).addClass(this.markerClassName); @@ -109,42 +98,7 @@ $.extend(SVGManager.prototype, { this._afterLoad(container, svg, settings || {}); } catch (e) { - if ($.browser.msie) { - if (!container.id) { - container.id = 'svg' + (this._uuid++); - } - this._settings[container.id] = settings; - container.innerHTML = ''; - } - else { - container.innerHTML = '

' + - this.local.notSupportedText + '

'; - } - } - }, - - /* SVG callback after loading - register SVG root. */ - _registerSVG: function() { - for (var i = 0; i < document.embeds.length; i++) { // Check all - var container = document.embeds[i].parentNode; - if (!$(container).hasClass($.svg.markerClassName) || // Not SVG - $.data(container, PROP_NAME)) { // Already done - continue; - } - var svg = null; - try { - svg = document.embeds[i].getSVGDocument(); - } - catch(e) { - setTimeout($.svg._registerSVG, 250); // Renesis takes longer to load - return; - } - svg = (svg ? svg.documentElement : null); - if (svg) { - $.svg._afterLoad(container, svg); - } + $(container).html('

SVG is not supported natively on this browser

'); } }, @@ -153,7 +107,7 @@ $.extend(SVGManager.prototype, { var settings = settings || this._settings[container.id]; this._settings[container ? container.id : ''] = null; var wrapper = new this._wrapperClass(svg, container); - $.data(container || svg, PROP_NAME, wrapper); + $.data(container || svg, $.svg.propertyName, wrapper); try { if (settings.loadURL) { // Load URL wrapper.load(settings.loadURL, settings); @@ -170,51 +124,48 @@ $.extend(SVGManager.prototype, { } }, - /* Return the SVG wrapper created for a given container. - @param container (string) selector for the container or - (element) the container for the SVG object or - jQuery collection - first entry is the container - @return (SVGWrapper) the corresponding SVG wrapper element, or null if not attached */ + /** Return the SVG wrapper created for a given container. + @param container {string|Element|jQuery} Selector for the container or + the container for the SVG object or jQuery collection where first entry is the container. + @return {SVGWrapper} The corresponding SVG wrapper element, or null if not attached. */ _getSVG: function(container) { - container = (typeof container == 'string' ? $(container)[0] : - (container.jquery ? container[0] : container)); - return $.data(container, PROP_NAME); + return $(container).data(this.propertyName); }, - /* Remove the SVG functionality from a div. - @param container (element) the container for the SVG object */ + /** Remove the SVG functionality from a div. + @param container {Element} The container for the SVG object. */ _destroySVG: function(container) { - var $container = $(container); - if (!$container.hasClass(this.markerClassName)) { + container = $(container); + if (!container.hasClass(this.markerClassName)) { return; } - $container.removeClass(this.markerClassName); - if (container.namespaceURI != this.svgNS) { - $container.empty(); + container.removeClass(this.markerClassName).removeData(this.propertyName); + if (container[0].namespaceURI !== this.svgNS) { + container.empty(); } - $.removeData(container, PROP_NAME); }, - /* Extend the SVGWrapper object with an embedded class. - The constructor function must take a single parameter that is + /** Extend the SVGWrapper object with an embedded class. +

The constructor function must take a single parameter that is a reference to the owning SVG root object. This allows the - extension to access the basic SVG functionality. - @param name (string) the name of the SVGWrapper attribute to access the new class - @param extClass (function) the extension class constructor */ + extension to access the basic SVG functionality.

+ @param name {string} The name of the SVGWrapper attribute to access the new class. + @param extClass {function} The extension class constructor. */ addExtension: function(name, extClass) { this._extensions.push([name, extClass]); }, - /* Does this node belong to SVG? - @param node (element) the node to be tested - @return (boolean) true if an SVG node, false if not */ + /** Does this node belong to SVG? + @param node {Element} The node to be tested. + @return {boolean} true if an SVG node, false if not. */ isSVGElem: function(node) { - return (node.nodeType == 1 && node.namespaceURI == $.svg.svgNS); + return (node.nodeType === 1 && node.namespaceURI === $.svg.svgNS); } }); -/* The main SVG interface, which encapsulates the SVG element. - Obtain a reference from $().svg('get') */ +/** The main SVG interface, which encapsulates the SVG element. +

Obtain a reference from $().svg('get')

+ @module SVGWrapper */ function SVGWrapper(svg, container) { this._svg = svg; // The SVG root node this._container = container; // The containing div @@ -226,28 +177,30 @@ function SVGWrapper(svg, container) { $.extend(SVGWrapper.prototype, { - /* Retrieve the width of the SVG object. */ - _width: function() { + /** Retrieve the width of the SVG object. + @return {number} The width of the SVG canvas. */ + width: function() { return (this._container ? this._container.clientWidth : this._svg.width); }, - /* Retrieve the height of the SVG object. */ - _height: function() { + /** Retrieve the height of the SVG object. + @return {number} The height of the SVG canvas. */ + height: function() { return (this._container ? this._container.clientHeight : this._svg.height); }, - /* Retrieve the root SVG element. - @return the top-level SVG element */ + /** Retrieve the root SVG element. + @return {SVGElement} The top-level SVG element. */ root: function() { return this._svg; }, - /* Configure a SVG node. - @param node (element, optional) the node to configure - @param settings (object) additional settings for the root - @param clear (boolean) true to remove existing attributes first, - false to add to what is already there (optional) - @return (SVGWrapper) this root */ + /** Configure a SVG node. + @param [node] {SVGElement} The node to configure, or the SVG root if not specified. + @param settings {object} Additional settings for the root. + @param [clear=false] {boolean} true to remove existing attributes first, + false to add to what is already there. + @return {SVGWrapper} This wrapper. */ configure: function(node, settings, clear) { if (!node.nodeName) { clear = settings; @@ -257,8 +210,8 @@ $.extend(SVGWrapper.prototype, { if (clear) { for (var i = node.attributes.length - 1; i >= 0; i--) { var attr = node.attributes.item(i); - if (!(attr.nodeName == 'onload' || attr.nodeName == 'version' || - attr.nodeName.substring(0, 5) == 'xmlns')) { + if (!(attr.nodeName === 'onload' || attr.nodeName === 'version' || + attr.nodeName.substring(0, 5) === 'xmlns')) { node.attributes.removeNamedItem(attr.nodeName); } } @@ -269,17 +222,17 @@ $.extend(SVGWrapper.prototype, { return this; }, - /* Locate a specific element in the SVG document. - @param id (string) the element's identifier - @return (element) the element reference, or null if not found */ + /** Locate a specific element in the SVG document. + @param id {string} The element's identifier. + @return {SVGElement} The element reference, or null if not found. */ getElementById: function(id) { return this._svg.ownerDocument.getElementById(id); }, - /* Change the attributes for a SVG node. - @param element (SVG element) the node to change - @param settings (object) the new settings - @return (SVGWrapper) this root */ + /** Change the attributes for a SVG node. + @param element {SVGElement} The node to change. + @param settings {object} The new settings. + @return {SVGWrapper} This wrapper. */ change: function(element, settings) { if (element) { for (var name in settings) { @@ -294,7 +247,12 @@ $.extend(SVGWrapper.prototype, { return this; }, - /* Check for parent being absent and adjust arguments accordingly. */ + /** Check for parent being absent and adjust arguments accordingly. + @private + @param values {string[]} The given parameters. + @param names {string[]} The names of the parameters in order. + @param optSettings {string[]} The names of optional parameters. + @return {object} An object representing the named parameters. */ _args: function(values, names, optSettings) { names.splice(0, 0, 'parent'); names.splice(names.length, 0, 'settings'); @@ -303,7 +261,7 @@ $.extend(SVGWrapper.prototype, { if (values[0] != null && values[0].jquery) { values[0] = values[0][0]; } - if (values[0] != null && !(typeof values[0] == 'object' && values[0].nodeName)) { + if (values[0] != null && !(typeof values[0] === 'object' && values[0].nodeName)) { args['parent'] = null; offset = 1; } @@ -312,7 +270,7 @@ $.extend(SVGWrapper.prototype, { } if (optSettings) { $.each(optSettings, function(i, value) { - if (typeof args[value] == 'object') { + if (typeof args[value] === 'object') { args.settings = args[value]; args[value] = null; } @@ -321,11 +279,11 @@ $.extend(SVGWrapper.prototype, { return args; }, - /* Add a title. - @param parent (element or jQuery) the parent node for the new title (optional) - @param text (string) the text of the title - @param settings (object) additional settings for the title (optional) - @return (element) the new title node */ + /** Add a title. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param text {string} The text of the title. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new title node. */ title: function(parent, text, settings) { var args = this._args(arguments, ['text']); var node = this._makeNode(args.parent, 'title', args.settings || {}); @@ -333,11 +291,11 @@ $.extend(SVGWrapper.prototype, { return node; }, - /* Add a description. - @param parent (element or jQuery) the parent node for the new description (optional) - @param text (string) the text of the description - @param settings (object) additional settings for the description (optional) - @return (element) the new description node */ + /** Add a description. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param text {string} The text of the description. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new description node. */ describe: function(parent, text, settings) { var args = this._args(arguments, ['text']); var node = this._makeNode(args.parent, 'desc', args.settings || {}); @@ -345,168 +303,162 @@ $.extend(SVGWrapper.prototype, { return node; }, - /* Add a definitions node. - @param parent (element or jQuery) the parent node for the new definitions (optional) - @param id (string) the ID of this definitions (optional) - @param settings (object) additional settings for the definitions (optional) - @return (element) the new definitions node */ + /** Add a definitions node. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param [id] {string} The ID of this definitions (optional). + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new definitions node. */ defs: function(parent, id, settings) { var args = this._args(arguments, ['id'], ['id']); - return this._makeNode(args.parent, 'defs', $.extend( - (args.id ? {id: args.id} : {}), args.settings || {})); - }, - - /* Add a symbol definition. - @param parent (element or jQuery) the parent node for the new symbol (optional) - @param id (string) the ID of this symbol - @param x1 (number) the left coordinate for this symbol - @param y1 (number) the top coordinate for this symbol - @param width (number) the width of this symbol - @param height (number) the height of this symbol - @param settings (object) additional settings for the symbol (optional) - @return (element) the new symbol node */ + return this._makeNode(args.parent, 'defs', $.extend((args.id ? {id: args.id} : {}), args.settings || {})); + }, + + /** Add a symbol definition. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param id {string} The ID of this symbol. + @param x1 {number} The left coordinate for this symbol. + @param y1 {number} The top coordinate for this symbol. + @param width {number} The width of this symbol. + @param height {number} The height of this symbol. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new symbol node. */ symbol: function(parent, id, x1, y1, width, height, settings) { var args = this._args(arguments, ['id', 'x1', 'y1', 'width', 'height']); return this._makeNode(args.parent, 'symbol', $.extend({id: args.id, - viewBox: args.x1 + ' ' + args.y1 + ' ' + args.width + ' ' + args.height}, - args.settings || {})); - }, - - /* Add a marker definition. - @param parent (element or jQuery) the parent node for the new marker (optional) - @param id (string) the ID of this marker - @param refX (number) the x-coordinate for the reference point - @param refY (number) the y-coordinate for the reference point - @param mWidth (number) the marker viewport width - @param mHeight (number) the marker viewport height - @param orient (string or int) 'auto' or angle (degrees) (optional) - @param settings (object) additional settings for the marker (optional) - @return (element) the new marker node */ + viewBox: args.x1 + ' ' + args.y1 + ' ' + args.width + ' ' + args.height}, args.settings || {})); + }, + + /** Add a marker definition. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param id {string} The ID of this marker. + @param refX {number} The x-coordinate for the reference point. + @param refY {number} The y-coordinate for the reference point. + @param mWidth {number} The marker viewport width. + @param mHeight {number} The marker viewport height. + @param [orient] {string|number} 'auto' or angle (degrees). + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new marker node. */ marker: function(parent, id, refX, refY, mWidth, mHeight, orient, settings) { - var args = this._args(arguments, ['id', 'refX', 'refY', - 'mWidth', 'mHeight', 'orient'], ['orient']); + var args = this._args(arguments, ['id', 'refX', 'refY', 'mWidth', 'mHeight', 'orient'], ['orient']); return this._makeNode(args.parent, 'marker', $.extend( {id: args.id, refX: args.refX, refY: args.refY, markerWidth: args.mWidth, markerHeight: args.mHeight, orient: args.orient || 'auto'}, args.settings || {})); }, - /* Add a style node. - @param parent (element or jQuery) the parent node for the new node (optional) - @param styles (string) the CSS styles - @param settings (object) additional settings for the node (optional) - @return (element) the new style node */ + /** Add a style node. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param styles {string} The CSS styles. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new style node. */ style: function(parent, styles, settings) { var args = this._args(arguments, ['styles']); - var node = this._makeNode(args.parent, 'style', $.extend( - {type: 'text/css'}, args.settings || {})); + var node = this._makeNode(args.parent, 'style', $.extend({type: 'text/css'}, args.settings || {})); node.appendChild(this._svg.ownerDocument.createTextNode(args.styles)); - if ($.browser.opera) { - $('head').append(''); - } return node; }, - /* Add a script node. - @param parent (element or jQuery) the parent node for the new node (optional) - @param script (string) the JavaScript code - @param type (string) the MIME type for the code (optional, default 'text/javascript') - @param settings (object) additional settings for the node (optional) - @return (element) the new script node */ + /** Add a script node. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param script {string} The JavaScript code. + @param [type='text/javascript'] {string} The MIME type for the code. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new script node. */ script: function(parent, script, type, settings) { var args = this._args(arguments, ['script', 'type'], ['type']); var node = this._makeNode(args.parent, 'script', $.extend( {type: args.type || 'text/javascript'}, args.settings || {})); node.appendChild(this._svg.ownerDocument.createTextNode(args.script)); - if (!$.browser.mozilla) { + if ($.svg._ie) { $.globalEval(args.script); } return node; }, - /* Add a linear gradient definition. - Specify all of x1, y1, x2, y2 or none of them. - @param parent (element or jQuery) the parent node for the new gradient (optional) - @param id (string) the ID for this gradient - @param stops (string[][]) the gradient stops, each entry is - [0] is offset (0.0-1.0 or 0%-100%), [1] is colour, - [2] is opacity (optional) - @param x1 (number) the x-coordinate of the gradient start (optional) - @param y1 (number) the y-coordinate of the gradient start (optional) - @param x2 (number) the x-coordinate of the gradient end (optional) - @param y2 (number) the y-coordinate of the gradient end (optional) - @param settings (object) additional settings for the gradient (optional) - @return (element) the new gradient node */ + /** Add a linear gradient definition. +

Specify all of x1, y1, x2, y2 or none of them.

+ @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param id {string} The ID for this gradient. + @param stops {string[][]} The gradient stops, each entry is [0] is offset (0.0-1.0 or 0%-100%), + [1] is colour, [2] is opacity (optional). + @param [x1] {number} The x-coordinate of the gradient start. + @param [y1] {number} The y-coordinate of the gradient start. + @param [x2] {number} The x-coordinate of the gradient end. + @param [y2] {number} The y-coordinate of the gradient end. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new linear gradient node. */ linearGradient: function(parent, id, stops, x1, y1, x2, y2, settings) { - var args = this._args(arguments, - ['id', 'stops', 'x1', 'y1', 'x2', 'y2'], ['x1']); - var sets = $.extend({id: args.id}, - (args.x1 != null ? {x1: args.x1, y1: args.y1, x2: args.x2, y2: args.y2} : {})); - return this._gradient(args.parent, 'linearGradient', - $.extend(sets, args.settings || {}), args.stops); - }, - - /* Add a radial gradient definition. - Specify all of cx, cy, r, fx, fy or none of them. - @param parent (element or jQuery) the parent node for the new gradient (optional) - @param id (string) the ID for this gradient - @param stops (string[][]) the gradient stops, each entry - [0] is offset, [1] is colour, [2] is opacity (optional) - @param cx (number) the x-coordinate of the largest circle centre (optional) - @param cy (number) the y-coordinate of the largest circle centre (optional) - @param r (number) the radius of the largest circle (optional) - @param fx (number) the x-coordinate of the gradient focus (optional) - @param fy (number) the y-coordinate of the gradient focus (optional) - @param settings (object) additional settings for the gradient (optional) - @return (element) the new gradient node */ + var args = this._args(arguments, ['id', 'stops', 'x1', 'y1', 'x2', 'y2'], ['x1']); + var sets = $.extend({id: args.id}, + (args.x1 != null ? {x1: args.x1, y1: args.y1, x2: args.x2, y2: args.y2} : {})); + return this._gradient(args.parent, 'linearGradient', $.extend(sets, args.settings || {}), args.stops); + }, + + /** Add a radial gradient definition. +

Specify all of cx, cy, r, + fx, fy or none of them.

+ @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param id {string} The ID for this gradient. + @param stops {string[][]} The gradient stops, each entry [0] is offset (0.0-1.0 or 0%-100%), + [1] is colour, [2] is opacity (optional). + @param [cx] {number} The x-coordinate of the largest circle centre. + @param [cy] {number} The y-coordinate of the largest circle centre. + @param [r] {number} The radius of the largest circle. + @param [fx] {number} The x-coordinate of the gradient focus. + @param [fy] {number} The y-coordinate of the gradient focus. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new radial gradient node. */ radialGradient: function(parent, id, stops, cx, cy, r, fx, fy, settings) { - var args = this._args(arguments, - ['id', 'stops', 'cx', 'cy', 'r', 'fx', 'fy'], ['cx']); - var sets = $.extend({id: args.id}, (args.cx != null ? - {cx: args.cx, cy: args.cy, r: args.r, fx: args.fx, fy: args.fy} : {})); - return this._gradient(args.parent, 'radialGradient', - $.extend(sets, args.settings || {}), args.stops); - }, - - /* Add a gradient node. */ + var args = this._args(arguments, ['id', 'stops', 'cx', 'cy', 'r', 'fx', 'fy'], ['cx']); + var sets = $.extend({id: args.id}, + (args.cx != null ? {cx: args.cx, cy: args.cy, r: args.r, fx: args.fx, fy: args.fy} : {})); + return this._gradient(args.parent, 'radialGradient', $.extend(sets, args.settings || {}), args.stops); + }, + + /** Add a gradient node. + @private + @param parent {SVGElement|jQuery} The parent node for the new node. + @param name {string} The type of gradient node to create. + @param settings {object} The settings for this node. + @param stops {string[][]} The gradient stops. + @return {SVGElement} The new gradient node. */ _gradient: function(parent, name, settings, stops) { var node = this._makeNode(parent, name, settings); for (var i = 0; i < stops.length; i++) { var stop = stops[i]; - this._makeNode(node, 'stop', $.extend( - {offset: stop[0], stopColor: stop[1]}, + this._makeNode(node, 'stop', $.extend({offset: stop[0], stopColor: stop[1]}, (stop[2] != null ? {stopOpacity: stop[2]} : {}))); } return node; }, - /* Add a pattern definition. - Specify all of vx, vy, xwidth, vheight or none of them. - @param parent (element or jQuery) the parent node for the new pattern (optional) - @param id (string) the ID for this pattern - @param x (number) the x-coordinate for the left edge of the pattern - @param y (number) the y-coordinate for the top edge of the pattern - @param width (number) the width of the pattern - @param height (number) the height of the pattern - @param vx (number) the minimum x-coordinate for view box (optional) - @param vy (number) the minimum y-coordinate for the view box (optional) - @param vwidth (number) the width of the view box (optional) - @param vheight (number) the height of the view box (optional) - @param settings (object) additional settings for the pattern (optional) - @return (element) the new pattern node */ + /** Add a pattern definition. +

Specify all of vx, vy, xwidth, + vheight or none of them.

+ @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param id {string} The ID for this pattern. + @param x {number} The x-coordinate for the left edge of the pattern. + @param y {number} The y-coordinate for the top edge of the pattern. + @param width {number} The width of the pattern. + @param height {number} The height of the pattern. + @param [vx] {number} The minimum x-coordinate for view box. + @param [vy] {number} The minimum y-coordinate for the view box. + @param [vwidth] {number} The width of the view box. + @param [vheight] {number} The height of the view box. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new pattern definition node. */ pattern: function(parent, id, x, y, width, height, vx, vy, vwidth, vheight, settings) { - var args = this._args(arguments, ['id', 'x', 'y', 'width', 'height', - 'vx', 'vy', 'vwidth', 'vheight'], ['vx']); - var sets = $.extend({id: args.id, x: args.x, y: args.y, - width: args.width, height: args.height}, (args.vx != null ? - {viewBox: args.vx + ' ' + args.vy + ' ' + args.vwidth + ' ' + args.vheight} : {})); + var args = this._args(arguments, ['id', 'x', 'y', 'width', 'height', 'vx', 'vy', 'vwidth', 'vheight'], ['vx']); + var sets = $.extend({id: args.id, x: args.x, y: args.y, width: args.width, height: args.height}, + (args.vx != null ? {viewBox: args.vx + ' ' + args.vy + ' ' + args.vwidth + ' ' + args.vheight} : {})); return this._makeNode(args.parent, 'pattern', $.extend(sets, args.settings || {})); }, - /* Add a clip path definition. - @param parent (element) the parent node for the new element (optional) - @param id (string) the ID for this path - @param units (string) either 'userSpaceOnUse' (default) or 'objectBoundingBox' (optional) - @return (element) the new clipPath node */ + /** Add a clip path definition. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param id {string} The ID for this path. + @param [units='userSpaceOnUse'] {string} Either 'userSpaceOnUse' or 'objectBoundingBox'. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new clip path definition node. */ clipPath: function(parent, id, units, settings) { var args = this._args(arguments, ['id', 'units']); args.units = args.units || 'userSpaceOnUse'; @@ -514,95 +466,92 @@ $.extend(SVGWrapper.prototype, { {id: args.id, clipPathUnits: args.units}, args.settings || {})); }, - /* Add a mask definition. - @param parent (element or jQuery) the parent node for the new mask (optional) - @param id (string) the ID for this mask - @param x (number) the x-coordinate for the left edge of the mask - @param y (number) the y-coordinate for the top edge of the mask - @param width (number) the width of the mask - @param height (number) the height of the mask - @param settings (object) additional settings for the mask (optional) - @return (element) the new mask node */ + /** Add a mask definition. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param id {string} The ID for this mask. + @param x {number} The x-coordinate for the left edge of the mask. + @param y {number} The y-coordinate for the top edge of the mask. + @param width {number} The width of the mask. + @param height {number} The height of the mask. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new mask definition node. */ mask: function(parent, id, x, y, width, height, settings) { var args = this._args(arguments, ['id', 'x', 'y', 'width', 'height']); return this._makeNode(args.parent, 'mask', $.extend( - {id: args.id, x: args.x, y: args.y, width: args.width, height: args.height}, - args.settings || {})); + {id: args.id, x: args.x, y: args.y, width: args.width, height: args.height}, args.settings || {})); }, - /* Create a new path object. - @return (SVGPath) a new path object */ + /** Create a new path object. + @return {SVGPath} A new path object. */ createPath: function() { return new SVGPath(); }, - /* Create a new text object. - @return (SVGText) a new text object */ + /** Create a new text object. + @return {SVGText} A new text object. */ createText: function() { return new SVGText(); }, - /* Add an embedded SVG element. - Specify all of vx, vy, vwidth, vheight or none of them. - @param parent (element or jQuery) the parent node for the new node (optional) - @param x (number) the x-coordinate for the left edge of the node - @param y (number) the y-coordinate for the top edge of the node - @param width (number) the width of the node - @param height (number) the height of the node - @param vx (number) the minimum x-coordinate for view box (optional) - @param vy (number) the minimum y-coordinate for the view box (optional) - @param vwidth (number) the width of the view box (optional) - @param vheight (number) the height of the view box (optional) - @param settings (object) additional settings for the node (optional) - @return (element) the new node */ + /** Add an embedded SVG element. +

Specify all of vx, vy, + vwidth, vheight or none of them.

+ @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param x {number} The x-coordinate for the left edge of the node. + @param y {number} The y-coordinate for the top edge of the node. + @param width {number} The width of the node. + @param height {number} The height of the node. + @param [vx] {number} The minimum x-coordinate for view box. + @param [vy] {number} The minimum y-coordinate for the view box. + @param [vwidth] {number} The width of the view box. + @param [vheight] {number} The height of the view box. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new svg node. */ svg: function(parent, x, y, width, height, vx, vy, vwidth, vheight, settings) { - var args = this._args(arguments, ['x', 'y', 'width', 'height', - 'vx', 'vy', 'vwidth', 'vheight'], ['vx']); + var args = this._args(arguments, ['x', 'y', 'width', 'height', 'vx', 'vy', 'vwidth', 'vheight'], ['vx']); var sets = $.extend({x: args.x, y: args.y, width: args.width, height: args.height}, - (args.vx != null ? {viewBox: args.vx + ' ' + args.vy + ' ' + - args.vwidth + ' ' + args.vheight} : {})); + (args.vx != null ? {viewBox: args.vx + ' ' + args.vy + ' ' + args.vwidth + ' ' + args.vheight} : {})); return this._makeNode(args.parent, 'svg', $.extend(sets, args.settings || {})); }, - /* Create a group. - @param parent (element or jQuery) the parent node for the new group (optional) - @param id (string) the ID of this group (optional) - @param settings (object) additional settings for the group (optional) - @return (element) the new group node */ + /** Create a group. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param [id] {string} The ID of this group. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new group node. */ group: function(parent, id, settings) { var args = this._args(arguments, ['id'], ['id']); return this._makeNode(args.parent, 'g', $.extend({id: args.id}, args.settings || {})); }, - /* Add a usage reference. - Specify all of x, y, width, height or none of them. - @param parent (element or jQuery) the parent node for the new node (optional) - @param x (number) the x-coordinate for the left edge of the node (optional) - @param y (number) the y-coordinate for the top edge of the node (optional) - @param width (number) the width of the node (optional) - @param height (number) the height of the node (optional) - @param ref (string) the ID of the definition node - @param settings (object) additional settings for the node (optional) - @return (element) the new node */ + /** Add a usage reference. +

Specify all of x, y, width, height or none of them.

+ @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param [x] {number} The x-coordinate for the left edge of the node. + @param [y] {number} The y-coordinate for the top edge of the node. + @param [width] {number} The width of the node. + @param [height] {number} The height of the node. + @param ref {string} The ID of the definition node. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new usage reference node. */ use: function(parent, x, y, width, height, ref, settings) { var args = this._args(arguments, ['x', 'y', 'width', 'height', 'ref']); - if (typeof args.x == 'string') { + if (typeof args.x === 'string') { args.ref = args.x; args.settings = args.y; args.x = args.y = args.width = args.height = null; } var node = this._makeNode(args.parent, 'use', $.extend( - {x: args.x, y: args.y, width: args.width, height: args.height}, - args.settings || {})); + {x: args.x, y: args.y, width: args.width, height: args.height}, args.settings || {})); node.setAttributeNS($.svg.xlinkNS, 'href', args.ref); return node; }, - /* Add a link, which applies to all child elements. - @param parent (element or jQuery) the parent node for the new link (optional) - @param ref (string) the target URL - @param settings (object) additional settings for the link (optional) - @return (element) the new link node */ + /** Add a link, which applies to all child elements. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param ref {string} The target URL. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new link node. */ link: function(parent, ref, settings) { var args = this._args(arguments, ['ref']); var node = this._makeNode(args.parent, 'a', args.settings); @@ -610,46 +559,45 @@ $.extend(SVGWrapper.prototype, { return node; }, - /* Add an image. - @param parent (element or jQuery) the parent node for the new image (optional) - @param x (number) the x-coordinate for the left edge of the image - @param y (number) the y-coordinate for the top edge of the image - @param width (number) the width of the image - @param height (number) the height of the image - @param ref (string) the path to the image - @param settings (object) additional settings for the image (optional) - @return (element) the new image node */ + /** Add an image. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param x {number} The x-coordinate for the left edge of the image. + @param y {number} The y-coordinate for the top edge of the image. + @param width {number} The width of the image. + @param height {number} The height of the image. + @param ref {string} The path to the image. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new image node. */ image: function(parent, x, y, width, height, ref, settings) { var args = this._args(arguments, ['x', 'y', 'width', 'height', 'ref']); var node = this._makeNode(args.parent, 'image', $.extend( - {x: args.x, y: args.y, width: args.width, height: args.height}, - args.settings || {})); + {x: args.x, y: args.y, width: args.width, height: args.height}, args.settings || {})); node.setAttributeNS($.svg.xlinkNS, 'href', args.ref); return node; }, - /* Draw a path. - @param parent (element or jQuery) the parent node for the new shape (optional) - @param path (string or SVGPath) the path to draw - @param settings (object) additional settings for the shape (optional) - @return (element) the new shape node */ + /** Draw a path. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param path {string|SVGPath} The path to draw. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new path node. */ path: function(parent, path, settings) { var args = this._args(arguments, ['path']); return this._makeNode(args.parent, 'path', $.extend( {d: (args.path.path ? args.path.path() : args.path)}, args.settings || {})); }, - /* Draw a rectangle. - Specify both of rx and ry or neither. - @param parent (element or jQuery) the parent node for the new shape (optional) - @param x (number) the x-coordinate for the left edge of the rectangle - @param y (number) the y-coordinate for the top edge of the rectangle - @param width (number) the width of the rectangle - @param height (number) the height of the rectangle - @param rx (number) the x-radius of the ellipse for the rounded corners (optional) - @param ry (number) the y-radius of the ellipse for the rounded corners (optional) - @param settings (object) additional settings for the shape (optional) - @return (element) the new shape node */ + /** Draw a rectangle. +

Specify both of rx and ry or neither.

+ @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param x {number} The x-coordinate for the left edge of the rectangle. + @param y {number} The y-coordinate for the top edge of the rectangle. + @param width {number} The width of the rectangle. + @param height {number} The height of the rectangle. + @param [rx] {number} The x-radius of the ellipse for the rounded corners. + @param [ry] {number} The y-radius of the ellipse for the rounded corners. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new rectangle node. */ rect: function(parent, x, y, width, height, rx, ry, settings) { var args = this._args(arguments, ['x', 'y', 'width', 'height', 'rx', 'ry'], ['rx']); return this._makeNode(args.parent, 'rect', $.extend( @@ -657,106 +605,108 @@ $.extend(SVGWrapper.prototype, { (args.rx ? {rx: args.rx, ry: args.ry} : {}), args.settings || {})); }, - /* Draw a circle. - @param parent (element or jQuery) the parent node for the new shape (optional) - @param cx (number) the x-coordinate for the centre of the circle - @param cy (number) the y-coordinate for the centre of the circle - @param r (number) the radius of the circle - @param settings (object) additional settings for the shape (optional) - @return (element) the new shape node */ + /** Draw a circle. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param cx {number} The x-coordinate for the centre of the circle. + @param cy {number} The y-coordinate for the centre of the circle. + @param r {number} The radius of the circle. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new circle node. */ circle: function(parent, cx, cy, r, settings) { var args = this._args(arguments, ['cx', 'cy', 'r']); return this._makeNode(args.parent, 'circle', $.extend( {cx: args.cx, cy: args.cy, r: args.r}, args.settings || {})); }, - /* Draw an ellipse. - @param parent (element or jQuery) the parent node for the new shape (optional) - @param cx (number) the x-coordinate for the centre of the ellipse - @param cy (number) the y-coordinate for the centre of the ellipse - @param rx (number) the x-radius of the ellipse - @param ry (number) the y-radius of the ellipse - @param settings (object) additional settings for the shape (optional) - @return (element) the new shape node */ + /** Draw an ellipse. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param cx {number} The x-coordinate for the centre of the ellipse. + @param cy {number} The y-coordinate for the centre of the ellipse. + @param rx {number} The x-radius of the ellipse. + @param ry {number} The y-radius of the ellipse. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new ellipse node. */ ellipse: function(parent, cx, cy, rx, ry, settings) { var args = this._args(arguments, ['cx', 'cy', 'rx', 'ry']); return this._makeNode(args.parent, 'ellipse', $.extend( {cx: args.cx, cy: args.cy, rx: args.rx, ry: args.ry}, args.settings || {})); }, - /* Draw a line. - @param parent (element or jQuery) the parent node for the new shape (optional) - @param x1 (number) the x-coordinate for the start of the line - @param y1 (number) the y-coordinate for the start of the line - @param x2 (number) the x-coordinate for the end of the line - @param y2 (number) the y-coordinate for the end of the line - @param settings (object) additional settings for the shape (optional) - @return (element) the new shape node */ + /** Draw a line. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param x1 {number} The x-coordinate for the start of the line. + @param y1 {number} The y-coordinate for the start of the line. + @param x2 {number} The x-coordinate for the end of the line. + @param y2 {number} The y-coordinate for the end of the line. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new line node. */ line: function(parent, x1, y1, x2, y2, settings) { var args = this._args(arguments, ['x1', 'y1', 'x2', 'y2']); return this._makeNode(args.parent, 'line', $.extend( {x1: args.x1, y1: args.y1, x2: args.x2, y2: args.y2}, args.settings || {})); }, - /* Draw a polygonal line. - @param parent (element or jQuery) the parent node for the new shape (optional) - @param points (number[][]) the x-/y-coordinates for the points on the line - @param settings (object) additional settings for the shape (optional) - @return (element) the new shape node */ + /** Draw a polygonal line. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param points {number[][]} The x-/y-coordinates for the points on the line. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new polygonal line node. */ polyline: function(parent, points, settings) { var args = this._args(arguments, ['points']); return this._poly(args.parent, 'polyline', args.points, args.settings); }, - /* Draw a polygonal shape. - @param parent (element or jQuery) the parent node for the new shape (optional) - @param points (number[][]) the x-/y-coordinates for the points on the shape - @param settings (object) additional settings for the shape (optional) - @return (element) the new shape node */ + /** Draw a polygonal shape. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param points {number[][]} The x-/y-coordinates for the points on the shape. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new polygonal shape node. */ polygon: function(parent, points, settings) { var args = this._args(arguments, ['points']); return this._poly(args.parent, 'polygon', args.points, args.settings); }, - /* Draw a polygonal line or shape. */ + /** Draw a polygonal line or shape. + @private + @param parent {SVGElement|jQuery} The parent node for the new node. + @param name {string} The type of polygon to create. + @param points {number[][]} The x-/y-coordinates for the points on the shape. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new polygon node. */ _poly: function(parent, name, points, settings) { var ps = ''; for (var i = 0; i < points.length; i++) { ps += points[i].join() + ' '; } - return this._makeNode(parent, name, $.extend( - {points: $.trim(ps)}, settings || {})); - }, - - /* Draw text. - Specify both of x and y or neither of them. - @param parent (element or jQuery) the parent node for the text (optional) - @param x (number or number[]) the x-coordinate(s) for the text (optional) - @param y (number or number[]) the y-coordinate(s) for the text (optional) - @param value (string) the text content or - (SVGText) text with spans and references - @param settings (object) additional settings for the text (optional) - @return (element) the new text node */ + return this._makeNode(parent, name, $.extend({points: $.trim(ps)}, settings || {})); + }, + + /** Draw text. +

Specify both of x and y or neither of them.

+ @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param [x] {number|number[]} The x-coordinate(s) for the text. + @param [y] {number|number[]} The y-coordinate(s) for the text. + @param value {string|SVGText} The text content or text with spans and references. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new text node. */ text: function(parent, x, y, value, settings) { var args = this._args(arguments, ['x', 'y', 'value']); - if (typeof args.x == 'string' && arguments.length < 4) { + if (typeof args.x === 'string' && arguments.length < 4) { args.value = args.x; args.settings = args.y; args.x = args.y = null; } return this._text(args.parent, 'text', args.value, $.extend( - {x: (args.x && isArray(args.x) ? args.x.join(' ') : args.x), - y: (args.y && isArray(args.y) ? args.y.join(' ') : args.y)}, - args.settings || {})); - }, - - /* Draw text along a path. - @param parent (element or jQuery) the parent node for the text (optional) - @param path (string) the ID of the path - @param value (string) the text content or - (SVGText) text with spans and references - @param settings (object) additional settings for the text (optional) - @return (element) the new text node */ + {x: (args.x && $.isArray(args.x) ? args.x.join(' ') : args.x), + y: (args.y && $.isArray(args.y) ? args.y.join(' ') : args.y)}, args.settings || {})); + }, + + /** Draw text along a path. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param path {string} The ID of the path. + @param value {string|SVGText} The text content or text with spans and references. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new textpath node. */ textpath: function(parent, path, value, settings) { var args = this._args(arguments, ['path', 'value']); var node = this._text(args.parent, 'textPath', args.value, args.settings || {}); @@ -764,26 +714,32 @@ $.extend(SVGWrapper.prototype, { return node; }, - /* Draw text. */ + /** Draw text. + @private + @param parent {SVGElement|jQuery} The parent node for the new node. + @param name {string} The type of text to create. + @param value {string|SVGText} The text content or text with spans and references. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new text node. */ _text: function(parent, name, value, settings) { var node = this._makeNode(parent, name, settings); - if (typeof value == 'string') { + if (typeof value === 'string') { node.appendChild(node.ownerDocument.createTextNode(value)); } else { for (var i = 0; i < value._parts.length; i++) { var part = value._parts[i]; - if (part[0] == 'tspan') { + if (part[0] === 'tspan') { var child = this._makeNode(node, part[0], part[2]); child.appendChild(node.ownerDocument.createTextNode(part[1])); node.appendChild(child); } - else if (part[0] == 'tref') { + else if (part[0] === 'tref') { var child = this._makeNode(node, part[0], part[2]); child.setAttributeNS($.svg.xlinkNS, 'href', part[1]); node.appendChild(child); } - else if (part[0] == 'textpath') { + else if (part[0] === 'textpath') { var set = $.extend({}, part[2]); set.href = null; var child = this._makeNode(node, part[0], set); @@ -799,24 +755,28 @@ $.extend(SVGWrapper.prototype, { return node; }, - /* Add a custom SVG element. - @param parent (element or jQuery) the parent node for the new element (optional) - @param name (string) the name of the element - @param settings (object) additional settings for the element (optional) - @return (element) the new custom node */ + /** Add a custom SVG element. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param name {string} The name of the element. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new custom node. */ other: function(parent, name, settings) { var args = this._args(arguments, ['name']); return this._makeNode(args.parent, args.name, args.settings || {}); }, - /* Create a shape node with the given settings. */ + /** Create a SVG node with the given settings. + @private + @param parent {SVGElement|jQuery} The parent node for the new node, or SVG root if null. + @param name {string} The name of the element. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new node. */ _makeNode: function(parent, name, settings) { parent = parent || this._svg; var node = this._svg.ownerDocument.createElementNS($.svg.svgNS, name); for (var name in settings) { var value = settings[name]; - if (value != null && value != null && - (typeof value != 'string' || value != '')) { + if (value != null && (typeof value !== 'string' || value !== '')) { node.setAttribute($.svg._attrNames[name] || name, value); } } @@ -824,21 +784,17 @@ $.extend(SVGWrapper.prototype, { return node; }, - /* Add an existing SVG node to the diagram. - @param parent (element or jQuery) the parent node for the new node (optional) - @param node (element) the new node to add or - (string) the jQuery selector for the node or - (jQuery collection) set of nodes to add - @return (SVGWrapper) this wrapper */ + /** Add an existing SVG node to the document. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param node {SVGElement|string|jQuery} The new node to add or + the jQuery selector for the node or the set of nodes to add. + @return {SVGWrapper} This wrapper. */ add: function(parent, node) { - var args = this._args((arguments.length == 1 ? [null, parent] : arguments), ['node']); + var args = this._args((arguments.length === 1 ? [null, parent] : arguments), ['node']); var svg = this; args.parent = args.parent || this._svg; args.node = (args.node.jquery ? args.node : $(args.node)); try { - if ($.svg._renesis) { - throw 'Force traversal'; - } args.parent.appendChild(args.node.cloneNode(true)); } catch (e) { @@ -852,15 +808,14 @@ $.extend(SVGWrapper.prototype, { return this; }, - /* Clone an existing SVG node and add it to the diagram. - @param parent (element or jQuery) the parent node for the new node (optional) - @param node (element) the new node to add or - (string) the jQuery selector for the node or - (jQuery collection) set of nodes to add - @return (element[]) collection of new nodes */ + /** Clone an existing SVG node and add it to the document. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param node {SVGEelement|string|jQuery} The new node to add or + the jQuery selector for the node or the set of nodes to clone. + @return {SVGElement[]} The collection of new nodes. */ clone: function(parent, node) { var svg = this; - var args = this._args((arguments.length == 1 ? [null, parent] : arguments), ['node']); + var args = this._args((arguments.length === 1 ? [null, parent] : arguments), ['node']); args.parent = args.parent || this._svg; args.node = (args.node.jquery ? args.node : $(args.node)); var newNodes = []; @@ -875,20 +830,19 @@ $.extend(SVGWrapper.prototype, { return newNodes; }, - /* SVG nodes must belong to the SVG namespace, so clone and ensure this is so. - @param node (element) the SVG node to clone - @return (element) the cloned node */ + /** SVG nodes must belong to the SVG namespace, so clone and ensure this is so. + @private + @param node {SVGElement} The SVG node to clone. + @return {SVGElement} The cloned node. */ _cloneAsSVG: function(node) { var newNode = null; - if (node.nodeType == 1) { // element - newNode = this._svg.ownerDocument.createElementNS( - $.svg.svgNS, this._checkName(node.nodeName)); + if (node.nodeType === 1) { // element + newNode = this._svg.ownerDocument.createElementNS($.svg.svgNS, this._checkName(node.nodeName)); for (var i = 0; i < node.attributes.length; i++) { var attr = node.attributes.item(i); - if (attr.nodeName != 'xmlns' && attr.nodeValue) { - if (attr.prefix == 'xlink') { - newNode.setAttributeNS($.svg.xlinkNS, - attr.localName || attr.baseName, attr.nodeValue); + if (attr.nodeName !== 'xmlns' && attr.nodeValue) { + if (attr.prefix === 'xlink') { + newNode.setAttributeNS($.svg.xlinkNS, attr.localName || attr.baseName, attr.nodeValue); } else { newNode.setAttribute(this._checkName(attr.nodeName), attr.nodeValue); @@ -902,56 +856,54 @@ $.extend(SVGWrapper.prototype, { } } } - else if (node.nodeType == 3) { // text + else if (node.nodeType === 3) { // text if ($.trim(node.nodeValue)) { newNode = this._svg.ownerDocument.createTextNode(node.nodeValue); } } - else if (node.nodeType == 4) { // CDATA + else if (node.nodeType === 4) { // CDATA if ($.trim(node.nodeValue)) { try { newNode = this._svg.ownerDocument.createCDATASection(node.nodeValue); } catch (e) { newNode = this._svg.ownerDocument.createTextNode( - node.nodeValue.replace(/&/g, '&'). - replace(//g, '>')); + node.nodeValue.replace(/&/g, '&').replace(//g, '>')); } } } return newNode; }, - /* Node names must be lower case and without SVG namespace prefix. */ + /** Node names must be lower case and without SVG namespace prefix. + @private + @param name {string} The name to check. + @return {string} The corrected name. */ _checkName: function(name) { - name = (name.substring(0, 1) >= 'A' && name.substring(0, 1) <= 'Z' ? - name.toLowerCase() : name); - return (name.substring(0, 4) == 'svg:' ? name.substring(4) : name); - }, - - /* Load an external SVG document. - @param url (string) the location of the SVG document or - the actual SVG content - @param settings (boolean) see addTo below or - (function) see onLoad below or - (object) additional settings for the load with attributes below: - addTo (boolean) true to add to what's already there, - or false to clear the canvas first - changeSize (boolean) true to allow the canvas size to change, - or false to retain the original - onLoad (function) callback after the document has loaded, - 'this' is the container, receives SVG object and - optional error message as a parameter - parent (string or element or jQuery) the parent to load - into, defaults to top-level svg element - @return (SVGWrapper) this root */ + name = (name.substring(0, 1) >= 'A' && name.substring(0, 1) <= 'Z' ? name.toLowerCase() : name); + return (name.substring(0, 4) === 'svg:' ? name.substring(4) : name); + }, + + /** Load an external SVG document. + @param url {string} The location of the SVG document or + the actual SVG content (starting with '<svg'. + @param settings {boolean|function|object} Either addTo below or onLoad below or + additional settings for the load with attributes below: + addTo {boolean} true to add to what's already there, + or false to clear the canvas first, + changeSize {boolean} true to allow the canvas size to change, + or false to retain the original, + onLoad {function} callback after the document has loaded, + 'this' is the container, receives SVG object and optional error message as a parameter, + parent {string|SVGElement|jQuery} the parent to load into, + defaults to top-level svg element. + @return {SVGWrapper} This wrapper. */ load: function(url, settings) { - settings = (typeof settings == 'boolean' ? {addTo: settings} : - (typeof settings == 'function' ? {onLoad: settings} : - (typeof settings == 'string' ? {parent: settings} : - (typeof settings == 'object' && settings.nodeName ? {parent: settings} : - (typeof settings == 'object' && settings.jquery ? {parent: settings} : - settings || {}))))); + settings = (typeof settings === 'boolean' ? {addTo: settings} : + (typeof settings === 'function' ? {onLoad: settings} : + (typeof settings === 'string' ? {parent: settings} : + (typeof settings === 'object' && settings.nodeName ? {parent: settings} : + (typeof settings === 'object' && settings.jquery ? {parent: settings} : settings || {}))))); if (!settings.parent && !settings.addTo) { this.clear(false); } @@ -974,7 +926,7 @@ $.extend(SVGWrapper.prototype, { xml.resolveExternals = false; xml.async = false; xml.loadXML(data); - if (xml.parseError.errorCode != 0) { + if (xml.parseError.errorCode !== 0) { reportError(xml.parseError.reason); return null; } @@ -985,18 +937,17 @@ $.extend(SVGWrapper.prototype, { if (!data) { return; } - if (data.documentElement.nodeName != 'svg') { + if (data.documentElement.nodeName !== 'svg') { var errors = data.getElementsByTagName('parsererror'); var messages = (errors.length ? errors[0].getElementsByTagName('div') : []); // Safari - reportError(!errors.length ? '???' : - (messages.length ? messages[0] : errors[0]).firstChild.nodeValue); + reportError(!errors.length ? '???' : (messages.length ? messages[0] : errors[0]).firstChild.nodeValue); return; } var parent = (settings.parent ? $(settings.parent)[0] : wrapper._svg); var attrs = {}; for (var i = 0; i < data.documentElement.attributes.length; i++) { var attr = data.documentElement.attributes.item(i); - if (!(attr.nodeName == 'version' || attr.nodeName.substring(0, 5) == 'xmlns')) { + if (!(attr.nodeName === 'version' || attr.nodeName.substring(0, 5) === 'xmlns')) { attrs[attr.nodeName] = attr.nodeValue; } } @@ -1004,11 +955,8 @@ $.extend(SVGWrapper.prototype, { var nodes = data.documentElement.childNodes; for (var i = 0; i < nodes.length; i++) { try { - if ($.svg._renesis) { - throw 'Force traversal'; - } parent.appendChild(wrapper._svg.ownerDocument.importNode(nodes[i], true)); - if (nodes[i].nodeName == 'script') { + if (nodes[i].nodeName === 'script') { $.globalEval(nodes[i].textContent); } } @@ -1016,6 +964,15 @@ $.extend(SVGWrapper.prototype, { wrapper.add(parent, nodes[i]); } } + if (!settings.keepRelativeLinks && url.match('/')) { + var base = url.replace(/\/[^\/]*$/, '/'); + $('*', parent).each(function() { + var href = $(this).attr('xlink:href'); + if (href && !href.match(/(^[a-z][-a-z0-9+.]*:.*$)|(^\/.*$)|(^#.*$)/i)) { + $(this).attr('xlink:href', base + href); + } + }); + } if (!settings.changeSize) { wrapper.configure(parent, {width: size[0], height: size[1]}); } @@ -1024,13 +981,16 @@ $.extend(SVGWrapper.prototype, { } }; if (url.match('true to clear any root attributes as well, + false to leave them. + @return {SVGWrapper} This wrapper. */ clear: function(attrsToo) { if (attrsToo) { this.configure({}, true); @@ -1061,25 +1021,27 @@ $.extend(SVGWrapper.prototype, { return this; }, - /* Serialise the current diagram into an SVG text document. - @param node (SVG element) the starting node (optional) - @return (string) the SVG as text */ + /** Serialise the current diagram into an SVG text document. + @param [node] {SVGElement} The starting node, or SVG root if not specified . + @return {string} The SVG as text. */ toSVG: function(node) { node = node || this._svg; - return (typeof XMLSerializer == 'undefined' ? this._toSVG(node) : - new XMLSerializer().serializeToString(node)); + return (typeof XMLSerializer === 'undefined' ? this._toSVG(node) : new XMLSerializer().serializeToString(node)); }, - /* Serialise one node in the SVG hierarchy. */ + /** Serialise one node in the SVG hierarchy. + @private + @param node {SVGElement} The current node to serialise. + @return {string} The serialised SVG. */ _toSVG: function(node) { var svgDoc = ''; if (!node) { return svgDoc; } - if (node.nodeType == 3) { // Text + if (node.nodeType === 3) { // Text svgDoc = node.nodeValue; } - else if (node.nodeType == 4) { // CDATA + else if (node.nodeType === 4) { // CDATA svgDoc = ''; } else { // Element @@ -1087,9 +1049,9 @@ $.extend(SVGWrapper.prototype, { if (node.attributes) { for (var i = 0; i < node.attributes.length; i++) { var attr = node.attributes.item(i); - if (!($.trim(attr.nodeValue) == '' || attr.nodeValue.match(/^\[object/) || + if (!($.trim(attr.nodeValue) === '' || attr.nodeValue.match(/^\[object/) || attr.nodeValue.match(/^function/))) { - svgDoc += ' ' + (attr.namespaceURI == $.svg.xlinkNS ? 'xlink:' : '') + + svgDoc += ' ' + (attr.namespaceURI === $.svg.xlinkNS ? 'xlink:' : '') + attr.nodeName + '="' + attr.nodeValue + '"'; } } @@ -1111,170 +1073,171 @@ $.extend(SVGWrapper.prototype, { } }); -/* Helper to generate an SVG path. - Obtain an instance from the SVGWrapper object. - String calls together to generate the path and use its value: - var path = root.createPath(); +/** Helper to generate an SVG path. +

Obtain an instance from the SVGWrapper object.

+

String calls together to generate the path and use its value:

+ @module SVGPath + @example var path = root.createPath(); root.path(null, path.move(100, 100).line(300, 100).line(200, 300).close(), {fill: 'red'}); - or + // or root.path(null, path.move(100, 100).line([[300, 100], [200, 300]]).close(), {fill: 'red'}); */ function SVGPath() { this._path = ''; } $.extend(SVGPath.prototype, { - /* Prepare to create a new path. - @return (SVGPath) this path */ + /** Prepare to create a new path. + @return {SVGPath} This path. */ reset: function() { this._path = ''; return this; }, - /* Move the pointer to a position. - @param x (number) x-coordinate to move to or - (number[][]) x-/y-coordinates to move to - @param y (number) y-coordinate to move to (omitted if x is array) - @param relative (boolean) true for coordinates relative to the current point, - false for coordinates being absolute - @return (SVGPath) this path */ + /** Move the pointer to a position. + @param x {number|number[][]} x-coordinate to move to or x-/y-coordinates to move to. + @param [y] {number} y-coordinate to move to (omitted if x is array). + @param [relative=false] {boolean} true for coordinates relative to the current point, + false for coordinates being absolute. + @return {SVGPath} This path. */ move: function(x, y, relative) { - relative = (isArray(x) ? y : relative); + relative = ($.isArray(x) ? y : relative); return this._coords((relative ? 'm' : 'M'), x, y); }, - /* Draw a line to a position. - @param x (number) x-coordinate to move to or - (number[][]) x-/y-coordinates to move to - @param y (number) y-coordinate to move to (omitted if x is array) - @param relative (boolean) true for coordinates relative to the current point, - false for coordinates being absolute - @return (SVGPath) this path */ + /** Draw a line to a position. + @param x {number|number[][]} x-coordinate to move to or x-/y-coordinates to move to. + @param [y] {number} y-coordinate to move to (omitted if x is array). + @param [relative=false] {boolean} true for coordinates relative to the current point, + false for coordinates being absolute. + @return {SVGPath} This path. */ line: function(x, y, relative) { - relative = (isArray(x) ? y : relative); + relative = ($.isArray(x) ? y : relative); return this._coords((relative ? 'l' : 'L'), x, y); }, - /* Draw a horizontal line to a position. - @param x (number) x-coordinate to draw to or - (number[]) x-coordinates to draw to - @param relative (boolean) true for coordinates relative to the current point, - false for coordinates being absolute - @return (SVGPath) this path */ + /** Draw a horizontal line to a position. + @param x {number|number[]} x-coordinate to draw to or x-coordinates to draw to. + @param relative {boolean} true for coordinates relative to the current point, + false for coordinates being absolute. + @return {SVGPath} This path. */ horiz: function(x, relative) { - this._path += (relative ? 'h' : 'H') + (isArray(x) ? x.join(' ') : x); + this._path += (relative ? 'h' : 'H') + ($.isArray(x) ? x.join(' ') : x); return this; }, - /* Draw a vertical line to a position. - @param y (number) y-coordinate to draw to or - (number[]) y-coordinates to draw to - @param relative (boolean) true for coordinates relative to the current point, - false for coordinates being absolute - @return (SVGPath) this path */ + /** Draw a vertical line to a position. + @param y {number|number[]} y-coordinate to draw to or y-coordinates to draw to. + @param [relative=false] {boolean} true for coordinates relative to the current point, + false for coordinates being absolute. + @return {SVGPath} This path. */ vert: function(y, relative) { - this._path += (relative ? 'v' : 'V') + (isArray(y) ? y.join(' ') : y); + this._path += (relative ? 'v' : 'V') + ($.isArray(y) ? y.join(' ') : y); return this; }, - /* Draw a cubic Bézier curve. - @param x1 (number) x-coordinate of beginning control point or - (number[][]) x-/y-coordinates of control and end points to draw to - @param y1 (number) y-coordinate of beginning control point (omitted if x1 is array) - @param x2 (number) x-coordinate of ending control point (omitted if x1 is array) - @param y2 (number) y-coordinate of ending control point (omitted if x1 is array) - @param x (number) x-coordinate of curve end (omitted if x1 is array) - @param y (number) y-coordinate of curve end (omitted if x1 is array) - @param relative (boolean) true for coordinates relative to the current point, - false for coordinates being absolute - @return (SVGPath) this path */ + /** Draw a cubic Bézier curve. + @param x1 {number|number[][]} x-coordinate of beginning control point or + x-/y-coordinates of control and end points to draw to. + @param [y1] {number} y-coordinate of beginning control point (omitted if x1 is array). + @param [x2] {number} x-coordinate of ending control point (omitted if x1 is array). + @param [y2] {number} y-coordinate of ending control point (omitted if x1 is array). + @param [x] {number} x-coordinate of curve end (omitted if x1 is array). + @param [y] {number} y-coordinate of curve end (omitted if x1 is array). + @param [relative=false] {boolean} true for coordinates relative to the current point, + false for coordinates being absolute. + @return {SVGPath} This path. */ curveC: function(x1, y1, x2, y2, x, y, relative) { - relative = (isArray(x1) ? y1 : relative); + relative = ($.isArray(x1) ? y1 : relative); return this._coords((relative ? 'c' : 'C'), x1, y1, x2, y2, x, y); }, - /* Continue a cubic Bézier curve. - Starting control point is the reflection of the previous end control point. - @param x2 (number) x-coordinate of ending control point or - (number[][]) x-/y-coordinates of control and end points to draw to - @param y2 (number) y-coordinate of ending control point (omitted if x2 is array) - @param x (number) x-coordinate of curve end (omitted if x2 is array) - @param y (number) y-coordinate of curve end (omitted if x2 is array) - @param relative (boolean) true for coordinates relative to the current point, - false for coordinates being absolute - @return (SVGPath) this path */ + /** Continue a cubic Bézier curve. +

Starting control point is the reflection of the previous end control point.

+ @param x2 {number|number[][]} x-coordinate of ending control point or + x-/y-coordinates of control and end points to draw to. + @param [y2] {number} y-coordinate of ending control point (omitted if x2 is array). + @param [x] {number} x-coordinate of curve end (omitted if x2 is array). + @param [y] {number} y-coordinate of curve end (omitted if x2 is array). + @param [relative=false] {boolean} true for coordinates relative to the current point, + false for coordinates being absolute. + @return {SVGPath} This path. */ smoothC: function(x2, y2, x, y, relative) { - relative = (isArray(x2) ? y2 : relative); + relative = ($.isArray(x2) ? y2 : relative); return this._coords((relative ? 's' : 'S'), x2, y2, x, y); }, - /* Draw a quadratic Bézier curve. - @param x1 (number) x-coordinate of control point or - (number[][]) x-/y-coordinates of control and end points to draw to - @param y1 (number) y-coordinate of control point (omitted if x1 is array) - @param x (number) x-coordinate of curve end (omitted if x1 is array) - @param y (number) y-coordinate of curve end (omitted if x1 is array) - @param relative (boolean) true for coordinates relative to the current point, - false for coordinates being absolute - @return (SVGPath) this path */ + /** Draw a quadratic Bézier curve. + @param x1 {number|number[][]} x-coordinate of control point or + x-/y-coordinates of control and end points to draw to. + @param [y1] {number} y-coordinate of control point (omitted if x1 is array). + @param [x] {number} x-coordinate of curve end (omitted if x1 is array). + @param [y] {number} y-coordinate of curve end (omitted if x1 is array). + @param [relative=false] {boolean} true for coordinates relative to the current point, + false for coordinates being absolute. + @return {SVGPath} This path. */ curveQ: function(x1, y1, x, y, relative) { - relative = (isArray(x1) ? y1 : relative); + relative = ($.isArray(x1) ? y1 : relative); return this._coords((relative ? 'q' : 'Q'), x1, y1, x, y); }, - /* Continue a quadratic Bézier curve. - Control point is the reflection of the previous control point. - @param x (number) x-coordinate of curve end or - (number[][]) x-/y-coordinates of points to draw to - @param y (number) y-coordinate of curve end (omitted if x is array) - @param relative (boolean) true for coordinates relative to the current point, - false for coordinates being absolute - @return (SVGPath) this path */ + /** Continue a quadratic Bézier curve. +

Control point is the reflection of the previous control point.

+ @param x {number|number[][]} x-coordinate of curve end or x-/y-coordinates of points to draw to. + @param [y] {number} y-coordinate of curve end (omitted if x is array). + @param [relative=false] {boolean} true for coordinates relative to the current point, + false for coordinates being absolute. + @return {SVGPath} This path. */ smoothQ: function(x, y, relative) { - relative = (isArray(x) ? y : relative); + relative = ($.isArray(x) ? y : relative); return this._coords((relative ? 't' : 'T'), x, y); }, - /* Generate a path command with (a list of) coordinates. */ + /** Generate a path command with (a list of) coordinates. + @private + @param cmd {string} The command for the path element. + @param x1 {number} The first x-coordinate. + @param y1 {number} The first y-coordinate. + @param [x2] {number} The second x-coordinate. + @param [y2] {number} The second y-coordinate. + @param [x3] {number} The third x-coordinate. + @param [y3] {number} The third y-coordinate. + @return {SVGPath} This path. */ _coords: function(cmd, x1, y1, x2, y2, x3, y3) { - if (isArray(x1)) { + if ($.isArray(x1)) { for (var i = 0; i < x1.length; i++) { var cs = x1[i]; - this._path += (i == 0 ? cmd : ' ') + cs[0] + ',' + cs[1] + - (cs.length < 4 ? '' : ' ' + cs[2] + ',' + cs[3] + - (cs.length < 6 ? '': ' ' + cs[4] + ',' + cs[5])); + this._path += (i === 0 ? cmd : ' ') + cs[0] + ',' + cs[1] + (cs.length < 4 ? '' : + ' ' + cs[2] + ',' + cs[3] + (cs.length < 6 ? '': ' ' + cs[4] + ',' + cs[5])); } } else { this._path += cmd + x1 + ',' + y1 + - (x2 == null ? '' : ' ' + x2 + ',' + y2 + - (x3 == null ? '' : ' ' + x3 + ',' + y3)); + (x2 == null ? '' : ' ' + x2 + ',' + y2 + (x3 == null ? '' : ' ' + x3 + ',' + y3)); } return this; }, - /* Draw an arc to a position. - @param rx (number) x-radius of arc or - (number/boolean[][]) x-/y-coordinates and flags for points to draw to - @param ry (number) y-radius of arc (omitted if rx is array) - @param xRotate (number) x-axis rotation (degrees, clockwise) (omitted if rx is array) - @param large (boolean) true to draw the large part of the arc, - false to draw the small part (omitted if rx is array) - @param clockwise (boolean) true to draw the clockwise arc, - false to draw the anti-clockwise arc (omitted if rx is array) - @param x (number) x-coordinate of arc end (omitted if rx is array) - @param y (number) y-coordinate of arc end (omitted if rx is array) - @param relative (boolean) true for coordinates relative to the current point, - false for coordinates being absolute - @return (SVGPath) this path */ + /** Draw an arc to a position. + @param rx {number|any[][]} x-radius of arc or x-/y-coordinates and flags for points to draw to. + @param [ry] {number} y-radius of arc (omitted if rx is array). + @param [xRotate] {number} x-axis rotation (degrees, clockwise) (omitted if rx is array). + @param [large] {boolean} true to draw the large part of the arc, + false to draw the small part (omitted if rx is array). + @param [clockwise] {boolean} true to draw the clockwise arc, + false to draw the anti-clockwise arc (omitted if rx is array). + @param [x] {number} x-coordinate of arc end (omitted if rx is array). + @param [y] {number} y-coordinate of arc end (omitted if rx is array). + @param [relative=false] {boolean} true for coordinates relative to the current point, + false for coordinates being absolute. + @return {SVGPath} This path. */ arc: function(rx, ry, xRotate, large, clockwise, x, y, relative) { - relative = (isArray(rx) ? ry : relative); + relative = ($.isArray(rx) ? ry : relative); this._path += (relative ? 'a' : 'A'); - if (isArray(rx)) { + if ($.isArray(rx)) { for (var i = 0; i < rx.length; i++) { var cs = rx[i]; - this._path += (i == 0 ? '' : ' ') + cs[0] + ',' + cs[1] + ' ' + - cs[2] + ' ' + (cs[3] ? '1' : '0') + ',' + - (cs[4] ? '1' : '0') + ' ' + cs[5] + ',' + cs[6]; + this._path += (i === 0 ? '' : ' ') + cs[0] + ',' + cs[1] + ' ' + + cs[2] + ' ' + (cs[3] ? '1' : '0') + ',' + (cs[4] ? '1' : '0') + ' ' + cs[5] + ',' + cs[6]; } } else { @@ -1284,15 +1247,15 @@ $.extend(SVGPath.prototype, { return this; }, - /* Close the current path. - @return (SVGPath) this path */ + /** Close the current path. + @return {SVGPath} This path. */ close: function() { this._path += 'z'; return this; }, - /* Return the string rendering of the specified path. - @return (string) stringified path */ + /** Return the string rendering of the specified path. + @return {string} The stringified path. */ path: function() { return this._path; } @@ -1308,10 +1271,11 @@ SVGPath.prototype.curveQTo = SVGPath.prototype.curveQ; SVGPath.prototype.smoothQTo = SVGPath.prototype.smoothQ; SVGPath.prototype.arcTo = SVGPath.prototype.arc; -/* Helper to generate an SVG text object. - Obtain an instance from the SVGWrapper object. - String calls together to generate the text and use its value: - var text = root.createText(); +/** Helper to generate an SVG text object. +

Obtain an instance from the SVGWrapper object.

+

String calls together to generate the text and use its value:

+ @module SVGText + @example var text = root.createText(); root.text(null, x, y, text.string('This is '). span('red', {fill: 'red'}).string('!'), {fill: 'blue'}); */ function SVGText() { @@ -1319,62 +1283,61 @@ function SVGText() { } $.extend(SVGText.prototype, { - /* Prepare to create a new text object. - @return (SVGText) this text */ + /** Prepare to create a new text object. + @return {SVGText} This text object. */ reset: function() { this._parts = []; return this; }, - /* Add a straight string value. - @param value (string) the actual text - @return (SVGText) this text object */ + /** Add a straight string value. + @param value {string} The actual text. + @return {SVGText} This text object. */ string: function(value) { - this._parts[this._parts.length] = ['text', value]; + this._parts.push(['text', value]); return this; }, - /* Add a separate text span that has its own settings. - @param value (string) the actual text - @param settings (object) the settings for this text - @return (SVGText) this text object */ + /** Add a separate text span that has its own settings. + @param value {string} The actual text. + @param settings {object} The settings for this text. + @return {SVGText} This text object. */ span: function(value, settings) { - this._parts[this._parts.length] = ['tspan', value, settings]; + this._parts.push(['tspan', value, settings]); return this; }, - /* Add a reference to a previously defined text string. - @param id (string) the ID of the actual text - @param settings (object) the settings for this text - @return (SVGText) this text object */ + /** Add a reference to a previously defined text string. + @param id {string} The ID of the actual text. + @param settings {object} The settings for this text. + @return {SVGText} This text object. */ ref: function(id, settings) { - this._parts[this._parts.length] = ['tref', id, settings]; + this._parts.push(['tref', id, settings]); return this; }, - /* Add text drawn along a path. - @param id (string) the ID of the path - @param value (string) the actual text - @param settings (object) the settings for this text - @return (SVGText) this text object */ + /** Add text drawn along a path. + @param id {string} The ID of the path. + @param value {string} The actual text. + @param settings {object} The settings for this text. + @return {SVGText} This text object. */ path: function(id, value, settings) { - this._parts[this._parts.length] = ['textpath', value, - $.extend({href: id}, settings || {})]; + this._parts.push(['textpath', value, $.extend({href: id}, settings || {})]); return this; } }); -/* Attach the SVG functionality to a jQuery selection. - @param command (string) the command to run (optional, default 'attach') - @param options (object) the new settings to use for these SVG instances - @return jQuery (object) for chaining further calls */ +/** Attach the SVG functionality to a jQuery selection. + @param [command] {string} The command to run. + @param [options] {object} The new settings to use for these SVG instances. + @return {jQuery} For chaining further calls. */ $.fn.svg = function(options) { var otherArgs = Array.prototype.slice.call(arguments, 1); - if (typeof options == 'string' && options == 'get') { + if (typeof options === 'string' && options === 'get') { return $.svg['_' + options + 'SVG'].apply($.svg, [this[0]].concat(otherArgs)); } return this.each(function() { - if (typeof options == 'string') { + if (typeof options === 'string') { $.svg['_' + options + 'SVG'].apply($.svg, [this].concat(otherArgs)); } else { @@ -1383,11 +1346,6 @@ $.fn.svg = function(options) { }); }; -/* Determine whether an object is an array. */ -function isArray(a) { - return (a && a.constructor == Array); -} - // Singleton primary SVG interface $.svg = new SVGManager(); diff --git a/jquery.svg.min.js b/jquery.svg.min.js index b193b9e..7c99985 100644 --- a/jquery.svg.min.js +++ b/jquery.svg.min.js @@ -1,7 +1,6 @@ -/* http://keith-wood.name/svg.html - SVG for jQuery v1.4.5. +/* http://keith-wood.name/svg.html + SVG for jQuery v1.5.0. Written by Keith Wood (kbwood{at}iinet.com.au) August 2007. - Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and - MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. + Available under the MIT (http://keith-wood.name/licence.html) license. Please attribute the author if you use it. */ -(function($){function SVGManager(){this._settings=[];this._extensions=[];this.regional=[];this.regional['']={errorLoadingText:'Error loading',notSupportedText:'This browser does not support SVG'};this.local=this.regional[''];this._uuid=new Date().getTime();this._renesis=detectActiveX('RenesisX.RenesisCtrl')}function detectActiveX(a){try{return!!(window.ActiveXObject&&new ActiveXObject(a))}catch(e){return false}}var q='svgwrapper';$.extend(SVGManager.prototype,{markerClassName:'hasSVG',svgNS:'http://www.w3.org/2000/svg',xlinkNS:'http://www.w3.org/1999/xlink',_wrapperClass:SVGWrapper,_attrNames:{class_:'class',in_:'in',alignmentBaseline:'alignment-baseline',baselineShift:'baseline-shift',clipPath:'clip-path',clipRule:'clip-rule',colorInterpolation:'color-interpolation',colorInterpolationFilters:'color-interpolation-filters',colorRendering:'color-rendering',dominantBaseline:'dominant-baseline',enableBackground:'enable-background',fillOpacity:'fill-opacity',fillRule:'fill-rule',floodColor:'flood-color',floodOpacity:'flood-opacity',fontFamily:'font-family',fontSize:'font-size',fontSizeAdjust:'font-size-adjust',fontStretch:'font-stretch',fontStyle:'font-style',fontVariant:'font-variant',fontWeight:'font-weight',glyphOrientationHorizontal:'glyph-orientation-horizontal',glyphOrientationVertical:'glyph-orientation-vertical',horizAdvX:'horiz-adv-x',horizOriginX:'horiz-origin-x',imageRendering:'image-rendering',letterSpacing:'letter-spacing',lightingColor:'lighting-color',markerEnd:'marker-end',markerMid:'marker-mid',markerStart:'marker-start',stopColor:'stop-color',stopOpacity:'stop-opacity',strikethroughPosition:'strikethrough-position',strikethroughThickness:'strikethrough-thickness',strokeDashArray:'stroke-dasharray',strokeDashOffset:'stroke-dashoffset',strokeLineCap:'stroke-linecap',strokeLineJoin:'stroke-linejoin',strokeMiterLimit:'stroke-miterlimit',strokeOpacity:'stroke-opacity',strokeWidth:'stroke-width',textAnchor:'text-anchor',textDecoration:'text-decoration',textRendering:'text-rendering',underlinePosition:'underline-position',underlineThickness:'underline-thickness',vertAdvY:'vert-adv-y',vertOriginY:'vert-origin-y',wordSpacing:'word-spacing',writingMode:'writing-mode'},_attachSVG:function(a,b){var c=(a.namespaceURI==this.svgNS?a:null);var a=(c?null:a);if($(a||c).hasClass(this.markerClassName)){return}if(typeof b=='string'){b={loadURL:b}}else if(typeof b=='function'){b={onLoad:b}}$(a||c).addClass(this.markerClassName);try{if(!c){c=document.createElementNS(this.svgNS,'svg');c.setAttribute('version','1.1');if(a.clientWidth>0){c.setAttribute('width',a.clientWidth)}if(a.clientHeight>0){c.setAttribute('height',a.clientHeight)}a.appendChild(c)}this._afterLoad(a,c,b||{})}catch(e){if($.browser.msie){if(!a.id){a.id='svg'+(this._uuid++)}this._settings[a.id]=b;a.innerHTML=''}else{a.innerHTML='

'+this.local.notSupportedText+'

'}}},_registerSVG:function(){for(var i=0;i=0;i--){var d=a.attributes.item(i);if(!(d.nodeName=='onload'||d.nodeName=='version'||d.nodeName.substring(0,5)=='xmlns')){a.attributes.removeNamedItem(d.nodeName)}}}for(var e in b){a.setAttribute($.svg._attrNames[e]||e,b[e])}return this},getElementById:function(a){return this._svg.ownerDocument.getElementById(a)},change:function(a,b){if(a){for(var c in b){if(b[c]==null){a.removeAttribute($.svg._attrNames[c]||c)}else{a.setAttribute($.svg._attrNames[c]||c,b[c])}}}return this},_args:function(b,c,d){c.splice(0,0,'parent');c.splice(c.length,0,'settings');var e={};var f=0;if(b[0]!=null&&b[0].jquery){b[0]=b[0][0]}if(b[0]!=null&&!(typeof b[0]=='object'&&b[0].nodeName)){e['parent']=null;f=1}for(var i=0;i'+d.styles+'')}return e},script:function(a,b,c,d){var e=this._args(arguments,['script','type'],['type']);var f=this._makeNode(e.parent,'script',$.extend({type:e.type||'text/javascript'},e.settings||{}));f.appendChild(this._svg.ownerDocument.createTextNode(e.script));if(!$.browser.mozilla){$.globalEval(e.script)}return f},linearGradient:function(a,b,c,d,e,f,g,h){var i=this._args(arguments,['id','stops','x1','y1','x2','y2'],['x1']);var j=$.extend({id:i.id},(i.x1!=null?{x1:i.x1,y1:i.y1,x2:i.x2,y2:i.y2}:{}));return this._gradient(i.parent,'linearGradient',$.extend(j,i.settings||{}),i.stops)},radialGradient:function(a,b,c,d,e,r,f,g,h){var i=this._args(arguments,['id','stops','cx','cy','r','fx','fy'],['cx']);var j=$.extend({id:i.id},(i.cx!=null?{cx:i.cx,cy:i.cy,r:i.r,fx:i.fx,fy:i.fy}:{}));return this._gradient(i.parent,'radialGradient',$.extend(j,i.settings||{}),i.stops)},_gradient:function(a,b,c,d){var e=this._makeNode(a,b,c);for(var i=0;i/g,'>'))}}}return b},_checkName:function(a){a=(a.substring(0,1)>='A'&&a.substring(0,1)<='Z'?a.toLowerCase():a);return(a.substring(0,4)=='svg:'?a.substring(4):a)},load:function(j,k){k=(typeof k=='boolean'?{addTo:k}:(typeof k=='function'?{onLoad:k}:(typeof k=='string'?{parent:k}:(typeof k=='object'&&k.nodeName?{parent:k}:(typeof k=='object'&&k.jquery?{parent:k}:k||{})))));if(!k.parent&&!k.addTo){this.clear(false)}var l=[this._svg.getAttribute('width'),this._svg.getAttribute('height')];var m=this;var n=function(a){a=$.svg.local.errorLoadingText+': '+a;if(k.onLoad){k.onLoad.apply(m._container||m._svg,[m,a])}else{m.text(null,10,20,a)}};var o=function(a){var b=new ActiveXObject('Microsoft.XMLDOM');b.validateOnParse=false;b.resolveExternals=false;b.async=false;b.loadXML(a);if(b.parseError.errorCode!=0){n(b.parseError.reason);return null}return b};var p=function(a){if(!a){return}if(a.documentElement.nodeName!='svg'){var b=a.getElementsByTagName('parsererror');var c=(b.length?b[0].getElementsByTagName('div'):[]);n(!b.length?'???':(c.length?c[0]:b[0]).firstChild.nodeValue);return}var d=(k.parent?$(k.parent)[0]:m._svg);var f={};for(var i=0;i'}else{b='<'+a.nodeName;if(a.attributes){for(var i=0;i';var d=a.firstChild;while(d){b+=this._toSVG(d);d=d.nextSibling}b+=''}else{b+='/>'}}return b}});function SVGPath(){this._path=''}$.extend(SVGPath.prototype,{reset:function(){this._path='';return this},move:function(x,y,a){a=(isArray(x)?y:a);return this._coords((a?'m':'M'),x,y)},line:function(x,y,a){a=(isArray(x)?y:a);return this._coords((a?'l':'L'),x,y)},horiz:function(x,a){this._path+=(a?'h':'H')+(isArray(x)?x.join(' '):x);return this},vert:function(y,a){this._path+=(a?'v':'V')+(isArray(y)?y.join(' '):y);return this},curveC:function(a,b,c,d,x,y,e){e=(isArray(a)?b:e);return this._coords((e?'c':'C'),a,b,c,d,x,y)},smoothC:function(a,b,x,y,c){c=(isArray(a)?b:c);return this._coords((c?'s':'S'),a,b,x,y)},curveQ:function(a,b,x,y,c){c=(isArray(a)?b:c);return this._coords((c?'q':'Q'),a,b,x,y)},smoothQ:function(x,y,a){a=(isArray(x)?y:a);return this._coords((a?'t':'T'),x,y)},_coords:function(a,b,c,d,e,f,g){if(isArray(b)){for(var i=0;i0){c.setAttribute('width',a.clientWidth)}if(a.clientHeight>0){c.setAttribute('height',a.clientHeight)}a.appendChild(c)}this._afterLoad(a,c,b||{})}catch(e){$(a).html('

SVG is not supported natively on this browser

')}},_afterLoad:function(a,b,c){var c=c||this._settings[a.id];this._settings[a?a.id:'']=null;var d=new this._wrapperClass(b,a);$.data(a||b,$.svg.propertyName,d);try{if(c.loadURL){d.load(c.loadURL,c)}if(c.settings){d.configure(c.settings)}if(c.onLoad&&!c.loadURL){c.onLoad.apply(a||b,[d])}}catch(e){alert(e)}},_getSVG:function(a){return $(a).data(this.propertyName)},_destroySVG:function(a){a=$(a);if(!a.hasClass(this.markerClassName)){return}a.removeClass(this.markerClassName).removeData(this.propertyName);if(a[0].namespaceURI!==this.svgNS){a.empty()}},addExtension:function(a,b){this._extensions.push([a,b])},isSVGElem:function(a){return(a.nodeType===1&&a.namespaceURI===$.svg.svgNS)}});function SVGWrapper(a,b){this._svg=a;this._container=b;for(var i=0;i<$.svg._extensions.length;i++){var c=$.svg._extensions[i];this[c[0]]=new c[1](this)}}$.extend(SVGWrapper.prototype,{width:function(){return(this._container?this._container.clientWidth:this._svg.width)},height:function(){return(this._container?this._container.clientHeight:this._svg.height)},root:function(){return this._svg},configure:function(a,b,c){if(!a.nodeName){c=b;b=a;a=this._svg}if(c){for(var i=a.attributes.length-1;i>=0;i--){var d=a.attributes.item(i);if(!(d.nodeName==='onload'||d.nodeName==='version'||d.nodeName.substring(0,5)==='xmlns')){a.attributes.removeNamedItem(d.nodeName)}}}for(var e in b){a.setAttribute($.svg._attrNames[e]||e,b[e])}return this},getElementById:function(a){return this._svg.ownerDocument.getElementById(a)},change:function(a,b){if(a){for(var c in b){if(b[c]==null){a.removeAttribute($.svg._attrNames[c]||c)}else{a.setAttribute($.svg._attrNames[c]||c,b[c])}}}return this},_args:function(b,c,d){c.splice(0,0,'parent');c.splice(c.length,0,'settings');var e={};var f=0;if(b[0]!=null&&b[0].jquery){b[0]=b[0][0]}if(b[0]!=null&&!(typeof b[0]==='object'&&b[0].nodeName)){e['parent']=null;f=1}for(var i=0;i/g,'>'))}}}return b},_checkName:function(a){a=(a.substring(0,1)>='A'&&a.substring(0,1)<='Z'?a.toLowerCase():a);return(a.substring(0,4)==='svg:'?a.substring(4):a)},load:function(l,m){m=(typeof m==='boolean'?{addTo:m}:(typeof m==='function'?{onLoad:m}:(typeof m==='string'?{parent:m}:(typeof m==='object'&&m.nodeName?{parent:m}:(typeof m==='object'&&m.jquery?{parent:m}:m||{})))));if(!m.parent&&!m.addTo){this.clear(false)}var n=[this._svg.getAttribute('width'),this._svg.getAttribute('height')];var o=this;var p=function(a){a=$.svg.local.errorLoadingText+': '+a;if(m.onLoad){m.onLoad.apply(o._container||o._svg,[o,a])}else{o.text(null,10,20,a)}};var q=function(a){var b=new ActiveXObject('Microsoft.XMLDOM');b.validateOnParse=false;b.resolveExternals=false;b.async=false;b.loadXML(a);if(b.parseError.errorCode!==0){p(b.parseError.reason);return null}return b};var r=function(b){if(!b){return}if(b.documentElement.nodeName!=='svg'){var c=b.getElementsByTagName('parsererror');var d=(c.length?c[0].getElementsByTagName('div'):[]);p(!c.length?'???':(d.length?d[0]:c[0]).firstChild.nodeValue);return}var f=(m.parent?$(m.parent)[0]:o._svg);var g={};for(var i=0;i'}else{b='<'+a.nodeName;if(a.attributes){for(var i=0;i';var d=a.firstChild;while(d){b+=this._toSVG(d);d=d.nextSibling}b+=''}else{b+='/>'}}return b}});function SVGPath(){this._path=''}$.extend(SVGPath.prototype,{reset:function(){this._path='';return this},move:function(x,y,a){a=($.isArray(x)?y:a);return this._coords((a?'m':'M'),x,y)},line:function(x,y,a){a=($.isArray(x)?y:a);return this._coords((a?'l':'L'),x,y)},horiz:function(x,a){this._path+=(a?'h':'H')+($.isArray(x)?x.join(' '):x);return this},vert:function(y,a){this._path+=(a?'v':'V')+($.isArray(y)?y.join(' '):y);return this},curveC:function(a,b,c,d,x,y,e){e=($.isArray(a)?b:e);return this._coords((e?'c':'C'),a,b,c,d,x,y)},smoothC:function(a,b,x,y,c){c=($.isArray(a)?b:c);return this._coords((c?'s':'S'),a,b,x,y)},curveQ:function(a,b,x,y,c){c=($.isArray(a)?b:c);return this._coords((c?'q':'Q'),a,b,x,y)},smoothQ:function(x,y,a){a=($.isArray(x)?y:a);return this._coords((a?'t':'T'),x,y)},_coords:function(a,b,c,d,e,f,g){if($.isArray(b)){for(var i=0;i35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(9($){9 2k(){7.1X=[];7.1Y=[];7.2l=[];7.2l[\'\']={2Z:\'4d 4e\',30:\'4f 1r 4g 4h 4i 2m\'};7.2n=7.2l[\'\'];7.31=1e 4j().4k();7.2o=32(\'4l.4m\')}9 32(a){1s{u!!(4n.2p&&1e 2p(a))}1t(e){u 1L}}8 q=\'4o\';$.I(2k.W,{1C:\'4p\',1u:\'2q://2r.33.34/4q/D\',1j:\'2q://2r.33.34/4r/2s\',35:2t,1M:{4s:\'36\',4t:\'1Z\',4u:\'4v-2u\',4w:\'2u-4x\',2v:\'37-19\',4y:\'37-38\',4z:\'1D-39\',4A:\'1D-39-4B\',4C:\'1D-2w\',4D:\'4E-2u\',4F:\'4G-4H\',4I:\'3a-21\',4J:\'3a-38\',4K:\'3b-1D\',4L:\'3b-21\',4M:\'1v-4N\',4O:\'1v-3c\',4P:\'1v-3c-4Q\',4R:\'1v-4S\',4T:\'1v-1N\',4U:\'1v-4V\',4W:\'1v-4X\',4Y:\'3d-3e-4Z\',50:\'3d-3e-51\',52:\'22-3f-x\',53:\'22-3g-x\',54:\'23-2w\',55:\'56-3h\',57:\'58-1D\',59:\'1O-5a\',5b:\'1O-5c\',5d:\'1O-5e\',3i:\'2x-1D\',3j:\'2x-21\',5f:\'3k-3l\',5g:\'3k-3m\',5h:\'1w-5i\',5j:\'1w-5k\',5l:\'1w-5m\',5n:\'1w-5o\',5p:\'1w-5q\',5r:\'1w-21\',5s:\'1w-O\',5t:\'15-5u\',5v:\'15-5w\',5x:\'15-2w\',5y:\'3n-3l\',5z:\'3n-3m\',5A:\'24-3f-y\',5B:\'24-3g-y\',5C:\'5D-3h\',5E:\'5F-5G\'},3o:9(a,b){8 c=(a.25==7.1u?a:P);8 a=(c?P:a);w($(a||c).2y(7.1C)){u}w(13 b==\'1f\'){b={26:b}}Y w(13 b==\'9\'){b={1m:b}}$(a||c).5H(7.1C);1s{w(!c){c=27.2z(7.1u,\'D\');c.1x(\'2A\',\'1.1\');w(a.2B>0){c.1x(\'O\',a.2B)}w(a.2C>0){c.1x(\'U\',a.2C)}a.11(c)}7.2D(a,c,b||{})}1t(e){w($.1r.28){w(!a.E){a.E=\'D\'+(7.31++)}7.1X[a.E]=b;a.3p=\'<5I 1y="23/D+2E" O="3q%" \'+\'U="3q%" 5J="\'+(b.5K||\'\')+\'5L.D" \'+\'5M="2q://2r.5N.5O/D/5P/5Q/5R.5S"/>\'}Y{a.3p=\'

\'+7.2n.30+\'

\'}}},3r:9(){14(8 i=0;i<27.2F.R;i++){8 a=27.2F[i].3s;w(!$(a).2y($.D.1C)||$.2G(a,q)){5U}8 b=P;1s{b=27.2F[i].5V()}1t(e){5W($.D.3r,5X);u}b=(b?b.1P:P);w(b){$.D.2D(a,b)}}},2D:9(a,b,c){8 c=c||7.1X[a.E];7.1X[a?a.E:\'\']=P;8 d=1e 7.35(b,a);$.2G(a||b,q,d);1s{w(c.26){d.3t(c.26,c)}w(c.F){d.1Q(c.F)}w(c.1m&&!c.26){c.1m.1R(a||b,[d])}}1t(e){5Y(e)}},5Z:9(a){a=(13 a==\'1f\'?$(a)[0]:(a.1E?a[0]:a));u $.2G(a,q)},60:9(a){8 b=$(a);w(!b.2y(7.1C)){u}b.61(7.1C);w(a.25!=7.1u){b.62()}$.63(a,q)},64:9(a,b){7.1Y.3u([a,b])},65:9(a){u(a.1F==1&&a.25==$.D.1u)}});9 2t(a,b){7.N=a;7.1z=b;14(8 i=0;i<$.D.1Y.R;i++){8 c=$.D.1Y[i];7[c[0]]=1e c[1](7)}}$.I(2t.W,{66:9(){u(7.1z?7.1z.2B:7.N.O)},67:9(){u(7.1z?7.1z.2C:7.N.U)},68:9(){u 7.N},1Q:9(a,b,c){w(!a.12){c=b;b=a;a=7.N}w(c){14(8 i=a.1g.R-1;i>=0;i--){8 d=a.1g.29(i);w(!(d.12==\'69\'||d.12==\'2A\'||d.12.1G(0,5)==\'2H\')){a.1g.6a(d.12)}}}14(8 e 1Z b){a.1x($.D.1M[e]||e,b[e])}u 7},3v:9(a){u 7.N.17.3v(a)},6b:9(a,b){w(a){14(8 c 1Z b){w(b[c]==P){a.6c($.D.1M[c]||c)}Y{a.1x($.D.1M[c]||c,b[c])}}}u 7},J:9(b,c,d){c.3w(0,0,\'B\');c.3w(c.R,0,\'F\');8 e={};8 f=0;w(b[0]!=P&&b[0].1E){b[0]=b[0][0]}w(b[0]!=P&&!(13 b[0]==\'1S\'&&b[0].12)){e[\'B\']=P;f=1}14(8 i=0;i\'+d.2L+\'\')}u e},1H:9(a,b,c,d){8 e=7.J(G,[\'1H\',\'1y\'],[\'1y\']);8 f=7.K(e.B,\'1H\',$.I({1y:e.1y||\'15/6l\'},e.F||{}));f.11(7.N.17.1h(e.1H));w(!$.1r.6m){$.3D(e.1H)}u f},3E:9(a,b,c,d,e,f,g,h){8 i=7.J(G,[\'E\',\'2c\',\'1i\',\'1n\',\'1I\',\'1J\'],[\'1i\']);8 j=$.I({E:i.E},(i.1i!=P?{1i:i.1i,1n:i.1n,1I:i.1I,1J:i.1J}:{}));u 7.2M(i.B,\'3E\',$.I(j,i.F||{}),i.2c)},3F:9(a,b,c,d,e,r,f,g,h){8 i=7.J(G,[\'E\',\'2c\',\'1c\',\'1k\',\'r\',\'2N\',\'2O\'],[\'1c\']);8 j=$.I({E:i.E},(i.1c!=P?{1c:i.1c,1k:i.1k,r:i.r,2N:i.2N,2O:i.2O}:{}));u 7.2M(i.B,\'3F\',$.I(j,i.F||{}),i.2c)},2M:9(a,b,c,d){8 e=7.K(a,b,c);14(8 i=0;i/g,\'&6E;\'))}}}u b},2U:9(a){a=(a.1G(0,1)>=\'A\'&&a.1G(0,1)<=\'Z\'?a.6F():a);u(a.1G(0,4)==\'D:\'?a.1G(4):a)},3t:9(j,k){k=(13 k==\'6G\'?{3V:k}:(13 k==\'9\'?{1m:k}:(13 k==\'1f\'?{B:k}:(13 k==\'1S\'&&k.12?{B:k}:(13 k==\'1S\'&&k.1E?{B:k}:k||{})))));w(!k.B&&!k.3V){7.3W(1L)}8 l=[7.N.3X(\'O\'),7.N.3X(\'U\')];8 m=7;8 n=9(a){a=$.D.2n.2Z+\': \'+a;w(k.1m){k.1m.1R(m.1z||m.N,[m,a])}Y{m.15(P,10,20,a)}};8 o=9(a){8 b=1e 2p(\'6H.6I\');b.6J=1L;b.6K=1L;b.6L=1L;b.6M(a);w(b.3Y.6N!=0){n(b.3Y.6O);u P}u b};8 p=9(a){w(!a){u}w(a.1P.12!=\'D\'){8 b=a.3Z(\'6P\');8 c=(b.R?b[0].3Z(\'6Q\'):[]);n(!b.R?\'???\':(c.R?c[0]:b[0]).1W.16);u}8 d=(k.B?$(k.B)[0]:m.N);8 f={};14(8 i=0;i\'}Y{b=\'<\'+a.12;w(a.1g){14(8 i=0;i\';8 d=a.1W;41(d){b+=7.2Y(d);d=d.77}b+=\'\'}Y{b+=\'/>\'}}u b}});9 X(){7.1d=\'\'}$.I(X.W,{43:9(){7.1d=\'\';u 7},44:9(x,y,a){a=(18(x)?y:a);u 7.1B((a?\'m\':\'M\'),x,y)},2h:9(x,y,a){a=(18(x)?y:a);u 7.1B((a?\'l\':\'L\'),x,y)},22:9(x,a){7.1d+=(a?\'h\':\'H\')+(18(x)?x.1U(\' \'):x);u 7},24:9(y,a){7.1d+=(a?\'v\':\'V\')+(18(y)?y.1U(\' \'):y);u 7},45:9(a,b,c,d,x,y,e){e=(18(a)?b:e);u 7.1B((e?\'c\':\'C\'),a,b,c,d,x,y)},46:9(a,b,x,y,c){c=(18(a)?b:c);u 7.1B((c?\'s\':\'S\'),a,b,x,y)},47:9(a,b,x,y,c){c=(18(a)?b:c);u 7.1B((c?\'q\':\'Q\'),a,b,x,y)},48:9(x,y,a){a=(18(x)?y:a);u 7.1B((a?\'t\':\'T\'),x,y)},1B:9(a,b,c,d,e,f,g){w(18(b)){14(8 i=0;i 1 || parseInt($.fn.jquery.substring(2), 10) > 5; + // Enable animation for all of these SVG numeric attributes - // named as svg-* or svg* (with first character upper case) $.each(['x', 'y', 'width', 'height', 'rx', 'ry', 'cx', 'cy', 'r', 'x1', 'y1', 'x2', 'y2', @@ -24,7 +25,7 @@ $.each(['x', 'y', 'width', 'height', 'rx', 'ry', 'cx', 'cy', 'r', 'x1', 'y1', 'x var attr = fx.elem.attributes.getNamedItem(realAttrName); if (!fx.set) { fx.start = (attr ? parseFloat(attr.nodeValue) : 0); - var offset = ($.fn.jquery >= '1.6' ? '' : + var offset = (jQueryNew ? '' : fx.options.curAnim['svg' + ccName] || fx.options.curAnim['svg-' + attrName]); if (/^[+-]=/.exec(offset)) { fx.end = fx.start + parseFloat(offset.replace(/=/, '')); @@ -32,7 +33,7 @@ $.each(['x', 'y', 'width', 'height', 'rx', 'ry', 'cx', 'cy', 'r', 'x1', 'y1', 'x $(fx.elem).css(realAttrName, ''); fx.set = true; } - var value = (fx.pos * (fx.end - fx.start) + fx.start) + (fx.unit == '%' ? '%' : ''); + var value = (fx.pos * (fx.end - fx.start) + fx.start) + (fx.unit === '%' ? '%' : ''); (attr ? attr.nodeValue = value : fx.elem.setAttribute(realAttrName, value)); }; } @@ -44,13 +45,13 @@ $.fx.step['svgStroke-dasharray'] = $.fx.step['svg-stroke-dasharray'] = function( var attr = fx.elem.attributes.getNamedItem('stroke-dasharray'); if (!fx.set) { fx.start = parseDashArray(attr ? attr.nodeValue : ''); - var offset = ($.fn.jquery >= '1.6' ? fx.end : + var offset = (jQueryNew ? fx.end : fx.options.curAnim['svgStrokeDashArray'] || fx.options.curAnim['svg-strokeDashArray'] || fx.options.curAnim['svgStroke-dasharray'] || fx.options.curAnim['svg-stroke-dasharray']); fx.end = parseDashArray(offset); if (/^[+-]=/.exec(offset)) { offset = offset.split(/[, ]+/); - if (offset.length % 2 == 1) { // Must have an even number + if (offset.length % 2 === 1) { // Must have an even number var len = offset.length; for (var i = 0; i < len; i++) { // So repeat offset.push(offset[i]); @@ -70,9 +71,10 @@ $.fx.step['svgStroke-dasharray'] = $.fx.step['svg-stroke-dasharray'] = function( (attr ? attr.nodeValue = value : fx.elem.setAttribute('stroke-dasharray', value)); }; -/* Parse a strokeDashArray definition: dash, gap, ... - @param value (string) the definition - @return (number[2n]) the extracted values */ +/** Parse a strokeDashArray definition: dash, gap, ... + @private + @param value {string} The definition. + @return {number[]} The extracted values. */ function parseDashArray(value) { var dashArray = value.split(/[, ]+/); for (var i = 0; i < dashArray.length; i++) { @@ -81,7 +83,7 @@ function parseDashArray(value) { dashArray[i] = 0; } } - if (dashArray.length % 2 == 1) { // Must have an even number + if (dashArray.length % 2 === 1) { // Must have an even number var len = dashArray.length; for (var i = 0; i < len; i++) { // So repeat dashArray.push(dashArray[i]); @@ -95,8 +97,7 @@ $.fx.step['svgViewBox'] = $.fx.step['svg-viewBox'] = function(fx) { var attr = fx.elem.attributes.getNamedItem('viewBox'); if (!fx.set) { fx.start = parseViewBox(attr ? attr.nodeValue : ''); - var offset = ($.fn.jquery >= '1.6' ? fx.end : - fx.options.curAnim['svgViewBox'] || fx.options.curAnim['svg-viewBox']); + var offset = (jQueryNew ? fx.end : fx.options.curAnim['svgViewBox'] || fx.options.curAnim['svg-viewBox']); fx.end = parseViewBox(offset); if (/^[+-]=/.exec(offset)) { offset = offset.split(/[, ]+/); @@ -117,9 +118,10 @@ $.fx.step['svgViewBox'] = $.fx.step['svg-viewBox'] = function(fx) { (attr ? attr.nodeValue = value : fx.elem.setAttribute('viewBox', value)); }; -/* Parse a viewBox definition: x, y, width, height. - @param value (string) the definition - @return (number[4]) the extracted values */ +/** Parse a viewBox definition: x, y, width, height. + @private + @param value {string} The definition. + @return {number[]} The extracted values. */ function parseViewBox(value) { var viewBox = value.split(/[, ]+/); for (var i = 0; i < viewBox.length; i++) { @@ -151,22 +153,18 @@ $.fx.step['svgTransform'] = $.fx.step['svg-transform'] = function(fx) { (fx.pos * (fx.end.translateY - fx.start.translateY) + fx.start.translateY) + ')'; break; case 's': - transform += ' scale(' + - (fx.pos * (fx.end.scaleX - fx.start.scaleX) + fx.start.scaleX) + ',' + + transform += ' scale(' + (fx.pos * (fx.end.scaleX - fx.start.scaleX) + fx.start.scaleX) + ',' + (fx.pos * (fx.end.scaleY - fx.start.scaleY) + fx.start.scaleY) + ')'; break; case 'r': - transform += ' rotate(' + - (fx.pos * (fx.end.rotateA - fx.start.rotateA) + fx.start.rotateA) + ',' + + transform += ' rotate(' + (fx.pos * (fx.end.rotateA - fx.start.rotateA) + fx.start.rotateA) + ',' + (fx.pos * (fx.end.rotateX - fx.start.rotateX) + fx.start.rotateX) + ',' + (fx.pos * (fx.end.rotateY - fx.start.rotateY) + fx.start.rotateY) + ')'; break; case 'x': - transform += ' skewX(' + - (fx.pos * (fx.end.skewX - fx.start.skewX) + fx.start.skewX) + ')'; + transform += ' skewX(' + (fx.pos * (fx.end.skewX - fx.start.skewX) + fx.start.skewX) + ')'; case 'y': - transform += ' skewY(' + - (fx.pos * (fx.end.skewY - fx.start.skewY) + fx.start.skewY) + ')'; + transform += ' skewY(' + (fx.pos * (fx.end.skewY - fx.start.skewY) + fx.start.skewY) + ')'; break; case 'm': var matrix = ''; @@ -180,18 +178,18 @@ $.fx.step['svgTransform'] = $.fx.step['svg-transform'] = function(fx) { (attr ? attr.nodeValue = transform : fx.elem.setAttribute('transform', transform)); }; -/* Decode a transform string and extract component values. - @param value (string) the transform string to parse - @param original (object) the settings from the original node - @return (object) the combined transformation attributes */ +/** Decode a transform string and extract component values. + @private + @param value {string} The transform string to parse. + @param original {object} The settings from the original node. + @return {object} The combined transformation attributes. */ function parseTransform(value, original) { value = value || ''; - if (typeof value == 'object') { + if (typeof value === 'object') { value = value.nodeValue; } var transform = $.extend({translateX: 0, translateY: 0, scaleX: 0, scaleY: 0, - rotateA: 0, rotateX: 0, rotateY: 0, skewX: 0, skewY: 0, - matrix: [0, 0, 0, 0, 0, 0]}, original || {}); + rotateA: 0, rotateX: 0, rotateY: 0, skewX: 0, skewY: 0, matrix: [0, 0, 0, 0, 0, 0]}, original || {}); transform.order = ''; var pattern = /([a-zA-Z]+)\(\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*[\s,]\s*([+-]?[\d\.]+)\s*[\s,]\s*([+-]?[\d\.]+)\s*)?)?)?\)/g; var result = pattern.exec(value); @@ -224,14 +222,13 @@ function parseTransform(value, original) { case 'matrix': transform.order += 'm'; transform.matrix = [parseFloat(result[2]), parseFloat(result[3]), - parseFloat(result[4]), parseFloat(result[5]), - parseFloat(result[6]), parseFloat(result[7])]; + parseFloat(result[4]), parseFloat(result[5]), parseFloat(result[6]), parseFloat(result[7])]; break; } result = pattern.exec(value); } - if (transform.order == 'm' && Math.abs(transform.matrix[0]) == Math.abs(transform.matrix[3]) && - transform.matrix[1] != 0 && Math.abs(transform.matrix[1]) == Math.abs(transform.matrix[2])) { + if (transform.order === 'm' && Math.abs(transform.matrix[0]) === Math.abs(transform.matrix[3]) && + transform.matrix[1] !== 0 && Math.abs(transform.matrix[1]) === Math.abs(transform.matrix[2])) { // Simple rotate about origin and translate var angle = Math.acos(transform.matrix[0]) * 180 / Math.PI; angle = (transform.matrix[1] < 0 ? 360 - angle : angle); @@ -251,49 +248,51 @@ $.each(['fill', 'stroke'], $.fx.step['svg' + ccName] = $.fx.step['svg-' + attrName] = function(fx) { if (!fx.set) { fx.start = $.svg._getColour(fx.elem, attrName); - var toNone = (fx.end == 'none'); + var toNone = (fx.end === 'none'); fx.end = (toNone ? $.svg._getColour(fx.elem.parentNode, attrName) : $.svg._getRGB(fx.end)); fx.end[3] = toNone; $(fx.elem).css(attrName, ''); fx.set = true; } - var attr = fx.elem.attributes.getNamedItem(attrName); var colour = 'rgb(' + [ Math.min(Math.max(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 0), 255), Math.min(Math.max(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 0), 255), Math.min(Math.max(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 0), 255) ].join(',') + ')'; - colour = (fx.end[3] && fx.state == 1 ? 'none' : colour); + colour = (fx.end[3] && fx.state === 1 ? 'none' : colour); + var attr = fx.elem.attributes.getNamedItem(attrName); (attr ? attr.nodeValue = colour : fx.elem.setAttribute(attrName, colour)); } } ); -/* Find this attribute value somewhere up the node hierarchy. - @param elem (element) the starting element to find the attribute - @param attr (string) the attribute name - @return (number[3]) RGB components for the attribute colour */ +/** Find this attribute value somewhere up the node hierarchy. + @private + @param elem {SVGElement} The starting element to find the attribute. + @param attr {string} The attribute name. + @return {number[]} RGB components for the attribute colour. */ $.svg._getColour = function(elem, attr) { elem = $(elem); var colour; do { colour = elem.attr(attr) || elem.css(attr); // Keep going until we find an element that has colour, or exit SVG - if ((colour != '' && colour != 'none') || elem.hasClass($.svg.markerClassName)) { + if ((colour !== '' && colour !== 'none') || elem.hasClass($.svg.markerClassName)) { break; } } while (elem = elem.parent()); return $.svg._getRGB(colour); }; -/* Parse strings looking for common colour formats. - @param colour (string) colour description to parse - @return (number[3]) RGB components of this colour */ +/** Parse strings looking for common colour formats. + @private + @param colour {string} Colour description to parse. + @return {number[]} RGB components of this colour. */ $.svg._getRGB = function(colour) { var result; // Check if we're already dealing with an array of colors - if (colour && colour.constructor == Array) { - return (colour.length == 3 || colour.length == 4 ? colour : colours['none']); + if (colour && colour.constructor === Array) { + return (colour.length === 3 || colour.length === 4 ? colour : colours['none']); } // Look for rgb(num,num,num) if (result = /^rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)$/.exec(colour)) { @@ -301,8 +300,7 @@ $.svg._getRGB = function(colour) { } // Look for rgb(num%,num%,num%) if (result = /^rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)$/.exec(colour)) { - return [parseFloat(result[1]) * 2.55, parseFloat(result[2]) * 2.55, - parseFloat(result[3]) * 2.55]; + return [parseFloat(result[1]) * 2.55, parseFloat(result[2]) * 2.55, parseFloat(result[3]) * 2.55]; } // Look for #a0b1c2 if (result = /^#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})$/.exec(colour)) { diff --git a/jquery.svganim.min.js b/jquery.svganim.min.js index 8b0eca8..d9a9ac4 100644 --- a/jquery.svganim.min.js +++ b/jquery.svganim.min.js @@ -1,7 +1,6 @@ -/* http://keith-wood.name/svg.html - SVG attribute animations for jQuery v1.4.5. +/* http://keith-wood.name/svg.html + SVG attribute animations for jQuery v1.5.0. Written by Keith Wood (kbwood{at}iinet.com.au) June 2008. - Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and - MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. + Available under the MIT (http://keith-wood.name/licence.html) license. Please attribute the author if you use it. */ -(function($){$.each(['x','y','width','height','rx','ry','cx','cy','r','x1','y1','x2','y2','stroke-width','strokeWidth','opacity','fill-opacity','fillOpacity','stroke-opacity','strokeOpacity','stroke-dashoffset','strokeDashOffset','font-size','fontSize','font-weight','fontWeight','letter-spacing','letterSpacing','word-spacing','wordSpacing'],function(i,f){var g=f.charAt(0).toUpperCase()+f.substr(1);if($.cssProps){$.cssProps['svg'+g]=$.cssProps['svg-'+f]=f}$.fx.step['svg'+g]=$.fx.step['svg-'+f]=function(a){var b=$.svg._attrNames[f]||f;var c=a.elem.attributes.getNamedItem(b);if(!a.set){a.start=(c?parseFloat(c.nodeValue):0);var d=($.fn.jquery>='1.6'?'':a.options.curAnim['svg'+g]||a.options.curAnim['svg-'+f]);if(/^[+-]=/.exec(d)){a.end=a.start+parseFloat(d.replace(/=/,''))}$(a.elem).css(b,'');a.set=true}var e=(a.pos*(a.end-a.start)+a.start)+(a.unit=='%'?'%':'');(c?c.nodeValue=e:a.elem.setAttribute(b,e))}});$.fx.step['svgStrokeDashArray']=$.fx.step['svg-strokeDashArray']=$.fx.step['svgStroke-dasharray']=$.fx.step['svg-stroke-dasharray']=function(a){var b=a.elem.attributes.getNamedItem('stroke-dasharray');if(!a.set){a.start=parseDashArray(b?b.nodeValue:'');var c=($.fn.jquery>='1.6'?a.end:a.options.curAnim['svgStrokeDashArray']||a.options.curAnim['svg-strokeDashArray']||a.options.curAnim['svgStroke-dasharray']||a.options.curAnim['svg-stroke-dasharray']);a.end=parseDashArray(c);if(/^[+-]=/.exec(c)){c=c.split(/[, ]+/);if(c.length%2==1){var d=c.length;for(var i=0;i='1.6'?a.end:a.options.curAnim['svgViewBox']||a.options.curAnim['svg-viewBox']);a.end=parseViewBox(c);if(/^[+-]=/.exec(c)){c=c.split(/[, ]+/);while(c.length<4){c.push('0')}for(var i=0;i<4;i++){if(/^[+-]=/.exec(c[i])){a.end[i]=a.start[i]+parseFloat(c[i].replace(/=/,''))}}}a.set=true}var d=$.map(a.start,function(n,i){return(a.pos*(a.end[i]-n)+n)}).join(' ');(b?b.nodeValue=d:a.elem.setAttribute('viewBox',d))};function parseViewBox(a){var b=a.split(/[, ]+/);for(var i=0;i1||parseInt($.fn.jquery.substring(2),10)>5;$.each(['x','y','width','height','rx','ry','cx','cy','r','x1','y1','x2','y2','stroke-width','strokeWidth','opacity','fill-opacity','fillOpacity','stroke-opacity','strokeOpacity','stroke-dashoffset','strokeDashOffset','font-size','fontSize','font-weight','fontWeight','letter-spacing','letterSpacing','word-spacing','wordSpacing'],function(i,f){var g=f.charAt(0).toUpperCase()+f.substr(1);if($.cssProps){$.cssProps['svg'+g]=$.cssProps['svg-'+f]=f}$.fx.step['svg'+g]=$.fx.step['svg-'+f]=function(a){var b=$.svg._attrNames[f]||f;var c=a.elem.attributes.getNamedItem(b);if(!a.set){a.start=(c?parseFloat(c.nodeValue):0);var d=(h?'':a.options.curAnim['svg'+g]||a.options.curAnim['svg-'+f]);if(/^[+-]=/.exec(d)){a.end=a.start+parseFloat(d.replace(/=/,''))}$(a.elem).css(b,'');a.set=true}var e=(a.pos*(a.end-a.start)+a.start)+(a.unit==='%'?'%':'');(c?c.nodeValue=e:a.elem.setAttribute(b,e))}});$.fx.step['svgStrokeDashArray']=$.fx.step['svg-strokeDashArray']=$.fx.step['svgStroke-dasharray']=$.fx.step['svg-stroke-dasharray']=function(a){var b=a.elem.attributes.getNamedItem('stroke-dasharray');if(!a.set){a.start=parseDashArray(b?b.nodeValue:'');var c=(h?a.end:a.options.curAnim['svgStrokeDashArray']||a.options.curAnim['svg-strokeDashArray']||a.options.curAnim['svgStroke-dasharray']||a.options.curAnim['svg-stroke-dasharray']);a.end=parseDashArray(c);if(/^[+-]=/.exec(c)){c=c.split(/[, ]+/);if(c.length%2===1){var d=c.length;for(var i=0;i35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(A($){$.2f([\'x\',\'y\',\'2g\',\'2S\',\'2T\',\'2U\',\'2V\',\'2W\',\'r\',\'2X\',\'2Y\',\'2Z\',\'31\',\'U-2g\',\'33\',\'1F\',\'2h-1F\',\'36\',\'U-1F\',\'37\',\'U-38\',\'39\',\'2i-3a\',\'3b\',\'2i-3c\',\'3d\',\'3e-2j\',\'3f\',\'3g-2j\',\'3h\'],A(i,f){l g=f.1G(0).2k()+f.1H(1);q($.1I){$.1I[\'u\'+g]=$.1I[\'u-\'+f]=f}$.D.E[\'u\'+g]=$.D.E[\'u-\'+f]=A(a){l b=$.u.3i[f]||f;l c=a.B.1l.1m(b);q(!a.N){a.k=(c?p(c.O):0);l d=($.1J.1K>=\'1.6\'?\'\':a.V.W[\'u\'+g]||a.V.W[\'u-\'+f]);q(/^[+-]=/.L(d)){a.o=a.k+p(d.1L(/=/,\'\'))}$(a.B).1M(b,\'\');a.N=1n}l e=(a.w*(a.o-a.k)+a.k)+(a.3j==\'%\'?\'%\':\'\');(c?c.O=e:a.B.1o(b,e))}});$.D.E[\'2l\']=$.D.E[\'u-2m\']=$.D.E[\'2n-17\']=$.D.E[\'u-U-17\']=A(a){l b=a.B.1l.1m(\'U-17\');q(!a.N){a.k=1N(b?b.O:\'\');l c=($.1J.1K>=\'1.6\'?a.o:a.V.W[\'2l\']||a.V.W[\'u-2m\']||a.V.W[\'2n-17\']||a.V.W[\'u-U-17\']);a.o=1N(c);q(/^[+-]=/.L(c)){c=c.1r(/[, ]+/);q(c.F%2==1){l d=c.F;X(l i=0;i=\'1.6\'?a.o:a.V.W[\'2q\']||a.V.W[\'u-1t\']);a.o=1P(c);q(/^[+-]=/.L(c)){c=c.1r(/[, ]+/);1u(c.F<4){c.1s(\'0\')}X(l i=0;i<4;i++){q(/^[+-]=/.L(c[i])){a.o[i]=a.k[i]+p(c[i].1L(/=/,\'\'))}}}a.N=1n}l d=$.2o(a.k,A(n,i){G(a.w*(a.o[i]-n)+n)}).1O(\' \');(b?b.O=d:a.B.1o(\'1t\',d))};A 1P(a){l b=a.1r(/[, ]+/);X(l i=0;itrue if this class is present, false if not. */ $.fn.hasClass = function(origHasClass) { return function(className) { className = className || ''; var found = false; this.each(function() { if ($.svg.isSVGElem(this)) { - var classes = (this.className ? this.className.baseVal : - this.getAttribute('class')).split(/\s+/); - found = ($.inArray(className, classes) > -1); + found = ($.inArray(className, getClassNames(this).split(/\s+/)) > -1); } else { found = (origHasClass.apply($(this), [className])); @@ -89,15 +140,19 @@ $.fn.hasClass = function(origHasClass) { }; }($.fn.hasClass); -/* Support attributes on SVG nodes. */ +/** Support attributes on SVG nodes. + @param name {string} The attribute name. + @param [value] {any} The new attribute value. + @param type {boolean} Internal flag. + @return {any} If an attribute value is requested. */ $.fn.attr = function(origAttr) { return function(name, value, type) { - if (typeof name === 'string' && value === undefined) { - var val = origAttr.apply(this, [name]); + if (typeof name === 'string' && value === undefined) { // Return attribute value + var val = origAttr.apply(this, arguments); if (val && val.baseVal && val.baseVal.numberOfItems != null) { // Multiple values value = ''; val = val.baseVal; - if (name == 'transform') { + if (name === 'transform') { for (var i = 0; i < val.numberOfItems; i++) { var item = val.getItem(i); switch (item.type) { @@ -126,30 +181,39 @@ $.fn.attr = function(origAttr) { options = {}; options[name] = value; } - return this.each(function() { + if ($.isFunction(value)) { + return $(this).each(function(i) { + $(this).attr(name, value.call(this, i, $(this).attr(name))); + }); + } + var origArgs = arguments; + return $(this).each(function() { if ($.svg.isSVGElem(this)) { for (var n in options) { - var val = ($.isFunction(options[n]) ? options[n]() : options[n]); - (type ? this.style[n] = val : this.setAttribute(n, val)); + (type ? this.style[n] = options[n] : this.setAttribute(n, options[n])); } } else { - origAttr.apply($(this), [name, value, type]); + origAttr.apply($(this), origArgs); } }); }; }($.fn.attr); -/* Support removing attributes on SVG nodes. */ +/** Support removing attributes on SVG nodes. + @param names {string} The names of the attributes to remove. */ $.fn.removeAttr = function(origRemoveAttr) { - return function(name) { + return function(names) { + var origArgs = arguments; return this.each(function() { if ($.svg.isSVGElem(this)) { - (this[name] && this[name].baseVal ? this[name].baseVal.value = '' : - this.setAttribute(name, '')); + var node = this; + $.each(names.split(/\s+/), function(i, name) { + (node[name] && node[name].baseVal ? node[name].baseVal.value = null : node.removeAttribute(name)); + }); } else { - origRemoveAttr.apply($(this), [name]); + origRemoveAttr.apply($(this), origArgs); } }); }; @@ -165,242 +229,11 @@ $.extend($.cssNumber, { /* Support retrieving CSS/attribute values on SVG nodes. */ if ($.cssProps) { $.css = function(origCSS) { - return function(elem, name, extra) { + return function(elem, name, numeric, extra) { var value = (name.match(/^svg.*/) ? $(elem).attr($.cssProps[name] || name) : ''); - return value || origCSS(elem, name, extra); + return value || origCSS(elem, name, numeric, extra); }; }($.css); } - -/* Determine if any nodes are SVG nodes. */ -function anySVG(checkSet) { - for (var i = 0; i < checkSet.length; i++) { - if (checkSet[i].nodeType == 1 && checkSet[i].namespaceURI == $.svg.svgNS) { - return true; - } - } - return false; -} - -/* Update Sizzle selectors. */ - -$.expr.relative['+'] = function(origRelativeNext) { - return function(checkSet, part, isXML) { - origRelativeNext(checkSet, part, isXML || anySVG(checkSet)); - }; -}($.expr.relative['+']); - -$.expr.relative['>'] = function(origRelativeChild) { - return function(checkSet, part, isXML) { - origRelativeChild(checkSet, part, isXML || anySVG(checkSet)); - }; -}($.expr.relative['>']); - -$.expr.relative[''] = function(origRelativeDescendant) { - return function(checkSet, part, isXML) { - origRelativeDescendant(checkSet, part, isXML || anySVG(checkSet)); - }; -}($.expr.relative['']); - -$.expr.relative['~'] = function(origRelativeSiblings) { - return function(checkSet, part, isXML) { - origRelativeSiblings(checkSet, part, isXML || anySVG(checkSet)); - }; -}($.expr.relative['~']); - -$.expr.find.ID = function(origFindId) { - return function(match, context, isXML) { - return ($.svg.isSVGElem(context) ? - [context.ownerDocument.getElementById(match[1])] : - origFindId(match, context, isXML)); - }; -}($.expr.find.ID); - -var div = document.createElement('div'); -div.appendChild(document.createComment('')); -if (div.getElementsByTagName('*').length > 0) { // Make sure no comments are found - $.expr.find.TAG = function(match, context) { - var results = context.getElementsByTagName(match[1]); - if (match[1] === '*') { // Filter out possible comments - var tmp = []; - for (var i = 0; results[i] || results.item(i); i++) { - if ((results[i] || results.item(i)).nodeType === 1) { - tmp.push(results[i] || results.item(i)); - } - } - results = tmp; - } - return results; - }; -} - -$.expr.preFilter.CLASS = function(match, curLoop, inplace, result, not, isXML) { - match = ' ' + match[1].replace(/\\/g, '') + ' '; - if (isXML) { - return match; - } - for (var i = 0, elem = {}; elem != null; i++) { - elem = curLoop[i]; - if (!elem) { - try { - elem = curLoop.item(i); - } - catch (e) { - // Ignore - } - } - if (elem) { - var className = (!$.svg.isSVGElem(elem) ? elem.className : - (elem.className ? elem.className.baseVal : '') || elem.getAttribute('class')); - if (not ^ (className && (' ' + className + ' ').indexOf(match) > -1)) { - if (!inplace) - result.push(elem); - } - else if (inplace) { - curLoop[i] = false; - } - } - } - return false; -}; - -$.expr.filter.CLASS = function(elem, match) { - var className = (!$.svg.isSVGElem(elem) ? elem.className : - (elem.className ? elem.className.baseVal : elem.getAttribute('class'))); - return (' ' + className + ' ').indexOf(match) > -1; -}; - -$.expr.filter.ATTR = function(origFilterAttr) { - return function(elem, match) { - var handler = null; - if ($.svg.isSVGElem(elem)) { - handler = match[1]; - $.expr.attrHandle[handler] = function(elem){ - var attr = elem.getAttribute(handler); - return attr && attr.baseVal || attr; - }; - } - var filter = origFilterAttr(elem, match); - if (handler) { - $.expr.attrHandle[handler] = null; - } - return filter; - }; -}($.expr.filter.ATTR); - -/* - In the removeData function (line 1881, v1.7.2): - - if ( jQuery.support.deleteExpando ) { - delete elem[ internalKey ]; - } else { - try { // SVG - elem.removeAttribute( internalKey ); - } catch (e) { - elem[ internalKey ] = null; - } - } - - In the event.add function (line 2985, v1.7.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 3074, v1.7.2): - - if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { - try { // SVG - elem.removeEventListener(type, elemData.handle, false); - } - catch (e) { - if (elem.detachEvent) { - elem.detachEvent("on" + type, elemData.handle); - } - } - } - - In the event.fix function (line 3394, v1.7.2): - - if (event.target.namespaceURI == 'http://www.w3.org/2000/svg') { // SVG - event.button = [1, 4, 2][event.button]; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && button !== undefined ) { - event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); - } - - In the Sizzle function (line 4083, v1.7.2): - - if ( toString.call(checkSet) === "[object Array]" ) { - if ( !prune ) { - results.push.apply( results, checkSet ); - - } else if ( context && context.nodeType === 1 ) { - for ( i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { - results.push( set[i] || set.item(i) ); // SVG - } - } - - } else { - for ( 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 4877, v1.7.2): - - if ( toString.call(array) === "[object Array]" ) { - Array.prototype.push.apply( ret, array ); - - } else { - if ( typeof array.length === "number" ) { - for ( var l = array.length; i < l; i++ ) { - ret.push( array[i] || array.item(i) ); // SVG - } - - } else { - for ( ; array[i]; i++ ) { - ret.push( array[i] ); - } - } - } - - In the jQuery.cleandata function (line 6538, v1.7.2): - - if ( deleteExpando ) { - delete elem[ jQuery.expando ]; - - } else { - try { // SVG - elem.removeAttribute( jQuery.expando ); - } catch (e) { - // Ignore - } - } - - In the fallback getComputedStyle function (line 6727, v1.7.2): - - defaultView = (elem.ownerDocument ? elem.ownerDocument.defaultView : elem.defaultView); // SVG - if ( defaultView && - (computedStyle = defaultView.getComputedStyle( elem, null )) ) { - - ret = computedStyle.getPropertyValue( name ); - ... - -*/ })(jQuery); diff --git a/jquery.svgdom.min.js b/jquery.svgdom.min.js index 5c76168..3def35f 100644 --- a/jquery.svgdom.min.js +++ b/jquery.svgdom.min.js @@ -1,7 +1,6 @@ -/* http://keith-wood.name/svg.html - jQuery DOM compatibility for jQuery SVG v1.4.5. +/* http://keith-wood.name/svg.html + jQuery DOM compatibility for jQuery SVG v1.5.0. Written by Keith Wood (kbwood{at}iinet.com.au) April 2009. - Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and - MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. + Available under the MIT (http://keith-wood.name/licence.html) license. Please attribute the author if you use it. */ -(function($){$.fn.addClass=function(e){return function(d){d=d||'';return this.each(function(){if($.svg.isSVGElem(this)){var c=this;$.each(d.split(/\s+/),function(i,a){var b=(c.className?c.className.baseVal:c.getAttribute('class'));if($.inArray(a,b.split(/\s+/))==-1){b+=(b?' ':'')+a;(c.className?c.className.baseVal=b:c.setAttribute('class',b))}})}else{e.apply($(this),[d])}})}}($.fn.addClass);$.fn.removeClass=function(e){return function(d){d=d||'';return this.each(function(){if($.svg.isSVGElem(this)){var c=this;$.each(d.split(/\s+/),function(i,a){var b=(c.className?c.className.baseVal:c.getAttribute('class'));b=$.grep(b.split(/\s+/),function(n,i){return n!=a}).join(' ');(c.className?c.className.baseVal=b:c.setAttribute('class',b))})}else{e.apply($(this),[d])}})}}($.fn.removeClass);$.fn.toggleClass=function(c){return function(a,b){return this.each(function(){if($.svg.isSVGElem(this)){if(typeof b!=='boolean'){b=!$(this).hasClass(a)}$(this)[(b?'add':'remove')+'Class'](a)}else{c.apply($(this),[a,b])}})}}($.fn.toggleClass);$.fn.hasClass=function(d){return function(b){b=b||'';var c=false;this.each(function(){if($.svg.isSVGElem(this)){var a=(this.className?this.className.baseVal:this.getAttribute('class')).split(/\s+/);c=($.inArray(b,a)>-1)}else{c=(d.apply($(this),[b]))}return!c});return c}}($.fn.hasClass);$.fn.attr=function(h){return function(b,c,d){if(typeof b==='string'&&c===undefined){var e=h.apply(this,[b]);if(e&&e.baseVal&&e.baseVal.numberOfItems!=null){c='';e=e.baseVal;if(b=='transform'){for(var i=0;i']=function(d){return function(a,b,c){d(a,b,c||anySVG(a))}}($.expr.relative['>']);$.expr.relative['']=function(d){return function(a,b,c){d(a,b,c||anySVG(a))}}($.expr.relative['']);$.expr.relative['~']=function(d){return function(a,b,c){d(a,b,c||anySVG(a))}}($.expr.relative['~']);$.expr.find.ID=function(d){return function(a,b,c){return($.svg.isSVGElem(b)?[b.ownerDocument.getElementById(a[1])]:d(a,b,c))}}($.expr.find.ID);var j=document.createElement('div');j.appendChild(document.createComment(''));if(j.getElementsByTagName('*').length>0){$.expr.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==='*'){var d=[];for(var i=0;c[i]||c.item(i);i++){if((c[i]||c.item(i)).nodeType===1){d.push(c[i]||c.item(i))}}c=d}return c}}$.expr.preFilter.CLASS=function(a,b,c,d,f,g){a=' '+a[1].replace(/\\/g,'')+' ';if(g){return a}for(var i=0,elem={};elem!=null;i++){elem=b[i];if(!elem){try{elem=b.item(i)}catch(e){}}if(elem){var h=(!$.svg.isSVGElem(elem)?elem.className:(elem.className?elem.className.baseVal:'')||elem.getAttribute('class'));if(f^(h&&(' '+h+' ').indexOf(a)>-1)){if(!c)d.push(elem)}else if(c){b[i]=false}}}return false};$.expr.filter.CLASS=function(a,b){var c=(!$.svg.isSVGElem(a)?a.className:(a.className?a.className.baseVal:a.getAttribute('class')));return(' '+c+' ').indexOf(b)>-1};$.expr.filter.ATTR=function(g){return function(c,d){var e=null;if($.svg.isSVGElem(c)){e=d[1];$.expr.attrHandle[e]=function(a){var b=a.getAttribute(e);return b&&b.baseVal||b}}var f=g(c,d);if(e){$.expr.attrHandle[e]=null}return f}}($.expr.filter.ATTR)})(jQuery); \ No newline at end of file +(function($){var j=/[\t\r\n]/g,rspace=/\s+/,rwhitespace="[\\x20\\t\\r\\n\\f]";function getClassNames(a){return(!$.svg.isSVGElem(a)?a.className:(a.className?a.className.baseVal:a.getAttribute('class')))||''}function setClassNames(a,b){(a.className?a.className.baseVal=b:a.setAttribute('class',b))}$.fn.addClass=function(f){return function(d){if($.isFunction(d)){return this.each(function(i){$(this).addClass(d.call(this,i,getClassNames(this)))})}var e=arguments;d=d||'';return this.each(function(){if($.svg.isSVGElem(this)){var c=this;$.each(d.split(/\s+/),function(i,a){var b=getClassNames(c);if($.inArray(a,b.split(/\s+/))===-1){setClassNames(c,b+=(b?' ':'')+a)}})}else{f.apply($(this),e)}})}}($.fn.addClass);$.fn.removeClass=function(f){return function(d){if($.isFunction(d)){return this.each(function(i){$(this).removeClass(d.call(this,i,getClassNames(this)))})}var e=arguments;d=d||'';return this.each(function(){if($.svg.isSVGElem(this)){var c=this;$.each(d.split(/\s+/),function(i,a){var b=getClassNames(c);b=$.grep(b.split(/\s+/),function(n,i){return n!==a}).join(' ');setClassNames(c,b)})}else{f.apply($(this),e)}})}}($.fn.removeClass);$.fn.toggleClass=function(h){return function(d,e){if($.isFunction(d)){return this.each(function(i){$(this).toggleClass(d.call(this,i,getClassNames(this),e),e)})}var f=arguments;var g=(typeof e==='boolean');return this.each(function(){if($.svg.isSVGElem(this)){if(typeof d==='string'){var b=$(this);$.each(d.split(/\s+/),function(i,a){if(!g){e=!b.hasClass(a)}b[(e?'add':'remove')+'Class'](a)})}else{var c=getClassNames(this);if(c){$._data(this,'__className__',c)}setClassNames(this,c||d===false?'':$._data(this,'__className__')||'')}}else{h.apply($(this),f)}})}}($.fn.toggleClass);$.fn.hasClass=function(c){return function(a){a=a||'';var b=false;this.each(function(){if($.svg.isSVGElem(this)){b=($.inArray(a,getClassNames(this).split(/\s+/))>-1)}else{b=(c.apply($(this),[a]))}return!b});return b}}($.fn.hasClass);$.fn.attr=function(h){return function(a,b,c){if(typeof a==='string'&&b===undefined){var d=h.apply(this,arguments);if(d&&d.baseVal&&d.baseVal.numberOfItems!=null){b='';d=d.baseVal;if(a==='transform'){for(var i=0;i35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(7($){$.q.S=7(e){8 7(d){d=d||\'\';8 9.w(7(){k($.r.v(9)){l c=9;$.w(d.E(/\\s+/),7(i,a){l b=(c.o?c.o.p:c.B(\'z\'));k($.T(a,b.E(/\\s+/))==-1){b+=(b?\' \':\'\')+a;(c.o?c.o.p=b:c.H(\'z\',b))}})}x{e.A($(9),[d])}})}}($.q.S);$.q.U=7(e){8 7(d){d=d||\'\';8 9.w(7(){k($.r.v(9)){l c=9;$.w(d.E(/\\s+/),7(i,a){l b=(c.o?c.o.p:c.B(\'z\'));b=$.1d(b.E(/\\s+/),7(n,i){8 n!=a}).1e(\' \');(c.o?c.o.p=b:c.H(\'z\',b))})}x{e.A($(9),[d])}})}}($.q.U);$.q.V=7(c){8 7(a,b){8 9.w(7(){k($.r.v(9)){k(M b!==\'1f\'){b=!$(9).N(a)}$(9)[(b?\'1g\':\'1h\')+\'1i\'](a)}x{c.A($(9),[a,b])}})}}($.q.V);$.q.N=7(d){8 7(b){b=b||\'\';l c=I;9.w(7(){k($.r.v(9)){l a=(9.o?9.o.p:9.B(\'z\')).E(/\\s+/);c=($.T(b,a)>-1)}x{c=(d.A($(9),[b]))}8!c});8 c}}($.q.N);$.q.O=7(h){8 7(b,c,d){k(M b===\'W\'&&c===1j){l e=h.A(9,[b]);k(e&&e.p&&e.p.X!=J){c=\'\';e=e.p;k(b==\'1k\'){F(l i=0;i\']=7(d){8 7(a,b,c){d(a,b,c||G(a))}}($.m.y[\'>\']);$.m.y[\'\']=7(d){8 7(a,b,c){d(a,b,c||G(a))}}($.m.y[\'\']);$.m.y[\'~\']=7(d){8 7(a,b,c){d(a,b,c||G(a))}}($.m.y[\'~\']);$.m.Q.15=7(d){8 7(a,b,c){8($.r.v(b)?[b.1F.1G(a[1])]:d(a,b,c))}}($.m.Q.15);l j=16.1H(\'1I\');j.1J(16.1K(\'\'));k(j.17(\'*\').13>0){$.m.Q.1L=7(a,b){l c=b.17(a[1]);k(a[1]===\'*\'){l d=[];F(l i=0;c[i]||c.L(i);i++){k((c[i]||c.L(i)).14===1){d.18(c[i]||c.L(i))}}c=d}8 c}}$.m.1M.19=7(a,b,c,d,f,g){a=\' \'+a[1].1N(/\\\\/g,\'\')+\' \';k(g){8 a}F(l i=0,t={};t!=J;i++){t=b[i];k(!t){1O{t=b.L(i)}1P(e){}}k(t){l h=(!$.r.v(t)?t.o:(t.o?t.o.p:\'\')||t.B(\'z\'));k(f^(h&&(\' \'+h+\' \').1a(a)>-1)){k(!c)d.18(t)}x k(c){b[i]=I}}}8 I};$.m.R.19=7(a,b){l c=(!$.r.v(a)?a.o:(a.o?a.o.p:a.B(\'z\')));8(\' \'+c+\' \').1a(b)>-1};$.m.R.1b=7(g){8 7(c,d){l e=J;k($.r.v(c)){e=d[1];$.m.1c[e]=7(a){l b=a.B(e);8 b&&b.p||b}}l f=g(c,d);k(e){$.m.1c[e]=J}8 f}}($.m.R.1b)})(1Q);',62,115,'|||||||function|return|this|||||||||||if|var|expr||className|baseVal|fn|svg||elem|matrix|isSVGElem|each|else|relative|class|apply|getAttribute|case|break|split|for|anySVG|setAttribute|false|null|true|item|typeof|hasClass|attr|angle|find|filter|addClass|inArray|removeClass|toggleClass|string|numberOfItems|getItem|valueAsString|removeAttr|cssProps|css|length|nodeType|ID|document|getElementsByTagName|push|CLASS|indexOf|ATTR|attrHandle|grep|join|boolean|add|remove|Class|undefined|transform|switch|type|translate|scale|rotate|skewX|skewY|substring|in|isFunction|style|value|extend|cssNumber|stopOpacity|strokeMitrelimit|strokeOpacity|match|namespaceURI|svgNS|ownerDocument|getElementById|createElement|div|appendChild|createComment|TAG|preFilter|replace|try|catch|jQuery'.split('|'),0,{})) \ No newline at end of file diff --git a/jquery.svgfilter.js b/jquery.svgfilter.js index 7e5466e..e36d30c 100644 --- a/jquery.svgfilter.js +++ b/jquery.svgfilter.js @@ -1,8 +1,7 @@ /* http://keith-wood.name/svg.html - SVG filters for jQuery v1.4.5. + SVG filters for jQuery v1.5.0. Written by Keith Wood (kbwood{at}iinet.com.au) August 2007. - Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and - MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. + Available under the MIT (http://keith-wood.name/licence.html) license. Please attribute the author if you use it. */ (function($) { // Hide scope, no $ conflict @@ -11,139 +10,130 @@ $.svg.addExtension('filters', SVGFilter); $.extend($.svg._wrapperClass.prototype, { - /* Add a filter definition. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param id (string) the ID for this filter - @param x (number) the x-coordinate for the left edge of the filter - @param y (number) the y-coordinate for the top edge of the filter - @param width (number) the width of the filter - @param height (number) the height of the filter - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add a filter definition. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param id {string} The ID for this filter. + @param x {number} The x-coordinate for the left edge of the filter. + @param y {number} The y-coordinate for the top edge of the filter. + @param width {number} The width of the filter. + @param height {number} The height of the filter. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ filter: function(parent, id, x, y, width, height, settings) { var args = this._args(arguments, ['id', 'x', 'y', 'width', 'height']); return this._makeNode(args.parent, 'filter', $.extend( - {id: args.id, x: args.x, y: args.y, width: args.width, height: args.height}, - args.settings || {})); + {id: args.id, x: args.x, y: args.y, width: args.width, height: args.height}, args.settings || {})); } }); -/* Extension point for SVG filters. - Access through svg.filters. */ +/** The SVG filters manager. +

Use the singleton instance of this class, $.svg.filters, + to interact with the SVG filters functionality.

+ @module SVGFilter */ function SVGFilter(wrapper) { this._wrapper = wrapper; // The attached SVG wrapper object } $.extend(SVGFilter.prototype, { - /* Add a distant light filter. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param azimuth (number) the angle (degrees) in the XY plane for the light source - @param elevation (number) the angle (degrees) in the YZ plane for the light source - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add a distant light filter. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} The ID of this filter. + @param azimuth {number} The angle (degrees) in the XY plane for the light source. + @param elevation {number} The angle (degrees) in the YZ plane for the light source. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ distantLight: function(parent, result, azimuth, elevation, settings) { var args = this._wrapper._args(arguments, ['result', 'azimuth', 'elevation']); return this._wrapper._makeNode(args.parent, 'feDistantLight', $.extend( - {result: args.result, azimuth: args.azimuth, elevation: args.elevation}, - args.settings || {})); + {result: args.result, azimuth: args.azimuth, elevation: args.elevation}, args.settings || {})); }, - /* Add a point light filter. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param x (number) the x-coordinate for the light source - @param y (number) the y-coordinate for the light source - @param z (number) the z-coordinate for the light source - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add a point light filter. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} The ID of this filter. + @param x {number} The x-coordinate for the light source. + @param y {number} The y-coordinate for the light source. + @param z {number} The z-coordinate for the light source. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ pointLight: function(parent, result, x, y, z, settings) { var args = this._wrapper._args(arguments, ['result', 'x', 'y', 'z']); return this._wrapper._makeNode(args.parent, 'fePointLight', $.extend( {result: args.result, x: args.x, y: args.y, z: args.z}, args.settings || {})); }, - /* Add a spot light filter. - Specify all of toX, toY, toZ or none of them. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param x (number) the x-coordinate for the light source - @param y (number) the y-coordinate for the light source - @param z (number) the z-coordinate for the light source - @param toX (number) the x-coordinate for where the light is pointing (optional) - @param toY (number) the y-coordinate for where the light is pointing (optional) - @param toZ (number) the z-coordinate for where the light is pointing (optional) - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add a spot light filter. +

Specify all of toX, toY, toZ or none of them.

+ @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} The ID of this filter. + @param x {number} The x-coordinate for the light source. + @param y {number} The y-coordinate for the light source. + @param z {number} The z-coordinate for the light source. + @param [toX] {number} The x-coordinate for where the light is pointing. + @param [toY] {number} The y-coordinate for where the light is pointing. + @param [toZ] {number} The z-coordinate for where the light is pointing. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ spotLight: function(parent, result, x, y, z, toX, toY, toZ, settings) { - var args = this._wrapper._args(arguments, - ['result', 'x', 'y', 'z', 'toX', 'toY', 'toZ'], ['toX']); + var args = this._wrapper._args(arguments, ['result', 'x', 'y', 'z', 'toX', 'toY', 'toZ'], ['toX']); var sets = $.extend({result: args.result, x: args.x, y: args.y, z: args.z}, - (args.toX != null ? {pointsAtX: args.toX, pointsAtY: args.toY, - pointsAtZ: args.toZ} : {})); - return this._wrapper._makeNode(args.parent, 'feSpotLight', - $.extend(sets, args.settings || {})); + (args.toX != null ? {pointsAtX: args.toX, pointsAtY: args.toY, pointsAtZ: args.toZ} : {})); + return this._wrapper._makeNode(args.parent, 'feSpotLight', $.extend(sets, args.settings || {})); }, - /* Add a blend filter. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param mode (string) normal | multiply | screen | darken | lighten - @param in1 (string) the first image to blend - @param in2 (string) the second image to blend - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add a blend filter. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} The ID of this filter. + @param mode {string} One of 'normal', 'multiply', 'screen', 'darken', 'lighten'. + @param in1 {string} The first image to blend. + @param in2 {string} The second image to blend. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ blend: function(parent, result, mode, in1, in2, settings) { var args = this._wrapper._args(arguments, ['result', 'mode', 'in1', 'in2']); return this._wrapper._makeNode(args.parent, 'feBlend', $.extend( - {result: args.result, mode: args.mode, in_: args.in1, in2: args.in2}, - args.settings || {})); + {result: args.result, mode: args.mode, in_: args.in1, in2: args.in2}, args.settings || {})); }, - /* Add a colour matrix filter. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param in1 (string) the source to colour - @param type (string) matrix | saturate | hueRotate | luminanceToAlpha - @param values (number[][]) for 'matrix' the matrix (5x4) values to apply - (number) for 'saturate' 0.0 to 1.0 - (number) for 'hueRotate' degrees - (void) for 'luminanceToAlpha' - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add a colour matrix filter. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} The ID of this filter. + @param in1 {string} The source to colour. + @param type {string} One of 'matrix', 'saturate', 'hueRotate', 'luminanceToAlpha'. + @param values {number[][]|number} For 'matrix' the matrix (5x4) values to apply, for 'saturate' 0.0 to 1.0, + for 'hueRotate' degrees, for 'luminanceToAlpha' nothing. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ colorMatrix: function(parent, result, in1, type, values, settings) { var args = this._wrapper._args(arguments, ['result', 'in1', 'type', 'values']); - if (isArray(args.values)) { + if ($.isArray(args.values)) { var vs = ''; for (var i = 0; i < args.values.length; i++) { - vs += (i == 0 ? '' : ' ') + args.values[i].join(' '); + vs += (i === 0 ? '' : ' ') + args.values[i].join(' '); } args.values = vs; } - else if (typeof args.values == 'object') { + else if (typeof args.values === 'object') { args.settings = args.values; args.values = null; } var sets = $.extend({result: args.result, in_: args.in1, type: args.type}, (args.values != null ? {values: args.values} : {})); - return this._wrapper._makeNode(args.parent, 'feColorMatrix', - $.extend(sets, args.settings || {})); + return this._wrapper._makeNode(args.parent, 'feColorMatrix', $.extend(sets, args.settings || {})); }, - /* Add a component transfer filter. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param functions (object[]) one for each of RGB and A (alpha, optional) - for each entry: - [0] is (string) identity | table | discrete | linear | gamma - [1] is (number[]) for 'table' or 'discrete' the list of - interpolation or step values OR - (number) for 'linear' the slope, for 'gamma' the amplitude, - [2] is (number) for 'linear' the intercept, for 'gamma' the exponent, - [3] is (number) for 'gamma' the offset - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add a component transfer filter. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} The ID of this filter. + @param functions {object[]} One for each of RGB and A (alpha, optional), for each entry: + [0] {string} one of 'identity', 'table', 'discrete', 'linear', 'gamma', + [1] {number[]|number} for 'table' or 'discrete' the list of interpolation or step values OR + for 'linear' the slope, for 'gamma' the amplitude, + [2] {number} for 'linear' the intercept, for 'gamma' the exponent, + [3] {number} for 'gamma' the offset. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ componentTransfer: function(parent, result, functions, settings) { var args = this._wrapper._args(arguments, ['result', 'functions']); var node = this._wrapper._makeNode(args.parent, 'feComponentTransfer', @@ -152,99 +142,92 @@ $.extend(SVGFilter.prototype, { for (var i = 0; i < Math.min(4, args.functions.length); i++) { var props = args.functions[i]; var sets = $.extend({type: props[0]}, - (props[0] == 'table' || props[0] == 'discrete' ? {tableValues: props[1].join(' ')} : - (props[0] == 'linear' ? {slope: props[1], intercept: props[2]} : - (props[0] == 'gamma' ? {amplitude: props[1], - exponent: props[2], offset: props[3]} : {})))); + (props[0] === 'table' || props[0] === 'discrete' ? {tableValues: props[1].join(' ')} : + (props[0] === 'linear' ? {slope: props[1], intercept: props[2]} : + (props[0] === 'gamma' ? {amplitude: props[1], exponent: props[2], offset: props[3]} : {})))); this._wrapper._makeNode(node, 'feFunc' + rgba[i], sets); } return node; }, - /* Add a composite filter. - Specify all of k1, k2, k3, k4 or none of them. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param operator (string) over | in | out | atop | xor | arithmetic - @param in1 (string) the first filter to compose - @param in2 (string) the second filter to compose - @param k1 (number) for 'arithmetic' (optional) - @param k2 (number) for 'arithmetic' (optional) - @param k3 (number) for 'arithmetic' (optional) - @param k4 (number) for 'arithmetic' (optional) - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add a composite filter. +

Specify all of k1, k2, k3, k4 or none of them.

+ @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} The ID of this filter. + @param operator {string} One of 'over', 'in', 'out', 'atop', 'xor', 'arithmetic'. + @param in1 {string} The first filter to compose. + @param in2 {string} The second filter to compose. + @param [k1] {number} For 'arithmetic'. + @param [k2] {number} For 'arithmetic'. + @param [k3] {number} For 'arithmetic'. + @param [k4] {number} For 'arithmetic'. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ composite: function(parent, result, operator, in1, in2, k1, k2, k3, k4, settings) { - var args = this._wrapper._args(arguments, ['result', 'operator', - 'in1', 'in2', 'k1', 'k2', 'k3', 'k4'], ['k1']); - var sets = $.extend({result: args.result, operator: args.operator, - 'in': args.in1, in2: args.in2}, + var args = this._wrapper._args(arguments, ['result', 'operator', 'in1', 'in2', 'k1', 'k2', 'k3', 'k4'], ['k1']); + var sets = $.extend({result: args.result, operator: args.operator, 'in': args.in1, in2: args.in2}, (args.k1 != null ? {k1: args.k1, k2: args.k2, k3: args.k3, k4: args.k4} : {})); - return this._wrapper._makeNode(args.parent, 'feComposite', - $.extend(sets, args.settings || {})); + return this._wrapper._makeNode(args.parent, 'feComposite', $.extend(sets, args.settings || {})); }, - /* Add a convolve matrix filter. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param order (int or 'int int') the size(s) of the matrix - @param matrix (number[][]) the kernel matrix for the convolution - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add a convolve matrix filter. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} The ID of this filter + @param order {number|string} The size(s) of the matrix + optionally separated into x- and y-components ('number number'). + @param matrix {number[][]} The kernel matrix for the convolution. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ convolveMatrix: function(parent, result, order, matrix, settings) { var args = this._wrapper._args(arguments, ['result', 'order', 'matrix']); var mx = ''; for (var i = 0; i < args.matrix.length; i++) { - mx += (i == 0 ? '' : ' ') + args.matrix[i].join(' '); + mx += (i === 0 ? '' : ' ') + args.matrix[i].join(' '); } args.matrix = mx; return this._wrapper._makeNode(args.parent, 'feConvolveMatrix', $.extend( - {result: args.result, order: args.order, kernelMatrix: args.matrix}, - args.settings || {})); + {result: args.result, order: args.order, kernelMatrix: args.matrix}, args.settings || {})); }, - /* Add a diffuse lighting filter. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param colour (string) the lighting colour (optional) - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add a diffuse lighting filter. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} The ID of this filter. + @param [colour] {string} The lighting colour. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ diffuseLighting: function(parent, result, colour, settings) { var args = this._wrapper._args(arguments, ['result', 'colour'], ['colour']); - return this._wrapper._makeNode(args.parent, 'feDiffuseLighting', - $.extend($.extend({result: args.result}, + return this._wrapper._makeNode(args.parent, 'feDiffuseLighting', $.extend($.extend({result: args.result}, (args.colour ? {lightingColor: args.colour} : {})), args.settings || {})); }, - /* Add a displacement map filter. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param in1 (string) the source image - @param in2 (string) the displacement image - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add a displacement map filter. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} The ID of this filter. + @param in1 {string} The source image. + @param in2 {string} The displacement image. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ displacementMap: function(parent, result, in1, in2, settings) { var args = this._wrapper._args(arguments, ['result', 'in1', 'in2']); return this._wrapper._makeNode(args.parent, 'feDisplacementMap', - $.extend({result: args.result, in_: args.in1, in2: args.in2}, - args.settings || {})); + $.extend({result: args.result, in_: args.in1, in2: args.in2}, args.settings || {})); }, - /* Add a flood filter. - Specify all of x, y, width, height or none of them. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param x (number) the left coordinate of the rectangle (optional) - @param y (number) the top coordinate of the rectangle (optional) - @param width (number) the width of the rectangle (optional) - @param height (number) the height of the rectangle (optional) - @param colour (string) the colour to fill with - @param opacity (number) the opacity 0.0-1.0 - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add a flood filter. +

Specify all of x, y, width, height or none of them.

+ @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} The ID of this filter. + @param [x] {number} The left coordinate of the rectangle. + @param [y] {number} The top coordinate of the rectangle. + @param [width] {number} The width of the rectangle. + @param [height] {number} The height of the rectangle. + @param colour {string} The colour to fill with. + @param opacity {number} The opacity 0.0-1.0. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ flood: function(parent, result, x, y, width, height, colour, opacity, settings) { - var args = this._wrapper._args(arguments, - ['result', 'x', 'y', 'width', 'height', 'colour', 'opacity']); + var args = this._wrapper._args(arguments, ['result', 'x', 'y', 'width', 'height', 'colour', 'opacity']); if (arguments.length < 6) { args.colour = args.x; args.opacity = args.y; @@ -254,149 +237,132 @@ $.extend(SVGFilter.prototype, { var sets = $.extend({result: args.result, floodColor: args.colour, floodOpacity: args.opacity}, (args.x != null ? {x: args.x, y: args.y, width: args.width, height: args.height} : {})); - return this._wrapper._makeNode(args.parent, 'feFlood', - $.extend(sets, args.settings || {})); + return this._wrapper._makeNode(args.parent, 'feFlood', $.extend(sets, args.settings || {})); }, - /* Add a Gaussian blur filter. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param in1 (string) the source filter - @param stdDevX (number) the standard deviation along the x-axis - @param stdDevY (number) the standard deviation along the y-axis (optional) - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add a Gaussian blur filter. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} The ID of this filter. + @param in1 {string} The source filter. + @param stdDevX {number} The standard deviation along the x-axis. + @param [stdDevY] {number} The standard deviation along the y-axis. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ gaussianBlur: function(parent, result, in1, stdDevX, stdDevY, settings) { - var args = this._wrapper._args(arguments, - ['result', 'in1', 'stdDevX', 'stdDevY'], ['stdDevY']); + var args = this._wrapper._args(arguments, ['result', 'in1', 'stdDevX', 'stdDevY'], ['stdDevY']); return this._wrapper._makeNode(args.parent, 'feGaussianBlur', $.extend( {result: args.result, in_: args.in1, stdDeviation: args.stdDevX + (args.stdDevY ? ' ' + args.stdDevY : '')}, args.settings || {})); }, - /* Add an image filter. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param href (string) the URL of the image - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add an image filter. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} the ID of this filter. + @param href {string} The URL of the image. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ image: function(parent, result, href, settings) { var args = this._wrapper._args(arguments, ['result', 'href']); - var node = this._wrapper._makeNode(args.parent, 'feImage', $.extend( - {result: args.result}, args.settings || {})); + var node = this._wrapper._makeNode(args.parent, 'feImage', $.extend({result: args.result}, args.settings || {})); node.setAttributeNS($.svg.xlinkNS, 'href', args.href); return node; }, - /* Add a merge filter. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param refs (string[]) the IDs of the filters to merge - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add a merge filter. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} The ID of this filter. + @param refs {string[])} The IDs of the filters to merge. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ merge: function(parent, result, refs, settings) { var args = this._wrapper._args(arguments, ['result', 'refs']); - var node = this._wrapper._makeNode(args.parent, 'feMerge', $.extend( - {result: args.result}, args.settings || {})); + var node = this._wrapper._makeNode(args.parent, 'feMerge', $.extend({result: args.result}, args.settings || {})); for (var i = 0; i < args.refs.length; i++) { this._wrapper._makeNode(node, 'feMergeNode', {in_: args.refs[i]}); } return node; }, - /* Add a morphology filter. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param in1 (string) the source filter - @param operator (string) erode | dilate - @param radiusX (number) the size of the operation in the x-axis - @param radiusY (number) the size of the operation in the y-axis (optional) - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add a morphology filter. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} The ID of this filter. + @param in1 {string} The source filter. + @param operator {string} One of 'erode', 'dilate'. + @param radiusX {number} The size of the operation in the x-axis. + @param [radiusY] {number} The size of the operation in the y-axis. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ morphology: function(parent, result, in1, operator, radiusX, radiusY, settings) { - var args = this._wrapper._args(arguments, ['result', 'in1', - 'operator', 'radiusX', 'radiusY'], ['radiusY']); + var args = this._wrapper._args(arguments, ['result', 'in1', 'operator', 'radiusX', 'radiusY'], ['radiusY']); return this._wrapper._makeNode(args.parent, 'feMorphology', $.extend( {result: args.result, in_: args.in1, operator: args.operator, - radius: args.radiusX + (args.radiusY ? ' ' + args.radiusY : '')}, - args.settings || {})); + radius: args.radiusX + (args.radiusY ? ' ' + args.radiusY : '')}, args.settings || {})); }, - /* Add an offset filter. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param in1 (string) the source filter - @param dX (number) the offset in the x-axis - @param dY (number) the offset in the y-axis - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add an offset filter. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} The ID of this filter. + @param in1 {string} The source filter. + @param dX {number} The offset in the x-axis. + @param dY {number} The offset in the y-axis. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ offset: function(parent, result, in1, dx, dy, settings) { var args = this._wrapper._args(arguments, ['result', 'in1', 'dx', 'dy']); return this._wrapper._makeNode(args.parent, 'feOffset', $.extend( - {result: args.result, in_: args.in1, dx: args.dx, dy: args.dy}, - args.settings || {})); + {result: args.result, in_: args.in1, dx: args.dx, dy: args.dy}, args.settings || {})); }, - /* Add a specular lighting filter. - Numeric params are only optional if following numeric params are also omitted. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param in1 (string) the source filter - @param surfaceScale (number) the surface height when Ain = 1 (optional) - @param specularConstant (number) the ks in Phong lighting model (optional) - @param specularExponent (number) the shininess 1.0-128.0 (optional) - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ - specularLighting: function(parent, result, in1, surfaceScale, - specularConstant, specularExponent, settings) { - var args = this._wrapper._args(arguments, ['result', 'in1', - 'surfaceScale', 'specularConstant', 'specularExponent'], + /** Add a specular lighting filter. +

Numeric params are only optional if following numeric params are also omitted.

+ @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string}The ID of this filter. + @param in1 {string} The source filter. + @param [surfaceScale] {number} The surface height when Ain = 1. + @param [specularConstant] {number} The ks in Phong lighting model. + @param [specularExponent] {number} The shininess 1.0-128.0. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ + specularLighting: function(parent, result, in1, surfaceScale, specularConstant, specularExponent, settings) { + var args = this._wrapper._args(arguments, ['result', 'in1', 'surfaceScale', 'specularConstant', 'specularExponent'], ['surfaceScale', 'specularConstant', 'specularExponent']); return this._wrapper._makeNode(args.parent, 'feSpecularLighting', $.extend( {result: args.result, in_: args.in1, surfaceScale: args.surfaceScale, - specularConstant: args.specularConstant, specularExponent: args.specularExponent}, - args.settings || {})); + specularConstant: args.specularConstant, specularExponent: args.specularExponent}, args.settings || {})); }, - /* Add a tile filter. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param in1 (string) the source filter - @param x (number) the left coordinate of the rectangle - @param y (number) the top coordinate of the rectangle - @param width (number) the width of the rectangle - @param height (number) the height of the rectangle - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add a tile filter. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} The ID of this filter. + @param in1 {string} The source filter. + @param x {number} The left coordinate of the rectangle. + @param y {number} The top coordinate of the rectangle. + @param width {number} The width of the rectangle. + @param height {number} The height of the rectangle. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ tile: function(parent, result, in1, x, y, width, height, settings) { - var args = this._wrapper._args(arguments, - ['result', 'in1', 'x', 'y', 'width', 'height']); + var args = this._wrapper._args(arguments, ['result', 'in1', 'x', 'y', 'width', 'height']); return this._wrapper._makeNode(args.parent, 'feTile', $.extend( {result: args.result, in_: args.in1, x: args.x, y: args.y, width: args.width, height: args.height}, args.settings || {})); }, - /* Add a turbulence filter. - @param parent (element or jQuery) the parent node for the new filter (optional) - @param result (string) the ID of this filter - @param type (string) fractalNoise | turbulence - @param baseFreq (number or 'number number') the base frequency, - optionally separated into x- and y-components - @param octaves (number) the amount of turbulence (optional) - @param settings (object) additional settings for the filter (optional) - @return (element) the new filter node */ + /** Add a turbulence filter. + @param [parent] {SVGElement|jQuery} The parent node for the new node, or SVG root if not specified. + @param result {string} The ID of this filter. + @param type {string} One of 'fractalNoise', 'turbulence'. + @param [baseFreq] {number|string} The base frequency, + optionally separated into x- and y-components ('number number'). + @param [octaves] {number} The amount of turbulence. + @param [settings] {object} Additional settings for this node. + @return {SVGElement} The new filter node. */ turbulence: function(parent, result, type, baseFreq, octaves, settings) { - var args = this._wrapper._args(arguments, ['result', 'type', - 'baseFreq', 'octaves'], ['octaves']); + var args = this._wrapper._args(arguments, ['result', 'type', 'baseFreq', 'octaves'], ['octaves']); return this._wrapper._makeNode(args.parent, 'feTurbulence', $.extend( {result: args.result, type: args.type, baseFrequency: args.baseFreq, numOctaves: args.octaves}, args.settings || {})); } }); -/* Determine whether an object is an array. */ -function isArray(a) { - return (a && a.constructor == Array); -} - })(jQuery) diff --git a/jquery.svgfilter.min.js b/jquery.svgfilter.min.js index 65cfae2..d29a0b8 100644 --- a/jquery.svgfilter.min.js +++ b/jquery.svgfilter.min.js @@ -1,7 +1,6 @@ -/* http://keith-wood.name/svg.html - SVG filters for jQuery v1.4.5. +/* http://keith-wood.name/svg.html + SVG filters for jQuery v1.5.0. Written by Keith Wood (kbwood{at}iinet.com.au) August 2007. - Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and - MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. + Available under the MIT (http://keith-wood.name/licence.html) license. Please attribute the author if you use it. */ -(function($){$.svg.addExtension('filters',SVGFilter);$.extend($.svg._wrapperClass.prototype,{filter:function(a,b,x,y,c,d,e){var f=this._args(arguments,['id','x','y','width','height']);return this._makeNode(f.parent,'filter',$.extend({id:f.id,x:f.x,y:f.y,width:f.width,height:f.height},f.settings||{}))}});function SVGFilter(a){this._wrapper=a}$.extend(SVGFilter.prototype,{distantLight:function(a,b,c,d,e){var f=this._wrapper._args(arguments,['result','azimuth','elevation']);return this._wrapper._makeNode(f.parent,'feDistantLight',$.extend({result:f.result,azimuth:f.azimuth,elevation:f.elevation},f.settings||{}))},pointLight:function(a,b,x,y,z,c){var d=this._wrapper._args(arguments,['result','x','y','z']);return this._wrapper._makeNode(d.parent,'fePointLight',$.extend({result:d.result,x:d.x,y:d.y,z:d.z},d.settings||{}))},spotLight:function(a,b,x,y,z,c,d,e,f){var g=this._wrapper._args(arguments,['result','x','y','z','toX','toY','toZ'],['toX']);var h=$.extend({result:g.result,x:g.x,y:g.y,z:g.z},(g.toX!=null?{pointsAtX:g.toX,pointsAtY:g.toY,pointsAtZ:g.toZ}:{}));return this._wrapper._makeNode(g.parent,'feSpotLight',$.extend(h,g.settings||{}))},blend:function(a,b,c,d,e,f){var g=this._wrapper._args(arguments,['result','mode','in1','in2']);return this._wrapper._makeNode(g.parent,'feBlend',$.extend({result:g.result,mode:g.mode,in_:g.in1,in2:g.in2},g.settings||{}))},colorMatrix:function(a,b,c,d,e,f){var g=this._wrapper._args(arguments,['result','in1','type','values']);if(isArray(g.values)){var h='';for(var i=0;i35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(n($){$.V.1n(\'1o\',W);$.m($.V.1p.1e,{1f:n(a,b,x,y,c,d,e){9 f=7.s(q,[\'X\',\'x\',\'y\',\'w\',\'C\']);r 7.o(f.t,\'1f\',$.m({X:f.X,x:f.x,y:f.y,w:f.w,C:f.C},f.p||{}))}});n W(a){7.8=a}$.m(W.1e,{1q:n(a,b,c,d,e){9 f=7.8.s(q,[\'5\',\'Y\',\'Z\']);r 7.8.o(f.t,\'1r\',$.m({5:f.5,Y:f.Y,Z:f.Z},f.p||{}))},1s:n(a,b,x,y,z,c){9 d=7.8.s(q,[\'5\',\'x\',\'y\',\'z\']);r 7.8.o(d.t,\'1t\',$.m({5:d.5,x:d.x,y:d.y,z:d.z},d.p||{}))},1u:n(a,b,x,y,z,c,d,e,f){9 g=7.8.s(q,[\'5\',\'x\',\'y\',\'z\',\'N\',\'1g\',\'1h\'],[\'N\']);9 h=$.m({5:g.5,x:g.x,y:g.y,z:g.z},(g.N!=I?{1v:g.N,1w:g.1g,1x:g.1h}:{}));r 7.8.o(g.t,\'1y\',$.m(h,g.p||{}))},1z:n(a,b,c,d,e,f){9 g=7.8.s(q,[\'5\',\'10\',\'u\',\'D\']);r 7.8.o(g.t,\'1A\',$.m({5:g.5,10:g.10,E:g.u,D:g.D},g.p||{}))},1B:n(a,b,c,d,e,f){9 g=7.8.s(q,[\'5\',\'u\',\'F\',\'v\']);11(1i(g.v)){9 h=\'\';O(9 i=0;iUse the singleton instance of this class, $.svg.graphing, + to interact with the SVG graphing functionality.

+ @module SVGGraphing */ function SVGGraphing() { this.regional = []; this.regional[''] = {percentageText: 'Percentage'}; @@ -21,24 +23,26 @@ function SVGGraphing() { $.extend(SVGGraphing.prototype, { _chartTypes: [], - /* Add a new chart rendering type to the package. - The rendering object must implement the following functions: - getTitle(), getDescription(), getOptions(), drawChart(graph). - @param id (string) the ID of this graph renderer - @param chartType (object) the object implementing this chart type */ + /** Add a new chart rendering type to the package. +

The rendering object must implement the following functions: getTitle(), + getDescription(), getOptions(), drawChart(graph).

+ @param id {string} The ID of this graph renderer. + @param chartType {object} The object implementing this chart type. */ addChartType: function(id, chartType) { this._chartTypes[id] = chartType; }, - /* Retrieve the list of chart types. - @return (object[string]) the array of chart types indexed by ID */ + /** Retrieve the list of chart types. + @return {object[]} The array of chart types indexed by ID */ chartTypes: function() { return this._chartTypes; } }); -/* Extension point for SVG graphing. - Access through svg.graph. */ +/** The SVG graph manager. +

Use the singleton instance of this class, $.svg.graph, + to interact with the SVG graph functionality.

+ @module SVGGraph */ function SVGGraph(wrapper) { this._wrapper = wrapper; // The attached SVG wrapper object this._drawNow = false; // True for immediate update, false to wait for redraw call @@ -49,8 +53,7 @@ function SVGGraph(wrapper) { this._chartOptions = {}; // Extra options for the graph type // The graph title and settings this._title = {value: '', offset: 25, settings: {textAnchor: 'middle'}}; - this._area = [0.1, 0.1, 0.8, 0.9]; // The chart area: left, top, right, bottom, - // > 1 in pixels, <= 1 as proportion + this._area = [0.1, 0.1, 0.8, 0.9]; // The chart area: left, top, right, bottom, > 1 in pixels, <= 1 as proportion this._chartFormat = {fill: 'none', stroke: 'black'}; // The formatting for the chart area this._gridlines = []; // The formatting of the x- and y-gridlines this._series = []; // The series to be plotted, each is an object @@ -70,49 +73,54 @@ function SVGGraph(wrapper) { $.extend(SVGGraph.prototype, { /* Useful indexes. */ + /** Index in a dimensions array for x-coordinate. */ X: 0, + /** Index in a dimensions array for y-coordinate. */ Y: 1, + /** Index in a dimensions array for width. */ W: 2, + /** Index in a dimensions array for height. */ H: 3, + /** Index in an area array for left x-coordinate. */ L: 0, + /** Index in an area array for top y-coordinate. */ T: 1, + /** Index in an area array for right x-coordinate. */ R: 2, + /** Index in an area array for bottom y-coordinate. */ B: 3, /* Standard percentage axis. */ _percentageAxis: new SVGGraphAxis(this, $.svg.graphing.region.percentageText, 0, 100, 10, 0), - /* Set or retrieve the container for the graph. - @param cont (SVG element) the container for the graph - @return (SVGGraph) this graph object or - (SVG element) the current container (if no parameters) */ + /** Set or retrieve the container for the graph. + @param cont {SVGElement} The container for the graph. + @return {SVGGraph|SVGElement} This graph object or the current container (if no parameters). */ container: function(cont) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._chartCont; } this._chartCont = cont; return this; }, - /* Set or retrieve the type of chart to be rendered. - See $.svg.graphing.getChartTypes() for the list of available types. - @param id (string) the ID of the chart type - @param options (object) additional settings for this chart type (optional) - @return (SVGGraph) this graph object or - (string) the chart type (if no parameters) - @deprecated use type() */ + /** Set or retrieve the type of chart to be rendered. +

See $.svg.graphing.getChartTypes() for the list of available types.

+ @param id {string} The ID of the chart type. + @param [options] {object} Additional settings for this chart type. + @return {SVGGraph|string} This graph object or the chart type (if no parameters). + @deprecated Use type(). */ chartType: function(id, options) { - return (arguments.length == 0 ? this.type() : this.type(id, options)); + return (arguments.length === 0 ? this.type() : this.type(id, options)); }, - /* Set or retrieve the type of chart to be rendered. - See $.svg.graphing.getChartTypes() for the list of available types. - @param id (string) the ID of the chart type - @param options (object) additional settings for this chart type (optional) - @return (SVGGraph) this graph object or - (string) the chart type (if no parameters) */ + /** Set or retrieve the type of chart to be rendered. +

See $.svg.graphing.getChartTypes() for the list of available types.

+ @param id {string} The ID of the chart type. + @param [options] {object} Additional settings for this chart type. + @return {SVGGraph|string} This graph object or the chart type (if no parameters). */ type: function(id, options) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._chartType; } var chartType = $.svg.graphing._chartTypes[id]; @@ -124,21 +132,19 @@ $.extend(SVGGraph.prototype, { return this; }, - /* Set or retrieve additional options for the particular chart type. - @param options (object) the extra options - @return (SVGGraph) this graph object or - (object) the chart options (if no parameters) - @deprecated use options() */ + /** Set or retrieve additional options for the particular chart type. + @param options {object} The extra options. + @return {SVGGraph|object} This graph object or the chart options (if no parameters). + @deprecated Use options(). */ chartOptions: function(options) { - return(arguments.length == 0 ? this.options() : this.options(options)); + return(arguments.length === 0 ? this.options() : this.options(options)); }, - /* Set or retrieve additional options for the particular chart type. - @param options (object) the extra options - @return (SVGGraph) this graph object or - (object) the chart options (if no parameters) */ + /** Set or retrieve additional options for the particular chart type. + @param options {object} The extra options. + @return {SVGGraph|object} This graph object or the chart options (if no parameters). */ options: function(options) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._chartOptions; } this._chartOptions = $.extend({}, options); @@ -146,82 +152,72 @@ $.extend(SVGGraph.prototype, { return this; }, - /* Set or retrieve the background of the graph chart. - @param fill (string) how to fill the chart background - @param stroke (string) the colour of the outline (optional) - @param settings (object) additional formatting for the chart background (optional) - @return (SVGGraph) this graph object or - (object) the chart format (if no parameters) - @deprecated use format() */ + /** Set or retrieve the background of the graph chart. + @param fill {string} How to fill the chart background. + @param [stroke] {string} The colour of the outline. + @param [settings] {object} Additional formatting for the chart background. + @return {SVGGraph|object} This graph object or the chart format (if no parameters). + @deprecated Use format(). */ chartFormat: function(fill, stroke, settings) { - return (arguments.length == 0 ? this.format() : this.format(fill, stroke, settings)); + return (arguments.length === 0 ? this.format() : this.format(fill, stroke, settings)); }, - /* Set or retrieve the background of the graph chart. - @param fill (string) how to fill the chart background - @param stroke (string) the colour of the outline (optional) - @param settings (object) additional formatting for the chart background (optional) - @return (SVGGraph) this graph object or - (object) the chart format (if no parameters) */ + /** Set or retrieve the background of the graph chart. + @param fill {string} How to fill the chart background. + @param [stroke] {string} The colour of the outline. + @param [settings] {object} Additional formatting for the chart background. + @return {SVGGraph|object} This graph object or the chart format (if no parameters). */ format: function(fill, stroke, settings) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._chartFormat; } - if (typeof stroke == 'object') { + if (typeof stroke === 'object') { settings = stroke; stroke = null; } - this._chartFormat = $.extend({fill: fill}, - (stroke ? {stroke: stroke} : {}), settings || {}); + this._chartFormat = $.extend({fill: fill}, (stroke ? {stroke: stroke} : {}), settings || {}); this._drawGraph(); return this; }, - /* Set or retrieve the main chart area. - @param left (number) > 1 is pixels, <= 1 is proportion of width or - (number[4]) for left, top, right, bottom - @param top (number) > 1 is pixels, <= 1 is proportion of height - @param right (number) > 1 is pixels, <= 1 is proportion of width - @param bottom (number) > 1 is pixels, <= 1 is proportion of height - @return (SVGGraph) this graph object or - (number[4]) the chart area: left, top, right, bottom (if no parameters) - @deprecated use area() */ + /** Set or retrieve the main chart area. + @param left {number|number[]} > 1 is pixels, <= 1 is proportion of width or array for left, top, right, bottom. + @param [top] {number} > 1 is pixels, <= 1 is proportion of height. + @param [right] {number} > 1 is pixels, <= 1 is proportion of width. + @param [bottom] {number} > 1 is pixels, <= 1 is proportion of height. + @return {SVGGraph|number[]} This graph object or the chart area: left, top, right, bottom (if no parameters). + @deprecated Use area(). */ chartArea: function(left, top, right, bottom) { - return (arguments.length == 0 ? this.area() : this.area(left, top, right, bottom)); + return (arguments.length === 0 ? this.area() : this.area(left, top, right, bottom)); }, - /* Set or retrieve the main chart area. - @param left (number) > 1 is pixels, <= 1 is proportion of width or - (number[4]) for left, top, right, bottom - @param top (number) > 1 is pixels, <= 1 is proportion of height - @param right (number) > 1 is pixels, <= 1 is proportion of width - @param bottom (number) > 1 is pixels, <= 1 is proportion of height - @return (SVGGraph) this graph object or - (number[4]) the chart area: left, top, right, bottom (if no parameters) */ + /** Set or retrieve the main chart area. + @param left {number|number[]} > 1 is pixels, <= 1 is proportion of width or array for left, top, right, bottom. + @param [top] {number} > 1 is pixels, <= 1 is proportion of height. + @param [right] {number} > 1 is pixels, <= 1 is proportion of width. + @param [bottom] {number} > 1 is pixels, <= 1 is proportion of height. + @return {SVGGraph|number[]} This graph object or the chart area: left, top, right, bottom (if no parameters). */ area: function(left, top, right, bottom) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._area; } - this._area = (isArray(left) ? left : [left, top, right, bottom]); + this._area = ($.isArray(left) ? left : [left, top, right, bottom]); this._drawGraph(); return this; }, - /* Set or retrieve the gridlines formatting for the graph chart. - @param xSettings (string) the colour of the gridlines along the x-axis, or - (object) formatting for the gridlines along the x-axis, or - null for none - @param ySettings (string) the colour of the gridlines along the y-axis, or - (object) formatting for the gridlines along the y-axis, or - null for none - @return (SVGGraph) this graph object or - (object[2]) the gridlines formatting (if no parameters) */ + /** Set or retrieve the gridlines formatting for the graph chart. + @param xSettings {string|object} The colour of the gridlines along the x-axis, + or formatting for the gridlines along the x-axis, or null for none. + @param ySettings {string|object} The colour of the gridlines along the y-axis, + or formatting for the gridlines along the y-axis, or null for none. + @return {SVGGraph|object[]} This graph object or the gridlines formatting (if no parameters) */ gridlines: function(xSettings, ySettings) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._gridlines; } - this._gridlines = [(typeof xSettings == 'string' ? {stroke: xSettings} : xSettings), - (typeof ySettings == 'string' ? {stroke: ySettings} : ySettings)]; + this._gridlines = [(typeof xSettings === 'string' ? {stroke: xSettings} : xSettings), + (typeof ySettings === 'string' ? {stroke: ySettings} : ySettings)]; if (this._gridlines[0] == null && this._gridlines[1] == null) { this._gridlines = []; } @@ -229,81 +225,77 @@ $.extend(SVGGraph.prototype, { return this; }, - /* Set or retrieve the title of the graph and its formatting. - @param value (string) the title - @param offset (number) the vertical positioning of the title - > 1 is pixels, <= 1 is proportion of width (optional) - @param colour (string) the colour of the title (optional) - @param settings (object) formatting for the title (optional) - @return (SVGGraph) this graph object or - (object) value, offset, and settings for the title (if no parameters) */ + /** Set or retrieve the title of the graph and its formatting. + @param value {string} The title. + @param [offset] {number} The vertical positioning of the title > 1 is pixels, <= 1 is proportion of width. + @param [colour] {string} The colour of the title. + @param [settings] {object} Formatting for the title. + @return {SVGGraph|object} This graph object or value, offset, and settings for the title (if no parameters). */ title: function(value, offset, colour, settings) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._title; } - if (typeof offset != 'number') { + if (typeof offset !== 'number') { settings = colour; colour = offset; offset = null; } - if (typeof colour != 'string') { + if (typeof colour !== 'string') { settings = colour; colour = null; } this._title = {value: value, offset: offset || this._title.offset, - settings: $.extend({textAnchor: 'middle'}, - (colour ? {fill: colour} : {}), settings || {})}; + settings: $.extend({textAnchor: 'middle'}, (colour ? {fill: colour} : {}), settings || {})}; this._drawGraph(); return this; }, - /* Add a series of values to be plotted on the graph. - @param name (string) the name of this series (optional) - @param values (number[]) the values to be plotted - @param fill (string) how the plotted values are filled - @param stroke (string) the colour of the plotted lines (optional) - @param strokeWidth (number) the width of the plotted lines (optional) - @param settings (object) additional settings for the plotted values (optional) - @return (SVGGraph) this graph object */ + /** Add a series of values to be plotted on the graph. + @param [name] {string} The name of this series. + @param values {number[]} The values to be plotted. + @param fill {string} How the plotted values are filled. + @param [stroke] {string} The colour of the plotted lines. + @param [strokeWidth] {number} The width of the plotted lines. + @param [settings] {object} Additional settings for the plotted values. + @return {SVGGraph} This graph object. */ addSeries: function(name, values, fill, stroke, strokeWidth, settings) { - this._series.push(new SVGGraphSeries( - this, name, values, fill, stroke, strokeWidth, settings)); + this._series.push(new SVGGraphSeries(this, name, values, fill, stroke, strokeWidth, settings)); this._drawGraph(); return this; }, - /* Retrieve the series wrappers. - @param i (number) the series index (optional) - @return (SVGGraphSeries) the specified series or - (SVGGraphSeries[]) the list of series */ + /** Retrieve the series wrappers. + @param [i] {number} The series index. + @return {SVGGraphSeries|SVGGraphSeries[]} The specified series or the list of series. */ series: function(i) { return (arguments.length > 0 ? this._series[i] : null) || this._series; }, - /* Suppress drawing of the graph until redraw() is called. - @return (SVGGraph) this graph object */ + /** Suppress drawing of the graph until redraw() is called. + @return {SVGGraph} This graph object. */ noDraw: function() { this._drawNow = false; return this; }, - /* Redraw the entire graph with the current settings and values. - @return (SVGGraph) this graph object */ + /** Redraw the entire graph with the current settings and values. + @return {SVGGraph} This graph object. */ redraw: function() { this._drawNow = true; this._drawGraph(); return this; }, - /* Set the callback function for status updates. - @param onstatus (function) the callback function - @return (SVGGraph) this graph object */ + /** Set the callback function for status updates. + @param onstatus {function} The callback function. + @return {SVGGraph} This graph object. */ status: function(onstatus) { this._onstatus = onstatus; return this; }, - /* Actually draw the graph (if allowed) based on the graph type set. */ + /** Actually draw the graph (if allowed) based on the graph type set. + @private */ _drawGraph: function() { if (!this._drawNow) { return; @@ -317,47 +309,48 @@ $.extend(SVGGraph.prototype, { // Set sizes if not already there if (!this._chartCont.width) { this._chartCont.setAttribute('width', - parseInt(this._chartCont.getAttribute('width'), 10) || this._wrapper._width()); + parseInt(this._chartCont.getAttribute('width'), 10) || this._wrapper.width()); } else if (this._chartCont.width.baseVal) { - this._chartCont.width.baseVal.value = - this._chartCont.width.baseVal.value || this._wrapper._width(); + this._chartCont.width.baseVal.value = this._chartCont.width.baseVal.value || this._wrapper.width(); } else { - this._chartCont.width = this._chartCont.width || this._wrapper._width(); + this._chartCont.width = this._chartCont.width || this._wrapper.width(); } if (!this._chartCont.height) { this._chartCont.setAttribute('height', - parseInt(this._chartCont.getAttribute('height'), 10) || this._wrapper._height()); + parseInt(this._chartCont.getAttribute('height'), 10) || this._wrapper.height()); } else if (this._chartCont.height.baseVal) { - this._chartCont.height.baseVal.value = - this._chartCont.height.baseVal.value || this._wrapper._height(); + this._chartCont.height.baseVal.value = this._chartCont.height.baseVal.value || this._wrapper.height(); } else { - this._chartCont.height = this._chartCont.height || this._wrapper._height(); + this._chartCont.height = this._chartCont.height || this._wrapper.height(); } this._chartType.drawGraph(this); }, - /* Decode an attribute value. - @param node the node to examine - @param name the attribute name - @return the actual value */ + /** Decode an attribute value. + @private + @param node {SVGElement} The node to examine. + @param name {string} The attribute name. + @return {string} The actual value. */ _getValue: function(node, name) { return (!node[name] ? parseInt(node.getAttribute(name), 10) : (node[name].baseVal ? node[name].baseVal.value : node[name])); }, - /* Draw the graph title - centred. */ + /** Draw the graph title - centred. + @private */ _drawTitle: function() { this._wrapper.text(this._chartCont, this._getValue(this._chartCont, 'width') / 2, this._title.offset, this._title.value, this._title.settings); }, - /* Calculate the actual dimensions of the chart area. - @param area (number[4]) the area values to evaluate (optional) - @return (number[4]) an array of dimension values: left, top, width, height */ + /** Calculate the actual dimensions of the chart area. + @private + @param [area] {number[]} The area values to evaluate, defaulting to the current ones. + @return {number[]} An array of dimension values: left, top, width, height. */ _getDims: function(area) { area = area || this._area; var availWidth = this._getValue(this._chartCont, 'width'); @@ -369,10 +362,11 @@ $.extend(SVGGraph.prototype, { return [left, top, width, height]; }, - /* Draw the chart background, including gridlines. - @param noXGrid (boolean) true to suppress the x-gridlines, false to draw them (optional) - @param noYGrid (boolean) true to suppress the y-gridlines, false to draw them (optional) - @return (element) the background group element */ + /** Draw the chart background, including gridlines. + @private + @param [noXGrid=false] {boolean} true to suppress the x-gridlines, false to draw them. + @param [noYGrid=false] {boolean} true to suppress the y-gridlines, false to draw them. + @return {SVGEelement} The background group element */ _drawChartBackground: function(noXGrid, noYGrid) { var bg = this._wrapper.group(this._chartCont, {class_: 'background'}); var dims = this._getDims(); @@ -386,12 +380,13 @@ $.extend(SVGGraph.prototype, { return bg; }, - /* Draw one set of gridlines. - @param bg (element) the background group element - @param axis (SVGGraphAxis) the axis definition - @param horiz (boolean) true if horizontal, false if vertical - @param dims (number[]) the left, top, width, height of the chart area - @param format (object) additional settings for the gridlines */ + /** Draw one set of gridlines. + @private + @param bg {SVGElement} The background group element. + @param axis {SVGGraphAxis} The axis definition. + @param horiz {boolean} true if horizontal, false if vertical. + @param dims {number[]} The left, top, width, height of the chart area. + @param format {object} Additional settings for the gridlines. */ _drawGridlines: function(bg, axis, horiz, dims, format) { var g = this._wrapper.group(bg, format); var scale = (horiz ? dims[this.H] : dims[this.W]) / (axis._scale.max - axis._scale.min); @@ -406,15 +401,15 @@ $.extend(SVGGraph.prototype, { } }, - /* Draw the axes in their standard configuration. - @param noX (boolean) true to suppress the x-axes, false to draw it (optional) */ + /** Draw the axes in their standard configuration. + @private + @param [noX=false] {boolean} true to suppress the x-axes, false to draw it. */ _drawAxes: function(noX) { var dims = this._getDims(); if (this.xAxis && !noX) { if (this.xAxis._title) { this._wrapper.text(this._chartCont, dims[this.X] + dims[this.W] / 2, - dims[this.Y] + dims[this.H] + this.xAxis._titleOffset, - this.xAxis._title, this.xAxis._titleFormat); + dims[this.Y] + dims[this.H] + this.xAxis._titleOffset, this.xAxis._title, this.xAxis._titleFormat); } this._drawAxis(this.xAxis, 'xAxis', dims[this.X], dims[this.Y] + dims[this.H], dims[this.X] + dims[this.W], dims[this.Y] + dims[this.H]); @@ -425,37 +420,36 @@ $.extend(SVGGraph.prototype, { transform: 'translate(' + (dims[this.X] - this.yAxis._titleOffset) + ',' + (dims[this.Y] + dims[this.H] / 2) + ') rotate(-90)'}, this.yAxis._titleFormat || {})); } - this._drawAxis(this.yAxis, 'yAxis', dims[this.X], dims[this.Y], - dims[this.X], dims[this.Y] + dims[this.H]); + this._drawAxis(this.yAxis, 'yAxis', dims[this.X], dims[this.Y], dims[this.X], dims[this.Y] + dims[this.H]); } if (this.x2Axis && !noX) { if (this.x2Axis._title) { this._wrapper.text(this._chartCont, dims[this.X] + dims[this.W] / 2, dims[this.X] - this.x2Axis._titleOffset, this.x2Axis._title, this.x2Axis._titleFormat); } - this._drawAxis(this.x2Axis, 'x2Axis', dims[this.X], dims[this.Y], - dims[this.X] + dims[this.W], dims[this.Y]); + this._drawAxis(this.x2Axis, 'x2Axis', dims[this.X], dims[this.Y], dims[this.X] + dims[this.W], dims[this.Y]); } if (this.y2Axis) { if (this.y2Axis._title) { this._wrapper.text(this._chartCont, 0, 0, this.y2Axis._title, $.extend({textAnchor: 'middle', - transform: 'translate(' + (dims[this.X] + dims[this.W] + this.y2Axis._titleOffset) + - ',' + (dims[this.Y] + dims[this.H] / 2) + ') rotate(-90)'}, this.y2Axis._titleFormat || {})); + transform: 'translate(' + (dims[this.X] + dims[this.W] + this.y2Axis._titleOffset) + ',' + + (dims[this.Y] + dims[this.H] / 2) + ') rotate(-90)'}, this.y2Axis._titleFormat || {})); } this._drawAxis(this.y2Axis, 'y2Axis', dims[this.X] + dims[this.W], dims[this.Y], dims[this.X] + dims[this.W], dims[this.Y] + dims[this.H]); } }, - /* Draw an axis and its tick marks. - @param axis (SVGGraphAxis) the axis definition - @param id (string) the identifier for the axis group element - @param x1 (number) starting x-coodinate for the axis - @param y1 (number) starting y-coodinate for the axis - @param x2 (number) ending x-coodinate for the axis - @param y2 (number) ending y-coodinate for the axis */ + /** Draw an axis and its tick marks. + @private + @param axis {SVGGraphAxis} The axis definition. + @param id {string} The identifier for the axis group element. + @param x1 {number} Starting x-coodinate for the axis. + @param y1 {number} Starting y-coodinate for the axis. + @param x2 {number} Ending x-coodinate for the axis. + @param y2 {number} Ending y-coodinate for the axis. */ _drawAxis: function(axis, id, x1, y1, x2, y2) { - var horiz = (y1 == y2); + var horiz = (y1 === y2); var gl = this._wrapper.group(this._chartCont, $.extend({class_: id}, axis._lineFormat)); var gt = this._wrapper.group(this._chartCont, $.extend({class_: id + 'Labels', textAnchor: (horiz ? 'middle' : 'end')}, axis._labelFormat)); @@ -474,43 +468,42 @@ $.extend(SVGGraph.prototype, { var count = 0; while (major <= axis._scale.max || minor <= axis._scale.max) { var cur = Math.min(major, minor); - var len = (cur == major ? size : size / 2); - var v = (horiz ? x1 : y1) + - (horiz ? cur - axis._scale.min : axis._scale.max - cur) * scale; - this._wrapper.line(gl, (horiz ? v : x1 + len * offsets[0]), - (horiz ? y1 + len * offsets[0] : v), - (horiz ? v : x1 + len * offsets[1]), - (horiz ? y1 + len * offsets[1] : v)); - if (cur == major) { + var len = (cur === major ? size : size / 2); + var v = (horiz ? x1 : y1) + (horiz ? cur - axis._scale.min : axis._scale.max - cur) * scale; + this._wrapper.line(gl, (horiz ? v : x1 + len * offsets[0]), (horiz ? y1 + len * offsets[0] : v), + (horiz ? v : x1 + len * offsets[1]), (horiz ? y1 + len * offsets[1] : v)); + if (cur === major) { this._wrapper.text(gt, (horiz ? v : x1 - size), (horiz ? y1 + 2 * size : v), (axis._labels ? axis._labels[count++] : '' + cur)); } - major += (cur == major ? axis._ticks.major : 0); - minor += (cur == minor ? axis._ticks.minor : 0); + major += (cur === major ? axis._ticks.major : 0); + minor += (cur === minor ? axis._ticks.minor : 0); } } }, - /* Calculate offsets based on axis and tick positions. - @param axis (SVGGraphAxis) the axis definition - @param bottomRight (boolean) true if this axis is appearing on the bottom or - right of the chart area, false if to the top or left - @return (number[2]) the array of offset multipliers (-1..+1) */ + /** Calculate offsets based on axis and tick positions. + @private + @param axis {SVGGraphAxis} The axis definition. + @param bottomRight {boolean} true if this axis is appearing on the bottom or + right of the chart area, false if to the top or left. + @return {number[]} The array of offset multipliers (-1..+1). */ _getTickOffsets: function(axis, bottomRight) { - return [(axis._ticks.position == (bottomRight ? 'in' : 'out') || - axis._ticks.position == 'both' ? -1 : 0), - (axis._ticks.position == (bottomRight ? 'out' : 'in') || - axis._ticks.position == 'both' ? +1 : 0), ]; + return [(axis._ticks.position === (bottomRight ? 'in' : 'out') || axis._ticks.position === 'both' ? -1 : 0), + (axis._ticks.position === (bottomRight ? 'out' : 'in') || axis._ticks.position === 'both' ? +1 : 0), ]; }, - /* Retrieve the standard percentage axis. - @return (SVGGraphAxis) percentage axis */ + /** Retrieve the standard percentage axis. + @private + @return {SVGGraphAxis} Percentage axis. */ _getPercentageAxis: function() { this._percentageAxis._title = $.svg.graphing.region.percentageText; return this._percentageAxis; }, - /* Calculate the column totals across all the series. */ + /** Calculate the column totals across all the series. + @private + @return {number[]} The column totals. */ _getTotals: function() { var totals = []; var numVal = (this._series.length ? this._series[0]._values.length : 0); @@ -523,15 +516,15 @@ $.extend(SVGGraph.prototype, { return totals; }, - /* Draw the chart legend. */ + /** Draw the chart legend. + @private */ _drawLegend: function() { if (!this.legend._show) { return; } var g = this._wrapper.group(this._chartCont, {class_: 'legend'}); var dims = this._getDims(this.legend._area); - this._wrapper.rect(g, dims[this.X], dims[this.Y], dims[this.W], dims[this.H], - this.legend._bgSettings); + this._wrapper.rect(g, dims[this.X], dims[this.Y], dims[this.W], dims[this.H], this.legend._bgSettings); var horiz = dims[this.W] > dims[this.H]; var numSer = this._series.length; var offset = (horiz ? dims[this.W] : dims[this.H]) / numSer; @@ -548,7 +541,11 @@ $.extend(SVGGraph.prototype, { } }, - /* Show the current value status on hover. */ + /** Show the current value status on hover. + @private + @param elem {string|SVGElement} The selector or SVG element to show the status in. + @param label {string} The current label. + @param value {number} The current value. */ _showStatus: function(elem, label, value) { var status = this._onstatus; if (this._onstatus) { @@ -558,17 +555,21 @@ $.extend(SVGGraph.prototype, { } }); -/* Details about each graph series. - @param graph (SVGGraph) the owning graph - @param name (string) the name of this series (optional) - @param values (number[]) the list of values to be plotted - @param fill (string) how the series should be displayed - @param stroke (string) the colour of the (out)line for the series (optional) - @param strokeWidth (number) the width of the (out)line for the series (optional) - @param settings (object) additional formatting settings (optional) - @return (SVGGraphSeries) the new series object */ +/** A graph series definition. + @module SVGGraphSeries */ + +/** Details about each graph series. +

Created through graph.addSeries().

+ @param graph {SVGGraph} The owning graph. + @param [name] {string} The name of this series. + @param values {number[]} The values to be plotted. + @param fill {string} How the plotted values are filled. + @param [stroke] {string} The colour of the plotted lines. + @param [strokeWidth] {number} The width of the plotted lines. + @param [settings] {object} Additional settings for the plotted values. + @return {SVGGraphSeries} The new series object. */ function SVGGraphSeries(graph, name, values, fill, stroke, strokeWidth, settings) { - if (typeof name != 'string') { + if (typeof name !== 'string') { settings = strokeWidth; strokeWidth = stroke; stroke = fill; @@ -576,12 +577,12 @@ function SVGGraphSeries(graph, name, values, fill, stroke, strokeWidth, settings values = name; name = null; } - if (typeof stroke != 'string') { + if (typeof stroke !== 'string') { settings = strokeWidth; strokeWidth = stroke; stroke = null; } - if (typeof strokeWidth != 'number') { + if (typeof strokeWidth !== 'number') { settings = strokeWidth; strokeWidth = null; } @@ -597,12 +598,11 @@ function SVGGraphSeries(graph, name, values, fill, stroke, strokeWidth, settings $.extend(SVGGraphSeries.prototype, { - /* Set or retrieve the name for this series. - @param name (string) the series' name - @return (SVGGraphSeries) this series object or - (string) the series name (if no parameters) */ + /** Set or retrieve the name for this series. + @param name {string} The series' name. + @return {SVGGraphSeries|string} This series object or the series name (if no parameters). */ name: function(name) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._name; } this._name = name; @@ -610,16 +610,15 @@ $.extend(SVGGraphSeries.prototype, { return this; }, - /* Set or retrieve the values for this series. - @param name (string) the series' name (optional) - @param values (number[]) the values to be graphed - @return (SVGGraphSeries) this series object or - (number[]) the series values (if no parameters) */ + /** Set or retrieve the values for this series. + @param [name] {string} The series' name. + @param values {number[]} The values to be graphed. + @return {SVGGraphSeries|number[]} This series object or the series values (if no parameters). */ values: function(name, values) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._values; } - if (isArray(name)) { + if ($.isArray(name)) { values = name; name = null; } @@ -629,24 +628,22 @@ $.extend(SVGGraphSeries.prototype, { return this; }, - /* Set or retrieve the formatting for this series. - @param fill (string) how the values are filled when plotted - @param stroke (string) the (out)line colour (optional) - @param strokeWidth (number) the line's width (optional) - @param settings (object) additional formatting settings for the series (optional) - @return (SVGGraphSeries) this series object or - (object) formatting settings (if no parameters) */ + /** Set or retrieve the formatting for this series. + @param fill {string} How the values are filled when plotted. + @param [stroke] {string} The (out)line colour. + @param [strokeWidth] {number} The line's width. + @param [settings] {object} Additional formatting settings for the series. + @return {SVGGraphSeries|object} This series object or formatting settings (if no parameters). */ format: function(fill, stroke, strokeWidth, settings) { - if (arguments.length == 0) { - return $.extend({fill: this._fill, stroke: this._stroke, - strokeWidth: this._strokeWidth}, this._settings); + if (arguments.length === 0) { + return $.extend({fill: this._fill, stroke: this._stroke, strokeWidth: this._strokeWidth}, this._settings); } - if (typeof stroke != 'string') { + if (typeof stroke !== 'string') { settings = strokeWidth; strokeWidth = stroke; stroke = null; } - if (typeof strokeWidth != 'number') { + if (typeof strokeWidth !== 'number') { settings = strokeWidth; strokeWidth = null; } @@ -658,20 +655,24 @@ $.extend(SVGGraphSeries.prototype, { return this; }, - /* Return to the parent graph. */ + /** Return to the parent graph. + @return {SVGGraph} The parent graph. */ end: function() { return this._graph; } }); -/* Details about each graph axis. - @param graph (SVGGraph) the owning graph - @param title (string) the title of the axis - @param min (number) the minimum value displayed on this axis - @param max (number) the maximum value displayed on this axis - @param major (number) the distance between major ticks - @param minor (number) the distance between minor ticks (optional) - @return (SVGGraphAxis) the new axis object */ +/** A graph axis definition. + @module SVGGraphAxis */ + +/** Details about each graph axis. + @param graph {SVGGraph} The owning graph. + @param title {string} The title of the axis. + @param min [number} The minimum value displayed on this axis. + @param max {number} The maximum value displayed on this axis. + @param major {number} The distance between major ticks. + @param [minor] {number} The distance between minor ticks. + @return {SVGGraphAxis} The new axis object. */ function SVGGraphAxis(graph, title, min, max, major, minor) { this._graph = graph; // The owning graph this._title = title || ''; // Title of this axis @@ -687,13 +688,12 @@ function SVGGraphAxis(graph, title, min, max, major, minor) { $.extend(SVGGraphAxis.prototype, { - /* Set or retrieve the scale for this axis. - @param min (number) the minimum value shown - @param max (number) the maximum value shown - @return (SVGGraphAxis) this axis object or - (object) min and max values (if no parameters) */ + /** Set or retrieve the scale for this axis. + @param min {number} The minimum value shown. + @param max {number} The maximum value shown. + @return {SVGGraphAxis|object} This axis object or min and max values (if no parameters). */ scale: function(min, max) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._scale; } this._scale.min = min; @@ -702,19 +702,17 @@ $.extend(SVGGraphAxis.prototype, { return this; }, - /* Set or retrieve the ticks for this axis. - @param major (number) the distance between major ticks - @param minor (number) the distance between minor ticks - @param size (number) the length of the major ticks (minor are half) (optional) - @param position (string) the location of the ticks: - 'in', 'out', 'both' (optional) - @return (SVGGraphAxis) this axis object or - (object) major, minor, size, and position values (if no parameters) */ + /** Set or retrieve the ticks for this axis. + @param major {number} The distance between major ticks. + @param minor {number} The distance between minor ticks. + @param [size] {number} The length of the major ticks (minor are half). + @param [position] {string} The location of the ticks: 'in', 'out', 'both'. + @return {SVGGraphAxis|object} This axis object or major, minor, size, and position values (if no parameters). */ ticks: function(major, minor, size, position) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._ticks; } - if (typeof size == 'string') { + if (typeof size === 'string') { position = size; size = null; } @@ -726,23 +724,22 @@ $.extend(SVGGraphAxis.prototype, { return this; }, - /* Set or retrieve the title for this axis. - @param title (string) the title text - @param offset (number) the distance to offset the title position (optional) - @param colour (string) how to colour the title (optional) - @param format (object) formatting settings for the title (optional) - @return (SVGGraphAxis) this axis object or - (object) title, offset, and format values (if no parameters) */ + /** Set or retrieve the title for this axis. + @param title {string} The title text + @param [offset] {number} The distance to offset the title position. + @param [colour] {string} How to colour the title. + @param [format] {object} Formatting settings for the title. + @return {SVGGraphAxis|object} This axis object or title, offset, and format values (if no parameters). */ title: function(title, offset, colour, format) { - if (arguments.length == 0) { + if (arguments.length === 0) { return {title: this._title, offset: this._titleOffset, format: this._titleFormat}; } - if (typeof offset != 'number') { + if (typeof offset !== 'number') { format = colour; colour = offset; offset = null; } - if (typeof colour != 'string') { + if (typeof colour !== 'string') { format = colour; colour = null; } @@ -755,17 +752,16 @@ $.extend(SVGGraphAxis.prototype, { return this; }, - /* Set or retrieve the labels for this axis. - @param labels (string[]) the text for each entry - @param colour (string) how to colour the labels (optional) - @param format (object) formatting settings for the labels (optional) - @return (SVGGraphAxis) this axis object or - (object) labels and format values (if no parameters) */ + /** Set or retrieve the labels for this axis. + @param labels {string[]} The text for each entry. + @param [colour] {string} How to colour the labels. + @param [format] {object} Formatting settings for the labels. + @return {SVGGraphAxis|object} This axis object or labels and format values (if no parameters). */ labels: function(labels, colour, format) { - if (arguments.length == 0) { + if (arguments.length === 0) { return {labels: this._labels, format: this._labelFormat}; } - if (typeof colour != 'string') { + if (typeof colour !== 'string') { format = colour; colour = null; } @@ -777,42 +773,43 @@ $.extend(SVGGraphAxis.prototype, { return this; }, - /* Set or retrieve the line formatting for this axis. - @param colour (string) the line's colour - @param width (number) the line's width (optional) - @param settings (object) additional formatting settings for the line (optional) - @return (SVGGraphAxis) this axis object or - (object) line formatting values (if no parameters) */ + /** Set or retrieve the line formatting for this axis. + @param colour {string} The line's colour + @param [width] {number} The line's width. + @param [settings] {object} Additional formatting settings for the line. + @return {SVGGraphAxis|object} This axis object or line formatting values (if no parameters). */ line: function(colour, width, settings) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._lineFormat; } - if (typeof width == 'object') { + if (typeof width === 'object') { settings = width; width = null; } - $.extend(this._lineFormat, {stroke: colour}, - (width ? {strokeWidth: width} : {}), settings || {}); + $.extend(this._lineFormat, {stroke: colour}, (width ? {strokeWidth: width} : {}), settings || {}); this._graph._drawGraph(); return this; }, - /* Return to the parent graph. */ + /** Return to the parent graph. + @return {SVGGraph} The parent graph. */ end: function() { return this._graph; } }); -/* Details about the graph legend. - @param graph (SVGGraph) the owning graph - @param bgSettings (object) additional formatting settings for the legend background (optional) - @param textSettings (object) additional formatting settings for the legend text (optional) - @return (SVGGraphLegend) the new legend object */ +/** A graph legend definition. + @module SVGGraphLegend */ + +/** Details about each graph legend. + @param graph {SVGGraph} The owning graph. + @param [bgSettings] {object} Additional formatting settings for the legend background. + @param [textSettings] {object} Additional formatting settings for the legend text. + @return {SVGGraphLegend} The new legend object. */ function SVGGraphLegend(graph, bgSettings, textSettings) { this._graph = graph; // The owning graph this._show = true; // Show the legend? - this._area = [0.9, 0.1, 1.0, 0.9]; // The legend area: left, top, right, bottom, - // > 1 in pixels, <= 1 as proportion + this._area = [0.9, 0.1, 1.0, 0.9]; // The legend area: left, top, right, bottom, > 1 in pixels, <= 1 as proportion this._sampleSize = 15; // Size of sample box this._bgSettings = bgSettings || {stroke: 'gray'}; // Additional formatting settings for the legend background this._textSettings = textSettings || {}; // Additional formatting settings for the text @@ -820,12 +817,11 @@ function SVGGraphLegend(graph, bgSettings, textSettings) { $.extend(SVGGraphLegend.prototype, { - /* Set or retrieve whether the legend should be shown. - @param show (boolean) true to display it, false to hide it - @return (SVGGraphLegend) this legend object or - (boolean) show the legend? (if no parameters) */ + /** Set or retrieve whether the legend should be shown. + @param show {boolean} true to display it, false to hide it. + @return {SVGGraphLegend|boolean} This legend object or show the legend? (if no parameters) */ show: function(show) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._show; } this._show = show; @@ -833,35 +829,33 @@ $.extend(SVGGraphLegend.prototype, { return this; }, - /* Set or retrieve the legend area. - @param left (number) > 1 is pixels, <= 1 is proportion of width or - (number[4]) for left, top, right, bottom - @param top (number) > 1 is pixels, <= 1 is proportion of height - @param right (number) > 1 is pixels, <= 1 is proportion of width - @param bottom (number) > 1 is pixels, <= 1 is proportion of height - @return (SVGGraphLegend) this legend object or - (number[4]) the legend area: left, top, right, bottom (if no parameters) */ + /** Set or retrieve the legend area. + @param left {number|number[]} > 1 is pixels, <= 1 is proportion of width or array for left, top, right, bottom. + @param [top] {number) > 1 is pixels, <= 1 is proportion of height. + @param [right] {number) > 1 is pixels, <= 1 is proportion of width. + @param [bottom] {number) > 1 is pixels, <= 1 is proportion of height. + @return {SVGGraphLegend|number[]} This legend object or the legend area: + left, top, right, bottom (if no parameters). */ area: function(left, top, right, bottom) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._area; } - this._area = (isArray(left) ? left : [left, top, right, bottom]); + this._area = ($.isArray(left) ? left : [left, top, right, bottom]); this._graph._drawGraph(); return this; }, - /* Set or retrieve additional settings for the legend area. - @param sampleSize (number) the size of the sample box to display (optional) - @param bgSettings (object) additional formatting settings for the legend background - @param textSettings (object) additional formatting settings for the legend text (optional) - @return (SVGGraphLegend) this legend object or - (object) bgSettings and textSettings for the legend (if no parameters) */ + /** Set or retrieve additional settings for the legend area. + @param [sampleSize] {number} The size of the sample box to display. + @param bgSettings {object} Additional formatting settings for the legend background. + @param [textSettings] {object} Additional formatting settings for the legend text. + @return {SVGGraphLegend|object} This legend object or + bgSettings and textSettings for the legend (if no parameters). */ settings: function(sampleSize, bgSettings, textSettings) { - if (arguments.length == 0) { - return {sampleSize: this._sampleSize, bgSettings: this._bgSettings, - textSettings: this._textSettings}; + if (arguments.length === 0) { + return {sampleSize: this._sampleSize, bgSettings: this._bgSettings, textSettings: this._textSettings}; } - if (typeof sampleSize != 'number') { + if (typeof sampleSize !== 'number') { textSettings = bgSettings; bgSettings = sampleSize; sampleSize = null; @@ -873,7 +867,8 @@ $.extend(SVGGraphLegend.prototype, { return this; }, - /* Return to the parent graph. */ + /** Return to the parent graph. + @return {SVGGraph} The parent graph. */ end: function() { return this._graph; } @@ -881,42 +876,46 @@ $.extend(SVGGraphLegend.prototype, { //============================================================================== -/* Round a number to a given number of decimal points. */ +/** Round a number to a given number of decimal points. + @private + @param num {number} The original value. + @param dec {number} The number of decimal points to retain. + @return {number} The rounded number. */ function roundNumber(num, dec) { return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec); } -var barOptions = ['barWidth (number) - the width of each bar', - 'barGap (number) - the gap between sets of bars']; +var barOptions = ['barWidth (number) - the width of each bar', 'barGap (number) - the gap between sets of bars']; //------------------------------------------------------------------------------ -/* Draw a standard grouped column bar chart. */ +/** Draw a standard grouped column bar chart. + @module SVGColumnChart */ function SVGColumnChart() { } $.extend(SVGColumnChart.prototype, { - /* Retrieve the display title for this chart type. - @return the title */ + /** Retrieve the display title for this chart type. + @return {string} Its title. */ title: function() { return 'Basic column chart'; }, - /* Retrieve a description of this chart type. - @return its description */ + /** Retrieve a description of this chart type. + @return {string} Its description. */ description: function() { return 'Compare sets of values as vertical bars with grouped categories.'; }, - /* Retrieve a list of the options that may be set for this chart type. - @return options list */ + /** Retrieve a list of the options that may be set for this chart type. + @return {string[]} Its options list. */ options: function() { return barOptions; }, - /* Actually draw the graph in this type's style. - @param graph (object) the SVGGraph object */ + /** Actually draw the graph in this type's style. + @param graph {SVGGraph} The graph object. */ drawGraph: function(graph) { graph._drawChartBackground(true); var barWidth = graph._chartOptions.barWidth || 10; @@ -936,7 +935,16 @@ $.extend(SVGColumnChart.prototype, { graph._drawLegend(); }, - /* Plot an individual series. */ + /** Plot an individual series. + @private + @param graph {SVGGraph} The graph object. + @param cur {number} The current series index. + @param numSer {number} The number of points in this series. + @param barWidth {number} The width of each bar. + @param barGap {number} The space between bars. + @param dims {number[]} The dimensions of the drawing area. + @param xScale {number} The scaling factor in the horizontal direction. + @param yScale {number} The scaling factor in the vertical direction. */ _drawSeries: function(graph, cur, numSer, barWidth, barGap, dims, xScale, yScale) { var series = graph._series[cur]; var g = graph._wrapper.group(this._chart, @@ -951,7 +959,15 @@ $.extend(SVGColumnChart.prototype, { } }, - /* Draw the x-axis and its ticks. */ + /** Draw the x-axis and its ticks. + @private + @param graph {SVGGraph} The graph object. + @param numSer {number} The number of points in this series. + @param numVal {number} The current value index. + @param barWidth {number} The width of each bar. + @param barGap {number} The space between bars. + @param dims {number[]} The dimensions of the drawing area. + @param xScale {number} The scaling factor in the horizontal direction. */ _drawXAxis: function(graph, numSer, numVal, barWidth, barGap, dims, xScale) { var axis = graph.xAxis; if (axis._title) { @@ -982,33 +998,34 @@ $.extend(SVGColumnChart.prototype, { //------------------------------------------------------------------------------ -/* Draw a stacked column bar chart. */ +/** Draw a stacked column bar chart. + @module SVGStackedColumnChart */ function SVGStackedColumnChart() { } $.extend(SVGStackedColumnChart.prototype, { - /* Retrieve the display title for this chart type. - @return the title */ + /** Retrieve the display title for this chart type. + @return {string} Its title. */ title: function() { return 'Stacked column chart'; }, - /* Retrieve a description of this chart type. - @return its description */ + /** Retrieve a description of this chart type. + @return {string} Its description. */ description: function() { return 'Compare sets of values as vertical bars showing ' + 'relative contributions to the whole for each category.'; }, - /* Retrieve a list of the options that may be set for this chart type. - @return options list */ + /** Retrieve a list of the options that may be set for this chart type. + @return {string[]} Its options list. */ options: function() { return barOptions; }, - /* Actually draw the graph in this type's style. - @param graph (object) the SVGGraph object */ + /** Actually draw the graph in this type's style. + @param graph {SVGGraph} The graph object. */ drawGraph: function(graph) { var bg = graph._drawChartBackground(true, true); var dims = graph._getDims(); @@ -1030,13 +1047,21 @@ $.extend(SVGStackedColumnChart.prototype, { (dims[graph.Y] + dims[graph.H] / 2) + ') rotate(-90)'}, graph.yAxis._titleFormat || {})); var pAxis = $.extend({}, graph._getPercentageAxis()); $.extend(pAxis._labelFormat, graph.yAxis._labelFormat || {}); - graph._drawAxis(pAxis, 'yAxis', dims[graph.X], dims[graph.Y], - dims[graph.X], dims[graph.Y] + dims[graph.H]); + graph._drawAxis(pAxis, 'yAxis', dims[graph.X], dims[graph.Y], dims[graph.X], dims[graph.Y] + dims[graph.H]); this._drawXAxis(graph, numVal, barWidth, barGap, dims, xScale); graph._drawLegend(); }, - /* Plot all of the columns. */ + /** Plot all of the columns. + @private + @param graph {SVGGraph} The graph object. + @param numSer {number} The number of points in this series. + @param numVal {number} The current value index. + @param barWidth {number} The width of each bar. + @param barGap {number} The space between bars. + @param dims {number[]} The dimensions of the drawing area. + @param xScale {number} The scaling factor in the horizontal direction. + @param yScale {number} The scaling factor in the vertical direction. */ _drawColumns: function(graph, numSer, numVal, barWidth, barGap, dims, xScale, yScale) { var totals = graph._getTotals(); var accum = []; @@ -1045,23 +1070,26 @@ $.extend(SVGStackedColumnChart.prototype, { } for (var s = 0; s < numSer; s++) { var series = graph._series[s]; - var g = graph._wrapper.group(this._chart, - $.extend({class_: 'series' + s, fill: series._fill, - stroke: series._stroke, strokeWidth: series._strokeWidth}, - series._settings || {})); + var g = graph._wrapper.group(this._chart, $.extend({class_: 'series' + s, fill: series._fill, + stroke: series._stroke, strokeWidth: series._strokeWidth}, series._settings || {})); for (var i = 0; i < series._values.length; i++) { accum[i] += series._values[i]; - var r = graph._wrapper.rect(g, - dims[graph.X] + xScale * (barGap + i * (barWidth + barGap)), + var r = graph._wrapper.rect(g, dims[graph.X] + xScale * (barGap + i * (barWidth + barGap)), dims[graph.Y] + yScale * (totals[i] - accum[i]) / totals[i], xScale * barWidth, yScale * series._values[i] / totals[i]); - graph._showStatus(r, series._name, - roundNumber(series._values[i] / totals[i] * 100, 2)); + graph._showStatus(r, series._name, roundNumber(series._values[i] / totals[i] * 100, 2)); } } }, - /* Draw the x-axis and its ticks. */ + /** Draw the x-axis and its ticks. + @private + @param graph {SVGGraph} The graph object. + @param numVal {number} The current value index. + @param barWidth {number} The width of each bar. + @param barGap {number} The space between bars. + @param dims {number[]} The dimensions of the drawing area. + @param xScale {number} The scaling factor in the horizontal direction. */ _drawXAxis: function(graph, numVal, barWidth, barGap, dims, xScale) { var axis = graph.xAxis; if (axis._title) { @@ -1092,32 +1120,33 @@ $.extend(SVGStackedColumnChart.prototype, { //------------------------------------------------------------------------------ -/* Draw a standard grouped row bar chart. */ +/** Draw a standard grouped row bar chart. + @module SVGRowChart */ function SVGRowChart() { } $.extend(SVGRowChart.prototype, { - /* Retrieve the display title for this chart type. - @return the title */ + /** Retrieve the display title for this chart type. + @return {string} Its title. */ title: function() { return 'Basic row chart'; }, - /* Retrieve a description of this chart type. - @return its description */ + /** Retrieve a description of this chart type. + @return {string} Its description. */ description: function() { return 'Compare sets of values as horizontal rows with grouped categories.'; }, - /* Retrieve a list of the options that may be set for this chart type. - @return options list */ + /** Retrieve a list of the options that may be set for this chart type. + @return {string[]} Its options list. */ options: function() { return barOptions; }, - /* Actually draw the graph in this type's style. - @param graph (object) the SVGGraph object */ + /** Actually draw the graph in this type's style. + @param graph {SVGGraph} The graph object. */ drawGraph: function(graph) { var bg = graph._drawChartBackground(true, true); var dims = graph._getDims(); @@ -1137,23 +1166,37 @@ $.extend(SVGRowChart.prototype, { graph._drawLegend(); }, - /* Plot an individual series. */ + /** Plot an individual series. + @private + @param graph {SVGGraph} The graph object. + @param cur {number} The current series index. + @param numSer {number} The number of points in this series. + @param barWidth {number} The width of each bar. + @param barGap {number} The space between bars. + @param dims {number[]} The dimensions of the drawing area. + @param xScale {number} The scaling factor in the horizontal direction. + @param yScale {number} The scaling factor in the vertical direction. */ _drawSeries: function(graph, cur, numSer, barWidth, barGap, dims, xScale, yScale) { var series = graph._series[cur]; - var g = graph._wrapper.group(this._chart, - $.extend({class_: 'series' + cur, fill: series._fill, - stroke: series._stroke, strokeWidth: series._strokeWidth}, - series._settings || {})); + var g = graph._wrapper.group(this._chart, $.extend({class_: 'series' + cur, fill: series._fill, + stroke: series._stroke, strokeWidth: series._strokeWidth}, series._settings || {})); for (var i = 0; i < series._values.length; i++) { - var r = graph._wrapper.rect(g, - dims[graph.X] + xScale * (0 - graph.yAxis._scale.min), + var r = graph._wrapper.rect(g, dims[graph.X] + xScale * (0 - graph.yAxis._scale.min), dims[graph.Y] + yScale * (barGap + i * (numSer * barWidth + barGap) + (cur * barWidth)), xScale * series._values[i], yScale * barWidth); graph._showStatus(r, series._name, series._values[i]); } }, - /* Draw the axes for this graph. */ + /** Draw the axes for this graph. + @private + @param graph {SVGGraph} The graph object. + @param numSer {number} The number of points in this series. + @param numVal {number} The current value index. + @param barWidth {number} The width of each bar. + @param barGap {number} The space between bars. + @param dims {number[]} The dimensions of the drawing area. + @param yScale {number} The scaling factor in the vertical direction. */ _drawAxes: function(graph, numSer, numVal, barWidth, barGap, dims, yScale) { // X-axis var axis = graph.yAxis; @@ -1194,33 +1237,34 @@ $.extend(SVGRowChart.prototype, { //------------------------------------------------------------------------------ -/* Draw a stacked row bar chart. */ +/** Draw a stacked row bar chart. + @module SVGStackedRowChart */ function SVGStackedRowChart() { } $.extend(SVGStackedRowChart.prototype, { - /* Retrieve the display title for this chart type. - @return the title */ + /** Retrieve the display title for this chart type. + @return {string} Its title. */ title: function() { return 'Stacked row chart'; }, - /* Retrieve a description of this chart type. - @return its description */ + /** Retrieve a description of this chart type. + @return {string} Its description. */ description: function() { return 'Compare sets of values as horizontal bars showing ' + 'relative contributions to the whole for each category.'; }, - /* Retrieve a list of the options that may be set for this chart type. - @return options list */ + /** Retrieve a list of the options that may be set for this chart type. + @return {string[]} Its options list. */ options: function() { return barOptions; }, - /* Actually draw the graph in this type's style. - @param graph (object) the SVGGraph object */ + /** Actually draw the graph in this type's style. + @param graph {SVGGraph} The graph object. */ drawGraph: function(graph) { var bg = graph._drawChartBackground(true, true); var dims = graph._getDims(); @@ -1237,8 +1281,7 @@ $.extend(SVGStackedRowChart.prototype, { this._drawRows(graph, numSer, numVal, barWidth, barGap, dims, xScale, yScale); graph._drawTitle(); graph._wrapper.text(graph._chartCont, dims[graph.X] + dims[graph.W] / 2, - dims[graph.Y] + dims[graph.H] + graph.xAxis._titleOffset, - $.svg.graphing.region.percentageText, + dims[graph.Y] + dims[graph.H] + graph.xAxis._titleOffset, $.svg.graphing.region.percentageText, $.extend({textAnchor: 'middle'}, graph.yAxis._titleFormat || {})); var pAxis = $.extend({}, graph._getPercentageAxis()); $.extend(pAxis._labelFormat, graph.yAxis._labelFormat || {}); @@ -1248,7 +1291,16 @@ $.extend(SVGStackedRowChart.prototype, { graph._drawLegend(); }, - /* Plot all of the rows. */ + /** Plot all of the rows. + @private + @param graph {SVGGraph} The graph object. + @param numSer {number} The number of points in this series. + @param numVal {number} The current value index. + @param barWidth {number} The width of each bar. + @param barGap {number} The space between bars. + @param dims {number[]} The dimensions of the drawing area. + @param xScale {number} The scaling factor in the horizontal direction. + @param yScale {number} The scaling factor in the vertical direction. */ _drawRows: function(graph, numSer, numVal, barWidth, barGap, dims, xScale, yScale) { var totals = graph._getTotals(); var accum = []; @@ -1257,23 +1309,26 @@ $.extend(SVGStackedRowChart.prototype, { } for (var s = 0; s < numSer; s++) { var series = graph._series[s]; - var g = graph._wrapper.group(this._chart, - $.extend({class_: 'series' + s, fill: series._fill, - stroke: series._stroke, strokeWidth: series._strokeWidth}, - series._settings || {})); + var g = graph._wrapper.group(this._chart, $.extend({class_: 'series' + s, fill: series._fill, + stroke: series._stroke, strokeWidth: series._strokeWidth}, series._settings || {})); for (var i = 0; i < series._values.length; i++) { - var r = graph._wrapper.rect(g, - dims[graph.X] + xScale * accum[i] / totals[i], + var r = graph._wrapper.rect(g, dims[graph.X] + xScale * accum[i] / totals[i], dims[graph.Y] + yScale * (barGap + i * (barWidth + barGap)), xScale * series._values[i] / totals[i], yScale * barWidth); - graph._showStatus(r, series._name, - roundNumber(series._values[i] / totals[i] * 100, 2)); + graph._showStatus(r, series._name, roundNumber(series._values[i] / totals[i] * 100, 2)); accum[i] += series._values[i]; } } }, - /* Draw the y-axis and its ticks. */ + /** Draw the y-axis and its ticks. + @private + @param graph {SVGGraph} The graph object. + @param numVal {number} The current value index. + @param barWidth {number} The width of each bar. + @param barGap {number} The space between bars. + @param dims {number[]} The dimensions of the drawing area. + @param yScale {number} The scaling factor in the vertical direction. */ _drawYAxis: function(graph, numVal, barWidth, barGap, dims, yScale) { var axis = graph.xAxis; if (axis._title) { @@ -1281,12 +1336,10 @@ $.extend(SVGStackedRowChart.prototype, { transform: 'translate(' + (dims[graph.X] - axis._titleOffset) + ',' + (dims[graph.Y] + dims[graph.H] / 2) + ') rotate(-90)'}, axis._titleFormat || {})); } - var gl = graph._wrapper.group(graph._chartCont, - $.extend({class_: 'yAxis'}, axis._lineFormat)); + var gl = graph._wrapper.group(graph._chartCont, $.extend({class_: 'yAxis'}, axis._lineFormat)); var gt = graph._wrapper.group(graph._chartCont, $.extend({class_: 'yAxisLabels', textAnchor: 'end'}, axis._labelFormat)); - graph._wrapper.line(gl, dims[graph.X], dims[graph.Y], - dims[graph.X], dims[graph.Y] + dims[graph.H]); + graph._wrapper.line(gl, dims[graph.X], dims[graph.Y], dims[graph.X], dims[graph.Y] + dims[graph.H]); if (axis._ticks.major) { var offsets = graph._getTickOffsets(axis, false); for (var i = 1; i < numVal; i++) { @@ -1305,32 +1358,33 @@ $.extend(SVGStackedRowChart.prototype, { //------------------------------------------------------------------------------ -/* Draw a standard line chart. */ +/** Draw a standard line chart. + @module SVGLineChart */ function SVGLineChart() { } $.extend(SVGLineChart.prototype, { - /* Retrieve the display title for this chart type. - @return the title */ + /** Retrieve the display title for this chart type. + @return {string} Its title. */ title: function() { return 'Basic line chart'; }, - /* Retrieve a description of this chart type. - @return its description */ + /** Retrieve a description of this chart type. + @return {string} Its description. */ description: function() { return 'Compare sets of values as continuous lines.'; }, - /* Retrieve a list of the options that may be set for this chart type. - @return options list */ + /** Retrieve a list of the options that may be set for this chart type. + @return {string[]} Its options list. */ options: function() { return []; }, - /* Actually draw the graph in this type's style. - @param graph (object) the SVGGraph object */ + /** Actually draw the graph in this type's style. + @param graph {SVGGraph} The graph object. */ drawGraph: function(graph) { graph._drawChartBackground(); var dims = graph._getDims(); @@ -1345,30 +1399,36 @@ $.extend(SVGLineChart.prototype, { graph._drawLegend(); }, - /* Plot an individual series. */ + /** Plot an individual series. + @private + @param graph {SVGGraph} The graph object. + @param cur {number} The current series index. + @param dims {number[]} The dimensions of the drawing area. + @param xScale {number} The scaling factor in the horizontal direction. + @param yScale {number} The scaling factor in the vertical direction. */ _drawSeries: function(graph, cur, dims, xScale, yScale) { var series = graph._series[cur]; var path = graph._wrapper.createPath(); for (var i = 0; i < series._values.length; i++) { var x = dims[graph.X] + i * xScale; var y = dims[graph.Y] + (graph.yAxis._scale.max - series._values[i]) * yScale; - if (i == 0) { + if (i === 0) { path.move(x, y); } else { path.line(x, y); } } - var p = graph._wrapper.path(this._chart, path, - $.extend({id: 'series' + cur, fill: 'none', stroke: series._stroke, - strokeWidth: series._strokeWidth}, series._settings || {})); + var p = graph._wrapper.path(this._chart, path, $.extend({id: 'series' + cur, fill: 'none', + stroke: series._stroke, strokeWidth: series._strokeWidth}, series._settings || {})); graph._showStatus(p, series._name, 0); } }); //------------------------------------------------------------------------------ -/* Draw a standard pie chart. */ +/** Draw a standard pie chart. + @module SVGPieChart */ function SVGPieChart() { } @@ -1378,26 +1438,26 @@ $.extend(SVGPieChart.prototype, { 'explodeDist (number) - the distance to move an exploded section', 'pieGap (number) - the distance between pies for multiple values'], - /* Retrieve the display title for this chart type. - @return the title */ + /** Retrieve the display title for this chart type. + @return {string} Its title. */ title: function() { return 'Pie chart'; }, - /* Retrieve a description of this chart type. - @return its description */ + /** Retrieve a description of this chart type. + @return {string} Its description. */ description: function() { return 'Compare relative sizes of values as contributions to the whole.'; }, - /* Retrieve a list of the options that may be set for this chart type. - @return options list */ + /** Retrieve a list of the options that may be set for this chart type. + @return {string[]} Its options list. */ options: function() { return this._options; }, - /* Actually draw the graph in this type's style. - @param graph (object) the SVGGraph object */ + /** Actually draw the graph in this type's style. + @param graph {SVGGraph} The graph object. */ drawGraph: function(graph) { graph._drawChartBackground(true, true); this._chart = graph._wrapper.group(graph._chartCont, {class_: 'chart'}); @@ -1407,14 +1467,17 @@ $.extend(SVGPieChart.prototype, { graph._drawLegend(); }, - /* Plot all the series. */ + /** Plot all the series. + @private + @param graph {SVGGraph} The graph object. + @param dims {number[]} The dimensions of the drawing area. */ _drawSeries: function(graph, dims) { var totals = graph._getTotals(); var numSer = graph._series.length; var numVal = (numSer ? (graph._series[0])._values.length : 0); var path = graph._wrapper.createPath(); var explode = graph._chartOptions.explode || []; - explode = (isArray(explode) ? explode : [explode]); + explode = ($.isArray(explode) ? explode : [explode]); var explodeDist = graph._chartOptions.explodeDist || 10; var pieGap = (numVal <= 1 ? 0 : graph._chartOptions.pieGap || 10); var xBase = (dims[graph.W] - (numVal * pieGap) - pieGap) / numVal / 2; @@ -1429,12 +1492,12 @@ $.extend(SVGPieChart.prototype, { var curTotal = 0; for (var j = 0; j < numSer; j++) { var series = graph._series[j]; - if (i == 0) { - gl[j] = graph._wrapper.group(this._chart, $.extend({class_: 'series' + j, - fill: series._fill, stroke: series._stroke, + if (i === 0) { + gl[j] = graph._wrapper.group(this._chart, + $.extend({class_: 'series' + j, fill: series._fill, stroke: series._stroke, strokeWidth: series._strokeWidth}, series._settings || {})); } - if (series._values[i] == 0) { + if (series._values[i] === 0) { continue; } var start = (curTotal / totals[i]) * 2 * Math.PI; @@ -1442,7 +1505,7 @@ $.extend(SVGPieChart.prototype, { var end = (curTotal / totals[i]) * 2 * Math.PI; var exploding = false; for (var k = 0; k < explode.length; k++) { - if (explode[k] == j) { + if (explode[k] === j) { exploding = true; break; } @@ -1453,8 +1516,7 @@ $.extend(SVGPieChart.prototype, { line(x + radius * Math.cos(start), y + radius * Math.sin(start)). arc(radius, radius, 0, (end - start < Math.PI ? 0 : 1), 1, x + radius * Math.cos(end), y + radius * Math.sin(end)).close()); - graph._showStatus(p, series._name, - roundNumber((end - start) / 2 / Math.PI * 100, 2)); + graph._showStatus(p, series._name, roundNumber((end - start) / 2 / Math.PI * 100, 2)); } if (graph.xAxis) { graph._wrapper.text(gt, cx, dims[graph.Y] + dims[graph.H] + graph.xAxis._titleOffset, @@ -1466,11 +1528,6 @@ $.extend(SVGPieChart.prototype, { //------------------------------------------------------------------------------ -/* Determine whether an object is an array. */ -function isArray(a) { - return (a && a.constructor == Array); -} - // Basic chart types $.svg.graphing.addChartType('column', new SVGColumnChart()); $.svg.graphing.addChartType('stackedColumn', new SVGStackedColumnChart()); diff --git a/jquery.svggraph.min.js b/jquery.svggraph.min.js index f693148..84a5285 100644 --- a/jquery.svggraph.min.js +++ b/jquery.svggraph.min.js @@ -1,7 +1,6 @@ -/* http://keith-wood.name/svg.html - SVG graphing extension for jQuery v1.4.5. +/* http://keith-wood.name/svg.html + SVG graphing extension for jQuery v1.5.0. Written by Keith Wood (kbwood{at}iinet.com.au) August 2007. - Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and - MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. + Available under the MIT (http://keith-wood.name/licence.html) license. Please attribute the author if you use it. */ -(function($){$.svg.addExtension('graph',SVGGraph);$.svg.graphing=new SVGGraphing();function SVGGraphing(){this.regional=[];this.regional['']={percentageText:'Percentage'};this.region=this.regional['']}$.extend(SVGGraphing.prototype,{_chartTypes:[],addChartType:function(a,b){this._chartTypes[a]=b},chartTypes:function(){return this._chartTypes}});function SVGGraph(a){this._wrapper=a;this._drawNow=false;for(var b in $.svg.graphing._chartTypes){this._chartType=$.svg.graphing._chartTypes[b];break}this._chartOptions={};this._title={value:'',offset:25,settings:{textAnchor:'middle'}};this._area=[0.1,0.1,0.8,0.9];this._chartFormat={fill:'none',stroke:'black'};this._gridlines=[];this._series=[];this._onstatus=null;this._chartCont=this._wrapper.svg(0,0,0,0,{class_:'svg-graph'});this.xAxis=new SVGGraphAxis(this);this.xAxis.title('',40);this.yAxis=new SVGGraphAxis(this);this.yAxis.title('',40);this.x2Axis=null;this.y2Axis=null;this.legend=new SVGGraphLegend(this);this._drawNow=true}$.extend(SVGGraph.prototype,{X:0,Y:1,W:2,H:3,L:0,T:1,R:2,B:3,_percentageAxis:new SVGGraphAxis(this,$.svg.graphing.region.percentageText,0,100,10,0),container:function(a){if(arguments.length==0){return this._chartCont}this._chartCont=a;return this},chartType:function(a,b){return(arguments.length==0?this.type():this.type(a,b))},type:function(a,b){if(arguments.length==0){return this._chartType}var c=$.svg.graphing._chartTypes[a];if(c){this._chartType=c;this._chartOptions=$.extend({},b||{})}this._drawGraph();return this},chartOptions:function(a){return(arguments.length==0?this.options():this.options(a))},options:function(a){if(arguments.length==0){return this._chartOptions}this._chartOptions=$.extend({},a);this._drawGraph();return this},chartFormat:function(a,b,c){return(arguments.length==0?this.format():this.format(a,b,c))},format:function(a,b,c){if(arguments.length==0){return this._chartFormat}if(typeof b=='object'){c=b;b=null}this._chartFormat=$.extend({fill:a},(b?{stroke:b}:{}),c||{});this._drawGraph();return this},chartArea:function(a,b,c,d){return(arguments.length==0?this.area():this.area(a,b,c,d))},area:function(a,b,c,d){if(arguments.length==0){return this._area}this._area=(isArray(a)?a:[a,b,c,d]);this._drawGraph();return this},gridlines:function(a,b){if(arguments.length==0){return this._gridlines}this._gridlines=[(typeof a=='string'?{stroke:a}:a),(typeof b=='string'?{stroke:b}:b)];if(this._gridlines[0]==null&&this._gridlines[1]==null){this._gridlines=[]}this._drawGraph();return this},title:function(a,b,c,d){if(arguments.length==0){return this._title}if(typeof b!='number'){d=c;c=b;b=null}if(typeof c!='string'){d=c;c=null}this._title={value:a,offset:b||this._title.offset,settings:$.extend({textAnchor:'middle'},(c?{fill:c}:{}),d||{})};this._drawGraph();return this},addSeries:function(a,b,c,d,e,f){this._series.push(new SVGGraphSeries(this,a,b,c,d,e,f));this._drawGraph();return this},series:function(i){return(arguments.length>0?this._series[i]:null)||this._series},noDraw:function(){this._drawNow=false;return this},redraw:function(){this._drawNow=true;this._drawGraph();return this},status:function(a){this._onstatus=a;return this},_drawGraph:function(){if(!this._drawNow){return}while(this._chartCont.firstChild){this._chartCont.removeChild(this._chartCont.firstChild)}if(!this._chartCont.parent){this._wrapper._svg.appendChild(this._chartCont)}if(!this._chartCont.width){this._chartCont.setAttribute('width',parseInt(this._chartCont.getAttribute('width'),10)||this._wrapper._width())}else if(this._chartCont.width.baseVal){this._chartCont.width.baseVal.value=this._chartCont.width.baseVal.value||this._wrapper._width()}else{this._chartCont.width=this._chartCont.width||this._wrapper._width()}if(!this._chartCont.height){this._chartCont.setAttribute('height',parseInt(this._chartCont.getAttribute('height'),10)||this._wrapper._height())}else if(this._chartCont.height.baseVal){this._chartCont.height.baseVal.value=this._chartCont.height.baseVal.value||this._wrapper._height()}else{this._chartCont.height=this._chartCont.height||this._wrapper._height()}this._chartType.drawGraph(this)},_getValue:function(a,b){return(!a[b]?parseInt(a.getAttribute(b),10):(a[b].baseVal?a[b].baseVal.value:a[b]))},_drawTitle:function(){this._wrapper.text(this._chartCont,this._getValue(this._chartCont,'width')/2,this._title.offset,this._title.value,this._title.settings)},_getDims:function(a){a=a||this._area;var b=this._getValue(this._chartCont,'width');var c=this._getValue(this._chartCont,'height');var d=(a[this.L]>1?a[this.L]:b*a[this.L]);var e=(a[this.T]>1?a[this.T]:c*a[this.T]);var f=(a[this.R]>1?a[this.R]:b*a[this.R])-d;var g=(a[this.B]>1?a[this.B]:c*a[this.B])-e;return[d,e,f,g]},_drawChartBackground:function(a,b){var c=this._wrapper.group(this._chartCont,{class_:'background'});var d=this._getDims();this._wrapper.rect(c,d[this.X],d[this.Y],d[this.W],d[this.H],this._chartFormat);if(this._gridlines[0]&&this.yAxis._ticks.major&&!b){this._drawGridlines(c,this.yAxis,true,d,this._gridlines[0])}if(this._gridlines[1]&&this.xAxis._ticks.major&&!a){this._drawGridlines(c,this.xAxis,false,d,this._gridlines[1])}return c},_drawGridlines:function(a,b,c,d,e){var g=this._wrapper.group(a,e);var f=(c?d[this.H]:d[this.W])/(b._scale.max-b._scale.min);var h=Math.floor(b._scale.min/b._ticks.major)*b._ticks.major;h=(h(this._getValue(this._chartCont,'width')/2)&&f>(this._getValue(this._chartCont,'height')/2));var k=(g?e-c:f-d)/(a._scale.max-a._scale.min);var l=a._ticks.size;var m=Math.floor(a._scale.min/a._ticks.major)*a._ticks.major;m=(ma[this.H];var c=this._series.length;var d=(b?a[this.W]:a[this.H])/c;var e=a[this.X]+5;var f=a[this.Y]+((b?a[this.H]:d)+this.legend._sampleSize)/2;for(var i=0;i0?h:0);var q=a._wrapper.group(a._chartCont,$.extend({class_:'xAxisLabels',textAnchor:'middle'},a.xAxis._labelFormat));var r=[];for(var i=0;i0?this._series[i]:null)||this._series},noDraw:function(){this._drawNow=false;return this},redraw:function(){this._drawNow=true;this._drawGraph();return this},status:function(a){this._onstatus=a;return this},_drawGraph:function(){if(!this._drawNow){return}while(this._chartCont.firstChild){this._chartCont.removeChild(this._chartCont.firstChild)}if(!this._chartCont.parent){this._wrapper._svg.appendChild(this._chartCont)}if(!this._chartCont.width){this._chartCont.setAttribute('width',parseInt(this._chartCont.getAttribute('width'),10)||this._wrapper.width())}else if(this._chartCont.width.baseVal){this._chartCont.width.baseVal.value=this._chartCont.width.baseVal.value||this._wrapper.width()}else{this._chartCont.width=this._chartCont.width||this._wrapper.width()}if(!this._chartCont.height){this._chartCont.setAttribute('height',parseInt(this._chartCont.getAttribute('height'),10)||this._wrapper.height())}else if(this._chartCont.height.baseVal){this._chartCont.height.baseVal.value=this._chartCont.height.baseVal.value||this._wrapper.height()}else{this._chartCont.height=this._chartCont.height||this._wrapper.height()}this._chartType.drawGraph(this)},_getValue:function(a,b){return(!a[b]?parseInt(a.getAttribute(b),10):(a[b].baseVal?a[b].baseVal.value:a[b]))},_drawTitle:function(){this._wrapper.text(this._chartCont,this._getValue(this._chartCont,'width')/2,this._title.offset,this._title.value,this._title.settings)},_getDims:function(a){a=a||this._area;var b=this._getValue(this._chartCont,'width');var c=this._getValue(this._chartCont,'height');var d=(a[this.L]>1?a[this.L]:b*a[this.L]);var e=(a[this.T]>1?a[this.T]:c*a[this.T]);var f=(a[this.R]>1?a[this.R]:b*a[this.R])-d;var g=(a[this.B]>1?a[this.B]:c*a[this.B])-e;return[d,e,f,g]},_drawChartBackground:function(a,b){var c=this._wrapper.group(this._chartCont,{class_:'background'});var d=this._getDims();this._wrapper.rect(c,d[this.X],d[this.Y],d[this.W],d[this.H],this._chartFormat);if(this._gridlines[0]&&this.yAxis._ticks.major&&!b){this._drawGridlines(c,this.yAxis,true,d,this._gridlines[0])}if(this._gridlines[1]&&this.xAxis._ticks.major&&!a){this._drawGridlines(c,this.xAxis,false,d,this._gridlines[1])}return c},_drawGridlines:function(a,b,c,d,e){var g=this._wrapper.group(a,e);var f=(c?d[this.H]:d[this.W])/(b._scale.max-b._scale.min);var h=Math.floor(b._scale.min/b._ticks.major)*b._ticks.major;h=(h(this._getValue(this._chartCont,'width')/2)&&f>(this._getValue(this._chartCont,'height')/2));var k=(g?e-c:f-d)/(a._scale.max-a._scale.min);var l=a._ticks.size;var m=Math.floor(a._scale.min/a._ticks.major)*a._ticks.major;m=(ma[this.H];var c=this._series.length;var d=(b?a[this.W]:a[this.H])/c;var e=a[this.X]+5;var f=a[this.Y]+((b?a[this.H]:d)+this.legend._sampleSize)/2;for(var i=0;i0?h:0);var q=a._wrapper.group(a._chartCont,$.extend({class_:'xAxisLabels',textAnchor:'middle'},a.xAxis._labelFormat));var r=[];for(var i=0;i35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(7($){$.19.3M(\'3i\',2L);$.19.1k=1q 2M();7 2M(){4.2N=[];4.2N[\'\']={2g:\'3N\'};4.2h=4.2N[\'\']}$.G(2M.1v,{26:[],1V:7(a,b){4.26[a]=b},3O:7(){C 4.26}});7 2L(a){4.D=a;4.2i=1K;M(6 b 2O $.19.1k.26){4.2y=$.19.1k.26[b];3j}4.1h={};4.O={1L:\'\',2j:25,2z:{1b:\'1l\'}};4.1M=[0.1,0.1,0.8,0.9];4.2A={1o:\'3k\',1i:\'2P\'};4.1j=[];4.S=[];4.2B=Z;4.F=4.D.19(0,0,0,0,{U:\'19-3i\'});4.Q=1q 2k(4);4.Q.1w(\'\',40);4.N=1q 2k(4);4.N.1w(\'\',40);4.1N=Z;4.1O=Z;4.1x=1q 2Q(4);4.2i=18}$.G(2L.1v,{X:0,Y:1,W:2,H:3,L:0,T:1,R:2,B:3,2R:1q 2k(4,$.19.1k.2h.2g,0,2l,10,0),3P:7(a){E(11.J==0){C 4.F}4.F=a;C 4},3Q:7(a,b){C(11.J==0?4.2S():4.2S(a,b))},2S:7(a,b){E(11.J==0){C 4.2y}6 c=$.19.1k.26[a];E(c){4.2y=c;4.1h=$.G({},b||{})}4.12();C 4},3R:7(a){C(11.J==0?4.1G():4.1G(a))},1G:7(a){E(11.J==0){C 4.1h}4.1h=$.G({},a);4.12();C 4},3S:7(a,b,c){C(11.J==0?4.27():4.27(a,b,c))},27:7(a,b,c){E(11.J==0){C 4.2A}E(1c b==\'3l\'){c=b;b=Z}4.2A=$.G({1o:a},(b?{1i:b}:{}),c||{});4.12();C 4},3T:7(a,b,c,d){C(11.J==0?4.2C():4.2C(a,b,c,d))},2C:7(a,b,c,d){E(11.J==0){C 4.1M}4.1M=(2m(a)?a:[a,b,c,d]);4.12();C 4},3U:7(a,b){E(11.J==0){C 4.1j}4.1j=[(1c a==\'1H\'?{1i:a}:a),(1c b==\'1H\'?{1i:b}:b)];E(4.1j[0]==Z&&4.1j[1]==Z){4.1j=[]}4.12();C 4},1w:7(a,b,c,d){E(11.J==0){C 4.O}E(1c b!=\'1y\'){d=c;c=b;b=Z}E(1c c!=\'1H\'){d=c;c=Z}4.O={1L:a,2j:b||4.O.2j,2z:$.G({1b:\'1l\'},(c?{1o:c}:{}),d||{})};4.12();C 4},3V:7(a,b,c,d,e,f){4.S.3W(1q 2T(4,a,b,c,d,e,f));4.12();C 4},1W:7(i){C(11.J>0?4.S[i]:Z)||4.S},3X:7(){4.2i=1K;C 4},3Y:7(){4.2i=18;4.12();C 4},3Z:7(a){4.2B=a;C 4},12:7(){E(!4.2i){C}2U(4.F.3m){4.F.41(4.F.3m)}E(!4.F.42){4.D.43.44(4.F)}E(!4.F.1r){4.F.3n(\'1r\',2V(4.F.2W(\'1r\'),10)||4.D.2X())}2n E(4.F.1r.1P){4.F.1r.1P.1L=4.F.1r.1P.1L||4.D.2X()}2n{4.F.1r=4.F.1r||4.D.2X()}E(!4.F.1A){4.F.3n(\'1A\',2V(4.F.2W(\'1A\'),10)||4.D.2Y())}2n E(4.F.1A.1P){4.F.1A.1P.1L=4.F.1A.1P.1L||4.D.2Y()}2n{4.F.1A=4.F.1A||4.D.2Y()}4.2y.1X(4)},28:7(a,b){C(!a[b]?2V(a.2W(b),10):(a[b].1P?a[b].1P.1L:a[b]))},1Y:7(){4.D.14(4.F,4.28(4.F,\'1r\')/2,4.O.2j,4.O.1L,4.O.2z)},1B:7(a){a=a||4.1M;6 b=4.28(4.F,\'1r\');6 c=4.28(4.F,\'1A\');6 d=(a[4.L]>1?a[4.L]:b*a[4.L]);6 e=(a[4.T]>1?a[4.T]:c*a[4.T]);6 f=(a[4.R]>1?a[4.R]:b*a[4.R])-d;6 g=(a[4.B]>1?a[4.B]:c*a[4.B])-e;C[d,e,f,g]},1Z:7(a,b){6 c=4.D.V(4.F,{U:\'45\'});6 d=4.1B();4.D.20(c,d[4.X],d[4.Y],d[4.W],d[4.H],4.2A);E(4.1j[0]&&4.N.I.16&&!b){4.29(c,4.N,18,d,4.1j[0])}E(4.1j[1]&&4.Q.I.16&&!a){4.29(c,4.Q,1K,d,4.1j[1])}C c},29:7(a,b,c,d,e){6 g=4.D.V(a,e);6 f=(c?d[4.H]:d[4.W])/(b.K.1d-b.K.13);6 h=17.2Z(b.K.13/b.I.16)*b.I.16;h=(h(4.28(4.F,\'1r\')/2)&&f>(4.28(4.F,\'1A\')/2));6 k=(g?e-c:f-d)/(a.K.1d-a.K.13);6 l=a.I.1g;6 m=17.2Z(a.K.13/a.I.16)*a.I.16;m=(ma[4.H];6 c=4.S.J;6 d=(b?a[4.W]:a[4.H])/c;6 e=a[4.X]+5;6 f=a[4.Y]+((b?a[4.H]:d)+4.1x.1I)/2;M(6 i=0;i0?h:0);6 q=a.D.V(a.F,$.G({U:\'34\',1b:\'1l\'},a.Q.1p));6 r=[];M(6 i=0;iUse the singleton instance of this class, $.svg.plot, + to interact with the SVG plotting functionality.

+ @module SVGPlot */ function SVGPlot(wrapper) { this._wrapper = wrapper; // The attached SVG wrapper object this._drawNow = false; // True for immediate update, false to wait for redraw call // The plot title and settings this._title = {value: '', offset: 25, settings: {textAnchor: 'middle'}}; - this._area = [0.1, 0.1, 0.8, 0.9]; // The chart area: left, top, right, bottom, - // > 1 in pixels, <= 1 as proportion + this._area = [0.1, 0.1, 0.8, 0.9]; // The chart area: left, top, right, bottom, > 1 in pixels, <= 1 as proportion this._areaFormat = {fill: 'none', stroke: 'black'}; // The formatting for the plot area this._gridlines = []; // The formatting of the x- and y-gridlines this._equalXY = true; // True for equal-sized x- and y-units, false to fill available space @@ -25,91 +25,94 @@ function SVGPlot(wrapper) { this._onstatus = null; // The callback function for status updates this._uuid = new Date().getTime(); this._plotCont = this._wrapper.svg(0, 0, 0, 0, {class_: 'svg-plot'}); // The main container for the plot - - this.xAxis = new SVGPlotAxis(this); // The main x-axis + + /** The main x-axis for this plot. */ + this.xAxis = new SVGPlotAxis(this); this.xAxis.title('X', 20); - this.yAxis = new SVGPlotAxis(this); // The main y-axis + /** The main y-axis for this plot. */ + this.yAxis = new SVGPlotAxis(this); this.yAxis.title('Y', 20); - this.legend = new SVGPlotLegend(this); // The plot legend + /** The legend for this plot. */ + this.legend = new SVGPlotLegend(this); this._drawNow = true; } $.extend(SVGPlot.prototype, { /* Useful indexes. */ + /** Index in a dimensions array for x-coordinate. */ X: 0, + /** Index in a dimensions array for y-coordinate. */ Y: 1, + /** Index in a dimensions array for width. */ W: 2, + /** Index in a dimensions array for height. */ H: 3, + /** Index in an area array for left x-coordinate. */ L: 0, + /** Index in an area array for top y-coordinate. */ T: 1, + /** Index in an area array for right x-coordinate. */ R: 2, + /** Index in an area array for bottom y-coordinate. */ B: 3, - /* Set or retrieve the container for the plot. - @param cont (SVG element) the container for the plot - @return (SVGPlot) this plot object or - (SVG element) the current container (if no parameters) */ + /** Set or retrieve the container for the plot. + @param cont {SVGElement} The container for the plot. + @return {SVGPlot|SVGElement} This plot object or the current container (if no parameters). */ container: function(cont) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._plotCont; } this._plotCont = cont; return this; }, - /* Set or retrieve the main plotting area. - @param left (number) > 1 is pixels, <= 1 is proportion of width or - (number[4]) for left, top, right, bottom - @param top (number) > 1 is pixels, <= 1 is proportion of height - @param right (number) > 1 is pixels, <= 1 is proportion of width - @param bottom (number) > 1 is pixels, <= 1 is proportion of height - @return (SVGPlot) this plot object or - (number[4]) the plotting area: left, top, right, bottom (if no parameters) */ + /** Set or retrieve the main plotting area. + @param left {number|number[]} > 1 is pixels, <= 1 is proportion of width or array for left, top, right, bottom. + @param [top] {number) > 1 is pixels, <= 1 is proportion of height. + @param [right] {number) > 1 is pixels, <= 1 is proportion of width. + @param [bottom] {number) > 1 is pixels, <= 1 is proportion of height. + @return {SVGPlot|number[]} This plot object or the plotting area: left, top, right, bottom (if no parameters). */ area: function(left, top, right, bottom) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._area; } - this._area = (isArray(left) ? left : [left, top, right, bottom]); + this._area = ($.isArray(left) ? left : [left, top, right, bottom]); this._drawPlot(); return this; }, - /* Set or retrieve the background of the plot area. - @param fill (string) how to fill the area background - @param stroke (string) the colour of the outline (optional) - @param settings (object) additional formatting for the area background (optional) - @return (SVGPlot) this plot object or - (object) the area format (if no parameters) */ + /** Set or retrieve the background of the plot area. + @param fill {string} How to fill the area background. + @param [stroke] {string} The colour of the outline. + @param [settings] {object} Additional formatting for the area background. + @return {SVGPlot|object} This plot object or the area format (if no parameters). */ format: function(fill, stroke, settings) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._areaFormat; } - if (typeof stroke == 'object') { + if (typeof stroke === 'object') { settings = stroke; stroke = null; } - this._areaFormat = $.extend({fill: fill}, - (stroke ? {stroke: stroke} : {}), settings || {}); + this._areaFormat = $.extend({fill: fill}, (stroke ? {stroke: stroke} : {}), settings || {}); this._drawPlot(); return this; }, - /* Set or retrieve the gridlines formatting for the plot area. - @param xSettings (string) the colour of the gridlines along the x-axis, or - (object) formatting for the gridlines along the x-axis, or - null for none - @param ySettings (string) the colour of the gridlines along the y-axis, or - (object) formatting for the gridlines along the y-axis, or - null for none - @return (SVGPlot) this plot object or - (object[2]) the gridlines formatting (if no parameters) */ + /** Set or retrieve the gridlines formatting for the plot area. + @param xSettings {string|object} The colour of the gridlines along the x-axis, + or formatting for the gridlines along the x-axis, or null for none. + @param ySettings {string|object} The colour of the gridlines along the y-axis, + or formatting for the gridlines along the y-axis, or null for none. + @return {SVGPlot|object[]} This plot object or the gridlines formatting (if no parameters). */ gridlines: function(xSettings, ySettings) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._gridlines; } - this._gridlines = [(typeof xSettings == 'string' ? {stroke: xSettings} : xSettings), - (typeof ySettings == 'string' ? {stroke: ySettings} : ySettings)]; + this._gridlines = [(typeof xSettings === 'string' ? {stroke: xSettings} : xSettings), + (typeof ySettings === 'string' ? {stroke: ySettings} : ySettings)]; if (this._gridlines[0] == null && this._gridlines[1] == null) { this._gridlines = []; } @@ -117,94 +120,90 @@ $.extend(SVGPlot.prototype, { return this; }, - /* Set or retrieve the equality of the x- and y-axes. - @param value (boolean) true for equal x- and y-units, false to fill the available space - @return (SVGPlot) this plot object or - (boolean) the current setting (if no parameters) */ + /** Set or retrieve the equality of the x- and y-axes. + @param value {boolean} true for equal x- and y-units, + false to fill the available space. + @return {SVGPlot|boolean} This plot object or the current setting (if no parameters). */ equalXY: function(value) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._equalXY; } this._equalXY = value; return this; }, - /* Set or retrieve the title of the plot and its formatting. - @param value (string) the title - @param offset (number) the vertical positioning of the title - > 1 is pixels, <= 1 is proportion of width (optional) - @param colour (string) the colour of the title (optional) - @param settings (object) formatting for the title (optional) - @return (SVGPlot) this plot object or - (object) value, offset, and settings for the title (if no parameters) */ + /** Set or retrieve the title of the plot and its formatting. + @param value {string} The title. + @param [offset] {number} The vertical positioning of the title, > 1 is pixels, <= 1 is proportion of width. + @param [colour] {string} The colour of the title. + @param [settings] {object} Formatting for the title. + @return {SVGPlot|object} This plot object or value, offset, and settings for the title (if no parameters). */ title: function(value, offset, colour, settings) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._title; } - if (typeof offset != 'number') { + if (typeof offset !== 'number') { settings = colour; colour = offset; offset = null; } - if (typeof colour != 'string') { + if (typeof colour !== 'string') { settings = colour; colour = null; } this._title = {value: value, offset: offset || this._title.offset, - settings: $.extend({textAnchor: 'middle'}, - (colour ? {fill: colour} : {}), settings || {})}; + settings: $.extend({textAnchor: 'middle'}, (colour ? {fill: colour} : {}), settings || {})}; this._drawPlot(); return this; }, - /* Add a function to be plotted on the plot. - @param name (string) the name of this series (optional) - @param fn (function) the function to be plotted - @param range (number[2]) the range of values to plot (optional) - @param points (number) the number of points to plot within this range (optional) - @param stroke (string) the colour of the plotted lines (optional) - @param strokeWidth (number) the width of the plotted lines (optional) - @param settings (object) additional settings for the plotted values (optional) - @return (SVGPlot) this plot object */ + /** Add a function to be plotted on the plot. + @param [name] {string} The name of this series. + @param fn {function} The function to be plotted. + @param [range] {number[]} The range of values to plot. + @param [points] {number} The number of points to plot within this range. + @param [stroke] {string} The colour of the plotted lines. + @param [strokeWidth] {number} The width of the plotted lines. + @param [settings] {object} Additional settings for the plotted values. + @return {SVGPlot} This plot object. */ addFunction: function(name, fn, range, points, stroke, strokeWidth, settings) { - this._functions.push(new SVGPlotFunction( - this, name, fn, range, points, stroke, strokeWidth, settings)); + this._functions.push(new SVGPlotFunction(this, name, fn, range, points, stroke, strokeWidth, settings)); this._drawPlot(); return this; }, - /* Retrieve the function wrappers. - @param i (number) the function index (optional) - @return (SVGPlotFunction) the specified function or - (SVGPlotFunction[]) the list of functions */ + /** Retrieve the function wrappers. + @param [i] {number} the function index. + @return {SVGPlotFunction|SVGPlotFunction[]} the specified function or the list of functions. */ functions: function(i) { return (arguments.length > 0 ? this._functions[i] : null) || this._functions; }, - /* Suppress drawing of the plot until redraw() is called. - @return (SVGPlot) this plot object */ + /** Suppress drawing of the plot until redraw() is called. + @return {SVGPlot} this plot object. */ noDraw: function() { this._drawNow = false; return this; }, - /* Redraw the entire plot with the current settings and values. - @return (SVGPlot) this plot object */ + /** Redraw the entire plot with the current settings and values. + @return {SVGPlot} This plot object. */ redraw: function() { this._drawNow = true; this._drawPlot(); return this; }, - /* Set the callback function for status updates. - @param onstatus (function) the callback function - @return (SVGPlot) this plot object */ + /** Set the callback function for status updates. + @param onstatus {function} The callback function. + @return {SVGPlot} This plot object. */ status: function(onstatus) { this._onstatus = onstatus; return this; }, - /* Actually draw the plot (if allowed). */ + /** Actually draw the plot (if allowed). + @private */ _drawPlot: function() { if (!this._drawNow) { return; @@ -218,25 +217,23 @@ $.extend(SVGPlot.prototype, { // Set sizes if not already there if (!this._plotCont.width) { this._plotCont.setAttribute('width', - parseInt(this._plotCont.getAttribute('width'), 10) || this._wrapper._width()); + parseInt(this._plotCont.getAttribute('width'), 10) || this._wrapper.width()); } else if (this._plotCont.width.baseVal) { - this._plotCont.width.baseVal.value = - this._plotCont.width.baseVal.value || this._wrapper._width(); + this._plotCont.width.baseVal.value = this._plotCont.width.baseVal.value || this._wrapper.width(); } else { - this._plotCont.width = this._plotCont.width || this._wrapper._width(); + this._plotCont.width = this._plotCont.width || this._wrapper.width(); } if (!this._plotCont.height) { this._plotCont.setAttribute('height', - parseInt(this._plotCont.getAttribute('height'), 10) || this._wrapper._height()); + parseInt(this._plotCont.getAttribute('height'), 10) || this._wrapper.height()); } else if (this._plotCont.height.baseVal) { - this._plotCont.height.baseVal.value = - this._plotCont.height.baseVal.value || this._wrapper._height(); + this._plotCont.height.baseVal.value = this._plotCont.height.baseVal.value || this._wrapper.height(); } else { - this._plotCont.height = this._plotCont.height || this._wrapper._height(); + this._plotCont.height = this._plotCont.height || this._wrapper.height(); } this._drawChartBackground(); var dims = this._getDims(); @@ -253,18 +250,20 @@ $.extend(SVGPlot.prototype, { this._drawLegend(); }, - /* Decode an attribute value. - @param node the node to examine - @param name the attribute name - @return the actual value */ + /** Decode an attribute value. + @private + @param node {SVGElement} The node to examine. + @param name {string} The attribute name. + @return {string} The actual value. */ _getValue: function(node, name) { return (!node[name] ? parseInt(node.getAttribute(name), 10) : (node[name].baseVal ? node[name].baseVal.value : node[name])); }, - /* Calculate the actual dimensions of the plot area. - @param area (number[4]) the area values to evaluate (optional) - @return (number[4]) an array of dimension values: left, top, width, height */ + /** Calculate the actual dimensions of the plot area. + @private + @param [area] {number[]} The area values to evaluate, or the current area if not specified. + @return {number[]} An array of dimension values: left, top, width, height. */ _getDims: function(area) { var otherArea = (area != null); area = area || this._area; @@ -283,18 +282,20 @@ $.extend(SVGPlot.prototype, { return [left, top, width, height]; }, - /* Calculate the scaling factors for the plot area. - @return (number[2]) the x- and y-scaling factors */ + /** Calculate the scaling factors for the plot area. + @private + @return {number[]} The x- and y-scaling factors. */ _getScales: function() { var dims = this._getDims(); return [dims[this.W] / (this.xAxis._scale.max - this.xAxis._scale.min), dims[this.H] / (this.yAxis._scale.max - this.yAxis._scale.min)]; }, - /* Draw the chart background, including gridlines. - @param noXGrid (boolean) true to suppress the x-gridlines, false to draw them (optional) - @param noYGrid (boolean) true to suppress the y-gridlines, false to draw them (optional) - @return (element) the background group element */ + /** Draw the chart background, including gridlines. + @private + @param [noXGrid] {boolean} true to suppress the x-gridlines, false to draw them. + @param [noYGrid] {boolean} true to suppress the y-gridlines, false to draw them. + @return {SVGElement} The background group element. */ _drawChartBackground: function(noXGrid, noYGrid) { var bg = this._wrapper.group(this._plotCont, {class_: 'background'}); var dims = this._getDims(); @@ -308,10 +309,11 @@ $.extend(SVGPlot.prototype, { return bg; }, - /* Draw one set of gridlines. - @param bg (element) the background group element - @param horiz (boolean) true if horizontal, false if vertical - @param format (object) additional settings for the gridlines */ + /** Draw one set of gridlines. + @private + @param bg {SVGElement} The background group element. + @param horiz {boolean} true if horizontal, false if vertical. + @param format {object} Additional settings for the gridlines. */ _drawGridlines: function(bg, horiz, format, dims) { var g = this._wrapper.group(bg, format); var axis = (horiz ? this.yAxis : this.xAxis); @@ -327,8 +329,9 @@ $.extend(SVGPlot.prototype, { } }, - /* Draw an axis, its tick marks, and title. - @param horiz (boolean) true for x-axis, false for y-axis */ + /** Draw an axis, its tick marks, and title. + @private + @param horiz {boolean} true for x-axis, false for y-axis. */ _drawAxis: function(horiz) { var id = (horiz ? 'x' : 'y') + 'Axis'; var axis = (horiz ? this.xAxis : this.yAxis); @@ -341,8 +344,7 @@ $.extend(SVGPlot.prototype, { var zero = (horiz ? axis2._scale.max : -axis2._scale.min) * scales[horiz ? 1 : 0] + (horiz ? dims[this.Y] : dims[this.X]); this._wrapper.line(gl, (horiz ? dims[this.X] : zero), (horiz ? zero : dims[this.Y]), - (horiz ? dims[this.X] + dims[this.W] : zero), - (horiz ? zero : dims[this.Y] + dims[this.H])); + (horiz ? dims[this.X] + dims[this.W] : zero), (horiz ? zero : dims[this.Y] + dims[this.H])); if (axis._ticks.major) { var size = axis._ticks.size; var major = Math.floor(axis._scale.min / axis._ticks.major) * axis._ticks.major; @@ -350,23 +352,20 @@ $.extend(SVGPlot.prototype, { var minor = (!axis._ticks.minor ? axis._scale.max + 1 : Math.floor(axis._scale.min / axis._ticks.minor) * axis._ticks.minor); minor = (minor < axis._scale.min ? minor + axis._ticks.minor : minor); - var offsets = [(axis._ticks.position == 'nw' || axis._ticks.position == 'both' ? -1 : 0), - (axis._ticks.position == 'se' || axis._ticks.position == 'both' ? +1 : 0)]; + var offsets = [(axis._ticks.position === 'nw' || axis._ticks.position === 'both' ? -1 : 0), + (axis._ticks.position === 'se' || axis._ticks.position === 'both' ? +1 : 0)]; while (major <= axis._scale.max || minor <= axis._scale.max) { var cur = Math.min(major, minor); - var len = (cur == major ? size : size / 2); + var len = (cur === major ? size : size / 2); var xy = (horiz ? cur - axis._scale.min : axis._scale.max - cur) * scales[horiz ? 0 : 1] + (horiz ? dims[this.X] : dims[this.Y]); - this._wrapper.line(gl, (horiz ? xy : zero + len * offsets[0]), - (horiz ? zero + len * offsets[0] : xy), - (horiz ? xy : zero + len * offsets[1]), - (horiz ? zero + len * offsets[1] : xy)); - if (cur == major && cur != 0) { - this._wrapper.text(gt, (horiz ? xy : zero - size), - (horiz ? zero - size : xy), '' + cur); + this._wrapper.line(gl, (horiz ? xy : zero + len * offsets[0]), (horiz ? zero + len * offsets[0] : xy), + (horiz ? xy : zero + len * offsets[1]), (horiz ? zero + len * offsets[1] : xy)); + if (cur === major && cur !== 0) { + this._wrapper.text(gt, (horiz ? xy : zero - size), (horiz ? zero - size : xy), '' + cur); } - major += (cur == major ? axis._ticks.major : 0); - minor += (cur == minor ? axis._ticks.minor : 0); + major += (cur === major ? axis._ticks.major : 0); + minor += (cur === minor ? axis._ticks.minor : 0); } } if (axis._title) { @@ -375,14 +374,16 @@ $.extend(SVGPlot.prototype, { zero, axis._title, $.extend({textAnchor: 'end'}, axis._titleFormat || {})); } else { - this._wrapper.text(this._plotCont, zero, - dims[this.Y] + dims[this.H] + axis._titleOffset, + this._wrapper.text(this._plotCont, zero, dims[this.Y] + dims[this.H] + axis._titleOffset, axis._title, $.extend({textAnchor : 'middle'}, axis._titleFormat || {})); } } }, - /* Plot an individual function. */ + /** Plot an individual function. + @private + @param fn {function} The function to plot. + @param cur {number} The current function index. */ _plotFunction: function(fn, cur) { var dims = this._getDims(); var scales = this._getScales(); @@ -403,27 +404,27 @@ $.extend(SVGPlot.prototype, { path[(first ? 'move' : 'line') + 'To'](px, py); first = false; } - var p = this._wrapper.path(this._plot, path, - $.extend({class_: 'fn' + cur, fill: 'none', stroke: fn._stroke, + var p = this._wrapper.path(this._plot, path, $.extend({class_: 'fn' + cur, fill: 'none', stroke: fn._stroke, strokeWidth: fn._strokeWidth}, fn._settings || {})); this._showStatus(p, fn._name); }, - /* Draw the plot title - centred. */ + /** Draw the plot title - centred + @private */ _drawTitle: function() { this._wrapper.text(this._plotCont, this._getValue(this._plotCont, 'width') / 2, this._title.offset, this._title.value, this._title.settings); }, - /* Draw the chart legend. */ + /** Draw the chart legend. + @private */ _drawLegend: function() { if (!this.legend._show) { return; } var g = this._wrapper.group(this._plotCont, {class_: 'legend'}); var dims = this._getDims(this.legend._area); - this._wrapper.rect(g, dims[this.X], dims[this.Y], dims[this.W], dims[this.H], - this.legend._bgSettings); + this._wrapper.rect(g, dims[this.X], dims[this.Y], dims[this.W], dims[this.H], this.legend._bgSettings); var horiz = dims[this.W] > dims[this.H]; var numFn = this._functions.length; var offset = (horiz ? dims[this.W] : dims[this.H]) / numFn; @@ -439,7 +440,10 @@ $.extend(SVGPlot.prototype, { } }, - /* Show the current value status on hover. */ + /** Show the current value status on hover. + @private + @param elem {SVGElement} The current plot element. + @param label {string} The current status label. */ _showStatus: function(elem, label) { var status = this._onstatus; if (this._onstatus) { @@ -449,18 +453,22 @@ $.extend(SVGPlot.prototype, { } }); -/* Details about each plot function. - @param plot (SVGPlot) the owning plot - @param name (string) the name of this function (optional) - @param fn (function) the function to be plotted - @param range (number[2]) the range of values to be plotted (optional) - @param points (number) the number of points to plot within this range (optional) - @param stroke (string) the colour of the (out)line for the plot (optional) - @param strokeWidth (number) the width of the (out)line for the plot (optional) - @param settings (object) additional formatting settings (optional) - @return (SVGPlotFunction) the new plot function object */ +/** A plot function definition. + @module SVGPlotFunction */ + +/** Details about each plot function. +

Created through plot.addFunction().

+ @param plot {SVGPlot} The owning plot. + @param [name] {string} The name of this function. + @param fn {function} The function to be plotted. + @param [range] {number[]} The range of values to be plotted. + @param [points] {number} The number of points to plot within this range. + @param [stroke] {string} The colour of the (out)line for the plot. + @param [strokeWidth] {number} The width of the (out)line for the plot. + @param [settings] {object} Additional settings for the plotted values. + @return {SVGPlotFunction} The new plot function object. */ function SVGPlotFunction(plot, name, fn, range, points, stroke, strokeWidth, settings) { - if (typeof name != 'string') { + if (typeof name !== 'string') { settings = strokeWidth; strokeWidth = stroke; stroke = points; @@ -469,25 +477,25 @@ function SVGPlotFunction(plot, name, fn, range, points, stroke, strokeWidth, set fn = name; name = null; } - if (!isArray(range)) { + if (!$.isArray(range)) { settings = strokeWidth; strokeWidth = stroke; stroke = points; points = range; range = null; } - if (typeof points != 'number') { + if (typeof points !== 'number') { settings = strokeWidth; strokeWidth = stroke; stroke = points; points = null; } - if (typeof stroke != 'string') { + if (typeof stroke !== 'string') { settings = strokeWidth; strokeWidth = stroke; stroke = null; } - if (typeof strokeWidth != 'number') { + if (typeof strokeWidth !== 'number') { settings = strokeWidth; strokeWidth = null; } @@ -503,12 +511,11 @@ function SVGPlotFunction(plot, name, fn, range, points, stroke, strokeWidth, set $.extend(SVGPlotFunction.prototype, { - /* Set or retrieve the name for this function. - @param name (string) the function's name - @return (SVGPlotFunction) this plot function object or - (string) the function name (if no parameters) */ + /** Set or retrieve the name for this function. + @param name {string} The function's name. + @return {SVGPlotFunction|string} This plot function object or the function name (if no parameters). */ name: function(name) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._name; } this._name = name; @@ -516,16 +523,15 @@ $.extend(SVGPlotFunction.prototype, { return this; }, - /* Set or retrieve the function to be plotted. - @param name (string) the function's name (optional) - @param fn (function) the function to be ploted - @return (SVGPlotFunction) this plot function object or - (function) the actual function (if no parameters) */ + /** Set or retrieve the function to be plotted. + @param [name] {string} The function's name. + @param fn {function} The function to be ploted. + @return {SVGPlotFunction|function} This plot function object or the actual function (if no parameters). */ fn: function(name, fn) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._fn; } - if (typeof name == 'function') { + if (typeof name === 'function') { fn = name; name = null; } @@ -535,13 +541,12 @@ $.extend(SVGPlotFunction.prototype, { return this; }, - /* Set or retrieve the range of values to be plotted. - @param min (number) the minimum value to be plotted - @param max (number) the maximum value to be plotted - @return (SVGPlotFunction) this plot function object or - (number[2]) the value range (if no parameters) */ + /** Set or retrieve the range of values to be plotted. + @param min {number} The minimum value to be plotted. + @param max {number} The maximum value to be plotted. + @return {SVGPlotFunction|number[]} This plot function object or the value range (if no parameters). */ range: function(min, max) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._range; } this._range = (min == null ? null : [min, max]); @@ -549,12 +554,11 @@ $.extend(SVGPlotFunction.prototype, { return this; }, - /* Set or retrieve the number of points to be plotted. - @param value (number) the number of points to plot - @return (SVGPlotFunction) this plot function object or - (number) the number of points (if no parameters) */ + /** Set or retrieve the number of points to be plotted. + @param value {number} The number of points to plot. + @return {SVGPlotFunction|number} This plot function object or the number of points (if no parameters). */ points: function(value) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._points; } this._points = value; @@ -562,18 +566,16 @@ $.extend(SVGPlotFunction.prototype, { return this; }, - /* Set or retrieve the formatting for this function. - @param stroke (string) the (out)line colour - @param strokeWidth (number) the line's width (optional) - @param settings (object) additional formatting settings for the function (optional) - @return (SVGPlotFunction) this plot function object or - (object) formatting settings (if no parameters) */ + /** Set or retrieve the formatting for this function. + @param stroke {string} The (out)line colour. + @param [strokeWidth] {number} The line's width. + @param [settings] {object} Additional formatting settings for the function. + @return {SVGPlotFunction|object} This plot function object or formatting settings (if no parameters). */ format: function(stroke, strokeWidth, settings) { - if (arguments.length == 0) { - return $.extend({stroke: this._stroke, - strokeWidth: this._strokeWidth}, this._settings); + if (arguments.length === 0) { + return $.extend({stroke: this._stroke, strokeWidth: this._strokeWidth}, this._settings); } - if (typeof strokeWidth != 'number') { + if (typeof strokeWidth !== 'number') { settings = strokeWidth; strokeWidth = null; } @@ -584,7 +586,8 @@ $.extend(SVGPlotFunction.prototype, { return this; }, - /* Return to the parent plot. */ + /** Return to the parent plot. + @return {SVGPlot} The parent plot. */ end: function() { return this._plot; } @@ -597,14 +600,18 @@ function identity(x) { return x; } -/* Details about each plot axis. - @param plot (SVGPlot) the owning plot - @param title (string) the title of the axis - @param min (number) the minimum value displayed on this axis - @param max (number) the maximum value displayed on this axis - @param major (number) the distance between major ticks - @param minor (number) the distance between minor ticks (optional) - @return (SVGPlotAxis) the new axis object */ +/** A plot axis definition. + @module SVGPlotAxis */ + +/** Details about each plot axis. +

Accessed through plot.xAxis or plot.yAxis.

+ @param plot {SVGPlot} The owning plot. + @param title {string} The title of the axis. + @param min {number} The minimum value displayed on this axis. + @param max {number} The maximum value displayed on this axis. + @param major {number} The distance between major ticks. + @param [minor] {number} The distance between minor ticks. + @return {SVGPlotAxis} The new plot axis object. */ function SVGPlotAxis(plot, title, min, max, major, minor) { this._plot = plot; // The owning plot this._title = title || ''; // The plot's title @@ -619,13 +626,12 @@ function SVGPlotAxis(plot, title, min, max, major, minor) { $.extend(SVGPlotAxis.prototype, { - /* Set or retrieve the scale for this axis. - @param min (number) the minimum value shown - @param max (number) the maximum value shown - @return (SVGPlotAxis) this axis object or - (object) min and max values (if no parameters) */ + /** Set or retrieve the scale for this axis. + @param min {number} The minimum value shown. + @param max {number} The maximum value shown. + @return {SVGPlotAxis|object} This axis object or min and max values (if no parameters). */ scale: function(min, max) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._scale; } this._scale.min = min; @@ -634,19 +640,17 @@ $.extend(SVGPlotAxis.prototype, { return this; }, - /* Set or retrieve the ticks for this axis. - @param major (number) the distance between major ticks - @param minor (number) the distance between minor ticks - @param size (number) the length of the major ticks (minor are half) (optional) - @param position (string) the location of the ticks: - 'nw', 'se', 'both' (optional) - @return (SVGPlotAxis) this axis object or - (object) major, minor, size, and position values (if no parameters) */ + /** Set or retrieve the ticks for this axis. + @param major {number} The distance between major ticks. + @param minor {number} The distance between minor ticks. + @param [size] {number} The length of the major ticks (minor are half). + @param [position] {string} The location of the ticks: 'nw', 'se', 'both'. + @return {SVGPlotAxis|object} This axis object or major, minor, size, and position values (if no parameters). */ ticks: function(major, minor, size, position) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._ticks; } - if (typeof size == 'string') { + if (typeof size === 'string') { position = size; size = null; } @@ -658,23 +662,22 @@ $.extend(SVGPlotAxis.prototype, { return this; }, - /* Set or retrieve the title for this axis. - @param title (string) the title text - @param offset (number) the distance to offset the title position (optional) - @param colour (string) how to colour the title (optional) - @param format (object) formatting settings for the title (optional) - @return (SVGPlotAxis) this axis object or - (object) title, offset, and format values (if no parameters) */ + /** Set or retrieve the title for this axis. + @param title {string} The title text + @param [offset] {number} The distance to offset the title position. + @param [colour] {string} How to colour the title. + @param [format] {object} Formatting settings for the title. + @return {SVGPlotAxis|object} This axis object or title, offset, and format values (if no parameters). */ title: function(title, offset, colour, format) { - if (arguments.length == 0) { + if (arguments.length === 0) { return {title: this._title, offset: this._titleOffset, format: this._titleFormat}; } - if (typeof offset != 'number') { + if (typeof offset !== 'number') { format = colour; colour = offset; offset = null; } - if (typeof colour != 'string') { + if (typeof colour !== 'string') { format = colour; colour = null; } @@ -687,16 +690,15 @@ $.extend(SVGPlotAxis.prototype, { return this; }, - /* Set or retrieve the label format for this axis. - @param colour (string) how to colour the labels (optional) - @param format (object) formatting settings for the labels (optional) - @return (SVGPlotAxis) this axis object or - (object) format values (if no parameters) */ + /** Set or retrieve the label format for this axis. + @param [colour] {string} How to colour the labels. + @param [format] {object} Formatting settings for the labels. + @return {SVGPlotAxis|object} This axis object or format values (if no parameters). */ format: function(colour, format) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._labelFormat; } - if (typeof colour != 'string') { + if (typeof colour !== 'string') { format = colour; colour = null; } @@ -705,37 +707,40 @@ $.extend(SVGPlotAxis.prototype, { return this; }, - /* Set or retrieve the line formatting for this axis. - @param colour (string) the line's colour - @param width (number) the line's width (optional) - @param settings (object) additional formatting settings for the line (optional) - @return (SVGPlotAxis) this axis object or - (object) line formatting values (if no parameters) */ + /** Set or retrieve the line formatting for this axis. + @param colour {string} The line's colour. + @param [width] {number} The line's width. + @param [settings] {object} Additional formatting settings for the line. + @return {SVGPlotAxis|object} This axis object or line formatting values (if no parameters). */ line: function(colour, width, settings) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._lineFormat; } - if (typeof width != 'number') { + if (typeof width !== 'number') { settings = width; width = null; } - $.extend(this._lineFormat, {stroke: colour, strokeWidth: - width || this._lineFormat.strokeWidth}, settings || {}); + $.extend(this._lineFormat, {stroke: colour, strokeWidth: width || this._lineFormat.strokeWidth}, settings || {}); this._plot._drawPlot(); return this; }, - /* Return to the parent plot. */ + /** Return to the parent plot. + @return {SVGPlot} The parent plot. */ end: function() { return this._plot; } }); -/* Details about the plot legend. - @param plot (SVGPlot) the owning plot - @param bgSettings (object) additional formatting settings for the legend background (optional) - @param textSettings (object) additional formatting settings for the legend text (optional) - @return (SVGPlotLegend) the new legend object */ +/** A plot legend definition. + @module SVGPlotLegend */ + +/** Details about each plot legend. +

Accessed through plot.legend.

+ @param plot {SVGPlot} The owning plot. + @param [bgSettings] {object} Additional formatting settings for the legend background. + @param [textSettings] {object} Additional formatting settings for the legend text. + @return {SVGPlotLegend} The new plot legend object. */ function SVGPlotLegend(plot, bgSettings, textSettings) { this._plot = plot; // The owning plot this._show = true; // Show the legend? @@ -748,12 +753,11 @@ function SVGPlotLegend(plot, bgSettings, textSettings) { $.extend(SVGPlotLegend.prototype, { - /* Set or retrieve whether the legend should be shown. - @param show (boolean) true to display it, false to hide it - @return (SVGPlotLegend) this legend object or - (boolean) show the legend? (if no parameters) */ + /** Set or retrieve whether the legend should be shown. + @param show {boolean} true to display it, false to hide it. + @return {SVGPlotLegend|boolean} This legend object or show the legend? (if no parameters) */ show: function(show) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._show; } this._show = show; @@ -761,35 +765,33 @@ $.extend(SVGPlotLegend.prototype, { return this; }, - /* Set or retrieve the legend area. - @param left (number) > 1 is pixels, <= 1 is proportion of width or - (number[4]) for left, top, right, bottom - @param top (number) > 1 is pixels, <= 1 is proportion of height - @param right (number) > 1 is pixels, <= 1 is proportion of width - @param bottom (number) > 1 is pixels, <= 1 is proportion of height - @return (SVGPlotLegend) this legend object or - (number[4]) the legend area: left, top, right, bottom (if no parameters) */ + /** Set or retrieve the legend area. + @param left {number|number[]} > 1 is pixels, <= 1 is proportion of width or array for left, top, right, bottom. + @param [top] {number} > 1 is pixels, <= 1 is proportion of height. + @param [right] {number} > 1 is pixels, <= 1 is proportion of width. + @param [bottom] {number} > 1 is pixels, <= 1 is proportion of height. + @return {SVGPlotLegend|number[]} This legend object or the legend area: + left, top, right, bottom (if no parameters). */ area: function(left, top, right, bottom) { - if (arguments.length == 0) { + if (arguments.length === 0) { return this._area; } - this._area = (isArray(left) ? left : [left, top, right, bottom]); + this._area = ($.isArray(left) ? left : [left, top, right, bottom]); this._plot._drawPlot(); return this; }, - /* Set or retrieve additional settings for the legend area. - @param sampleSize (number) the size of the sample box to display (optional) - @param bgSettings (object) additional formatting settings for the legend background - @param textSettings (object) additional formatting settings for the legend text (optional) - @return (SVGPlotLegend) this legend object or - (object) bgSettings and textSettings for the legend (if no parameters) */ + /** Set or retrieve additional settings for the legend area. + @param [sampleSize] {number} The size of the sample box to display. + @param bgSettings {object} Additional formatting settings for the legend background. + @param [textSettings] {object} Additional formatting settings for the legend text. + @return {SVGPlotLegend|object} This legend object or + bgSettings and textSettings for the legend (if no parameters). */ settings: function(sampleSize, bgSettings, textSettings) { - if (arguments.length == 0) { - return {sampleSize: this._sampleSize, bgSettings: this._bgSettings, - textSettings: this._textSettings}; + if (arguments.length === 0) { + return {sampleSize: this._sampleSize, bgSettings: this._bgSettings, textSettings: this._textSettings}; } - if (typeof sampleSize == 'object') { + if (typeof sampleSize === 'object') { textSettings = bgSettings; bgSettings = sampleSize; sampleSize = null; @@ -801,17 +803,11 @@ $.extend(SVGPlotLegend.prototype, { return this; }, - /* Return to the parent plot. */ + /** Return to the parent plot. + @return {SVGPlot} The parent plot. */ end: function() { return this._plot; } }); -//============================================================================== - -/* Determine whether an object is an array. */ -function isArray(a) { - return (a && a.constructor == Array); -} - })(jQuery) diff --git a/jquery.svgplot.min.js b/jquery.svgplot.min.js index 78d9f39..dc47017 100644 --- a/jquery.svgplot.min.js +++ b/jquery.svgplot.min.js @@ -1,7 +1,6 @@ -/* http://keith-wood.name/svg.html - SVG plotting extension for jQuery v1.4.5. +/* http://keith-wood.name/svg.html + SVG plotting extension for jQuery v1.5.0. Written by Keith Wood (kbwood{at}iinet.com.au) December 2008. - Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and - MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. + Available under the MIT (http://keith-wood.name/licence.html) license. Please attribute the author if you use it. */ -(function($){$.svg.addExtension('plot',SVGPlot);function SVGPlot(a){this._wrapper=a;this._drawNow=false;this._title={value:'',offset:25,settings:{textAnchor:'middle'}};this._area=[0.1,0.1,0.8,0.9];this._areaFormat={fill:'none',stroke:'black'};this._gridlines=[];this._equalXY=true;this._functions=[];this._onstatus=null;this._uuid=new Date().getTime();this._plotCont=this._wrapper.svg(0,0,0,0,{class_:'svg-plot'});this.xAxis=new SVGPlotAxis(this);this.xAxis.title('X',20);this.yAxis=new SVGPlotAxis(this);this.yAxis.title('Y',20);this.legend=new SVGPlotLegend(this);this._drawNow=true}$.extend(SVGPlot.prototype,{X:0,Y:1,W:2,H:3,L:0,T:1,R:2,B:3,container:function(a){if(arguments.length==0){return this._plotCont}this._plotCont=a;return this},area:function(a,b,c,d){if(arguments.length==0){return this._area}this._area=(isArray(a)?a:[a,b,c,d]);this._drawPlot();return this},format:function(a,b,c){if(arguments.length==0){return this._areaFormat}if(typeof b=='object'){c=b;b=null}this._areaFormat=$.extend({fill:a},(b?{stroke:b}:{}),c||{});this._drawPlot();return this},gridlines:function(a,b){if(arguments.length==0){return this._gridlines}this._gridlines=[(typeof a=='string'?{stroke:a}:a),(typeof b=='string'?{stroke:b}:b)];if(this._gridlines[0]==null&&this._gridlines[1]==null){this._gridlines=[]}this._drawPlot();return this},equalXY:function(a){if(arguments.length==0){return this._equalXY}this._equalXY=a;return this},title:function(a,b,c,d){if(arguments.length==0){return this._title}if(typeof b!='number'){d=c;c=b;b=null}if(typeof c!='string'){d=c;c=null}this._title={value:a,offset:b||this._title.offset,settings:$.extend({textAnchor:'middle'},(c?{fill:c}:{}),d||{})};this._drawPlot();return this},addFunction:function(a,b,c,d,e,f,g){this._functions.push(new SVGPlotFunction(this,a,b,c,d,e,f,g));this._drawPlot();return this},functions:function(i){return(arguments.length>0?this._functions[i]:null)||this._functions},noDraw:function(){this._drawNow=false;return this},redraw:function(){this._drawNow=true;this._drawPlot();return this},status:function(a){this._onstatus=a;return this},_drawPlot:function(){if(!this._drawNow){return}while(this._plotCont.firstChild){this._plotCont.removeChild(this._plotCont.firstChild)}if(!this._plotCont.parent){this._wrapper._svg.appendChild(this._plotCont)}if(!this._plotCont.width){this._plotCont.setAttribute('width',parseInt(this._plotCont.getAttribute('width'),10)||this._wrapper._width())}else if(this._plotCont.width.baseVal){this._plotCont.width.baseVal.value=this._plotCont.width.baseVal.value||this._wrapper._width()}else{this._plotCont.width=this._plotCont.width||this._wrapper._width()}if(!this._plotCont.height){this._plotCont.setAttribute('height',parseInt(this._plotCont.getAttribute('height'),10)||this._wrapper._height())}else if(this._plotCont.height.baseVal){this._plotCont.height.baseVal.value=this._plotCont.height.baseVal.value||this._wrapper._height()}else{this._plotCont.height=this._plotCont.height||this._wrapper._height()}this._drawChartBackground();var a=this._getDims();var b=this._wrapper.other(this._plotCont,'clipPath',{id:'clip'+this._uuid});this._wrapper.rect(b,a[this.X],a[this.Y],a[this.W],a[this.H]);this._plot=this._wrapper.group(this._plotCont,{class_:'foreground',clipPath:'url(#clip'+this._uuid+')'});this._drawAxis(true);this._drawAxis(false);for(var i=0;i1?a[this.L]:c*a[this.L]);var f=(a[this.T]>1?a[this.T]:d*a[this.T]);var g=(a[this.R]>1?a[this.R]:c*a[this.R])-e;var h=(a[this.B]>1?a[this.B]:d*a[this.B])-f;if(this._equalXY&&!b){var i=Math.min(g/(this.xAxis._scale.max-this.xAxis._scale.min),h/(this.yAxis._scale.max-this.yAxis._scale.min));g=i*(this.xAxis._scale.max-this.xAxis._scale.min);h=i*(this.yAxis._scale.max-this.yAxis._scale.min)}return[e,f,g,h]},_getScales:function(){var a=this._getDims();return[a[this.W]/(this.xAxis._scale.max-this.xAxis._scale.min),a[this.H]/(this.yAxis._scale.max-this.yAxis._scale.min)]},_drawChartBackground:function(a,b){var c=this._wrapper.group(this._plotCont,{class_:'background'});var d=this._getDims();this._wrapper.rect(c,d[this.X],d[this.Y],d[this.W],d[this.H],this._areaFormat);if(this._gridlines[0]&&this.yAxis._ticks.major&&!b){this._drawGridlines(c,true,this._gridlines[0],d)}if(this._gridlines[1]&&this.xAxis._ticks.major&&!a){this._drawGridlines(c,false,this._gridlines[1],d)}return c},_drawGridlines:function(a,b,c,d){var g=this._wrapper.group(a,c);var e=(b?this.yAxis:this.xAxis);var f=this._getScales();var h=Math.floor(e._scale.min/e._ticks.major)*e._ticks.major;h+=(h<=e._scale.min?e._ticks.major:0);while(hthis.xAxis._scale.max+g){break}if(xa[this.H];var c=this._functions.length;var d=(b?a[this.W]:a[this.H])/c;var e=a[this.X]+5;var f=a[this.Y]+((b?a[this.H]:d)+this.legend._sampleSize)/2;for(var i=0;i0?this._functions[i]:null)||this._functions},noDraw:function(){this._drawNow=false;return this},redraw:function(){this._drawNow=true;this._drawPlot();return this},status:function(a){this._onstatus=a;return this},_drawPlot:function(){if(!this._drawNow){return}while(this._plotCont.firstChild){this._plotCont.removeChild(this._plotCont.firstChild)}if(!this._plotCont.parent){this._wrapper._svg.appendChild(this._plotCont)}if(!this._plotCont.width){this._plotCont.setAttribute('width',parseInt(this._plotCont.getAttribute('width'),10)||this._wrapper.width())}else if(this._plotCont.width.baseVal){this._plotCont.width.baseVal.value=this._plotCont.width.baseVal.value||this._wrapper.width()}else{this._plotCont.width=this._plotCont.width||this._wrapper.width()}if(!this._plotCont.height){this._plotCont.setAttribute('height',parseInt(this._plotCont.getAttribute('height'),10)||this._wrapper.height())}else if(this._plotCont.height.baseVal){this._plotCont.height.baseVal.value=this._plotCont.height.baseVal.value||this._wrapper.height()}else{this._plotCont.height=this._plotCont.height||this._wrapper.height()}this._drawChartBackground();var a=this._getDims();var b=this._wrapper.other(this._plotCont,'clipPath',{id:'clip'+this._uuid});this._wrapper.rect(b,a[this.X],a[this.Y],a[this.W],a[this.H]);this._plot=this._wrapper.group(this._plotCont,{class_:'foreground',clipPath:'url(#clip'+this._uuid+')'});this._drawAxis(true);this._drawAxis(false);for(var i=0;i1?a[this.L]:c*a[this.L]);var f=(a[this.T]>1?a[this.T]:d*a[this.T]);var g=(a[this.R]>1?a[this.R]:c*a[this.R])-e;var h=(a[this.B]>1?a[this.B]:d*a[this.B])-f;if(this._equalXY&&!b){var i=Math.min(g/(this.xAxis._scale.max-this.xAxis._scale.min),h/(this.yAxis._scale.max-this.yAxis._scale.min));g=i*(this.xAxis._scale.max-this.xAxis._scale.min);h=i*(this.yAxis._scale.max-this.yAxis._scale.min)}return[e,f,g,h]},_getScales:function(){var a=this._getDims();return[a[this.W]/(this.xAxis._scale.max-this.xAxis._scale.min),a[this.H]/(this.yAxis._scale.max-this.yAxis._scale.min)]},_drawChartBackground:function(a,b){var c=this._wrapper.group(this._plotCont,{class_:'background'});var d=this._getDims();this._wrapper.rect(c,d[this.X],d[this.Y],d[this.W],d[this.H],this._areaFormat);if(this._gridlines[0]&&this.yAxis._ticks.major&&!b){this._drawGridlines(c,true,this._gridlines[0],d)}if(this._gridlines[1]&&this.xAxis._ticks.major&&!a){this._drawGridlines(c,false,this._gridlines[1],d)}return c},_drawGridlines:function(a,b,c,d){var g=this._wrapper.group(a,c);var e=(b?this.yAxis:this.xAxis);var f=this._getScales();var h=Math.floor(e._scale.min/e._ticks.major)*e._ticks.major;h+=(h<=e._scale.min?e._ticks.major:0);while(hthis.xAxis._scale.max+g){break}if(xa[this.H];var c=this._functions.length;var d=(b?a[this.W]:a[this.H])/c;var e=a[this.X]+5;var f=a[this.Y]+((b?a[this.H]:d)+this.legend._sampleSize)/2;for(var i=0;i35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(r($){$.1S.2r(\'2a\',1T);r 1T(a){4.u=a;4.1i=1j;4.M={11:\'\',1k:25,1z:{1l:\'1A\'}};4.12=[0.1,0.1,0.8,0.9];4.1B={17:\'2b\',U:\'1U\'};4.Q=[];4.1C=18;4.13=[];4.1D=z;4.1V=1m 2s().2t();4.t=4.u.1S(0,0,0,0,{19:\'1S-2a\'});4.G=1m 1E(4);4.G.1n(\'X\',20);4.N=1m 1E(4);4.N.1n(\'Y\',20);4.P=1m 1W(4);4.1i=18}$.K(1T.1F,{X:0,Y:1,W:2,H:3,L:0,T:1,R:2,B:3,2u:r(a){7(E.D==0){q 4.t}4.t=a;q 4},2c:r(a,b,c,d){7(E.D==0){q 4.12}4.12=(1G(a)?a:[a,b,c,d]);4.F();q 4},1H:r(a,b,c){7(E.D==0){q 4.1B}7(I b==\'2d\'){c=b;b=z}4.1B=$.K({17:a},(b?{U:b}:{}),c||{});4.F();q 4},2v:r(a,b){7(E.D==0){q 4.Q}4.Q=[(I a==\'14\'?{U:a}:a),(I b==\'14\'?{U:b}:b)];7(4.Q[0]==z&&4.Q[1]==z){4.Q=[]}4.F();q 4},2w:r(a){7(E.D==0){q 4.1C}4.1C=a;q 4},1n:r(a,b,c,d){7(E.D==0){q 4.M}7(I b!=\'1e\'){d=c;c=b;b=z}7(I c!=\'14\'){d=c;c=z}4.M={11:a,1k:b||4.M.1k,1z:$.K({1l:\'1A\'},(c?{17:c}:{}),d||{})};4.F();q 4},2x:r(a,b,c,d,e,f,g){4.13.2y(1m 1X(4,a,b,c,d,e,f,g));4.F();q 4},2z:r(i){q(E.D>0?4.13[i]:z)||4.13},2A:r(){4.1i=1j;q 4},2B:r(){4.1i=18;4.F();q 4},2C:r(a){4.1D=a;q 4},F:r(){7(!4.1i){q}1Y(4.t.2e){4.t.2D(4.t.2e)}7(!4.t.2E){4.u.2F.2G(4.t)}7(!4.t.S){4.t.2f(\'S\',1Z(4.t.21(\'S\'),10)||4.u.22())}1o 7(4.t.S.16){4.t.S.16.11=4.t.S.16.11||4.u.22()}1o{4.t.S=4.t.S||4.u.22()}7(!4.t.V){4.t.2f(\'V\',1Z(4.t.21(\'V\'),10)||4.u.23())}1o 7(4.t.V.16){4.t.V.16.11=4.t.V.16.11||4.u.23()}1o{4.t.V=4.t.V||4.u.23()}4.2g();6 a=4.1a();6 b=4.u.2H(4.t,\'2h\',{2I:\'2i\'+4.1V});4.u.1I(b,a[4.X],a[4.Y],a[4.W],a[4.H]);4.A=4.u.1f(4.t,{19:\'2J\',2h:\'2K(#2i\'+4.1V+\')\'});4.24(18);4.24(1j);26(6 i=0;i<4.13.D;i++){4.2j(4.13[i],i)}4.2k();4.2l()},1J:r(a,b){q(!a[b]?1Z(a.21(b),10):(a[b].16?a[b].16.11:a[b]))},1a:r(a){6 b=(a!=z);a=a||4.12;6 c=4.1J(4.t,\'S\');6 d=4.1J(4.t,\'V\');6 e=(a[4.L]>1?a[4.L]:c*a[4.L]);6 f=(a[4.T]>1?a[4.T]:d*a[4.T]);6 g=(a[4.R]>1?a[4.R]:c*a[4.R])-e;6 h=(a[4.B]>1?a[4.B]:d*a[4.B])-f;7(4.1C&&!b){6 i=1p.C(g/(4.G.s.J-4.G.s.C),h/(4.N.s.J-4.N.s.C));g=i*(4.G.s.J-4.G.s.C);h=i*(4.N.s.J-4.N.s.C)}q[e,f,g,h]},1K:r(){6 a=4.1a();q[a[4.W]/(4.G.s.J-4.G.s.C),a[4.H]/(4.N.s.J-4.N.s.C)]},2g:r(a,b){6 c=4.u.1f(4.t,{19:\'2L\'});6 d=4.1a();4.u.1I(c,d[4.X],d[4.Y],d[4.W],d[4.H],4.1B);7(4.Q[0]&&4.N.w.O&&!b){4.27(c,18,4.Q[0],d)}7(4.Q[1]&&4.G.w.O&&!a){4.27(c,1j,4.Q[1],d)}q c},27:r(a,b,c,d){6 g=4.u.1f(a,c);6 e=(b?4.N:4.G);6 f=4.1K();6 h=1p.28(e.s.C/e.w.O)*e.w.O;h+=(h<=e.s.C?e.w.O:0);1Y(h4.G.s.J+g){2R}7(x<4.G.s.C-g){2S}6 j=(x-4.G.s.C)*d[0]+c[4.X];6 k=c[4.H]-((a.1O(x)-4.N.s.C)*d[1])+c[4.Y];e[(h?\'2T\':\'1q\')+\'2U\'](j,k);h=1j}6 p=4.u.2V(4.A,e,$.K({19:\'2m\'+b,17:\'2b\',U:a.1h,1w:a.1x},a.1P||{}));4.2n(p,a.1d)},2k:r(){4.u.1t(4.t,4.1J(4.t,\'S\')/2,4.M.1k,4.M.11,4.M.1z)},2l:r(){7(!4.P.1Q){q}6 g=4.u.1f(4.t,{19:\'P\'});6 a=4.1a(4.P.12);4.u.1I(g,a[4.X],a[4.Y],a[4.W],a[4.H],4.P.1R);6 b=a[4.W]>a[4.H];6 c=4.13.D;6 d=(b?a[4.W]:a[4.H])/c;6 e=a[4.X]+5;6 f=a[4.Y]+((b?a[4.H]:d)+4.P.Z)/2;26(6 i=0;i=1.7" + } +} \ No newline at end of file diff --git a/svgBasic.html b/svgBasic.html index e57edca..9f5e866 100644 --- a/svgBasic.html +++ b/svgBasic.html @@ -1,16 +1,15 @@ - + jQuery SVG Basics - - - - + +