Last active
June 20, 2017 10:31
-
-
Save FHell/70f4ea7e93bdc4349fce35929d653dad to your computer and use it in GitHub Desktop.
Scratchpad for networks
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
{ | |
"nodes": [ | |
{ | |
"id": 1, | |
"name": "A" | |
}, | |
{ | |
"id": 2, | |
"name": "B" | |
}, | |
{ | |
"id": 3, | |
"name": "C" | |
}, | |
{ | |
"id": 4, | |
"name": "D" | |
}, | |
{ | |
"id": 5, | |
"name": "E" | |
}, | |
{ | |
"id": 6, | |
"name": "F" | |
}, | |
{ | |
"id": 7, | |
"name": "G" | |
}, | |
{ | |
"id": 8, | |
"name": "H" | |
}, | |
{ | |
"id": 9, | |
"name": "I" | |
}, | |
{ | |
"id": 10, | |
"name": "J" | |
} | |
], | |
"links": [ | |
{ | |
"source": 1, | |
"target": 2 | |
}, | |
{ | |
"source": 1, | |
"target": 5 | |
}, | |
{ | |
"source": 1, | |
"target": 6 | |
}, | |
{ | |
"source": 2, | |
"target": 3 | |
}, | |
{ | |
"source": 2, | |
"target": 7 | |
} | |
, | |
{ | |
"source": 3, | |
"target": 4 | |
}, | |
{ | |
"source": 8, | |
"target": 3 | |
} | |
, | |
{ | |
"source": 4, | |
"target": 5 | |
} | |
, | |
{ | |
"source": 4, | |
"target": 9 | |
}, | |
{ | |
"source": 5, | |
"target": 10 | |
} | |
] | |
} | |
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> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.js"></script> | |
<style> | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
</style> | |
</head> | |
<body> | |
<div id="option"> | |
<input name="toggleButton" | |
type="button" | |
value="Toggle" | |
onclick="toggle()" /> | |
</div> | |
<script> | |
var simWorker = new Worker('simulation.js'); | |
var svg = d3.select("body").append("svg") | |
.attr("width", 960) | |
.attr("height", 500) | |
var width = +svg.attr("width") | |
var height = +svg.attr("height") | |
var state | |
var index | |
toggle_text = svg.append("text") | |
.text("Forces On") | |
.attr("y", 30) | |
.attr("x", 30) | |
.style("font-size", 36) | |
.style("font-family", "monospace") | |
loading_text = svg.append("text") | |
.text("Loading...") | |
.attr("y", 60) | |
.attr("x", 30) | |
.style("font-size", 36) | |
.style("font-family", "monospace") | |
worker_text = svg.append("text") | |
.text("Loading...") | |
.attr("y", 90) | |
.attr("x", 30) | |
.style("font-size", 36) | |
.style("font-family", "monospace") | |
linkForce = d3.forceLink().id(function(d) { return d.id; }) | |
manyBodyForce = d3.forceManyBody().strength(-400) | |
centerForce = d3.forceCenter(width / 2, height / 2) | |
simulation = d3.forceSimulation() | |
.force("link", linkForce) | |
.force("charge", manyBodyForce) | |
.force("center", centerForce); | |
d3.json("data.json", function(e, d) {simulate_graph(d)}) | |
function simulate_graph(graph_loaded){ | |
graph = graph_loaded | |
index = new Object() | |
graph.nodes.forEach(function(node, i) {index[node.id] = i}) | |
loading_text.text("JSON loaded and processing") | |
var link = svg.append("g") | |
.style("stroke", "#aaa") | |
.selectAll("line") | |
.data(graph.links) | |
.enter().append("line"); | |
var node = svg.append("g") | |
.attr("class", "nodes") | |
.selectAll("circle") | |
.data(graph.nodes) | |
.enter().append("circle") | |
.attr("r", 6) | |
.call(d3.drag() | |
.on("start", dragstarted) | |
.on("drag", dragged) | |
.on("end", dragended)) | |
.on("click", clicked); | |
node | |
.attr("r", 20) | |
.style("fill", "#d9d9d9") | |
.style("stroke", "#969696") | |
.style("stroke-width", "1px") | |
data = { | |
m_type: "network", | |
graph: graph | |
}; | |
simWorker.postMessage(data) | |
simWorker.onmessage = e => { | |
states = e.data | |
node.style("fill", function(d) { return d3.interpolateRainbow(states[index[d.id]] % 1) } ) | |
.attr("r", function(d) {return 7 * Math.sin(states[index[d.id]]) + 10}) | |
worker_text.text("Worker message recevied with " + states) | |
} | |
worker_text.text("Worker callback set") | |
simulation.nodes(graph.nodes) | |
simulation.force("link").links(graph.links); | |
simulation.on("tick", ticked); | |
ticks = 0 | |
var buffer = new ArrayBuffer(graph.nodes.length * 8) | |
var states = new Float64Array(buffer) | |
var index = new Object() | |
graph.nodes.forEach(function(node, i) {index[node.id] = i; states[i] = 0}) | |
function ticked() { | |
ticks += 1 | |
loading_text.text("JSON loaded and tick " + ticks) | |
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; }) | |
} | |
} | |
t = true | |
function dragstarted(d) { | |
/* I don't understand this line at all*/ | |
if (!d3.event.active) simulation.alphaTarget(0.3).restart(); | |
d.fx = d.x; | |
d.fy = d.y; | |
} | |
function dragged(d) { | |
d.fx = d3.event.x; | |
d.fy = d3.event.y; | |
} | |
function dragended(d) { | |
/* I don't understand this line at all*/ | |
if (!d3.event.active) simulation.alphaTarget(0); | |
d.fx = null; | |
d.fy = null; | |
} | |
function clicked(d) { | |
data = {m_type: 'perturbation', perturbation: d.id} | |
simWorker.postMessage(data) | |
} | |
function toggle() { | |
if (t) { | |
toggle_text.text("Forces Off") | |
t = false | |
simulation | |
.force("link", null) | |
.force("charge", null) | |
.force("center", null); | |
} else { | |
toggle_text.text("Forces On") | |
t = true | |
simulation | |
.force("link", linkForce) | |
.force("charge", manyBodyForce) | |
.force("center", centerForce); | |
simulation.alpha(1).alphaTarget(0).restart(); | |
} | |
} | |
</script> | |
</body> |
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
var graph = null | |
var simulation_running = false | |
var simulation = null | |
var states | |
var buffer | |
var index | |
onmessage = function(e) { | |
switch (e.data.m_type){ | |
case 'network': | |
graph = e.data.graph | |
initialize_simulation(graph) | |
break | |
case 'sim_on': | |
start_simulation() | |
break | |
case 'sim_off': | |
stop_simulation() | |
break | |
case 'perturbation': | |
perturb_simulation(e.data.perturbation) | |
break | |
} | |
} | |
function initialize_simulation(g) { | |
buffer = new ArrayBuffer(graph.nodes.length * 8) | |
states = new Float64Array(buffer) | |
index = new Object() | |
graph.nodes.forEach(function(node, i) {index[node.id] = i; states[i] = 0}) | |
start_simulation() | |
} | |
function start_simulation(){ | |
simulation = setInterval(function () {states[0] += 0.07; postMessage(states);}, 50) | |
} | |
function stop_simulation(){ | |
if (simulation) { | |
clearInterval(simulation) | |
} | |
} | |
function perturb_simulation(perturbation){ | |
if (simulation) { | |
states[index[perturbation]] += 0.7 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment