Skip to content

Instantly share code, notes, and snippets.

@sangheestyle
Created December 10, 2014 07:30
Show Gist options
  • Save sangheestyle/e0e412c549f16d738557 to your computer and use it in GitHub Desktop.
Save sangheestyle/e0e412c549f16d738557 to your computer and use it in GitHub Desktop.
Developers' relationship, take 1

A simple example to show developers' relationship by analyzing commits in AOSP frameworks/base repository. Only commits submitted within past 2 months were used for generating this relationship. You might want to click 'open in a new window' link (right) to see this on larger window.

This graph was built by the following.

  • making edges by developer to his or her modified file (bipartite graph)
  • making projection by developer nodes

Each dot shows each developer and each color of circle represents each company which hires the developer. You can generate the json file by flatiron.

This example is based on Couchand's block 6495846.

{
"directed": false,
"graph": [],
"nodes": [
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "sonyericsson.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "sonymobile.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "linaro.org",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "htc.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "sonymobile.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "android.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "codeaurora.org",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "lge.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "lge.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "lge.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "sonymobile.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "htc.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "sonymobile.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "google.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "htc.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "intel.com",
"bipartite": 0,
"id": "[email protected]"
},
{
"company": "android.com",
"bipartite": 0,
"id": "[email protected]"
}
],
"links": [
{
"source": 0,
"target": 39
},
{
"source": 1,
"target": 3
},
{
"source": 2,
"target": 28
},
{
"source": 2,
"target": 12
},
{
"source": 4,
"target": 26
},
{
"source": 4,
"target": 25
},
{
"source": 4,
"target": 14
},
{
"source": 4,
"target": 5
},
{
"source": 5,
"target": 26
},
{
"source": 5,
"target": 14
},
{
"source": 6,
"target": 37
},
{
"source": 6,
"target": 43
},
{
"source": 7,
"target": 48
},
{
"source": 7,
"target": 32
},
{
"source": 7,
"target": 44
},
{
"source": 7,
"target": 45
},
{
"source": 7,
"target": 50
},
{
"source": 8,
"target": 49
},
{
"source": 9,
"target": 21
},
{
"source": 10,
"target": 28
},
{
"source": 10,
"target": 19
},
{
"source": 10,
"target": 12
},
{
"source": 11,
"target": 14
},
{
"source": 12,
"target": 28
},
{
"source": 12,
"target": 19
},
{
"source": 12,
"target": 22
},
{
"source": 13,
"target": 28
},
{
"source": 14,
"target": 26
},
{
"source": 15,
"target": 33
},
{
"source": 15,
"target": 50
},
{
"source": 16,
"target": 38
},
{
"source": 17,
"target": 28
},
{
"source": 17,
"target": 19
},
{
"source": 18,
"target": 41
},
{
"source": 19,
"target": 42
},
{
"source": 19,
"target": 30
},
{
"source": 19,
"target": 46
},
{
"source": 19,
"target": 27
},
{
"source": 19,
"target": 28
},
{
"source": 19,
"target": 34
},
{
"source": 20,
"target": 28
},
{
"source": 20,
"target": 36
},
{
"source": 20,
"target": 34
},
{
"source": 20,
"target": 40
},
{
"source": 22,
"target": 28
},
{
"source": 23,
"target": 47
},
{
"source": 23,
"target": 35
},
{
"source": 24,
"target": 28
},
{
"source": 24,
"target": 47
},
{
"source": 24,
"target": 31
},
{
"source": 24,
"target": 29
},
{
"source": 27,
"target": 28
},
{
"source": 28,
"target": 36
},
{
"source": 28,
"target": 34
},
{
"source": 28,
"target": 42
},
{
"source": 28,
"target": 30
},
{
"source": 28,
"target": 40
},
{
"source": 28,
"target": 46
},
{
"source": 29,
"target": 31
},
{
"source": 32,
"target": 45
},
{
"source": 32,
"target": 44
},
{
"source": 32,
"target": 48
},
{
"source": 32,
"target": 50
},
{
"source": 34,
"target": 36
},
{
"source": 35,
"target": 47
},
{
"source": 37,
"target": 43
},
{
"source": 44,
"target": 48
},
{
"source": 44,
"target": 45
},
{
"source": 44,
"target": 50
},
{
"source": 45,
"target": 48
},
{
"source": 45,
"target": 50
},
{
"source": 48,
"target": 50
}
],
"multigraph": false
}
<html>
<head>
<style>
.node {
opacity: 0.5;
}
.node:hover {
opacity: 1;
}
.link {
stroke: #999;
stroke-opacity: 0.2;
}
.link:hover {
stroke: #999;
stroke-opacity: 0.8;
}
</style>
<script src="http://d3js.org/d3.v3.min.js"></script>
</head>
<body>
<div id="viz"></div>
<script>
function email(d) { return d.id; }
function group(d) { return d.company; }
var color = d3.scale.category20();
function colorByGroup(d) { return color(group(d)); }
var width = 960,
height = 500;
var svg = d3.select('#viz')
.append('svg')
.attr('width', width)
.attr('height', height);
var node, link;
var voronoi = d3.geom.voronoi()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.clipExtent([[-10, -10], [width+10, height+10]]);
function recenterVoronoi(nodes) {
var shapes = [];
voronoi(nodes).forEach(function(d) {
if ( !d.length ) return;
var n = [];
d.forEach(function(c){
n.push([ c[0] - d.point.x, c[1] - d.point.y ]);
});
n.point = d.point;
shapes.push(n);
});
return shapes;
}
var force = d3.layout.force()
.charge(-500)
.friction(0.3)
.linkDistance(50)
.size([width, height]);
force.on('tick', function() {
node.attr('transform', function(d) { return 'translate('+d.x+','+d.y+')'; })
.attr('clip-path', function(d) { return 'url(#clip-'+d.index+')'; });
link.attr('x1', function(d) { return d.source.x; })
.attr('y1', function(d) { return d.source.y; })
.attr('x2', function(d) { return d.target.x; })
.attr('y2', function(d) { return d.target.y; });
var clip = svg.selectAll('.clip')
.data( recenterVoronoi(node.data()), function(d) { return d.point.index; } );
clip.enter().append('clipPath')
.attr('id', function(d) { return 'clip-'+d.point.index; })
.attr('class', 'clip');
clip.exit().remove()
clip.selectAll('path').remove();
clip.append('path')
.attr('d', function(d) { return 'M'+d.join(',')+'Z'; });
});
d3.json('developers.json', function(err, data) {
data.nodes.forEach(function(d, i) {
d.nid = i;
});
link = svg.selectAll('.link')
.data( data.links )
.enter().append('line')
.attr('class', 'link')
.style("stroke-width", function(d) { return Math.sqrt(d.value); });
node = svg.selectAll('.node')
.data( data.nodes )
.enter().append('g')
.attr('title', email)
.attr('class', 'node')
.call( force.drag );
node.append('circle')
.attr('r', 12)
.attr('fill', colorByGroup)
.attr('fill-opacity', 0.5);
node.append('circle')
.attr('r', 2)
.attr('stroke', 'black');
force
.nodes( data.nodes )
.links( data.links )
.start();
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment