Skip to content

Commit

Permalink
Merge pull request #255 from logisky/jh/fix
Browse files Browse the repository at this point in the history
Fix scrolling and enhance its performance
  • Loading branch information
ImJeremyHe authored Jan 4, 2025
2 parents d282817 + 06331bf commit 797d3d4
Show file tree
Hide file tree
Showing 27 changed files with 178 additions and 37 deletions.
12 changes: 6 additions & 6 deletions src/components/canvas/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {InvalidFormulaComponent} from './invalid-formula'
import {Buttons, simpleUuid} from '@/core'
import {DialogComponent} from '@/ui/dialog'
import {useInjection} from '@/core/ioc/provider'
import {DataServiceImpl, MAX_COUNT, RenderCell} from '@/core/data2'
import {DataServiceImpl, MAX_COUNT, RenderCell} from '@/core/data'
import {TYPES} from '@/core/ioc/types'
import {CANVAS_ID, CanvasStore, CanvasStoreContext} from './store'
import {observer} from 'mobx-react'
Expand Down Expand Up @@ -108,16 +108,16 @@ const Internal: FC<CanvasProps> = observer((props: CanvasProps) => {
let lastScrollTime = 0
const onMouseWheel = (e: WheelEvent) => {
// only support y scrollbar currently
if (store.anchorY + e.deltaY < 0) {
store.setAnchor(store.anchorX, 0)
return
let delta = e.deltaY
if (store.anchorY + delta < 0) {
delta = -store.anchorY
}

const now = Date.now()
if (now - lastScrollTime < 200) return
if (now - lastScrollTime < 150) return

lastScrollTime = now
store.setAnchor(store.anchorX, store.anchorY + e.deltaY)
store.setAnchor(store.anchorX, store.anchorY + delta)
store.render.render()
store.scrollbar.update('y')
store.scroll()
Expand Down
2 changes: 1 addition & 1 deletion src/components/canvas/contextmenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
BlockInfo,
} from 'logisheets-web'
import {TYPES} from '@/core/ioc/types'
import {DataService} from '@/core/data2'
import {DataService} from '@/core/data'

export interface ContextmenuProps {
mouseevent: MouseEvent
Expand Down
2 changes: 1 addition & 1 deletion src/components/canvas/defs/cell.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {RenderCell} from '@/core/data2'
import {RenderCell} from '@/core/data'
import {shallowCopy} from '@/core'
export type CellType =
| 'Cell'
Expand Down
2 changes: 1 addition & 1 deletion src/components/canvas/defs/match.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {LeftTop} from '@/core/settings'
import {Range} from '@/core/standable'
import {Cell} from './cell'
import {CellViewData} from '@/core/data2'
import {CellViewData} from '@/core/data'

export function getOffset(
clientX: number,
Expand Down
15 changes: 13 additions & 2 deletions src/components/canvas/store/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import {makeObservable, action} from 'mobx'
import {CanvasStore} from './store'
import {Box, CanvasAttr, PainterService, TextAttr} from '@/core/painter'
import {simpleUuid, toA1notation} from '@/core'
import {CellView, RenderCell, toCanvasPosition} from '@/core/data2'
import {CellView, RenderCell, toCanvasPosition} from '@/core/data'
import {LeftTop, SETTINGS} from '@/core/settings'
import {StandardColor, Range, StandardCell} from '@/core/standable'
import {StandardStyle} from '@/core/standable/style'
import {isErrorMessage, PatternFill} from 'logisheets-web'
import {Cell} from '../defs'
import {CONTAINER} from '@/core/ioc/config'
import {TYPES} from '@/core/ioc/types'
import {Pool} from '@/core/pool'
export const CANVAS_ID = simpleUuid()
const BUFFER_SIZE = 50

Expand All @@ -25,11 +28,17 @@ export class Render {
this.store.currSheetIdx,
this.store.anchorX - BUFFER_SIZE,
this.store.anchorY - BUFFER_SIZE,
rect.height + BUFFER_SIZE * 2,
rect.height + BUFFER_SIZE,
rect.width + BUFFER_SIZE
)
resp.then((r) => {
if (isErrorMessage(r)) return
const req = r.request
// Discard responses that are invisible now
if (Math.abs(req.startX - this.store.anchorX) > req.width) return
if (Math.abs(req.startY - this.store.anchorY) > req.height) {
return
}
const data = r.data
this._painterService.setupCanvas(this.canvas)
this._painterService.clear()
Expand All @@ -39,6 +48,8 @@ export class Render {
this._renderTopHeader(data)
this._renderLeftTop()

const pool = CONTAINER.get<Pool>(TYPES.Pool)
pool.releaseCellView(data)
// rerender resizer
this.store.resizer.init()
})
Expand Down
2 changes: 1 addition & 1 deletion src/components/canvas/store/resizer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {action, makeObservable, observable} from 'mobx'
import {CanvasStore} from './store'
import {RenderCell} from '@/core/data2'
import {RenderCell} from '@/core/data'
import {Range} from '@/core/standable'
import {pxToPt, pxToWidth} from '@/core'
import {
Expand Down
2 changes: 1 addition & 1 deletion src/components/canvas/store/scrollbar.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {action, makeObservable, observable} from 'mobx'
import {CanvasStore} from './store'
import type {ScrollbarAttr, ScrollbarType} from '@/components/scrollbar'
import {CANVAS_OFFSET} from '@/core/data2'
import {CANVAS_OFFSET} from '@/core/data'
import {isErrorMessage} from 'logisheets-web'
import {ptToPx, widthToPx} from '@/core'

Expand Down
2 changes: 1 addition & 1 deletion src/components/canvas/store/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {Selector} from './selector'
import {Dnd} from './dnd'
import {ScrollBar} from './scrollbar'
import {Textarea} from './textarea'
import {RenderCell, DataService, CellViewData, CellView} from '@/core/data2'
import {RenderCell, DataService, CellViewData, CellView} from '@/core/data'
import {Range} from '@/core/standable'
import {LeftTop} from '@/core/settings'

Expand Down
2 changes: 1 addition & 1 deletion src/components/content/edit-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {CellInputBuilder, Transaction} from 'logisheets-web'
import {FC, useEffect, useState} from 'react'
import styles from './edit-bar.module.scss'
import {useInjection} from '@/core/ioc/provider'
import {DataService} from '@/core/data2'
import {DataService} from '@/core/data'
import {TYPES} from '@/core/ioc/types'
import {isErrorMessage} from 'packages/web/src/api/utils'
export interface EditBarProps {
Expand Down
2 changes: 1 addition & 1 deletion src/components/sheets-tab/contextmenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from 'logisheets-web'
import {useState} from 'react'
import Modal from 'react-modal'
import {DataService} from '@/core/data2'
import {DataService} from '@/core/data'
import {useInjection} from '@/core/ioc/provider'
import {TYPES} from '@/core/ioc/types'
import {useToast} from '@/ui/notification/useToast'
Expand Down
2 changes: 1 addition & 1 deletion src/components/sheets-tab/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {useInjection} from '@/core/ioc/provider'
import {TYPES} from '@/core/ioc/types'
import {Tabs} from 'antd'
import {Subscription} from 'rxjs'
import {DataService} from '@/core/data2'
import {DataService} from '@/core/data'

export interface SheetTabProps {
activeSheet: number
Expand Down
2 changes: 1 addition & 1 deletion src/components/top-bar/content/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {ColorResult, SketchPicker} from 'react-color'
import styles from './start.module.scss'
import {useEffect, useState} from 'react'
import {StandardColor, StandardFont} from '@/core/standable'
import {DataService} from '@/core/data2'
import {DataService} from '@/core/data'
import {useInjection} from '@/core/ioc/provider'
import {TYPES} from '@/core/ioc/types'
import {isErrorMessage} from 'packages/web/src/api/utils'
Expand Down
2 changes: 1 addition & 1 deletion src/components/top-bar/file/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {ChangeEvent, FC, useRef} from 'react'
import styles from './file.module.scss'
import {getU8} from '@/core/file'
import {DataService} from '@/core/data2'
import {DataService} from '@/core/data'
import {useInjection} from '@/core/ioc/provider'
import {TYPES} from '@/core/ioc/types'
import {useToast} from '@/ui/notification/useToast'
Expand Down
File renamed without changes.
7 changes: 7 additions & 0 deletions src/core/data2/render.ts → src/core/data/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ export class RenderCell {
return this
}

reset() {
this.hidden = false
this.coordinate.reset()
this.position.reset()
this.info = undefined
}

public hidden = false
/**
* start/end row/col index
Expand Down
18 changes: 15 additions & 3 deletions src/core/data2/service.ts → src/core/data/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import {CellViewResponse, ViewManager} from './view_manager'
import {CellView} from './types'
import {Resp, WorkbookClient} from './workbook'
import {Pool} from '../pool'

export const MAX_COUNT = 100000000
export const CANVAS_OFFSET = 100
Expand Down Expand Up @@ -64,7 +65,10 @@ export interface DataService {
@injectable()
export class DataServiceImpl implements DataService {
readonly id = getID()
constructor(@inject(TYPES.Workbook) private _workbook: WorkbookClient) {
constructor(
@inject(TYPES.Workbook) private _workbook: WorkbookClient,
@inject(TYPES.Pool) private _pool: Pool
) {
this._init()
}

Expand Down Expand Up @@ -151,7 +155,11 @@ export class DataServiceImpl implements DataService {
): Resp<CellViewResponse> {
const cacheManager = this._cellViews.get(sheetIdx)
if (!cacheManager) {
const manager = new ViewManager(this._workbook, sheetIdx)
const manager = new ViewManager(
this._workbook,
sheetIdx,
this._pool
)
this._cellViews.set(sheetIdx, manager)
}
const viewManager = this._cellViews.get(sheetIdx) as ViewManager
Expand All @@ -167,7 +175,11 @@ export class DataServiceImpl implements DataService {
): Resp<CellViewResponse> {
const cacheManager = this._cellViews.get(sheetIdx)
if (!cacheManager) {
const manager = new ViewManager(this._workbook, sheetIdx)
const manager = new ViewManager(
this._workbook,
sheetIdx,
this._pool
)
this._cellViews.set(sheetIdx, manager)
}
const viewManager = this._cellViews.get(sheetIdx) as ViewManager
Expand Down
File renamed without changes.
File renamed without changes.
58 changes: 44 additions & 14 deletions src/core/data2/view_manager.ts → src/core/data/view_manager.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import {pxToPt, pxToWidth, widthToPx} from '../rate'
import {LeftTop} from '../settings'
import {RenderCell} from './render'
import {CellViewData, Rect, overlap, OverlapType, CellView} from './types'
import {CellViewData, Rect, CellView} from './types'
import {Range, StandardColInfo, StandardRowInfo} from '@/core/standable'
import {ptToPx, width2px} from '@/core/rate'
import {DisplayWindowWithStartPoint, isErrorMessage} from 'logisheets-web'
import {Resp, WorkbookClient} from './workbook'
import {Pool} from '../pool'

/**
* The `ViewManager` is responsible for efficiently and seamlessly generating `CellViewData`.
Expand All @@ -15,7 +16,11 @@ import {Resp, WorkbookClient} from './workbook'
* and the WASM module, ensuring smooth performance by avoiding redundant calculations.
*/
export class ViewManager {
constructor(private _workbook: WorkbookClient, private _sheetIdx: number) {}
constructor(
private _workbook: WorkbookClient,
private _sheetIdx: number,
private _pool: Pool
) {}

public async getViewResponseWithCell(
row: number,
Expand Down Expand Up @@ -58,7 +63,13 @@ export class ViewManager {
const windows = await Promise.all(windowsPromise)
const data = windows
.filter((w) => !isErrorMessage(w))
.map((w) => parseDisplayWindow(w as DisplayWindowWithStartPoint))
.map((w) => {
return parseDisplayWindow(
w as DisplayWindowWithStartPoint,
this._pool.getRenderCell.bind(this._pool),
this._pool.getRange.bind(this._pool)
)
})

if (type === CellViewRespType.New) {
this.dataChunks = data
Expand All @@ -73,7 +84,16 @@ export class ViewManager {
return a.fromRow < b.fromRow || a.fromCol < b.fromCol ? -1 : 1
})

return {type, data: new CellView(this.dataChunks)}
return {
type,
data: new CellView(this.dataChunks),
request: {
startX,
startY,
height,
width,
},
}
}

/**
Expand All @@ -89,26 +109,36 @@ export enum CellViewRespType {
New,
}

export interface CellViewRequest {
readonly startX: number
readonly startY: number
readonly height: number
readonly width: number
}

export interface CellViewResponse {
readonly type: CellViewRespType
readonly data: CellView
readonly request: CellViewRequest
}

export function parseDisplayWindow(
window: DisplayWindowWithStartPoint
window: DisplayWindowWithStartPoint,
getRenderCell: () => RenderCell,
getRange: () => Range
): CellViewData {
const xStart = width2px(window.startX)
const yStart = ptToPx(window.startY)

let x = xStart
const cols = window.window.cols.map((c) => {
const colInfo = StandardColInfo.from(c)
const renderCol = new RenderCell()
const renderCol = getRenderCell()
.setCoordinate(
new Range().setStartCol(colInfo.idx).setEndCol(colInfo.idx)
getRange().setStartCol(colInfo.idx).setEndCol(colInfo.idx)
)
.setPosition(
new Range()
getRange()
.setStartCol(x)
.setEndCol(x + colInfo.px)
.setStartRow(0)
Expand All @@ -121,12 +151,12 @@ export function parseDisplayWindow(
let y = yStart
const rows = window.window.rows.map((r) => {
const rowInfo = StandardRowInfo.from(r)
const renderRow = new RenderCell()
const renderRow = getRenderCell()
.setCoordinate(
new Range().setStartRow(rowInfo.idx).setEndRow(rowInfo.idx)
getRange().setStartRow(rowInfo.idx).setEndRow(rowInfo.idx)
)
.setPosition(
new Range()
getRange()
.setStartRow(y)
.setEndRow(y + rowInfo.px)
.setStartCol(0)
Expand All @@ -142,18 +172,18 @@ export function parseDisplayWindow(
for (let c = 0; c < cols.length; c += 1) {
const row = rows[r]
const col = cols[c]
const corrdinate = new Range()
const corrdinate = getRange()
.setStartRow(row.coordinate.startRow)
.setEndRow(row.coordinate.endRow)
.setStartCol(col.coordinate.startCol)
.setEndCol(col.coordinate.endCol)

const position = new Range()
const position = getRange()
.setStartRow(row.position.startRow)
.setEndRow(row.position.endRow)
.setStartCol(col.position.startCol)
.setEndCol(col.position.endCol)
const renderCell = new RenderCell()
const renderCell = getRenderCell()
.setPosition(position)
.setCoordinate(corrdinate)
.setInfo(window.window.cells[idx])
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
5 changes: 4 additions & 1 deletion src/core/ioc/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ import {
DataServiceImpl,
WorkbookClient,
IWorkbookClient,
} from '@/core/data2'
} from '@/core/data'
import {TYPES} from './types'
import {Pool} from '../pool'

export const CONTAINER = new Container()

export async function setup() {
const pool = new Pool()
CONTAINER.bind<Pool>(TYPES.Pool).toConstantValue(pool)
const workbook = new WorkbookClient()
CONTAINER.bind<IWorkbookClient>(TYPES.Workbook).toConstantValue(workbook)
return workbook.isReady().then((_) => {
Expand Down
1 change: 1 addition & 0 deletions src/core/ioc/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const TYPES = {
Data: Symbol.for('Data'),
Workbook: Symbol.for('Workbook'),
Pool: Symbol.for('Pool'),
}
Loading

0 comments on commit 797d3d4

Please sign in to comment.