// sizes var w = 100, h = 100, p = 5, //padding between cells s = 20, //spacer for macro-axis labels k = 100, //spacer for legend key xlim = 30, ylim = 100, y = d3.scale.linear().domain([0, ylim]).range([0 + p, h - p]), x = d3.scale.linear().domain([0, xlim]).range([0 + p, w - p]), c = d3.scale.ordinal().domain(RH).range([ "cornflowerblue", "limegreen", "orange", "crimson" ]);; // Nest data by temp and then degree days var nest = d3.nest() .key(function(d) { return d.temp; }) .key(function(d) { return d.ddays; }) .key(function(d) { return d.RH; }) .entries(data); // Root panel var svg = d3.select("body") .append("svg:svg") .attr("class", "chart") .attr("width", w * nest.length + p * (nest.length - 1) + s + k) .attr("height", h * nest.length + p * (nest.length - 1) + s); // Make a row per temp var row = svg.selectAll("g") .data(nest) .enter().append("svg:g") .attr("transform", function(d, i) { return "translate(0," + (p + s + i * h) + ")"; }); // label the rows row.append("svg:rect") .attr("x", 0) .attr("y", p-1) .attr("class", "rowLab") .attr("width", 20) .attr("height", h-p) .style("fill", "cornflowerblue"); row.append("svg:text") .attr("x", 0) .attr("y", p-1) .attr("transform", "translate(10," + h / 2 + ")rotate(-90)") .attr("text-anchor", "middle") .style("fill", "white") .text(function(d) { return d.key; }); // And a column per duration in degree days var cell = row.selectAll("g") .data( function(d) { return d.values; }) .enter().append("svg:g") .attr("transform", function(d, i) { return "translate(" + (p + s + i * w) + "," + (h) + ")"; }); // label the columns var collabel = svg.selectAll("colLab") .data(ddays) .enter().append("svg:rect") .attr("x", function(d,i) { return p*2+s+w*i; }) .attr("y", 0) .attr("width", w-p*2) .attr("height", 20) .style("fill", "orange"); var coltxt = svg.selectAll("coltxt") .data(ddays) .enter().append("svg:text") .attr("x", function(d,i) { return p*2+s+w/2+w*i; }) .attr("y", s/2+p) .attr("text-anchor", "middle") .style("fill", "white") .text(function(d) { return d; }); // Add a group per RH var cond = cell.selectAll("g") .data( function(d) { return d.values; }) .enter().append("svg:g"); // Gridlines cell.selectAll(".xGrid") .data(x.ticks(5)) .enter().append("svg:line") .attr("class", "xGrid") .attr("x1", function(d) { return x(d); }) .attr("y1", -1 * y(0)) .attr("x2", function(d) { return x(d); }) .attr("y2", -1 * y(ylim)); cell.selectAll(".yGrid") .data(y.ticks(4)) .enter().append("svg:line") .attr("class", "yGrid") .attr("y1", function(d) { return -1 * y(d); }) .attr("x1", x(xlim)) .attr("y2", function(d) { return -1 * y(d); }) .attr("x2", x(0)); var path = d3.svg.line() .x(function(d) { return x(d.days); }) .y(function(d) { return -1 * y(d.germ); }) .interpolate("basis") .tension(1); // Add lines between data points var line = cond.selectAll("path.line") .data(function(d) { return [d]; }) .enter().append("svg:path") .attr("class", "line") .attr("d", function(d) { return path(d.values); }); // Add dots - days on x-axis, germination % on y-axis var dots = cond.selectAll("circle.line") .data( function(d) { return d.values; }) .enter().append("svg:circle") .attr("class", "line") .attr("cx", function(d) { return x(d.days); }) .attr("cy", function(d) { return -1 * y(d.germ); }) .attr("r", 4); // colour lines by RH cell.selectAll("path.line") .style("stroke", function(d) { return c(d.key); }) .style("stroke-width", "2px") .style("fill", "none"); // colour dots by RH cell.selectAll("circle.line") .style("fill", function(d) { return c(d.RH); }) .style("fill-opacity", .8); // add legend var legend = svg.append("svg:text") .attr("x", (w+p)*4+s*2+10) .attr("y", h) .attr("text-anchor", "middle") .style("fill", "black") .style("font-size", "2em") .text("RH (%)"); var key = svg.selectAll("key.circle") .data(RH) .enter().append("svg:circle") .attr("cx", (w+p)*4+s*2) .attr("cy", function(d) { return h + d; }) .attr("r", 4) .style("fill", function(d) { return c(d); }) .style("fill-opacity", .8); var keyText = svg.selectAll("key.text") .data(RH) .enter().append("svg:text") .attr("x", (w+p)*4+s*2+10) .attr("y", function(d) { return h + d+4; }) .text(function(d) { return d; });