Nick Frev Nick Frev - 2 months ago 9
HTML Question

Moving svg:svg is not working

I'm having trouble moving an svg that is inside another svg. I would like to directly effect the x and y value but I get a "read-only" error. Then I tried to use transform however it doesn't do anything. I'm currently using Chrome to test.

Code:
http://jsfiddle.net/un6ep/68/

"use strict";

function SVGGraph(div, data, pos) {
this.div = (div===undefined)?document.getElementsByTagName("BODY")[0]:div;
this.data = (data===undefined)?[]:data;
this.children = [];
this.width = 100;
this.height = 100;

this.pos = {x:0,y:0};
this.scale = 1;
this.rotation = 0;

this.ns = "http://www.w3.org/2000/svg";

/////////////////////////////////////////////////////////
//Functions to set the display the information to the user
/////////////////////////////////////////////////////////
this.generateSelf = function() {
var line = document.createElementNS(this.ns, 'path');
var start = {x:0,y:0}
var end = {x:100,y:100}
var ctrl = 100;
line.setAttribute("d", "M"+start.x+","+start.y+" C"+(start.x+ctrl)+","+start.y+" "+(end.x-ctrl)+","+end.y+" "+end.x+","+end.y+"");
line.style.stroke = "#ff00ff";
line.style.fill = "none";
line.style.strokeWidth = "5px";

this.svg.appendChild(line);
}

/////////////////////////////////////////////////////////
//Functions to deal with child object
/////////////////////////////////////////////////////////
this.addChild = function(data) {
data = (data===undefined)?[]:data;
this.children.push(new SVGGraph(this.svg, data));
}

/////////////////////////////////////////////////////////
//Functions to set the properties of the svg
/////////////////////////////////////////////////////////
this.setPos = function(x, y) {
this.pos.x = x;
this.pos.y = y;
//I would like to do this.svg.x = <some number>
this.updateTransform();
}

this.updateTransform = function() {
console.log('translate('+this.pos.x+','+this.pos.y+')');
this.svg.setAttribute('transform','translate(50,50)');
//this.svg.setAttributeNS(this.ns,'transform','translate(50,50)');
}

/////////////////////////////////////////////////////////
//Init function
/////////////////////////////////////////////////////////
this.init = function() {
//create the svg area
this.svg = document.createElementNS(this.ns, 'svg');
if (this.div.nodeName.toLowerCase() != "svg") {//if the div is not a sub div then make it fill the space
this.svg.style.width = "100%";
this.svg.style.height = "100%";
}
this.svg.style.overflow = "visible";
this.div.appendChild(this.svg);
//generate what this looks like
this.generateSelf();
}
this.init();
}
var temp;
window.onload = mainInit;
function mainInit() {
console.log("hello");
temp = new SVGGraph();
temp.addChild();
temp.children[0].setPos(50,50)
}
mainInit()

Answer

As described here, transforms are not supported for svg elements.

But, in order to achieve what you need you will need to wrap everything in a g element (a group) and you can apply the transform to that:

...
var group = document.createElementNS(this.ns, 'g');
group.appendChild(line);
this.svg.appendChild(group);

and then when you set the transform

this.svg.children[0].setAttribute('transform','translate(50,50)');

Like this each SVG you create will have a group and the group will contains everything you need to be translated, and this group will alos support other kinds of transformations. http://jsfiddle.net/un6ep/69/

EDIT: Better you need to use this to work on IE ... seems that IE does not know children:

this.svg.childNodes[0].setAttribute('transform','translate(50,50)');

http://jsfiddle.net/un6ep/70/