diff options
Diffstat (limited to 'src/client/views/nodes/DataVizBox/components/Histogram.tsx')
-rw-r--r-- | src/client/views/nodes/DataVizBox/components/Histogram.tsx | 101 |
1 files changed, 80 insertions, 21 deletions
diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx index 6672603f3..110626923 100644 --- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx +++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx @@ -43,8 +43,8 @@ export class Histogram extends ObservableReactComponent<HistogramProps> { private numericalYData: boolean = false; // whether the y axis is controlled by provided data rather than frequency 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 - private selectedData: any = undefined; // Selection of selected bar + private curBarSelected: any = undefined; // histogram bin of selected bar for when just one bar is selected + private selectedData: any[] = []; // array of selected bars private hoverOverData: any = undefined; // Selection of bar being hovered over constructor(props: any) { @@ -104,11 +104,29 @@ export class Histogram extends ObservableReactComponent<HistogramProps> { Array.from(Object.keys(this._disposers)).forEach(key => this._disposers[key]()); } componentDidMount() { + // draw histogram this._disposers.chartData = reaction( () => ({ dataSet: this._histogramData, w: this.width, h: this.height }), ({ dataSet, w, h }) => dataSet!.length > 0 && this.drawChart(dataSet, w, h), { fireImmediately: true } ); + + // restore selected bars + var svg = this._histogramSvg; + if (svg) { + const selectedDataBars = StrListCast(this._props.layoutDoc.dataViz_histogram_selectedData) + svg.selectAll('rect').attr('class', (d: any) => { + let selected = false; + selectedDataBars.forEach(eachSelectedData => { + if (d[0]==eachSelectedData) selected = true; + }) + if (selected){ + this.selectedData.push(d); + return 'histogram-bar hover' + } + else return 'histogram-bar'; + }); + } } @action @@ -162,16 +180,49 @@ export class Histogram extends ObservableReactComponent<HistogramProps> { if (changeSelectedVariables) { // for when a bar is selected - not just hovered over sameAsCurrent = this._currSelected ? showSelected[xAxisTitle] == this._currSelected![xAxisTitle] && showSelected[yAxisTitle] == this._currSelected![yAxisTitle] : false; - this._currSelected = sameAsCurrent ? undefined : showSelected; - this.selectedData = sameAsCurrent ? undefined : d; + let sameAsAny = false; + const selectedDataBars = Cast(this._props.layoutDoc.dataViz_histogram_selectedData, listSpec('number'), null); + this.selectedData.forEach(eachData => { + if (!sameAsAny){ + let match = true; + Object.keys(d).forEach(key => { + if (d[key] != eachData[key]) match = false; + }) + if (match) { + sameAsAny = true; + let index = this.selectedData.indexOf(eachData) + this.selectedData.splice(index, 1); + selectedDataBars.splice(index, 1); + this._currSelected = undefined; + } + } + }) + if(!sameAsAny) { + this.selectedData.push(d); + selectedDataBars.push(d[0]); + this._currSelected = this.selectedData.length>1? undefined : showSelected; + } + + // 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 => { + let match = false; + for (let i=0; i<d.length; i++){ + if (this._props.records[rowID][xAxisTitle].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '') == d[i]) match = true; + } + if (match && !selectedRows?.includes(rowID)) selectedRows?.push(rowID); // adding to filtered rows + else if (match && sameAsAny) selectedRows.splice(selectedRows.indexOf(rowID), 1); // removing from filtered rows + }) + } } else this.hoverOverData = d; return true; } return false; }); if (changeSelectedVariables) { - if (sameAsCurrent!) this.curBarSelected = undefined; - else this.curBarSelected = selected; + if (this._currSelected) this.curBarSelected = selected; + else this.curBarSelected = undefined; } }; @@ -321,7 +372,11 @@ export class Histogram extends ObservableReactComponent<HistogramProps> { const hoverOverBar = this.hoverOverData; const selectedData = this.selectedData; svg.selectAll('rect').attr('class', function (d: any) { - return (hoverOverBar && hoverOverBar[0] == d[0]) || (selectedData && selectedData[0] == d[0]) ? 'histogram-bar hover' : 'histogram-bar'; + let selected = false; + selectedData.forEach(eachSelectedData => { + if (d[0]==eachSelectedData[0]) selected = true; + }) + return (hoverOverBar && hoverOverBar[0] == d[0]) || selected ? 'histogram-bar hover' : 'histogram-bar'; }); }; svg.on('click', onPointClick).on('mouseover', onHover).on('mouseout', mouseOut); @@ -352,8 +407,8 @@ export class Histogram extends ObservableReactComponent<HistogramProps> { const eachData = histDataSet.filter((data: { [x: string]: number }) => { return data[xAxisTitle] == d[0]; }); - const length = eachData.length ? eachData[0][yAxisTitle].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '') : 0; - return 'translate(' + x(d.x0!) + ',' + y(length) + ')'; + const length = eachData.length ? StrCast(eachData[0][yAxisTitle]).replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '') : 0; + return 'translate(' + x(d.x0!) + ',' + y(Number(length)) + ')'; } : function (d) { return 'translate(' + x(d.x0!) + ',' + y(d.length) + ')'; @@ -366,8 +421,8 @@ export class Histogram extends ObservableReactComponent<HistogramProps> { const eachData = histDataSet.filter((data: { [x: string]: number }) => { return data[xAxisTitle] == d[0]; }); - const length = eachData.length ? eachData[0][yAxisTitle].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '') : 0; - return height - y(length); + const length = eachData.length ? StrCast(eachData[0][yAxisTitle]).replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '') : 0; + return height - y(Number(length)); } : function (d) { return height - y(d.length); @@ -376,13 +431,13 @@ export class Histogram extends ObservableReactComponent<HistogramProps> { .attr('width', eachRectWidth) .attr( 'class', - selected - ? function (d) { - return selected && selected[0] === d[0] ? 'histogram-bar hover' : 'histogram-bar'; - } - : function (d) { - return 'histogram-bar'; - } + function (d) { + let selectThisData = false; + selected.forEach(eachSelectedData => { + if (d[0]==eachSelectedData[0]) selectThisData = true; + }) + return selectThisData ? 'histogram-bar hover' : 'histogram-bar'; + } ) .attr('fill', d => { var barColor; @@ -415,9 +470,11 @@ export class Histogram extends ObservableReactComponent<HistogramProps> { barColors.forEach(each => each.split('::')[0] === barName && barColors.splice(barColors.indexOf(each), 1)); }; - updateBarColors = () => { + // reloads the bar colors and selected bars + updateSavedUI = () => { var svg = this._histogramSvg; - if (svg) + if (svg) { + // bar color svg.selectAll('rect').attr('fill', (d: any) => { var barColor; const barColors = StrListCast(this._props.layoutDoc.dataViz_histogram_barColors).map(each => each.split('::')); @@ -430,10 +487,11 @@ export class Histogram extends ObservableReactComponent<HistogramProps> { }); return barColor ? StrCast(barColor) : StrCast(this._props.layoutDoc.dataViz_histogram_defaultColor); }); + } }; render() { - this.updateBarColors(); + this.updateSavedUI(); this._histogramData; var curSelectedBarName = ''; var titleAccessor: any = 'dataViz_histogram_title'; @@ -442,6 +500,7 @@ export class Histogram extends ObservableReactComponent<HistogramProps> { if (!this._props.layoutDoc[titleAccessor]) this._props.layoutDoc[titleAccessor] = this.defaultGraphTitle; if (!this._props.layoutDoc.dataViz_histogram_defaultColor) this._props.layoutDoc.dataViz_histogram_defaultColor = '#69b3a2'; if (!this._props.layoutDoc.dataViz_histogram_barColors) this._props.layoutDoc.dataViz_histogram_barColors = new List<string>(); + if (!this._props.layoutDoc.dataViz_histogram_selectedData) this._props.layoutDoc.dataViz_histogram_selectedData = new List<string>(); var selected = 'none'; if (this._currSelected) { curSelectedBarName = StrCast(this._currSelected![this._props.axes[0]].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '')); |