From 9200e09939ba3d23bcf79efda008a7a990d29b95 Mon Sep 17 00:00:00 2001
From: srichman333 <sarah_n_richman@brown.edu>
Date: Thu, 11 Jan 2024 02:37:07 -0500
Subject: toggle scheme dataviz box as live

---
 src/client/views/nodes/DataVizBox/DataVizBox.tsx | 61 +++++++++++++++++-------
 1 file changed, 45 insertions(+), 16 deletions(-)

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

diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index 5a55ca764..1aef98131 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -28,6 +28,7 @@ import { Histogram } from './components/Histogram';
 import { LineChart } from './components/LineChart';
 import { PieChart } from './components/PieChart';
 import { TableBox } from './components/TableBox';
+import { Checkbox } from '@mui/material';
 
 export enum DataVizView {
     TABLE = 'table',
@@ -44,9 +45,9 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
     anchorMenuClick?: () => undefined | ((anchor: Doc) => void);
     crop: ((region: Doc | undefined, addCrop?: boolean) => Doc | undefined) | undefined;
-    @observable schemaDataVizChildren: any = undefined;
     @observable _marqueeing: number[] | undefined = undefined;
     @observable _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
+
     @computed get annotationLayer() {
         TraceMobx();
         return <div className="dataVizBox-annotationLayer" style={{ height: this._props.PanelHeight(), width: this._props.PanelWidth() }} ref={this._annotationLayer} />;
@@ -80,6 +81,11 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
 
     // all datasets that have been retrieved from the server stored as a map from the dataset url to an array of records
     static dataset = new ObservableMap<string, { [key: string]: string }[]>();
+ 
+    // when a dataset comes from schema view, this stores the original dataset to refer back to
+    // href : dataset
+    static datasetSchemaOG = new Map();
+
     private _vizRenderer: LineChart | Histogram | PieChart | undefined;
     private _sidebarRef = React.createRef<SidebarAnnos>();
 
@@ -322,30 +328,46 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         GPTPopup.Instance.addDoc = this.sidebarAddDocument;
     };
 
+    @action
+    changeLiveSchemaCheckbox = () => {
+        this.layoutDoc.dataViz_schemaLive = !this.layoutDoc.dataViz_schemaLive
+        console.log(this.layoutDoc.dataViz_schemaLive)
+        this.updateSchemaViz();
+    }
+
     @action
     updateSchemaViz = () => {
-        const getFrom = DocCast(this.layoutDoc.dataViz_asSchema);
-        const keys = Cast(getFrom.schema_columnKeys, listSpec('string'))?.filter(key => key != 'text');
-        if (!keys) return;
-        const children = DocListCast(getFrom[Doc.LayoutFieldKey(getFrom)]);
-        var current: { [key: string]: string }[] = [];
-        for (let i = 0; i < children.length; i++) {
-            var row: { [key: string]: string } = {};
-            if (children[i]) {
-                for (let j = 0; j < keys.length; j++) {
-                    var cell = children[i][keys[j]];
-                    if (cell && (cell as string)) cell = cell.toString().replace(/\,/g, '');
-                    row[keys[j]] = StrCast(cell);
+        const href = CsvCast(this.Document[this.fieldKey]).url.href;
+        if (this.layoutDoc.dataViz_schemaLive || !DataVizBox.datasetSchemaOG.has(href)){
+            const getFrom = DocCast(this.layoutDoc.dataViz_asSchema);
+            const keys = Cast(getFrom.schema_columnKeys, listSpec('string'))?.filter(key => key != 'text');
+            if (!keys) return;
+            const children = DocListCast(getFrom[Doc.LayoutFieldKey(getFrom)]);
+
+            var current: { [key: string]: string }[] = [];
+            for (let i = 0; i < children.length; i++) {
+                var row: { [key: string]: string } = {};
+                if (children[i]) {
+                    for (let j = 0; j < keys.length; j++) {
+                        var cell = children[i][keys[j]];
+                        if (cell && (cell as string)) cell = cell.toString().replace(/\,/g, '');
+                        row[keys[j]] = StrCast(cell);
+                    }
                 }
+                current.push(row);
+            }
+
+            if (!DataVizBox.datasetSchemaOG.has(href)){
+                DataVizBox.datasetSchemaOG.set(href, current);
             }
-            current.push(row);
+            DataVizBox.dataset.set(href, current);
         }
-        DataVizBox.dataset.set(CsvCast(this.Document[this.fieldKey]).url.href, current);
+        else DataVizBox.dataset.set(href, DataVizBox.datasetSchemaOG.get(href));
     };
 
     render() {
+        if (this.layoutDoc.dataViz_schemaLive == undefined) this.layoutDoc.dataViz_schemaLive = true;
         if (this.layoutDoc && this.layoutDoc.dataViz_asSchema) {
-            this.schemaDataVizChildren = DocListCast(DocCast(this.layoutDoc.dataViz_asSchema)[Doc.LayoutFieldKey(DocCast(this.layoutDoc.dataViz_asSchema))]).length;
             this.updateSchemaViz();
         }
 
@@ -393,6 +415,13 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                     {this.renderVizView}
                 </CollectionFreeFormView> */}
 
+                {(this.layoutDoc && this.layoutDoc.dataViz_asSchema)?(
+                    <div className={'liveSchema-checkBox'} style={{ width: this._props.width }}>
+                    <Checkbox color="primary" onChange={this.changeLiveSchemaCheckbox} checked={this.layoutDoc.dataViz_schemaLive as boolean} />
+                    Display Live Updates to Canvas
+                </div>
+                ) : null}
+
                 {this.renderVizView}
                 <div className="dataviz-sidebar" style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }} onPointerDown={this.onPointerDown}>
                     <SidebarAnnos
-- 
cgit v1.2.3-70-g09d2


From 923b0d20cd95311122ec5886698b3fb2dfadb882 Mon Sep 17 00:00:00 2001
From: srichman333 <sarah_n_richman@brown.edu>
Date: Fri, 12 Jan 2024 12:56:09 -0500
Subject: live schema toggle works on refresh

---
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  5 +-
 .../collectionSchema/CollectionSchemaView.scss     |  6 ++-
 src/client/views/nodes/DataVizBox/DataVizBox.tsx   | 58 ++++++++++++++++------
 3 files changed, 51 insertions(+), 18 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 8268a47d8..de4f01014 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -2005,15 +2005,14 @@ ScriptingGlobals.add(function datavizFromSchema(doc: Doc) {
             csvRows.push(eachRow);
         }
         const blob = new Blob([csvRows.join('\n')], { type: 'text/csv' });
-        const options = { x: 0, y: -300, title: 'schemaTable', _width: 300, _height: 100, type: 'text/csv' };
+        const options = { x: 0, y: 0, title: 'schemaTable', _width: 300, _height: 100, type: 'text/csv' };
         const file = new File([blob], 'schemaTable', options);
         const loading = Docs.Create.LoadingDocument(file, options);
         loading.presentation_openInLightbox = true;
         DocUtils.uploadFileToDoc(file, {}, loading);
 
         if (view.ComponentView?.addDocument) {
-            //  loading.dataViz_fromSchema = true;
-            loading.dataViz_asSchema = view.layoutDoc;
+            loading._dataViz_asSchema = view.layoutDoc;
             SchemaCSVPopUp.Instance.setView(view);
             SchemaCSVPopUp.Instance.setTarget(view.layoutDoc);
             SchemaCSVPopUp.Instance.setDataVizDoc(loading);
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
index 02131ae22..da9da8fbe 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
@@ -18,17 +18,21 @@
 
         .schema-add {
             position: relative;
-            height: 30;
+            height: 35;
             display: flex;
             align-items: center;
+            top: -10px;
             width: 100%;
             text-align: right;
             background: lightgray;
             .editableView-container-editing {
                 width: 100%;
+                height: 35px;
+                margin: 20px;
             }
             .editableView-input {
                 width: 100%;
+                margin: 20px;
                 float: right;
                 text-align: right;
                 background: yellow;
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index 1aef98131..6d060f535 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -1,6 +1,6 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Colors, Toggle, ToggleType, Type } from 'browndash-components';
-import { ObservableMap, action, computed, observable, runInAction } from 'mobx';
+import { ObservableMap, action, computed, makeObservable, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { emptyFunction, returnEmptyString, returnFalse, returnOne, setupMoveUpEvents } from '../../../../Utils';
@@ -11,7 +11,7 @@ import { listSpec } from '../../../../fields/Schema';
 import { Cast, CsvCast, DocCast, NumCast, StrCast } from '../../../../fields/Types';
 import { CsvField } from '../../../../fields/URLField';
 import { TraceMobx } from '../../../../fields/util';
-import { Docs } from '../../../documents/Documents';
+import { DocUtils, Docs } from '../../../documents/Documents';
 import { DocumentManager } from '../../../util/DocumentManager';
 import { UndoManager, undoable } from '../../../util/UndoManager';
 import { ViewBoxAnnotatableComponent } from '../../DocComponent';
@@ -40,13 +40,13 @@ export enum DataVizView {
 @observer
 export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
-    private _ffref = React.createRef<CollectionFreeFormView>();
     private _marqueeref = React.createRef<MarqueeAnnotator>();
     private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
     anchorMenuClick?: () => undefined | ((anchor: Doc) => void);
     crop: ((region: Doc | undefined, addCrop?: boolean) => Doc | undefined) | undefined;
     @observable _marqueeing: number[] | undefined = undefined;
     @observable _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
+    @observable schemaBoxLength: any = 0;
 
     @computed get annotationLayer() {
         TraceMobx();
@@ -81,10 +81,9 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
 
     // all datasets that have been retrieved from the server stored as a map from the dataset url to an array of records
     static dataset = new ObservableMap<string, { [key: string]: string }[]>();
- 
     // when a dataset comes from schema view, this stores the original dataset to refer back to
     // href : dataset
-    static datasetSchemaOG = new Map();
+    static datasetSchemaOG = new ObservableMap<string, { [key: string]: string }[]>();
 
     private _vizRenderer: LineChart | Histogram | PieChart | undefined;
     private _sidebarRef = React.createRef<SidebarAnnos>();
@@ -104,10 +103,10 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         return Cast(this.dataDoc[this.fieldKey], CsvField);
     }
     @computed.struct get axes() {
-        return StrListCast(this.layoutDoc.dataViz_axes);
+        return StrListCast(this.layoutDoc._dataViz_axes);
     }
 
-    selectAxes = (axes: string[]) => (this.layoutDoc.dataViz_axes = new List<string>(axes));
+    selectAxes = (axes: string[]) => (this.layoutDoc._dataViz_axes = new List<string>(axes));
 
     @action // pinned / linked anchor doc includes selected rows, graph titles, and graph colors
     restoreView = (data: Doc) => {
@@ -331,19 +330,52 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     @action
     changeLiveSchemaCheckbox = () => {
         this.layoutDoc.dataViz_schemaLive = !this.layoutDoc.dataViz_schemaLive
-        console.log(this.layoutDoc.dataViz_schemaLive)
         this.updateSchemaViz();
     }
 
+    @action
+    setDataset(href: any, data: any) {
+        DataVizBox.dataset.set(href, data);
+    }
+
     @action
     updateSchemaViz = () => {
         const href = CsvCast(this.Document[this.fieldKey]).url.href;
+
         if (this.layoutDoc.dataViz_schemaLive || !DataVizBox.datasetSchemaOG.has(href)){
             const getFrom = DocCast(this.layoutDoc.dataViz_asSchema);
             const keys = Cast(getFrom.schema_columnKeys, listSpec('string'))?.filter(key => key != 'text');
             if (!keys) return;
             const children = DocListCast(getFrom[Doc.LayoutFieldKey(getFrom)]);
 
+            if (!this.layoutDoc._dataViz_schemaOG){
+                let csvRows = [];
+                csvRows.push(keys.join(','));
+                for (let i = 0; i < children.length; i++) {
+                    let eachRow = [];
+                    for (let j = 0; j < keys.length; j++) {
+                        var cell = children[i][keys[j]];
+                        if (cell && (cell as string)) cell = cell.toString().replace(/\,/g, '');
+                        eachRow.push(cell);
+                    }
+                    csvRows.push(eachRow);
+                }
+                const blob = new Blob([csvRows.join('\n')], { type: 'text/csv' });
+                const options = { x: 0, y: 0, title: 'schemaTable for static dataviz', _width: 300, _height: 100, type: 'text/csv' };
+                const file = new File([blob], 'schemaTable for static dataviz', options);
+                const loading = Docs.Create.LoadingDocument(file, options);
+                DocUtils.uploadFileToDoc(file, {}, loading);
+                this.layoutDoc._dataViz_schemaOG = loading;
+            }
+
+            const ogDoc = this.layoutDoc._dataViz_schemaOG as Doc
+            const ogHref = CsvCast(ogDoc[this.fieldKey])? CsvCast(ogDoc[this.fieldKey]).url.href : undefined;
+            if (ogHref && !DataVizBox.datasetSchemaOG.has(href)){
+                DataVizBox.datasetSchemaOG.set(href, []);
+                fetch('/csvData?uri=' + ogHref)
+                    .then(res => res.json().then(action(res => !res.errno && DataVizBox.datasetSchemaOG.set(href, res))));
+            }
+
             var current: { [key: string]: string }[] = [];
             for (let i = 0; i < children.length; i++) {
                 var row: { [key: string]: string } = {};
@@ -356,13 +388,11 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                 }
                 current.push(row);
             }
-
-            if (!DataVizBox.datasetSchemaOG.has(href)){
-                DataVizBox.datasetSchemaOG.set(href, current);
-            }
-            DataVizBox.dataset.set(href, current);
+            this.setDataset(href, current);
+        }
+        else {
+            this.setDataset(href, DataVizBox.datasetSchemaOG.get(href));
         }
-        else DataVizBox.dataset.set(href, DataVizBox.datasetSchemaOG.get(href));
     };
 
     render() {
-- 
cgit v1.2.3-70-g09d2


From db51496360e8eac55b5e83283370c4aeec7a11d8 Mon Sep 17 00:00:00 2001
From: srichman333 <sarah_n_richman@brown.edu>
Date: Wed, 17 Jan 2024 15:01:30 -0500
Subject: cleaner

---
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   2 +
 src/client/views/nodes/DataVizBox/DataVizBox.tsx   | 116 +++++++++------------
 .../views/nodes/DataVizBox/components/TableBox.tsx |   2 -
 3 files changed, 52 insertions(+), 68 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index de4f01014..881c80a1a 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1985,6 +1985,7 @@ ScriptingGlobals.add(function sendToBack(doc: Doc) {
     SelectionManager.Views.forEach(view => view.CollectionFreeFormView?.bringToFront(view.Document, true));
 });
 ScriptingGlobals.add(function datavizFromSchema(doc: Doc) {
+    // creating a dataviz doc to represent the schema table
     SelectionManager.Views.forEach(view => {
         if (!view.layoutDoc.schema_columnKeys) {
             view.layoutDoc.schema_columnKeys = new List<string>(['title', 'type', 'author', 'author_date']);
@@ -2011,6 +2012,7 @@ ScriptingGlobals.add(function datavizFromSchema(doc: Doc) {
         loading.presentation_openInLightbox = true;
         DocUtils.uploadFileToDoc(file, {}, loading);
 
+        // holds the doc in a popup until it is dragged onto a canvas
         if (view.ComponentView?.addDocument) {
             loading._dataViz_asSchema = view.layoutDoc;
             SchemaCSVPopUp.Instance.setView(view);
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index 6d060f535..981ec0aa1 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -1,6 +1,6 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Colors, Toggle, ToggleType, Type } from 'browndash-components';
-import { ObservableMap, action, computed, makeObservable, observable, runInAction } from 'mobx';
+import { ObservableMap, action, computed, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { emptyFunction, returnEmptyString, returnFalse, returnOne, setupMoveUpEvents } from '../../../../Utils';
@@ -17,7 +17,6 @@ import { UndoManager, undoable } from '../../../util/UndoManager';
 import { ViewBoxAnnotatableComponent } from '../../DocComponent';
 import { MarqueeAnnotator } from '../../MarqueeAnnotator';
 import { SidebarAnnos } from '../../SidebarAnnos';
-import { CollectionFreeFormView } from '../../collections/collectionFreeForm';
 import { AnchorMenu } from '../../pdf/AnchorMenu';
 import { GPTPopup } from '../../pdf/GPTPopup/GPTPopup';
 import { DocFocusOptions, DocumentView } from '../DocumentView';
@@ -339,59 +338,63 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     }
 
     @action
+    // handles when the dataviz doc was made by copying a schema table
     updateSchemaViz = () => {
         const href = CsvCast(this.Document[this.fieldKey]).url.href;
-
-        if (this.layoutDoc.dataViz_schemaLive || !DataVizBox.datasetSchemaOG.has(href)){
-            const getFrom = DocCast(this.layoutDoc.dataViz_asSchema);
-            const keys = Cast(getFrom.schema_columnKeys, listSpec('string'))?.filter(key => key != 'text');
-            if (!keys) return;
-            const children = DocListCast(getFrom[Doc.LayoutFieldKey(getFrom)]);
-
-            if (!this.layoutDoc._dataViz_schemaOG){
-                let csvRows = [];
-                csvRows.push(keys.join(','));
-                for (let i = 0; i < children.length; i++) {
-                    let eachRow = [];
-                    for (let j = 0; j < keys.length; j++) {
-                        var cell = children[i][keys[j]];
-                        if (cell && (cell as string)) cell = cell.toString().replace(/\,/g, '');
-                        eachRow.push(cell);
+        const getFromDoc = DocCast(this.layoutDoc.dataViz_asSchema);
+        const children = DocListCast(getFromDoc[Doc.LayoutFieldKey(getFromDoc)]);
+
+        if (children.length != this.schemaBoxLength) {
+            if (this.layoutDoc.dataViz_schemaLive || !DataVizBox.datasetSchemaOG.has(href)){
+                const keys = Cast(getFromDoc.schema_columnKeys, listSpec('string'))?.filter(key => key != 'text');
+                if (!keys) return;
+
+                if (!this.layoutDoc._dataViz_schemaOG){
+                    // makes a copy of the original table for the "live" toggle
+                    let csvRows = [];
+                    csvRows.push(keys.join(','));
+                    for (let i = 0; i < children.length; i++) {
+                        let eachRow = [];
+                        for (let j = 0; j < keys.length; j++) {
+                            var cell = children[i][keys[j]];
+                            if (cell && (cell as string)) cell = cell.toString().replace(/\,/g, '');
+                            eachRow.push(cell);
+                        }
+                        csvRows.push(eachRow);
                     }
-                    csvRows.push(eachRow);
+                    const blob = new Blob([csvRows.join('\n')], { type: 'text/csv' });
+                    const options = { x: 0, y: 0, title: 'schemaTable for static dataviz', _width: 300, _height: 100, type: 'text/csv' };
+                    const file = new File([blob], 'schemaTable for static dataviz', options);
+                    const loading = Docs.Create.LoadingDocument(file, options);
+                    DocUtils.uploadFileToDoc(file, {}, loading);
+                    this.layoutDoc._dataViz_schemaOG = loading;
                 }
-                const blob = new Blob([csvRows.join('\n')], { type: 'text/csv' });
-                const options = { x: 0, y: 0, title: 'schemaTable for static dataviz', _width: 300, _height: 100, type: 'text/csv' };
-                const file = new File([blob], 'schemaTable for static dataviz', options);
-                const loading = Docs.Create.LoadingDocument(file, options);
-                DocUtils.uploadFileToDoc(file, {}, loading);
-                this.layoutDoc._dataViz_schemaOG = loading;
-            }
 
-            const ogDoc = this.layoutDoc._dataViz_schemaOG as Doc
-            const ogHref = CsvCast(ogDoc[this.fieldKey])? CsvCast(ogDoc[this.fieldKey]).url.href : undefined;
-            if (ogHref && !DataVizBox.datasetSchemaOG.has(href)){
-                DataVizBox.datasetSchemaOG.set(href, []);
-                fetch('/csvData?uri=' + ogHref)
-                    .then(res => res.json().then(action(res => !res.errno && DataVizBox.datasetSchemaOG.set(href, res))));
-            }
+                const ogDoc = this.layoutDoc._dataViz_schemaOG as Doc
+                const ogHref = CsvCast(ogDoc[this.fieldKey])? CsvCast(ogDoc[this.fieldKey]).url.href : undefined;
+                if (ogHref && !DataVizBox.datasetSchemaOG.has(href)){
+                    DataVizBox.datasetSchemaOG.set(href, []);
+                    fetch('/csvData?uri=' + ogHref)
+                        .then(res => res.json().then(action(res => !res.errno && DataVizBox.datasetSchemaOG.set(href, res))));
+                }
 
-            var current: { [key: string]: string }[] = [];
-            for (let i = 0; i < children.length; i++) {
-                var row: { [key: string]: string } = {};
-                if (children[i]) {
-                    for (let j = 0; j < keys.length; j++) {
-                        var cell = children[i][keys[j]];
-                        if (cell && (cell as string)) cell = cell.toString().replace(/\,/g, '');
-                        row[keys[j]] = StrCast(cell);
+                var current: { [key: string]: string }[] = [];
+                for (let i = 0; i < children.length; i++) {
+                    var row: { [key: string]: string } = {};
+                    if (children[i]) {
+                        for (let j = 0; j < keys.length; j++) {
+                            var cell = children[i][keys[j]];
+                            if (cell && (cell as string)) cell = cell.toString().replace(/\,/g, '');
+                            row[keys[j]] = StrCast(cell);
+                        }
                     }
+                    current.push(row);
                 }
-                current.push(row);
+                this.setDataset(href, current);
+            }
+            else {
+                this.setDataset(href, DataVizBox.datasetSchemaOG.get(href));
             }
-            this.setDataset(href, current);
-        }
-        else {
-            this.setDataset(href, DataVizBox.datasetSchemaOG.get(href));
         }
     };
 
@@ -425,26 +428,6 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                     <Toggle text={'PIE CHART'} toggleType={ToggleType.BUTTON} type={Type.SEC} color={'black'} onClick={e => (this.layoutDoc._dataViz = DataVizView.PIECHART)} toggleStatus={this.layoutDoc._dataViz == -DataVizView.PIECHART} />
                 </div>
 
-                {/* <CollectionFreeFormView
-                    ref={this._ffref}
-                    {...this._props}
-                    setContentView={emptyFunction}
-                    renderDepth={this._props.renderDepth - 1}
-                    fieldKey={this.annotationKey}
-                    styleProvider={this._props.styleProvider}
-                    isAnnotationOverlay={true}
-                    annotationLayerHostsContent={false}
-                    PanelWidth={this._props.PanelWidth}
-                    PanelHeight={this._props.PanelHeight}
-                    select={emptyFunction}
-                    isAnyChildContentActive={returnFalse}
-                    whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
-                    removeDocument={this.removeDocument}
-                    moveDocument={this.moveDocument}
-                    addDocument={this.addDocument}>
-                    {this.renderVizView}
-                </CollectionFreeFormView> */}
-
                 {(this.layoutDoc && this.layoutDoc.dataViz_asSchema)?(
                     <div className={'liveSchema-checkBox'} style={{ width: this._props.width }}>
                     <Checkbox color="primary" onChange={this.changeLiveSchemaCheckbox} checked={this.layoutDoc.dataViz_schemaLive as boolean} />
@@ -453,6 +436,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                 ) : null}
 
                 {this.renderVizView}
+
                 <div className="dataviz-sidebar" style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }} onPointerDown={this.onPointerDown}>
                     <SidebarAnnos
                         ref={this._sidebarRef}
diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
index ed44d9269..c5fda18ae 100644
--- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx
+++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
@@ -83,14 +83,12 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
         return this._props.docView?.()?.screenToViewTransform().Scale || 1;
     }
     @computed get rowHeight() {
-        console.log('scale = ' + this.viewScale + '  table = ' + this._tableHeight + ' ids = ' + this._tableDataIds.length);
         return (this.viewScale * this._tableHeight) / this._tableDataIds.length;
     }
     @computed get startID() {
         return this.rowHeight ? Math.max(Math.floor(this._scrollTop / this.rowHeight) - 1, 0) : 0;
     }
     @computed get endID() {
-        console.log('start = ' + this.startID + '  container = ' + this._tableContainerHeight + ' scale = ' + this.viewScale + ' row = ' + this.rowHeight);
         return Math.ceil(this.startID + (this._tableContainerHeight * this.viewScale) / (this.rowHeight || 1));
     }
     @action handleScroll = () => {
-- 
cgit v1.2.3-70-g09d2


From aa3c70399ac2b6a337a9c85fb30f57f82ee44063 Mon Sep 17 00:00:00 2001
From: srichman333 <sarah_n_richman@brown.edu>
Date: Tue, 23 Jan 2024 13:22:13 -0500
Subject: data has a title column

---
 src/client/views/nodes/DataVizBox/DataVizBox.tsx   |  8 ++++++--
 .../nodes/DataVizBox/components/Histogram.tsx      |  1 +
 .../nodes/DataVizBox/components/LineChart.tsx      |  1 +
 .../views/nodes/DataVizBox/components/PieChart.tsx |  1 +
 .../views/nodes/DataVizBox/components/TableBox.tsx | 22 ++++++++++++++++------
 5 files changed, 25 insertions(+), 8 deletions(-)

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

diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index 981ec0aa1..ea053b09d 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -104,8 +104,11 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     @computed.struct get axes() {
         return StrListCast(this.layoutDoc._dataViz_axes);
     }
-
     selectAxes = (axes: string[]) => (this.layoutDoc._dataViz_axes = new List<string>(axes));
+    @computed.struct get titleCol() {
+        return StrCast(this.layoutDoc._dataViz_titleCol);
+    }
+    selectTitleCol = (titleCol: string) => (this.layoutDoc._dataViz_titleCol = titleCol);
 
     @action // pinned / linked anchor doc includes selected rows, graph titles, and graph colors
     restoreView = (data: Doc) => {
@@ -271,6 +274,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             layoutDoc: this.layoutDoc,
             records: this.records,
             axes: this.axes,
+            titleCol: this.titleCol,
             //width: this.SidebarShown? this._props.PanelWidth()*.9/1.2: this._props.PanelWidth() * 0.9,
             height: (this._props.PanelHeight() / scale - 32) /* height of 'change view' button */ * 0.9,
             width: (this._props.PanelWidth() / scale) * 0.9,
@@ -278,7 +282,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         };
         if (!this.records.length) return 'no data/visualization';
         switch (this.dataVizView) {
-            case DataVizView.TABLE:     return <TableBox  {...sharedProps} docView={this._props.DocumentView} selectAxes={this.selectAxes} />;
+            case DataVizView.TABLE:     return <TableBox  {...sharedProps} docView={this._props.DocumentView} selectAxes={this.selectAxes} selectTitleCol={this.selectTitleCol}/>;
             case DataVizView.LINECHART: return <LineChart {...sharedProps} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={r => (this._vizRenderer = r ?? undefined)} vizBox={this} />;
             case DataVizView.HISTOGRAM: return <Histogram {...sharedProps} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={r => (this._vizRenderer = r ?? undefined)} />;
             case DataVizView.PIECHART:  return <PieChart  {...sharedProps} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={r => (this._vizRenderer = r ?? undefined)} 
diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
index 412957fb1..44e8b97c6 100644
--- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx
+++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
@@ -20,6 +20,7 @@ export interface HistogramProps {
     Document: Doc;
     layoutDoc: Doc;
     axes: string[];
+    titleCol: string;
     records: { [key: string]: any }[];
     width: number;
     height: number;
diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx
index 2a9a8b354..f23ab94a2 100644
--- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx
+++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx
@@ -28,6 +28,7 @@ export interface LineChartProps {
     Document: Doc;
     layoutDoc: Doc;
     axes: string[];
+    titleCol: string;
     records: { [key: string]: any }[];
     width: number;
     height: number;
diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
index 1259a13ff..55c2208a3 100644
--- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx
+++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
@@ -19,6 +19,7 @@ export interface PieChartProps {
     Document: Doc;
     layoutDoc: Doc;
     axes: string[];
+    titleCol: string;
     records: { [key: string]: any }[];
     width: number;
     height: number;
diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
index c5fda18ae..c20509029 100644
--- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx
+++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
@@ -18,7 +18,9 @@ interface TableBoxProps {
     layoutDoc: Doc;
     records: { [key: string]: any }[];
     selectAxes: (axes: string[]) => void;
+    selectTitleCol: (titleCol: string) => void;
     axes: string[];
+    titleCol: string;
     width: number;
     height: number;
     margin: {
@@ -153,11 +155,18 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
             },
             emptyFunction,
             action(e => {
-                const newAxes = this._props.axes;
-                if (newAxes.includes(col)) newAxes.splice(newAxes.indexOf(col), 1);
-                else if (newAxes.length > 1) newAxes[1] = col;
-                else newAxes.push(col);
-                this._props.selectAxes(newAxes);
+                if (e.shiftKey){
+                    if (this._props.titleCol == col) this._props.titleCol = "";
+                    else this._props.titleCol = col;
+                    this._props.selectTitleCol(this._props.titleCol);
+                }
+                else{
+                    const newAxes = this._props.axes;
+                    if (newAxes.includes(col)) newAxes.splice(newAxes.indexOf(col), 1);
+                    else if (newAxes.length > 1) newAxes[1] = col;
+                    else newAxes.push(col);
+                    this._props.selectAxes(newAxes);
+                }
             })
         );
     };
@@ -234,7 +243,8 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
                                                 background: NumListCast(this._props.layoutDoc.dataViz_highlitedRows).includes(rowId) ? 'lightYellow' : NumListCast(this._props.layoutDoc.dataViz_selectedRows).includes(rowId) ? 'lightgrey' : '',
                                             }}>
                                             {this.columns.map(col => {
-                                                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;
+                                                var 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;
+                                                if (this._props.titleCol==col) colSelected = true;
                                                 return (
                                                     <td key={this.columns.indexOf(col)} style={{ border: colSelected ? '3px solid black' : '1px solid black', fontWeight: colSelected ? 'bolder' : 'normal' }}>
                                                         <div className="tableBox-cell">{this._props.records[rowId][col]}</div>
-- 
cgit v1.2.3-70-g09d2


From 9ceb805cec6fa3cab9236b46a1865bbf3436605c Mon Sep 17 00:00:00 2001
From: srichman333 <sarah_n_richman@brown.edu>
Date: Mon, 29 Jan 2024 16:44:15 -0500
Subject: live schema toggle fix

---
 src/client/views/nodes/DataVizBox/DataVizBox.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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

diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index 742dc60d1..1cd72e29a 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -306,7 +306,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
                     const ogHref = CsvCast(ogDoc[this.fieldKey])? CsvCast(ogDoc[this.fieldKey]).url.href : undefined;
                     const href = CsvCast(this.Document[this.fieldKey]).url.href
                     if (ogHref && !DataVizBox.datasetSchemaOG.has(href)){ // sets original dataset to the var
-                        DataVizBox.datasetSchemaOG.set(href, []);
+                        DataVizBox.datasetSchemaOG.set(href, current);
                         fetch('/csvData?uri=' + ogHref)
                             .then(res => res.json().then(action(res => !res.errno && DataVizBox.datasetSchemaOG.set(href, res))));
                     }
-- 
cgit v1.2.3-70-g09d2


From 5b57029fa39c1ccee9d426be057161e92c5fa759 Mon Sep 17 00:00:00 2001
From: srichman333 <sarah_n_richman@brown.edu>
Date: Mon, 29 Jan 2024 16:57:34 -0500
Subject: static schema as dataviz doesn't include itself

---
 src/client/views/nodes/DataVizBox/DataVizBox.tsx | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

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

diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index 1cd72e29a..66a08f13e 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -286,7 +286,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
                     if (!this.layoutDoc._dataViz_schemaOG){ // makes a copy of the original table for the "live" toggle
                         let csvRows = [];
                         csvRows.push(keys.join(','));
-                        for (let i = 0; i < children.length; i++) {
+                        for (let i = 0; i < children.length-1; i++) {
                             let eachRow = [];
                             for (let j = 0; j < keys.length; j++) {
                                 var cell = children[i][keys[j]];
@@ -306,7 +306,9 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im
                     const ogHref = CsvCast(ogDoc[this.fieldKey])? CsvCast(ogDoc[this.fieldKey]).url.href : undefined;
                     const href = CsvCast(this.Document[this.fieldKey]).url.href
                     if (ogHref && !DataVizBox.datasetSchemaOG.has(href)){ // sets original dataset to the var
+                        const lastRow = current.pop();
                         DataVizBox.datasetSchemaOG.set(href, current);
+                        current.push(lastRow!);
                         fetch('/csvData?uri=' + ogHref)
                             .then(res => res.json().then(action(res => !res.errno && DataVizBox.datasetSchemaOG.set(href, res))));
                     }
-- 
cgit v1.2.3-70-g09d2

