Added caching for render sheet viewport for O(n)
This commit is contained in:
parent
3f896f5603
commit
81bf284591
43
src/main.ts
43
src/main.ts
|
|
@ -11,6 +11,7 @@ import { Styles } from "./modules/styles";
|
|||
import { Viewport } from "./modules/viewport";
|
||||
import './scss/main.scss'
|
||||
import { createSampleConfig, createSampleData } from "./utils/createData";
|
||||
import { Cache, CachedColumn, CachedRow } from "./modules/cache";
|
||||
|
||||
/*
|
||||
! Component structure
|
||||
|
|
@ -41,21 +42,23 @@ export class Spreadsheet {
|
|||
public data: Cell[][]
|
||||
public viewport: Viewport
|
||||
public selection: Selection
|
||||
public cache: Cache
|
||||
|
||||
constructor(target: string | HTMLElement, props?: SpreadsheetConstructorProperties) {
|
||||
const config = createSampleConfig(750, 750)
|
||||
const config = createSampleConfig(10000, 600)
|
||||
if (props?.view) {
|
||||
config.view = props.view
|
||||
}
|
||||
|
||||
this.config = new Config(config)
|
||||
this.sheet = new Sheet(this)
|
||||
const data = createSampleData(750, 750)
|
||||
const data = createSampleData(10000, 600)
|
||||
this.table = new Table(this)
|
||||
this.scroller = new Scroller(this)
|
||||
this.toolbar = new Toolbar(this)
|
||||
this.header = new Header(this)
|
||||
this.editor = new Editor(this)
|
||||
this.cache = this.getInitialCache()
|
||||
this.viewport = new Viewport(this, this.scroller.getViewportBoundlingRect())
|
||||
this.selection = new Selection()
|
||||
|
||||
|
|
@ -66,6 +69,42 @@ export class Spreadsheet {
|
|||
this.appendTableToTarget(target)
|
||||
}
|
||||
|
||||
private getInitialCache(): Cache {
|
||||
const cachedCols: CachedColumn[] = []
|
||||
let currentWidth = 0
|
||||
for(let i = 0; i <= this.config.columns.length - 1; i++) {
|
||||
const col = this.config.columns[i]
|
||||
currentWidth += col.width
|
||||
const cacheCol = new CachedColumn({
|
||||
xPos: currentWidth,
|
||||
colIdx: i
|
||||
})
|
||||
cachedCols.push(cacheCol)
|
||||
}
|
||||
|
||||
const cachedRows: CachedRow[] = []
|
||||
let currentHeight = 0
|
||||
for(let i = 0; i <= this.config.rows.length - 1; i++) {
|
||||
const row = this.config.rows[i]
|
||||
currentHeight += row.height
|
||||
const cacheRow = new CachedRow({
|
||||
yPos: currentHeight,
|
||||
rowIdx: i
|
||||
})
|
||||
cachedRows.push(cacheRow)
|
||||
}
|
||||
|
||||
|
||||
const cache = new Cache({
|
||||
columns: cachedCols,
|
||||
rows: cachedRows
|
||||
})
|
||||
|
||||
console.log("CACHE: ", cache)
|
||||
console.log("CONFIG: ", this.config)
|
||||
return cache
|
||||
}
|
||||
|
||||
private buildComponent(): void {
|
||||
|
||||
const content = document.createElement('div') //* Abstract
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
export interface CachedColumnProperties {
|
||||
xPos: number
|
||||
colIdx: number
|
||||
}
|
||||
|
||||
export class CachedColumn {
|
||||
xPos: number
|
||||
colIdx: number
|
||||
|
||||
constructor(props: CachedColumnProperties) {
|
||||
this.xPos = props.xPos
|
||||
this.colIdx = props.colIdx
|
||||
}
|
||||
}
|
||||
|
||||
export interface CachedRowProperties {
|
||||
yPos: number
|
||||
rowIdx: number
|
||||
}
|
||||
|
||||
export class CachedRow {
|
||||
yPos: number
|
||||
rowIdx: number
|
||||
|
||||
constructor(props: CachedRowProperties) {
|
||||
this.yPos = props.yPos
|
||||
this.rowIdx = props.rowIdx
|
||||
}
|
||||
}
|
||||
|
||||
export interface CacheConstructorProps {
|
||||
columns: CachedColumn[]
|
||||
rows: CachedRow[]
|
||||
}
|
||||
|
||||
export class Cache {
|
||||
public columns: CachedColumn[]
|
||||
public rows: CachedRow[]
|
||||
constructor(initial: CacheConstructorProps) {
|
||||
this.columns = initial.columns
|
||||
this.rows = initial.rows
|
||||
}
|
||||
|
||||
public getRowByYCoord(y: number): number {
|
||||
let rowIdx = 0;
|
||||
for (let i = 0; i < this.rows.length; i++) {
|
||||
if (y <= this.rows[i].yPos) { //* Intersection detect
|
||||
rowIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rowIdx;
|
||||
}
|
||||
|
||||
|
||||
public getColumnByXCoord(x: number): number {
|
||||
let colIdx = 0;
|
||||
for (let i = 0; i < this.columns.length; i++) {
|
||||
if (x <= this.columns[i].xPos) { //* Intersection detect
|
||||
colIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return colIdx;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -55,49 +55,23 @@ export class Viewport {
|
|||
|
||||
/** Get index of first row in viewport */
|
||||
private getFirstRow(): number {
|
||||
let rowIdx = 0
|
||||
for (let idx = 0, currHeight = 0; currHeight <= this.top; idx++) {
|
||||
currHeight += this.root.config.rows[idx].height
|
||||
rowIdx = idx
|
||||
}
|
||||
let rowIdx = this.root.cache.getRowByYCoord(this.top)
|
||||
return rowIdx
|
||||
}
|
||||
|
||||
private getLastRow(): number {
|
||||
let rowIdx = this.getFirstRow()
|
||||
let height = this.top
|
||||
|
||||
while (height <= this.bottom) {
|
||||
height += this.root.config.rows[rowIdx].height
|
||||
if (height >= this.bottom) break;
|
||||
rowIdx++;
|
||||
}
|
||||
|
||||
let rowIdx = this.root.cache.getRowByYCoord(this.bottom)
|
||||
return rowIdx
|
||||
}
|
||||
|
||||
private getFirstCol(): number {
|
||||
let colIdx = 0;
|
||||
let currWidth = 0
|
||||
|
||||
while (currWidth <= this.left) {
|
||||
currWidth += this.root.config.columns[colIdx].width
|
||||
if (currWidth >= this.left) break;
|
||||
colIdx += 1
|
||||
}
|
||||
let colIdx = this.root.cache.getColumnByXCoord(this.left)
|
||||
|
||||
return colIdx
|
||||
}
|
||||
|
||||
private getLastCol(): number {
|
||||
let colIdx = this.getFirstCol()
|
||||
let width = this.left
|
||||
|
||||
while (width <= this.right) {
|
||||
width += this.root.config.columns[colIdx].width
|
||||
if (width >= this.right) break;
|
||||
colIdx++;
|
||||
}
|
||||
let colIdx = this.root.cache.getColumnByXCoord(this.right)
|
||||
|
||||
return colIdx
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue