diff options
Diffstat (limited to 'src/client/views/nodes/DataVizBox/DataVizBox.tsx')
-rw-r--r-- | src/client/views/nodes/DataVizBox/DataVizBox.tsx | 107 |
1 files changed, 59 insertions, 48 deletions
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index d548ab9f1..e71739231 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -1,9 +1,9 @@ -import { action, computed, observable, ObservableMap, ObservableSet } from 'mobx'; +import { action, computed, ObservableMap, ObservableSet } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Doc, StrListCast } from '../../../../fields/Doc'; +import { Doc, Field, StrListCast } from '../../../../fields/Doc'; import { List } from '../../../../fields/List'; -import { Cast, CsvCast, NumCast, StrCast } from '../../../../fields/Types'; +import { Cast, CsvCast, StrCast } from '../../../../fields/Types'; import { CsvField } from '../../../../fields/URLField'; import { Docs } from '../../../documents/Documents'; import { ViewBoxAnnotatableComponent } from '../../DocComponent'; @@ -12,56 +12,44 @@ import { PinProps } from '../trails'; import { LineChart } from './components/LineChart'; import { TableBox } from './components/TableBox'; import './DataVizBox.scss'; +import { Histogram } from './components/Histogram'; +import { PieChart } from './components/PieChart'; +import { Toggle, ToggleType, Type } from 'browndash-components'; export enum DataVizView { TABLE = 'table', LINECHART = 'lineChart', + HISTOGRAM = 'histogram', + PIECHART = 'pieChart' } @observer export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { - public static LayoutString(fieldKey: string) { - return FieldView.LayoutString(DataVizBox, fieldKey); - } - // says we have an object and any string - // 2 ways of doing it - // @observable private pairs: { [key: string]: number | string | undefined }[] = []; - // @observable private pairs: { [key: string]: FieldResult }[] = []; + + // all data static pairSet = new ObservableMap<string, { [key: string]: string }[]>(); @computed.struct get pairs() { return DataVizBox.pairSet.get(CsvCast(this.rootDoc[this.fieldKey]).url.href); } - private _chartRenderer: LineChart | undefined; - // // another way would be store a schema that defines the type of data we are expecting from an imported doc - - // method1() { - // this.pairs[0].x = 3; - // } - // method() { - // // this.pairs[0].x = 3; - // // go through the pairs - // const x = this.pairs[0].x; - // if (typeof x == 'number') { - // let x1 = Number(x); - // // let x1 = NumCast(x); - // } - // } - - // could use field result - // [key: string]: FieldResult; - // instead of numeric x,y in there, - - // TODO: nda - use onmousedown and onmouseup when dragging and changing height and width to update the height and width props only when dragging stops + private _chartRenderer: LineChart | Histogram | PieChart | undefined; + // current displayed chart type @computed get dataVizView(): DataVizView { return StrCast(this.layoutDoc._dataVizView, 'table') as DataVizView; } - @action + @action // pinned / linked anchor doc includes selected rows, graph titles, and graph colors restoreView = (data: Doc) => { const changedView = this.dataVizView !== data.presDataVizView && (this.layoutDoc._dataVizView = data.presDataVizView); const changedAxes = this.axes.join('') !== StrListCast(data.presDataVizAxes).join('') && (this.layoutDoc._data_vizAxes = new List<string>(StrListCast(data.presDataVizAxes))); + this.layoutDoc.selected = Field.Copy(data.selected); + this.layoutDoc.histogramBarColors = Field.Copy(data.histogramBarColors); + this.layoutDoc.defaultHistogramColor = data.defaultHistogramColor; + this.layoutDoc.pieSliceColors = Field.Copy(data.pieSliceColors); + Object.keys(this.layoutDoc).map(key => { + if (key.startsWith('histogram-title') || key.startsWith('lineChart-title') || key.startsWith('pieChart-title')){ this.layoutDoc['_'+key] = data[key]; } + }) const func = () => this._chartRenderer?.restoreView(data); if (changedView || changedAxes) { setTimeout(func, 100); @@ -69,7 +57,6 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } return func() ?? false; }; - getAnchor = (addAsAnnotation?: boolean, pinProps?: PinProps) => { const anchor = !pinProps ? this.rootDoc @@ -79,10 +66,15 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { // this is for when we want the whole doc (so when the chartBox getAnchor returns without a marker) /*put in some options*/ }); - anchor.presDataVizView = this.dataVizView; anchor.presDataVizAxes = this.axes.length ? new List<string>(this.axes) : undefined; - + anchor.selected = Field.Copy(this.layoutDoc.selected); + anchor.histogramBarColors = Field.Copy(this.layoutDoc.histogramBarColors); + anchor.defaultHistogramColor = this.layoutDoc.defaultHistogramColor; + anchor.pieSliceColors = Field.Copy(this.layoutDoc.pieSliceColors); + Object.keys(this.layoutDoc).map(key => { + if (key.startsWith('histogram-title') || key.startsWith('lineChart-title') || key.startsWith('pieChart-title')){ anchor[key] = this.layoutDoc[key]; } + }) this.addDocument(anchor); return anchor; }; @@ -92,17 +84,20 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } selectAxes = (axes: string[]) => (this.layoutDoc.data_vizAxes = new List<string>(axes)); + // toggles for user to decide which chart type to view the data in @computed get selectView() { const width = this.props.PanelWidth() * 0.9; const height = (this.props.PanelHeight() - 32) /* height of 'change view' button */ * 0.9; - const margin = { top: 10, right: 25, bottom: 50, left: 25 }; + const margin = { top: 10, right: 25, bottom: 75, left: 45 }; if (!this.pairs) return 'no data'; - // prettier-ignore switch (this.dataVizView) { - case DataVizView.TABLE: return <TableBox pairs={this.pairs} axes={this.axes} docView={this.props.DocumentView} selectAxes={this.selectAxes}/>; - case DataVizView.LINECHART: return <LineChart ref={r => (this._chartRenderer = r ?? undefined)} height={height} width={width} fieldKey={this.fieldKey} margin={margin} rootDoc={this.rootDoc} axes={this.axes} pairs={this.pairs} dataDoc={this.dataDoc} />; + case DataVizView.TABLE: return <TableBox layoutDoc={this.layoutDoc} pairs={this.pairs} axes={this.axes} height={height} width={width} margin={margin} rootDoc={this.rootDoc} docView={this.props.DocumentView} selectAxes={this.selectAxes}/>; + case DataVizView.LINECHART: return <LineChart layoutDoc={this.layoutDoc} ref={r => (this._chartRenderer = r ?? undefined)} height={height} width={width} fieldKey={this.fieldKey} margin={margin} rootDoc={this.rootDoc} axes={this.axes} pairs={this.pairs} dataDoc={this.dataDoc} />; + case DataVizView.HISTOGRAM: return <Histogram layoutDoc={this.layoutDoc} ref={r => (this._chartRenderer = r ?? undefined)} height={height} width={width} fieldKey={this.fieldKey} margin={margin} rootDoc={this.rootDoc} axes={this.axes} pairs={this.pairs} dataDoc={this.dataDoc} />; + case DataVizView.PIECHART: return <PieChart layoutDoc={this.layoutDoc} ref={r => (this._chartRenderer = r ?? undefined)} height={height} width={width} fieldKey={this.fieldKey} margin={margin} rootDoc={this.rootDoc} axes={this.axes} pairs={this.pairs} dataDoc={this.dataDoc} />; } } + @computed get dataUrl() { return Cast(this.dataDoc[this.fieldKey], CsvField); } @@ -119,16 +114,15 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { .then(res => res.json().then(action(res => !res.errno && DataVizBox.pairSet.set(CsvCast(this.rootDoc[this.fieldKey]).url.href, res)))); } - // handle changing the view using a button - @action changeViewHandler(e: React.MouseEvent<HTMLButtonElement>) { - e.preventDefault(); - e.stopPropagation(); - this.layoutDoc._dataVizView = this.dataVizView === DataVizView.TABLE ? DataVizView.LINECHART : DataVizView.TABLE; - } - render() { + if (!this.layoutDoc._dataVizView) this.layoutDoc._dataVizView = this.dataVizView; return !this.pairs?.length ? ( - <div>Loading...</div> + // 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 + t' to bring the data table + to your canvas. + </div> ) : ( <div className="dataViz" @@ -143,7 +137,24 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { { passive: false } ) }> - <button onClick={e => this.changeViewHandler(e)}>{this.dataVizView === DataVizView.TABLE ? DataVizView.LINECHART : DataVizView.TABLE}</button> + <div className={'datatype-button'}> + <Toggle text={"TABLE"} toggleType={ToggleType.BUTTON} type={Type.SEC} color={"black"} + onClick={e => this.layoutDoc._dataVizView = DataVizView.TABLE} + toggleStatus={this.layoutDoc._dataVizView == DataVizView.TABLE} + /> + <Toggle text={"LINECHART"} toggleType={ToggleType.BUTTON} type={Type.SEC} color={"black"} + onClick={e => this.layoutDoc._dataVizView = DataVizView.LINECHART} + toggleStatus={this.layoutDoc._dataVizView == DataVizView.LINECHART} + /> + <Toggle text={"HISTOGRAM"} toggleType={ToggleType.BUTTON} type={Type.SEC} color={"black"} + onClick={e => this.layoutDoc._dataVizView = DataVizView.HISTOGRAM} + toggleStatus={this.layoutDoc._dataVizView == DataVizView.HISTOGRAM} + /> + <Toggle text={"PIE CHART"} toggleType={ToggleType.BUTTON} type={Type.SEC} color={"black"} + onClick={e => this.layoutDoc._dataVizView = DataVizView.PIECHART} + toggleStatus={this.layoutDoc._dataVizView == DataVizView.PIECHART} + /> + </div> {this.selectView} </div> ); |