forked from bvaughn/react-virtualized
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSectionManager.js
More file actions
117 lines (99 loc) · 3.06 KB
/
SectionManager.js
File metadata and controls
117 lines (99 loc) · 3.06 KB
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
108
109
110
111
112
113
114
115
116
117
/**
* Window Sections are used to group nearby cells.
* This enables us to more quickly determine which cells to display in a given region of the Window.
* @flow
*/
import Section from './Section'
import type { Index, SizeAndPositionInfo } from './types'
const SECTION_SIZE = 100
type RegisterCellParams = {
cellMetadatum: SizeAndPositionInfo,
index: number
};
/**
* Contains 0 to many Sections.
* Grows (and adds Sections) dynamically as cells are registered.
* Automatically adds cells to the appropriate Section(s).
*/
export default class SectionManager {
constructor (sectionSize = SECTION_SIZE) {
this._sectionSize = sectionSize
this._cellMetadata = []
this._sections = {}
}
/**
* Gets all cell indices contained in the specified region.
* A region may encompass 1 or more Sections.
*/
getCellIndices ({
height,
width,
x,
y
}: SizeAndPositionInfo): Array<number> {
const indices = {}
this.getSections({ height, width, x, y })
.forEach(
(section) => section.getCellIndices().forEach(
(index) => {
indices[index] = index
}
)
)
// Object keys are strings; this function returns numbers
return Object.keys(indices).map((index) => indices[index])
}
/** Get size and position information for the cell specified. */
getCellMetadata ({
index
}: Index): SizeAndPositionInfo {
return this._cellMetadata[index]
}
/** Get all Sections overlapping the specified region. */
getSections ({
height,
width,
x,
y
}: SizeAndPositionInfo): Array<Section> {
const sectionXStart = Math.floor(x / this._sectionSize)
const sectionXStop = Math.floor((x + width - 1) / this._sectionSize)
const sectionYStart = Math.floor(y / this._sectionSize)
const sectionYStop = Math.floor((y + height - 1) / this._sectionSize)
const sections = []
for (let sectionX = sectionXStart; sectionX <= sectionXStop; sectionX++) {
for (let sectionY = sectionYStart; sectionY <= sectionYStop; sectionY++) {
const key = `${sectionX}.${sectionY}`
if (!this._sections[key]) {
this._sections[key] = new Section({
height: this._sectionSize,
width: this._sectionSize,
x: sectionX * this._sectionSize,
y: sectionY * this._sectionSize
})
}
sections.push(this._sections[key])
}
}
return sections
}
/** Total number of Sections based on the currently registered cells. */
getTotalSectionCount () {
return Object.keys(this._sections).length
}
/** Intended for debugger/test purposes only */
toString () {
return Object.keys(this._sections).map(
(index) => this._sections[index].toString()
)
}
/** Adds a cell to the appropriate Sections and registers it metadata for later retrievable. */
registerCell ({
cellMetadatum,
index
}: RegisterCellParams) {
this._cellMetadata[index] = cellMetadatum
this.getSections(cellMetadatum)
.forEach((section) => section.addCellIndex({ index }))
}
}