Last active
December 16, 2015 02:49
-
-
Save biovisualize/5365390 to your computer and use it in GitHub Desktop.
DAG arc diagram
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta http-equiv="content-type" content="text/html; charset=UTF-8"> | |
<title></title> | |
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script> | |
<style type="text/css"> | |
</style> | |
</head> | |
<body> | |
<script type="text/javascript"> | |
var w = 900, | |
h = 500; | |
var matrixSize = 8; | |
function generateDagAdjacencyList(_size){ | |
// Random lower diagonal matrix | |
var dagMatrix = d3.range(_size).map(function(d, i){ | |
return d3.range(_size).map(function(d2, i2){return (i-i2 > 0) ? +(Math.random() > 0.5): 0;}); | |
}); | |
// adjacencyList = {..., "7":[0,2,5],"8":[0,3,4,7],"9":[2,4,6]} | |
var adjacencyList = {}; | |
dagMatrix.forEach(function(d, i){ | |
return d.forEach(function(d2, i2){ | |
if(!adjacencyList[i]) adjacencyList[i] = []; | |
if(!!d2) adjacencyList[i].push(i2); | |
}); | |
}); | |
// dagObjectList = [{"node":8,"nodeName":"node8","link":[0,3,4,7],"idx":8}, ...] | |
var dagObjectList = d3.entries(adjacencyList).map(function(d, i){ | |
return {node: parseInt(d.key), nodeName: 'node'+ d.key, link: d.value, idx: i}; | |
}); | |
var sortedList = dagObjectList.sort(function(a, b){return b.link.length - a.link.length;}); | |
return sortedList; | |
} | |
var randomDag = generateDagAdjacencyList(matrixSize); | |
var svg = d3.select('body') | |
.append('svg') | |
.attr({width: w, height: h, xmlns: 'http://www.w3.org/2000/svg'}); | |
var rootGroup = svg.append('g') | |
.classed('root', true) | |
.attr({transform: 'translate(0,'+h/2+')'}); | |
var markerW = 8; | |
var marker = svg.append('defs') | |
.append('marker') | |
.attr({ | |
id: 'Triangle', | |
refX: markerW*2, | |
refY: markerW, | |
markerUnits: 'strokeWidth', | |
markerWidth: markerW + markerW, | |
markerHeight: markerW * 2 + markerW, | |
orient: 'auto' | |
}) | |
.append('path') | |
.attr({d: 'M 0 0 '+markerW*2+' '+markerW+' 0 '+markerW*2+' '+markerW/2+' '+markerW}); | |
var labelW = 60; | |
var labelH = 20; | |
var gap = 20; | |
var linkGenerator = d3.svg.line() | |
.x(function(d, i){return d[0];}) | |
.y(function(d, i){return d[1];}) | |
.interpolate('cardinal') | |
.tension(0); | |
var linkPath = function(d, i, pI){ | |
var neighbourIdx = randomDag.map(function(d, i){return d.node;}).indexOf(d); | |
var anchor1 = pI*(labelW+gap)+labelW/2; | |
var anchor2 = neighbourIdx*(labelW+gap)+labelW/2; | |
var isBackLink = (anchor2-anchor1) < 0; | |
var deltaAnchors = (anchor2-anchor1)/2; | |
var path = linkGenerator([[anchor1, (isBackLink) ? 0 : labelH], | |
[anchor1+deltaAnchors, deltaAnchors*0.8], | |
[anchor2, (isBackLink) ? 0 : labelH]]); | |
return path; | |
}; | |
var links = rootGroup.selectAll('g.links') | |
.data(randomDag, function(d, i){return d.idx;}) | |
.enter().append('g') | |
.classed('links', true); | |
links.selectAll('path.arrow') | |
.data(function(d, i){return d.link;}) | |
.enter().append('path') | |
.classed('arrow', true) | |
.attr({ | |
d: linkPath, | |
'marker-end': 'url(#Triangle)' | |
}) | |
.style({fill: 'none', stroke: 'black', opacity: 1, 'stroke-width': 1}); | |
links.selectAll('path.broad') | |
.data(function(d, i){return d.link;}) | |
.enter().append('path') | |
.classed('broad', true) | |
.attr({d: linkPath}) | |
.style({fill: 'none', stroke: 'orangered', opacity: 0.3, 'stroke-width': 20, 'stroke-linecap': 'round'}); | |
var labels = rootGroup.selectAll('g.labels') | |
.data(randomDag, function(d, i){return d.node;}) | |
.enter().append('g') | |
.classed('labels', true) | |
.attr({transform: function(d, i){return 'translate('+(i*(labelW+gap))+',0)';}}); | |
labels.append('rect') | |
.classed('label-frame', true) | |
.attr({ | |
x: 0, | |
y: 0, | |
width: labelW, | |
height: labelH, | |
}) | |
.style({fill: 'skyblue', stroke: 'grey'}); | |
labels.append('text') | |
.classed('label-text', true) | |
.attr({ | |
x: 4, | |
y: 0, | |
dy: '1em' | |
}) | |
.style({}) | |
.text(function(d, i){return d.nodeName;}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment