diff options
Diffstat (limited to 'src/client/views/nodes/DataVizBox/components/LineChart.tsx')
-rw-r--r-- | src/client/views/nodes/DataVizBox/components/LineChart.tsx | 82 |
1 files changed, 37 insertions, 45 deletions
diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx index 46cf27705..3de7a0c4a 100644 --- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx @@ -1,21 +1,19 @@ +import { EditableText, Size } from 'browndash-components'; +import * as d3 from 'd3'; import { action, computed, IReactionDisposer, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import * as d3 from 'd3'; -import { Doc, DocListCast, StrListCast } from '../../../../../fields/Doc'; -import { Id } from '../../../../../fields/FieldSymbols'; +import { Doc, DocListCast, NumListCast, StrListCast } from '../../../../../fields/Doc'; import { List } from '../../../../../fields/List'; import { listSpec } from '../../../../../fields/Schema'; import { Cast, DocCast, StrCast } from '../../../../../fields/Types'; import { Docs } from '../../../../documents/Documents'; import { DocumentManager } from '../../../../util/DocumentManager'; -import { LinkManager } from '../../../../util/LinkManager'; +import { undoable } from '../../../../util/UndoManager'; import { PinProps, PresBox } from '../../trails'; import { DataVizBox } from '../DataVizBox'; import { createLineGenerator, drawLine, minMaxRange, scaleCreatorNumerical, xAxisCreator, xGrid, yAxisCreator, yGrid } from '../utils/D3Utils'; import './Chart.scss'; -import { EditableText, Size } from 'browndash-components'; -import { undoable } from '../../../../util/UndoManager'; export interface DataPoint { x: number; @@ -28,7 +26,7 @@ export interface LineChartProps { rootDoc: Doc; layoutDoc: Doc; axes: string[]; - pairs: { [key: string]: any }[]; + records: { [key: string]: any }[]; width: number; height: number; dataDoc: Doc; @@ -49,32 +47,35 @@ export class LineChart extends React.Component<LineChartProps> { @observable _currSelected: SelectedDataPoint | undefined = undefined; // TODO: nda - some sort of mapping that keeps track of the annotated points so we can easily remove when annotations list updates + @computed get _tableDataIds() { + return !this.parentViz ? this.props.records.map((rec, i) => i) : NumListCast(this.parentViz.dataViz_selectedRows); + } + // returns all the data records that will be rendered by only returning those records that have been selected by the parent visualization (or all records if there is no parent) + @computed get _tableData() { + return !this.parentViz ? this.props.records : this._tableDataIds.map(rowId => this.props.records[rowId]); + } @computed get _lineChartData() { - var guids = StrListCast(this.props.layoutDoc.dataViz_rowGuids); + var guids = StrListCast(this.props.layoutDoc.dataViz_rowIds); if (this.props.axes.length <= 1) return []; - return this.props.pairs - ?.filter(pair => (!this.incomingLinks.length ? true : this.incomingLinks[0]!.dataViz_selectedRows && StrListCast(this.incomingLinks[0].dataViz_selectedRows).includes(guids[this.props.pairs.indexOf(pair)]))) - .map(pair => ({ x: Number(pair[this.props.axes[0]]), y: Number(pair[this.props.axes[1]]) })) - .sort((a, b) => (a.x < b.x ? -1 : 1)); + return this._tableData.map(record => ({ x: Number(record[this.props.axes[0]]), y: Number(record[this.props.axes[1]]) })).sort((a, b) => (a.x < b.x ? -1 : 1)); } @computed get graphTitle() { return this.props.axes[1] + ' vs. ' + this.props.axes[0] + ' Line Chart'; } - @computed get incomingLinks() { - return LinkManager.Instance.getAllRelatedLinks(this.props.rootDoc) // out of all links - .filter(link => { - return link.link_anchor_1 == this.props.rootDoc.draggedFrom; - }) // 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 parentViz() { + return DocCast(this.props.rootDoc.dataViz_parentViz); + // return LinkManager.Instance.getAllRelatedLinks(this.props.rootDoc) // out of all links + // .filter(link => { + // return link.link_anchor_1 == this.props.rootDoc.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 incomingSelected() { + @computed get incomingHighlited() { // return selected x and y axes // otherwise, use the selection of whatever is linked to us - return this.incomingLinks // all links that are pointing to this node - .map(anchor => DocumentManager.Instance.getFirstDocumentView(anchor)?.ComponentView as DataVizBox) // get their data viz boxes - .filter(dvb => dvb) - .map(dvb => dvb.pairs?.filter(pair => pair['select' + dvb.rootDoc[Id]])) // get all the datapoints they have selected field set by incoming anchor - .lastElement(); + const incomingVizBox = DocumentManager.Instance.getFirstDocumentView(this.parentViz)?.ComponentView as DataVizBox; + const highlitedRowIds = NumListCast(incomingVizBox?.rootDoc?.dataViz_highlitedRows); + return this._tableData.filter((record, i) => highlitedRowIds.includes(this._tableDataIds[i])); // get all the datapoints they have selected field set by incoming anchor } @computed get rangeVals(): { xMin?: number; xMax?: number; yMin?: number; yMax?: number } { return minMaxRange([this._lineChartData]); @@ -88,10 +89,6 @@ export class LineChart extends React.Component<LineChartProps> { ({ dataSet, w, h }) => { if (dataSet) { this.drawChart([dataSet], this.rangeVals, w, h); - // redraw annotations when the chart data has changed, or the local or inherited selection has changed - this.clearAnnotations(); - this._currSelected && this.drawAnnotations(Number(this._currSelected.x), Number(this._currSelected.y), true); - this.incomingSelected?.forEach((pair: any) => this.drawAnnotations(Number(pair[this.props.axes[0]]), Number(pair[this.props.axes[1]]))); } }, { fireImmediately: true } @@ -103,7 +100,7 @@ export class LineChart extends React.Component<LineChartProps> { // could be blue colored to make it look like anchor // this.drawAnnotations() // loop through annotations and draw them - annotations.forEach(a => this.drawAnnotations(Number(a.x), Number(a.y))); + // annotations.forEach(a => this.drawAnnotations(Number(a.x), Number(a.y))); // this.drawAnnotations(annotations.x, annotations.y); }, { fireImmediately: true } @@ -111,13 +108,13 @@ export class LineChart extends React.Component<LineChartProps> { this._disposers.highlights = reaction( () => ({ selected: this._currSelected, - incomingSelected: this.incomingSelected, + incomingHighlited: this.incomingHighlited, }), - ({ selected, incomingSelected }) => { + ({ selected, incomingHighlited }) => { // redraw annotations when the chart data has changed, or the local or inherited selection has changed this.clearAnnotations(); selected && this.drawAnnotations(Number(selected.x), Number(selected.y), true); - incomingSelected?.forEach((pair: any) => this.drawAnnotations(Number(pair[this.props.axes[0]]), Number(pair[this.props.axes[1]]))); + incomingHighlited?.forEach((record: any) => this.drawAnnotations(Number(record[this.props.axes[0]]), Number(record[this.props.axes[1]]))); }, { fireImmediately: true } ); @@ -153,10 +150,6 @@ export class LineChart extends React.Component<LineChartProps> { } }; - removeAnnotations(dataX: number, dataY: number) { - // loop through and remove any annotations that no longer exist - } - @action restoreView = (data: Doc) => { const coords = Cast(data.config_dataVizSelection, listSpec('number'), null); @@ -193,7 +186,7 @@ export class LineChart extends React.Component<LineChartProps> { @computed get defaultGraphTitle() { var ax0 = this.props.axes[0]; var ax1 = this.props.axes.length > 1 ? this.props.axes[1] : undefined; - if (this.props.axes.length < 2 || !/\d/.test(this.props.pairs[0][ax0]) || !ax1) { + if (this.props.axes.length < 2 || !/\d/.test(this.props.records[0][ax0]) || !ax1) { return ax0 + ' Line Chart'; } else return ax1 + ' by ' + ax0 + ' Line Chart'; } @@ -217,7 +210,7 @@ export class LineChart extends React.Component<LineChartProps> { // TODO: nda - get rid of svg element in the list? if (this._currSelected && this._currSelected.x == x && this._currSelected.y == y) this._currSelected = undefined; else this._currSelected = x !== undefined && y !== undefined ? { x, y } : undefined; - this.props.pairs.forEach(pair => pair[this.props.axes[0]] === x && pair[this.props.axes[1]] === y && (pair.selected = true)); + this.props.records.forEach(record => record[this.props.axes[0]] === x && record[this.props.axes[1]] === y && (record.selected = true)); } drawDataPoints(data: DataPoint[], idx: number, xScale: d3.ScaleLinear<number, number, never>, yScale: d3.ScaleLinear<number, number, never>) { @@ -352,16 +345,15 @@ export class LineChart extends React.Component<LineChartProps> { } render() { - this.componentDidMount(); var titleAccessor: any = ''; - if (this.props.axes.length == 2) titleAccessor = 'dataViz_title_lineChart_' + this.props.axes[0] + '-' + this.props.axes[1]; - else if (this.props.axes.length > 0) titleAccessor = 'dataViz_title_lineChart_' + this.props.axes[0]; + if (this.props.axes.length == 2) titleAccessor = 'dataViz_lineChart_title' + this.props.axes[0] + '-' + this.props.axes[1]; + 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'; - if (this._lineChartData.length>0 || (!this.incomingLinks || this.incomingLinks.length==0)){ - return this.props.axes.length>=2 && /\d/.test(this.props.pairs[0][this.props.axes[0]]) && /\d/.test(this.props.pairs[0][this.props.axes[1]]) ? ( - <div className="chart-container" > - <div className="graph-title"> + 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]]) ? ( + <div className="chart-container"> + <div className="graph-title"> <EditableText val={StrCast(this.props.layoutDoc[titleAccessor])} setVal={undoable( |