D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
mforando
Full window
Github gist
Fit Grid Items to Rect
Built with
blockbuilder.org
<!DOCTYPE html> <head> <meta charset="utf-8"> <script src="https://d3js.org/d3.v4.min.js"></script> <style> body { margin:0;top:0;right:0;bottom:0;left:0; } #main{ width:500px; vertical-align:top; } #mainsvg{ background:'rgb(240,240,240)'; } </style> </head> <div id='main'> <svg id='mainsvg' width="500" height="500"> <rect id='rect' transform='translate(50, 50)' width='380' height='300'></rect> <svg> </div> <body> <script> // bisect d3.range(30); d3.range(30); var width = 500; var height = 700; var desiredItems = 30; // height/width var desiredRatio = 4/3; var colsarray = d3.range(desiredItems).map((d)=>{return d + 1;}).reverse(); var options = []; // generate an dataset of all of the possible layouts up to an Nth column grid colsarray.forEach((cols)=>{ // find number of rows required for n columns grid. var rows = Math.ceil(desiredItems/cols); var cellWidth = width/cols; var cellHeight = cellWidth * desiredRatio var gridHeight = cellHeight * rows; var gridRatio = gridHeight/width; // find aspect ratio of this layout. var thisRatio = cols/rows; // given number of columns/rows figure out which is the constraining value. var sizePerRow = height/rows; var sizePerCol = width/cols/desiredRatio; // find cell width. var colwidth = width/cols; options.push({'columns': cols, 'rows': rows, 'gridaspect': gridRatio}); }) console.log(options); function updateGrid(){ var rect = d3.select("#rect") .node() .getBoundingClientRect(); console.log(rect.height/rect.width); var ratio = rect.height/rect.width; var ratios = options.map((d)=>{return d.gridaspect}); var index = d3.bisectLeft(ratios, ratio); // find the smallest aspect ratio to the actual screen ratio. var valid = options.filter((d)=>{return d.gridaspect <= ratio}); var gridToUse = valid[valid.length-1]; var griddata = d3.cross(d3.range(gridToUse.rows), d3.range(gridToUse.columns)); var xScale = d3.scaleBand() .range([0, rect.width]) .domain(d3.range(gridToUse.columns)) var yScale = d3.scaleBand() .range([0, gridToUse.rows * xScale.bandwidth() * desiredRatio]) .domain(d3.range(gridToUse.rows)) console.log(gridToUse.rows); d3.select("#mainsvg") .selectAll('.gridrects') .data(griddata) .enter() .append('rect') .style('fill', 'red') .style('opacity', .5) .attr('transform', 'translate(50, 50)') .style('stroke', 'white') .attr('width', xScale.bandwidth()) .attr('height', yScale.bandwidth()) .attr('x', (d)=>{return xScale(d[1])}) .attr('y', (d)=>{return yScale(d[0])}) console.log(griddata); } updateGrid(); </script> </body>
https://d3js.org/d3.v4.min.js