Skip to content

Instantly share code, notes, and snippets.

@peakera
Last active March 23, 2016 14:53
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 peakera/6a00b5fbaa6cc9741e6c to your computer and use it in GitHub Desktop.
Save peakera/6a00b5fbaa6cc9741e6c to your computer and use it in GitHub Desktop.
Tess amidst Flora (Tess)

This visual is one of a set that attempts to contextualize both human characters and nonhuman others within the natural world of Thomas Hardy's 1892 novel Tess of the d'Urbervilles. This cluster visualizes words tagged "flora" that appear within 120 characters of a word tagged "Tess." Words may be repeated and have been sorted according to their location in the novel. To see context from the novel, click on a word. You can submit feedback or questions and read more about the larger project here.

<!DOCTYPE html>
<meta charset="utf-8">
<link href='http://fonts.googleapis.com/css?family=Libre+Baskerville:400,700,400italic|Open+Sans:400,600' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Londrina+Shadow' rel='stylesheet' type='text/css'>
<style>
.wrapper {
display: inline-block;
position: absolute;
left: 0;
width: 100%;
vertical-align: top;
overflow: hidden;
}
.node circle {
fill: #fff;
stroke: green;
stroke-width: 1.5px;
}
.link {
fill: none;
stroke: green;
stroke-width: 1.5px;
}
.keyword {
font-size: 3vw;
color: #8e44ad;
}
.keyword2 {
font-size: 3vw;
color: green;
}
.titleBox {
box-sizing: border-box;
margin-top: 5%;
display: inline-block;
font-size: 5vw;
position: absolute;
right: 0;
width: 37%;
padding: 10px;
}
.tooltip {
font-family: serif;
font-size: 2vw;
margin-top: 2vw;
line-height: 2.7vw;
}
.cluster {
left: 0;
width: 70%;
}
@media (max-width: 600px) {
.cluster {
position: static;
width: 100%;
}
.titleBox {
position: static;
width: 100%;
}
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
var diameter = window.outerWidth;
var tree = d3.layout.tree()
.size([360, diameter / 2 - 200])
.separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; });
var diagonal = d3.svg.diagonal.radial()
.projection(function(d) { return [d.y, d.x / 180 * Math.PI]; });
d3.select("body").append("div")
.attr("class", "wrapper")
var titleBox = d3.select(".wrapper").append('div', ":first:child")
.attr('class', 'titleBox')
.text('Tess amidst Flora');
var svg = d3.select(".wrapper").append("svg")
.attr("viewBox", "0 0 2000 1500")
.attr("preserveAspectRatio", "xMinYMin meet")
.attr('class', "cluster")
.attr("width", diameter)
.append("g")
.attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")")
.style("float", 'left');
d3.json("https://api.myjson.com/bins/3owb5", function(error, root) {
var nodes = tree.nodes(root),
links = tree.links(nodes);
var link = svg.selectAll(".link")
.data(links)
.enter().append("path")
.attr("class", "link")
.attr("d", diagonal);
var tooltip = d3.select(".titleBox").append("div")
.attr('class', 'tooltip')
var node = svg.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; })
.on("mouseover", mouseover)
.on('mouseout', mouseout)
.on("click", function(d) {
tooltip.transition()
.ease('linear')
.duration(1000)
.styleTween("opacity", function() { return d3.interpolate(0, 1); });
var word = d.word1;
var space = " ";
var tag2 = d.word2;
var str = d.endContext
var beg = d.beginContext
if(beg.search(tag2)) {
var beg = beg.replace(tag2, "<span class='keyword2'>" + tag2 + "</span>");}
else {var beg = beg;
};
if(str.search(tag2)) {
var str = str.replace(tag2, "<span class='keyword2'>" + tag2 + "</span>");}
else {var str = str;
};
if(!!str.match(/^[.,:;!?-]/)) {
var str = str;
} else {var str = (space.concat(str));};
tooltip.html(beg + " " + "<span class='keyword'>" + word + "</span>" + str);
// if(d.beginContext.search(tag2)) {
// tooltip.html(beginContext + "<span class='keyword'>" + tag2 + "</span>" + str);
// };
});
node.append("circle")
.attr("r", 4.5);
node.append("text")
.attr("dy", ".31em")
.attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
.attr("transform", function(d) { return d.x < 180 ? "translate(8)" : "rotate(180)translate(-8)"; })
.text(function(d) { return d.word1; })
.style("font-size", 32 + "px")
.style("text-transform", "lowercase");
//The chunk of code below can be used if/when I decide to work with invoked beings in the novel
// .style('font-family', function(d) {
// if (d.type == "invoked") {return "Londrina Shadow"}
// else {return "sans-serif"};
// });
});
var chart = $(".cluster"),
aspect = chart.width() / chart.height(),
container = chart.parent();
$(window).on("resize", function() {
var targetWidth = container.width();
chart.attr("width", targetWidth);
chart.attr("height", Math.round(targetWidth / aspect));
}).trigger("resize");
function mouseover() { //makes the text size increase on mouseover
d3.select(this).select("text").transition()
.duration(750)
.style("font-size", "80px");
}
function mouseout() { //returns text to original size
d3.select(this).select("text").transition()
.duration(750)
.style("font-size", "32px");
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment