block by nstrayer 32611a741aeff274273dd7ca4389af44

Hive Plot (Links)

Full Screen

See my article on Krzywinski’s Hive Plots. See also area hive plots.

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.link {
  fill: none;
  stroke-width: 1.5px;
}

.axis, .node {
  stroke: #000;
  stroke-width: 1.5px;
}

</style>
<body>
<script src="//d3js.org/d3.v4.min.js"></script>
<script src="d3.hive.min.js"></script>
<script>

var width = 960,
    height = 500,
    innerRadius = 40,
    outerRadius = 240,
    numberOfGroups = 20,
    numberOfLinks = 3000,
    number_of_nodes = 100;
    
var angle  = d3.scalePoint().domain(d3.range(numberOfGroups)).range([0, 2 * Math.PI]),
    radius = d3.scaleLinear().range([innerRadius, outerRadius]),
    color  = d3.scaleOrdinal(d3.schemeCategory10).domain(d3.range(20));


// Returns a random integer between min (included) and max (excluded)
function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;
}

var newNodes = [];
for (var i = 0; i < number_of_nodes; i++) {
    var x = getRandomInt(0,numberOfGroups);
    var y = Math.random();
    var newNode = {"x": x, "y": y};
    newNodes.push(newNode);
}

//generate random links
var newLinks = [];
for (var i = 0; i < numberOfLinks; i++){
	var source = newNodes[getRandomInt(0,number_of_nodes)];
	var target = newNodes[getRandomInt(0,number_of_nodes)];
	var link = {"source": source, "target": target};
	newLinks.push(link);
}

newLinks.forEach((l) => {
	console.log("source: " + l.source.x + " | target: " + l.target.x );
})

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
/* 
svg.selectAll(".axis")
    .data(d3.range(3))
  .enter().append("line")
    .attr("class", "axis")
    .attr("transform", function(d) { return "rotate(" + degrees(angle(d)) + ")"; })
    .attr("x1", radius.range()[0])
    .attr("x2", radius.range()[1]); */

svg.selectAll(".link")
    .data(newLinks)
  .enter().append("path")
    .attr("class", "link")
    .attr("d", d3.hive.link()
      .angle(function(d) { return angle(d.x); })
      .radius(function(d) { return radius(d.y); })
     )
    .style("stroke", function(d) { return color(d.source.x); })
    .style("stroke-opacity", 0.1);

svg.selectAll(".node")
    .data(newNodes)
  .enter().append("circle")
    .attr("class", "node")
    .attr("transform", function(d) { return "rotate(" + degrees(angle(d.x)) + ")"; })
    .attr("cx", function(d) { return radius(d.y); })
    .attr("r", 5)
    .style("fill", function(d) { return color(d.x); })
	.style("opacity", 0)

function degrees(radians) {
  return radians / Math.PI * 180 - 90;
}

</script>
	

d3.hive.min.js

d3.hive={},d3.hive.link=function(){function t(t,s){var u,h=a(r,this,t,s),i=a(n,this,t,s);h.a>i.a&&(u=i,i=h,h=u),i.a-h.a>Math.PI&&(h.a+=2*Math.PI);var e=h.a+(i.a-h.a)/3,c=i.a-(i.a-h.a)/3;return h.r0-h.r1||i.r0-i.r1?"M"+Math.cos(h.a)*h.r0+","+Math.sin(h.a)*h.r0+"L"+Math.cos(h.a)*h.r1+","+Math.sin(h.a)*h.r1+"C"+Math.cos(e)*h.r1+","+Math.sin(e)*h.r1+" "+Math.cos(c)*i.r1+","+Math.sin(c)*i.r1+" "+Math.cos(i.a)*i.r1+","+Math.sin(i.a)*i.r1+"L"+Math.cos(i.a)*i.r0+","+Math.sin(i.a)*i.r0+"C"+Math.cos(c)*i.r0+","+Math.sin(c)*i.r0+" "+Math.cos(e)*h.r0+","+Math.sin(e)*h.r0+" "+Math.cos(h.a)*h.r0+","+Math.sin(h.a)*h.r0:"M"+Math.cos(h.a)*h.r0+","+Math.sin(h.a)*h.r0+"C"+Math.cos(e)*h.r1+","+Math.sin(e)*h.r1+" "+Math.cos(c)*i.r1+","+Math.sin(c)*i.r1+" "+Math.cos(i.a)*i.r1+","+Math.sin(i.a)*i.r1}function a(t,a,r,n){var e=t.call(a,r,n),c=+("function"==typeof s?s.call(a,e,n):s)+i,o=+("function"==typeof u?u.call(a,e,n):u),M=u===h?o:+("function"==typeof h?h.call(a,e,n):h);return{r0:o,r1:M,a:c}}var r=function(t){return t.source},n=function(t){return t.target},s=function(t){return t.angle},u=function(t){return t.radius},h=u,i=-Math.PI/2;return t.source=function(a){return arguments.length?(r=a,t):r},t.target=function(a){return arguments.length?(n=a,t):n},t.angle=function(a){return arguments.length?(s=a,t):s},t.radius=function(a){return arguments.length?(u=h=a,t):u},t.startRadius=function(a){return arguments.length?(u=a,t):u},t.endRadius=function(a){return arguments.length?(h=a,t):h},t};