removed perspective intersection observer

This commit is contained in:
Jan Prochazka 2022-07-31 15:28:04 +02:00
parent fe31cfb552
commit bf51f45934
6 changed files with 173 additions and 77 deletions

View File

@ -4,7 +4,7 @@ import { format } from 'path';
import { PerspectiveBindingGroup, PerspectiveCache } from './PerspectiveCache';
import { PerspectiveDataLoader } from './PerspectiveDataLoader';
const PERSPECTIVE_PAGE_SIZE = 100;
export const PERSPECTIVE_PAGE_SIZE = 10;
export interface PerspectiveDatabaseConfig {
conid: string;

View File

@ -76,13 +76,14 @@ export class PerspectiveDisplayRow {
rowCellSkips: boolean[] = null;
rowJoinIds: number[] = [];
incompleteRowsIndicator: string[] = null;
// incompleteRowsIndicator: string[] = null;
}
export class PerspectiveDisplay {
columns: PerspectiveDisplayColumn[] = [];
rows: PerspectiveDisplayRow[] = [];
readonly columnLevelCount: number;
loadIndicatorsCounts: { [uniqueName: string]: number } = {};
constructor(public root: PerspectiveTreeNode, rows: any[]) {
// dbg('source rows', rows);
@ -92,7 +93,7 @@ export class PerspectiveDisplay {
}
this.columnLevelCount = _max(this.columns.map(x => x.parentNodes.length)) + 1;
const collectedRows = this.collectRows(rows, root.childNodes);
// dbg('collected rows', collectedRows);
dbg('collected rows', collectedRows);
// console.log('COLLECTED', JSON.stringify(collectedRows, null, 2));
// this.mergeRows(collectedRows);
this.mergeRows(collectedRows);
@ -212,16 +213,22 @@ export class PerspectiveDisplay {
}
mergeRow(collectedRow: CollectedPerspectiveDisplayRow, rowIndex: number): number {
if (collectedRow.incompleteRowsIndicator?.length > 0) {
for (const indicator of collectedRow.incompleteRowsIndicator) {
if (!this.loadIndicatorsCounts[indicator]) {
this.loadIndicatorsCounts[indicator] = rowIndex;
}
if (rowIndex < this.loadIndicatorsCounts[indicator]) {
this.loadIndicatorsCounts[indicator] = rowIndex;
}
}
return 0;
}
const mainRow = this.getRowAt(rowIndex);
for (let i = 0; i < collectedRow.columnIndexes.length; i++) {
mainRow.rowData[collectedRow.columnIndexes[i]] = collectedRow.rowData[i];
}
if (collectedRow.incompleteRowsIndicator) {
mainRow.incompleteRowsIndicator = [
...(mainRow.incompleteRowsIndicator || []),
...collectedRow.incompleteRowsIndicator,
];
}
let rowCount = 1;
for (const subrows of collectedRow.subRowCollections) {

View File

@ -12,13 +12,17 @@ test('test flat view', () => {
const root = new PerspectiveTableNode(artistTable, chinookDbInfo, createPerspectiveConfig(), null, null, null, null);
const display = new PerspectiveDisplay(root, artistDataFlat);
console.log(display.rows);
expect(display.rows.length).toEqual(5);
// console.log(display.loadIndicatorsCounts);
// console.log(display.rows);
expect(display.rows.length).toEqual(4);
expect(display.rows[0]).toEqual(
expect.objectContaining({
rowData: ['AC/DC'],
})
);
expect(display.loadIndicatorsCounts).toEqual({
Artist: 4,
});
});
test('test one level nesting', () => {
@ -34,8 +38,9 @@ test('test one level nesting', () => {
);
const display = new PerspectiveDisplay(root, artistDataAlbum);
console.log(display.rows);
expect(display.rows.length).toEqual(7);
console.log(display.loadIndicatorsCounts);
// console.log(display.rows);
expect(display.rows.length).toEqual(6);
expect(display.rows[0]).toEqual(
expect.objectContaining({
rowData: ['AC/DC', 'For Those About To Rock We Salute You'],
@ -63,6 +68,11 @@ test('test one level nesting', () => {
rowSpans: [1, 1],
})
);
expect(display.loadIndicatorsCounts).toEqual({
Artist: 6,
'Artist.Album': 6,
});
});
test('test two level nesting', () => {
@ -79,7 +89,7 @@ test('test two level nesting', () => {
const display = new PerspectiveDisplay(root, artistDataAlbumTrack);
console.log(display.rows);
expect(display.rows.length).toEqual(9);
expect(display.rows.length).toEqual(8);
expect(display.rows[0]).toEqual(
expect.objectContaining({
rowData: ['AC/DC', 'For Those About To Rock We Salute You', 'For Those About To Rock (We Salute You)'],

View File

@ -1,55 +1,56 @@
export default [
{
"ArtistId": 1,
"Name": "AC/DC",
"Album": [
ArtistId: 1,
Name: 'AC/DC',
Album: [
{
"Title": "For Those About To Rock We Salute You",
"ArtistId": 1
Title: 'For Those About To Rock We Salute You',
ArtistId: 1,
},
{
"Title": "Let There Be Rock",
"ArtistId": 1
}
]
Title: 'Let There Be Rock',
ArtistId: 1,
},
],
},
{
"ArtistId": 2,
"Name": "Accept",
"Album": [
ArtistId: 2,
Name: 'Accept',
Album: [
{
"Title": "Balls to the Wall",
"ArtistId": 2
Title: 'Balls to the Wall',
ArtistId: 2,
},
{
"Title": "Restless and Wild",
"ArtistId": 2
}
]
Title: 'Restless and Wild',
ArtistId: 2,
},
],
},
{
"ArtistId": 3,
"Name": "Aerosmith",
"Album": [
ArtistId: 3,
Name: 'Aerosmith',
Album: [
{
"Title": "Big Ones",
"ArtistId": 3
}
]
Title: 'Big Ones',
ArtistId: 3,
},
],
},
{
"ArtistId": 4,
"Name": "Alanis Morissette",
"Album": [
ArtistId: 4,
Name: 'Alanis Morissette',
Album: [
{
"Title": "Jagged Little Pill",
"ArtistId": 4
}
]
Title: 'Jagged Little Pill',
ArtistId: 4,
},
{
"incompleteRowsIndicator": [
"Artist"
]
}
]
incompleteRowsIndicator: ['Artist.Album'],
},
],
},
{
incompleteRowsIndicator: ['Artist'],
},
];

View File

@ -3,6 +3,7 @@
export let rootNode;
export let onLoadNext;
export let incompleteRowsIndicator;
let domObserved;
@ -30,4 +31,4 @@
});
</script>
<div bind:this={domObserved}>... data to be loaded</div>
<div bind:this={domObserved} on:click={onLoadNext}>... data to be loaded {incompleteRowsIndicator.join(',')}</div>

View File

@ -12,9 +12,9 @@
</script>
<script lang="ts">
import { PerspectiveDisplay, PerspectiveTreeNode } from 'dbgate-datalib';
import { PerspectiveDisplay, PerspectiveTreeNode, PERSPECTIVE_PAGE_SIZE } from 'dbgate-datalib';
import _, { values } from 'lodash';
import { onMount } from 'svelte';
import { onMount, tick } from 'svelte';
import resizeObserver from '../utility/resizeObserver';
import PerspectiveIntersectionObserver from './PerspectiveIntersectionObserver.svelte';
import debug from 'debug';
@ -40,6 +40,7 @@
let dataRows;
let domWrapper;
let domTable;
let errorMessage;
let isLoading = false;
@ -51,7 +52,7 @@
const loadProps = node.getNodeLoadProps(parentRows);
let { rows, incomplete } = await node.dataProvider.loadData({
...loadProps,
topCount: counts[node.uniqueName] || 100,
topCount: counts[node.uniqueName] || PERSPECTIVE_PAGE_SIZE,
});
// console.log('ROWS', rows, node.isRoot);
@ -111,7 +112,7 @@
try {
await loadLevelData(node, rows, counts);
dataRows = rows;
dbg('display rows', rows);
dbg('data rows', rows);
errorMessage = null;
} catch (err) {
console.error(err);
@ -142,6 +143,11 @@
$: loadData(root, $loadedCounts);
$: display = root && dataRows ? new PerspectiveDisplay(root, dataRows) : null;
$: {
display;
checkLoadAdditionalData();
}
function buildMenu() {
return [
{
@ -152,16 +158,86 @@
},
];
}
function getLastVisibleRowIndex() {
var rows = domTable.querySelectorAll('tbody>tr');
const wrapBox = domWrapper.getBoundingClientRect();
let rowIndex = 0;
// let lastTr = null;
for (const row of rows) {
const box = row.getBoundingClientRect();
// console.log('BOX', box);
if (box.y > wrapBox.bottom) {
break;
}
// if (box.y > domWrapper.scrollTop + wrapBox.height) {
// break;
// }
// lastTr = row;
rowIndex += 1;
}
return rowIndex;
}
async function checkLoadAdditionalData() {
if (!display) return;
await tick();
if (!domTable) return;
const rowIndex = getLastVisibleRowIndex();
const growIndicators = _.keys(display.loadIndicatorsCounts).filter(
indicator => rowIndex >= display.loadIndicatorsCounts[indicator]
);
// console.log('growIndicators', growIndicators);
// console.log('display.loadIndicatorsCounts IN', display.loadIndicatorsCounts);
// console.log('rowIndex', rowIndex);
if (growIndicators.length > 0) {
dbg('load next', growIndicators);
loadedCounts.update(counts => {
const res = { ...counts };
for (const id of growIndicators) {
res[id] = (res[id] || PERSPECTIVE_PAGE_SIZE) + PERSPECTIVE_PAGE_SIZE;
}
return res;
});
}
// console.log('LAST VISIBLE ROW', rowIndex, wrapBox.height, lastTr, lastTr.getBoundingClientRect());
// var start = 0;
// var end = rows.length;
// var count = 0;
// while (start != end) {
// var mid = start + Math.floor((end - start) / 2);
// if ($(rows[mid]).offset().top < document.documentElement.scrollTop) start = mid + 1;
// else end = mid;
// }
// console.log('SCROLL', domTable.querySelector('tr:visible:last'));
}
// $: console.log('display.loadIndicatorsCounts', display?.loadIndicatorsCounts);
</script>
<div class="wrapper" bind:this={domWrapper} use:resizeObserver={true} use:contextMenu={buildMenu}>
<div
class="wrapper"
bind:this={domWrapper}
use:resizeObserver={true}
use:contextMenu={buildMenu}
on:scroll={checkLoadAdditionalData}
>
{#if display}
<table>
<table bind:this={domTable}>
<thead>
{#each _.range(display.columnLevelCount) as columnLevel}
<tr>
{#each display.columns as column}
<PerspectiveHeaderControl label={column.title} {column} {columnLevel} {setConfig} {config} />
<PerspectiveHeaderControl {column} {columnLevel} {setConfig} {config} />
{/each}
</tr>
{/each}
@ -185,12 +261,13 @@
<td colspan={display.columns.length}
><PerspectiveIntersectionObserver
rootNode={domWrapper}
incompleteRowsIndicator={row.incompleteRowsIndicator}
onLoadNext={() => {
dbg('load next', row.incompleteRowsIndicator);
loadedCounts.update(counts => {
const res = { ...counts };
for (const id of row.incompleteRowsIndicator) {
res[id] = (res[id] || 100) + 100;
res[id] = (res[id] || PERSPECTIVE_PAGE_SIZE) + PERSPECTIVE_PAGE_SIZE;
}
return res;
});