aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/DataVizBox/components/PieChart.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/DataVizBox/components/PieChart.tsx')
-rw-r--r--src/client/views/nodes/DataVizBox/components/PieChart.tsx95
1 files changed, 51 insertions, 44 deletions
diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
index 4622b470a..e644870da 100644
--- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx
+++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
@@ -1,6 +1,7 @@
+import { Checkbox } from '@mui/material';
import { ColorPicker, EditableText, Size, Type } from 'browndash-components';
import * as d3 from 'd3';
-import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { FaFillDrip } from 'react-icons/fa';
@@ -12,10 +13,10 @@ import { Docs } from '../../../../documents/Documents';
import { undoable } from '../../../../util/UndoManager';
import { PinProps, PresBox } from '../../trails';
import './Chart.scss';
-import { Checkbox } from '@material-ui/core';
+import { ObservableReactComponent } from '../../../ObservableReactComponent';
export interface PieChartProps {
- rootDoc: Doc;
+ Document: Doc;
layoutDoc: Doc;
axes: string[];
records: { [key: string]: any }[];
@@ -32,7 +33,7 @@ export interface PieChartProps {
}
@observer
-export class PieChart extends React.Component<PieChartProps> {
+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;
@@ -41,44 +42,49 @@ export class PieChart extends React.Component<PieChartProps> {
private hoverOverData: any = undefined; // Selection of slice being hovered over
@observable _currSelected: any | undefined = undefined; // Object of selected slice
+ constructor(props: any) {
+ super(props);
+ makeObservable(this);
+ }
+
@computed get _tableDataIds() {
- return !this.parentViz ? this.props.records.map((rec, i) => i) : NumListCast(this.parentViz.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.parentViz ? 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
// otherwise, assume data is organized by categories
@computed get byCategory() {
- return !/\d/.test(this.props.records[0][this.props.axes[0]]) || this.props.layoutDoc.dataViz_pie_asHistogram;
+ return !/\d/.test(this._props.records[0][this._props.axes[0]]) || this._props.layoutDoc.dataViz_pie_asHistogram;
}
// filters all data to just display selected data if brushed (created from an incoming link)
@computed get _pieChartData() {
- if (this.props.axes.length < 1) return [];
+ if (this._props.axes.length < 1) return [];
- const ax0 = this.props.axes[0];
- if (this.props.axes.length < 2) {
- return this._tableData.map(record => ({ [ax0]: record[this.props.axes[0]] }));
+ const ax0 = this._props.axes[0];
+ if (this._props.axes.length < 2) {
+ return this._tableData.map(record => ({ [ax0]: record[this._props.axes[0]] }));
}
- const ax1 = this.props.axes[1];
- return this._tableData.map(record => ({ [ax0]: record[this.props.axes[0]], [ax1]: record[this.props.axes[1]] }));
+ const ax1 = this._props.axes[1];
+ return this._tableData.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 || !/\d/.test(this.props.records[0][ax0]) || !ax1) {
+ 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.records[0][ax0]) || !ax1) {
return ax0 + ' Pie Chart';
}
return ax1 + ' by ' + ax0 + ' Pie Chart';
}
@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
+ 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
}
@@ -101,16 +107,16 @@ export class PieChart extends React.Component<PieChartProps> {
//
title: 'piechart doc selection' + this._currSelected,
});
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this.props.rootDoc);
+ PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Document);
return anchor;
};
@computed get height() {
- return this.props.height - this.props.margin.top - this.props.margin.bottom;
+ return this._props.height - this._props.margin.top - this._props.margin.bottom;
}
@computed get width() {
- return this.props.width - this.props.margin.left - this.props.margin.right;
+ return this._props.width - this._props.margin.left - this._props.margin.right;
}
// cleans data by converting numerical data to numbers and taking out empty cells
@@ -181,7 +187,7 @@ export class PieChart extends React.Component<PieChartProps> {
var percentField = Object.keys(dataSet[0])[0];
var descriptionField = Object.keys(dataSet[0])[1]!;
- var radius = Math.min(width, height - this.props.margin.top - this.props.margin.bottom) / 2;
+ var radius = Math.min(width, height - this._props.margin.top - this._props.margin.bottom) / 2;
// converts data into Objects
var data = this.data(dataSet);
@@ -209,10 +215,10 @@ export class PieChart extends React.Component<PieChartProps> {
.select(this._piechartRef.current)
.append('svg')
.attr('class', 'graph')
- .attr('width', width + this.props.margin.right + this.props.margin.left)
- .attr('height', height + this.props.margin.top + this.props.margin.bottom)
+ .attr('width', width + this._props.margin.right + this._props.margin.left)
+ .attr('height', height + this._props.margin.top + this._props.margin.bottom)
.append('g'));
- let g = svg.append('g').attr('transform', 'translate(' + (width / 2 + this.props.margin.left) + ',' + height / 2 + ')');
+ let g = svg.append('g').attr('transform', 'translate(' + (width / 2 + this._props.margin.left) + ',' + height / 2 + ')');
var pie = d3.pie();
var arc = d3.arc().innerRadius(0).outerRadius(radius);
@@ -249,7 +255,7 @@ export class PieChart extends React.Component<PieChartProps> {
} catch (error) {}
possibleDataPointVals.push(dataPointVal);
});
- const sliceColors = StrListCast(this.props.layoutDoc.dataViz_pie_sliceColors).map(each => each.split('::'));
+ const sliceColors = StrListCast(this._props.layoutDoc.dataViz_pie_sliceColors).map(each => each.split('::'));
arcs.append('path')
.attr('fill', (d, i) => {
var dataPoint;
@@ -261,7 +267,7 @@ export class PieChart extends React.Component<PieChartProps> {
}
var sliceColor;
if (dataPoint) {
- const sliceTitle = dataPoint[this.props.axes[0]];
+ 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]));
}
@@ -277,6 +283,7 @@ export class PieChart extends React.Component<PieChartProps> {
return 'slice';
}
)
+ // @ts-ignore
.attr('d', arc)
.on('click', onPointClick)
.on('mouseover', onHover)
@@ -308,10 +315,10 @@ export class PieChart extends React.Component<PieChartProps> {
@action changeSelectedColor = (color: string) => {
this.curSliceSelected.attr('fill', color);
- const sliceTitle = this._currSelected[this.props.axes[0]];
+ const sliceTitle = this._currSelected[this._props.axes[0]];
const sliceName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/\%/g, '').replace(/\#/g, '').replace(/\</g, '') : sliceTitle;
- const sliceColors = Cast(this.props.layoutDoc.dataViz_pie_sliceColors, listSpec('string'), null);
+ const sliceColors = Cast(this._props.layoutDoc.dataViz_pie_sliceColors, listSpec('string'), null);
sliceColors.map(each => {
if (each.split('::')[0] == sliceName) sliceColors.splice(sliceColors.indexOf(each), 1);
});
@@ -319,20 +326,20 @@ export class PieChart extends React.Component<PieChartProps> {
};
@action changeHistogramCheckBox = () => {
- this.props.layoutDoc.dataViz_pie_asHistogram = !this.props.layoutDoc.dataViz_pie_asHistogram;
+ this._props.layoutDoc.dataViz_pie_asHistogram = !this._props.layoutDoc.dataViz_pie_asHistogram;
this.drawChart(this._pieChartData, this.width, this.height);
};
render() {
var titleAccessor: any = '';
- if (this.props.axes.length == 2) titleAccessor = 'dataViz_pie_title' + this.props.axes[0] + '-' + this.props.axes[1];
- else if (this.props.axes.length > 0) titleAccessor = 'dataViz_pie_title' + 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.axes.length == 2) titleAccessor = 'dataViz_pie_title' + this._props.axes[0] + '-' + this._props.axes[1];
+ else if (this._props.axes.length > 0) titleAccessor = 'dataViz_pie_title' + 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>();
var selected: string;
var curSelectedSliceName = '';
if (this._currSelected) {
- const sliceTitle = this._currSelected[this.props.axes[0]];
+ const sliceTitle = this._currSelected[this._props.axes[0]];
curSelectedSliceName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/\%/g, '').replace(/\#/g, '').replace(/\</g, '') : sliceTitle;
selected = '{ ';
Object.keys(this._currSelected).map(key => {
@@ -342,19 +349,19 @@ export class PieChart extends React.Component<PieChartProps> {
selected += ' }';
} else selected = 'none';
var selectedSliceColor;
- var sliceColors = StrListCast(this.props.layoutDoc.dataViz_pie_sliceColors).map(each => each.split('::'));
+ var sliceColors = StrListCast(this._props.layoutDoc.dataViz_pie_sliceColors).map(each => each.split('::'));
sliceColors.forEach(each => {
if (each[0] == curSelectedSliceName!) selectedSliceColor = each[1];
});
if (this._pieChartData.length > 0 || !this.parentViz) {
- return this.props.axes.length >= 1 ? (
- <div className="chart-container" style={{width: this.props.width+this.props.margin.right}}>
+ return this._props.axes.length >= 1 ? (
+ <div className="chart-container" style={{width: this._props.width+this._props.margin.right}}>
<div className="graph-title">
<EditableText
- val={StrCast(this.props.layoutDoc[titleAccessor])}
+ val={StrCast(this._props.layoutDoc[titleAccessor])}
setVal={undoable(
- action(val => (this.props.layoutDoc[titleAccessor] = val as string)),
+ action(val => (this._props.layoutDoc[titleAccessor] = val as string)),
'Change Graph Title'
)}
color={'black'}
@@ -362,9 +369,9 @@ export class PieChart extends React.Component<PieChartProps> {
fillWidth
/>
</div>
- {this.props.axes.length === 1 && /\d/.test(this.props.records[0][this.props.axes[0]]) ? (
- <div className={'asHistogram-checkBox'} style={{ width: this.props.width }}>
- <Checkbox color="primary" onChange={this.changeHistogramCheckBox} checked={this.props.layoutDoc.dataViz_pie_asHistogram as boolean} />
+ {this._props.axes.length === 1 && /\d/.test(this._props.records[0][this._props.axes[0]]) ? (
+ <div className={'asHistogram-checkBox'} style={{ width: this._props.width }}>
+ <Checkbox color="primary" onChange={this.changeHistogramCheckBox} checked={this._props.layoutDoc.dataViz_pie_asHistogram as boolean} />
Organize data as histogram
</div>
) : null}