diff options
Diffstat (limited to 'src/client/views/nodes/DataVizBox/components/TableBox.tsx')
-rw-r--r-- | src/client/views/nodes/DataVizBox/components/TableBox.tsx | 160 |
1 files changed, 133 insertions, 27 deletions
diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx index 53d1869d9..558847a03 100644 --- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx +++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx @@ -12,6 +12,7 @@ import { ObservableReactComponent } from '../../../ObservableReactComponent'; import { DocumentView } from '../../DocumentView'; import { DataVizView } from '../DataVizBox'; import './Chart.scss'; +import { undoBatch } from '../../../../util/UndoManager'; const { DATA_VIZ_TABLE_ROW_HEIGHT } = require('../../../global/globalCssVariables.module.scss'); // prettier-ignore interface TableBoxProps { Document: Doc; @@ -37,6 +38,13 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { _inputChangedDisposer?: IReactionDisposer; _containerRef: HTMLDivElement | null = null; + @observable settingTitle: boolean = false; // true when setting a title column + @observable hasRowsToFilter: boolean = false; // true when any rows are selected + @observable filtering: boolean = false; // true when the filtering menu is open + @observable filteringColumn: any = ""; // column to filter + @observable filteringType: string = "Value"; // "Value" or "Range" + filteringVal: any[] = ["", ""]; // value or range to filter the column with + @observable _scrollTop = -1; @observable _tableHeight = 0; @observable _tableContainerHeight = 0; @@ -49,6 +57,8 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { // if the tableData changes (ie., when records are selected by the parent (input) visulization), // then we need to remove any selected rows that are no longer part of the visualized dataset. this._inputChangedDisposer = reaction(() => this._tableData.slice(), this.filterSelectedRowsDown, { fireImmediately: true }); + const selected = NumListCast(this._props.layoutDoc.dataViz_selectedRows); + if (selected.length>0) this.hasRowsToFilter = true; this.handleScroll(); } componentWillUnmount() { @@ -64,9 +74,6 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { @computed get parentViz() { return DocCast(this._props.Document.dataViz_parentViz); - // return LinkManager.Instance.getAllRelatedLinks(this._props.Document) // out of all links - // .filter(link => link.link_anchor_1 == this._props.Document.dataViz_parentViz) // get links where this chart doc is the target of the link - // .map(link => DocCast(link.link_anchor_1)); // then return the source of the link } @computed get columns() { @@ -115,6 +122,7 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { } else selected?.push(rowId); } e.stopPropagation(); + this.hasRowsToFilter = (selected.length>0)? true : false; }; columnPointerDown = (e: React.PointerEvent, col: string) => { @@ -155,8 +163,9 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { }, emptyFunction, action(e => { - if (e.shiftKey) { - if (this._props.titleCol == col) this._props.titleCol = ''; + if (e.shiftKey || this.settingTitle){ + if (this.settingTitle) this.settingTitle = false; + if (this._props.titleCol == col) this._props.titleCol = ""; else this._props.titleCol = col; this._props.selectTitleCol(this._props.titleCol); } else { @@ -170,6 +179,101 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { ); }; + /** + * These functions handle the filtering popup for when the "filter" button is pressed to select rows + */ + @undoBatch + filter = (e: any) => { + var start: any; + var end: any; + if (this.filteringType=="Range"){ + start = (this.filteringVal[0] as Number)? Number(this.filteringVal[0]): this.filteringVal[0] + end = (this.filteringVal[1] as Number)? Number(this.filteringVal[1]): this.filteringVal[0] + } + + this._tableDataIds.forEach(rowID => { + if (this.filteringType=="Value"){ + if (this._props.records[rowID][this.filteringColumn]==this.filteringVal[0]) { + if (!NumListCast(this._props.layoutDoc.dataViz_selectedRows).includes(rowID)) { + this.tableRowClick(e, rowID); + } + } + } + else { + let compare = this._props.records[rowID][this.filteringColumn] + if (compare as Number) compare = Number(compare) + if (start<=compare && compare<=end){ + if (!NumListCast(this._props.layoutDoc.dataViz_selectedRows).includes(rowID)) { + this.tableRowClick(e, rowID); + } + } + } + }) + this.filtering = false; + this.filteringColumn = ""; + this.filteringVal = ["", ""]; + } + @action + setFilterColumn = (e:any) => { + this.filteringColumn = e.currentTarget.value; + } + @action + setFilterType = (e:any) => { + this.filteringType = e.currentTarget.value; + } + changeFilterValue = action((e: React.ChangeEvent<HTMLInputElement>) => { + this.filteringVal[0] = e.target.value; + }); + changeFilterRange0 = action((e: React.ChangeEvent<HTMLInputElement>) => { + this.filteringVal[0] = e.target.value; + }); + changeFilterRange1 = action((e: React.ChangeEvent<HTMLInputElement>) => { + this.filteringVal[1] = e.target.value; + }); + @computed get renderFiltering() { + if (this.filteringColumn==="") this.filteringColumn = this.columns[0]; + return ( + <div className="tableBox-filterPopup" style={{right: this._props.width*.05}}> + <div className="tableBox-filterPopup-selectColumn"> + Column: + <select className="tableBox-filterPopup-selectColumn-each" value={this.filteringColumn!=""? this.filteringColumn : this.columns[0]} onChange={e => this.setFilterColumn(e)}> + {this.columns.map(column => ( + <option className="" key={column} value={column}> {column} </option> + ))} + </select> + </div> + <div className="tableBox-filterPopup-setValue"> + <select className="tableBox-filterPopup-setValue-each" value={this.filteringType} onChange={e => this.setFilterType(e)}> + <option className="" key={"Value"} value={"Value"}> {"Value"} </option> + <option className="" key={"Range"} value={"Range"}> {"Range"} </option> + </select> + : + {this.filteringType=="Value"? + <input className="tableBox-filterPopup-setValue-input" defaultValue="" autoComplete="off" + onChange={this.changeFilterValue} onKeyDown={e => {e.stopPropagation();}} + type="text" placeholder="" id="search-input" + /> + : + <div> + <input className="tableBox-filterPopup-setValue-input" defaultValue="" autoComplete="off" + onChange={this.changeFilterRange0} onKeyDown={e => {e.stopPropagation();}} + type="text" placeholder="" id="search-input" style={{width: this._props.width*.15}} + /> + to + <input className="tableBox-filterPopup-setValue-input" defaultValue="" autoComplete="off" + onChange={this.changeFilterRange1} onKeyDown={e => {e.stopPropagation();}} + type="text" placeholder="" id="search-input" style={{width: this._props.width*.15}} + /> + </div> + } + </div> + <div className="tableBox-filterPopup-setFilter"> + <Button onClick={action((e) => this.filter(e))} text="Set Filter" type={Type.SEC} color={'black'} /> + </div> + </div> + ) + } + render() { if (this._tableData.length > 0) { return ( @@ -183,9 +287,23 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { this._props.layoutDoc.dataViz_selectedRows = new List<number>(this._tableDataIds); } }}> - <div className="selectAll-buttons"> - <Button onClick={action(() => (this._props.layoutDoc.dataViz_selectedRows = new List<number>(this._tableDataIds)))} text="Select All" type={Type.SEC} color={'black'} /> - <Button onClick={action(() => (this._props.layoutDoc.dataViz_selectedRows = new List<number>()))} text="Deselect All" type={Type.SEC} color={'black'} /> + <div className="tableBox-selectButtons"> + <div className="tableBox-selectTitle"> + <Button onClick={action(() => (this.settingTitle = !this.settingTitle))} text="Select Title Column" type={Type.SEC} color={'black'} /> + </div> + <div className="tableBox-filtering"> + {this.filtering? this.renderFiltering : null} + <Button onClick={action(() => (this.filtering = !this.filtering))} text="Filter" type={Type.SEC} color={'black'} /> + <div className="tableBox-filterAll"> + {this.hasRowsToFilter? <Button onClick={action(() => { + this._props.layoutDoc.dataViz_selectedRows = new List<number>(); + this.hasRowsToFilter = false; })} text="Deselect All" type={Type.SEC} color={'black'} tooltip="Select rows to be displayed in any DataViz boxes dragged off of this one." /> + : <Button onClick={action(() => { + this._props.layoutDoc.dataViz_selectedRows = new List<number>(this._tableDataIds) + this.hasRowsToFilter = true; })} text="Select All" type={Type.SEC} color={'black'} tooltip="Select rows to be displayed in any DataViz boxes dragged off of this one." /> + } + </div> + </div> </div> <div className={`tableBox-container ${this.columns[0]}`} @@ -219,25 +337,13 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { <th key={this.columns.indexOf(col)} style={{ - color: - this._props.axes.slice().reverse().lastElement() === col - ? 'darkgreen' - : this._props.axes.length > 2 && this._props.axes.lastElement() === col - ? 'darkred' - : this._props.axes.lastElement() === col || (this._props.axes.length > 2 && this._props.axes[1] == col) - ? 'darkblue' - : undefined, - background: - this._props.axes.slice().reverse().lastElement() === col - ? '#E3fbdb' - : this._props.axes.length > 2 && this._props.axes.lastElement() === col - ? '#Fbdbdb' - : this._props.axes.lastElement() === col || (this._props.axes.length > 2 && this._props.axes[1] == col) - ? '#c6ebf7' - : undefined, - // blue: #ADD8E6 - // green: #E3fbdb - // red: #Fbdbdb + color: this._props.axes.slice().reverse().lastElement() === col ? 'darkgreen' + : (this._props.axes.length>2 && this._props.axes.lastElement() === col) ? 'darkred' + : (this._props.axes.lastElement()===col || (this._props.axes.length>2 && this._props.axes[1]==col))? 'darkblue' : undefined, + background: this.settingTitle? 'lightgrey' + : this._props.axes.slice().reverse().lastElement() === col ? '#E3fbdb' + : (this._props.axes.length>2 && this._props.axes.lastElement() === col) ? '#Fbdbdb' + : (this._props.axes.lastElement()===col || (this._props.axes.length>2 && this._props.axes[1]==col))? '#c6ebf7' : undefined, fontWeight: 'bolder', border: '3px solid black', }} |