Created
August 8, 2015 20:31
-
-
Save emagee/76caed32650e6aa4ac18 to your computer and use it in GitHub Desktop.
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
source | target | weight | |
---|---|---|---|
white chocolate | almonds | 1 | |
white chocolate | apricots | 1 | |
white chocolate | bananas | 1 | |
white chocolate | basil | 1 | |
white chocolate | berries | 1 | |
white chocolate | caramel | 1 | |
white chocolate | cashews | 1 | |
white chocolate | coconut | 1 | |
white chocolate | dates | 1 | |
white chocolate | figs | 1 | |
white chocolate | ginger | 1 | |
white chocolate | grapes | 1 | |
white chocolate | hazelnuts | 1 | |
white chocolate | lime | 1 | |
white chocolate | macadamia nuts | 1 | |
white chocolate | mangoes | 1 | |
white chocolate | papayas | 1 | |
white chocolate | passion fruit | 1 | |
white chocolate | persimmons | 1 | |
white chocolate | pistachios | 1 | |
white chocolate | pomegranates | 1 | |
white chocolate | prunes | 1 | |
white chocolate | rum | 1 | |
white chocolate | strawberries | 1 | |
white chocolate | sugar | 1 | |
white chocolate | sweet potatoes | 1 | |
white chocolate | yogurt | 1 | |
almonds | apricots | 1 | |
almonds | cherries | 1 | |
almonds | dark chocolate | 1 | |
almonds | grapes | 1 | |
almonds | orange | 1 | |
almonds | passion fruit | 1 | |
almonds | prunes | 1 | |
almonds | raspberries | 1 | |
almonds | rum | 1 | |
almonds | strawberries | 1 | |
apricots | bananas | 1 | |
apricots | caramel | 1 | |
apricots | coconut | 1 | |
apricots | hazelnuts | 1 | |
apricots | macadamia nuts | 1 | |
apricots | orange | 1 | |
apricots | prunes | 1 | |
apricots | raspberries | 1 | |
apricots | rum | 1 | |
apricots | strawberries | 1 | |
apricots | yogurt | 1 | |
bananas | berries | 1 | |
bananas | dates | 1 | |
bananas | figs | 1 | |
bananas | hazelnuts | 1 | |
bananas | passion fruit | 1 | |
bananas | pomegranates | 1 | |
bananas | raspberries | 1 | |
bananas | strawberries | 1 | |
bananas | sweet potatoes | 1 | |
bananas | yogurt | 1 | |
basil | berries | 1 | |
basil | coconut | 1 | |
basil | ginger | 1 | |
basil | lime | 1 | |
basil | orange | 1 | |
basil | raspberries | 1 | |
berries | lemon | 1 | |
berries | lime | 1 | |
berries | mint | 1 | |
berries | yogurt | 1 | |
caramel | lemon | 1 | |
caramel | lime | 1 | |
caramel | macadamia nuts | 1 | |
caramel | mangoes | 1 | |
caramel | rum | 1 | |
cashews | dark chocolate | 1 | |
cashews | coconut | 1 | |
cashews | dates | 1 | |
cashews | ginger | 1 | |
cashews | lemon | 1 | |
cashews | macadamia nuts | 1 | |
cashews | mangoes | 1 | |
cashews | mint | 1 | |
cashews | papayas | 1 | |
cashews | passion fruit | 1 | |
cashews | persimmons | 1 | |
cashews | rum | 1 | |
cashews | sugar | 1 | |
cashews | vanilla | 1 | |
cherries | bananas | 1 | |
cherries | caramel | 1 | |
cherries | figs | 1 | |
cherries | ginger | 1 | |
cherries | lemon | 1 | |
cherries | lime | 1 | |
cherries | orange | 1 | |
cherries | pistachios | 1 | |
cherries | raspberries | 1 | |
cherries | rum | 1 | |
cherries | yogurt | 1 | |
dark chocolate | coconut | 1 | |
dark chocolate | dates | 1 | |
dark chocolate | figs | 1 | |
dark chocolate | grapes | 1 | |
dark chocolate | lemon | 1 | |
dark chocolate | macadamia nuts | 1 | |
dark chocolate | mangoes | 1 | |
dark chocolate | orange | 1 | |
dark chocolate | passion fruit | 1 | |
dark chocolate | prunes | 1 | |
dark chocolate | strawberries | 1 | |
coconut | dates | 1 | |
coconut | figs | 1 | |
coconut | ginger | 1 | |
coconut | lemon | 1 | |
coconut | macadamia nuts | 1 | |
coconut | orange | 1 | |
coconut | papayas | 1 | |
coconut | pistachios | 1 | |
dates | hazelnuts | 1 | |
dates | lemon | 1 | |
dates | lime | 1 | |
dates | macadamia nuts | 1 | |
dates | prunes | 1 | |
dates | rum | 1 | |
dates | vanilla | 1 | |
figs | ginger | 1 | |
figs | orange | 1 | |
figs | papayas | 1 | |
figs | persimmons | 1 | |
figs | prunes | 1 | |
figs | raspberries | 1 | |
figs | strawberries | 1 | |
figs | vanilla | 1 | |
figs | yogurt | 1 | |
ginger | hazelnuts | 1 | |
ginger | orange | 1 | |
ginger | papayas | 1 | |
ginger | persimmons | 1 | |
ginger | prunes | 1 | |
ginger | raspberries | 1 | |
ginger | strawberries | 1 | |
ginger | vanilla | 1 | |
ginger | yogurt | 1 | |
grapes | hazelnuts | 1 | |
grapes | mint | 1 | |
grapes | pistachios | 1 | |
grapes | raspberries | 1 | |
grapes | rum | 1 | |
grapes | strawberries | 1 | |
grapes | yogurt | 1 | |
hazelnuts | lemon | 1 | |
hazelnuts | mangoes | 1 | |
hazelnuts | mint | 1 | |
hazelnuts | orange | 1 | |
hazelnuts | persimmons | 1 | |
hazelnuts | prunes | 1 | |
hazelnuts | raspberries | 1 | |
hazelnuts | rum | 1 | |
hazelnuts | strawberries | 1 | |
hazelnuts | sugar | 1 | |
hazelnuts | sweet potatoes | 1 | |
lemon | lime | 1 | |
lemon | mangoes | 1 | |
lemon | mint | 1 | |
lemon | orange | 1 | |
lemon | papayas | 1 | |
lemon | passion fruit | 1 | |
lemon | persimmons | 1 | |
lemon | pistachios | 1 | |
lemon | prunes | 1 | |
lemon | raspberries | 1 | |
lemon | rum | 1 | |
lemon | yogurt | 1 | |
lime | macadamia nuts | 1 | |
lime | mangoes | 1 | |
lime | mint | 1 | |
lime | orange | 1 | |
lime | papayas | 1 | |
lime | passion fruit | 1 | |
lime | raspberries | 1 | |
lime | rum | 1 | |
lime | strawberries | 1 | |
lime | sugar | 1 | |
lime | sweet potatoes | 1 | |
lime | vanilla | 1 | |
lime | yogurt | 1 | |
macadamia nuts | mangoes | 1 | |
macadamia nuts | mint | 1 | |
macadamia nuts | orange | 1 | |
macadamia nuts | papayas | 1 | |
macadamia nuts | prunes | 1 | |
macadamia nuts | raspberries | 1 | |
macadamia nuts | rum | 1 | |
macadamia nuts | sugar | 1 | |
macadamia nuts | vanilla | 1 | |
mangoes | raspberries | 1 | |
mangoes | strawberries | 1 | |
mangoes | vanilla | 1 | |
mangoes | yogurt | 1 | |
mint | orange | 1 | |
mint | papayas | 1 | |
mint | raspberries | 1 | |
mint | strawberries | 1 | |
mint | vanilla | 1 | |
orange | papayas | 1 | |
orange | passion fruit | 1 | |
orange | persimmons | 1 | |
orange | pistachios | 1 | |
orange | prunes | 1 | |
orange | raspberries | 1 | |
orange | rum | 1 | |
orange | strawberries | 1 | |
orange | sweet potatoes | 1 | |
orange | yogurt | 1 | |
papayas | strawberries | 1 | |
papayas | vanilla | 1 | |
papayas | yogurt | 1 | |
passion fruit | rum | 1 | |
passion fruit | vanilla | 1 | |
passion fruit | yogurt | 1 | |
persimmons | rum | 1 | |
persimmons | sweet potatoes | 1 | |
persimmons | yogurt | 1 | |
pistachios | prunes | 1 | |
pistachios | raspberries | 1 | |
pistachios | sugar | 1 | |
pistachios | vanilla | 1 | |
pistachios | yogurt | 1 | |
prunes | rum | 1 | |
rum | vanilla | 1 | |
strawberries | yogurt | 1 | |
sugar | yogurt | 1 | |
sweet potatoes | vanilla | 1 | |
sweet potatoes | yogurt | 1 | |
vanilla | yogurt | 1 | |
white chocolate | dark chocolate | 2 | |
white chocolate | lemon | 2 | |
white chocolate | mint | 2 | |
white chocolate | orange | 2 | |
white chocolate | vanilla | 2 | |
almonds | caramel | 2 | |
almonds | coconut | 2 | |
almonds | figs | 2 | |
almonds | hazelnuts | 2 | |
almonds | lemon | 2 | |
almonds | sugar | 2 | |
apricots | ginger | 2 | |
apricots | papayas | 2 | |
apricots | pistachios | 2 | |
bananas | ginger | 2 | |
bananas | lime | 2 | |
bananas | mangoes | 2 | |
bananas | orange | 2 | |
bananas | papayas | 2 | |
bananas | vanilla | 2 | |
basil | lemon | 2 | |
basil | mint | 2 | |
berries | dark chocolate | 2 | |
berries | sugar | 2 | |
caramel | dark chocolate | 2 | |
caramel | passion fruit | 2 | |
cherries | apricots | 2 | |
cherries | coconut | 2 | |
dark chocolate | ginger | 2 | |
coconut | lime | 2 | |
coconut | mangoes | 2 | |
coconut | mint | 2 | |
coconut | passion fruit | 2 | |
coconut | rum | 2 | |
coconut | sugar | 2 | |
dates | pistachios | 2 | |
dates | sugar | 2 | |
figs | lemon | 2 | |
figs | mint | 2 | |
figs | passion fruit | 2 | |
figs | rum | 2 | |
ginger | lemon | 2 | |
ginger | mint | 2 | |
ginger | passion fruit | 2 | |
ginger | rum | 2 | |
grapes | lemon | 2 | |
grapes | sugar | 2 | |
mangoes | mint | 2 | |
mangoes | papayas | 2 | |
orange | pomegranates | 2 | |
orange | vanilla | 2 | |
papayas | passion fruit | 2 | |
papayas | sugar | 2 | |
passion fruit | strawberries | 2 | |
persimmons | pomegranates | 2 | |
persimmons | sugar | 2 | |
persimmons | vanilla | 2 | |
pomegranates | sugar | 2 | |
pomegranates | vanilla | 2 | |
prunes | sugar | 2 | |
prunes | vanilla | 2 | |
raspberries | rum | 2 | |
raspberries | strawberries | 2 | |
raspberries | yogurt | 2 | |
almonds | vanilla | 3 | |
apricots | lemon | 3 | |
apricots | sugar | 3 | |
bananas | caramel | 3 | |
bananas | dark chocolate | 3 | |
bananas | coconut | 3 | |
bananas | lemon | 3 | |
bananas | rum | 3 | |
bananas | sugar | 3 | |
caramel | vanilla | 3 | |
cherries | dark chocolate | 3 | |
cherries | hazelnuts | 3 | |
cherries | sugar | 3 | |
cherries | vanilla | 3 | |
dark chocolate | hazelnuts | 3 | |
dark chocolate | mint | 3 | |
dark chocolate | raspberries | 3 | |
dark chocolate | rum | 3 | |
dark chocolate | sugar | 3 | |
dark chocolate | vanilla | 3 | |
coconut | vanilla | 3 | |
dates | orange | 3 | |
figs | sugar | 3 | |
ginger | sugar | 3 | |
hazelnuts | vanilla | 3 | |
lemon | sugar | 3 | |
lemon | vanilla | 3 | |
mangoes | orange | 3 | |
mangoes | sugar | 3 | |
mint | sugar | 3 | |
mint | yogurt | 3 | |
orange | sugar | 3 | |
passion fruit | sugar | 3 | |
raspberries | sugar | 3 | |
raspberries | vanilla | 3 | |
rum | sugar | 3 | |
strawberries | sugar | 3 | |
strawberries | vanilla | 3 | |
sugar | sweet potatoes | 3 | |
sugar | vanilla | 3 | |
apricots | vanilla | 4 | |
white chocolate | raspberries | 4 |
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> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
<title>Flavor pairings: White chocolate</title> | |
<link rel="stylesheet" type="text/css" href="networks.css"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script> | |
<script src="http://d3js.org/queue.v1.min.js"></script> | |
</head> | |
<body> | |
<header> | |
<h1>Flavor pairings for white chocolate,<br/>and how the paired foods might be paired with each other</h1> | |
<h2>As listed in <cite><a href="http://www.indiebound.org/book/9780316118408">The Flavor Bible</a></cite>, by Karen Page and Andrew Dornenburg</h2> | |
<p> From the bookflap:</p> | |
<blockquote><em>The Flavor Bible</em> is your guide to hundreds of ingredients along with the herbs, spices, and other seasonings that will allow you to coax the greatest possible flavor and pleasure from them. This astonishing reference distills the combined experience of dozens of America's most innovative culinarians . . .</blockquote> | |
<p> The grading system is the authors' own; in the book the pairing grades are denoted through typography: <ul> | |
<li>Regular type denotes pairings "suggested by one or more experts."</li> | |
<li>Bold type denotes pairings "recommended by a number of experts."</li> | |
<li>Bold caps denotes pairings "very highly recommended by an even greater number of experts."</li> | |
<li>Bold caps with an asterisk denotes "Holy Grail" pairings that are "the most highly recommended by the greatest number of experts."</li> | |
</ul> | |
</p> | |
<p>For this graph, I translated these grades into weights, which are represented by the widths and shades of the edges. | |
</p> | |
<p class="small">Graph by Marcia Gray</p> | |
</header> | |
<svg></svg> | |
<script> | |
forceDirected(); | |
function forceDirected() { | |
// We need to load two datasets before we can get started, | |
// and queue.js lets us move the asynchronous loaders | |
// into a synchronous format. | |
queue() | |
.defer(d3.csv, "nodelist-3.csv") | |
.defer(d3.csv, "edgelist-5.csv") | |
.await(function(error, file1, file2) { | |
createForceLayout(file1, file2); | |
}); | |
// A hash allows us to test if a source-target pair has a link | |
function createForceLayout(nodes, edges) { | |
var nodeHash = {}; | |
for (x in nodes) { | |
// Creates a hash that associates each node JSON object | |
// with its ID value | |
nodeHash[nodes[x].id] = nodes[x]; | |
// Sets each node with an x position based on its array position | |
}; | |
for (x in edges) { | |
edges[x].weight = parseInt(edges[x].weight); | |
// Replaces the string ID of the node with | |
// a pointer to the JSON object | |
edges[x].source = nodeHash[edges[x].source]; | |
edges[x].target = nodeHash[edges[x].target]; | |
}; | |
var weightScale = d3.scale.linear() | |
.domain(d3.extent(edges, function(d) {return d.weight})) | |
.range([.1, 3]); | |
var force = d3.layout.force() | |
// how much each node pushes away each other; | |
// if set to a positive value, nodes attract each other | |
.charge(-1500) | |
.size([800, 800]) | |
.distance(175) | |
.nodes(nodes) | |
.links(edges) | |
.linkDistance(550) | |
.linkStrength(.25) | |
//.chargeDistance(350) | |
.gravity(.9) | |
.friction(.9) | |
//"tick" events are fired continuously, | |
// running the associated function | |
.on("tick", forceTick) | |
; | |
d3.select("svg") | |
.selectAll("line.link") | |
// Key values for your nodes and edges will help | |
// when we update the network later | |
.data(edges, function(d) { | |
return d.source.id + "-" + d.target.id; | |
}) | |
.enter() | |
.append("line") | |
.attr("class", "link") | |
.style("stroke", function(d) { | |
if (d.weight == 1) { | |
return "#FEE391"; | |
} | |
else if (d.weight == 2) { | |
return "#FEC44F"; | |
} | |
else if (d.weight == 3) { | |
return "#FE9929"; | |
} | |
else { | |
return "#cc4c02"; | |
}; | |
}) | |
.style("opacity", .7) | |
.style("stroke-width", function(d) { | |
return d.weight * 1.25; | |
}) | |
.style("stroke-width", function(d) { | |
return d.weight * 1.25; | |
}); | |
var nodeEnter = d3.select("svg") | |
.selectAll("g.node") | |
.data(nodes, function(d) { | |
return d.id; | |
}) | |
.enter() | |
.append("g") | |
.attr("class", "node"); | |
nodeEnter.append("circle") | |
.attr("r", function(d) { | |
if (d.id == "white chocolate") { | |
return "10"; | |
} else { | |
return "6"; | |
};}) | |
.style("fill", "#cc4c02") | |
//.style("stroke", "brown") | |
.style("stroke-width", "1px"); | |
nodeEnter.append("text") | |
.style("text-anchor", "middle") | |
.attr("y", function(d) { | |
if (d.id == "white chocolate") { | |
return "34"; | |
} else { | |
return "16" | |
}}) | |
.text(function(d) { | |
return d.id; | |
}) | |
.style("stroke", "none") | |
.style("fill", "#662506") | |
.style("font-family", "helvetica, 'sans-serif'") | |
.style("font-weight", "bold") | |
.style("font-size", function(d) { | |
if (d.id == "white chocolate") { | |
return "26px"; | |
} else { | |
return "13px" | |
}}) ; | |
// Initializing the network starts firing "tick" events and calculates | |
// the degree centrality of nodes | |
force.start(); | |
// One effective interaction technique is to set a node as fixed | |
// when the user interacts with it. This allows users to drag nodes | |
// to a position on the canvas so they can virtually sort the | |
// important nodes. | |
// You can enable dragging on all your nodes by selecting them and calling | |
// force.drag() on that selection | |
d3.selectAll("g.node") | |
.call(force.drag()); | |
d3.selectAll("g.site") | |
.on("click", fixNode); | |
function fixNode(d) { | |
d3.select(this) | |
.select("circle") | |
.style("stroke-width", 4); | |
d.fixed = true; | |
}; // end function fixNode | |
function forceTick() { | |
// The tick function updates the edge-drawing code and | |
// node-drawing code based on the newly calculated node positions | |
d3.selectAll("line.link") | |
.attr("x1", function(d) { | |
return d.source.x; | |
}) | |
.attr("x2", function(d) { | |
return d.target.x; | |
}) | |
.attr("y1", function(d) { | |
return d.source.y; | |
}) | |
.attr("y2", function(d) { | |
return d.target.y; | |
}); | |
// Setting the White Chocolate Node to center top position | |
nodes[0].x = 400; | |
nodes[0].y = 50; | |
d3.selectAll("g.node") | |
.attr("transform", function(d) { | |
return "translate(" + d.x + "," + d.y + ")"; | |
}) | |
.each(collide(0.5)); //Added for function collide; | |
}; // end function forceTick | |
/* | |
Anti-node-overlap code below via Mike Bostock | |
via http://www.coppelia.io/2014/07/ | |
an-a-to-z-of-extra-features-for-the-d3-force-layout/ | |
*/ | |
var padding = 13, // separation between circles | |
radius=10; | |
function collide(alpha) { | |
var quadtree = d3.geom.quadtree(nodes); | |
return function(d) { | |
var rb = 2*radius + padding, | |
nx1 = d.x - rb, | |
nx2 = d.x + rb, | |
ny1 = d.y - rb, | |
ny2 = d.y + rb; | |
quadtree.visit(function(quad, x1, y1, x2, y2) { | |
if (quad.point && (quad.point !== d)) { | |
var x = d.x - quad.point.x, | |
y = d.y - quad.point.y, | |
l = Math.sqrt(x * x + y * y); | |
if (l < rb) { | |
l = (l - rb) / l * alpha; | |
d.x -= x *= l; | |
d.y -= y *= l; | |
quad.point.x += x; | |
quad.point.y += y; | |
} | |
} | |
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1; | |
}); | |
}; | |
} // end function collide | |
}; // end function createForceLayout | |
}; // end function forceDirected | |
var legend = d3.select("svg").append("g") | |
.attr("class", "legend"); | |
legend.append("rect") | |
.attr("x", 635) | |
.attr("y", 15) | |
.attr("width", 150) | |
.attr("height", 100) | |
.style("fill", "none"); | |
legend.insert("image") | |
.attr("x", 621) | |
.attr("y", 16) | |
.attr("width", 170) | |
.attr("height", 124) | |
.attr("xlink:href", "legend-d2-OL.svg"); | |
</script> | |
</body> | |
</html> |
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
.grid { | |
stroke: black; | |
stroke-width: 1px; | |
fill: red | |
} | |
.arc { | |
stroke: black; | |
fill: none; | |
} | |
circle.active { | |
fill: red; | |
} | |
path.active { | |
stroke: red; | |
} | |
svg { | |
height: 800px; | |
width: 800px; | |
border: 1px solid #662506; | |
background-color: white; | |
} | |
body { | |
font: 10px sans-serif; | |
margin: 10px; | |
background-color: #f9f9eb; | |
width: 800px; | |
margin: 0, auto; | |
} | |
header p { | |
font-size: 1.4em; | |
line-height: 1.25em; | |
} | |
div#source p { | |
font-size: 11px; | |
} | |
h1 { | |
color: #cc4c02; | |
margin-bottom: 6px; | |
font-size: 2.5em; | |
} | |
h2 { | |
color: #662506; | |
margin-top: 4px; | |
margin-bottom: 20px; | |
font-weight: bold; | |
font-size: 1.5em; | |
} | |
p { | |
font-size: 1.25em; | |
} | |
blockquote { | |
font-size: 1.25em; | |
margin-top: -1em; | |
} | |
ul { | |
margin-top: -1.25em; | |
} | |
ul li { | |
font-size: 1.25em; | |
} | |
.small { | |
font-size: .85em; | |
} | |
a:-webkit-any-link { | |
color: -webkit-link; | |
text-decoration: none; | |
cursor: auto; | |
color: #662506; | |
} | |
a:any-link { | |
color: -webkit-link; | |
text-decoration: none; | |
cursor: auto; | |
color: #662506; | |
} | |
a:link, a:visited, a:hover, a:active { | |
color: #662506; | |
text-decoration: none; | |
} |
We can make this file beautiful and searchable if this error is corrected: No commas found in this CSV file in line 0.
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
id | |
white chocolate | |
almonds | |
apricots | |
bananas | |
basil | |
berries | |
caramel | |
cashews | |
cherries | |
dark chocolate | |
coconut | |
dates | |
figs | |
ginger | |
grapes | |
hazelnuts | |
lemon | |
lime | |
macadamia nuts | |
mangoes | |
mint | |
orange | |
papayas | |
passion fruit | |
persimmons | |
pistachios | |
pomegranates | |
prunes | |
raspberries | |
rum | |
strawberries | |
sugar | |
sweet potatoes | |
vanilla | |
yogurt |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment