From fa98e9f411ed19a752a912e42b6ed9607d151159 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 25 Aug 2023 01:55:09 -0400
Subject: optimizations to speed up pie/table viz

---
 .../nodes/DataVizBox/components/Histogram.tsx      | 164 +++++++++------------
 1 file changed, 69 insertions(+), 95 deletions(-)

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

diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
index b3bdccbbb..48cbe5c5f 100644
--- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx
+++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
@@ -1,26 +1,26 @@
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { ColorPicker, EditableText, IconButton, Size, Type } from 'browndash-components';
+import * as d3 from 'd3';
+import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
-import { Doc, StrListCast } from '../../../../../fields/Doc';
 import * as React from 'react';
-import * as d3 from 'd3';
-import { IReactionDisposer, action, computed, observable, reaction } from 'mobx';
-import { LinkManager } from '../../../../util/LinkManager';
-import { Cast, DocCast, StrCast } from '../../../../../fields/Types';
-import { PinProps, PresBox } from '../../trails';
-import { Docs } from '../../../../documents/Documents';
-import { List } from '../../../../../fields/List';
-import './Chart.scss';
-import { ColorPicker, EditableText, IconButton, Size, Type } from 'browndash-components';
 import { FaFillDrip } from 'react-icons/fa';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Doc, 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 { LinkManager } from '../../../../util/LinkManager';
+import { undoable } from '../../../../util/UndoManager';
+import { PinProps, PresBox } from '../../trails';
 import { scaleCreatorNumerical, yAxisCreator } from '../utils/D3Utils';
-import { undoBatch, undoable } from '../../../../util/UndoManager';
+import './Chart.scss';
 
 export interface HistogramProps {
     rootDoc: Doc;
     layoutDoc: Doc;
     axes: string[];
-    pairs: { [key: string]: any }[];
+    records: { [key: string]: any }[];
     width: number;
     height: number;
     dataDoc: Doc;
@@ -48,41 +48,41 @@ export class Histogram extends React.Component<HistogramProps> {
 
     // filters all data to just display selected data if brushed (created from an incoming link)
     @computed get _histogramData() {
-        var guids = StrListCast(this.props.layoutDoc.dataViz_rowGuids);
+        var guids = StrListCast(this.props.layoutDoc.dataViz_rowIds);
         if (this.props.axes.length < 1) return [];
         if (this.props.axes.length < 2) {
             var ax0 = this.props.axes[0];
-            if (/\d/.test(this.props.pairs[0][ax0])) {
+            if (/\d/.test(this.props.records[0][ax0])) {
                 this.numericalXData = true;
             }
-            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 => ({ [ax0]: pair[this.props.axes[0]] }));
+            return this.props.records
+                ?.filter(record => (!this.incomingLinks.length ? true : this.incomingLinks[0]!.dataViz_selectedRows && StrListCast(this.incomingLinks[0].dataViz_selectedRows).includes(guids[this.props.records.indexOf(record)])))
+                .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.pairs[0][ax0])) {
+        if (/\d/.test(this.props.records[0][ax0])) {
             this.numericalXData = true;
         }
-        if (/\d/.test(this.props.pairs[0][ax1])) {
+        if (/\d/.test(this.props.records[0][ax1])) {
             this.numericalYData = true;
         }
-        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 => ({ [ax0]: pair[this.props.axes[0]], [ax1]: pair[this.props.axes[1]] }));
+        return this.props.records
+            ?.filter(record => (!this.incomingLinks.length ? true : this.incomingLinks[0]!.dataViz_selectedRows && StrListCast(this.incomingLinks[0].dataViz_selectedRows).includes(guids[this.props.records.indexOf(record)])))
+            .map(record => ({ [ax0]: record[this.props.axes[0]], [ax1]: record[this.props.axes[1]] }));
     }
 
     @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 || !ax1 || !/\d/.test(this.props.pairs[0][ax1]) || !this.numericalYData) {
+        if (this.props.axes.length < 2 || !ax1 || !/\d/.test(this.props.records[0][ax1]) || !this.numericalYData) {
             return ax0 + ' Histogram';
         } else return ax0 + ' by ' + ax1 + ' Histogram';
     }
 
     @computed get incomingLinks() {
         return LinkManager.Instance.getAllRelatedLinks(this.props.rootDoc) // out of all links
-            .filter(link => link.link_anchor_1 == this.props.rootDoc.draggedFrom) // get links where this chart doc is the target of the link
+            .filter(link => 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
     }
 
@@ -100,11 +100,7 @@ export class Histogram extends React.Component<HistogramProps> {
     componentDidMount = () => {
         this._disposers.chartData = reaction(
             () => ({ dataSet: this._histogramData, w: this.width, h: this.height }),
-            ({ dataSet, w, h }) => {
-                if (dataSet!.length > 0) {
-                    this.drawChart(dataSet, w, h);
-                }
-            },
+            ({ dataSet, w, h }) => dataSet!.length > 0 && this.drawChart(dataSet, w, h),
             { fireImmediately: true }
         );
     };
@@ -114,7 +110,6 @@ export class Histogram extends React.Component<HistogramProps> {
     // create a document anchor that stores whatever is needed to reconstruct the viewing state (selection,zoom,etc)
     getAnchor = (pinProps?: PinProps) => {
         const anchor = Docs.Create.ConfigDocument({
-            //
             title: 'histogram doc selection' + this._currSelected,
         });
         PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this.props.rootDoc);
@@ -131,21 +126,15 @@ export class Histogram extends React.Component<HistogramProps> {
 
     // cleans data by converting numerical data to numbers and taking out empty cells
     data = (dataSet: any) => {
-        var validData = dataSet.filter((d: { [x: string]: unknown }) => {
-            var valid = true;
-            Object.keys(dataSet[0]).map(key => {
-                if (!d[key] || Number.isNaN(d[key])) valid = false;
-            });
-            return valid;
-        });
-        var field = dataSet[0] ? Object.keys(dataSet[0])[0] : undefined;
-        const data = validData.map((d: { [x: string]: any }) => {
-            if (this.numericalXData) {
-                return +d[field!].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '');
-            }
-            return d[field!];
-        });
-        return data;
+        var validData = dataSet.filter((d: { [x: string]: unknown }) => !Object.keys(dataSet[0]).some(key => !d[key] || Number.isNaN(d[key])));
+        const field = dataSet[0] ? Object.keys(dataSet[0])[0] : undefined;
+        return !field
+            ? []
+            : validData.map((d: { [x: string]: any }) =>
+                  !this.numericalXData //
+                      ? d[field]
+                      : +d[field!].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '')
+              );
     };
 
     // outlines the bar selected / hovered over
@@ -185,24 +174,18 @@ export class Histogram extends React.Component<HistogramProps> {
         d3.select(this._histogramRef.current).select('svg').remove();
         d3.select(this._histogramRef.current).select('.tooltip').remove();
 
-        var data = this.data(dataSet);
-        var xAxisTitle = Object.keys(dataSet[0])[0];
-        var yAxisTitle = this.numericalYData ? Object.keys(dataSet[0])[1] : 'frequency';
-        let uniqueArr: unknown[] = [...new Set(data)];
+        const data = this.data(dataSet);
+        const xAxisTitle = Object.keys(dataSet[0])[0];
+        const yAxisTitle = this.numericalYData ? Object.keys(dataSet[0])[1] : 'frequency';
+        const uniqueArr: unknown[] = [...new Set(data)];
         var numBins = this.numericalXData && Number.isInteger(data[0]) ? this.rangeVals.xMax! - this.rangeVals.xMin! : uniqueArr.length;
         var translateXAxis = !this.numericalXData || numBins < this.maxBins ? width / (numBins + 1) / 2 : 0;
         if (numBins > this.maxBins) numBins = this.maxBins;
-        var startingPoint = this.numericalXData ? this.rangeVals.xMin! : 0;
-        var endingPoint = this.numericalXData ? this.rangeVals.xMax! : numBins;
+        const startingPoint = this.numericalXData ? this.rangeVals.xMin! : 0;
+        const endingPoint = this.numericalXData ? this.rangeVals.xMax! : numBins;
 
         // converts data into Objects
-        var histDataSet = dataSet.filter((d: { [x: string]: unknown }) => {
-            var valid = true;
-            Object.keys(dataSet[0]).map(key => {
-                if (!d[key] || Number.isNaN(d[key])) valid = false;
-            });
-            return valid;
-        });
+        var histDataSet = dataSet.filter((d: { [x: string]: unknown }) => !Object.keys(dataSet[0]).some(key => !d[key] || Number.isNaN(d[key])));
         if (!this.numericalXData) {
             var histStringDataSet: { [x: string]: unknown }[] = [];
             if (this.numericalYData) {
@@ -321,7 +304,7 @@ export class Histogram extends React.Component<HistogramProps> {
         // click/hover
         const onPointClick = action((e: any) => this.highlightSelectedBar(true, svg, eachRectWidth, d3.pointer(e)[0], xAxisTitle, yAxisTitle, histDataSet));
         const onHover = action((e: any) => {
-            const selected = this.highlightSelectedBar(false, svg, eachRectWidth, d3.pointer(e)[0], xAxisTitle, yAxisTitle, histDataSet);
+            this.highlightSelectedBar(false, svg, eachRectWidth, d3.pointer(e)[0], xAxisTitle, yAxisTitle, histDataSet);
             updateHighlights();
         });
         const mouseOut = action((e: any) => {
@@ -360,10 +343,10 @@ export class Histogram extends React.Component<HistogramProps> {
                 'transform',
                 this.numericalYData
                     ? function (d) {
-                          var eachData = histDataSet.filter((data: { [x: string]: number }) => {
+                          const eachData = histDataSet.filter((data: { [x: string]: number }) => {
                               return data[xAxisTitle] == d[0];
                           });
-                          var length = eachData.length ? eachData[0][yAxisTitle].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '') : 0;
+                          const length = eachData.length ? eachData[0][yAxisTitle].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '') : 0;
                           return 'translate(' + x(d.x0!) + ',' + y(length) + ')';
                       }
                     : function (d) {
@@ -374,10 +357,10 @@ export class Histogram extends React.Component<HistogramProps> {
                 'height',
                 this.numericalYData
                     ? function (d) {
-                          var eachData = histDataSet.filter((data: { [x: string]: number }) => {
+                          const eachData = histDataSet.filter((data: { [x: string]: number }) => {
                               return data[xAxisTitle] == d[0];
                           });
-                          var length = eachData.length ? eachData[0][yAxisTitle].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '') : 0;
+                          const length = eachData.length ? eachData[0][yAxisTitle].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '') : 0;
                           return height - y(length);
                       }
                     : function (d) {
@@ -389,7 +372,7 @@ export class Histogram extends React.Component<HistogramProps> {
                 'class',
                 selected
                     ? function (d) {
-                          return selected && selected[0] == d[0] ? 'histogram-bar hover' : 'histogram-bar';
+                          return selected && selected[0] === d[0] ? 'histogram-bar hover' : 'histogram-bar';
                       }
                     : function (d) {
                           return 'histogram-bar';
@@ -397,11 +380,11 @@ export class Histogram extends React.Component<HistogramProps> {
             )
             .attr('fill', d => {
                 var barColor;
-                var barColors = StrListCast(this.props.layoutDoc.histogramBarColors).map(each => each.split('::'));
-                barColors.map(each => {
+                const barColors = StrListCast(this.props.layoutDoc.histogramBarColors).map(each => each.split('::'));
+                barColors.forEach(each => {
                     if (d[0] && d[0].toString() && each[0] == d[0].toString()) barColor = each[1];
                     else {
-                        var range = StrCast(each[0]).split(' to ');
+                        const range = StrCast(each[0]).split(' to ');
                         if (Number(range[0]) <= d[0] && d[0] <= Number(range[1])) barColor = each[1];
                     }
                 });
@@ -411,23 +394,19 @@ export class Histogram extends React.Component<HistogramProps> {
 
     @action changeSelectedColor = (color: string) => {
         this.curBarSelected.attr('fill', color);
-        var barName = StrCast(this._currSelected[this.props.axes[0]].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, ''));
+        const barName = StrCast(this._currSelected[this.props.axes[0]].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, ''));
 
         const barColors = Cast(this.props.layoutDoc.histogramBarColors, listSpec('string'), null);
-        barColors.map(each => {
-            if (each.split('::')[0] == barName) barColors.splice(barColors.indexOf(each), 1);
-        });
+        barColors.forEach(each => each.split('::')[0] === barName && barColors.splice(barColors.indexOf(each), 1));
         barColors.push(StrCast(barName + '::' + color));
     };
 
     @action eraseSelectedColor = () => {
         this.curBarSelected.attr('fill', this.props.layoutDoc.defaultHistogramColor);
-        var barName = StrCast(this._currSelected[this.props.axes[0]].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, ''));
+        const barName = StrCast(this._currSelected[this.props.axes[0]].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, ''));
 
         const barColors = Cast(this.props.layoutDoc.histogramBarColors, listSpec('string'), null);
-        barColors.map(each => {
-            if (each.split('::')[0] == barName) barColors.splice(barColors.indexOf(each), 1);
-        });
+        barColors.forEach(each => each.split('::')[0] === barName && barColors.splice(barColors.indexOf(each), 1));
     };
 
     render() {
@@ -439,25 +418,22 @@ export class Histogram extends React.Component<HistogramProps> {
         if (!this.props.layoutDoc[titleAccessor]) this.props.layoutDoc[titleAccessor] = this.defaultGraphTitle;
         if (!this.props.layoutDoc.defaultHistogramColor) this.props.layoutDoc.defaultHistogramColor = '#69b3a2';
         if (!this.props.layoutDoc.histogramBarColors) this.props.layoutDoc.histogramBarColors = new List<string>();
-        var selected: string;
+        var selected = 'none';
         if (this._currSelected) {
             curSelectedBarName = StrCast(this._currSelected![this.props.axes[0]].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, ''));
             selected = '{ ';
-            Object.keys(this._currSelected).map(key => {
-                key != '' ? (selected += key + ': ' + this._currSelected[key] + ', ') : '';
-            });
-            selected = selected.substring(0, selected.length - 2);
-            selected += ' }';
-        } else selected = 'none';
+            Object.keys(this._currSelected).forEach(key =>
+                key //
+                    ? (selected += key + ': ' + this._currSelected[key] + ', ')
+                    : ''
+            );
+            selected = selected.substring(0, selected.length - 2) + ' }';
+        }
         var selectedBarColor;
         var barColors = StrListCast(this.props.layoutDoc.histogramBarColors).map(each => each.split('::'));
-        barColors.map(each => {
-            if (each[0] == curSelectedBarName!) selectedBarColor = each[1];
-        });
+        barColors.forEach(each => each[0] === curSelectedBarName && (selectedBarColor = each[1]));
 
-        this.componentDidMount();
-
-        if (this._histogramData.length > 0 || (!this.incomingLinks || this.incomingLinks.length==0)) {
+        if (this._histogramData.length > 0 || !this.incomingLinks || this.incomingLinks.length == 0) {
             return this.props.axes.length >= 1 ? (
                 <div className="chart-container">
                     <div className="graph-title">
@@ -514,10 +490,8 @@ export class Histogram extends React.Component<HistogramProps> {
             ) : (
                 <span className="chart-container"> {'first use table view to select a column to graph'}</span>
             );
-        } else
-            return (
-                // when it is a brushed table and the incoming table doesn't have any rows selected
-                <div className="chart-container">Selected rows of data from the incoming DataVizBox to display.</div>
-            );
+        }
+        // when it is a brushed table and the incoming table doesn't have any rows selected
+        return <div className="chart-container">Selected rows of data from the incoming DataVizBox to display.</div>;
     }
-}
\ No newline at end of file
+}
-- 
cgit v1.2.3-70-g09d2


From 6f2fc57f29a90b02dad0bc98c20ec69ef90c39ef Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 25 Aug 2023 11:58:14 -0400
Subject: simplification of vizBoxes to use parentViz instead of going through
 links

---
 .../nodes/DataVizBox/components/Histogram.tsx      | 29 +++++++++--------
 .../nodes/DataVizBox/components/LineChart.tsx      | 36 ++++++++++++----------
 .../views/nodes/DataVizBox/components/PieChart.tsx | 15 ++++-----
 .../views/nodes/DataVizBox/components/TableBox.tsx | 15 ++++-----
 4 files changed, 51 insertions(+), 44 deletions(-)

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

diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
index 48cbe5c5f..50facf03e 100644
--- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx
+++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
@@ -5,7 +5,7 @@ import { action, computed, IReactionDisposer, observable, reaction } from 'mobx'
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { FaFillDrip } from 'react-icons/fa';
-import { Doc, StrListCast } from '../../../../../fields/Doc';
+import { Doc, NumListCast, StrListCast } from '../../../../../fields/Doc';
 import { List } from '../../../../../fields/List';
 import { listSpec } from '../../../../../fields/Schema';
 import { Cast, DocCast, StrCast } from '../../../../../fields/Types';
@@ -46,18 +46,22 @@ export class Histogram extends React.Component<HistogramProps> {
     private selectedData: any = undefined; // Selection of selected bar
     private hoverOverData: any = undefined; // Selection of bar being hovered over
 
+    @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]);
+    }
     // filters all data to just display selected data if brushed (created from an incoming link)
     @computed get _histogramData() {
-        var guids = StrListCast(this.props.layoutDoc.dataViz_rowIds);
         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])) {
                 this.numericalXData = true;
             }
-            return this.props.records
-                ?.filter(record => (!this.incomingLinks.length ? true : this.incomingLinks[0]!.dataViz_selectedRows && StrListCast(this.incomingLinks[0].dataViz_selectedRows).includes(guids[this.props.records.indexOf(record)])))
-                .map(record => ({ [ax0]: record[this.props.axes[0]] }));
+            return this._tableData.map(record => ({ [ax0]: record[this.props.axes[0]] }));
         }
         var ax0 = this.props.axes[0];
         var ax1 = this.props.axes[1];
@@ -67,9 +71,7 @@ export class Histogram extends React.Component<HistogramProps> {
         if (/\d/.test(this.props.records[0][ax1])) {
             this.numericalYData = true;
         }
-        return this.props.records
-            ?.filter(record => (!this.incomingLinks.length ? true : this.incomingLinks[0]!.dataViz_selectedRows && StrListCast(this.incomingLinks[0].dataViz_selectedRows).includes(guids[this.props.records.indexOf(record)])))
-            .map(record => ({ [ax0]: record[this.props.axes[0]], [ax1]: record[this.props.axes[1]] }));
+        return this._tableData.map(record => ({ [ax0]: record[this.props.axes[0]], [ax1]: record[this.props.axes[1]] }));
     }
 
     @computed get defaultGraphTitle() {
@@ -80,10 +82,11 @@ export class Histogram extends React.Component<HistogramProps> {
         } else return ax0 + ' by ' + ax1 + ' Histogram';
     }
 
-    @computed get incomingLinks() {
-        return LinkManager.Instance.getAllRelatedLinks(this.props.rootDoc) // out of all links
-            .filter(link => 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 parentViz() {
+        return DocCast(this.props.rootDoc.dataViz_parentViz);
+        // return LinkManager.Instance.getAllRelatedLinks(this.props.rootDoc) // out of all links
+        //     .filter(link => 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 rangeVals(): { xMin?: number; xMax?: number; yMin?: number; yMax?: number } {
@@ -433,7 +436,7 @@ export class Histogram extends React.Component<HistogramProps> {
         var barColors = StrListCast(this.props.layoutDoc.histogramBarColors).map(each => each.split('::'));
         barColors.forEach(each => each[0] === curSelectedBarName && (selectedBarColor = each[1]));
 
-        if (this._histogramData.length > 0 || !this.incomingLinks || this.incomingLinks.length == 0) {
+        if (this._histogramData.length > 0 || !this.parentViz) {
             return this.props.axes.length >= 1 ? (
                 <div className="chart-container">
                     <div className="graph-title">
diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx
index 655c6de20..3ef2bd8b0 100644
--- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx
+++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx
@@ -2,7 +2,7 @@ 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 { Doc, DocListCast, NumListCast, StrListCast } from '../../../../../fields/Doc';
 import { Id } from '../../../../../fields/FieldSymbols';
 import { List } from '../../../../../fields/List';
 import { listSpec } from '../../../../../fields/Schema';
@@ -49,32 +49,34 @@ 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_rowIds);
         if (this.props.axes.length <= 1) return [];
-        return this.props.records
-            ?.filter(record => (!this.incomingLinks.length ? true : this.incomingLinks[0]!.dataViz_selectedRows && StrListCast(this.incomingLinks[0].dataViz_selectedRows).includes(guids[this.props.records.indexOf(record)])))
-            .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));
+        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.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 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() {
         // 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.records?.filter(record => record['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;
+        return incomingVizBox.records?.filter(record => record['select' + incomingVizBox.rootDoc[Id]]); // 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]);
@@ -358,7 +360,7 @@ export class LineChart extends React.Component<LineChartProps> {
         else if (this.props.axes.length > 0) titleAccessor = 'dataViz_title_lineChart_' + 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) {
+        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">
diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
index 79d7b3f23..a8aa51897 100644
--- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx
+++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
@@ -42,11 +42,11 @@ export class PieChart extends React.Component<PieChartProps> {
     @observable _currSelected: any | undefined = undefined; // Object of selected slice
 
     @computed get _tableDataIds() {
-        return !this.incomingLinks.length ? this.props.records.map((rec, i) => i) : NumListCast(this.incomingLinks[0].dataViz_selectedRows);
+        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.incomingLinks.length ? this.props.records : this._tableDataIds.map(rowId => this.props.records[rowId]);
+        return !this.parentViz ? this.props.records : this._tableDataIds.map(rowId => this.props.records[rowId]);
     }
 
     // organized by specified number percentages/ratios if one column is selected and it contains numbers
@@ -78,10 +78,11 @@ export class PieChart extends React.Component<PieChartProps> {
         return ax1 + ' by ' + ax0 + ' Pie Chart';
     }
 
-    @computed get incomingLinks() {
-        return LinkManager.Instance.getAllRelatedLinks(this.props.rootDoc) // out of all links
-            .filter(link => 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 parentViz() {
+        return DocCast(this.props.rootDoc.dataViz_parentViz);
+        // return LinkManager.Instance.getAllRelatedLinks(this.props.rootDoc) // out of all links
+        //     .filter(link => 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
     }
 
     componentWillUnmount() {
@@ -343,7 +344,7 @@ export class PieChart extends React.Component<PieChartProps> {
             if (each[0] == curSelectedSliceName!) selectedSliceColor = each[1];
         });
 
-        if (this._piechartData.length > 0 || !this.incomingLinks || this.incomingLinks.length == 0) {
+        if (this._piechartData.length > 0 || !this.parentViz) {
             return this.props.axes.length >= 1 ? (
                 <div className="chart-container">
                     <div className="graph-title">
diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
index e90b541ae..7bca08c15 100644
--- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx
+++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
@@ -41,17 +41,18 @@ export class TableBox extends React.Component<TableBoxProps> {
         this._inputChangedDisposer?.();
     }
     @computed get _tableDataIds() {
-        return !this.incomingLinks.length ? this.props.records.map((rec, i) => i) : NumListCast(this.incomingLinks[0].dataViz_selectedRows);
+        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.incomingLinks.length ? this.props.records : this._tableDataIds.map(rowId => this.props.records[rowId]);
+        return !this.parentViz ? this.props.records : this._tableDataIds.map(rowId => this.props.records[rowId]);
     }
 
-    @computed get incomingLinks() {
-        return LinkManager.Instance.getAllRelatedLinks(this.props.rootDoc) // out of all links
-            .filter(link => 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 parentViz() {
+        return DocCast(this.props.rootDoc.dataViz_parentViz);
+        // return LinkManager.Instance.getAllRelatedLinks(this.props.rootDoc) // out of all links
+        //     .filter(link => 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 columns() {
@@ -105,7 +106,7 @@ export class TableBox extends React.Component<TableBoxProps> {
                                                         const embedding = Doc.MakeEmbedding(this.props.docView?.()!.rootDoc!);
                                                         embedding._dataViz = DataVizView.TABLE;
                                                         embedding._dataViz_axes = new List<string>([col, col]);
-                                                        embedding._dataViz_parentViz = this.props.docView?.()!.rootDoc!;
+                                                        embedding._dataViz_parentViz = this.props.rootDoc;
                                                         embedding.annotationOn = annotationOn; //this.props.docView?.()!.rootDoc!;
                                                         embedding.histogramBarColors = Field.Copy(this.props.layoutDoc.histogramBarColors);
                                                         embedding.defaultHistogramColor = this.props.layoutDoc.defaultHistogramColor;
-- 
cgit v1.2.3-70-g09d2

