From d334eb163e0e960c9d662eb696fcf98aa02fdadf Mon Sep 17 00:00:00 2001
From: srichman333 <sarah_n_richman@brown.edu>
Date: Thu, 28 Sep 2023 03:09:23 -0400
Subject: doesn't lag / glitch system but scrolling can be kinda funky

---
 .../views/nodes/DataVizBox/components/TableBox.tsx | 139 +++++++++++++++------
 1 file changed, 100 insertions(+), 39 deletions(-)

(limited to 'src/client/views/nodes/DataVizBox/components/TableBox.tsx')

diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
index 5045fde3a..243c1a0c7 100644
--- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx
+++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
@@ -1,5 +1,5 @@
 import { Button, Type } from 'browndash-components';
-import { action, computed, IReactionDisposer, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { Doc, Field, NumListCast } from '../../../../../fields/Doc';
@@ -31,6 +31,9 @@ interface TableBoxProps {
 
 @observer
 export class TableBox extends React.Component<TableBoxProps> {
+    @observable startID: number = 0;
+    @observable endID: number = 20;
+
     _inputChangedDisposer?: IReactionDisposer;
     componentDidMount() {
         // if the tableData changes (ie., when records are selected by the parent (input) visulization),
@@ -67,8 +70,61 @@ export class TableBox extends React.Component<TableBoxProps> {
         this.props.layoutDoc.dataViz_highlitedRows = new List<number>(highlighted.filter(rowId => this._tableDataIds.includes(rowId))); // filters through highlighted to remove guids that were removed in the incoming data
     };
 
+    @action handleScroll = () => {
+        console.log("scroll")
+        // console.log("before", this.startID, this.endID)
+        var container = document.getElementsByClassName("table-container"); 
+        var eachCell = document.getElementsByClassName("table-row");
+        if (eachCell.length==0 || container.length==0) return;
+
+        var useContainer;
+        if (container.length==1) useContainer = container[0];
+        else {
+            for (var i=0; i<container.length; i++){
+                if (container[i].classList.contains(this.columns[0])) useContainer = container[i];
+            }
+        }
+        var useCell;
+        if (eachCell.length==1) useCell = eachCell[0];
+        else {
+            for (var i=0; i<eachCell.length; i++){
+                if (eachCell[i].classList.contains(this.columns[0])) useCell = eachCell[i];
+            }
+        }
+        if (useCell && useContainer){
+            // top
+            if (useContainer.scrollTop <= 10 && this.startID >= -1){
+                this.startID -= 1;
+                this.endID -= 1;
+            }
+            
+            // bottom
+            else if (useContainer.scrollHeight - 50  <= useContainer.scrollTop + useContainer.getBoundingClientRect().height && this.endID<=this._tableDataIds.length){
+                this.startID += 1;
+                this.endID += 1;
+            }
+
+            // regular scroll
+            else {
+            let newStart = (useContainer.scrollTop / useCell.getBoundingClientRect().height ) - 1;
+            newStart = Math.floor(Number(newStart))
+            if (newStart<this.startID && this.startID>=-1){ this.startID -= 1; }
+            if (newStart>this.startID) { this.startID += 1; }
+            
+            let newEnd = this.startID + useContainer.getBoundingClientRect().height / useCell.getBoundingClientRect().height + 1;
+            newEnd = Math.floor(Number(newEnd))
+            if (newEnd<this.endID){ this.endID -= 1; }
+            if (newEnd>this.endID && this.endID<=this._tableDataIds.length) { this.endID += 1; }
+            }
+        }
+        else {
+            this.endID = this._tableDataIds.length - 1;
+        }
+    }
+
     render() {
         if (this._tableData.length > 0) {
+
             return (
                 <div
                     className="tableBox"
@@ -84,13 +140,14 @@ export class TableBox extends React.Component<TableBoxProps> {
                         <Button onClick={action(() => (this.props.layoutDoc.dataViz_selectedRows = new List<number>()))} text="Deselect All" type={Type.SEC} color={'black'} />
                     </div>
                     <div
-                        className="table-container"
+                        className={`table-container ${this.columns[0]}`}
                         style={{ height: this.props.height }}
                         ref={r =>
                             r?.addEventListener(
                                 'wheel', // if scrollTop is 0, then don't let wheel trigger scroll on any container (which it would since onScroll won't be triggered on this)
                                 (e: WheelEvent) => {
                                     if (!r.scrollTop && e.deltaY <= 0) e.preventDefault();
+                                    this.handleScroll();
                                     e.stopPropagation();
                                 },
                                 { passive: false }
@@ -98,7 +155,7 @@ export class TableBox extends React.Component<TableBoxProps> {
                         }>
                         <table className="table">
                             <thead>
-                                <tr className="table-row">
+                                <tr >
                                     {this.columns.map(col => (
                                         <th
                                             key={this.columns.indexOf(col)}
@@ -167,42 +224,46 @@ export class TableBox extends React.Component<TableBoxProps> {
                             <tbody>
                                 {this._tableDataIds
                                     ?.map(rowId => ({ record: this.props.records[rowId], rowId }))
-                                    .map(({ record, rowId }) => (
-                                        <tr
-                                            key={rowId}
-                                            className="table-row"
-                                            onClick={action(e => {
-                                                const highlited = Cast(this.props.layoutDoc.dataViz_highlitedRows, listSpec('number'), null);
-                                                const selected = Cast(this.props.layoutDoc.dataViz_selectedRows, listSpec('number'), null);
-                                                if (e.metaKey) {
-                                                    // highlighting a row
-                                                    if (highlited?.includes(rowId)) highlited.splice(highlited.indexOf(rowId), 1);
-                                                    else highlited?.push(rowId);
-                                                    if (!selected?.includes(rowId)) selected?.push(rowId);
-                                                } else {
-                                                    // selecting a row
-                                                    if (selected?.includes(rowId)) {
-                                                        if (highlited?.includes(rowId)) highlited.splice(highlited.indexOf(rowId), 1);
-                                                        selected.splice(selected.indexOf(rowId), 1);
-                                                    } else selected?.push(rowId);
-                                                }
-                                                e.stopPropagation();
-                                            })}
-                                            style={{
-                                                background: NumListCast(this.props.layoutDoc.dataViz_highlitedRows).includes(rowId) ? 'lightYellow' : NumListCast(this.props.layoutDoc.dataViz_selectedRows).includes(rowId) ? 'lightgrey' : '',
-                                                width: '110%',
-                                            }}>
-                                            {this.columns.map(col => {
-                                                // each cell
-                                                const colSelected = this.props.axes.length > 1 ? this.props.axes[0] == col || this.props.axes[1] == col : this.props.axes.length > 0 ? this.props.axes[0] == col : false;
-                                                return (
-                                                    <td key={this.columns.indexOf(col)} style={{ border: colSelected ? '3px solid black' : '1px solid black', fontWeight: colSelected ? 'bolder' : 'normal' }}>
-                                                        {record[col]}
-                                                    </td>
-                                                );
-                                            })}
-                                        </tr>
-                                    ))}
+                                    .map(({ record, rowId }) => {
+                                        if (this.startID<=rowId && rowId<=this.endID){
+                                            return (
+                                                <tr
+                                                    key={rowId}
+                                                    className={`table-row ${this.columns[0]}`}
+                                                    onClick={action(e => {
+                                                        const highlited = Cast(this.props.layoutDoc.dataViz_highlitedRows, listSpec('number'), null);
+                                                        const selected = Cast(this.props.layoutDoc.dataViz_selectedRows, listSpec('number'), null);
+                                                        if (e.metaKey) {
+                                                            // highlighting a row
+                                                            if (highlited?.includes(rowId)) highlited.splice(highlited.indexOf(rowId), 1);
+                                                            else highlited?.push(rowId);
+                                                            if (!selected?.includes(rowId)) selected?.push(rowId);
+                                                        } else {
+                                                            // selecting a row
+                                                            if (selected?.includes(rowId)) {
+                                                                if (highlited?.includes(rowId)) highlited.splice(highlited.indexOf(rowId), 1);
+                                                                selected.splice(selected.indexOf(rowId), 1);
+                                                            } else selected?.push(rowId);
+                                                        }
+                                                        e.stopPropagation();
+                                                    })}
+                                                    style={{
+                                                        background: NumListCast(this.props.layoutDoc.dataViz_highlitedRows).includes(rowId) ? 'lightYellow' : NumListCast(this.props.layoutDoc.dataViz_selectedRows).includes(rowId) ? 'lightgrey' : '',
+                                                        width: '110%',
+                                                    }}>
+                                                    {this.columns.map(col => {
+                                                        // each cell
+                                                        const colSelected = this.props.axes.length > 1 ? this.props.axes[0] == col || this.props.axes[1] == col : this.props.axes.length > 0 ? this.props.axes[0] == col : false;
+                                                        return (
+                                                            <td key={this.columns.indexOf(col)} style={{ border: colSelected ? '3px solid black' : '1px solid black', fontWeight: colSelected ? 'bolder' : 'normal' }}>
+                                                                {record[col]}
+                                                            </td>
+                                                        );
+                                                    })}
+                                                </tr>
+                                            )
+                                        }
+                                    })}
                             </tbody>
                         </table>
                     </div>
-- 
cgit v1.2.3-70-g09d2

