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 + ")";
}
Related
the path is exceeding when we have huge data. getting this issue when the source and target have bigger shock width . is there a way when i can fix the path not to exceed the borders. thankyou
my code
var svg = d3.select("#chart").append("svg")
.attr("width", width1.schemaWidth + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("class", "svgchart")
.append("g")
.attr("transform",
"translate(" + (nodeTextMaxLength*5.5) + "," + margin.top + ")");
var sankey = d3.sankey()
.nodeWidth(30)
.nodePadding(8)
.size([width1.schemaWidth, height]);
var path = sankey.link();
var div = d3.select("body").append("div")
.attr("class", "tooltipsankey")
.style("opacity", 0);
link = svg.append("g").selectAll(".link")
.data(graph.links)
.enter().append("path")
.attr("class", "linksankey")
.attr("d", path)
.attr("id", function(d) { return "link" + d.source.name; })
.style("stroke-width", function(d) { return Math.max(1, d.dy); })
.style("stroke", function(d) {
return d.color; });
rect = node.append("rect")
.attr("height", function(d) { return d.dy; })
.attr("width", function(d) {
return sankey.nodeWidth()
}).style("fill", function(d) { return color(d.name) });
the issue is on both source and target side.
sankey link method
sankey.link = function() {
var curvature = .5;
function link(d) {
var x0 = d.source.x + d.source.dx,
x1 = d.target.x - 50,
xi = d3.interpolateNumber(x0, x1),
x2 = xi(curvature),
x3 = xi(1 - curvature),
y0 = d.source.y + d.sy + d.dy / 2,
y1 = d.target.y + d.ty + d.dy / 2;
return "M" + x0 + "," + y0
+ "C" + x2 + "," + y0
+ " " + x3 + "," + y1
+ " " + x1 + "," + y1;
}
link.curvature = function(_) {
if (!arguments.length) return curvature;
curvature = +_;
return link;
};
return link;
};
I created tree layout as in JSFiddle example http://jsfiddle.net/oo66o0q0/15/.
Requirement is path should highlighted in red and with extra width when user click on node's right click menu "Highlight Route" option.
This is working in chrome correctly but in IE highlighted route color becomes black.
If I remove markers then it works in IE as well.
How to resolve this issue in IE but not removing markers?
function treeInitialize(graphData){
diagramLayout = d3.select("#diagramLayout")
.attr("id", "diagramLayout")//set id
.attr("width", width)//set width
.attr("height", height)//set height
.append("g")
.attr("transform", "translate(" + 20 + "," + 20 + ")")
markerRefx = 40;
var data2 = graphData.links.filter(function(l){
if(l.target == undefined && l.source == undefined){
return false;
}else{
return true;
}
});
data2.push(JSON.parse('{"target":"glossforArrow","source":""}'))
var treeData = d3.stratify().id(function(d){ return d.target; }).parentId(function(d) {
return d.source;
})(data2)
nodes = d3.hierarchy(treeData, function(d) {return d.children;});
var levelWidth = [1];
var childCount = function(level, n) {
if(n.children && n.children.length > 0) {
if(levelWidth.length <= level + 1) levelWidth.push(0);
levelWidth[level+1] += n.children.length;
n.children.forEach(function(d) {
childCount(level + 1, d);
});
}
};
childCount(0, nodes);
newHeight = d3.max(levelWidth) * 100;
var tree = d3.tree().size([height, width])
tree.size([newHeight,height/2]);
tree.separation(function (a, b) {
return a.parent == b.parent ? 50 : 100;
});
nodes = tree(nodes);
treeLayout(nodes);
function treeLayout(nodes){
var node = diagramLayout.selectAll(".node");
node = node.data(nodes.descendants());
var link = diagramLayout.selectAll(".link")
.data(nodes.descendants().slice(1))
.enter().append("path")
.attr("class", "link")
.attr("fill", "none")
.attr("stroke", "#000")
.attr("stroke-width", "1px")
.attr("stroke-opacity", "0.3")
.attr("d",connector)
nodes.descendants().slice(1).forEach(function(d) {
var mark = diagramLayout.append("svg:defs").selectAll("marker")//
.data(["start"]) // Different link/path types can be defined here
.enter().append("svg:marker") // This section adds in the arrows
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", -markerRefx)
.attr("refY", 0)
.attr("markerWidth", 5)
.attr("markerHeight", 5)
.attr("orient", "auto")
.attr("stroke", "#000")
.attr("fill", "#000")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5")
.style("stroke-width", "0.3px")
.attr("transform","rotate(180,5, 0)");
});
link.attr("marker-start", "url(#start)")
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("height", nodeHeight)
.attr("width", nodeWidth)
nodeEnter.attr("transform", function(d) {
return "translate(" + project(d.x, d.y) + ")";
}).on('contextmenu', menuCall);
var nodeIcon = nodeEnter.append("rect")
.attr("class", "rect")
.attr("x", -20)
.attr("y", -20)
.attr("rx", 10)
.attr("width", 40)
.attr("height", 40)
.attr("stroke-width", function(d) { return Math.sqrt(2); })
.attr("stroke-opacity", "0.3")
.attr("stroke", "#000" )
.attr("fill", "blue" )
//wrap(nodeText, 8)
}
}
function connector(d) {
return "M" + project(d.x, d.y)
+ "C" + project(d.x, (d.y + d.parent.y) / 2)
+ " " + project(d.parent.x, (d.y + d.parent.y) / 2)
+ " " + project(d.parent.x, d.parent.y);
}
function project(x, y) {
return [x,y];
}
function menuCall(di,i) {
var nodeClicked = d3.select(this);
var menuitems = ["Highlight route"];
d3.selectAll('.context-menu').data([1])
.enter()
.append('div')
.attr('class', 'context-menu');
// close menu
d3.select('body').on('click.context-menu', function() {
d3.select('.context-menu').style('display', 'none');
});
// this gets executed when a contextmenu event occurs
d3.selectAll('.context-menu')
.html('')
.append('ul')
.selectAll('li')
.data(menuitems).enter()
.append('li')
.on('click' , function(d) {
// d3.select('.context-menu').style('display', 'none');
if(d=="Highlight route"){
var id = nodeClicked.datum().data.id;
var node = diagramLayout.selectAll(".node");
var link = diagramLayout.selectAll(".link");
link.style("stroke","black").style("stroke-width", "1.5px")
var linkSelected = link.filter(function (d, i) {
console.log(d.data.id)
console.log(id)
return d.data.id === id;});
linkSelected.style("stroke", "red").style("stroke-width", "5px");
}
d3.select('.context-menu').style('display', 'none');
}).text(function(di) { return di; });
d3.select('.context-menu').style('display', 'none');
// show the context menu
d3.select('.context-menu')
.style('left', (d3.event.pageX - 2) + 'px')
.style('top', (d3.event.pageY - 2) + 'px')
.style('display', 'block');
d3.event.preventDefault();
}
Looks like a bug in IE. If you inspect the DOM after you apply the highlight, IE reports that the inline style has overridden the sheet style (as it should), but the path does not update:
The only fix I can think us is to remove the sheet stroke style on class link
.link {
stroke-opacity: .6;
}
And just apply all the styles in-line.
Updated fiddle.
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);
}
}
})
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.