I have not been able to show the tooltip for this graph:
http://mbostock.github.io/d3/talk/20111018/cluster.html
I have tried the simplest way without success:
node.append("svg:title").text(function(d) { return d.key; });
And also tried this without success:
var div = d3.select("body").append("div").attr("class", "tooltip")
.style("opacity", 0);
node.append("svg:circle")
.attr("r", 3)
.on("mouseover", function (d) {
div.transition()
.duration(0)
div.style("opacity", 1)
div.html(d.key)
.style("width", d.key.length + "mm")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function (d) {
div.transition()
.duration(0)
.style("opacity", 0);
});
Here is the complete code:
var w = 1280,
h = 800,
rx = w / 2,
ry = h / 2,
m0,
rotate = 0;
var cluster = d3.layout.cluster()
.size([360, ry - 120])
.sort(null);
var diagonal = d3.svg.diagonal.radial()
.projection(function (d) {
return [d.y, d.x / 180 * Math.PI];
});
var svg = d3.select("body").append("div")
.style("width", w + "px")
.style("height", w + "px");
var vis = svg.append("svg:svg")
.attr("width", w)
.attr("height", w)
.append("svg:g")
.attr("transform", "translate(" + rx + "," + ry + ")");
vis.append("svg:path")
.attr("class", "arc")
.attr("d", d3.svg.arc().innerRadius(ry - 120).outerRadius(ry).startAngle(0).endAngle(2 * Math.PI))
.on("mousedown", mousedown);
var div = d3.select("body").append("div").attr("class", "tooltip")
.style("opacity", 0);
function drawNodes(graph) {
var nodes = cluster.nodes(graph);
var link = vis.selectAll("path.link")
.data(cluster.links(nodes))
.enter().append("svg:path")
.attr("class", "link")
.attr("d", diagonal);
var node = vis.selectAll("g.node")
.data(nodes)
.enter().append("svg:g")
.attr("class", "node")
.attr("transform", function (d) {
return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")";
})
node.append("svg:circle")
.attr("r", 3)
.on("mouseover", function (d) {
div.transition()
.duration(0)
div.style("opacity", 1)
div.html(/*"info:" + "<br/>" + */d.key)
.style("width", d.key.length + "mm")
//.style("height", "10mm") ???
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function (d) {
div.transition()
.duration(0)
.style("opacity", 0);
});
node.append("svg:text")
.attr("dx", function (d) {
return d.x < 180 ? 8 : -8;
})
.attr("dy", ".31em")
.attr("text-anchor", function (d) {
return d.x < 180 ? "start" : "end";
})
.attr("transform", function (d) {
return d.x < 180 ? null : "rotate(180)";
})
.text(function (d) {
return d.name;
});
// TODO: does not work...not sure why...mouseover being captured already?
node.append("svg:title")
.text(function(d) { return d.key; });
}
//});
d3.select(window)
.on("mousemove", mousemove)
.on("mouseup", mouseup);
function mouse(e) {
return [e.pageX - rx, e.pageY - ry];
}
function mousedown() {
m0 = mouse(d3.event);
d3.event.preventDefault();
}
function mousemove() {
if (m0) {
var m1 = mouse(d3.event),
dm = Math.atan2(cross(m0, m1), dot(m0, m1)) * 180 / Math.PI,
tx = "translate3d(0," + (ry - rx) + "px,0)rotate3d(0,0,0," + dm + "deg)translate3d(0," + (rx - ry) + "px,0)";
svg.style("-moz-transform", tx)
.style("-ms-transform", tx)
.style("-webkit-transform", tx);
}
}
function mouseup() {
if (m0) {
var m1 = mouse(d3.event),
dm = Math.atan2(cross(m0, m1), dot(m0, m1)) * 180 / Math.PI,
tx = "rotate3d(0,0,0,0deg)";
rotate += dm;
if (rotate > 360) rotate -= 360;
else if (rotate < 0) rotate += 360;
m0 = null;
svg.style("-moz-transform", tx)
.style("-ms-transform", tx)
.style("-webkit-transform", tx);
vis.attr("transform", "translate(" + rx + "," + ry + ")rotate(" + rotate + ")")
.selectAll("g.node text")
.attr("dx", function (d) {
return (d.x + rotate) % 360 < 180 ? 8 : -8;
})
.attr("text-anchor", function (d) {
return (d.x + rotate) % 360 < 180 ? "start" : "end";
})
.attr("transform", function (d) {
return (d.x + rotate) % 360 < 180 ? null : "rotate(180)";
});
}
}
function cross(a, b) {
return a[0] * b[1] - a[1] * b[0];
}
function dot(a, b) {
return a[0] * b[0] + a[1] * b[1];
}
The CSS of the example is preventing the nodes from capturing the pointer and thus from showing the tooltips. If you remove the line
pointer-events: none;
from the CSS for .node, it works fine.
Related
I am learning d3, i use the "dataset" variable for the values of the graphic,
i wish use dataset.nombre values for label the d3 graphic, but i can only use dataset.numbers, this is a simplified code version:
<body>
<div id="container2"></div>
<script>
var dataset = {
numbers: [15, 3, 10, 2, 14,17,1],
nombre:["a","b","c","d","e","f","g"]
};
var color = d3.scale.category20();
var pie = d3.layout.pie()
.sort(null);
var piedata = pie(dataset.apples);
var arc = d3.svg.arc()
.innerRadius(radius - 100)
.outerRadius(radius - 50);
var svg = d3.select("#container2").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var path = svg.selectAll("path")
.data(piedata)
.enter().append("path")
.attr("fill", function(d, i) { return color(i); })
.attr("d", arc);
svg.selectAll("text").data(piedata)
.enter()
.append("text")
.attr("text-anchor", "middle")
.attr("x", function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cx = Math.cos(a) * (radius - 75);
return d.x = Math.cos(a) * (radius - 20);
})
.attr("y", function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cy = Math.sin(a) * (radius - 75);
return d.y = Math.sin(a) * (radius - 20);
})
.text(function(d) { return d.value; })
.each(function(d) {
var bbox = this.getBBox();
d.sx = d.x - bbox.width/2 - 2;
d.ox = d.x + bbox.width/2 + 2;
d.sy = d.oy = d.y + 5;
});
svg.append("defs").append("marker")
.attr("id", "circ")
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("refX", 3)
.attr("refY", 3)
.append("circle")
.attr("cx", 3)
.attr("cy", 3)
.attr("r", 3);
svg.selectAll("path.pointer").data(piedata).enter()
.append("path")
.attr("class", "pointer")
.style("fill", "none")
.style("stroke", "black")
.attr("marker-end", "url(#circ)")
.attr("d", function(d) {
if(d.cx > d.ox) {
return "M" + d.sx + "," + d.sy + "L" + d.ox + "," + d.oy + " " + d.cx + "," + d.cy;
} else {
return "M" + d.ox + "," + d.oy + "L" + d.sx + "," + d.sy + " " + d.cx + "," + d.cy;
}
});
</script>
</body>
Ideally you'd have objects instead of numbers as the data you pass to the pie layout; then you'd be able to use the data directly. In your case, you can still do so by using the index:
.text(function(d, i) { return dataset.nombre[i]; })
Complete demo here.
My problem is labels of donut chart too long. It'll be cut lost when it get over width or height of svg.
i don't know how i must cut it to 2 or more line. I try to add tag div outside tag text but it's wrong. Who can give me a solution. This is my code:
var tooltip = d3.select('#chart')
.append('div')
.attr('class', 'tooltips');
tooltip.append('div')
.attr('class', 'label');
var data = [
{country: "UNITED KINGDOMhhhhhhhhhhhhhhhhhhhhhhhhh hhhhhhhhhhhhhhhhh", val: 86.68},
{country: "HONG KONGggggggggggggggggggggg g g g gg g g g g gg gg g g ", val: 9.23},
{country: "OTHERS", val: 4.09}
];
var w = 600,
h = 600,
r = Math.min(w, h) / 2 - 100,
labelr = r + 30, // radius for label anchor
color = d3.scale.category20(),
donut = d3.layout.pie(),
arc = d3.svg.arc().innerRadius(r * .6).outerRadius(r);
var vis = d3.select("#chart")
.append("svg:svg")
.data([data])
.attr("width", w + 150)
.attr("height", h);
var arcs = vis.selectAll("g.arc")
.data(donut.value(function(d) { return d.val }))
.enter().append("svg:g")
.attr("class", "arc")
.attr("transform", "translate(" + (r + 200) + "," + (r+100) + ")");
var arcOver = d3.svg.arc()
.innerRadius(r * .57)
.outerRadius(r + 5);
arcs.append("path")
.attr("fill", function(d, i) { return color(i); })
.attr("d", arc)
.on("mouseover",function(d){
d3.select(this).transition()
.duration(50)
.attr("d", arcOver);
tooltip.select('.label').html(d.value + "%");
tooltip.style('display', 'block');
})
.on('mouseout', function() {
d3.select(this).transition()
.duration(50)
.attr("d", arc);
tooltip.style('display', 'none');
})
.on('mousemove', function(d) {
tooltip.style('top', (d3.event.pageY - 80) + 'px')
.style('left', (d3.event.pageX + 10) + 'px');
});
arcs.append("text")
.attr("transform", function(d) {
var c = arc.centroid(d),
x = c[0],
y = c[1],
// pythagorean theorem for hypotenuse
h = Math.sqrt(x*x + y*y);
return "translate(" + (x/h * labelr) + ',' +
(y/h * labelr) + ")";
})
.attr("dy", ".35em")
.attr("text-anchor", function(d) {
// are we past the center?
return (d.endAngle + d.startAngle)/2 > Math.PI ?
"end" : "start";
})
.text(function(d) { return d.data.country; });
Thanks!!!
var tooltip = d3.select('#chart')
.append('div')
.attr('class', 'tooltips');
tooltip.append('div')
.attr('class', 'label');
var data = [
{country: "UNITED KINGDOMhhhhhhhhhhhhhhhhhhhhhhhhh hhhhhhhhhhhhhhhhh", val: 86.68},
{country: "HONG KONGggggggggggggggggggggg g g g gg g g g g gg gg g g ", val: 9.23},
{country: "OTHERS", val: 4.09}
];
var w = 600,
h = 600,
r = Math.min(w, h) / 2 - 100,
labelr = r + 30, // radius for label anchor
color = d3.scale.category20(),
donut = d3.layout.pie(),
arc = d3.svg.arc().innerRadius(r * .6).outerRadius(r);
var vis = d3.select("#chart")
.append("svg:svg")
.data([data])
.attr("width", w + 150)
.attr("height", h);
var arcs = vis.selectAll("g.arc")
.data(donut.value(function(d) { return d.val }))
.enter().append("svg:g")
.attr("class", "arc")
.attr("transform", "translate(" + (r + 200) + "," + (r+100) + ")");
var arcOver = d3.svg.arc()
.innerRadius(r * .57)
.outerRadius(r + 5);
arcs.append("path")
.attr("fill", function(d, i) { return color(i); })
.attr("d", arc)
.on("mouseover",function(d){
d3.select(this).transition()
.duration(50)
.attr("d", arcOver);
tooltip.select('.label').html(d.value + "%");
tooltip.style('display', 'block');
})
.on('mouseout', function() {
d3.select(this).transition()
.duration(50)
.attr("d", arc);
tooltip.style('display', 'none');
})
.on('mousemove', function(d) {
tooltip.style('top', (d3.event.pageY - 80) + 'px')
.style('left', (d3.event.pageX + 10) + 'px');
});
var text = arcs.append("text")
.attr("transform", function(d) {
var c = arc.centroid(d),
x = c[0],
y = c[1],
// pythagorean theorem for hypotenuse
h = Math.sqrt(x*x + y*y);
return "translate(" + (x/h * labelr) + ',' +
(y/h * labelr) + ")";
})
.attr("dy", ".35em")
.attr("text-anchor", function(d) {
// are we past the center?
return (d.endAngle + d.startAngle)/2 > Math.PI ?
"end" : "start";
});/*
.text(function(d) {
return d.data.country;
});*/
text.each(function(d){
var text = d3.select(this),
words = d.data.country.split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 0.22, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null)
.append("tspan")
.attr("x", 0)
.attr("y", y)
.attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > 10) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan")
.attr("x", 0)
.attr("y", y)
.attr("dy", ++lineNumber * lineHeight + dy + "em")
.text(word);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id='chart'></div>
After doing a great lot of work out. I got this.
Hope this will fulfill your need/requirement.
All I did is,
Adding tspan elements to text element.Observe below code. text is a var see above code. which holds all text elements which we want to add to the every g
text.each(function(d){
var text = d3.select(this),//selecting current text element
words = d.data.country.split(/\s+/).reverse(),//splitting the country name by using space, if you want you can change.
word,//to store one one word
line = [],
lineNumber = 0,
lineHeight = 0.22, // ems, you can increase for more gaps vise versa
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null)
.append("tspan")
.attr("x", 0)
.attr("y", y)
.attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > 10) {//here I'm checking the length of the text
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan")
.attr("x", 0)
.attr("y", y)
.attr("dy", ++lineNumber * lineHeight + dy + "em")//setting the gap between the label line gaps.
.text(word);
}
}
})
Is it possible to create a sunburst that is shaped as a semicircle? I was able to give it the shape that I want, but I have problems with the nodes. Not all the colors appear on the new shape and the text is displayed wrong.
var partition = d3.layout.partition()
.sort(null)
.value(function(d) { return d.size; });
var arc = d3.svg.arc()
.startAngle(function(d) { return Math.max(0, Math.min(Math.PI/360, x(d.x))); })
.endAngle(function(d) { return Math.max(0, Math.min(Math.PI, x(d.x + d.dx))); })
.innerRadius(function(d) { return Math.max(0, d.y ? y(d.y) : d.y); })
.outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)); });
var nodes = partition.nodes(json);
var path = vis.selectAll("path").data(nodes);
path.enter().append("path")
.attr("id", function(d, i) { return "path-" + i; })
.attr("d", arc)
.attr("fill-rule", "evenodd")
.attr("fill", function(d) { return color((d.children ? d : d.parent).name); })
.on("click", function(d,i) {
//This is a mimic of the selection in the Tree List Box - picking all the parents of the selected cell
_this.Data.SearchColumn(0, "*" + d.name + "*",false);
});
var text = vis.selectAll("text").data(nodes);
var textEnter = text.enter().append("text")
.style("opacity", 1)
.style("fill","#333")
.attr("text-anchor", function(d) {
return x(d.x + d.dx / 2) > Math.PI ? "end" : "start";
})
.attr("dy", ".2em")
.attr("transform", function(d) {
var multiline = (d.name || "").split(" ").length > 1,
angle = x(d.x + d.dx / 2) * 180 / Math.PI -90,
rotate = angle + (multiline ? -.5 : 0);
return "rotate(" + rotate + ")translate(" + (y(d.y) + p) + ")rotate(" + (angle > 90 ? -180 : 0) + ")";
})
.on("click", function(d,i) {
_this.Data.SearchColumn(0, "*" + d.name + "*",false);
});
textEnter.append("tspan")
.attr("x", 0)
.text(function(d) { return d.depth ? d.name.split(" ")[0] : ""; });
textEnter.append("tspan")
.attr("x", 0)
.attr("dy", "1em")
.text(function(d) { return d.depth ? d.name.split(" ")[1] || "" : ""; });
textEnter.append("tspan")
.text(" ");
textEnter.append("tspan")
.text(function(d) { return d.depth ? d.name.split(" ")[2] || "" : ""; } );
textEnter.append("tspan")
.text(" ");
textEnter.append("tspan")
.text(function(d) { return d.depth ? d.name.split(" ")[3] || "" : ""; } );
I've solved the problem. This is the code I used:
var w = Math.min(heightc,widthc),
h = w/2,
r = w / 2-20,
x = d3.scale.linear().range([0, 1* Math.PI]),
y = d3.scale.pow().exponent(1.3).domain([0, 1]).range([0, r]),
p = 4,
color = d3.scale.category20c(),
duration = 1000;
var div = d3.select("#"+myDivId);
div.select("img").remove();
var vis = div.append("svg")
.attr("width", w + p * 2)
.attr("height", h + p * 2)
.append("g")
.attr("transform", "translate(" + (p) + "," + (r + p) + ")");
var partition = d3.layout.partition()
.sort(null)
.value(function(d) { return d.size; });
var arc = d3.svg.arc()
.startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x))); })
.endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))); })
.innerRadius(function(d) { return Math.max(0, d.y ? y(d.y) : d.y); })
.outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)); });
And the rest of the code remained the same.
I make a drill down pie chart and it works well.
You can see it here.
But there is an issue:
1) click a node then it shows its children (level 1) or level 0 nodes.
2) Move mouse to another position and move back to the new node which contains its original position, the node disappears.
I think there is problem in this code (gradientPie.js)
var paths = gPie.selectAll("path").data(pieChart(currData), function(d) {return d.data.cat;});
var texts = gPie.selectAll("text").data(pieChart(currData), function(d) {return d.data.cat;});
var lines = gPie.selectAll("line").data(pieChart(currData), function(d) {return d.data.cat;});
var arcs = paths.enter().append("g").attr('class', 'slice');
arcs.append("path").attr("fill", function(d, i) { return "url(#gradient" + d.data.cat + ")"; })
.transition().duration(1000).attrTween("d", tweenIn).each("end", function(){
this._listenToEvents = true;
gradPie.transitioning = false;
})
.attr("id", function(d, i){return 'p' + i;})
.each(function(d) { this._current = d; });
arcs.append("text").attr("transform", function(d) {
var c = d3.svg.arc().outerRadius(radius * 1.4).innerRadius(radius).centroid(d);
return "translate(" + (0 + c[0]) + "," + (0 + c[1]) + ")";
})
.attr("dy", ".35em")
.attr("class", "text-main")
.style("text-anchor", "middle")
.style("fill", "#3f5763")
.style("font", "bold 14px Helvetica")
.text(function(d) {
$("#" + d.data.domID + " p").html(d.data.percent + "%");
return d.data.percent + "%";
});
arcs.append("line").attr("transform", function (d, i) {
var rAngle = ((d.startAngle + d.endAngle) / 2 - (Math.PI / 2)) * 180 / Math.PI;
return "rotate(" + rAngle + ")translate(" + radius * 1.1 + ")";
})
.attr("class", "line-ticks")
.attr('stroke-width', '1')
.attr("x2", -0.5 * radius)
.style("stroke", "#3f5763")
.style("fill", "none");
// Mouse interaction handling
paths.on("click", function(d, i){
if(this.childNodes[0]._listenToEvents && !gradPie.transitioning){
// Reset inmediatelly
d3.select(this).attr("transform", "translate(0,0)")
// Change level on click if no transition has started
paths.each(function(){
this.childNodes[0]._listenToEvents = false;
});
updateGraph(d.data.subfractions? d.data.cat : undefined);
}
})
.on("mouseover", function(d, i){
// Mouseover effect if no transition has started
if(this.childNodes[0]._listenToEvents && !gradPie.transitioning) {
// Calculate angle bisector
var ang = (d.endAngle + d.startAngle)/2;
// Transformate to SVG space
ang = (ang - (Math.PI / 2) ) * -1;
// Calculate a 10% radius displacement
var x = Math.cos(ang) * radius * 0.1;
var y = Math.sin(ang) * radius * -0.1;
d3.select(this).transition()
.duration(250).attr("transform", function() {
return "translate(" + x + ", " + y + ")";
})
}
})
.on("mouseout", function(d){
// Mouseout effect if no transition has started
if(this.childNodes[0]._listenToEvents && !gradPie.transitioning){
d3.select(this).transition()
.duration(150).attr("transform", function() {
return "translate(0,0)";
});
}
});
// Collapse sectors for the exit selection
paths.exit().transition()
.duration(1000)
.attrTween("d", tweenOut).remove();
texts.exit().transition()
.duration(100).remove();
lines.exit().transition()
.duration(100).remove();
Any help?
How to display each node of different image. I show an example of d3 on github. but in this there is only one links.
How to display each node a different image. Any solution?
This is my example.
var nodes = {};
// Compute the distinct nodes from the links.
links.forEach(function(link) {
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
link.target = nodes[link.target] || (nodes[link.target] = {name: link.target});
});
var width = 900,
height = 900;
var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkDistance(90)
.charge(-600)
.on("tick", tick)
.start(type, crawledPageID);
var svg = d3.select("#d3Graph").append("svg")
.attr("width", width)
.attr("height", height).call(zoom);
// Per-type markers, as they don't inherit styles.
svg.append("defs").selectAll("marker")
.data(["suit", "licensing", "resolved"])
.enter().append("marker")
.attr("id", function(d) { return d; })
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5");
var path = svg.append("g").selectAll("path")
.data(force.links())
.enter().append("path")
.attr("class", function(d) { return "link " + d.type; })
.attr("marker-end", function(d) { return "url(#" + d.type + ")"; });
var circle = svg.append("g").selectAll("circle")
.data(force.nodes())
.enter().append("circle")
.attr("r", 3)
.call(force.drag);
var text = svg.append("g").selectAll("text")
.data(force.nodes())
.enter().append("text")
.attr("x", 6)
.attr("y", ".21em")
.text(function(d) {return d.name; });
var edgeText = svg.append("svg:g").selectAll("path")
.data(force.links())
.enter().append("svg:path")
.attr("id", function(d) { return d.source.index + "_" + d.target.index; })
.attr("class", function(d) { return "link " + d.type; })
.attr("marker-end", function(d) { return "url(#" + d.type + ")"; });
var path_label = svg.append("svg:g").selectAll(".path_label")
.data(force.links())
.enter().append("svg:text")
.attr("class", "path_label")
.append("svg:textPath")
.attr("startOffset", "50%")
.attr("text-anchor", "middle")
.attr("xlink:href", function(d) { return "#" + d.source.index + "_" + d.target.index; })
.style("fill", "#000")//edge color
.style("font-size","10px")
.style("font-family", "Serif")
.text(function displayNote(d){ return "";// d.rel;
});
/**
function displayNote(){
var chkStatus1 = document.getElementById("door2");
if (chkStatus1.checked)
{
return d.rel;
}
else
{
return "----";
}
} *
*
*/
// Use elliptical arc path segments to doubly-encode directionality.
function tick()
{
circle.attr("transform", transform);
text.attr("transform", transform);
edgeText.attr("d", function(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = 0;//Math.sqrt(dx * dx + dy * dy);
return "M" +
d.source.x + "," +
d.source.y + "A" +
dr + "," + dr + " 0 0,1 " +
d.target.x + "," +
d.target.y;
});
}
/*function linkArc(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
}*/
function transform(d)
{
return "translate(" + d.x + "," + d.y + ")";
}