Skip to content

Instantly share code, notes, and snippets.

@fernandogelin
Last active June 2, 2016 13:22
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 fernandogelin/8f8867141db460f94d21a64d6ef7c80f to your computer and use it in GitHub Desktop.
Save fernandogelin/8f8867141db460f94d21a64d6ef7c80f to your computer and use it in GitHub Desktop.
Beer Flavor Wheel
{
"name": "",
"children": [
{
"name": "malt",
"children": [
{
"name": "dark",
"children": [
{"name": "roasted", "size": 1},
{"name": "burnt/charred", "size": 1},
{"name": "coffee", "size": 1},
{"name": "dark chocolate", "size":1},
{"name": "tobacco", "size": 1},
{"name": "licorice", "size": 1},
{"name": "tea", "size": 1},
{"name": "milk chocolate", "size": 1},
{"name": "toasted nuts", "size": 1},
{"name": "bonfire", "size": 1}
]
},
{
"name": "speciality grains",
"children": [
{"name": "smoked meat", "size": 1},
{"name": "islay whisky", "size": 1},
{"name": "wheat", "size": 1},
{"name": "raisins", "size": 1},
{"name": "creamy", "size": 1},
{"name": "spicy/herbal", "size": 1},
{"name": "nutty", "size": 1}
]
},
{
"name": "caramalt and crystal malt",
"children": [
{"name": "caramel", "size": 1},
{"name": "toffee", "size": 1},
{"name": "barley sugar", "size": 1}
]
},
{
"name": "pale",
"children": [
{"name": "malt drink", "size": 1},
{"name": "honey", "size": 1},
{"name": "brown bread", "size": 1},
{"name": "crackers", "size": 1},
{"name": "toast", "size": 1},
{"name": "white bread", "size": 1},
{"name": "cereal", "size": 1},
{"name": "biscuit", "size": 1}
]
}
]
},
{
"name": "hops",
"children": [
{
"name": "bitterness",
"children": [
{"name": "earthy", "size": 1},
{"name": "peppery", "size": 1},
{"name": "botanic", "size": 1},
{"name": "pithy", "size": 1},
{"name": "dry", "size": 1}
]
},
{
"name": "english",
"children": [
{"name": "berries", "size": 1},
{"name": "orchad fruit", "size": 1},
{"name": "woody", "size": 1},
{"name": "elderflower", "size": 1},
{"name": "hedgerow", "size": 1},
{"name": "peppery", "size": 1}
]
},
{
"name": "central european",
"children": [
{"name": "herbal", "size": 1},
{"name": "grassy", "size": 1},
{"name": "stone fruit", "size": 1},
{"name": "floral", "size": 1}
]
},
{
"name": "southern hemisphere",
"children": [
{"name": "lemony", "size": 1},
{"name": "gooseberry", "size": 1},
{"name": "grapes", "size": 1},
{"name": "tropical fruits", "size": 1},
{"name": "passion fruit", "size": 1},
{"name": "cut grass", "size": 1}
]
},
{
"name": "american",
"children": [
{"name": "grapefruit", "size": 1},
{"name": "orange", "size": 1},
{"name": "pine", "size": 1},
{"name": "red berries", "size": 1},
{"name": "herbal", "size": 1},
{"name": "blossom", "size": 1}
]
}
]
},
{
"name": "yeast",
"children": [
{
"name": "esters",
"children": [
{"name": "vanilla", "size": 1},
{"name": "bubblegum", "size": 1},
{"name": "banana", "size": 1},
{"name": "pear", "size": 1},
{"name": "strawberry", "size": 1},
{"name": "almond", "size": 1},
{"name": "rose", "size": 1},
{"name": "clove", "size": 1},
{"name": "pinapple", "size": 1},
{"name": "apple", "size": 1}
]
},
{
"name": "yeast profile",
"children": [
{"name": "clean", "size": 1},
{"name": "fruity", "size": 1},
{"name": "peppery/spicy", "size": 1}
]
},
{
"name": "wild and bacteria",
"children": [
{"name": "farmyard", "size": 1},
{"name": "lactic", "size": 1},
{"name": "acetic/vinegar", "size": 1},
{"name": "acidic/citrus", "size": 1}
]
}
]
},
{
"name": "water",
"children": [
{
"name": "soft",
"children": [
{"name": "soft", "size": 1},
{"name": "clean", "size": 1},
{"name": "light", "size": 1}
]
},
{
"name": "hard",
"children": [
{"name": "dry", "size": 1},
{"name": "mineral", "size": 1},
{"name": "bitter", "size": 1}
]
}
]
},
{
"name": "bad",
"children": [
{"name": "infection",
"children": [
{"name": "sour", "size": 1},
{"name": "funky", "size": 1},
{"name": "phenol antiseptico", "size": 1}
]
},
{
"name": "undesirable and brewing faults",
"children": [
{"name": "burnt rubber", "size": 1},
{"name": "skunked", "size": 1},
{"name": "soy sauce", "size": 1},
{"name": "butter", "size": 1},
{"name": "cheesy", "size": 1},
{"name": "baby sick/diapers", "size": 1},
{"name": "sweet corn/cabbage", "size": 1},
{"name": "apple peel/juice", "size": 1},
{"name": "solvent/nail polish", "size": 1},
{"name": "cardboard/wet paper", "size": 1},
{"name": "sherry", "size": 1}
]
}
]
},
{
"name": "mouthfeel",
"children": [
{"name": "heavy/thick", "size": 1},
{"name": "smooth/velvety", "size": 1},
{"name": "creamy", "size": 1},
{"name": "chewy", "size": 1},
{"name": "round/fat", "size": 1},
{"name": "thin", "size": 1},
{"name": "dry", "size": 1},
{"name": "acrid", "size": 1},
{"name": "astringent", "size": 1},
{"name": "sharp", "size": 1},
{"name": "fizzy", "size": 1},
{"name": "flat", "size": 1},
{"name": "delicate", "size": 1}
]
},
{
"name": "sugar",
"children": [
{"name": "molasses", "size": 1},
{"name": "dried fruit", "size": 1},
{"name": "candy", "size": 1},
{"name": "creamy (milk/sugar)", "size": 1}
]
},
{
"name": "alcohol",
"children": [
{"name": "warming", "size": 1},
{"name": "slick", "size": 1},
{"name": "spirit", "size": 1}
]
},
{
"name": "barrel-aged",
"children": [
{"name": "spice", "size": 1},
{"name": "smoke", "size": 1},
{"name": "wood", "size": 1}
]
}
]
}
<!DOCTYPE html>
<meta charset="utf-8">
<style>
path {
stroke: #fff;
fill-rule: evenodd;
}
text {
font-family: Helvetica, sans-serif;
font-size: 12px;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var width = 960,
height = 700,
radius = Math.min(width, height) / 2.1;
var x = d3.scale.linear()
.range([0, 2 * Math.PI]);
var y = d3.scale.linear()
.range([0, radius]);
var color = d3.scale.category20c();
var colorBeer = ["#ffffff", "#d77f59", "#31302c", "#4c3b2b",
"#94523a", "#ffe93e", "#ffff45", "#70db70",
"#33cc33", "#2eb82e", "#29a329", "#248f24",
"#f49f44", "#d77f59", "#94523a", "#804541",
"#e6f2ff", "#80bfff", "#0073e6", "#b30000",
"#990000", "#800000", "#00b3b3", "#006600",
"#66ffff", "#666633"]
var color2 = d3.scale.ordinal()
.range(colorBeer);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + (height / 2 + 10) + ")");
var partition = d3.layout.partition()
.value(function(d) { return d.size; });
var arc = d3.svg.arc()
.startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x))); })
.endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))); })
.innerRadius(function(d) { return Math.max(0, y(d.y) - 10); })
.outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)); });
d3.json("beer-flavor-v2.json", function(error, root) {
var g = svg.selectAll("g")
.data(partition.nodes(root))
.enter().append("g");
var path = g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color2((d.children ? d : d.parent).name); })
.on("click", click);
var text = g.append("text")
.attr("transform", function(d) { return "rotate(" + computeTextRotation(d) + ")"; })
.attr("x", function(d) { return y(d.y); })
.attr("dx", "6") // margin
.attr("dy", ".35em") // vertical-align
.text(function(d) { return d.name; });
function click(d) {
// fade out all text elements
text.transition().attr("opacity", 0);
path.transition()
.duration(750)
.attrTween("d", arcTween(d))
.each("end", function(e, i) {
// check if the animated element's data e lies within the visible angle span given in d
if (e.x >= d.x && e.x < (d.x + d.dx)) {
// get a selection of the associated text element
var arcText = d3.select(this.parentNode).select("text");
// fade in the text element and recalculate positions
arcText.transition().duration(750)
.attr("opacity", 1)
.attr("transform", function() { return "rotate(" + computeTextRotation(e) + ")" })
.attr("x", function(d) { return y(d.y); });
}
});
}
});
d3.select(self.frameElement).style("height", height + "px");
// Interpolate the scales!
function arcTween(d) {
var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
yd = d3.interpolate(y.domain(), [d.y, 1]),
yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
return function(d, i) {
return i
? function(t) { return arc(d); }
: function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); };
};
}
function computeTextRotation(d) {
return (x(d.x + d.dx / 2) - Math.PI / 2) / Math.PI * 180;
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment