D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
sampathweb
Full window
Github gist
Barley Yields Simple Multiples
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> <style type="text/css"> /*css to go here*/ .axis text { font: 10px sans-serif; } .axis path { fill: none; } .axis line { stroke-width:1px; stroke: #ccc; stroke-dasharray: 2px 2px; } rect.sub-plot { stroke: grey; fill: none; } rect.yield { stroke: steelblue; stroke-width: 1; fill: none; } line.yield { stroke: red; stroke-width: 2; } line.wiskers-top, line.wiskers-bottom { stroke: steelblue; stroke-width: 1; } text.site-text { font: 12px sans-serif; } </style> </head> <body> <div id="viz"></div> <script> //JS to go here d3.csv("barley-yields.csv", function(error, data) { data.forEach(function(d) { d.year = +d.year; d.yield = +d.yield; }); var margin = {top: 20, right: 20, bottom: 50, left: 50}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var svg = d3.select("#viz") .append("svg") .attr({ width: width + margin.left + margin.right, height: height + margin.top + margin.bottom }) .append("g") .attr("transform", "translate(" + [margin.left, margin.top] + ")"); var xScale = d3.scale.ordinal() .rangeRoundBands([0, width/3], 0.7, 0.5) .domain(data.map(function(d) { return d.year; })); var yScale = d3.scale.linear() .range([height / 2, 0]) .domain([0, d3.max(data, function(d) { return d.yield; })]); var siteGroups = d3.nest() .key(function(d) { return d.site; }) .key(function(d) { return d.year; }) .rollup(function(leaves) { var yields = leaves.map(function(d) { return d.yield; }).sort(d3.ascending); console.log(yields); return { min: d3.min(yields), max: d3.max(yields), p50: d3.mean(yields), p25: d3.quantile(yields, 0.25), p75: d3.quantile(yields, 0.75), p05: d3.quantile(yields, 0.05), p95: d3.quantile(yields, 0.95) }; }) .entries(data); var sites = svg.selectAll("g.site").data(siteGroups); var chartHeight = height / 2, chartWidth = width / 3; sites.enter() .append("g") .classed("site", true) .attr("transform", function(d, i) { var x = (i % 3) * chartWidth; var y = parseInt(i/3) * chartHeight; return "translate(" + [x, y] + ")"; }); sites.each(function(d, i) { if (i % 3 == 0) { // Build y Axis var yAxis = d3.svg.axis() .scale(yScale) .orient("left") .tickSize(-width); d3.select(this) .append("g") .classed("y axis", true) .call(yAxis); } else if (i%3 == 2) { // Build y Axis on Right var yAxis = d3.svg.axis() .scale(yScale) .orient("right"); d3.select(this) .append("g") .classed("y axis", true) .attr("transform", "translate(" + [chartWidth, 0] + ")") .call(yAxis); } if (i <= 2) { // Build x Axis var xAxis = d3.svg.axis() .scale(xScale) .orient("top"); d3.select(this) .append("g") .classed("x axis", true) .call(xAxis); } else { // Build x Axis var xAxis = d3.svg.axis() .scale(xScale) .orient("bottom") .tickSize(-height); d3.select(this) .append("g") .classed("x axis", true) .attr("transform", "translate(" + [0, chartHeight] + ")") .call(xAxis); } d3.select(this) .append("rect") .classed("sub-plot", true) .attr({ x: 0, y: 0, height: chartHeight, width: chartWidth }); d3.select(this) .append("text") .classed("site-text", true) .attr({ x: 5, y: 20 }) .text(d.key) d3.select(this) .selectAll("rect.yield") .data(d.values) .enter() .append("rect") .classed("yield", true) .attr({ x: function(d) { return xScale(d.key); }, y: function(d) { return yScale(d.values.p75); }, height: function(d) { return yScale(d.values.p25) - yScale(d.values.p75); }, width: function(d) { return xScale.rangeBand(); } }); d3.select(this) .selectAll("line.yield") .data(d.values) .enter() .append("line") .classed("yield", true) .attr({ x1: function(d) { return xScale(d.key); }, y1: function(d) { return yScale(d.values.p50); }, x2: function(d) { return xScale(d.key) + xScale.rangeBand(); }, y2: function(d) { return yScale(d.values.p50); } }); // Add Wiskers d3.select(this) .selectAll("line.wiskers-top") .data(d.values) .enter() .append("line") .classed("wiskers-top", true) .attr({ x1: function(d) { return xScale(d.key) + xScale.rangeBand()/2; }, y1: function(d) { return yScale(d.values.p75); }, x2: function(d) { return xScale(d.key) + xScale.rangeBand()/2; }, y2: function(d) { return yScale(d.values.p95); } }) d3.select(this) .selectAll("line.wiskers-bottom") .data(d.values) .enter() .append("line") .classed("wiskers-bottom", true) .attr({ x1: function(d) { return xScale(d.key) + xScale.rangeBand()/2; }, y1: function(d) { return yScale(d.values.p25); }, x2: function(d) { return xScale(d.key) + xScale.rangeBand()/2; }, y2: function(d) { return yScale(d.values.p05); } }); }); }); </script> </body> </html>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js