diff options
Diffstat (limited to 'src')
3 files changed, 67 insertions, 60 deletions
diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx index 1fc33396a..2152df8a1 100644 --- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx +++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx @@ -44,7 +44,6 @@ export class Histogram extends ObservableReactComponent<HistogramProps> { private maxBins = 15; // maximum number of bins that is readable on a normal sized doc @observable _currSelected: any | undefined = undefined; // Object of selected bar private curBarSelected: any = undefined; // histogram bin of selected bar for when just one bar is selected - // private selectedData: any = undefined; // Selection of selected bar private selectedData: any[] = []; // array of selected bars private hoverOverData: any = undefined; // Selection of bar being hovered over diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx index e093ec648..11d117b29 100644 --- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx @@ -48,6 +48,8 @@ export class LineChart extends ObservableReactComponent<LineChartProps> { private _lineChartRef: React.RefObject<HTMLDivElement> = React.createRef(); private _lineChartSvg: d3.Selection<SVGGElement, unknown, null, undefined> | undefined; @observable _currSelected: any | undefined = undefined; + private selectedData: any[] = []; // array of selected data points + // 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); @@ -71,11 +73,6 @@ export class LineChart extends ObservableReactComponent<LineChartProps> { } @computed get parentViz() { return DocCast(this._props.Document.dataViz_parentViz); - // return LinkManager.Instance.getAllRelatedLinks(this._props.Document) // out of all links - // .filter(link => { - // return 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 incomingHighlited() { // return selected x and y axes @@ -91,6 +88,7 @@ export class LineChart extends ObservableReactComponent<LineChartProps> { Array.from(Object.keys(this._disposers)).forEach(key => this._disposers[key]()); } componentDidMount() { + // draw chart this._disposers.chartData = reaction( () => ({ dataSet: this._lineChartData, w: this.width, h: this.height }), ({ dataSet, w, h }) => { @@ -100,31 +98,23 @@ export class LineChart extends ObservableReactComponent<LineChartProps> { }, { fireImmediately: true } ); - this._disposers.annos = reaction( - () => DocListCast(this._props.dataDoc[this._props.fieldKey + '_annotations']), - annotations => { - // modify how d3 renders so that anything in this annotations list would be potentially highlighted in some way - // 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))); - // this.drawAnnotations(annotations.x, annotations.y); - }, - { fireImmediately: true } - ); - this._disposers.highlights = reaction( - () => ({ - selected: this._currSelected, - incomingHighlited: this.incomingHighlited, - }), - ({ 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); - incomingHighlited?.forEach((record: any) => this.drawAnnotations(Number(record[this._props.axes[0]]), Number(record[this._props.axes[1]]))); - }, - { fireImmediately: true } - ); + + // coloring the selected point + const elements = document.querySelectorAll('.datapoint'); + for (let i = 0; i < elements.length; i++) { + const x = Number(elements[i].getAttribute('data-x')); + const y = Number(elements[i].getAttribute('data-y')); + const selectedDataBars = StrListCast(this._props.layoutDoc.dataViz_lineChart_selectedData) + let selected = false; + selectedDataBars.forEach(eachSelectedData => { + // parse each selected point into x,y + let xy = eachSelectedData.split(','); + if (Number(xy[0])===x && Number(xy[1])===y) selected = true; + }) + if (selected) { + this.drawAnnotations(x, y, false); + } + } } // anything that doesn't need to be recalculated should just be stored as drawCharts (i.e. computed values) and drawChart is gonna iterate over these observables and generate svgs based on that @@ -137,12 +127,9 @@ export class LineChart extends ObservableReactComponent<LineChartProps> { element.classList.remove('selected'); } }; - // gets called whenever the "data_annotations" fields gets updated + + // draws red annotation on data points when selected drawAnnotations = (dataX: number, dataY: number, selected?: boolean) => { - // TODO: nda - can optimize this by having some sort of mapping of the x and y values to the individual circle elements - // loop through all html elements with class .circle-d1 and find the one that has "data-x" and "data-y" attributes that match the dataX and dataY - // if it exists, then highlight it - // if it doesn't exist, then remove the highlight const elements = document.querySelectorAll('.datapoint'); for (let i = 0; i < elements.length; i++) { const element = elements[i]; @@ -151,25 +138,11 @@ export class LineChart extends ObservableReactComponent<LineChartProps> { if (x === dataX.toString() && y === dataY.toString()) { element.classList.add(selected ? 'selected' : 'brushed'); } - // TODO: nda - this remove highlight code should go where we remove the links - // } else { - // } } }; @action - restoreView = (data: Doc) => { - const coords = Cast(data.config_dataVizSelection, listSpec('number'), null); - if (coords?.length > 1 && (this._currSelected?.x !== coords[0] || this._currSelected?.y !== coords[1])) { - this.setCurrSelected(coords[0], coords[1]); - return true; - } - if (this._currSelected) { - this.setCurrSelected(); - return true; - } - return false; - }; + restoreView = (data: Doc) => {}; // create a document anchor that stores whatever is needed to reconstruct the viewing state (selection,zoom,etc) getAnchor = (pinProps?: PinProps) => { @@ -211,13 +184,48 @@ export class LineChart extends ObservableReactComponent<LineChartProps> { .style('font-size', '12px'); } - // TODO: nda - use this everyewhere we update currSelected? @action - setCurrSelected(x?: number, y?: number) { - // 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.records.forEach(record => record[this._props.axes[0]] === x && record[this._props.axes[1]] === y && (record.selected = true)); + setCurrSelected(d: DataPoint) { + let sameAsAny = false; + const selectedDatapoints = Cast(this._props.layoutDoc.dataViz_lineChart_selectedData, listSpec('string'), null); + this.selectedData.forEach(eachData => { + if (!sameAsAny){ + if (eachData.x==d.x && eachData.y==d.y) { + sameAsAny = true; + let index = this.selectedData.indexOf(eachData) + this.selectedData.splice(index, 1); + selectedDatapoints.splice(index, 1); + this._currSelected = undefined; + } + } + }) + if(!sameAsAny) { + this.selectedData.push(d); + selectedDatapoints.push(d.x + "," + d.y); + this._currSelected = this.selectedData.length>1? undefined : d; + } + + // for filtering child dataviz docs + if (this._props.layoutDoc.dataViz_filterSelection){ + const selectedRows = Cast(this._props.layoutDoc.dataViz_selectedRows, listSpec('number'), null); + this._tableDataIds.forEach(rowID => { + if (this._props.records[rowID][this._props.axes[0]]==d.x && this._props.records[rowID][this._props.axes[1]]==d.y) { + if (!selectedRows?.includes(rowID)) selectedRows?.push(rowID); // adding to filtered rows + else if (sameAsAny) selectedRows.splice(selectedRows.indexOf(rowID), 1); // removing from filtered rows + } + }) + } + + // coloring the selected point + const elements = document.querySelectorAll('.datapoint'); + for (let i = 0; i < elements.length; i++) { + const x = Number(elements[i].getAttribute('data-x')); + const y = Number(elements[i].getAttribute('data-y')); + if (x===d.x && y===d.y) { + if (sameAsAny) elements[i].classList.remove('brushed'); + else elements[i].classList.add('brushed'); + } + } } drawDataPoints(data: DataPoint[], idx: number, xScale: d3.ScaleLinear<number, number, never>, yScale: d3.ScaleLinear<number, number, never>) { @@ -345,8 +353,7 @@ export class LineChart extends ObservableReactComponent<LineChartProps> { const x0 = 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]; // find .circle-d1 with data-x = d0.x and data-y = d0.y - const selected = svg.selectAll('.datapoint').filter((d: any) => d['data-x'] === d0.x && d['data-y'] === d0.y); - this.setCurrSelected(d0.x, d0.y); + this.setCurrSelected(d0); this.updateTooltip(higlightFocusPt, xScale, d0, yScale, tooltip); }); @@ -398,6 +405,7 @@ export class LineChart extends ObservableReactComponent<LineChartProps> { if (this._props.axes.length == 2) titleAccessor = titleAccessor + this._props.axes[0] + '-' + this._props.axes[1]; else if (this._props.axes.length > 0) titleAccessor = titleAccessor + this._props.axes[0]; if (!this._props.layoutDoc[titleAccessor]) this._props.layoutDoc[titleAccessor] = this.defaultGraphTitle; + if (!this._props.layoutDoc.dataViz_lineChart_selectedData) this._props.layoutDoc.dataViz_lineChart_selectedData = new List<string>(); 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){ diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx index 364a5c2ff..3819c2f82 100644 --- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx @@ -103,7 +103,7 @@ export class PieChart extends ObservableReactComponent<PieChartProps> { const selectedDataBars = StrListCast(this._props.layoutDoc.dataViz_pie_selectedData) svg.selectAll('path').attr('class', (d: any) => { let selected = false; - selectedDataBars.map(eachSelectedData => { + selectedDataBars.forEach(eachSelectedData => { if (d[key]==eachSelectedData) selected = true; }) if (selected){ |