Forked from Captain Anonymous's Pen oXpoev.
A Pen by Shelby Sturgis on CodePen.
| <svg class="visualize"></svg> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script> |
Forked from Captain Anonymous's Pen oXpoev.
A Pen by Shelby Sturgis on CodePen.
| // Try increasing the number of empty objects in this array | |
| var data = [ | |
| {}, {}, {}, | |
| {}, {}, {}, | |
| {}, {}, {}, | |
| {} | |
| ]; | |
| var width = 600; // Change the width | |
| var height = 400; // Change the height | |
| // Try changing the layout option to: 'rows', 'grid', or 'columns' | |
| var layout = innerSelection() | |
| .cssClass("chart") | |
| .layout("grid") | |
| .columns(0) // when layout == "grid" number of cols before wrap | |
| .size([width, height]); | |
| d3.select(".visualize") | |
| .style("width", width + "px") | |
| .style("height", height + "px") | |
| .datum(data) // Each object represents a chart | |
| .call(layout) | |
| .selectAll('g.chart') | |
| .append('g') | |
| .attr('transform', function (d) { | |
| return "translate(0,0)"; | |
| }) | |
| .append('rect') | |
| .attr("x", function (d) { return 0; }) | |
| .attr("y", function (d) { return 0; }) | |
| .attr("width", function (d) { return d.width; }) | |
| .attr("height", function (d) { return d.height; }) | |
| .style('fill', 'red') | |
| .style('stroke', 'black') | |
| .style('stroke-width', 1); | |
| /* *************************************************** */ | |
| // Returns proper number of rows and columns for each layout type. | |
| function getFormat(length, type, cols) { | |
| var output = {}; | |
| switch (type) { | |
| case "grid": | |
| output.rows = cols ? Math.ceil(length / cols) : Math.round(Math.sqrt(length)); | |
| output.columns = cols ? cols : Math.ceil(Math.sqrt(length)); | |
| break; | |
| case "columns": | |
| output.rows = 1; | |
| output.columns = length; | |
| break; | |
| default: | |
| output.rows = length; | |
| output.columns = 1; | |
| break; | |
| } | |
| return output; | |
| } | |
| // Appends the proper dx (left), dy (top), width, and height values | |
| // for each chart in the dataset. | |
| function format() { | |
| var type = "rows"; // type: 'rows', 'columns', 'grid' | |
| var size = [500, 500]; // [width, height] | |
| var rowScale = d3.scale.linear(); | |
| var columnScale = d3.scale.linear(); | |
| var numCols = 0; | |
| function layout(data) { | |
| var format = getFormat(data.length, type, numCols); | |
| var rows = format.rows; | |
| var columns = format.columns; | |
| var cellWidth = size[0] / columns; | |
| var cellHeight = size[1] / rows; | |
| var cell = 0; | |
| rowScale.domain([0, rows]).range([0, size[1]]); | |
| columnScale.domain([0, columns]).range([0, size[0]]); | |
| d3.range(rows).forEach(function (row) { | |
| d3.range(columns).forEach(function (col) { | |
| if (!data[cell]) { return; } | |
| data[cell].dx = columnScale(col); | |
| data[cell].dy = rowScale(row); | |
| data[cell].height = cellHeight; | |
| data[cell].width = cellWidth; | |
| cell++; | |
| }); | |
| }); | |
| return data; | |
| } | |
| // Public API | |
| layout.type = function (_) { | |
| if (!arguments.length) { return type; } | |
| type = _; | |
| return layout; | |
| }; | |
| layout.size = function (_) { | |
| if (!arguments.length) { return size; } | |
| size = _; | |
| return layout; | |
| }; | |
| layout.columns = function (_) { | |
| if (!arguments.length) { return numCols; } | |
| numCols = _; | |
| return layout; | |
| }; | |
| return layout; | |
| } | |
| // Creates divs for each chart in the dataset. | |
| function innerSelection() { | |
| // Private variables | |
| var cssClass = "chart"; | |
| var type = "rows"; | |
| var columns = 0; | |
| var size = [500, 500]; | |
| var layout = format(); | |
| function component(selection) { | |
| selection.each(function (data, index) { | |
| layout.type(type).size(size).columns(columns); | |
| var g = d3.select(this).selectAll("g") | |
| .data(layout(data)); | |
| // Exit | |
| g.exit().remove(); | |
| // Enter | |
| g.enter().append("g"); | |
| // Update | |
| g.attr("class", cssClass) | |
| .attr("transform", function (d) { | |
| return "translate(" + d.dx + "," + d.dy + ")"; | |
| }); | |
| }); | |
| return selection; | |
| } | |
| component.cssClass = function (_) { | |
| if (!arguments.length) return cssClass; | |
| cssClass = _; | |
| return component; | |
| }; | |
| component.layout = function (_) { | |
| if (!arguments.length) return type; | |
| type = _; | |
| return component; | |
| }; | |
| component.columns = function (_) { | |
| if (!arguments.length) return columns; | |
| columns = _; | |
| return component; | |
| }; | |
| component.size = function (_) { | |
| if (!arguments.length) return size; | |
| size = _; | |
| return component; | |
| }; | |
| return component; | |
| } |
| .visualize { | |
| background-color: grey; | |
| } | |
| .chart { | |
| background-color: blue; | |
| border: 1px solid; | |
| } |