Skip to content

Instantly share code, notes, and snippets.

@emagee
Created August 8, 2015 20:31
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 emagee/76caed32650e6aa4ac18 to your computer and use it in GitHub Desktop.
Save emagee/76caed32650e6aa4ac18 to your computer and use it in GitHub Desktop.
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
<!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>
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
.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.
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