Skip to content

Instantly share code, notes, and snippets.

@nitaku
Last active July 17, 2017 12:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nitaku/f86779216b57d41504adb78db0ca4992 to your computer and use it in GitHub Desktop.
Save nitaku/f86779216b57d41504adb78db0ca4992 to your computer and use it in GitHub Desktop.
Force layout node-link
svg = d3.select 'svg'
width = svg.node().getBoundingClientRect().width
height = svg.node().getBoundingClientRect().height
# Data
graph = {
nodes: [
{id: 'A'}
{id: 'B'}
{id: 'C'}
{id: 'D'}
{id: 'E'}
]
links: [
{source: 'A', target: 'B'}
{source: 'A', target: 'C'}
{source: 'A', target: 'D'}
{source: 'B', target: 'C'}
{source: 'C', target: 'E'}
{source: 'E', target: 'A'}
]
}
# objectify the graph
index = {}
graph.nodes.forEach (d) -> index[d.id] = d
graph.links.forEach (l) ->
l.source = index[l.source]
l.target = index[l.target]
# Layout
simulation = d3.forceSimulation()
.force('link', d3.forceLink()
.id((d) -> d.id)
.strength(0.5))
.force('charge', d3.forceManyBody())
.force('center', d3.forceCenter(width/2, height/2))
# Vis
links_layer = svg.append 'g'
nodes_layer = svg.append 'g'
nodes = nodes_layer.selectAll '.node'
.data graph.nodes
enn = nodes.enter().append 'g'
.attrs
class: 'node'
enn.append 'circle'
.attrs
r: 3
enn.append 'text'
.text (d) -> d.id
.attrs
dy: '1.2em'
links = links_layer.selectAll '.link'
.data graph.links
enl = links.enter().append 'line'
.attrs
class: 'link'
# Simulation
simulation
.nodes(graph.nodes)
.on 'tick', () ->
enn.attrs
transform: (d) -> "translate(#{d.x}, #{d.y})"
enl.attrs
x1: (d) -> d.source.x
y1: (d) -> d.source.y
x2: (d) -> d.target.x
y2: (d) -> d.target.y
simulation.force('link')
.links(graph.links)
body, html {
padding: 0;
margin: 0;
height: 100%;
}
svg {
width: 100%;
height: 100%;
background: white;
}
.node circle {
fill: #333;
stroke: white;
}
.node text {
font-family: sans-serif;
font-size: 12px;
text-anchor: middle;
}
.link {
stroke: #CCC;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Force layout node-link</title>
<link type="text/css" href="index.css" rel="stylesheet"/>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-selection-multi.v0.4.min.js"></script>
</head>
<body>
<svg></svg>
<script src="index.js"></script>
</body>
</html>
// Generated by CoffeeScript 1.10.0
(function() {
var enl, enn, graph, height, index, links, links_layer, nodes, nodes_layer, simulation, svg, width;
svg = d3.select('svg');
width = svg.node().getBoundingClientRect().width;
height = svg.node().getBoundingClientRect().height;
graph = {
nodes: [
{
id: 'A'
}, {
id: 'B'
}, {
id: 'C'
}, {
id: 'D'
}, {
id: 'E'
}
],
links: [
{
source: 'A',
target: 'B'
}, {
source: 'A',
target: 'C'
}, {
source: 'A',
target: 'D'
}, {
source: 'B',
target: 'C'
}, {
source: 'C',
target: 'E'
}, {
source: 'E',
target: 'A'
}
]
};
index = {};
graph.nodes.forEach(function(d) {
return index[d.id] = d;
});
graph.links.forEach(function(l) {
l.source = index[l.source];
return l.target = index[l.target];
});
simulation = d3.forceSimulation().force('link', d3.forceLink().id(function(d) {
return d.id;
}).strength(0.5)).force('charge', d3.forceManyBody()).force('center', d3.forceCenter(width / 2, height / 2));
links_layer = svg.append('g');
nodes_layer = svg.append('g');
nodes = nodes_layer.selectAll('.node').data(graph.nodes);
enn = nodes.enter().append('g').attrs({
"class": 'node'
});
enn.append('circle').attrs({
r: 3
});
enn.append('text').text(function(d) {
return d.id;
}).attrs({
dy: '1.2em'
});
links = links_layer.selectAll('.link').data(graph.links);
enl = links.enter().append('line').attrs({
"class": 'link'
});
simulation.nodes(graph.nodes).on('tick', function() {
enn.attrs({
transform: function(d) {
return "translate(" + d.x + ", " + d.y + ")";
}
});
return enl.attrs({
x1: function(d) {
return d.source.x;
},
y1: function(d) {
return d.source.y;
},
x2: function(d) {
return d.target.x;
},
y2: function(d) {
return d.target.y;
}
});
});
simulation.force('link').links(graph.links);
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment