Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(table): 列宽调整需要考虑列的最小宽度 #803

Merged
merged 6 commits into from
Sep 4, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 53 additions & 9 deletions js/table/recalculate-column-width.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,22 @@ export default function recalculateColumnWidth<T extends BaseTableCol<T>>(
const missingWidthCols: T[] = [];
const thMap: { [colKey: string]: number } = {};

// 获取列 width 属性
const getColWidth = (col: T) => {
const { width } = col;
return isNumber(width) ? width : parseFloat(width);
};

// 获取列 minWidth 属性
const getColMinWidth = (col: T) => {
const { minWidth } = col;
return isNumber(minWidth) ? minWidth : parseFloat(minWidth);
};
ZTao-z marked this conversation as resolved.
Show resolved Hide resolved

// 计算现有列的列宽总和
columns.forEach((col) => {
if (!thWidthList[col.colKey]) {
thMap[col.colKey] = isNumber(col.width) ? col.width : parseFloat(col.width);
thMap[col.colKey] = getColWidth(col);
} else {
thMap[col.colKey] = thWidthList[col.colKey];
}
Expand All @@ -36,24 +48,56 @@ export default function recalculateColumnWidth<T extends BaseTableCol<T>>(
if (missingWidthCols.length) {
// 当前列宽总宽度小于表宽,将剩余宽度平均分配给未指定宽度的列
if (actualWidth < tableWidth) {
const widthDiff = tableWidth - actualWidth;
const avgWidth = widthDiff / missingWidthCols.length;
let widthDiff = tableWidth - actualWidth;
const remainCols: T[] = [];
// 优先保证设置了minWidth的列满足最小宽度
missingWidthCols.forEach((col) => {
thMap[col.colKey] = avgWidth;
const minWidth = getColMinWidth(col);
if (minWidth) {
thMap[col.colKey] = minWidth;
widthDiff -= minWidth;
} else {
remainCols.push(col);
}
});

// 如果剩余宽度 > 0
if (widthDiff > 0) {
ZTao-z marked this conversation as resolved.
Show resolved Hide resolved
// 如果存在未设置minWidth的列,这些列均分剩余宽度
if (remainCols.length) {
const avgWidth = widthDiff / remainCols.length;
remainCols.forEach((col) => {
thMap[col.colKey] = avgWidth;
});
} else {
// 否则所有列均分剩余宽度
const avgWidth = widthDiff / missingWidthCols.length;
missingWidthCols.forEach((col) => {
thMap[col.colKey] += avgWidth;
});
}
} else {
// 剩余宽度 <= 0, 所有剩余列默认填充100px
remainCols.forEach((col) => {
thMap[col.colKey] = 100;
});
}
} else if (tableLayout === 'fixed') {
// 当前列表总宽度大于等于表宽,且当前排版模式为fixed,默认填充100px
// 当前列表总宽度大于等于表宽,且当前排版模式为fixed,默认填充minWidth || 100px
missingWidthCols.forEach((col) => {
const originWidth = thMap[col.colKey] || 100;
const originWidth = getColMinWidth(col) || 100;
thMap[col.colKey] = isNumber(originWidth) ? originWidth : parseFloat(originWidth);
});
} else {
// 当前列表总宽度大于等于表宽,且当前排版模式为auto,默认填充100px,然后按比例重新分配各列宽度
const extraWidth = missingWidthCols.length * 100;
// 当前列表总宽度大于等于表宽,且当前排版模式为auto,默认填充minWidth || 100px,然后按比例重新分配各列宽度
let extraWidth = 0;
missingWidthCols.forEach((col) => {
extraWidth += getColMinWidth(col) || 100;
});
const totalWidth = extraWidth + actualWidth;
columns.forEach((col) => {
if (!thMap[col.colKey]) {
thMap[col.colKey] = (100 / totalWidth) * tableWidth;
thMap[col.colKey] = ((getColMinWidth(col) || 100) / totalWidth) * tableWidth;
} else {
thMap[col.colKey] = (thMap[col.colKey] / totalWidth) * tableWidth;
}
Expand Down
36 changes: 26 additions & 10 deletions js/table/set-column-width-by-drag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ export default function setThWidthListByColumnDrag<T extends BaseTableCol<T>>(
const dragChildrenCols = findAllChildren(dragCol);
const effectChildrenCols = findAllChildren(effectCol);

// 获取列 width 属性
const getColWidth = (col: T) => {
const { width } = col;
return isNumber(width) ? width : parseFloat(width);
};

// 获取列 minWidth 属性
const getColMinWidth = (col: T) => {
const { minWidth } = col;
return isNumber(minWidth) ? minWidth : parseFloat(minWidth);
};
ZTao-z marked this conversation as resolved.
Show resolved Hide resolved

// 若有
if (dragChildrenCols.length || effectChildrenCols.length) {
let oldWidth = 0;
Expand All @@ -54,17 +66,18 @@ export default function setThWidthListByColumnDrag<T extends BaseTableCol<T>>(

// 根据多级表头的叶节点计算实际宽度(拖动列)
dragChildrenCols.forEach((child) => {
const defaultWidth = isNumber(child.width) ? child.width : parseFloat(child.width);
oldWidth += thWidthList[child.colKey] || defaultWidth;
oldWidth += thWidthList[child.colKey] || getColWidth(child);
notCalculateCols.push(child.colKey);
});

// 根据多级表头的叶节点计算实际宽度(受影响的列)
effectChildrenCols.forEach((child) => {
const defaultWidth = isNumber(child.width) ? child.width : parseFloat(child.width);
oldEffectWidth += thWidthList[child.colKey] || defaultWidth;
oldEffectWidth += thWidthList[child.colKey] || getColWidth(child);
notCalculateCols.push(child.colKey);
effectColsMinWidth += child.resize?.minWidth || DEFAULT_MIN_WIDTH;
effectColsMinWidth += Math.max(
child.resize?.minWidth || DEFAULT_MIN_WIDTH,
getColMinWidth(child) || DEFAULT_MIN_WIDTH
);
});

// 按比例划分新宽度(拖动列)
Expand All @@ -76,27 +89,30 @@ export default function setThWidthListByColumnDrag<T extends BaseTableCol<T>>(
const remainWidth = Math.max(
effectColsMinWidth,
oldWidth + oldEffectWidth - dragWidth,
effectCol.resize?.minWidth || DEFAULT_MIN_WIDTH,
Math.max(
getColMinWidth(effectCol) || DEFAULT_MIN_WIDTH,
effectCol.resize?.minWidth || DEFAULT_MIN_WIDTH
),
);
effectChildrenCols.forEach((child) => {
updateMap[child.colKey] = Math.max(
child.resize?.minWidth || DEFAULT_MIN_WIDTH,
getColMinWidth(child) || DEFAULT_MIN_WIDTH,
(thWidthList[child.colKey] / oldEffectWidth) * remainWidth,
);
});

// 更新各列宽度
callback(updateMap, notCalculateCols);
} else {
const colWidth = isNumber(dragCol.width) ? dragCol.width : parseFloat(dragCol.width);
const effectWidth = isNumber(effectCol.width) ? effectCol.width : parseFloat(effectCol.width);
const oldWidth = thWidthList[dragCol.colKey] || colWidth;
const oldEffectWidth = thWidthList[effectCol.colKey] || effectWidth;
const oldWidth = thWidthList[dragCol.colKey] || getColWidth(dragCol);
const oldEffectWidth = thWidthList[effectCol.colKey] || getColWidth(effectCol);

callback({
[dragCol.colKey]: dragWidth,
[effectCol.colKey]: Math.max(
effectCol.resize?.minWidth || DEFAULT_MIN_WIDTH,
getColMinWidth(effectCol) || DEFAULT_MIN_WIDTH,
oldWidth + oldEffectWidth - dragWidth,
),
}, [dragCol.colKey, effectCol.colKey]);
Expand Down
3 changes: 2 additions & 1 deletion js/table/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ export interface BaseTableCol<T> {
children?: T[],
colKey?: string,
resize?: { [attr: string]: any },
width?: number | string
width?: number | string,
minWidth?: number | string,
}