D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
emagee
Full window
Github gist
Small multiples, eventually with tooltips?
<!DOCTYPE html> <meta charset="utf-8"> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script> <title>ISBN counts, 2002-2012</title> <style> body { font: 10px sans-serif; margin: 0; } .line { fill: none; stroke: #426789; stroke-width: 4px; } .area { fill: #e8eef4; } g#xAxisG text, g#yAxisG text { stroke: none; fill: silver; font-size: 9px; } header, div#source { margin-left: 40px; margin-bottom: 38px; max-width: 75%; } header p { font-size: 1.4em; line-height: 1.25em; } div#source p { font-size: 11px; } h1 { color: #B35959; margin-bottom: 6px; font-size: 2.5em; } h2 { color: #426789; margin-top: 4px; margin-bottom: 20px; font-weight: normal; font-size: 1.5em; } .small { font-size: .85em; } a:-webkit-any-link { color: -webkit-link; text-decoration: none; cursor: auto; color: #426789; } a:any-link { color: -webkit-link; text-decoration: none; cursor: auto; color: #426789; } a:link, a:visited, a:hover, a:active { color: #426789; text-decoration: none; } /* testing: */ div.tooltip { position: absolute; text-align: center; width: 60px; height: 28px; padding: 2px; font: 12px sans-serif; background: lightsteelblue; border: 0px; border-radius: 8px; pointer-events: none; } </style> <body> <header> <h1>ISBN counts for print adult nonfiction books, 2002–2012</h1> <h2>By the subject reported by Bowker customers when registering a book's ISBN</h2> <p>According to Wikipedia, “...Bowker provides bibliographic information on published works to the book trade, including publishers, booksellers, libraries, and individuals... Bowker is the exclusive U.S. agent for issuing International Standard Book Numbers (ISBNs), a universal method of identifying books in print.” <span class="small">(<a href = "https://en.wikipedia.org/wiki/R.R._Bowker">https://en.wikipedia.org/wiki/R.R._Bowker</a>, accessed July 31, 2015)</span></p> <p>Additional books are classified under “non-traditional” or “unclassified;” these are not included in this chart. These ISBNs ranged in count from 247,777 to 2,042,840 per year during this ten-year period.</p> </header> <div id="mainSVG"></div> <div id="source"> <p>Source: <a href="https://www.bowker.com/documents/isbn-output-report-2002-2013.html">https://www.bowker.com/documents/isbn-output-report-2002-2013.html</a></p> </div> <script> var margin = {top: 8, right: 15, bottom: 20, left: 40}, width = 180 - margin.left - margin.right, height = 120 - margin.top - margin.bottom; var parseDate = d3.time.format("%Y").parse; var x = d3.time.scale() .range([10, width+10]); var y = d3.scale.linear() .range([height, 0]); var area = d3.svg.area() .x(function(d) { return x(d.date); }) .y0(height) .y1(function(d) { return y(d.count); }); var line = d3.svg.line() .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.count); }); d3.csv("bowker-data-clean-reformatted-3.csv", type, function(error, data) { // Nest data by subject. var subjects = d3.nest() .key(function(d) { return d.subject; }) .entries(data); // Compute the maximum count per subject, needed for the y-domain. subjects.forEach(function(s) { s.maxCount = d3.max(s.values, function(d) { return d.count+500; }); }); // Compute the minimum and maximum date across subjects. // We assume values are sorted by date. x.domain([ d3.min(subjects, function(s) { return s.values[0].date; }), d3.max(subjects, function(s) { return s.values[s.values.length - 1].date; }) ]); // Add an SVG element for each subject, with the desired dimensions and margin. var svg = d3.select("#mainSVG").selectAll("svg") .data(subjects) .enter().append("svg") .style("margin-bottom", "10px") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")") ; // Add the area path elements. Note: the y-domain is set per element. svg.append("path") .attr("class", "area") .attr("d", function(d) { y.domain([0, 33000]); return area(d.values); }); var toolTipDiv = d3.select("#mainSVG").append("div") .attr("class", "tooltip") .style("opacity", 0); // Add the line path elements. Note: the y-domain is set per element. svg.append("path") .attr("class", "line") .attr("d", function(d) { y.domain([0, 33000]); return line(d.values); }) // This mouseover tooltip should reveal the date and count variables at each point. .on("mouseover", function(s) { toolTipDiv.transition() .duration(200) .style("opacity", .9); toolTipDiv.html(s.key + "<br/>" + s.key + "<br/>" + "ARRGH") .style("left", (d3.event.pageX) + "px") .style("top", (d3.event.pageY - 28) + "px"); }) .on("mouseout", function(d) { toolTipDiv.transition() .duration(500) .style("opacity", 0);}); // Add a small label for the symbol name. svg.append("text") .attr("x", (width + 12)/2) .attr("y", height - 85) .style("text-anchor", "middle") .style("font-family", "helvetica, 'sans-serif'") .style("font-size", "12px") /*.style("font-weight", "bold")*/ .attr("fill", "#B35959") .text(function(d) { return d.key; }); // attempt to add axes var xScale = x; var yScale = y; var yAxis = d3.svg.axis().scale(yScale).orient("left") .tickFormat(function (d) { if ((d / 1000) >= 1) { d = d / 1000 + "K"; } return d; }); svg.append("g").attr("id", "yAxisG").call(yAxis); var xAxis = d3.svg.axis().scale(xScale).orient("bottom").ticks(3); svg.append("g").attr("id", "xAxisG").call(xAxis); d3.selectAll("path.domain").style("fill", "none").style("stroke", "silver"); d3.selectAll("line").style("stroke", "silver"); d3.selectAll("#xAxisG").attr("transform","translate(0,92)"); }); function type(d) { d.count = +d.count; d.date = parseDate(d.date); return d; } </script>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js