How to offset text in D3 node - javascript

I am trying to use the D3 javascript library to make a force-directed graph, and I want to offset text appended to my nodes. However, no attributes that I seem to try and change have an affect on this. Instead, my text gets overlayed on the node and it's very hard to read:
Here is how I am appending the text:
node.append("text")
.attr("dy", -3)
.attr("text-anchor", "right")
.style("color", "white", null)
.text(function(d) { return d.name; });
I have tried different values of dx and dy but nothing seems to offset the text. It always looks the same.
Edit: Full code (http://g.nychis.com/force-directed.zip and open force-edges-names.html)
<!DOCTYPE html>
<html>
<head>
<title>Force-Directed Layout</title>
<script type="text/javascript" src="d3.v2.js"></script>
<style type="text/css">
div.node {
border-radius: 12px;
width: 24px;
height: 24px;
margin: -6px 0 0 -6px;
position: absolute;
}
div.link {
position: absolute;
border-bottom: solid #999 1px;
height: 0;
-webkit-transform-origin: 0 0;
-moz-transform-origin: 0 0;
-ms-transform-origin: 0 0;
-o-transform-origin: 0 0;
transform-origin: 0 0;
}
</style>
</head>
<body bgcolor="#000000">
<FONT COLOR="#FFFFFF">Floor: 1</FONT>
<script type="text/javascript">
var width = 700,
height = 500,
radius = 6,
fill = d3.scale.category20();
var force = d3.layout.force()
.gravity(0)
.charge(-100)
.linkDistance(function(d) { return (d.value-d.sub)*8; })
.size([width, height]);
var vis = d3.select("body").append("div")
.style("width", width + "px")
.style("height", height + "px");
d3.json("home.json", function(json) {
var link = vis.selectAll("div.link")
.data(json.links)
.enter().append("div")
.attr("class", "link");
var node = vis.selectAll("div.node")
.data(json.nodes)
.enter().append("div")
.attr("class", "node")
.style("background", function(d) { return fill(d.group); })
.style("border-color", function(d) { return d3.rgb(fill(d.group)).darker(); })
.call(force.drag);
node.append("text")
.style("color", "white", null)
.text(function(d) { return d.name; });
force
.nodes(json.nodes)
.links(json.links)
.on("tick", tick)
.start();
function tick() {
node.style("left", function(d) { return (d.x = Math.max(radius, Math.min(width - radius, d.x))) + "px"; })
.style("top", function(d) { return (d.y = Math.max(radius, Math.min(height - radius, d.y))) + "px"; });
link.style("left", function(d) { return d.source.x + "px"; })
.style("top", function(d) { return d.source.y + "px"; })
.style("width", length)
.style("-webkit-transform", transform)
.style("-moz-transform", transform)
.style("-ms-transform", transform)
.style("-o-transform", transform)
.style("transform", transform);
}
function transform(d) {
return "rotate(" + Math.atan2(d.target.y - d.source.y, d.target.x - d.source.x) * 180 / Math.PI + "deg)";
}
function length(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y;
return Math.sqrt(dx * dx + dy * dy) + "px";
}
});
</script>
</body>
</html>

You can translate the text element:
node.append("div")
.style("transform", "translate(0px,-10px)")
...
.html(...);
The name of the "transform" property depends on the browser you're using, see here. You might want to set all of these.

node.append("text")
.attr({
"dy": -3,
"transform": "translate(" + 15 + "," + 5 + ")"
})
.style("color", "white", null)
.text(function(d) { return d.name; });

Related

Cannot get d3 force graph to have xlink:href (clickable) nodes

I've tried to add xlink:href dummy URL just to see if I'm getting anywhere, but I am completely stuck.
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>Job graph</title>
<style>
.link {
fill: none;
stroke: #666;
stroke-width: 1.5px;
}
#licensing {
fill: green;
}
.link.licensing {
stroke: green;
}
.link.resolved {
stroke-dasharray: 0, 2 1;
}
circle {
stroke: #333;
stroke-width: 1.5px;
}
text {
font: 10px sans-serif;
pointer-events: none;
text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff;
}
</style>
</head>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var links = [{
"source": 0,
"target": 1
}];
var nodes = [{
"id": "p1"
}, {
"id",
"p2"
}];
var node_fills = {
"p1": "rgba(204,204,204,0.5)",
"p2": "rgba(204,204,204,0.5)"
};
var width = window.innerWidth,
height = window.innerHeight;
var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkDistance(60)
.charge(-300)
.on("tick", tick)
.start();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
// 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("xlink:href", function(d) {
return "http://google.com/" + d.id
})
.attr("r", 8)
.attr("fill", function(d) {
return node_fills[d.id];
})
.call(force.drag);
var text = svg.append("g").selectAll("text")
.data(force.nodes())
.enter().append("text")
.attr("x", 8)
.attr("y", ".31em")
.text(function(d) {
return d.id;
});
// Use elliptical arc path segments to doubly-encode directionality.
function tick() {
path.attr("d", linkArc);
circle.attr("transform", transform);
text.attr("transform", transform);
}
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 + ")";
}
</script>

D3 Map - Marks Zooming

I have a problem with marks on my D3 map. When I set up zooming for each state the marks are not zooming within the map..
That's my first try for D3 map, so sorry if I messed up something in the code. If I did or missed something I'll really appreciate explanation.
If anyone can help with that I'll be really thankful.
var width = 960,
height = 500,
centered;
var projection = d3.geo.albersUsa()
.scale(1070)
.translate([width / 2, height / 2]);
var path = d3.geo.path()
.projection(projection);
var svg = d3.select("body")
.append("svg")
.attr("viewBox", "0 0 " + width + " " + height )
.attr("preserveAspectRatio", "xMinYMin");
svg.append("rect")
.attr("class", "background")
.attr("width", width)
.attr("height", height)
.on("click", clicked);
var g = svg.append("g");
var div = d3.select("body")
.append("div")
.attr("class", "tooltip")
.style("opacity", 0);
d3.json("https://bl.ocks.org/mbostock/raw/4090846/us.json", function(error, us) {
if (error) throw error;
g.append("g")
.attr("id", "states")
.selectAll("path")
.data(topojson.feature(us, us.objects.states).features)
.enter().append("path")
.attr("d", path)
.style("fill", "#26404b")
.on("click", clicked);
g.append("path")
.datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; }))
.attr("id", "state-borders")
.attr("d", path);
// CITIES
d3.json("https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json", function(data) {
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([d.longitude, d.latitude])[0];
})
.attr("cy", function(d) {
return projection([d.longitude, d.latitude])[1];
})
.attr("r", function(d) {
if(d.population >= 1 && d.population < 10000){
return 1;
}
else if(d.population >= 10000 && d.population < 100000){
return 2;
}
else if(d.population >= 100000 && d.population < 500000){
return 3;
}
else if(d.population >= 500000 && d.population < 1000000){
return 4;
}
else if(d.population >= 1000000 && d.population < 5000000){
return 5;
}
else if(d.population < 5000000){
return 10;
}
else {
return 0;
};
})
.style("fill", "rgba(26, 188, 156,0.8)")
// HOVER
.on("mouseover", function(d) {
d3.select(this)
.transition()
.duration(200)
.style('fill', 'rgba(26, 188, 156, 0.3)')
.style('stroke', '#1abc9c')
.style('stroke-width', 4);
div.transition()
.duration(200)
.style("opacity", .9);
div.html('<span id="place">City: ' + d.city + '</span><br><span id="people">Calls: ' + d.population + '</span>')
.style("left", (d3.event.pageX) + 35 + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
d3.select(this)
.transition()
.duration(200)
.style('fill', 'rgba(26, 188, 156, 0.8)')
.style('stroke-width', 0);
div.transition()
.duration(200)
.style("opacity", 0);
});
});
});
function clicked(d) {
var x, y, k;
if (d && centered !== d) {
var centroid = path.centroid(d);
x = centroid[0];
y = centroid[1];
k = 4;
centered = d;
} else {
x = width / 2;
y = height / 2;
k = 1;
centered = null;
}
g.selectAll("path")
.classed("active", centered && function(d) { return d === centered; });
g.transition()
.duration(750)
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(" + k + ")translate(" + -x + "," + -y + ")")
.style("stroke-width", 1.5 / k + "px");
}
.background {
fill: #435863;
pointer-events: all;
}
path:hover {
fill-opacity: .9;
}
#states .active {
fill-opacity: .9;
}
#state-borders {
fill: none;
stroke: rgba(22, 160, 133, .1);
stroke-width: 1px;
}
/* Style for Custom Tooltip */
div.tooltip {
position: absolute;
height: 28px;
padding: 5px 10px;
font: 12px sans-serif;
background: white;
border: 0px;
border-radius: 5px;
pointer-events: none;
}
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
The problem is that you are appending your circles to the svg directly, but your US state are being appended to a g element. Your zoom transition is only applied to the g, meaning the circles will be unaffected:
g.transition()
.duration(750)
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(" + k + ")translate(" + -x + "," + -y + ")")
.style("stroke-width", 1.5 / k + "px");
You should be able to correct this by simply appending your circles to the same g element itself, rather than the svg:
d3.json("cities.json", function(data) {
g.selectAll("circle")
.data(data)
.enter()
...

Unable to display the tooltip and arctween transition ata a time in d3 pie chart

Hello I am trying to add arctween transition to my pie chart. I am able to show the tooltips and legends in my pie chart but when I try to add arctween transition to my pie chart the tooltip is not working. How to make this possible to display both the tooltip and the arctween transition in this pie chart.
(function(d3) {
'use strict';
var margin = {top: 50, right: 50, bottom: 50, left: 50};
var width = 800 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var radius = Math.min(width, height) / 3;
var legendRectSize = 18;
var legendSpacing = 4;
var data = [
{"IP":"192.168.12.1", "count":20},
{"IP":"76.09.45.34", "count":40},
{"IP":"34.91.23.76", "count":80},
{"IP":"192.168.19.32", "count":16},
{"IP":"192.168.10.89", "count":50},
{"IP":"192.178.34.07", "count":18},
{"IP":"192.168.12.98", "count":30}];
var color = d3.scale.category10();
var svg = d3.select('#chart')
.append('svg')
.attr('width', width+margin.left+margin.right)
.attr('height', height+margin.left+margin.right)
.append('g')
.attr('transform', 'translate(' + (width / 2) + ',' + (height / 2) + ')');
var arc = d3.svg.arc()
.innerRadius(0)
.outerRadius(radius);
var arcOver = d3.svg.arc()
.innerRadius(0)
.outerRadius(radius + 5);
var pie = d3.layout.pie()
.sort(null)
.startAngle(1.1*Math.PI)
.endAngle(3.1*Math.PI)
.value(function(d) { return d.count; });
var tooltip = d3.select('#chart')
.append('div')
.attr('class', 'tooltip');
tooltip.append('div')
.attr('class', 'label');
tooltip.append('div')
.attr('class', 'count');
tooltip.append('div')
.attr('class', 'percent');
var path = svg.selectAll('path')
.data(pie(data))
.enter()
.append('path')
.attr('d', arc)
.attr('fill', function(d,i) {
return color(d.data.IP);
});
path.on('mouseover', function(d) {
d3.select(this).transition()
.ease("exp")
.duration(3000)
.attrTween("d", tweenPie)
.duration(200)
.attr("d", arcOver)
.style('opacity',0.7)
function tweenPie(b) {
var i = d3.interpolate({startAngle: 1.1*Math.PI, endAngle: 1.1*Math.PI}, b);
return function(t) { return arc(i(t)); };
}
var total = d3.sum(data.map(function(d) {
return d.count;
}));
var percent = Math.round(1000 * d.data.count / total) / 10;
tooltip.select('.label').html(d.data.IP);
tooltip.select('.count').html(d.data.count);
tooltip.select('.percent').html(percent + '%');
tooltip.style('display', 'block');
});
path.on("mouseout", function(d) {
d3.select(this).transition()
.duration(100)
.attr("d", arc)
.style('opacity','1');
tooltip.style('display', 'none');
});
var legend = d3.select("#chart")
.append("svg")
.attr("class", "legend")
.attr("width", radius+50)
.attr("height", radius * 2)
.selectAll("g")
.data(color.domain())
.enter()
.append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append('rect')
.attr('width', legendRectSize)
.attr('height', legendRectSize)
.style('fill', color)
.style('stroke', color);
legend.append('text')
.attr('x', legendRectSize + legendSpacing)
.attr('y', legendRectSize - legendSpacing)
.text(function(d) { return d; });
})(window.d3);
#chart {
margin-top: 100px;
position: absolute;
margin-right: 50px;
margin-left: 50px;
}
.tooltip {
background: #eee;
box-shadow: 0 0 5px #999999;
color: #900C3F;
display: inline-block;
font-size: 12px;
left: 600px;
padding: 10px;
position: absolute;
text-align: center;
top: 95px;
width: 100px;
z-index: 10;
opacity: 1;
}
rect {
stroke-width: 2;
}
path {
stroke: #ffffff;
stroke-width: 0.5;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Testing Pie Chart</title>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
<div id="chart"></div>
</body>
</html>
Please help me. Above mentioned are the codes that I have tried yet.
Thanks for help in advance.
You want something like this(http://jsbin.com/guqozu/edit?html,js,output):
.on("mouseover", function(d) {
var htmlMsg="";
div.transition()
.style("opacity", .9);
div.html(
"IP :"+d.data.IP+""+"<br/>"+
"Count : " + d.data.count +"<br/>" + htmlMsg)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY) + "px");
svg.selectAll("path").sort(function (a, b) {
if (a != d) return -1;
else return 1;
});
var endAngle = d.endAngle + 0.1;
var arcOver = d3.svg.arc()
.outerRadius(radius +10).endAngle(endAngle).startAngle(startAngle);
d3.select(this)
.attr("stroke","white")
.transition()
.ease("bounce")
.duration(1000)
.attr("d", arcOver)
.attr("stroke-width",6);
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
d3.select(this).transition()
.attr("d", arc)
.attr("stroke","none");
})
.transition()
.ease("bounce")
.duration(2000)
.attrTween("d", tweenPie);
var div = d3.select("#toolTip");
var data = [
{"IP":"192.168.12.1", "count":20},
{"IP":"76.09.45.34", "count":40},
{"IP":"34.91.23.76", "count":80},
{"IP":"192.168.19.32", "count":16},
{"IP":"192.168.10.89", "count":50},
{"IP":"192.178.34.07", "count":18},
{"IP":"192.168.12.98", "count":30}];
var width = 300,
height = 300;
var margin = {top: 15, right: 15, bottom: 20, left: 40},
radius = Math.min(width, height) / 2 - 10;
var legendRectSize = 18,
legendSpacing = 4;
var color = d3.scale.category20b();
var arc = d3.svg.arc()
.outerRadius(radius);
var arcOver = d3.svg.arc()
.outerRadius(radius + 10);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.count; });
var labelArc = d3.svg.arc()
.outerRadius(radius - 40)
.innerRadius(radius - 40);
var svg = d3.select("#chart").append("svg")
.datum(data)
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var arcs = svg.selectAll(".arc")
.data(pie)
.enter().append("g")
.attr("class", "arc");
var arcs2 = svg.selectAll(".arc2")
.data(pie)
.enter().append("g")
.attr("class", "arc2");
arcs.append("path")
.attr("fill", function(d, i) { return color(i); })
.on("mouseover", function(d) {
var htmlMsg="";
div.transition()
.style("opacity",0.9);
div.html(
"IP :"+d.data.IP+""+"<br/>"+
"Count : " + d.data.count +"<br/>" + htmlMsg)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY) + "px");
svg.selectAll("path").sort(function (a, b) {
if (a != d) return -1;
else return 1;
});
var endAngle = d.endAngle + 0.1;
var startAngle = d.startAngle - 0.1;
var arcOver = d3.svg.arc()
.outerRadius(radius + 10).endAngle(endAngle).startAngle(startAngle);
d3.select(this)
.attr("stroke","white")
.transition()
.ease("bounce")
.duration(1000)
.attr("d", arcOver)
.attr("stroke-width",6);
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
d3.select(this).transition()
.attr("d", arc)
.attr("stroke","none");
})
.transition()
.ease("bounce")
.duration(2000)
.attrTween("d", tweenPie);
function tweenPie(b) {
b.innerRadius = 0;
var i = d3.interpolate({startAngle: 0, endAngle: 0}, b);
return function(t) { return arc(i(t)); };
}
var k=0;
arcs2.append("text")
.transition()
.ease("elastic")
.duration(2000)
.delay(function (d, i) {
return i * 250;
})
.attr("x","6")
.attr("dy", ".35em")
.text(function(d) { if(d.data.count >0){ k = k+1; return d.data.count;} })
.attr("transform", function(d) { if (k >1){return "translate(" + labelArc.centroid(d) + ") rotate(" + angle(d) + ")";} else{return "rotate(-360)";} })
.attr("font-size", "10px");
function type(d) {
d.count = +d.count;
return d;
}
function angle(d) {
var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;
return a > 90 ? a - 180 : a;
}
var legend = d3.select("#chart")
.append("svg")
.attr("class", "legend")
.attr("width", radius+50)
.attr("height", radius * 2)
.selectAll("g")
.data(color.domain())
.enter()
.append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append('rect')
.attr('width', legendRectSize)
.attr('height', legendRectSize)
.style('fill', color)
.style('stroke', color);
legend.append('text')
.attr('x', legendRectSize + legendSpacing)
.attr('y', legendRectSize - legendSpacing)
.data(data)
.text(function(d,i) { return d.IP; });
#chart {
margin-top: 100px;
position: absolute;
margin-right: 50px;
margin-left: 50px;
}
.tooltip {
background: #eee;
box-shadow: 0 0 5px #999999;
color: #900C3F;
display: inline-block;
font-size: 12px;
left: 600px;
padding: 10px;
position: absolute;
text-align: center;
top: 95px;
width: 150px;
z-index: 10;
opacity: 1;
}
rect {
stroke-width: 2;
}
path {
stroke: #ffffff;
stroke-width: 0.5;
}
div.tooltip {
position: absolute;
z-index: 999;
padding: 10px;
background: #f4f4f4;
border: 0px;
border-radius: 3px;
pointer-events: none;
font-size: 11px;
color: #000;
line-height: 16px;
border: 1px solid #d4d4d4;
}
.legend{
margin-left: 300px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Testing Pie Chart</title>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
<div id="chart"></div>
<div id="toolTip" class="tooltip" style="opacity: 0;"></div>
<script type="text/javascript">
</script>
</body>
</html>
Thank you SiddP for suggesting some useful tips. Based on his codes and my research I have added a legend along with arctween and tooltip to this pie chart to make it complete. I hope this helps someone struggling over D3 pie chart.
Thank you stackoverflow. :}

Unable to make pie chart from the dataset

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Testing Pie Chart</title>
<script src="d3.v3.min.js" charset="utf-8"></script>
<style type="text/css">
#chart {
margin-top: 100px;
position: absolute;
margin-right: 50px;
margin-left: 50px;
}
.tooltip {
background: #eee;
box-shadow: 0 0 5px #999999;
color: #900C3F;
display: inline-block;
font-size: 12px;
left: 600px;
padding: 10px;
position: absolute;
text-align: center;
top: 95px;
width: 150px;
z-index: 10;
opacity: 1;
}
rect {
stroke-width: 2;
}
path {
stroke: #ffffff;
stroke-width: 0.5;
}
div.tooltip {
position: absolute;
z-index: 999;
padding: 10px;
background: #f4f4f4;
border: 0px;
border-radius: 3px;
pointer-events: none;
font-size: 11px;
color: #000;
line-height: 16px;
border: 1px solid #d4d4d4;
}
.legend{
margin-left: 300px;
}
</style>
</head>
<body>
<div id="chart"></div>
<div id="toolTip" class="tooltip" style="opacity: 0;"></div>
<script type="text/javascript">
var div = d3.select("#toolTip");
var data = [ ["IP", "count"]
["192.168.12.1", "20"],
["76.09.45.34", "40"],
["34.91.23.76", "80"],
["192.168.19.32", "16"],
["192.168.10.89", "50"],
["192.178.34.07", "18"],
["192.168.12.98", "30"]];
var width = 300,
height = 300;
var margin = {top: 15, right: 15, bottom: 20, left: 40},
radius = Math.min(width, height) / 2 - 10;
var legendRectSize = 18,
legendSpacing = 4;
var color = d3.scale.category20b();
var arc = d3.svg.arc()
.outerRadius(radius);
var arcOver = d3.svg.arc()
.outerRadius(radius + 10);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.data.count; });
var labelArc = d3.svg.arc()
.outerRadius(radius - 40)
.innerRadius(radius - 40);
var svg = d3.select("#chart").append("svg")
.datum(data)
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var arcs = svg.selectAll(".arc")
.data(pie)
.enter().append("g")
.attr("class", "arc");
var arcs2 = svg.selectAll(".arc2")
.data(pie)
.enter().append("g")
.attr("class", "arc2");
arcs.append("path")
.attr("fill", function(d, i) { return color(i); })
.on("mouseover", function(d) {
var htmlMsg="";
div.transition()
.style("opacity",0.9);
var total = d3.sum(data.map(function(d) {
return d.count;
}));
var percent = Math.round(1000 * d.data.count / total) / 10;
div.html(
"IP :"+ d.data.IP +""+"<br/>"+
"Count : " + d.data.count +"<br/>" +
"Percent: " + percent + '%'+ htmlMsg)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY) + "px");
svg.selectAll("path").sort(function (a, b) {
if (a != d) return -1;
else return 1;
});
var endAngle = d.endAngle + 0.1;
var startAngle = d.startAngle - 0.1;
var arcOver = d3.svg.arc()
.outerRadius(radius + 10).endAngle(endAngle).startAngle(startAngle);
d3.select(this)
.attr("stroke","white")
.transition()
.ease("bounce")
.duration(1000)
.attr("d", arcOver)
.attr("stroke-width",6);
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
d3.select(this).transition()
.attr("d", arc)
.attr("stroke","none");
})
.transition()
.ease("bounce")
.duration(2000)
.attrTween("d", tweenPie);
function tweenPie(b) {
b.innerRadius = 0;
var i = d3.interpolate({startAngle: 0, endAngle: 0}, b);
return function(t) { return arc(i(t)); };
}
var k=0;
arcs2.append("text")
.transition()
.ease("elastic")
.duration(2000)
.delay(function (d, i) {
return i * 250;
})
.attr("x","6")
.attr("dy", ".35em")
.text(function(d) { if(d.data.count >0){ k = k+1; return d.data.count;} })
.attr("transform", function(d) { if (k >1){return "translate(" + labelArc.centroid(d) + ") rotate(" + angle(d) + ")";} else{return "rotate(-360)";} })
.attr("font-size", "10px");
function type(d) {
d.count = +d.count;
return d;
}
function angle(d) {
var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;
return a > 90 ? a - 180 : a;
}
var legend = d3.select("#chart")
.append("svg")
.attr("class", "legend")
.attr("width", radius+50)
.attr("height", radius * 2)
.selectAll("g")
.data(color.domain())
.enter()
.append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append('rect')
.attr('width', legendRectSize)
.attr('height', legendRectSize)
.style('fill', color)
.style('stroke', color);
legend.append('text')
.attr('x', legendRectSize + legendSpacing)
.attr('y', legendRectSize - legendSpacing)
.data(data)
.text(function(d,i) { return d.IP; });
</script>
</body>
</html>
I am trying to make a pie chart with the provided dataset and I am facing error. How to define the parameter d to fetch the data from the variable "data" and its subsequent values "IP" and "count"? I dont know what mistake I am doing in my codes. What should I change in my current codes so that I can get a pie chart with current data format? Please help me. I am stuck. The condition is I should not use any kind of .csv or .tsv file in this code for importing. Thanks for any help.
One issue is with your data array... you need to remove the first item in it [ Also, you are missing a ',' after the item. but the item is itself not required as its an array ].
Second is with d.data.count inside the pie function... you need to refer it as d[1] as you need to plot the second item in data array in your chart.
Working code below:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Testing Pie Chart</title>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<style type="text/css">
#chart {
margin-top: 100px;
position: absolute;
margin-right: 50px;
margin-left: 50px;
}
.tooltip {
background: #eee;
box-shadow: 0 0 5px #999999;
color: #900C3F;
display: inline-block;
font-size: 12px;
left: 600px;
padding: 10px;
position: absolute;
text-align: center;
top: 95px;
width: 150px;
z-index: 10;
opacity: 1;
}
rect {
stroke-width: 2;
}
path {
stroke: #ffffff;
stroke-width: 0.5;
}
div.tooltip {
position: absolute;
z-index: 999;
padding: 10px;
background: #f4f4f4;
border: 0px;
border-radius: 3px;
pointer-events: none;
font-size: 11px;
color: #000;
line-height: 16px;
border: 1px solid #d4d4d4;
}
.legend{
margin-left: 300px;
}
</style>
</head>
<body>
<div id="chart"></div>
<div id="toolTip" class="tooltip" style="opacity: 0;"></div>
<script type="text/javascript">
var div = d3.select("#toolTip");
var data = [
["192.168.12.1", "20"],
["76.09.45.34", "40"],
["34.91.23.76", "80"],
["192.168.19.32", "16"],
["192.168.10.89", "50"],
["192.178.34.07", "18"],
["192.168.12.98", "30"]];
var width = 300,
height = 300;
var margin = {top: 15, right: 15, bottom: 20, left: 40},
radius = Math.min(width, height) / 2 - 10;
var legendRectSize = 18,
legendSpacing = 4;
var color = d3.scale.category20b();
var arc = d3.svg.arc()
.outerRadius(radius);
var arcOver = d3.svg.arc()
.outerRadius(radius + 10);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d[1]; });
var labelArc = d3.svg.arc()
.outerRadius(radius - 40)
.innerRadius(radius - 40);
var svg = d3.select("#chart").append("svg")
.datum(data)
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var arcs = svg.selectAll(".arc")
.data(pie)
.enter().append("g")
.attr("class", "arc");
var arcs2 = svg.selectAll(".arc2")
.data(pie)
.enter().append("g")
.attr("class", "arc2");
arcs.append("path")
.attr("fill", function(d, i) { return color(i); })
.on("mouseover", function(d) {
var htmlMsg="";
div.transition()
.style("opacity",0.9);
var total = d3.sum(data.map(function(d) {
return d.count;
}));
var percent = Math.round(1000 * d.data.count / total) / 10;
div.html(
"IP :"+ d.data.IP +""+"<br/>"+
"Count : " + d.data.count +"<br/>" +
"Percent: " + percent + '%'+ htmlMsg)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY) + "px");
svg.selectAll("path").sort(function (a, b) {
if (a != d) return -1;
else return 1;
});
var endAngle = d.endAngle + 0.1;
var startAngle = d.startAngle - 0.1;
var arcOver = d3.svg.arc()
.outerRadius(radius + 10).endAngle(endAngle).startAngle(startAngle);
d3.select(this)
.attr("stroke","white")
.transition()
.ease("bounce")
.duration(1000)
.attr("d", arcOver)
.attr("stroke-width",6);
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
d3.select(this).transition()
.attr("d", arc)
.attr("stroke","none");
})
.transition()
.ease("bounce")
.duration(2000)
.attrTween("d", tweenPie);
function tweenPie(b) {
b.innerRadius = 0;
var i = d3.interpolate({startAngle: 0, endAngle: 0}, b);
return function(t) { return arc(i(t)); };
}
var k=0;
arcs2.append("text")
.transition()
.ease("elastic")
.duration(2000)
.delay(function (d, i) {
return i * 250;
})
.attr("x","6")
.attr("dy", ".35em")
.text(function(d) { if(d.data.count >0){ k = k+1; return d.data.count;} })
.attr("transform", function(d) { if (k >1){return "translate(" + labelArc.centroid(d) + ") rotate(" + angle(d) + ")";} else{return "rotate(-360)";} })
.attr("font-size", "10px");
function type(d) {
d.count = +d.count;
return d;
}
function angle(d) {
var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;
return a > 90 ? a - 180 : a;
}
var legend = d3.select("#chart")
.append("svg")
.attr("class", "legend")
.attr("width", radius+50)
.attr("height", radius * 2)
.selectAll("g")
.data(color.domain())
.enter()
.append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append('rect')
.attr('width', legendRectSize)
.attr('height', legendRectSize)
.style('fill', color)
.style('stroke', color);
legend.append('text')
.attr('x', legendRectSize + legendSpacing)
.attr('y', legendRectSize - legendSpacing)
.data(data)
.text(function(d,i) { return d.IP; });
</script>
</body>
</html>
Your data input format is wrong.
Change from:
var data = [ ["IP", "count"]
["192.168.12.1", "20"],
["76.09.45.34", "40"],
["34.91.23.76", "80"],
["192.168.19.32", "16"],
["192.168.10.89", "50"],
["192.178.34.07", "18"],
["192.168.12.98", "30"]];
to
var data = [
{"IP":"192.168.12.1", "count":"20"},
{"IP":"76.09.45.34", "count":"40"},
{"IP":"34.91.23.76", "count":"80"},
{"IP":"192.168.19.32", "count":"16"},
{"IP":"192.168.10.89", "count":"50"},
{"IP":"192.178.34.07", "count":"18"},
{"IP":"192.168.12.98", "count":"30"}
];

I need to draw a chord in d3 in eclipse shape rather as circle

Here is my sample js file i need to draw a chord but in eclipse shape rather then a circle. Secondly i need to know that what is a matrix use while creating chord diagram and are we able to draw a chord with simple json file (without using matrix) as mentioned http://www.delimited.io/blog/2013/12/8/chord-diagrams-in-d3 here. Because in every example of chord some matrix is give to draw it. I am new to d3 i need to learn lot of things. Can any one help really appreciate it
var outerRadius = 500 / 2,
innerRadius = outerRadius - 100;
var fill = d3.scale.category20c();
var chord = d3.layout.chord()
.padding(.04)
.sortSubgroups(d3.descending)
.sortChords(d3.descending);
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(innerRadius + 20);
var svg = d3.select('#content').append("svg")
.attr("width", outerRadius * 2)
.attr("height", outerRadius * 2)
.append("g")
.attr("transform", "translate(" + outerRadius + "," + outerRadius +
")");
d3.json("readme.json", function(error, imports) {
if (error) throw error;
var indexByName = d3.map(),
nameByIndex = d3.map(),
matrix = [],
n = 0;
// Returns the Flare package name for the given class name.
function name(name) {
return name.substring(0, name.lastIndexOf(".")).substring(6);
}
// Compute a unique index for each package name.
imports.forEach(function(d) {
if (!indexByName.has(d = name(d.name))) {
nameByIndex.set(n, d);
indexByName.set(d, n++);
}
});
// Construct a square matrix counting package imports.
imports.forEach(function(d) {
var source = indexByName.get(name(d.name)),
row = matrix[source];
if (!row) {
row = matrix[source] = [];
for (var i = -1; ++i < n;) row[i] = 0;
}
d.imports.forEach(function(d) { row[indexByName.get(name(d))]++; });
});
chord.matrix(matrix);
var g = svg.selectAll("g.group")
.data(chord.groups())
.enter().append("svg:g")
.attr("class", "group")
.on("mouseover", fade(.02))
.on("mouseout", fade(.80));
// .on("mouseover", mouseover);
//.on("mouseout", fade(1));
g.append("svg:path")
.style("stroke", "none")
.style("fill", function(d) { return fill(d.index); })
.attr("d", arc);
/* g.append("path")
.style("fill", function(d) { return fill(d.index); })
.style("stroke", function(d) { return fill(d.index); })
.attr("d", arc);*/
g.append("text")
.each(function(d) { d.angle = (d.startAngle + d.endAngle) / 2; })
.attr("dy", ".35em")
.attr("transform", function(d) {
return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")"
+ "translate(" + (innerRadius + 26) + ")"
+ (d.angle > Math.PI ? "rotate(180)" : "");
})
.style("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; })
.text(function(d) { return nameByIndex.get(d.index); });
svg.selectAll(".chord")
.data(chord.chords)
.enter().append("path")
.attr("class", "chord")
.style("stroke", function(d) { return
d3.rgb(fill(d.source.index)).darker(); })
.style("fill", function(d) { return fill(d.source.index); })
//.style("opacity", 1)
.attr("d", d3.svg.chord().radius(innerRadius));
});
d3.select(self.frameElement).style("height", outerRadius * 5 + "px");
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
#tooltip {
color: white;
opacity: .9;
background: #333;
padding: 5px;
border: 1px solid lightgrey;
border-radius: 5px;
position: absolute;
z-index: 10;
visibility: hidden;
white-space: nowrap;
pointer-events: none;
}
#circle circle {
fill: none;
pointer-events: all;
}
path.group {
fill-opacity: .8;
}
path.chord {
fill-opacity: .8;
stroke: #000;
stroke-width: .25px;
}
#circle:hover path.fade {
display: none;
}
</style>
</head>
<body>
<div id="tooltip"></div>
<script src="lib/d3.js"></script>
<script src="lib/underscore.js"></script>
<script src="js/mapper.js"></script>
<script>
//*******************************************************************
// CREATE MATRIX AND MAP
//*******************************************************************
d3.csv('data/CNV.csv', function (error, data) {
var mpr = chordMpr(data);
mpr
.addValuesToMap('chr_no')
.addValuesToMap('MUT')
mpr .setFilter(function (row, a, b) {
return (row.chr_no === a.name && row.MUT === b.name) ||
(row.chr_no === b.name && row.MUT === a.name)
})
.setAccessor(function (recs, a, b) {
if (!recs[0]) return 0;
return recs[0].MUT === a.name ? +recs[0].chr_start :
+recs[0].chr_stop ;
});
drawChords(mpr.getMatrix(), mpr.getMap());
});
//*******************************************************************
// DRAW THE CHORD DIAGRAM
//*******************************************************************
function drawChords (matrix, mmap) {
var w = 980, h = 800, r1 = h / 2, r0 = r1 - 110;
var fill = d3.scale.ordinal()
.range(['#c7b570','#c6cdc7','#335c64','#768935',
'#507282','#5c4a56','#aa7455','#574109','#837722',
'#73342d','#0a5564','#9c8f57','#7895a4','#4a5456',
'#b0a690','#0a3542',]);
var chord = d3.layout.chord()
.padding(.04)
.sortSubgroups(d3.descending)
.sortChords(d3.descending);
var arc = d3.svg.arc()
.innerRadius(r0)
.outerRadius(r0 + 20);
var svg = d3.select("body").append("svg:svg")
.attr("width", w)
.attr("height", h)
.append("svg:g")
.attr("id", "circle")
.attr("transform", "translate(" + w / 2 + "," + h / 2 + ")");
svg.append("circle")
.attr("r", r0 + 20);
var rdr = chordRdr(matrix, mmap);
chord.matrix(matrix);
var g = svg.selectAll("g.group")
.data(chord.groups())
.enter().append("svg:g")
.attr("class", "group")
.on("mouseover", mouseover)
.on("mouseout", function (d) {
d3.select("#tooltip").style("visibility", "hidden") });
g.append("svg:path")
.style("stroke", "black")
.style("fill", function(d) { return fill(rdr(d).gname); })
.attr("d", arc);
g.append("svg:text")
.each(function(d) { d.angle = (d.startAngle + d.endAngle) / 2;
})
.attr("dy", ".35em")
.style("font-family", "helvetica, arial, sans-serif")
.style("font-size", "9px")
.attr("text-anchor", function(d) { return d.angle > Math.PI ?
"end" : null; })
.attr("transform", function(d) {
return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")"
+ "translate(" + (r0 + 26) + ")"
+ (d.angle > Math.PI ? "rotate(180)" : "");
})
.text(function(d) { return rdr(d).gname; });
var chordPaths = svg.selectAll("path.chord")
.data(chord.chords())
.enter().append("svg:path")
.attr("class", "chord")
.style("stroke", function(d) { return
d3.rgb(fill(rdr(d).sname)).darker(); })
.style("fill", function(d) { return fill(rdr(d).sname); })
.attr("d", d3.svg.chord().radius(r0))
.on("mouseover", function (d) {
d3.select("#tooltip")
.style("visibility", "visible")
.html(chordTip(rdr(d)))
.style("top", function () { return (d3.event.pageY -
170)+"px"})
.style("left", function () { return (d3.event.pageX -
100)+"px";})
})
.on("mouseout", function (d) {
d3.select("#tooltip").style("visibility", "hidden") });
function chordTip (d) {
var p = d3.format(".0%"), q = d3.format("0d")
return "Choromosome information:<br/>"
+ q(d.sname) + " overlap with " + d.tname +" " +
"<br/>chromosome starts at"+" "+ d.sdata +" " +
"<br/>chromosome ends at"+ " "+ d.tdata
}
}
function mouseover(d, i) {
d3.select("#tooltip")
.style("visibility", "visible")
.html(groupTip(rdr(d)))
.style("top", function () { return (d3.event.pageY - 80)+"px"})
.style("left", function () { return (d3.event.pageX - 130)+"px";})
chordPaths.classed("fade", function(p) {
return p.source.index != i
&& p.target.index != i;
});
}
}
</script>

Categories

Resources