react-flexigrid
Version:
A React table component designed to allow presenting millions of rows of data.
365 lines (298 loc) • 10.4 kB
JavaScript
import _extends from 'babel-runtime/helpers/extends';
import _Object$keys from 'babel-runtime/core-js/object/keys';
import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
export function getColumnsWidth(columns) {
return columns.reduce(function (memo, column) {
return memo + column.width;
}, 0);
}
function getContentWidth(columns) {
return columns.reduce(function (memo, _ref) {
var children = _ref.children,
width = _ref.width;
return memo + (children && children.length ? getContentWidth(children) : width);
}, 0);
}
function getFlexGrowCount(columns) {
return columns.reduce(function (memo, _ref2) {
var children = _ref2.children,
flexGrow = _ref2.flexGrow;
return memo + (children && children.length ? getFlexGrowCount(children) : flexGrow || 0);
}, 0);
}
function getFlexColumns(columns) {
var result = [];
columns.forEach(function (column) {
var children = column.children,
flexGrow = column.flexGrow;
if (children && children.length) {
result.push.apply(result, getFlexColumns(children));
} else if (flexGrow) {
result.push(column);
}
});
return result;
}
function getColumnsFixed(columns) {
var fixed = false;
columns.some(function (column) {
if (column.fixed) {
fixed = column.fixed;
return true;
}
return false;
});
return fixed;
}
function getLeftFixedEndIndex(columns) {
// get index of the last left fixed column
for (var i = columns.length - 1; i >= 0; i -= 1) {
var fixed = columns[i].fixed;
if (fixed === true || fixed === 'left') {
return i;
}
}
return -1;
}
function getRightFixedStartIndex(columns) {
// get index of the first right fixed column
for (var i = 0, l = columns.length; i < l; i += 1) {
var fixed = columns[i].fixed;
if (fixed === 'right') {
return i;
}
}
return -1;
}
function colneColumns(columns) {
var widthMap = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
var parent = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
return columns.map(function (_ref3, index) {
var children = _ref3.children,
fixed = _ref3.fixed,
column = _objectWithoutProperties(_ref3, ['children', 'fixed']);
column.depth = depth + 1;
if (children && children.length) {
column.children = colneColumns(children, widthMap, column.depth, column);
column.width = getColumnsWidth(column.children);
// calc group key
column.key = column.children.map(function (_ref4) {
var key = _ref4.key;
return key;
}).join('-');
fixed = getColumnsFixed(column.children); // eslint-disable-line
} else {
// fix column key
if (!column.key) {
column.key = column.dataIndex;
}
if (widthMap[column.key]) {
column.width = widthMap[column.key];
}
}
column.isLastLeaf = index === columns.length - 1;
column.isFirstLeaf = index === 0;
if (fixed) {
column.fixed = fixed;
}
if (parent) {
column.parent = parent;
}
return column;
});
}
function flattenColumns(columns) {
var cols = [];
columns.forEach(function (column) {
if (column.children && column.children.length) {
cols.push.apply(cols, flattenColumns(column.children));
} else {
cols.push(column);
}
});
return cols;
}
function finalCalc(columns, left, fixed) {
var offsetLeft = left;
columns.forEach(function (column) {
column.left = offsetLeft;
var current = column;
var parent = current.parent;
while (parent && current.isFirstLeaf) {
parent.left = current.left;
current = parent;
parent = current.parent;
}
if (fixed && fixed !== column.fixed) {
column.fixed = fixed;
parent = column.parent;
while (parent) {
parent.fixed = fixed;
parent = parent.parent;
}
}
offsetLeft += column.width;
});
}
function sortColumns(columns) {
var orderMap = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var keys = _Object$keys(orderMap);
if (keys.length) {
var orders = keys.map(function (key) {
return orderMap[key];
});
var cache = {};
var result = [];
columns.forEach(function (column) {
var index = keys.indexOf('' + column.key);
if (index >= 0) {
cache[orders[index]] = column;
result.push(null);
} else {
result.push(column);
}
});
_Object$keys(cache).forEach(function (order) {
var column = cache[order];
result[order] = column;
delete orderMap[column.key];
});
keys = _Object$keys(orderMap);
if (keys.length) {
result.some(function (column) {
keys = _Object$keys(orderMap);
if (keys.length && column.children) {
column.children = sortColumns(column.children, orderMap);
}
return keys.length === 0;
});
}
return result;
}
return columns;
}
export function shrinkColumnsWidth(columnData, exceedWidth) {
var growCount = columnData.growCount,
leftFixedLeafColumns = columnData.leftFixedLeafColumns,
scrollableLeafColumns = columnData.scrollableLeafColumns,
rightFixedLeafColumns = columnData.rightFixedLeafColumns;
var columnCount = leftFixedLeafColumns.length + scrollableLeafColumns.length + rightFixedLeafColumns.length;
var divideEqually = growCount === 0;
var factor = exceedWidth / (divideEqually ? columnCount : growCount);
var calc = function calc(columns, unAssignedWidth, isLast) {
var assigned = 0;
var unassigned = unAssignedWidth;
var length = columns.length;
columns.forEach(function (column, index) {
var grow = divideEqually ? 1 : column.flexGrow;
var growWidth = Math.round(factor * grow);
if (unassigned - growWidth < 0) {
growWidth = unassigned;
}
if (isLast && index === length - 1) {
growWidth = unassigned;
}
if (growWidth && unassigned) {
assigned += growWidth;
unassigned -= growWidth;
column.width -= growWidth;
var parent = column.parent;
while (parent) {
parent.width -= growWidth;
parent = parent.parent;
}
}
});
return {
assigned: assigned,
unassigned: unassigned
};
};
var _calc = calc(leftFixedLeafColumns, exceedWidth, scrollableLeafColumns.length === 0 && rightFixedLeafColumns.length === 0),
assigned = _calc.assigned,
unassigned = _calc.unassigned;
if (assigned > 0) {
columnData.leftFixedColumnsWidth -= assigned;
}
if (unassigned > 0) {
var ret = calc(scrollableLeafColumns, unassigned, rightFixedLeafColumns.length === 0);
assigned = ret.assigned;
unassigned = ret.unassigned;
}
if (assigned > 0) {
columnData.scrollableColumnsWidth -= assigned;
}
if (unassigned) {
var _ret = calc(rightFixedLeafColumns, unassigned, true);
assigned = _ret.assigned;
}
if (assigned > 0) {
columnData.rightFixedColumnsWidth -= assigned;
}
}
export function parseColumns(columns, _ref5) {
var _ref5$widthMap = _ref5.widthMap,
widthMap = _ref5$widthMap === undefined ? {} : _ref5$widthMap,
_ref5$orderMap = _ref5.orderMap,
orderMap = _ref5$orderMap === undefined ? {} : _ref5$orderMap,
viewportWidth = _ref5.viewportWidth;
var contentWidth = getContentWidth(columns);
var growCount = getFlexGrowCount(columns);
if (contentWidth < viewportWidth && growCount) {
var flexColumns = getFlexColumns(columns);
var unsignedWidth = viewportWidth - contentWidth;
var factor = unsignedWidth / growCount;
var flexColumnsCount = flexColumns.length;
widthMap = _extends({}, widthMap); // eslint-disable-line
flexColumns.forEach(function (_ref6, index) {
var key = _ref6.key,
dataIndex = _ref6.dataIndex,
flexGrow = _ref6.flexGrow,
width = _ref6.width;
var keey = key || dataIndex;
var addWidth = index === flexColumnsCount - 1 ? unsignedWidth : Math.round(factor * flexGrow);
unsignedWidth -= addWidth;
if (!widthMap[keey]) {
widthMap[keey] = width + addWidth;
}
});
}
columns = colneColumns(columns, widthMap); // eslint-disable-line
var leftFixedIndex = getLeftFixedEndIndex(columns);
var rightFixedIndex = getRightFixedStartIndex(columns);
var leftFixedColumns = leftFixedIndex >= 0 ? columns.slice(0, leftFixedIndex + 1) : [];
var rightFixedColumns = rightFixedIndex > 0 ? columns.slice(rightFixedIndex, columns.length) : [];
var scrollableColumns = columns.slice(leftFixedIndex >= 0 ? leftFixedIndex + 1 : 0, rightFixedIndex > 0 ? rightFixedIndex : columns.length);
var cachedOrderMap = _extends({}, orderMap);
leftFixedColumns = sortColumns(leftFixedColumns, cachedOrderMap);
scrollableColumns = sortColumns(scrollableColumns, cachedOrderMap);
rightFixedColumns = sortColumns(rightFixedColumns, cachedOrderMap);
var leftFixedLeafColumns = flattenColumns(leftFixedColumns);
var scrollableLeafColumns = flattenColumns(scrollableColumns);
var rightFixedLeafColumns = flattenColumns(rightFixedColumns);
finalCalc(leftFixedLeafColumns, 0, 'left');
finalCalc(scrollableLeafColumns, getColumnsWidth(leftFixedColumns), null);
finalCalc(rightFixedLeafColumns, 0, 'right');
var depth = Math.max(Math.max.apply(Math, leftFixedLeafColumns.map(function (column) {
return column.depth;
})), Math.max.apply(Math, scrollableLeafColumns.map(function (column) {
return column.depth;
})), Math.max.apply(Math, rightFixedLeafColumns.map(function (column) {
return column.depth;
})));
return {
columns: columns,
leftFixedColumns: leftFixedColumns,
scrollableColumns: scrollableColumns,
rightFixedColumns: rightFixedColumns,
leftFixedLeafColumns: leftFixedLeafColumns,
scrollableLeafColumns: scrollableLeafColumns,
rightFixedLeafColumns: rightFixedLeafColumns,
leftFixedColumnsWidth: getColumnsWidth(leftFixedColumns),
scrollableColumnsWidth: getColumnsWidth(scrollableColumns),
rightFixedColumnsWidth: getColumnsWidth(rightFixedColumns),
growCount: growCount,
depth: depth
};
}