-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalculateBreakpoints0.js
107 lines (89 loc) · 3.84 KB
/
calculateBreakpoints0.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import calculateFit from "./calculateFit.js";
import deriveViewportFromTable from "./deriveViewportFromTable.js";
import deriveTableFromViewport from "./deriveTableFromViewport.js";
// Maybe the other way around, start with an empty set and keep adding columns in the order of
// priority as long as they fit?
export default function* calculateBreakpoints(
/** @type {Column[]} */
tableColumns,
/** @ype {number | {}} */
deadspace
) {
// Start off with all columns visible because that's the default visibility of an element
let breakpoint = [...tableColumns]
.sort((a, b) => a.weight - b.weight)
.map(c => c.key)
.join();
// Calculate the size above which there can be no breakpoint because all columns fit and go from there
const fitTableWidth = calculateFit(tableColumns);
// Calculate a viewport size which fits the fit table size to start from
const fitViewportWidth = deriveViewportFromTable(fitTableWidth, deadspace);
// Walk the viewport size down to zero and determine which columns hide or show
for (
let viewportWidth = 165; // fitViewportWidth;
viewportWidth > 164; // 0;
viewportWidth--
) {
let tableWidth = deriveTableFromViewport(viewportWidth, deadspace);
// Start with all the columns in each viewport dimension and recursively remove the unfitting ones
const columns = [...tableColumns].sort((a, b) => a.weight - b.weight);
// Hoist which column to remove outside of the loop so that we can use it in its condition
/** @type {Column?} */
let columnToRemove;
do {
console.group(viewportWidth, tableWidth);
// Reset this so that we avoid a false positive in the `while` condition if this is set from last iteration
columnToRemove = undefined;
// Recalculate the sum total of the ratio excluding the removed columns so the ratios add up to 1
const adjustedColumnRatioSum = columns.reduce(
(a, c) => a + (c.ratio || 1),
0
);
// Walk the remaining columns in this iteration for this viewport size in case of multiple removals
for (const column of columns) {
// Recalculate the column ratio to compare it to the ratio sum total of the remaining columns
const adjustedColumnRatio =
(column.ratio || 1) / adjustedColumnRatioSum;
// Determine the size occupied by the column with its adjusted ratio among the remaining columns
const effectiveColumnWidth = adjustedColumnRatio * tableWidth;
console.log(
column.key,
column.weight,
effectiveColumnWidth,
column.limit,
effectiveColumnWidth < column.limit ? "no fit" : ""
);
if (
// Mark this column for deletion if it doesn't reach its limit
effectiveColumnWidth < (column.limit || 0) &&
// Replace the currently marked column for deletion only if this one has lower weight
(!columnToRemove ||
(column.weight || 0) < (columnToRemove.weight || 0))
) {
columnToRemove = column;
}
}
// Remove the non-fitting column with the lowest weight if any
if (columnToRemove) {
columns.splice(columns.indexOf(columnToRemove), 1);
console.log("ditch", columnToRemove.key, columnToRemove.weight);
}
console.groupEnd();
// Continue if we find a non-fitting column if any to recalculate the remaining columns' fit
} while (columnToRemove);
const visibleColumns = columns.map(c => c.key).join();
if (breakpoint !== visibleColumns) {
console.log(visibleColumns);
yield {
version: 0,
tableBreakpoint: tableWidth,
viewportBreakpoint: viewportWidth,
columns: tableColumns.map(c => ({
key: c.key,
status: columns.includes(c) ? "visible" : "hidden"
}))
};
breakpoint = visibleColumns;
}
}
}