diff options
| author | bobzel <zzzman@gmail.com> | 2024-05-19 01:01:02 -0400 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2024-05-19 01:01:02 -0400 |
| commit | 6e72f969029c22fe797397a6437836a0482260b6 (patch) | |
| tree | e8ccde75702e557b2226c9069263e1bc3bd21a4b /src/client/views/nodes/DataVizBox/DataVizBox.tsx | |
| parent | 5ff0bef5d3c4825aa7210a26c98aae3b24f4a835 (diff) | |
| parent | 13dc6de0e0099f699ad0d2bb54401e6a0aa25018 (diff) | |
Merge branch 'restoringEslint' into alyssa-starter
Diffstat (limited to 'src/client/views/nodes/DataVizBox/DataVizBox.tsx')
| -rw-r--r-- | src/client/views/nodes/DataVizBox/DataVizBox.tsx | 299 |
1 files changed, 204 insertions, 95 deletions
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index 66a08f13e..4d5f15a3e 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -1,33 +1,37 @@ +/* eslint-disable react/jsx-props-no-spreading */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Checkbox } from '@mui/material'; import { Colors, Toggle, ToggleType, Type } from 'browndash-components'; import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { emptyFunction, returnEmptyString, returnFalse, returnOne, setupMoveUpEvents } from '../../../../Utils'; +import { returnEmptyString, returnFalse, returnOne, setupMoveUpEvents } from '../../../../ClientUtils'; +import { emptyFunction } from '../../../../Utils'; import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../../fields/Doc'; import { InkTool } from '../../../../fields/InkField'; import { List } from '../../../../fields/List'; -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 { DocUtils, Docs } from '../../../documents/Documents'; -import { DocumentManager } from '../../../util/DocumentManager'; +import { DocUtils } from '../../../documents/DocUtils'; +import { DocumentType } from '../../../documents/DocumentTypes'; +import { Docs } from '../../../documents/Documents'; import { UndoManager, undoable } from '../../../util/UndoManager'; -import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../../DocComponent'; +import { ContextMenu } from '../../ContextMenu'; +import { ViewBoxAnnotatableComponent } from '../../DocComponent'; import { MarqueeAnnotator } from '../../MarqueeAnnotator'; +import { PinProps } from '../../PinFuncs'; import { SidebarAnnos } from '../../SidebarAnnos'; import { AnchorMenu } from '../../pdf/AnchorMenu'; -import { GPTPopup } from '../../pdf/GPTPopup/GPTPopup'; +import { GPTPopup, GPTPopupMode } from '../../pdf/GPTPopup/GPTPopup'; import { DocumentView } from '../DocumentView'; -import { FocusViewOptions, FieldView, FieldViewProps } from '../FieldView'; -import { PinProps } from '../trails'; +import { FieldView, FieldViewProps } from '../FieldView'; +import { FocusViewOptions } from '../FocusViewOptions'; import './DataVizBox.scss'; 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', @@ -37,12 +41,13 @@ export enum DataVizView { } @observer -export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface { +export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { private _mainCont: React.RefObject<HTMLDivElement> = React.createRef(); private _marqueeref = React.createRef<MarqueeAnnotator>(); private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef(); private _disposers: { [name: string]: IReactionDisposer } = {}; anchorMenuClick?: () => undefined | ((anchor: Doc) => void); + sidebarAddDoc: ((doc: Doc | Doc[], sidebarKey?: string | undefined) => boolean) | undefined; crop: ((region: Doc | undefined, addCrop?: boolean) => Doc | undefined) | undefined; @observable _marqueeing: number[] | undefined = undefined; @observable _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>(); @@ -62,9 +67,9 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im setupMoveUpEvents( this, e, - action(e => { + action(moveEv => { MarqueeAnnotator.clearAnnotations(this._savedAnnotations); - this._marqueeref.current?.onInitiateSelection([e.clientX, e.clientY]); + this._marqueeref.current?.onInitiateSelection([moveEv.clientX, moveEv.clientY]); return true; }), returnFalse, @@ -95,7 +100,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im // all CSV records in the dataset (that aren't an empty row) @computed.struct get records() { - var records = DataVizBox.dataset.get(CsvCast(this.dataDoc[this.fieldKey]).url.href); + const records = DataVizBox.dataset.get(CsvCast(this.dataDoc[this.fieldKey]).url.href); return records?.filter(record => Object.keys(record).some(key => record[key])) ?? []; } @@ -110,31 +115,36 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im @computed.struct get 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); + }; @computed.struct get titleCol() { return StrCast(this.layoutDoc._dataViz_titleCol); } - selectTitleCol = (titleCol: string) => (this.layoutDoc._dataViz_titleCol = 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) => { - const changedView = this.dataVizView !== data.config_dataViz && (this.layoutDoc._dataViz = data.config_dataViz); - const changedAxes = this.axes.join('') !== StrListCast(data.config_dataVizAxes).join('') && (this.layoutDoc._dataViz_axes = new List<string>(StrListCast(data.config_dataVizAxes))); + // const changedView = data.config_dataViz && this.dataVizView !== data.config_dataViz && (this.layoutDoc._dataViz = data.config_dataViz); + // const changedAxes = data.config_dataVizAxes && this.axes.join('') !== StrListCast(data.config_dataVizAxes).join('') && (this.layoutDoc._dataViz_axes = new List<string>(StrListCast(data.config_dataVizAxes))); this.layoutDoc.dataViz_selectedRows = Field.Copy(data.dataViz_selectedRows); this.layoutDoc.dataViz_histogram_barColors = Field.Copy(data.dataViz_histogram_barColors); this.layoutDoc.dataViz_histogram_defaultColor = data.dataViz_histogram_defaultColor; this.layoutDoc.dataViz_pie_sliceColors = Field.Copy(data.dataViz_pie_sliceColors); - Object.keys(this.layoutDoc).map(key => { + Object.keys(this.layoutDoc).forEach(key => { if (key.startsWith('dataViz_histogram_title') || key.startsWith('dataViz_lineChart_title') || key.startsWith('dataViz_pieChart_title')) { this.layoutDoc['_' + key] = data[key]; } }); - const func = () => this._vizRenderer?.restoreView(data); - if (changedView || changedAxes) { - setTimeout(func, 100); - return true; - } - return func() ?? false; + return true; + // const func = () => this._vizRenderer?.restoreView(data); + // if (changedView || changedAxes) { + // setTimeout(func, 100); + // return true; + // } + // return func() ?? false; }; getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => { const visibleAnchor = AnchorMenu.Instance.GetAnchor?.(undefined, addAsAnnotation); @@ -150,7 +160,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im annotationOn: this.Document, // when we clear selection -> we should have it so chartBox getAnchor returns undefined // this is for when we want the whole doc (so when the chartBox getAnchor returns without a marker) - /*put in some options*/ + /* put in some options */ }); anchor.config_dataViz = this.dataVizView; anchor.config_dataVizAxes = this.axes.length ? new List<string>(this.axes) : undefined; @@ -158,24 +168,21 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im anchor.dataViz_histogram_barColors = Field.Copy(this.layoutDoc.dataViz_histogram_barColors); anchor.dataViz_histogram_defaultColor = this.layoutDoc.dataViz_histogram_defaultColor; anchor.dataViz_pie_sliceColors = Field.Copy(this.layoutDoc.dataViz_pie_sliceColors); - Object.keys(this.layoutDoc).map(key => { + Object.keys(this.layoutDoc).forEach(key => { if (key.startsWith('dataViz_histogram_title') || key.startsWith('dataViz_lineChart_title') || key.startsWith('dataViz_pieChart_title')) { anchor[key] = this.layoutDoc[key]; } }); this.addDocument(anchor); - //addAsAnnotation && this.addDocument(anchor); + // addAsAnnotation && this.addDocument(anchor); return anchor; }; createNoteAnnotation = () => { - const createFunc = undoable( - action(() => { - const note = this._sidebarRef.current?.anchorMenuClick(this.getAnchor(false), ['latitude', 'longitude', '-linkedTo']); - }), - 'create note annotation' - ); + const createFunc = undoable(() => { + this._sidebarRef.current?.anchorMenuClick(this.getAnchor(false), ['latitude', 'longitude', '-linkedTo']); + }, 'create note annotation'); if (!this.layoutDoc.layout_showSidebar) { this.toggleSidebar(); setTimeout(createFunc); @@ -192,7 +199,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im this.layoutDoc._width = this.layoutDoc._layout_showSidebar ? NumCast(this.layoutDoc._width) * 1.2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth); }; @computed get SidebarShown() { - return this.layoutDoc._layout_showSidebar ? true : false; + return !!this.layoutDoc._layout_showSidebar; } @computed get sidebarHandle() { return ( @@ -206,7 +213,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK, }} onPointerDown={this.sidebarBtnDown}> - <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={'comment-alt'} size="sm" /> + <FontAwesomeIcon style={{ color: Colors.WHITE }} icon="comment-alt" size="sm" /> </div> ); } @@ -218,7 +225,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im setupMoveUpEvents( this, e, - (e, down, delta) => + (moveEv, down, delta) => runInAction(() => { const localDelta = this._props .ScreenToLocalTransform() @@ -246,7 +253,9 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im options.didMove = true; this.toggleSidebar(); } - return new Promise<Opt<DocumentView>>(res => DocumentManager.Instance.AddViewRenderedCb(doc, dv => res(dv))); + return new Promise<Opt<DocumentView>>(res => { + DocumentView.addViewRenderedCb(doc, dv => res(dv)); + }); }; @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%'); @@ -266,59 +275,60 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im if (!DataVizBox.dataset.has(CsvCast(this.dataDoc[this.fieldKey]).url.href)) this.fetchData(); this._disposers.datavis = reaction( () => { - if (this.layoutDoc.dataViz_schemaLive==undefined) this.layoutDoc.dataViz_schemaLive = true; + if (this.layoutDoc.dataViz_schemaLive === undefined) this.layoutDoc.dataViz_schemaLive = true; 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 }[] = []; + if (!getFrom?.schema_columnKeys) return undefined; + const keys = StrListCast(getFrom?.schema_columnKeys).filter(key => key !== 'text'); + const children = DocListCast(getFrom?.[Doc.LayoutFieldKey(getFrom)]); + const current: { [key: string]: string }[] = []; children .filter(child => child) .forEach(child => { const row: { [key: string]: string } = {}; keys.forEach(key => { - var cell = child[key]; - if (cell && (cell as string)) cell = cell.toString().replace(/\,/g, ''); + let cell = child[key]; + if (cell && (cell as string)) cell = cell.toString().replace(/,/g, ''); row[key] = StrCast(cell); }); current.push(row); }); - 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-1; 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); + if (!this.layoutDoc._dataViz_schemaOG) { + // makes a copy of the original table for the "live" toggle + const csvRows = []; + csvRows.push(keys.join(',')); + for (let i = 0; i < children.length - 1; i++) { + const eachRow = []; + for (let j = 0; j < keys.length; j++) { + let cell = children[i][keys[j]]; + if (cell && (cell as string)) cell = cell.toString().replace(/,/g, ''); + eachRow.push(cell); } - 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; - 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)))); + 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; + const { href } = CsvCast(this.Document[this.fieldKey]).url; + 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(jsonRes => !jsonRes.errno && DataVizBox.datasetSchemaOG.set(href, jsonRes)))); + } return current; }, current => { if (current) { - const href = CsvCast(this.Document[this.fieldKey]).url.href; - if (this.layoutDoc.dataViz_schemaLive) DataVizBox.dataset.set(href, current); - else DataVizBox.dataset.set(href, DataVizBox.datasetSchemaOG.get(href)!); + const { href } = CsvCast(this.Document[this.fieldKey]).url; + if (this.layoutDoc.dataViz_schemaLive) DataVizBox.dataset.set(href, current); + else DataVizBox.dataset.set(href, DataVizBox.datasetSchemaOG.get(href)!); } }, { fireImmediately: true } @@ -328,8 +338,8 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im fetchData = () => { if (!this.Document.dataViz_asSchema) { DataVizBox.dataset.set(CsvCast(this.dataDoc[this.fieldKey]).url.href, []); // assign temporary dataset as a lock to prevent duplicate server requests - fetch('/csvData?uri=' + this.dataUrl?.url.href) // - .then(res => res.json().then(action(res => !res.errno && DataVizBox.dataset.set(CsvCast(this.dataDoc[this.fieldKey]).url.href, res)))); + fetch('/csvData?uri=' + (this.dataUrl?.url.href ?? '')) // + .then(res => res.json().then(action(jsonRes => !jsonRes.errno && DataVizBox.dataset.set(CsvCast(this.dataDoc[this.fieldKey]).url.href, jsonRes)))); } }; @@ -342,19 +352,21 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im 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.SidebarShown? this._props.PanelWidth()*.9/1.2: this._props.PanelWidth() * 0.9, + height: (this._props.PanelHeight() / scale - 55) /* height of 'change view' button */ * 0.8, width: ((this._props.PanelWidth() - this.sidebarWidth()) / scale) * 0.9, margin: { top: 10, right: 25, bottom: 75, left: 45 }, }; if (!this.records.length) return 'no data/visualization'; switch (this.dataVizView) { case DataVizView.TABLE: return <TableBox {...sharedProps} docView={this.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)} + 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;}} margin={{ top: 10, right: 15, bottom: 15, left: 15 }} />; + default: } // prettier-ignore + return null; } @action @@ -366,10 +378,13 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im this._marqueeing = [e.clientX, e.clientY]; const target = e.target as any; if (e.target && (target.className.includes('endOfContent') || (target.parentElement.className !== 'textLayer' && target.parentElement.parentElement?.className !== 'textLayer'))) { + /* empty */ } else { // if textLayer is hit, then we select text instead of using a marquee so clear out the marquee. setTimeout( - action(() => (this._marqueeing = undefined)), + action(() => { + this._marqueeing = undefined; + }), 100 ); // bcz: hack .. anchor menu is setup within MarqueeAnnotator so we need to at least create the marqueeAnnotator even though we aren't using it. @@ -397,16 +412,81 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im GPTPopup.Instance.addDoc = this.sidebarAddDocument; }; + // represents whether or not a data viz box created from a schema table displays live updates to the canvas @action changeLiveSchemaCheckbox = () => { - this.layoutDoc.dataViz_schemaLive = !this.layoutDoc.dataViz_schemaLive - } + this.layoutDoc.dataViz_schemaLive = !this.layoutDoc.dataViz_schemaLive; + }; + + // represents whether or not clicking on a peice of data in the visualization + // (i.e. a data point in a linechart, a bar on a histogram, or a slice of a pie chart) + // filters the data onto a new data viz doc created off of this one + @action + changeFilteringCheckbox = () => { + this.layoutDoc.dataViz_filterSelection = !this.layoutDoc.dataViz_filterSelection; + }; + + specificContextMenu = (): void => { + const cm = ContextMenu.Instance; + const options = cm.findByDescription('Options...'); + const optionItems = options && 'subitems' in options ? options.subitems : []; + optionItems.push({ description: `Analyze with AI`, event: () => this.askGPT(), icon: 'lightbulb' }); + !options && cm.addItem({ description: 'Options...', subitems: optionItems, icon: 'eye' }); + }; + + askGPT = action(async () => { + GPTPopup.Instance.setSidebarId('data_sidebar'); + GPTPopup.Instance.addDoc = this.sidebarAddDocument; + GPTPopup.Instance.createFilteredDoc = this.createFilteredDoc; + GPTPopup.Instance.setDataJson(''); + GPTPopup.Instance.setMode(GPTPopupMode.DATA); + const data = DataVizBox.dataset.get(CsvCast(this.dataDoc[this.fieldKey]).url.href); + GPTPopup.Instance.setDataJson(JSON.stringify(data)); + GPTPopup.Instance.generateDataAnalysis(); + }); + + /** + * creates a new dataviz document filter from this one + * it appears to the right of this document, with the + * parameters passed in being used to create an initial display + */ + createFilteredDoc = (axes?: any) => { + const embedding = Doc.MakeEmbedding(this.Document!); + embedding._layout_showSidebar = false; + embedding._dataViz = DataVizView.LINECHART; + embedding._dataViz_axes = new List<string>(axes); + embedding._dataViz_parentViz = this.Document; + embedding.histogramBarColors = Field.Copy(this.layoutDoc.histogramBarColors); + embedding.defaultHistogramColor = this.layoutDoc.defaultHistogramColor; + embedding.pieSliceColors = Field.Copy(this.layoutDoc.pieSliceColors); + embedding._layout_showSidebar = false; + embedding.width = NumCast(this.layoutDoc._width) - this.sidebarWidth(); + embedding._layout_sidebarWidthPercent = '0%'; + this._props.addDocument?.(embedding); + embedding._dataViz_axes = new List<string>(axes); + this.layoutDoc.dataViz_selectedRows = new List<number>(this.records.map((rec, i) => i)); + embedding.x = Number(embedding.x) + Number(this.Document.width); + + return true; + }; render() { const scale = this._props.NativeDimScaling?.() || 1; + const toggleBtn = (name: string, type: DataVizView) => ( + <Toggle + text={name} + toggleType={ToggleType.BUTTON} + type={Type.SEC} + color="black" + onClick={() => { + this.layoutDoc._dataViz = type; + }} + toggleStatus={this.layoutDoc._dataViz === type} + /> + ); return !this.records.length ? ( // displays how to get data into the DataVizBox if its empty - <div className="start-message">To create a DataViz box, either import / drag a CSV file into your canvas or copy a data table and use the command 'ctrl + p' to bring the data table to your canvas.</div> + <div className="start-message">To create a DataViz box, either import / drag a CSV file into your canvas or copy a data table and use the command (ctrl + p) to bring the data table to your canvas.</div> ) : ( <div className="dataViz-box" @@ -418,20 +498,29 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im transform: `scale(${scale})`, position: 'absolute', }} + onContextMenu={this.specificContextMenu} onWheel={e => e.stopPropagation()} ref={this._mainCont}> <div className="datatype-button"> - <Toggle text={' TABLE '} toggleType={ToggleType.BUTTON} type={Type.SEC} color={'black'} onClick={e => (this.layoutDoc._dataViz = DataVizView.TABLE)} toggleStatus={this.layoutDoc._dataViz === DataVizView.TABLE} /> - <Toggle text={'LINECHART'} toggleType={ToggleType.BUTTON} type={Type.SEC} color={'black'} onClick={e => (this.layoutDoc._dataViz = DataVizView.LINECHART)} toggleStatus={this.layoutDoc._dataViz === DataVizView.LINECHART} /> - <Toggle text={'HISTOGRAM'} toggleType={ToggleType.BUTTON} type={Type.SEC} color={'black'} onClick={e => (this.layoutDoc._dataViz = DataVizView.HISTOGRAM)} toggleStatus={this.layoutDoc._dataViz === DataVizView.HISTOGRAM} /> - <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} /> + {toggleBtn(' TABLE ', DataVizView.TABLE)} + {toggleBtn('LINECHART', DataVizView.LINECHART)} + {toggleBtn('HISTOGRAM', DataVizView.HISTOGRAM)} + {toggleBtn('PIE CHART', DataVizView.PIECHART)} </div> - {(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> + {this.layoutDoc && this.layoutDoc.dataViz_asSchema ? ( + <div className="displaySchemaLive"> + <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> + </div> + ) : null} + {this.layoutDoc._dataViz !== DataVizView.TABLE ? ( + <div className="filterData-checkBox"> + <Checkbox color="primary" onChange={this.changeFilteringCheckbox} checked={this.layoutDoc.dataViz_filterSelection as boolean} /> + Select data to filter + </div> ) : null} {this.renderVizView} @@ -444,7 +533,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im Document={this.Document} layoutDoc={this.layoutDoc} dataDoc={this.dataDoc} - usePanelWidth={true} + usePanelWidth showSidebar={this.SidebarShown} nativeWidth={NumCast(this.layoutDoc._nativeWidth)} whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} @@ -478,3 +567,23 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() im ); } } +Docs.Prototypes.TemplateMap.set(DocumentType.DATAVIZ, { + layout: { view: DataVizBox, dataField: 'data' }, + options: { + acl: '', + dataViz_title: '', + dataViz_line: '', + dataViz_pie: '', + dataViz_histogram: '', + dataViz: 'table', + _layout_fitWidth: true, + _layout_reflowHorizontal: true, + _layout_reflowVertical: true, + _layout_nativeDimEditable: true, + }, +}); + +Docs.Prototypes.TemplateMap.set(DocumentType.DATAVIZ, { + layout: { view: DataVizBox, dataField: 'data' }, + options: { dataViz_title: '', dataViz_line: '', dataViz_pie: '', dataViz_histogram: '', dataViz: 'table', _layout_fitWidth: true, _layout_reflowHorizontal: true, _layout_reflowVertical: true, _layout_nativeDimEditable: true }, +}); |
