Skip to content

Commit

Permalink
Merge pull request #83 from bennyboer/feature/81-ignore-fixed-areas-w…
Browse files Browse the repository at this point in the history
…hen-rendering-scrollbars

Feature/81 ignore fixed areas when rendering scrollbars
  • Loading branch information
bennyboer authored Aug 7, 2022
2 parents e3e0703 + 9eaea6d commit 5f5510a
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 31 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "table-engine",
"version": "0.2.1",
"version": "0.2.2",
"description": "Library to visualize huge tables in web environments",
"files": [
"lib/**/*"
Expand Down
97 changes: 67 additions & 30 deletions src/renderer/canvas/canvas-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1785,6 +1785,9 @@ export class CanvasRenderer implements ITableEngineRenderer {
y: number,
start: IScrollBarDragContext
): void {
const options = this._options.renderer.canvas.scrollBar;
const drawOverFixedAreas = options.drawOverFixedAreas;

const viewportSize = this.getViewportSize();
const fixedAreaInfos = this.getFixedAreaInfos();
const scrollableViewportSize: ISize = {
Expand All @@ -1797,7 +1800,7 @@ export class CanvasRenderer implements ITableEngineRenderer {
fixedAreaInfos.top.size -
fixedAreaInfos.bottom.size,
};
const tableSize: ISize = {
const scrollableTableSize: ISize = {
width:
this._cellModel.getWidth() -
fixedAreaInfos.left.size -
Expand All @@ -1807,38 +1810,64 @@ export class CanvasRenderer implements ITableEngineRenderer {
fixedAreaInfos.top.size -
fixedAreaInfos.bottom.size,
};
const tableSize: ISize = {
width: this._cellModel.getWidth(),
height: this._cellModel.getHeight(),
};
const scrollBarTableSize: ISize = {
width: drawOverFixedAreas
? tableSize.width
: scrollableTableSize.width,
height: drawOverFixedAreas
? tableSize.height
: scrollableTableSize.height,
};
const scrollBarViewportSize: ISize = {
width: drawOverFixedAreas
? viewportSize.width
: scrollableViewportSize.width,
height: drawOverFixedAreas
? viewportSize.height
: scrollableViewportSize.height,
};

const currentScrollOffset = this._viewportScroller.getScrollOffset();
const updatedScrollOffset: IPoint = {
...currentScrollOffset,
};
if (start.scrollVertically) {
// Normalize x and y coordinates for fixed rows/columns
y -= fixedAreaInfos.top.size;
const startY = start.startY - fixedAreaInfos.top.size;
let startY = start.startY;
if (!drawOverFixedAreas) {
// Normalize x and y coordinates for fixed rows/columns
y -= fixedAreaInfos.top.size;
startY -= fixedAreaInfos.top.size;
}

const curY = startY + (y - startY) + start.offsetFromScrollBarStart;
const maxY =
scrollableViewportSize.height -
scrollBarViewportSize.height -
this._lastRenderingContext.scrollBar.vertical.length;

updatedScrollOffset.y =
(curY / maxY) *
(tableSize.height - scrollableViewportSize.height);
(scrollBarTableSize.height - scrollBarViewportSize.height);
}
if (start.scrollHorizontally) {
// Normalize x and y coordinates for fixed rows/columns
x -= fixedAreaInfos.left.size;
const startX = start.startX - fixedAreaInfos.left.size;
let startX = start.startX;
if (!drawOverFixedAreas) {
// Normalize x and y coordinates for fixed rows/columns
x -= fixedAreaInfos.left.size;
startX -= fixedAreaInfos.left.size;
}

const curX = startX + (x - startX) + start.offsetFromScrollBarStart;
const maxX =
scrollableViewportSize.width -
scrollBarViewportSize.width -
this._lastRenderingContext.scrollBar.horizontal.length;

updatedScrollOffset.x =
(curX / maxX) *
(tableSize.width - scrollableViewportSize.width);
(scrollBarTableSize.width - scrollBarViewportSize.width);
}

if (
Expand Down Expand Up @@ -3042,6 +3071,7 @@ export class CanvasRenderer implements ITableEngineRenderer {
const minScrollBarLength: number = scrollBarOptions.minLength;
const scrollBarOffset: number = scrollBarOptions.offset;
const cornerRadius: number = scrollBarOptions.cornerRadius;
const drawOverFixedAreas: boolean = scrollBarOptions.drawOverFixedAreas;

const scrollableViewportSize: ISize = {
width:
Expand All @@ -3053,7 +3083,7 @@ export class CanvasRenderer implements ITableEngineRenderer {
fixedAreaInfos.top.size -
fixedAreaInfos.bottom.size,
};
const tableSize: ISize = {
const scrollableTableSize: ISize = {
width:
this._cellModel.getWidth() -
fixedAreaInfos.left.size -
Expand All @@ -3063,20 +3093,31 @@ export class CanvasRenderer implements ITableEngineRenderer {
fixedAreaInfos.top.size -
fixedAreaInfos.bottom.size,
};
const scrollBarViewportSize: ISize = {
width: drawOverFixedAreas
? viewPort.width
: scrollableViewportSize.width,
height: drawOverFixedAreas
? viewPort.height
: scrollableViewportSize.height,
};

const maxVerticalOffset: number =
tableSize.height - scrollableViewportSize.height;
scrollableTableSize.height - scrollableViewportSize.height;
const maxHorizontalOffset: number =
tableSize.width - scrollableViewportSize.width;
scrollableTableSize.width - scrollableViewportSize.width;

const currentScrollOffset = this._viewportScroller.getScrollOffset();

const xOffset = drawOverFixedAreas ? 0 : fixedAreaInfos.left.size;
const yOffset = drawOverFixedAreas ? 0 : fixedAreaInfos.top.size;

// Calculate vertical scrollbar layout
let vertical: IScrollBarAxisRenderContext = null;
if (tableSize.height > scrollableViewportSize.height) {
if (scrollableTableSize.height > scrollableViewportSize.height) {
const length = Math.max(
(scrollableViewportSize.height / tableSize.height) *
scrollableViewportSize.height,
(scrollableViewportSize.height / scrollableTableSize.height) *
scrollBarViewportSize.height,
minScrollBarLength
);
const progress = currentScrollOffset.y / maxVerticalOffset;
Expand All @@ -3085,37 +3126,33 @@ export class CanvasRenderer implements ITableEngineRenderer {
size: scrollBarSize,
length,
x:
Math.min(scrollableViewportSize.width, tableSize.width) -
scrollBarViewportSize.width -
scrollBarSize -
scrollBarOffset +
fixedAreaInfos.left.size,
y:
(scrollableViewportSize.height - length) * progress +
fixedAreaInfos.top.size,
xOffset,
y: (scrollBarViewportSize.height - length) * progress + yOffset,
};
}

// Calculate horizontal scrollbar layout
let horizontal: IScrollBarAxisRenderContext = null;
if (tableSize.width > scrollableViewportSize.width) {
if (scrollableTableSize.width > scrollableViewportSize.width) {
const length = Math.max(
(scrollableViewportSize.width / tableSize.width) *
scrollableViewportSize.width,
(scrollableViewportSize.width / scrollableTableSize.width) *
scrollBarViewportSize.width,
minScrollBarLength
);
const progress = currentScrollOffset.x / maxHorizontalOffset;

horizontal = {
size: scrollBarSize,
length,
x:
(scrollableViewportSize.width - length) * progress +
fixedAreaInfos.left.size,
x: (scrollBarViewportSize.width - length) * progress + xOffset,
y:
Math.min(scrollableViewportSize.height, tableSize.height) -
scrollBarViewportSize.height -
scrollBarSize -
scrollBarOffset +
fixedAreaInfos.top.size,
yOffset,
};
}

Expand Down
14 changes: 14 additions & 0 deletions src/renderer/options/scrollbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ const DEFAULT_SCROLLBAR_COLOR: IColor = {
alpha: 0.6,
};

const DEFAULT_DRAW_OVER_FIXED_AREAS: boolean = true;

/**
* Options regarding the scrollbar to display.
*/
Expand Down Expand Up @@ -60,6 +62,11 @@ export interface IScrollBarOptions {
* Radius of the scrollbars rounded corners.
*/
cornerRadius?: number;

/**
* Whether to draw the scrollbars over the fixed areas of the table.
*/
drawOverFixedAreas?: boolean;
}

/**
Expand Down Expand Up @@ -91,5 +98,12 @@ export const fillOptions = (options?: IScrollBarOptions) => {
options.cornerRadius = DEFAULT_SCROLLBAR_RADIUS;
}

if (
options.drawOverFixedAreas === undefined ||
options.drawOverFixedAreas === null
) {
options.drawOverFixedAreas = DEFAULT_DRAW_OVER_FIXED_AREAS;
}

return options;
};

0 comments on commit 5f5510a

Please sign in to comment.