aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsrichman333 <sarah_n_richman@brown.edu>2023-09-28 03:09:23 -0400
committersrichman333 <sarah_n_richman@brown.edu>2023-09-28 03:09:23 -0400
commitd334eb163e0e960c9d662eb696fcf98aa02fdadf (patch)
tree7f97a79b142fec226fceb640bd2d289dc5a74f09 /src
parent49ff44c885e6a823f9579c1c3248feff44af015a (diff)
doesn't lag / glitch system but scrolling can be kinda funky
Diffstat (limited to 'src')
-rw-r--r--src/client/views/nodes/DataVizBox/components/TableBox.tsx139
1 files changed, 100 insertions, 39 deletions
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>