127 lines
2.9 KiB
JavaScript
127 lines
2.9 KiB
JavaScript
/**
|
|
* Reorders a flat array into column-major order for grid display.
|
|
*
|
|
* @param {object[]} arr
|
|
* @param {number} numCols
|
|
* @returns {object[]}
|
|
*/
|
|
export function reorderForColumnSorting(arr, numCols) {
|
|
const numRows = Math.ceil(arr.length / numCols);
|
|
const reordered = new Array(arr.length);
|
|
|
|
const baseRowCount = Math.floor(arr.length / numCols);
|
|
const extraColumns = arr.length % numCols;
|
|
|
|
const colHeights = new Array(numCols).fill(baseRowCount);
|
|
for (let i = 0; i < extraColumns; i++) {
|
|
colHeights[i] += 1;
|
|
}
|
|
|
|
let index = 0;
|
|
|
|
for (let col = 0; col < numCols; col++) {
|
|
const rowCount = colHeights[col];
|
|
|
|
for (let row = 0; row < rowCount; row++) {
|
|
const newIndex = numCols * row + col;
|
|
|
|
if (newIndex < arr.length) {
|
|
reordered[newIndex] = arr[index];
|
|
index += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return reordered;
|
|
}
|
|
|
|
/**
|
|
* @param {object} column
|
|
* @param {object} group
|
|
* @returns {void}
|
|
*/
|
|
function appendSkillGroupToColumn(column, group) {
|
|
column.blocks.push({
|
|
type: "groupHeader",
|
|
group: group.group,
|
|
label: group.label,
|
|
...(group.isSpecialTraining ? { isSpecialTraining: true } : {}),
|
|
});
|
|
|
|
const skillType = group.isSpecialTraining ? "training" : "typedSkill";
|
|
for (const skill of group.skills) {
|
|
column.blocks.push({ ...skill, type: skillType });
|
|
}
|
|
|
|
column.height += group.rowCount;
|
|
}
|
|
|
|
/**
|
|
* @param {object[]} groups
|
|
* @param {number} numCols
|
|
* @returns {object[][]}
|
|
*/
|
|
function packSkillGroupsByColumn(groups, numCols) {
|
|
const columns = Array.from({ length: numCols }, () => ({
|
|
blocks: [],
|
|
height: 0,
|
|
}));
|
|
|
|
if (groups.length === 0) {
|
|
return columns.map((col) => col.blocks);
|
|
}
|
|
|
|
const totalHeight = groups.reduce((sum, group) => sum + group.rowCount, 0);
|
|
const targetHeight = totalHeight / numCols;
|
|
let colIndex = 0;
|
|
|
|
for (const group of groups) {
|
|
const col = columns[colIndex];
|
|
|
|
if (
|
|
colIndex < numCols - 1 &&
|
|
col.blocks.length > 0 &&
|
|
col.height + group.rowCount > targetHeight
|
|
) {
|
|
colIndex += 1;
|
|
}
|
|
|
|
appendSkillGroupToColumn(columns[colIndex], group);
|
|
}
|
|
|
|
return columns.map((col) => col.blocks);
|
|
}
|
|
|
|
/**
|
|
* @param {object[]} groups
|
|
* @param {number} numCols
|
|
* @returns {object[][]}
|
|
*/
|
|
function packSkillGroupsByRow(groups, numCols) {
|
|
const columns = Array.from({ length: numCols }, () => ({
|
|
blocks: [],
|
|
height: 0,
|
|
}));
|
|
|
|
for (let i = 0; i < groups.length; i++) {
|
|
appendSkillGroupToColumn(columns[i % numCols], groups[i]);
|
|
}
|
|
|
|
return columns.map((col) => col.blocks);
|
|
}
|
|
|
|
/**
|
|
* Packs skill groups into columns without splitting a group across columns.
|
|
*
|
|
* @param {object[]} groups
|
|
* @param {number} numCols
|
|
* @param {boolean} sortByColumn
|
|
* @returns {object[][]}
|
|
*/
|
|
export function packSkillGroupsIntoColumns(groups, numCols, sortByColumn) {
|
|
if (sortByColumn) {
|
|
return packSkillGroupsByColumn(groups, numCols);
|
|
}
|
|
return packSkillGroupsByRow(groups, numCols);
|
|
}
|