A simple editor to allow the manipulation of force-directed graph parameters.
This example is based on Mike Bostock's block 4062045.
This simple force-directed graph shows character co-occurence in Les Misérables. A physical simulation of charged particles and springs places related characters in closer proximity, while unrelated characters are farther apart. Layout algorithm inspired by Tim Dwyer and Thomas Jakobsen. Data based on character coappearence in Victor Hugo's Les Misérables, compiled by Donald Knuth.
xxxxxxxxxx
<meta charset="utf-8">
<link rel="stylesheet" href="https://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.9.1.js"></script>
<script src="https://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<style>
.node {
stroke: #fff;
stroke-width: 1.5px;
}
.link {
stroke: #999;
stroke-opacity: .6;
}
.controls {
position: fixed;
bottom: 0;
left: 0;
margin: 0;
padding-left: 8px;
padding-bottom: 5px;
}
.controls li {
width: 400px;
list-style-type: none;
}
.controls div {
width: 200px;
float: right;
}
</style>
<body>
<ul class="controls">
<li>charge(<span class="value">-120</span>)<div id="charge"></div></li>
<li>linkDistance(<span class="value">30</span>)<div id="linkDistance"></div></li>
<li>linkStrength(<span class="value">1</span>)<div id="linkStrength"></div></li>
<li>gravity(<span class="value">0.1</span>)<div id="gravity"></div></li>
<li>friction(<span class="value">0.9</span>)<div id="friction"></div></li>
<li>theta(<span class="value">0.8</span>)<div id="theta"></div></li>
</ul>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
var width = 960,
height = 500;
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var params = {
charge: { min: -1000, max: 10, step: 5, value: -120 },
linkDistance: { min: 0, max: 1000, step: 5, value: 30 },
linkStrength: { min: 0, max: 1, step: 0.05, value: 1 },
gravity: { min: -1, max: 1, step: 0.05, value: 0.1 },
friction: { min: 0, max: 1, step: 0.05, value: 0.9 },
theta: { min: 0, max: 1, step: 0.05, value: 0.8 }
};
function onSlide(param) {
return function(e, ui) {
$(this).closest('li').find('.value').text(ui.value);
force[param](ui.value);
force.start();
};
}
$('.controls div').each(function() {
var param = $(this).attr('id');
console.log(param);
$(this).slider({
slide: onSlide(param),
min: params[param].min,
max: params[param].max,
step: params[param].step,
value: params[param].value
});
});
d3.json("miserables.json", function(error, graph) {
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return Math.sqrt(d.value); });
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 5)
.style("fill", function(d) { return color(d.group); })
.call(force.drag);
node.append("title")
.text(function(d) { return d.name; });
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(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
});
</script>
Modified http://code.jquery.com/jquery-1.9.1.js to a secure url
Modified http://code.jquery.com/ui/1.10.3/jquery-ui.js to a secure url
Modified http://d3js.org/d3.v3.min.js to a secure url
https://code.jquery.com/jquery-1.9.1.js
https://code.jquery.com/ui/1.10.3/jquery-ui.js
https://d3js.org/d3.v3.min.js