SVGGraphic.js revision 66ca16dd76367c074fe4df1dcf7b555489a9bf85
4778ff543a041ac356d6e661cc9b66c3fafa2092Adam Moore/**
4778ff543a041ac356d6e661cc9b66c3fafa2092Adam Moore * Graphic is a simple drawing api that allows for basic drawing operations.
2c5ce90c334a2d0f18474e85c93b424b6ec9daaaAdam Moore *
4778ff543a041ac356d6e661cc9b66c3fafa2092Adam Moore * @module graphics
2c5ce90c334a2d0f18474e85c93b424b6ec9daaaAdam Moore * @class SVGGraphic
4778ff543a041ac356d6e661cc9b66c3fafa2092Adam Moore * @constructor
c4e6d94ea429e473a6732b6eb5e0fc980e822881Adam Moore */
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam MooreSVGGraphic = function(cfg) {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore SVGGraphic.superclass.constructor.apply(this, arguments);
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore};
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam MooreSVGGraphic.NAME = "svgGraphic";
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam MooreSVGGraphic.ATTRS = {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore render: {},
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore /**
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * Unique id for class instance.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore *
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @attribute id
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @type String
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore id: {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore valueFn: function()
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore return Y.guid();
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore },
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore setter: function(val)
16bec62f211cecacdbbc2cb4632f079ef8c7f936Adam Moore {
c7eb563867fa29409073f3b495a067d9afa00006Adam Moore var node = this._node;
16bec62f211cecacdbbc2cb4632f079ef8c7f936Adam Moore if(node)
16bec62f211cecacdbbc2cb4632f079ef8c7f936Adam Moore {
9fb523cf517ad4d6a53ae9f461d672cba63835d2Adam Moore node.setAttribute("id", val);
9fb523cf517ad4d6a53ae9f461d672cba63835d2Adam Moore }
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore return val;
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore }
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore },
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore /**
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * Key value pairs in which a shape instance is associated with its id.
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore *
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @attribute shapes
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * @type Object
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * @readOnly
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore */
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore shapes: {
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore readOnly: true,
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore
489c0c8e2523f1bcd1acee1173c6d85f6a7edd6aAdam Moore getter: function()
4390434761f176b0f8d7a71c00a6e0141aa1752cAdam Moore {
4390434761f176b0f8d7a71c00a6e0141aa1752cAdam Moore return this._shapes;
4390434761f176b0f8d7a71c00a6e0141aa1752cAdam Moore }
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore },
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore /**
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * Object containing size and coordinate data for the content of a Graphic in relation to the coordSpace node.
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore *
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * @attribute contentBounds
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * @type Object
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * @readOnly
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore */
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore contentBounds: {
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore readOnly: true,
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore getter: function()
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore {
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore return this._contentBounds;
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore }
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore },
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore /**
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * The html element that represents to coordinate system of the Graphic instance.
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore *
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * @attribute node
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * @type HTMLElement
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @readOnly
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore */
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore node: {
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore readOnly: true,
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore getter: function()
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore {
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore return this._node;
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore }
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore },
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore width: {
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore setter: function(val)
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore {
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore if(this._node)
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore {
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore this._node.style.width = val + "px";
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore }
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore return val;
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore }
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore },
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore height: {
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore setter: function(val)
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore {
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore if(this._node)
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore {
87b084086b5937585acc7e091b2f1951e94d9145Adam Moore this._node.style.height = val + "px";
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore }
16bec62f211cecacdbbc2cb4632f079ef8c7f936Adam Moore return val;
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore }
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore },
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore /**
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * Determines how the size of instance is calculated. If true, the width and height are determined by the size of the contents.
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * If false, the width and height values are either explicitly set or determined by the size of the parent node's dimensions.
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore *
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * @attribute autoSize
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * @type Boolean
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * @default false
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore */
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore autoSize: {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore value: false
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore },
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore /**
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * When overflow is set to true, by default, the contentBounds will resize to greater values but not to smaller values. (for performance)
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * When resizing the contentBounds down is desirable, set the resizeDown value to true.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore *
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @attribute resizeDown
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @type Boolean
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore resizeDown: {
16bec62f211cecacdbbc2cb4632f079ef8c7f936Adam Moore getter: function()
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore return this._resizeDown;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore },
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore setter: function(val)
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore this._resizeDown = val;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore this._redraw();
efa57736d44cf446f1661497a8645bd388b493fbAdam Moore return val;
efa57736d44cf446f1661497a8645bd388b493fbAdam Moore }
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore },
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore /**
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * Indicates the x-coordinate for the instance.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore *
ba2701ee03e94104edf19911ee0989f8cee11088Adam Moore * @attribute x
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @type Number
ba2701ee03e94104edf19911ee0989f8cee11088Adam Moore */
489c0c8e2523f1bcd1acee1173c6d85f6a7edd6aAdam Moore x: {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore getter: function()
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore return this._x;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore },
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
c4e6d94ea429e473a6732b6eb5e0fc980e822881Adam Moore setter: function(val)
23209f57fce338501bc1dc828a991d103732b92fAdam Moore {
23209f57fce338501bc1dc828a991d103732b92fAdam Moore this._x = val;
23209f57fce338501bc1dc828a991d103732b92fAdam Moore if(this._node)
23209f57fce338501bc1dc828a991d103732b92fAdam Moore {
23209f57fce338501bc1dc828a991d103732b92fAdam Moore this._node.style.left = val + "px";
23209f57fce338501bc1dc828a991d103732b92fAdam Moore }
23209f57fce338501bc1dc828a991d103732b92fAdam Moore return val;
23209f57fce338501bc1dc828a991d103732b92fAdam Moore }
23209f57fce338501bc1dc828a991d103732b92fAdam Moore },
23209f57fce338501bc1dc828a991d103732b92fAdam Moore
23209f57fce338501bc1dc828a991d103732b92fAdam Moore /**
23209f57fce338501bc1dc828a991d103732b92fAdam Moore * Indicates the y-coordinate for the instance.
23209f57fce338501bc1dc828a991d103732b92fAdam Moore *
23209f57fce338501bc1dc828a991d103732b92fAdam Moore * @attribute y
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore * @type Number
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore */
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore y: {
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore getter: function()
489c0c8e2523f1bcd1acee1173c6d85f6a7edd6aAdam Moore {
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore return this._y;
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore },
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore setter: function(val)
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore {
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore this._y = val;
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore if(this._node)
23209f57fce338501bc1dc828a991d103732b92fAdam Moore {
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore this._node.style.top = val + "px";
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore }
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore return val;
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore }
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore },
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore /**
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * Indicates whether or not the instance will automatically redraw after a change is made to a shape.
0dca577a07715960da42d47787eecc25b285182fAdam Moore * This property will get set to false when batching operations.
0dca577a07715960da42d47787eecc25b285182fAdam Moore *
0dca577a07715960da42d47787eecc25b285182fAdam Moore * @attribute autoDraw
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @type Boolean
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @default true
0dca577a07715960da42d47787eecc25b285182fAdam Moore * @private
0dca577a07715960da42d47787eecc25b285182fAdam Moore */
0dca577a07715960da42d47787eecc25b285182fAdam Moore autoDraw: {
0dca577a07715960da42d47787eecc25b285182fAdam Moore value: true
b9f576e4a859f38cf945d867cf23fdbb84347564Adam Moore },
b9f576e4a859f38cf945d867cf23fdbb84347564Adam Moore
b9f576e4a859f38cf945d867cf23fdbb84347564Adam Moore visible: {
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore value: true,
b9f576e4a859f38cf945d867cf23fdbb84347564Adam Moore
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore setter: function(val)
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore {
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore this._toggleVisible(val);
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore return val;
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore }
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore },
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore /**
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * Indicates the pointer-events setting for the svg:svg element.
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore *
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @attribute pointerEvents
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @type String
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore */
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore pointerEvents: {
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore value: "none"
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore }
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore};
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam MooreY.extend(SVGGraphic, Y.BaseGraphic, {
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore /**
b9f576e4a859f38cf945d867cf23fdbb84347564Adam Moore * @private
b9f576e4a859f38cf945d867cf23fdbb84347564Adam Moore */
b9f576e4a859f38cf945d867cf23fdbb84347564Adam Moore _x: 0,
b9f576e4a859f38cf945d867cf23fdbb84347564Adam Moore
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore /**
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @private
b9f576e4a859f38cf945d867cf23fdbb84347564Adam Moore */
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore _y: 0,
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore /**
9fb523cf517ad4d6a53ae9f461d672cba63835d2Adam Moore * Gets the current position of the graphic instance in page coordinates.
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore *
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @method getXY
9fb523cf517ad4d6a53ae9f461d672cba63835d2Adam Moore * @return Array The XY position of the shape.
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore */
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore getXY: function()
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore {
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore var node = Y.one(this._node),
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore xy;
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore if(node)
c4e6d94ea429e473a6732b6eb5e0fc980e822881Adam Moore {
xy = node.getXY();
}
return xy;
},
/**
* @private
* @property _resizeDown
* @type Boolean
*/
_resizeDown: false,
/**
* Initializes the class.
*
* @method initializer
* @private
*/
initializer: function() {
var render = this.get("render");
this._shapes = {};
this._contentBounds = {
left: 0,
top: 0,
right: 0,
bottom: 0
};
this._gradients = {};
this._node = DOCUMENT.createElement('div');
this._node.style.position = "absolute";
this._node.style.left = this.get("x") + "px";
this._node.style.top = this.get("y") + "px";
this._contentNode = this._createGraphics();
this._contentNode.setAttribute("id", this.get("id"));
this._node.appendChild(this._contentNode);
if(render)
{
this.render(render);
}
},
/**
* Adds the graphics node to the dom.
*
* @method render
* @param {HTMLElement} parentNode node in which to render the graphics node into.
*/
render: function(render) {
var parentNode = Y.one(render),
w = this.get("width") || parseInt(parentNode.getComputedStyle("width"), 10),
h = this.get("height") || parseInt(parentNode.getComputedStyle("height"), 10);
parentNode = parentNode || DOCUMENT.body;
parentNode.appendChild(this._node);
this.parentNode = parentNode;
this.set("width", w);
this.set("height", h);
this.parentNode = parentNode;
return this;
},
/**
* Removes all nodes.
*
* @method destroy
*/
destroy: function()
{
this.removeAllShapes();
this._removeChildren(this._node);
if(this._node && this._node.parentNode)
{
this._node.parentNode.removeChild(this._node);
}
},
/**
* Generates a shape instance by type.
*
* @method getShape
* @param {String} type type of shape to generate.
* @param {Object} cfg attributes for the shape
* @return Shape
*/
getShape: function(cfg)
{
cfg.graphic = this;
var shapeClass = this._getShapeClass(cfg.type),
shape = new shapeClass(cfg);
this.addShape(shape);
return shape;
},
/**
* Adds a shape instance to the graphic instance.
*
* @method addShape
* @param {Shape} shape The shape instance to be added to the graphic.
*/
addShape: function(shape)
{
var node = shape.node,
parentNode = this._frag || this._contentNode;
if(this.get("autoDraw"))
{
parentNode.appendChild(node);
}
else
{
this._getDocFrag().appendChild(node);
}
},
/**
* Removes a shape instance from from the graphic instance.
*
* @method removeShape
* @param {Shape|String} shape The instance or id of the shape to be removed.
*/
removeShape: function(shape)
{
if(!(shape instanceof SVGShape))
{
if(Y_LANG.isString(shape))
{
shape = this._shapes[shape];
}
}
if(shape && shape instanceof SVGShape)
{
shape.destroy();
delete this._shapes[shape.get("id")];
}
if(this.get("autoDraw"))
{
this._redraw();
}
return shape;
},
/**
* Removes all shape instances from the dom.
*
* @method removeAllShapes
*/
removeAllShapes: function()
{
var shapes = this._shapes,
i;
for(i in shapes)
{
if(shapes.hasOwnProperty(i))
{
shapes[i].destroy();
}
}
this._shapes = {};
},
/**
* Removes all child nodes.
*
* @method _removeChildren
* @param {HTMLElement} node
* @private
*/
_removeChildren: function(node)
{
if(node.hasChildNodes())
{
var child;
while(node.firstChild)
{
child = node.firstChild;
this._removeChildren(child);
node.removeChild(child);
}
}
},
/**
* Clears the graphics object.
*
* @method clear
*/
clear: function() {
this.removeAllShapes();
},
/**
* Toggles visibility
*
* @method _toggleVisible
* @param {Boolean} val indicates visibilitye
* @private
*/
_toggleVisible: function(val)
{
var i,
shapes = this._shapes,
visibility = val ? "visible" : "hidden";
if(shapes)
{
for(i in shapes)
{
if(shapes.hasOwnProperty(i))
{
shapes[i].set("visible", val);
}
}
}
this._contentNode.style.visibility = visibility;
this._node.style.visibility = visibility;
},
/**
* @private
*/
_getShapeClass: function(val)
{
var shape = this._shapeClass[val];
if(shape)
{
return shape;
}
return val;
},
/**
* @private
*/
_shapeClass: {
circle: Y.SVGCircle,
rect: Y.SVGRect,
path: Y.SVGPath,
ellipse: Y.SVGEllipse,
pieslice: Y.SVGPieSlice
},
/**
* Returns a shape based on the id of its dom node.
*
* @method getShapeById
* @param {String} id Dom id of the shape's node attribute.
* @return Shape
*/
getShapeById: function(id)
{
var shape = this._shapes[id];
return shape;
},
/**
* Allows for creating multiple shapes in order to batch appending and redraw operations.
*
* @method batch
* @param {Function} method Method to execute.
*/
batch: function(method)
{
var autoDraw = this.get("autoDraw");
this.set("autoDraw", false);
method();
this._redraw();
this.set("autoDraw", autoDraw);
},
_getDocFrag: function()
{
if(!this._frag)
{
this._frag = DOCUMENT.createDocumentFragment();
}
return this._frag;
},
_redraw: function()
{
var box = this.get("resizeDown") ? this._getUpdatedContentBounds() : this._contentBounds;
this._contentNode.style.left = box.left + "px";
this._contentNode.style.top = box.top + "px";
this._contentNode.setAttribute("width", box.width);
this._contentNode.setAttribute("height", box.height);
this._contentNode.style.width = box.width + "px";
this._contentNode.style.height = box.height + "px";
this._contentNode.setAttribute("viewBox", "" + box.left + " " + box.top + " " + box.width + " " + box.height + "");
if(this.get("autoSize"))
{
this.set("width", box.right);
this.set("height", box.bottom);
}
if(this._frag)
{
this._contentNode.appendChild(this._frag);
this._frag = null;
}
},
/**
* Adds a shape to the redraw queue and calculates the contentBounds.
*
* @method addToRedrawQueue
* @param shape {SVGShape}
*/
addToRedrawQueue: function(shape)
{
var shapeBox,
box;
this._shapes[shape.get("id")] = shape;
if(!this.get("resizeDown"))
{
shapeBox = shape.getBounds();
box = this._contentBounds;
box.left = box.left < shapeBox.left ? box.left : shapeBox.left;
box.top = box.top < shapeBox.top ? box.top : shapeBox.top;
box.right = box.right > shapeBox.right ? box.right : shapeBox.right;
box.bottom = box.bottom > shapeBox.bottom ? box.bottom : shapeBox.bottom;
box.width = box.right - box.left;
box.height = box.bottom - box.top;
this._contentBounds = box;
}
if(this.get("autoDraw"))
{
this._redraw();
}
},
_getUpdatedContentBounds: function()
{
var bounds,
i,
shape,
queue = this._shapes,
box = {
left: 0,
top: 0,
right: 0,
bottom: 0
};
for(i in queue)
{
if(queue.hasOwnProperty(i))
{
shape = queue[i];
bounds = shape.getBounds();
box.left = Math.min(box.left, bounds.left);
box.top = Math.min(box.top, bounds.top);
box.right = Math.max(box.right, bounds.right);
box.bottom = Math.max(box.bottom, bounds.bottom);
}
}
box.width = box.right - box.left;
box.height = box.bottom - box.top;
this._contentBounds = box;
return box;
},
/**
* Creates a contentNode element
*
* @method _createGraphics
* @private
*/
_createGraphics: function() {
var contentNode = this._createGraphicNode("svg"),
pointerEvents = this.get("pointerEvents");
contentNode.style.position = "absolute";
contentNode.style.top = "px";
contentNode.style.left = "0px";
contentNode.style.overflow = "auto";
contentNode.setAttribute("overflow", "auto");
contentNode.setAttribute("pointer-events", pointerEvents);
return contentNode;
},
/**
* Creates a graphic node
*
* @method _createGraphicNode
* @param {String} type node type to create
* @param {String} pe specified pointer-events value
* @return HTMLElement
* @private
*/
_createGraphicNode: function(type, pe)
{
var node = DOCUMENT.createElementNS("http://www.w3.org/2000/svg", "svg:" + type),
v = pe || "none";
if(type !== "defs" && type !== "stop" && type !== "linearGradient" && type != "radialGradient")
{
node.setAttribute("pointer-events", v);
}
return node;
},
/**
* Returns a reference to a gradient definition based on an id and type.
*
* @method getGradientNode
* @param {String} key id that references the gradient definition
* @param {String} type description of the gradient type
* @return HTMLElement
*/
getGradientNode: function(key, type)
{
var gradients = this._gradients,
gradient,
nodeType = type + "Gradient";
if(gradients.hasOwnProperty(key) && gradients[key].tagName.indexOf(type) > -1)
{
gradient = this._gradients[key];
}
else
{
gradient = this._createGraphicNode(nodeType);
if(!this._defs)
{
this._defs = this._createGraphicNode("defs");
this._contentNode.appendChild(this._defs);
}
this._defs.appendChild(gradient);
key = key || "gradient" + Math.round(100000 * Math.random());
gradient.setAttribute("id", key);
if(gradients.hasOwnProperty(key))
{
this._defs.removeChild(gradients[key]);
}
gradients[key] = gradient;
}
return gradient;
}
});
Y.SVGGraphic = SVGGraphic;