From 9200e09939ba3d23bcf79efda008a7a990d29b95 Mon Sep 17 00:00:00 2001 From: srichman333 Date: Thu, 11 Jan 2024 02:37:07 -0500 Subject: toggle scheme dataviz box as live --- src/client/views/nodes/DataVizBox/components/Chart.scss | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/components') diff --git a/src/client/views/nodes/DataVizBox/components/Chart.scss b/src/client/views/nodes/DataVizBox/components/Chart.scss index 2f7dd0487..a17dc9599 100644 --- a/src/client/views/nodes/DataVizBox/components/Chart.scss +++ b/src/client/views/nodes/DataVizBox/components/Chart.scss @@ -19,8 +19,6 @@ margin-bottom: -20px; } .asHistogram-checkBox { - // display: flex; - // flex-direction: row; align-items: left; align-self: left; align-content: left; -- cgit v1.2.3-70-g09d2 From db51496360e8eac55b5e83283370c4aeec7a11d8 Mon Sep 17 00:00:00 2001 From: srichman333 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/components') 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(['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() { } @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() { (this.layoutDoc._dataViz = DataVizView.PIECHART)} toggleStatus={this.layoutDoc._dataViz == -DataVizView.PIECHART} /> - {/* - {this.renderVizView} - */} - {(this.layoutDoc && this.layoutDoc.dataViz_asSchema)?(
@@ -453,6 +436,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { ) : null} {this.renderVizView} +
{ 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 99e57e5c98a69b1d95e87ecc7728164748886a0e Mon Sep 17 00:00:00 2001 From: srichman333 Date: Tue, 23 Jan 2024 12:24:22 -0500 Subject: non-numerical histogram fix --- src/client/views/nodes/DataVizBox/components/Histogram.tsx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/components') diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx index 4a1fb2ed1..412957fb1 100644 --- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx +++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx @@ -63,17 +63,17 @@ export class Histogram extends ObservableReactComponent { if (this._props.axes.length < 1) return []; if (this._props.axes.length < 2) { var ax0 = this._props.axes[0]; - if (/\d/.test(this._props.records[0][ax0])) { + if (!/[A-Za-z-:]/.test(this._props.records[0][ax0])){ this.numericalXData = true; } return this._tableData.map(record => ({ [ax0]: record[this._props.axes[0]] })); } var ax0 = this._props.axes[0]; var ax1 = this._props.axes[1]; - if (/\d/.test(this._props.records[0][ax0])) { + if (!/[A-Za-z-:]/.test(this._props.records[0][ax0])) { this.numericalXData = true; } - if (/\d/.test(this._props.records[0][ax1])) { + if (!/[A-Za-z-:]/.test(this._props.records[0][ax1])) { this.numericalYData = true; } return this._tableData.map(record => ({ [ax0]: record[this._props.axes[0]], [ax1]: record[this._props.axes[1]] })); @@ -89,9 +89,6 @@ export class Histogram extends ObservableReactComponent { @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 rangeVals(): { xMin?: number; xMax?: number; yMin?: number; yMax?: number } { -- cgit v1.2.3-70-g09d2 From aa3c70399ac2b6a337a9c85fb30f57f82ee44063 Mon Sep 17 00:00:00 2001 From: srichman333 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/components') 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() { @computed.struct get axes() { return StrListCast(this.layoutDoc._dataViz_axes); } - selectAxes = (axes: string[]) => (this.layoutDoc._dataViz_axes = new List(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() { 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() { }; if (!this.records.length) return 'no data/visualization'; switch (this.dataVizView) { - case DataVizView.TABLE: return ; + case DataVizView.TABLE: return ; case DataVizView.LINECHART: return (this._vizRenderer = r ?? undefined)} vizBox={this} />; case DataVizView.HISTOGRAM: return (this._vizRenderer = r ?? undefined)} />; case DataVizView.PIECHART: return (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 { }, 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 { 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 (
{this._props.records[rowId][col]}
-- cgit v1.2.3-70-g09d2 From 16c4a0ad4f9c33e6e52241bef8e6b250237226ae Mon Sep 17 00:00:00 2001 From: srichman333 Date: Mon, 29 Jan 2024 13:00:31 -0500 Subject: show selected names for pie charts + line charts --- .../views/nodes/DataVizBox/components/LineChart.tsx | 15 +++++++++++++-- .../views/nodes/DataVizBox/components/PieChart.tsx | 16 +++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/components') diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx index f23ab94a2..47ac751cd 100644 --- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx @@ -47,7 +47,7 @@ export class LineChart extends ObservableReactComponent { private _disposers: { [key: string]: IReactionDisposer } = {}; private _lineChartRef: React.RefObject = React.createRef(); private _lineChartSvg: d3.Selection | undefined; - @observable _currSelected: SelectedDataPoint | undefined = undefined; + @observable _currSelected: any | undefined = undefined; // TODO: nda - some sort of mapping that keeps track of the annotated points so we can easily remove when annotations list updates constructor(props: any) { super(props); @@ -357,6 +357,17 @@ export class LineChart extends ObservableReactComponent { else if (this._props.axes.length > 0) titleAccessor = 'dataViz_lineChart_title' + this._props.axes[0]; if (!this._props.layoutDoc[titleAccessor]) this._props.layoutDoc[titleAccessor] = this.defaultGraphTitle; const selectedPt = this._currSelected ? `{ ${this._props.axes[0]}: ${this._currSelected.x} ${this._props.axes[1]}: ${this._currSelected.y} }` : 'none'; + var selectedTitle = ""; + if (this._currSelected && this._props.titleCol){ + selectedTitle+= "\n" + this._props.titleCol + ": " + this._tableData.forEach(each => { + var mapThisEntry = false; + if (this._currSelected.x==each[this._props.axes[0]] && this._currSelected.y==each[this._props.axes[1]]) mapThisEntry = true; + else if (this._currSelected.y==each[this._props.axes[0]] && this._currSelected.x==each[this._props.axes[1]]) mapThisEntry = true; + if (mapThisEntry) selectedTitle += each[this._props.titleCol] + ", "; + }) + selectedTitle = selectedTitle.slice(0,-1).slice(0,-1); + } if (this._lineChartData.length > 0 || !this.parentViz || this.parentViz.length == 0) { return this._props.axes.length >= 2 && /\d/.test(this._props.records[0][this._props.axes[0]]) && /\d/.test(this._props.records[0][this._props.axes[1]]) ? (
@@ -376,9 +387,9 @@ export class LineChart extends ObservableReactComponent { {selectedPt != 'none' ? (
{`Selected: ${selectedPt}`} + {`${selectedTitle}`} diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx index 55c2208a3..f98d51123 100644 --- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx @@ -340,14 +340,28 @@ export class PieChart extends ObservableReactComponent { var selected: string; var curSelectedSliceName = ''; if (this._currSelected) { + selected = '{ '; const sliceTitle = this._currSelected[this._props.axes[0]]; curSelectedSliceName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/\%/g, '').replace(/\#/g, '').replace(/\ { key != '' ? (selected += key + ': ' + this._currSelected[key] + ', ') : ''; }); selected = selected.substring(0, selected.length - 2); selected += ' }'; + if (this._props.titleCol!="" && (!this._currSelected["frequency"] || this._currSelected["frequency"]<10) && this._pieChartData){ + var percentField = Object.keys(this._pieChartData[0])[0]; + var descriptionField = Object.keys(this._pieChartData[0])[1]!; + selected+= "\n" + this._props.titleCol + ": " + this._tableData.forEach(each => { + if (this._currSelected[percentField]==each[percentField]) { + if (descriptionField){ + if (this._currSelected[descriptionField]==each[descriptionField]) selected+= each[this._props.titleCol] + ", "; + } + else selected+= each[this._props.titleCol] + ", "; + } + }) + selected = selected.slice(0,-1).slice(0,-1); + } } else selected = 'none'; var selectedSliceColor; var sliceColors = StrListCast(this._props.layoutDoc.dataViz_pie_sliceColors).map(each => each.split('::')); -- cgit v1.2.3-70-g09d2 From d252886fe97524603ee49e577a535a39f1e664ae Mon Sep 17 00:00:00 2001 From: srichman333 Date: Mon, 29 Jan 2024 13:15:27 -0500 Subject: show title of selected histogram bars --- src/client/views/nodes/DataVizBox/components/Histogram.tsx | 12 ++++++++++++ src/client/views/nodes/DataVizBox/components/PieChart.tsx | 10 ++++------ 2 files changed, 16 insertions(+), 6 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/components') diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx index 44e8b97c6..c0e738cfa 100644 --- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx +++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx @@ -452,6 +452,18 @@ export class Histogram extends ObservableReactComponent { : '' ); selected = selected.substring(0, selected.length - 2) + ' }'; + if (this._props.titleCol!="" && (!this._currSelected["frequency"] || this._currSelected["frequency"]<10)){ + selected+= "\n" + this._props.titleCol + ": " + this._tableData.forEach(each => { + if (this._currSelected[this._props.axes[0]]==each[this._props.axes[0]]) { + if (this._props.axes[1]){ + if (this._currSelected[this._props.axes[1]]==each[this._props.axes[1]]) selected+= each[this._props.titleCol] + ", "; + } + else selected+= each[this._props.titleCol] + ", "; + } + }) + selected = selected.slice(0,-1).slice(0,-1); + } } var selectedBarColor; var barColors = StrListCast(this._props.layoutDoc.histogramBarColors).map(each => each.split('::')); diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx index f98d51123..54a83879c 100644 --- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx @@ -348,14 +348,12 @@ export class PieChart extends ObservableReactComponent { }); selected = selected.substring(0, selected.length - 2); selected += ' }'; - if (this._props.titleCol!="" && (!this._currSelected["frequency"] || this._currSelected["frequency"]<10) && this._pieChartData){ - var percentField = Object.keys(this._pieChartData[0])[0]; - var descriptionField = Object.keys(this._pieChartData[0])[1]!; + if (this._props.titleCol!="" && (!this._currSelected["frequency"] || this._currSelected["frequency"]<10)){ selected+= "\n" + this._props.titleCol + ": " this._tableData.forEach(each => { - if (this._currSelected[percentField]==each[percentField]) { - if (descriptionField){ - if (this._currSelected[descriptionField]==each[descriptionField]) selected+= each[this._props.titleCol] + ", "; + if (this._currSelected[this._props.axes[0]]==each[this._props.axes[0]]) { + if (this._props.axes[1]){ + if (this._currSelected[this._props.axes[1]]==each[this._props.axes[1]]) selected+= each[this._props.titleCol] + ", "; } else selected+= each[this._props.titleCol] + ", "; } -- cgit v1.2.3-70-g09d2 From 6d5a43b114b54820e3578862a5429eb096c71058 Mon Sep 17 00:00:00 2001 From: srichman333 Date: Wed, 31 Jan 2024 17:36:41 -0500 Subject: can select 3 columns (+ beginning of basic 2 columns displayed on y axis in linechart) --- .../views/nodes/DataVizBox/components/LineChart.tsx | 19 ++++++++++++++++--- .../views/nodes/DataVizBox/components/TableBox.tsx | 18 ++++++++++++++---- 2 files changed, 30 insertions(+), 7 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/components') diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx index 47ac751cd..8d6671e65 100644 --- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx @@ -272,12 +272,25 @@ export class LineChart extends ObservableReactComponent { const data = dataSet[0]; const lineGen = createLineGenerator(xScale, yScale); var validData = data.filter(d => { - var valid = true; Object.keys(data[0]).map(key => { - if (!d[key] || Number.isNaN(d[key])) valid = false; + if (!d[key] || Number.isNaN(d[key])) return false; }); - return valid; + return true; }); + + if (this._props.axes.length>2){ + var next = this._tableData.map(record => ({ x: Number(record[this._props.axes[0]]), y: Number(record[this._props.axes[2]]) })).sort((a, b) => (a.x < b.x ? -1 : 1)); + var validNext = next.filter(d => { + // Object.keys(next[0]).map(key => { + // if (!d[key] || Number.isNaN(d[key])) return false; + // }); + if (!d.x || Number.isNaN(d.x) || !d.y || Number.isNaN(d.y)) valid = false; + return true; + }); + drawLine(svg.append('path'), validNext, lineGen); + this.drawDataPoints(validNext, 0, xScale, yScale); + } + // draw the plot line drawLine(svg.append('path'), validData, lineGen); // draw the datapoint circle diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx index c20509029..1b239b5e5 100644 --- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx +++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx @@ -163,7 +163,7 @@ export class TableBox extends ObservableReactComponent { 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 if (newAxes.length > 2) newAxes[newAxes.length-1] = col; else newAxes.push(col); this._props.selectAxes(newAxes); } @@ -220,8 +220,15 @@ export class TableBox extends ObservableReactComponent { 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 fontWeight: 'bolder', border: '3px solid black', }} @@ -243,7 +250,10 @@ export class TableBox extends ObservableReactComponent { background: NumListCast(this._props.layoutDoc.dataViz_highlitedRows).includes(rowId) ? 'lightYellow' : NumListCast(this._props.layoutDoc.dataViz_selectedRows).includes(rowId) ? 'lightgrey' : '', }}> {this.columns.map(col => { - 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; + var colSelected = false; + if (this._props.axes.length>2) colSelected = this._props.axes[0]==col || this._props.axes[1]==col || this._props.axes[2]==col; + else if (this._props.axes.length>1) colSelected = this._props.axes[0]==col || this._props.axes[1]==col; + else if (this._props.axes.length>0) colSelected = this._props.axes[0]==col; if (this._props.titleCol==col) colSelected = true; return ( -- cgit v1.2.3-70-g09d2 From 4a0f77ae19934273a34e3a57541e7e8c4172b469 Mon Sep 17 00:00:00 2001 From: srichman333 Date: Wed, 31 Jan 2024 17:56:11 -0500 Subject: 2 lines on line charts --- .../nodes/DataVizBox/components/LineChart.tsx | 47 +++++++++++++--------- 1 file changed, 27 insertions(+), 20 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/components') diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx index 8d6671e65..dd6a6b007 100644 --- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx @@ -236,21 +236,16 @@ export class LineChart extends ObservableReactComponent { } } - // TODO: nda - can use d3.create() to create html element instead of appending drawChart = (dataSet: any[][], rangeVals: { xMin?: number; xMax?: number; yMin?: number; yMax?: number }, width: number, height: number) => { // clearing tooltip and the current chart d3.select(this._lineChartRef.current).select('svg').remove(); d3.select(this._lineChartRef.current).select('.tooltip').remove(); - const { xMin, xMax, yMin, yMax } = rangeVals; + var { xMin, xMax, yMin, yMax } = rangeVals; if (xMin === undefined || xMax === undefined || yMin === undefined || yMax === undefined) { return; } - // creating the x and y scales - const xScale = scaleCreatorNumerical(xMin, xMax, 0, width); - const yScale = scaleCreatorNumerical(0, yMax, height, 0); - // adding svg const margin = this._props.margin; const svg = (this._lineChartSvg = d3 @@ -262,15 +257,40 @@ export class LineChart extends ObservableReactComponent { .append('g') .attr('transform', `translate(${margin.left}, ${margin.top})`)); + var validSecondData; + if (this._props.axes.length>2){ // for when there are 2 lines on the chart + var next = this._tableData.map(record => ({ x: Number(record[this._props.axes[0]]), y: Number(record[this._props.axes[2]]) })).sort((a, b) => (a.x < b.x ? -1 : 1)); + validSecondData = next.filter(d => { + if (!d.x || Number.isNaN(d.x) || !d.y || Number.isNaN(d.y)) return false; + return true; + }); + var secondDataRange = minMaxRange([validSecondData]); + if (secondDataRange.xMax!>xMax) xMax = secondDataRange.xMax; + if (secondDataRange.yMax!>yMax) yMax = secondDataRange.yMax; + if (secondDataRange.xMin! { Object.keys(data[0]).map(key => { if (!d[key] || Number.isNaN(d[key])) return false; @@ -278,19 +298,6 @@ export class LineChart extends ObservableReactComponent { return true; }); - if (this._props.axes.length>2){ - var next = this._tableData.map(record => ({ x: Number(record[this._props.axes[0]]), y: Number(record[this._props.axes[2]]) })).sort((a, b) => (a.x < b.x ? -1 : 1)); - var validNext = next.filter(d => { - // Object.keys(next[0]).map(key => { - // if (!d[key] || Number.isNaN(d[key])) return false; - // }); - if (!d.x || Number.isNaN(d.x) || !d.y || Number.isNaN(d.y)) valid = false; - return true; - }); - drawLine(svg.append('path'), validNext, lineGen); - this.drawDataPoints(validNext, 0, xScale, yScale); - } - // draw the plot line drawLine(svg.append('path'), validData, lineGen); // draw the datapoint circle -- cgit v1.2.3-70-g09d2 From a1939f7547413aa97c8d8967f57b4bb5aea0cdef Mon Sep 17 00:00:00 2001 From: srichman333 Date: Thu, 1 Feb 2024 00:15:05 -0500 Subject: 2 lines on line chart have a legend --- .../nodes/DataVizBox/components/LineChart.tsx | 34 ++++++++++++++++++---- src/client/views/nodes/DataVizBox/utils/D3Utils.ts | 4 +-- 2 files changed, 30 insertions(+), 8 deletions(-) (limited to 'src/client/views/nodes/DataVizBox/components') diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx index dd6a6b007..8268d22b6 100644 --- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx @@ -269,8 +269,6 @@ export class LineChart extends ObservableReactComponent { if (secondDataRange.yMax!>yMax) yMax = secondDataRange.yMax; if (secondDataRange.xMin! { yAxisCreator(svg.append('g'), width, yScale); if (validSecondData) { - drawLine(svg.append('path'), validSecondData, lineGen); + drawLine(svg.append('path'), validSecondData, lineGen, true); this.drawDataPoints(validSecondData, 0, xScale, yScale); + svg.append('path').attr("stroke", "red"); + + // legend + var color = d3.scaleOrdinal() + .range(["black", "blue"]) + .domain([this._props.axes[1], this._props.axes[2]]) + svg.selectAll("mydots") + .data([this._props.axes[1], this._props.axes[2]]) + .enter() + .append("circle") + .attr("cx", 5) + .attr("cy", function(d,i){ return -30 + i*15}) + .attr("r", 7) + .style("fill", function(d){ return color(d)}) + svg.selectAll("mylabels") + .data([this._props.axes[1], this._props.axes[2]]) + .enter() + .append("text") + .attr("x", 25) + .attr("y", function(d,i){ return -30 + i*15}) + .style("fill", function(d){ return color(d)}) + .text(function(d){ return d}) + .attr("text-anchor", "left") + .style("alignment-baseline", "middle") } // get valid data points @@ -299,7 +321,7 @@ export class LineChart extends ObservableReactComponent { }); // draw the plot line - drawLine(svg.append('path'), validData, lineGen); + drawLine(svg.append('path'), validData, lineGen, false); // draw the datapoint circle this.drawDataPoints(validData, 0, xScale, yScale); @@ -312,7 +334,7 @@ export class LineChart extends ObservableReactComponent { const xPos = d3.pointer(e)[0]; const x0 = Math.min(data.length - 1, bisect(data, xScale.invert(xPos - 5))); // shift x by -5 so that you can reach points on the left-side axis const d0 = data[x0]; - if (!d0) return; + if (d0) this.updateTooltip(higlightFocusPt, xScale, d0, yScale, tooltip); this.updateTooltip(higlightFocusPt, xScale, d0, yScale, tooltip); }); @@ -348,7 +370,7 @@ export class LineChart extends ObservableReactComponent { svg.append('text') .attr('transform', 'rotate(-90)' + ' ' + 'translate( 0, ' + -10 + ')') .attr('x', -(height / 2)) - .attr('y', -20) + .attr('y', -30) .attr('height', 20) .attr('width', 20) .style('text-anchor', 'middle') diff --git a/src/client/views/nodes/DataVizBox/utils/D3Utils.ts b/src/client/views/nodes/DataVizBox/utils/D3Utils.ts index 10bfb0c64..336935d23 100644 --- a/src/client/views/nodes/DataVizBox/utils/D3Utils.ts +++ b/src/client/views/nodes/DataVizBox/utils/D3Utils.ts @@ -61,6 +61,6 @@ export const yGrid = (g: d3.Selection, wi ); }; -export const drawLine = (p: d3.Selection, dataPts: DataPoint[], lineGen: d3.Line) => { - p.datum(dataPts).attr('fill', 'none').attr('stroke', 'rgba(53, 162, 235, 0.5)').attr('stroke-width', 2).attr('class', 'line').attr('d', lineGen); +export const drawLine = (p: d3.Selection, dataPts: DataPoint[], lineGen: d3.Line, extra: boolean) => { + p.datum(dataPts).attr('fill', 'none').attr('stroke', 'rgba(53, 162, 235, 0.5)').attr('stroke-width', 2).attr('stroke', extra? 'blue' : 'black').attr('class', 'line').attr('d', lineGen); }; -- cgit v1.2.3-70-g09d2