I freely admit that this is outrageously geeky. A conversation with folks on twitter led to attempts to try and describe, visually, polyamorous relationships. We kept finding ourselves annotating the links between us, notably with each end of the link, and adding other types of relationships, not all formal or even romantic. This is simply the standard FDL example, with info added about relationship meaning when you hover over the relationship link itself.
Last active
June 27, 2024 15:31
-
-
Save makyo/6754267 to your computer and use it in GitHub Desktop.
Mapping poly relationships with force directed layouts
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": | |
[ | |
{"name": "Makyo"}, | |
{"name": "JD"}, | |
{"name": "Lexy"}, | |
{"name": "Forneus"}, | |
{"name": "Des"}, | |
{"name": "Peri"}, | |
{"name": "The Cloud™", | |
"attrs": {"x": -20, "y": -20, "r": 20, "fill": "#eee", | |
"stroke": "#000", "stroke-width": "1px", | |
"stroke-dasharray": "5,5"}}, | |
{"name": "Cullen"}, | |
{"name": "Osric"}, | |
{"name": "Bel"}, | |
{"name": "Sean"}, | |
{"name": "Kader"} | |
], | |
"links": | |
[ | |
{"source": 0, "target": 1, "value": 1, "targetMeaning": "husbandog", | |
"sourceMeaning": "wifox", "linkMeaning": "partners, civil union"}, | |
{"source": 0, "target": 3, "value": 2, "targetMeaning": "catfriend", | |
"sourceMeaning": "foxfriend", "linkMeaning": "partners"}, | |
{"source": 3, "target": 4, "value": 1, "targetMeaning": "catfriend", | |
"sourceMeaning": "catfriend", "linkMeaning": "partners"}, | |
{"source": 0, "target": 2, "value": 2, "targetMeaning": "pet", | |
"sourceMeaning": "owner", "linkMeaning": "puppydog and her howner"}, | |
{"source": 0, "target": 7, "value": 3, "dashed": true, | |
"linkMeaning": "a little too far apart and a little too alike"}, | |
{"source": 0, "target": 5, "value": 4, "dashed": true}, | |
{"source": 0, "target": 9, "value": 4, "dashed": true, | |
"linkMeaning": "another universe, maybe"}, | |
{"source": 1, "target": 8, "value": 4, "dashed": true, | |
"linkMeaning": "another universe, maybe"}, | |
{"source": 8, "target": 9, "value": 1, "sourceMeaning": "husband", | |
"targetMeaning": "husband", "linkMeaning": "married"}, | |
{"source": 0, "target": 6, "value": 4, "dashed": true, | |
"targetMeaning": "squishees", "sourceMeaning": "squisher"}, | |
{"source": 4, "target": 10, "value": 2, "linkMeaning": "partner"}, | |
{"source": 10, "target": 11, "value": 1, "linkMeaning": "partner"} | |
] | |
} |
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> | |
<meta charset="utf-8"> | |
<style> | |
.link line { | |
stroke: rgba(0,0,0,0.35); | |
} | |
.link .meaning { | |
fill: #00F; | |
} | |
.node text { | |
pointer-events: none; | |
font: 10px sans-serif; | |
} | |
.hidden { | |
display: none; | |
} | |
</style> | |
<body> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script> | |
var width = 960, | |
height = 500 | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
var force = d3.layout.force() | |
.gravity(.05) | |
.distance(100) | |
.charge(-100) | |
.size([width, height]); | |
d3.json("graph.json", function(error, json) { | |
force | |
.nodes(json.nodes) | |
.links(json.links) | |
.distance(function(d) { return Math.log(d.value * 3) * 50; }) | |
.start(); | |
var link = svg.selectAll(".link") | |
.data(json.links) | |
.enter().append("g") | |
.attr("class", "link"); | |
link.append('text') | |
.attr('class', 'sourceMeaning meaning hidden') | |
.text(function(d) { return d.sourceMeaning }); | |
link.append('text') | |
.attr('class', 'targetMeaning meaning hidden') | |
.text(function(d) { return d.targetMeaning }); | |
link.append('text') | |
.attr('class', 'linkMeaning meaning hidden') | |
.text(function(d) { return d.linkMeaning || ''; }); | |
link.append('line') | |
.attr("stroke-width", function(d) { | |
return 10 / (d.value / 1); | |
}) | |
.attr("stroke-dasharray", function(d) { | |
if (d.dashed) { | |
return "5,5"; | |
} | |
}) | |
.on('mouseover', function(d) { | |
d3.select(this.parentNode).selectAll('.meaning') | |
.classed('hidden', false); | |
}) | |
.on('mouseout', function(d) { | |
d3.select(this.parentNode).selectAll('.meaning') | |
.classed('hidden', true); | |
}); | |
var node = svg.selectAll(".node") | |
.data(json.nodes) | |
.enter().append("g") | |
.attr("class", "node") | |
.call(force.drag); | |
node.append("circle") | |
.each(function(d) { | |
var attrs = d.attrs ? d.attrs : { | |
x: -10, | |
y: -10, | |
r: 10, | |
fill: '#888' | |
}; | |
d3.select(this).attr(attrs); | |
}); | |
node.append("text") | |
.attr("dx", function(d) { return d.attrs ? d.attrs.r + 2 : 12; }) | |
.attr("dy", ".35em") | |
.text(function(d) { return d.name }); | |
force.on("tick", function() { | |
link.select('line') | |
.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; }); | |
link.select('.sourceMeaning') | |
.attr('dx', function(d) { return d.source.x + 12}) | |
.attr('dy', function(d) { return d.source.y + 24}); | |
link.select('.targetMeaning') | |
.attr('dx', function(d) { return d.target.x + 12}) | |
.attr('dy', function(d) { return d.target.y + 24}); | |
link.select('.linkMeaning') | |
.attr('dx', function(d) { | |
return (d.source.x + ((d.target.x - d.source.x) / 2)); | |
}) | |
.attr('dy', function(d) { | |
return (d.source.y + ((d.target.y - d.source.y) / 2)); | |
}); | |
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); | |
}); | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment