| 120413 | return v < 0 ? Math.ceil(-v) : 0; |
| 120414 | } |
| 120415 | function gridLayout(view, groups, opt) { |
| 120416 | var dirty = !opt.nodirty, bbox = opt.bounds === Flush ? bboxFlush : bboxFull, bounds = tempBounds.set(0, 0, 0, 0), alignCol = get(opt.align, Column), alignRow = get(opt.align, Row), padCol = get(opt.padding, Column), padRow = get(opt.padding, Row), ncols = opt.columns || groups.length, nrows = ncols <= 0 ? 1 : Math.ceil(groups.length / ncols), n = groups.length, xOffset = Array(n), xExtent = Array(ncols), xMax = 0, yOffset = Array(n), yExtent = Array(nrows), yMax = 0, dx = Array(n), dy = Array(n), boxes = Array(n), m, i, c, r, b, g, px, py, x, y, offset; |
| 120417 | for(i = 0; i < ncols; ++i)xExtent[i] = 0; |
| 120418 | for(i = 0; i < nrows; ++i)yExtent[i] = 0; // determine offsets for each group |
| 120419 | for(i = 0; i < n; ++i){ |
| 120420 | g = groups[i]; |
| 120421 | b = boxes[i] = bbox(g); |
| 120422 | g.x = g.x || 0; |
| 120423 | dx[i] = 0; |
| 120424 | g.y = g.y || 0; |
| 120425 | dy[i] = 0; |
| 120426 | c = i % ncols; |
| 120427 | r = ~~(i / ncols); |
| 120428 | xMax = Math.max(xMax, px = Math.ceil(b.x2)); |
| 120429 | yMax = Math.max(yMax, py = Math.ceil(b.y2)); |
| 120430 | xExtent[c] = Math.max(xExtent[c], px); |
| 120431 | yExtent[r] = Math.max(yExtent[r], py); |
| 120432 | xOffset[i] = padCol + offsetValue(b.x1); |
| 120433 | yOffset[i] = padRow + offsetValue(b.y1); |
| 120434 | if (dirty) view.dirty(groups[i]); |
| 120435 | } // set initial alignment offsets |
| 120436 | for(i = 0; i < n; ++i){ |
| 120437 | if (i % ncols === 0) xOffset[i] = 0; |
| 120438 | if (i < ncols) yOffset[i] = 0; |
| 120439 | } // enforce column alignment constraints |
| 120440 | if (alignCol === Each) for(c = 1; c < ncols; ++c){ |
| 120441 | for(offset = 0, i = c; i < n; i += ncols)if (offset < xOffset[i]) offset = xOffset[i]; |
| 120442 | for(i = c; i < n; i += ncols)xOffset[i] = offset + xExtent[c - 1]; |
| 120443 | } |
| 120444 | else if (alignCol === All) { |
| 120445 | for(offset = 0, i = 0; i < n; ++i)if (i % ncols && offset < xOffset[i]) offset = xOffset[i]; |
| 120446 | for(i = 0; i < n; ++i)if (i % ncols) xOffset[i] = offset + xMax; |
| 120447 | } else { |
| 120448 | for(alignCol = false, c = 1; c < ncols; ++c)for(i = c; i < n; i += ncols)xOffset[i] += xExtent[c - 1]; |
| 120449 | } // enforce row alignment constraints |
| 120450 | if (alignRow === Each) for(r = 1; r < nrows; ++r){ |
| 120451 | for(offset = 0, i = r * ncols, m = i + ncols; i < m; ++i)if (offset < yOffset[i]) offset = yOffset[i]; |
| 120452 | for(i = r * ncols; i < m; ++i)yOffset[i] = offset + yExtent[r - 1]; |
| 120453 | } |
| 120454 | else if (alignRow === All) { |
| 120455 | for(offset = 0, i = ncols; i < n; ++i)if (offset < yOffset[i]) offset = yOffset[i]; |
| 120456 | for(i = ncols; i < n; ++i)yOffset[i] = offset + yMax; |
| 120457 | } else { |
| 120458 | for(alignRow = false, r = 1; r < nrows; ++r)for(i = r * ncols, m = i + ncols; i < m; ++i)yOffset[i] += yExtent[r - 1]; |
| 120459 | } // perform horizontal grid layout |
| 120460 | for(x = 0, i = 0; i < n; ++i){ |
| 120461 | x = xOffset[i] + (i % ncols ? x : 0); |
| 120462 | dx[i] += x - groups[i].x; |
| 120463 | } // perform vertical grid layout |
| 120464 | for(c = 0; c < ncols; ++c)for(y = 0, i = c; i < n; i += ncols){ |
| 120465 | y += yOffset[i]; |
| 120466 | dy[i] += y - groups[i].y; |
| 120467 | } |
| 120468 | // perform horizontal centering |
| 120469 | if (alignCol && get(opt.center, Column) && nrows > 1) for(i = 0; i < n; ++i){ |
| 120470 | b = alignCol === All ? xMax : xExtent[i % ncols]; |
| 120471 | x = b - boxes[i].x2 - groups[i].x - dx[i]; |
| 120472 | if (x > 0) dx[i] += x / 2; |