Reputation: 351
I want to generate some grid by size 6x5 that overall means 30 cells by default though it can have less cells because all cells should be draggable and resizable.
Now I have something following for a default grid
_.map(items, (item, i) => {
return {x: i * 1 % 6, y: Math.floor(i / 6) * 2, w: 1, h: 1, i: i.toString()};
});
It populates 30 cells on the grid with div
elements but if the grid already predefined with some custom cells then need to check which cells are empty and set coordinates x,y and w,h accordingly where there a free space to not make collision with already existing cells.
It should not be anything complicated with the grid, it planning to work simple and as I think to have something similar to that pattern by keeping information in the Array but maybe there are better solutions how to organize it.
[
[xxxxxx],
[xxxxxx],
[xxxxxx],
[xxxxxx],
[xxxxxx]
]
As I wrote if database returns the information for the grid, it could look like this, for instance,
let db = {
0: {x:1,y:0,w:2:h1},
1: {x:4,y:0,w:1:h1},
2: {x:3,y:2,w:2:h2},
}
respectively to that information the grid would look like
[
[x00x1x],
[xxxxxx],
[xxx22x],
[xxx22x],
[xxxxxx]
]
And after that need to refill empty cells with empty div
elements. But the function specified above didn't check that and causes issues
Upvotes: 0
Views: 135
Reputation: 258
If I understand correctly your goal, you want to generate a grid with filled cells according to an array of coordinates and width/height, written like this (there was typos in your question so I rewrote it down here):
let db = {
0: { x: 1, y: 0, w: 2, h: 1 },
1: { x: 4, y: 0, w: 1, h: 1 },
2: { x: 3, y: 2, w: 2, h: 2 },
}
and it would be represented this way for convenience:
x00x1x xxxxxx xxx22x xxx22x xxxxxx
Since you used the ES6 syntax and lodash on your question, I'll use it also in the proposed answer as well, but I want to mention that this would require changes without lodash and may not work on some system as experimental features are in use here.
Proposed method :
let db = {
0: { x:1, y:0, w:2, h:1 },
1: { x:4, y:0, w:1, h:1 },
2: { x:3, y:2, w:2, h:2 },
};
// Generate the default grid
const emptyGrid = (rows, cols) =>
[...Array(rows).keys()].map((e, row) =>
[...Array(cols).keys()].map((e, col) =>
({ x: col, y: row, w: 0, h: 0 })));
// Generate array of cell coordinates to fill from width and height
const cellCoords = cell => {
let coords = [];
for (let i = cell.w - 1; i >= 0; i--)
for (let j = cell.h - 1; j >= 0; j--)
coords = [...coords, {x: cell.x + i, y: cell.y + j}];
return coords;
};
// Generate a grid of rows by cols, filled with optional cells data
const generateGrid = (rows, cols, cells) => {
cells = cells || [];
return _.reduce(cells, (grid, cell, index) => {
cellCoords(cell).forEach(({x, y}) =>
grid[y][x] = {...grid[y][x], ...cell, i: index});
return grid;
}, emptyGrid(rows, cols));
}
// Here are some utilities for the snippet exemple
const displayGrid = (grid, target) => {
grid = _.map(grid, row => _.reduce(row, (s, c) => s + (c.i ? c.i.toString() : 'x'), ''));
document.getElementById(target).innerHTML = grid.join('<br/>');
}
displayGrid(generateGrid(5, 6), 'output')
displayGrid(generateGrid(5, 6, db), 'output-prefilled')
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
Empty Grid:
<div id="output" style="margin:10px"></div>
Prefilled Grid:
<div id="output-prefilled" style="margin:10px"></div>
Upvotes: 2