xxxxxxxxxx
<meta charset="utf-8">
<style type="text/css">
body {
font-family: arial, sans;
font-size: 9px;
width: 960px;
margin: 40px auto;
}
svg {
border: 1px solid #f0f;
}
.container {
margin-bottom: 12px;
}
.block {
margin-bottom: 3px;
display: inline-block;
vertical-align: middle;
}
.authorBlock {
width: 80px;
}
.booksBlock {
margin-left: 10px;
}
.timelineBaseline {
stroke: black;
stroke-width: 1px;
}
.timelineActive {
opacity: 0.5;
}
.bookCircleLabel {
text-anchor: middle;
}
.book {
margin-right: 6px;
}
/* .axis path {
display: none;
}
.yAxis .tick line {
stroke: #ddd;
}
.xAxis .tick line {
stroke: #ddd;
}*/
</style>
<body>
<h1>Author and Book Data Comparisons</h1>
<div class="mainContainer"></div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script>
<script type="text/javascript">
var margin = {top: 10, right: 10, bottom: 10, left: 10};
var width = 500 - margin.left - margin.right,
height = 40 - margin.top - margin.bottom;
var xScale = d3.scale.linear()
.range([0,width]);
d3.tsv("books_authors.tsv", ready);
function ready(error, data) {
if (error) return console.warn(error);
function capitalizeEachWord(str) {
return str.replace(/\w\S*/g, function(txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
});
};
data.forEach( function (d) {
d.AGE_BOOK = +d.AGE_BOOK;
d.AGE_FIRST_NOVEL = +d.AGE_FIRST_NOVEL;
d.BORN = +d.BORN;
d.DIED = +d.DIED;
d.EDITORS_WIKI = +d.EDITORS_WIKI;
d.FIRST_NOVEL = +d.FIRST_NOVEL;
d.LIFESPAN = +d.LIFESPAN;
d.RANKING = +d.RANKING;
d.WIKIPEDIA_VIEWS = +d.WIKIPEDIA_VIEWS;
d.YEAR_BOOK = +d.YEAR_BOOK;
d.NATION = capitalizeEachWord(d.NATION);
d.ACTIVE_SPAN = d.LIFESPAN - d.AGE_FIRST_NOVEL;
});
var xLifespan = data.map( function (d) { return d.LIFESPAN; });
var xMax = d3.max(xLifespan);
console.log(xMax);
var nestedData = d3.nest()
.key(function(d) { return d.AUTHOR; })
.entries(data);
nestedData.forEach( function (d) {
d.BORN = +d.values[0].BORN;
d.DIED = +d.values[0].DIED;
d.AGE_FIRST_NOVEL = +d.values[0].AGE_FIRST_NOVEL;
d.LIFESPAN = +d.values[0].LIFESPAN;
d.NATION = capitalizeEachWord(d.values[0].NATION);
d.ACTIVE_SPAN = +d.values[0].LIFESPAN - +d.values[0].AGE_FIRST_NOVEL;
});
// data is ready
console.log(nestedData);
var container = d3.select("body").select("div.mainContainer").selectAll("div.container")
.data(nestedData)
.enter()
.append("div")
.attr("class", "container");
// build containers
var authorContainer = d3.selectAll("div.container");
authorContainer.append("div").attr("class", "authorBlock block");
authorContainer.append("div").attr("class", "timelineBlock block");
authorContainer.append("div").attr("class", "booksBlock block");
// add author information
var authorBlockInfo = d3.selectAll("div.authorBlock");
authorBlockInfo.append("div")
.attr("class", "authorName")
.text( function (d) { return d.key; });
authorBlockInfo.append("div")
.attr("class", "authorCountry")
.text( function (d) { return d.NATION; });
authorBlockInfo.append("div")
.attr("class", "authorYears")
.text( function (d) { return d.BORN + "—" + d.DIED; });
// add timeline
var timelineBlockInfo = authorContainer.select("div.timelineBlock");
timelineBlockInfo.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
xScale.domain([0,xMax]);
var rectHeight = 5;
var bookRadius = 5;
var timelineDraw = timelineBlockInfo.selectAll("g")
.append('g');
timelineDraw.append("line")
.attr("class", "timelineBaseline")
.attr("x1", 0)
.attr("x2", function (d) { return xScale(d.LIFESPAN); })
.attr("y1", height/2)
.attr("y2", height/2);
timelineDraw.append("rect")
.attr("class", "timelineActive")
.attr("width", function (d) { return xScale(d.ACTIVE_SPAN); })
.attr("height", rectHeight)
.attr("x", function (d) { return xScale(d.LIFESPAN - d.ACTIVE_SPAN); })
.attr("y", height/2-rectHeight/2);
timelineDraw.selectAll(".bookCircle")
.data( function (d) { return d.values; })
.enter()
.append("circle")
.attr("class", "bookCircle")
.attr("r", bookRadius)
.attr("cy", height/2)
.attr("cx", function (d) { return xScale(d.AGE_BOOK); });
timelineDraw.selectAll(".bookCircleLabel")
.data( function (d) { return d.values; })
.enter()
.append("text")
.attr("text-anchor", "middle")
.attr("dy", height/2+bookRadius+10)
.attr("dx", function (d) { return xScale(d.AGE_BOOK); })
.text( function (d) { return d.AGE_BOOK; });
// add books
var booksBlockInfo = authorContainer.select("div.booksBlock");
booksBlockInfo.selectAll(".book")
.data( function (d) { return d.values; })
.enter()
.append("span")
.attr("class", "book")
.text( function (d) { return d.RANKING + ". " + d.BOOK; });
};
</script>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js