aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsrichman333 <sarah_n_richman@brown.edu>2024-04-28 18:35:44 -0400
committersrichman333 <sarah_n_richman@brown.edu>2024-04-28 18:35:44 -0400
commitbf89ce9ec19c22dec4ad302a755e354e34182f66 (patch)
tree3d1cf0b79a43276cba94d25088614b0e35a86d24 /src
parent8de07e0c17c2914bb6aff54f86e198eef5d2ac06 (diff)
pie chart filtering, mult-selection, selection on refresh updates
Diffstat (limited to 'src')
-rw-r--r--src/client/views/nodes/DataVizBox/components/Chart.scss11
-rw-r--r--src/client/views/nodes/DataVizBox/components/Histogram.tsx10
-rw-r--r--src/client/views/nodes/DataVizBox/components/PieChart.tsx98
3 files changed, 86 insertions, 33 deletions
diff --git a/src/client/views/nodes/DataVizBox/components/Chart.scss b/src/client/views/nodes/DataVizBox/components/Chart.scss
index 47cad9649..0eb27b65b 100644
--- a/src/client/views/nodes/DataVizBox/components/Chart.scss
+++ b/src/client/views/nodes/DataVizBox/components/Chart.scss
@@ -18,14 +18,9 @@
margin-top: -35px;
}
.asHistogram-checkBox {
- align-items: left;
- align-self: left;
- align-content: left;
- justify-content: flex-end;
- float: left;
- left: 0;
- position: relative;
- margin-bottom: -35px;
+ margin-left: 10px;
+ margin-bottom: -10px;
+ margin-top: -20px;
}
.selected-data {
align-items: center;
diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
index 74711bd58..1fc33396a 100644
--- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx
+++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
@@ -118,7 +118,7 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
const selectedDataBars = StrListCast(this._props.layoutDoc.dataViz_histogram_selectedData)
svg.selectAll('rect').attr('class', (d: any) => {
let selected = false;
- selectedDataBars.map(eachSelectedData => {
+ selectedDataBars.forEach(eachSelectedData => {
if (d[0]==eachSelectedData) selected = true;
})
if (selected){
@@ -183,10 +183,10 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
sameAsCurrent = this._currSelected ? showSelected[xAxisTitle] == this._currSelected![xAxisTitle] && showSelected[yAxisTitle] == this._currSelected![yAxisTitle] : false;
let sameAsAny = false;
const selectedDataBars = Cast(this._props.layoutDoc.dataViz_histogram_selectedData, listSpec('number'), null);
- this.selectedData.map(eachData => {
+ this.selectedData.forEach(eachData => {
if (!sameAsAny){
let match = true;
- Object.keys(d).map(key => {
+ Object.keys(d).forEach(key => {
if (d[key] != eachData[key]) match = false;
})
if (match) {
@@ -374,7 +374,7 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
const selectedData = this.selectedData;
svg.selectAll('rect').attr('class', function (d: any) {
let selected = false;
- selectedData.map(eachSelectedData => {
+ selectedData.forEach(eachSelectedData => {
if (d[0]==eachSelectedData[0]) selected = true;
})
return (hoverOverBar && hoverOverBar[0] == d[0]) || selected ? 'histogram-bar hover' : 'histogram-bar';
@@ -434,7 +434,7 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
'class',
function (d) {
let selectThisData = false;
- selected.map(eachSelectedData => {
+ selected.forEach(eachSelectedData => {
if (d[0]==eachSelectedData[0]) selectThisData = true;
})
return selectThisData ? 'histogram-bar hover' : 'histogram-bar';
diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
index fc23f47de..364a5c2ff 100644
--- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx
+++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
@@ -38,8 +38,8 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
private _disposers: { [key: string]: IReactionDisposer } = {};
private _piechartRef: React.RefObject<HTMLDivElement> = React.createRef();
private _piechartSvg: d3.Selection<SVGGElement, unknown, null, undefined> | undefined;
- private curSliceSelected: any = undefined; // d3 data of selected slice
- private selectedData: any = undefined; // Selection of selected slice
+ private curSliceSelected: any = undefined; // d3 data of selected slice for when just one slice is selected
+ private selectedData: any[] = []; // array of selected slices
private hoverOverData: any = undefined; // Selection of slice being hovered over
@observable _currSelected: any | undefined = undefined; // Object of selected slice
@@ -84,20 +84,35 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
@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
}
componentWillUnmount() {
Array.from(Object.keys(this._disposers)).forEach(key => this._disposers[key]());
}
componentDidMount() {
+ // draw chart
this._disposers.chartData = reaction(
() => ({ dataSet: this._pieChartData, w: this.width, h: this.height }),
({ dataSet, w, h }) => dataSet!.length > 0 && this.drawChart(dataSet, w, h),
{ fireImmediately: true }
);
+ // restore selected slices
+ let key = Object.keys(this._pieChartData[0])[0]
+ var svg = this._piechartSvg;
+ if (svg) {
+ const selectedDataBars = StrListCast(this._props.layoutDoc.dataViz_pie_selectedData)
+ svg.selectAll('path').attr('class', (d: any) => {
+ let selected = false;
+ selectedDataBars.map(eachSelectedData => {
+ if (d[key]==eachSelectedData) selected = true;
+ })
+ if (selected){
+ this.selectedData.push(d);
+ return 'slice hover'
+ }
+ else return 'slice';
+ });
+ }
}
@action
@@ -163,21 +178,54 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
if (lineCrossCount % 2 != 0) {
// inside the slice of it crosses an odd number of edges
var showSelected = this.byCategory ? pieDataSet[index] : this._pieChartData[index];
+ let key = 'data' // key that represents slice
+ if (Object.keys(showSelected)[0]=='frequency') key = Object.keys(showSelected)[1]
if (changeSelectedVariables) {
// for when a bar is selected - not just hovered over
sameAsCurrent = this._currSelected
? showSelected[Object.keys(showSelected)[0]] == this._currSelected![Object.keys(showSelected)[0]] && showSelected[Object.keys(showSelected)[1]] == this._currSelected![Object.keys(showSelected)[1]]
: this._currSelected === showSelected;
- this._currSelected = sameAsCurrent ? undefined : showSelected;
- this.selectedData = sameAsCurrent ? undefined : d;
+ let sameAsAny = false;
+ const selectedDataSlices = Cast(this._props.layoutDoc.dataViz_pie_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);
+ selectedDataSlices.splice(index, 1);
+ this._currSelected = undefined;
+ }
+ }
+ })
+ if(!sameAsAny) {
+ this.selectedData.push(d);
+ selectedDataSlices.push(d[key]);
+ 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;
+ if (this._props.records[rowID][key] == d[key]) 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.curSliceSelected = undefined;
- else this.curSliceSelected = selected;
+ if (this._currSelected) this.curSliceSelected = selected;
+ else this.curSliceSelected = undefined;
}
};
@@ -237,9 +285,11 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
const hoverOverSlice = this.hoverOverData;
const selectedData = this.selectedData;
svg.selectAll('path').attr('class', function (d: any) {
- return (selectedData && d.startAngle == selectedData.startAngle && d.endAngle == selectedData.endAngle) || (hoverOverSlice && d.startAngle == hoverOverSlice.startAngle && d.endAngle == hoverOverSlice.endAngle)
- ? 'slice hover'
- : 'slice';
+ let selected = false;
+ selectedData.forEach((eachSelectedData: any) => {
+ if (d.startAngle==eachSelectedData.startAngle) selected = true;
+ })
+ return selected || (hoverOverSlice && d.startAngle == hoverOverSlice.startAngle && d.endAngle == hoverOverSlice.endAngle) ? 'slice hover' : 'slice';
});
};
@@ -257,8 +307,14 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
possibleDataPointVals.push(dataPointVal);
});
const sliceColors = StrListCast(this._props.layoutDoc.dataViz_pie_sliceColors).map(each => each.split('::'));
+
+ // to make sure all important slice information is on 'd' object
+ let addKey: any = false;
+ if (Object.keys(pieDataSet[0])[0]=='frequency'){
+ addKey = Object.keys(pieDataSet[0])[1]
+ }
arcs.append('path')
- .attr('fill', (d, i) => {
+ .attr('fill', (d: any, i) => {
var dataPoint;
const possibleDataPoints = possibleDataPointVals.filter((pval: any) => pval[percentField] === Number(d.data));
if (possibleDataPoints.length == 1) dataPoint = possibleDataPoints[0];
@@ -268,6 +324,7 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
}
var sliceColor;
if (dataPoint) {
+ if (addKey) d[addKey] = dataPoint[addKey] // adding all slice information to d
const sliceTitle = dataPoint[this._props.axes[0]];
const accessByName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/\%/g, '').replace(/\#/g, '').replace(/\</g, '') : sliceTitle;
sliceColors.forEach(each => each[0] == accessByName && (sliceColor = each[1]));
@@ -276,13 +333,13 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
})
.attr(
'class',
- selected
- ? function (d) {
- return selected && d.startAngle == selected.startAngle && d.endAngle == selected.endAngle ? 'slice hover' : 'slice';
- }
- : function (d) {
- return 'slice';
- }
+ function (d: any) {
+ let selectThisData = false;
+ selected.forEach((eachSelectedData: any) => {
+ if (d.startAngle==eachSelectedData.startAngle) selectThisData = true;
+ })
+ return selectThisData ? 'slice hover' : 'slice';
+ }
)
// @ts-ignore
.attr('d', arc)
@@ -337,6 +394,7 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
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_pie_sliceColors) this._props.layoutDoc.dataViz_pie_sliceColors = new List<string>();
+ if (!this._props.layoutDoc.dataViz_pie_selectedData) this._props.layoutDoc.dataViz_pie_selectedData = new List<string>();
var selected: string;
var curSelectedSliceName = '';
if (this._currSelected) {