UNPKG

4.88 kBPlain TextView Raw
1import {Config, FONT_ROW_RATIO} from './config';
2import {getStringWidth, ellipsize} from './common';
3
4/**
5 * Calculate the column widths
6 */
7export function calculateWidths(doc, pageWidth) {
8
9 let table = Config.tableInstance();
10
11 // Column and table content width
12 let fixedWidth = 0;
13 let autoWidth = 0;
14 let dynamicColumns = [];
15 table.columns.forEach(function (column) {
16 column.contentWidth = 0;
17 table.rows.concat(table.headerRow).forEach(function (row) {
18 let cell = row.cells[column.dataKey];
19 cell.contentWidth = cell.padding('horizontal') + getStringWidth(cell.text, cell.styles);
20 if (cell.contentWidth > column.contentWidth) {
21 column.contentWidth = cell.contentWidth;
22 }
23 });
24 table.contentWidth += column.contentWidth;
25 if (typeof column.widthStyle === 'number') {
26 column.preferredWidth = column.widthStyle;
27 fixedWidth += column.preferredWidth;
28 column.width = column.preferredWidth;
29 } else if (column.widthStyle === 'wrap') {
30 column.preferredWidth = column.contentWidth;
31 fixedWidth += column.preferredWidth;
32 column.width = column.preferredWidth;
33 } else {
34 column.preferredWidth = column.contentWidth;
35 autoWidth += column.contentWidth;
36 dynamicColumns.push(column);
37 }
38 table.preferredWidth += column.preferredWidth;
39 });
40
41 if (typeof table.settings.tableWidth === 'number') {
42 table.width = table.settings.tableWidth;
43 } else if (table.settings.tableWidth === 'wrap') {
44 table.width = table.preferredWidth;
45 } else {
46 table.width = pageWidth - table.margin('left') - table.margin('right');
47 }
48
49 distributeWidth(dynamicColumns, fixedWidth, autoWidth, 0);
50
51 // Row height, table height and text overflow
52 let all = table.rows.concat(table.headerRow);
53 all.forEach(function (row) {
54 table.columns.forEach(function (col) {
55 let cell = row.cells[col.dataKey];
56
57 Config.applyStyles(cell.styles);
58 let textSpace = col.width - cell.padding('horizontal');
59 if (cell.styles.overflow === 'linebreak') {
60 // Add one pt to textSpace to fix rounding error
61 try {
62 cell.text = doc.splitTextToSize(cell.text, textSpace + 1, {fontSize: cell.styles.fontSize});
63 } catch(e) {
64 if (e instanceof TypeError && Array.isArray(cell.text)) {
65 cell.text = doc.splitTextToSize(cell.text.join(' '), textSpace + 1, {fontSize: cell.styles.fontSize});
66 } else {
67 throw e;
68 }
69 }
70 } else if (cell.styles.overflow === 'ellipsize') {
71 cell.text = ellipsize(cell.text, textSpace, cell.styles);
72 } else if (cell.styles.overflow === 'visible') {
73 // Do nothing
74 } else if (cell.styles.overflow === 'hidden') {
75 cell.text = ellipsize(cell.text, textSpace, cell.styles, '');
76 } else if (typeof cell.styles.overflow === 'function') {
77 cell.text = cell.styles.overflow(cell.text, textSpace);
78 } else {
79 console.error("Unrecognized overflow type: " + cell.styles.overflow);
80 }
81
82 let k = Config.scaleFactor();
83 let lineCount = Array.isArray(cell.text) ? cell.text.length : 1;
84 let fontHeight = cell.styles.fontSize / k * FONT_ROW_RATIO;
85 cell.contentHeight = lineCount * fontHeight + cell.padding('vertical');
86 if (cell.contentHeight > row.height) {
87 row.height = cell.contentHeight;
88 row.maxLineCount = lineCount;
89 }
90 });
91
92 table.height += row.height;
93 });
94}
95
96function distributeWidth(dynamicColumns, staticWidth, dynamicColumnsContentWidth, fairWidth) {
97 let table = Config.tableInstance();
98 let extraWidth = table.width - staticWidth - dynamicColumnsContentWidth;
99 for (let i = 0; i < dynamicColumns.length; i++) {
100 let col = dynamicColumns[i];
101 let ratio = col.contentWidth / dynamicColumnsContentWidth;
102 // A column turned out to be none dynamic, start over recursively
103 let isNoneDynamic = col.contentWidth + extraWidth * ratio < fairWidth;
104 if (extraWidth < 0 && isNoneDynamic) {
105 dynamicColumns.splice(i, 1);
106 dynamicColumnsContentWidth -= col.contentWidth;
107 col.width = fairWidth;
108 staticWidth += col.width;
109 distributeWidth(dynamicColumns, staticWidth, dynamicColumnsContentWidth, fairWidth);
110 break;
111 } else {
112 col.width = col.contentWidth + extraWidth * ratio;
113 }
114 }
115}
\No newline at end of file