Skip to content

Instantly share code, notes, and snippets.

@widged
Last active June 13, 2021 09:49
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save widged/3847527 to your computer and use it in GitHub Desktop.
Save widged/3847527 to your computer and use it in GitHub Desktop.
D3 companion planting
var r1 = 900 / 2,
r0 = r1 - 200;
var chord = d3.layout.chord()
.padding(0.02)
.sortSubgroups(d3.descending)
.sortChords(d3.descending);
var arc = d3.svg.arc()
.innerRadius(r0)
.outerRadius(r0 + 20);
var svg = d3.select("body").append("svg")
.attr("width", r1 * 2)
.attr("height", r1 * 2)
.append("g")
.attr("transform", "translate(" + r1 + "," + r1 + ")");
/** Returns an event handler for fading a given chord group. */
function fade(opacity) {
return function(g, i) {
svg.selectAll("g path.chord")
.filter(function(d) {
return d.source.index != i && d.target.index != i;
})
.transition()
.style("opacity", opacity);
};
}
function draw(companions) {
var indexByName = {},
nameByIndex = {},
matrix = [],
n = 0;
// Compute a unique index for each name.
var families= {},
f = 0,
indexInFamily = 0,
familyHue = 0,
hueStep = 26;
companions.forEach(function(d) {
p = d.name;
console.log();
if(!families[d.family] || !families[d.family].color) {
f++;
var hSaturation = (f % 2 !== 0) ? 0.5 : 0.9;
var hLightness = (f % 2 !== 0) ? 0.5 : 0.9;
indexInFamily = 1;
families[d.family] = {name: d.family,color: d3.hsl(familyHue, hSaturation, hLightness)}; familyHue+= hueStep;
}
else
{
indexInFamily++;
}
var baseColor = families[d.family].color;
// var ramp=d3.scale.linear().domain([0,6]).range(["#fdfdfd",baseColor]);
d.recolor = d3.rgb(baseColor); // d3.rgb(ramp(indexInFamily));
if (!(d in indexByName)) {
nameByIndex[n] = p;
indexByName[p] = n++;
}
});
// Construct a square matrix counting relationships.
companions.forEach(function(d) {
var source = indexByName[d.name],
row = matrix[source];
if (!row) {
row = matrix[source] = [];
for (var i = -1; ++i < n;) row[i] = 0;
}
d.companions.forEach(function(d) { row[indexByName[d]]++; });
});
chord.matrix(matrix);
var g = svg.selectAll("g.group")
.data(chord.groups)
.enter().append("g")
.attr("class", "group");
g.append("path")
.style("fill", function(d, i) { return companions[i].recolor; })
.style("stroke", function(d, i) { return companions[i].recolor.darker(); })
.attr("d", arc)
.on("mouseover", fade(0.1))
.on("mouseout", fade(1));
g.append("text")
.each(function(d) { d.angle = (d.startAngle + d.endAngle) / 2; })
.attr("dy", ".35em")
.attr("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; })
.attr("transform", function(d) {
return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")"
+ "translate(" + (r0 + 26) + ")"
+ (d.angle > Math.PI ? "rotate(180)" : "");
})
.text(function(d) { return nameByIndex[d.index]; });
svg.selectAll("path.chord")
.data(chord.chords)
.enter().append("path")
.attr("class", "chord")
.style("stroke", function(d, i) { return companions[d.source.index].recolor.darker(); })
.style("fill", function(d, i) { return companions[d.source.index].recolor; })
.attr("d", d3.svg.chord().radius(r0));
}
d3.json("companions.json",draw);
[
{"family": "Alliaceae" , "name": "chive" , "size":1, "companions":[]},
{"family": "Alliaceae" , "name": "leek" , "size":1, "companions":["onion","celery","carrot"]},
{"family": "Alliaceae" , "name": "onion" , "size":1, "companions":["beet", "strawberry", "tomato", "lettuce", "bean"]},
{"family": "Amaranthaceae" , "name": "beet" , "size":1, "companions":["onion", "kohlrabi"]},
{"family": "Amaranthaceae" , "name": "spinach" , "size":1, "companions":["strawberry"]},
{"family": "Apiaceae" , "name": "carrot" , "size":1, "companions":["pea", "lettuce", "chive", "onion", "leek", "rosemary", "sage", "tomato"]},
{"family": "Apiaceae" , "name": "celery" , "size":1, "companions":["leek", "tomato", "bean-bush", "cauliflower", "cabbage"]},
{"family": "Apiaceae" , "name": "dill" , "size":1, "companions":["cabbage","carrot"]},
{"family": "Apiaceae" , "name": "parsley" , "size":1, "companions":["tomato","asparagus"]},
{"family": "Asteraceae" , "name": "lettuce" , "size":1, "companions":[]},
{"family": "Asteraceae" , "name": "chamomile" , "size":1, "companions":["cabbage","onion"]},
{"family": "Asteraceae" , "name": "marigold" , "size":1, "companions":[]},
{"family": "Asteraceae" , "name": "sunflower" , "size":1, "companions":["cucumber"]},
{"family": "Brassicaceae" , "name": "cabbage" , "size":1, "companions":["potato", "celery", "dill", "chamomile", "sage", "thyme", "mint", "pennyroyal", "rosemary", "lavender", "beet", "onion"]},
{"family": "Brassicaceae" , "name": "cauliflower", "size":1, "companions":[]},
{"family": "Brassicaceae" , "name": "horseradish", "size":1, "companions":["potato", "plum"]},
{"family": "Brassicaceae" , "name": "kohlrabi" , "size":1, "companions":[]},
{"family": "Brassicaceae" , "name": "radish" , "size":1, "companions":["pea", "nasturtium", "lettuce", "cucumber"]},
{"family": "Cucurbitaceae" , "name": "cucumber" , "size":1, "companions":["bean", "corn", "pea", "radish", "sunflower"]},
{"family": "Cucurbitaceae" , "name": "pumpkin" , "size":1, "companions":["corn"]},
{"family": "Cucurbitaceae" , "name": "squash" , "size":1, "companions":["nasturtium", "corn"]},
{"family": "Fabaceae" , "name": "bean" , "size":1, "companions":["potato", "carrot", "cucumber", "cauliflower", "cabbage"]},
{"family": "Fabaceae" , "name": "bean-bush" , "size":1, "companions":["sunflower", "cucumber", "potato", "corn", "celery"]},
{"family": "Fabaceae" , "name": "bean-lima" , "size":1, "companions":[]},
{"family": "Fabaceae" , "name": "pea" , "size":1, "companions":["squash"]},
{"family": "Poaceae" , "name": "corn" , "size":1, "companions":["potato","pea","bean","cucumber","pumpkin","squash"]},
{"family": "Solanaceae" , "name": "eggplant" , "size":1, "companions":["bean"]},
{"family": "Solanaceae" , "name": "potato" , "size":1, "companions":["horseradish", "bean", "corn", "cabbage", "marigold", "bean-lima", "eggplant"]},
{"family": "Solanaceae" , "name": "tomato" , "size":1, "companions":["chive","onion", "parsley", "asparagus", "marigold", "nasturtium", "carrot", "bean"]},
{"family": "Other" , "name": "asparagus" , "size":1, "companions":["tomato","parsley","basil"]},
{"family": "Tropaeolaceae" , "name": "nasturtium" , "size":1, "companions":["cucumber","squash","tomato", "radish","cabbage"]},
{"family": "Lamiaceae" , "name": "basil" , "size":1, "companions":["tomato"]},
{"family": "Lamiaceae" , "name": "lavender" , "size":1, "companions":[]},
{"family": "Lamiaceae" , "name": "mint" , "size":1, "companions":["cabbage","tomato"]},
{"family": "Lamiaceae" , "name": "pennyroyal" , "size":1, "companions":[]},
{"family": "Lamiaceae" , "name": "rosemary" , "size":1, "companions":["carrot", "bean", "cabbage", "sage"]},
{"family": "Lamiaceae" , "name": "sage" , "size":1, "companions":["rosemary", "carrot", "cabbage", "pea", "bean"]},
{"family": "Lamiaceae" , "name": "thyme" , "size":1, "companions":["cabbage"]},
{"family": "Boraginaceae" , "name": "borage" , "size":1, "companions":["tomato","squash","strawberry"]},
{"family": "Fruit" , "name": "plum" , "size":1, "companions":[]},
{"family": "Fruit" , "name": "strawberry" , "size":1, "companions":["bean-bush", "spinach", "borage", "lettuce"]}
]
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Companion Planting Chord Diagram</title>
<script src="http://d3js.org/d3.v2.js"></script>
<style>
body {
font: 11px sans-serif;
}
path.chord {
fill-opacity: .3;
stroke-opacity: .4;
}
</style>
</head>
<body>
<script type="text/javascript" src="companionchord.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment