Cycle digram with d3.js.
Built with blockbuilder.org
Cycle digram with d3.js.
Built with blockbuilder.org
<!DOCTYPE html> | |
<html> | |
<head> | |
<script data-require="[email protected]" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script> | |
<script src="//labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script> | |
<style> | |
body { | |
font: 12px sans-serif; | |
} | |
.d3-tip { | |
line-height: 1; | |
font-weight: bold; | |
padding: 12px; | |
background: rgba(0, 0, 0, 0.8); | |
color: #fff; | |
border-radius: 2px; | |
pointer-events: none; | |
} | |
/* Creates a small triangle extender for the tooltip */ | |
.d3-tip:after { | |
box-sizing: border-box; | |
display: inline; | |
font-size: 10px; | |
width: 100%; | |
line-height: 1; | |
color: rgba(0, 0, 0, 0.8); | |
position: absolute; | |
pointer-events: none; | |
} | |
/* Westward tooltips */ | |
.d3-tip.w:after { | |
content: "\25B6"; | |
margin: -4px 0 0 -1px; | |
top: 50%; | |
left: 100%; | |
} | |
</style> | |
</head> | |
<body> | |
<script> | |
var data = [{ | |
label: 'one', | |
children: ['all', 'the', 'rain'] | |
}, { | |
label: 'two', | |
children: ['fails', 'mainly'] | |
}, { | |
label: 'three', | |
children: ['on', 'the', 'plains'] | |
}, { | |
label: 'four', | |
children: ['now', 'is', 'the'] | |
}, { | |
label: 'five', | |
children: ['time', 'for', 'all'] | |
}, { | |
label: 'seven', | |
children: ['good', 'men', 'to'] | |
}, { | |
label: 'eight', | |
children: ['come', 'to', 'the'] | |
}, { | |
label: 'nine', | |
children: ['aid', 'of their', 'country'] | |
}], | |
width = 500, | |
height = 500, | |
c = Math.min(width, height) / 2, | |
ro = Math.min(width, height) / 2 - (c * .3), | |
ri = Math.min(width, height) / 2 - (c * .6), | |
a = (Math.PI * 2) / data.length, | |
colors = d3.scale.category10(); | |
var tip = d3.tip() | |
.attr('class', 'd3-tip') | |
.direction('w') | |
.html(function(d) { | |
return d.children.join(" ") | |
}); | |
var arc = d3.svg.arc() | |
.innerRadius(ri) | |
.outerRadius(ro); | |
var svg = d3.select('body') | |
.append('svg') | |
.attr('width', 500) | |
.attr('height', 500) | |
.call(tip); | |
svg = svg.append('g') | |
.attr('transform', 'translate(' + c + ',' + c + ')') | |
var arcs = svg.selectAll('.cycle') | |
.data(data); | |
var arcsG = arcs.enter() | |
.append('g') | |
.attr('class', 'cycle'); | |
arcsG | |
.append("path") | |
.attr('class', 'cycle') | |
.style('fill', function(d, i) { | |
return colors(i); | |
}) | |
.attr("id", function(d) { | |
return "path" + d.label; | |
}) | |
.attr("d", function(d, i) { | |
arc.startAngle(a * i); | |
arc.endAngle(a * (i + 1)); | |
d.centroid = arc.centroid(); | |
return arc(); | |
}) | |
.on('mouseover', tip.show) | |
.on('mouseout', tip.hide); | |
arcsG | |
.append("text") | |
.attr("transform", function(d) { | |
return "translate(" + d.centroid + ")"; | |
}) | |
.text(function(d) { | |
return d.label; | |
}) | |
.style("fill", "white") | |
.style("text-anchor", "middle") | |
.style("alignment-baseline", "middle") | |
.style("pointer-events", "none"); | |
// draw arrow heads last so they end up on top | |
arcs | |
.enter() | |
.append('polygon') | |
.attr("points", function(d, i) { | |
var sta = a * i, | |
spa = a * (i + 1); | |
// determine points for arrowhead | |
arrowHead = [Math.cos(spa - Math.PI / 2) * (ri - 15), Math.sin(spa - Math.PI / 2) * (ri - 15)] + ' '; | |
arrowHead += [Math.cos(spa - Math.PI / 2) * (ro + 15), Math.sin(spa - Math.PI / 2) * (ro + 15)] + ' '; | |
arrowHead += [Math.cos(spa - Math.PI / 2 + ((spa - sta) / 4)) * (ri + (ro - ri) / 2), Math.sin(spa - Math.PI / 2 + ((spa - sta) / 4)) * (ri + (ro - ri) / 2)]; | |
return arrowHead; | |
}) | |
.style("fill", function(d, i) { | |
return colors(i); | |
}) | |
.style("stroke", function(d, i) { | |
return colors(i); | |
}); | |
</script> | |
</body> | |
</html> |