diff options
| author | Terry Truong <terry06890@gmail.com> | 2022-03-27 17:45:48 +1100 |
|---|---|---|
| committer | Terry Truong <terry06890@gmail.com> | 2022-03-27 18:02:55 +1100 |
| commit | bdc3bf69fae2e61aed8b3e41f46d2b0675a88231 (patch) | |
| tree | de31d85550736c8f224ef5fb9d146cd8348ed0de /src/lib.ts | |
| parent | 3e5f65f838b4a6676eaaf37ac25690176e51b6e0 (diff) | |
Add faster rect-layout algorithm
Diffstat (limited to 'src/lib.ts')
| -rw-r--r-- | src/lib.ts | 32 |
1 files changed, 30 insertions, 2 deletions
@@ -142,7 +142,8 @@ export type LayoutOptions = { minTileSz: number; // Minimum size of a tile edge, in pixels (ignoring borders) maxTileSz: number; layoutType: 'sqr' | 'rect' | 'sweep'; // The LayoutFn function to use - rectMode: 'horz' | 'vert' | 'linear' | 'auto'; // Layout in 1 row, 1 column, 1 row or column, or multiple rows + rectMode: 'horz' | 'vert' | 'linear' | 'auto' | 'auto first-row'; + // Layout in 1 row, 1 column, 1 row or column, or multiple rows (with/without first-row-heuristic) sweepMode: 'left' | 'top' | 'shorter' | 'auto'; // Sweep to left, top, shorter-side, or to minimise empty space sweptNodesPrio: 'linear' | 'sqrt' | 'pow-2/3'; // Specifies allocation of space to swept-vs-remaining nodes sweepingToParent: boolean; // Allow swept nodes to occupy empty space in a parent's swept-leaves area @@ -341,7 +342,7 @@ let rectLayout: LayoutFn = function (node, pos, dims, showHeader, allowCollapse, return false; } // Try finding arrangement with low empty space - // Done by searching possible row groupings, allocating within rows using dCounts, and trimming empty space + // Done by searching possible rows groupings, allocating within rows using dCounts, and trimming empty space let numChildren = node.children.length; let rowBrks: number[] = []; // Will hold indices for nodes at which each row starts let lowestEmpSpc = Number.POSITIVE_INFINITY; @@ -389,6 +390,33 @@ let rectLayout: LayoutFn = function (node, pos, dims, showHeader, allowCollapse, } } break; + case 'auto first-row': // Like auto, but only iterates over first-rows, determining the rest with dCounts + if (rowBrks.length == 0){ + rowBrks = [0]; + } else { + // Get next possible first row + let idxFirstRowLastEl = (rowBrks.length == 1 ? numChildren : rowBrks[1]) - 1; + if (idxFirstRowLastEl == 0){ + break rowBrksLoop; + } + rowBrks = [0]; + rowBrks.push(idxFirstRowLastEl); + // Allocate remaining rows + let firstRowDCount = arraySum(range(rowBrks[1]).map(idx => node.children[idx].dCount)); + let dCountTotal = node.children[idxFirstRowLastEl].dCount; + let nextRowIdx = idxFirstRowLastEl + 1; + while (nextRowIdx < numChildren){ // Over potential next row breaks + let nextDCountTotal = dCountTotal + node.children[nextRowIdx].dCount; + if (nextDCountTotal <= firstRowDCount){ // If acceptable within current row + dCountTotal = nextDCountTotal; + } else { + rowBrks.push(nextRowIdx); + dCountTotal = node.children[nextRowIdx].dCount; + } + nextRowIdx++; + } + } + break; } // Create array-of-arrays representing each rows' cells' dCounts let rowsOfCnts: number[][] = new Array(rowBrks.length); |
