Skip to content

Instantly share code, notes, and snippets.

@mayblue9
Forked from sangheestyle/README.md
Created July 13, 2016 04:20
Show Gist options
  • Save mayblue9/cea6dcd81d0534b9559f60d8781329ad to your computer and use it in GitHub Desktop.
Save mayblue9/cea6dcd81d0534b9559f60d8781329ad to your computer and use it in GitHub Desktop.
Developers' relationship, take 2

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

You might want to know what the graph represents

  • Each circle shows each developer.
  • Each color of inner circle represents each company which hires the developer.
  • Each diameter of outer circle represents how many code lines added by the developer.
  • You can see developer's name and how many code lines added by him or her when you do mouse over the circle.

You can generate the json file by flatiron.

This example is based on Couchand's block 6495846.

{
"directed": false,
"graph": [],
"nodes": [
{
"deletions": 1,
"company": "sonyericsson.com",
"insertions": 1,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 16,
"company": "google.com",
"insertions": 18,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 2,
"company": "google.com",
"insertions": 5,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 163,
"company": "google.com",
"insertions": 236,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 5,
"company": "google.com",
"insertions": 3,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 1,
"company": "google.com",
"insertions": 1,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 7,
"company": "sonymobile.com",
"insertions": 14,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 10514,
"company": "google.com",
"insertions": 16573,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 31,
"company": "google.com",
"insertions": 29,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 6,
"company": "google.com",
"insertions": 10,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 27,
"company": "linaro.org",
"insertions": 29,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 10,
"company": "google.com",
"insertions": 7,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 328,
"company": "google.com",
"insertions": 653,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 12,
"company": "google.com",
"insertions": 16,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 4,
"company": "htc.com",
"insertions": 5,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 17,
"company": "google.com",
"insertions": 21,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 7,
"company": "sonymobile.com",
"insertions": 11,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 220,
"company": "google.com",
"insertions": 255,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 194,
"company": "android.com",
"insertions": 178,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 1906,
"company": "google.com",
"insertions": 2030,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 2,
"company": "google.com",
"insertions": 2,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 14,
"company": "codeaurora.org",
"insertions": 16,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 52,
"company": "google.com",
"insertions": 47,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 12,
"company": "google.com",
"insertions": 68,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 22,
"company": "google.com",
"insertions": 24,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 1,
"company": "intel.com",
"insertions": 1,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 1,
"company": "google.com",
"insertions": 1,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 3457,
"company": "google.com",
"insertions": 3199,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 12,
"company": "google.com",
"insertions": 31,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 4,
"company": "google.com",
"insertions": 15,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 12,
"company": "google.com",
"insertions": 41,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 1,
"company": "lge.com",
"insertions": 1,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 20,
"company": "google.com",
"insertions": 61,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 9,
"company": "google.com",
"insertions": 11,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 1,
"company": "google.com",
"insertions": 2,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 7,
"company": "lge.com",
"insertions": 1,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 1,
"company": "google.com",
"insertions": 1,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 16,
"company": "google.com",
"insertions": 27,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 11,
"company": "lge.com",
"insertions": 7,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 45,
"company": "google.com",
"insertions": 151,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 4,
"company": "google.com",
"insertions": 16,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 2,
"company": "google.com",
"insertions": 2,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 4,
"company": "sonymobile.com",
"insertions": 4,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 1,
"company": "htc.com",
"insertions": 3,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 17,
"company": "sonymobile.com",
"insertions": 35,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 172,
"company": "google.com",
"insertions": 155,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 8,
"company": "htc.com",
"insertions": 9,
"bipartite": 0,
"id": "[email protected]"
},
{
"deletions": 29,
"company": "android.com",
"insertions": 61,
"bipartite": 0,
"id": "[email protected]"
}
],
"links": [
{
"source": 0,
"target": 2
},
{
"source": 1,
"target": 27
},
{
"source": 1,
"target": 10
},
{
"source": 3,
"target": 24
},
{
"source": 3,
"target": 23
},
{
"source": 3,
"target": 12
},
{
"source": 3,
"target": 4
},
{
"source": 4,
"target": 24
},
{
"source": 4,
"target": 12
},
{
"source": 5,
"target": 36
},
{
"source": 5,
"target": 41
},
{
"source": 6,
"target": 25
},
{
"source": 7,
"target": 19
},
{
"source": 8,
"target": 27
},
{
"source": 8,
"target": 17
},
{
"source": 8,
"target": 10
},
{
"source": 9,
"target": 12
},
{
"source": 10,
"target": 27
},
{
"source": 10,
"target": 17
},
{
"source": 10,
"target": 20
},
{
"source": 11,
"target": 27
},
{
"source": 12,
"target": 24
},
{
"source": 13,
"target": 32
},
{
"source": 13,
"target": 47
},
{
"source": 14,
"target": 37
},
{
"source": 15,
"target": 27
},
{
"source": 15,
"target": 17
},
{
"source": 16,
"target": 39
},
{
"source": 17,
"target": 40
},
{
"source": 17,
"target": 29
},
{
"source": 17,
"target": 44
},
{
"source": 17,
"target": 26
},
{
"source": 17,
"target": 27
},
{
"source": 17,
"target": 33
},
{
"source": 18,
"target": 27
},
{
"source": 18,
"target": 35
},
{
"source": 18,
"target": 33
},
{
"source": 18,
"target": 38
},
{
"source": 20,
"target": 27
},
{
"source": 21,
"target": 45
},
{
"source": 21,
"target": 34
},
{
"source": 22,
"target": 27
},
{
"source": 22,
"target": 45
},
{
"source": 22,
"target": 30
},
{
"source": 22,
"target": 28
},
{
"source": 26,
"target": 27
},
{
"source": 27,
"target": 35
},
{
"source": 27,
"target": 33
},
{
"source": 27,
"target": 40
},
{
"source": 27,
"target": 29
},
{
"source": 27,
"target": 38
},
{
"source": 27,
"target": 44
},
{
"source": 28,
"target": 30
},
{
"source": 31,
"target": 46
},
{
"source": 31,
"target": 42
},
{
"source": 31,
"target": 43
},
{
"source": 31,
"target": 47
},
{
"source": 33,
"target": 35
},
{
"source": 34,
"target": 45
},
{
"source": 36,
"target": 41
},
{
"source": 42,
"target": 43
},
{
"source": 42,
"target": 46
},
{
"source": 42,
"target": 47
},
{
"source": 43,
"target": 46
},
{
"source": 43,
"target": 47
},
{
"source": 46,
"target": 47
}
],
"multigraph": false
}
<html>
<head>
<style>
.node {
opacity: 0.6;
}
.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 title(d) { return d.id+" "+d.insertions; }
function group(d) { return d.company; }
var color = d3.scale.category10();
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(-700)
.friction(0.3)
.linkDistance(55)
.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', title)
.attr('class', 'node')
.call( force.drag );
node.append('circle')
.attr('r', function(d) {return Math.sqrt(d.insertions)+5})
.attr('fill', 'gray')
.attr('fill-opacity', 0.3);
node.append('circle')
.attr('r', 5)
.attr('fill', colorByGroup);
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