Module graph visualisation
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
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>Module dependency graph</title> | |
<style> | |
.module .node { | |
stroke: black; | |
stroke-width: 1.5px; | |
} | |
.module .text { | |
font-size: 12px; | |
fill: white; | |
stroke: none; | |
margin: 50px; | |
} | |
.module[data-type="system"] { | |
fill: green; | |
} | |
.module[data-type="std"] { | |
fill: orange; | |
} | |
.module[data-type="local"] { | |
fill: gray; | |
} | |
.module[data-type="external"] { | |
fill: brown; | |
} | |
.link { | |
stroke: #999; | |
stroke-width: 1px; | |
stroke-opacity: .6; | |
} | |
body { | |
background: #222 url(data:image/png;base64,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); | |
color: white; | |
font-family: Monaco, Menlo,"Andale Mono","lucida console","Courier New", monospace; | |
} | |
</style> | |
</head> | |
<body> | |
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.v2.js?2.9.1"></script> | |
<script type="text/javascript" src="visualize.js"></script> | |
</body> | |
</html> |
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
document.body.innerHTML = ""; | |
var graph = { | |
"./main": { | |
"type": "local", | |
"requirements": { | |
"./utils/model": "./utils/model" | |
} | |
}, | |
"./utils/model": { | |
"type": "local", | |
"requirements": { | |
"panel": "sdk/panel", | |
"api-utils/functional": "api-utils/functional", | |
"devtools/scratchpad": "devtools/scratchpad", | |
"./controller": "./utils/controller", | |
"backbone/events": "backbone/events" | |
} | |
}, | |
"./utils/controller": { | |
"type": "local", | |
"requirements": { | |
// ... | |
} | |
}, | |
"api-utils/functional": { | |
"type": "deprecated", | |
"correction": "sdk/functional" | |
}, | |
"sdk/functional": { | |
"type": "std" | |
}, | |
"sdk/panel": { | |
"type": "std" | |
}, | |
"devtools/scratchpad": { | |
"type": "system" | |
}, | |
"backbone/events": { | |
"type": "external" | |
} | |
} | |
var width = window.innerWidth - 10 | |
var height = window.innerHeight - 10 | |
var svg = d3. | |
select('body'). | |
append('svg:svg'). | |
attr('width', width). | |
attr('height', height) | |
var force = d3. | |
layout. | |
force(). | |
charge(-500). | |
distance(100). | |
size([ width, height ]) | |
function modules(graph) { | |
return Object.keys(graph).map(function(id) { | |
var node = graph[id] | |
return { | |
id: id, | |
type: node.type, | |
requirements: node.requirements | |
} | |
}) | |
} | |
function connections(modules) { | |
var ids = modules.map(function(module) { return module.id }) | |
return modules.reduce(function(links, module) { | |
var requirements = module.requirements || {} | |
var dependencies = Object.keys(requirements).map(function(path) { | |
return requirements[path] | |
}) | |
return links.concat(dependencies.map(function(id) { | |
return { | |
from: module.id, | |
to: id, | |
source: modules.indexOf(module), | |
target: ids.indexOf(id) | |
} | |
})) | |
}, []) | |
} | |
function links(graph) { | |
return modules(graph).reduce(function(links, module) { | |
var requirements = module.requirements || {} | |
var dependencies = Object.keys(requirements).map(function(path) { | |
return requirements[path] | |
}) | |
return links.concat(dependencies .map(function(id) { | |
return { from: module.id, to: id } | |
})) | |
}, []) | |
} | |
function draw(graph) { | |
var nodes = modules(graph) | |
var links = connections(nodes) | |
force. | |
nodes(nodes). | |
links(links). | |
start() | |
var link = svg. | |
selectAll('line.link'). | |
data(links). | |
enter(). | |
append('svg:line'). | |
attr('class', 'link requirement'). | |
call(force.drag) | |
var node = svg. | |
selectAll('g.node'). | |
data(nodes) | |
node. | |
transition(). | |
duration(1000). | |
attr('r', 20) | |
// For each node, create svg group <g> to hold circle, image, and title | |
var module = node. | |
enter(). | |
append('svg:g'). | |
attr('class', 'node module'). | |
attr('data-type', function(node) { | |
return node.type | |
}). | |
call(force.drag) | |
module. | |
append('svg:circle'). | |
attr('class', 'node'). | |
attr('r', 15). | |
attr('cx', 0). | |
attr('cy', 0). | |
attr('id', function(node) { | |
return node.id | |
}) | |
module. | |
append('svg:text'). | |
attr('class', 'text'). | |
text(function(node) { | |
return node.id | |
}) | |
force.on("tick", function() { | |
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; }) | |
node. | |
//attr("cx", function($) { return $.x; }). | |
//attr("cy", function($) { return $.y; }) | |
attr("transform", function($) { | |
// <g> doesn't take x or y attributes but it can be | |
// positioned with a transformation | |
return "translate(" + $.x + "," + $.y + ")"; | |
}) | |
}) | |
} | |
draw(graph) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment