diff options
author | srichman333 <sarah_n_richman@brown.edu> | 2023-07-14 15:17:03 -0400 |
---|---|---|
committer | srichman333 <sarah_n_richman@brown.edu> | 2023-07-14 15:17:03 -0400 |
commit | 258d9f39bb2eb8b871ad01070eeab033b30c397b (patch) | |
tree | 81cba81f1894c297da25c9272efd7eba84e274f9 /src | |
parent | 9cfd160f8e1b6caf4711bc034f9bed850eb4b12b (diff) |
pie chart groupings
Diffstat (limited to 'src')
3 files changed, 50 insertions, 24 deletions
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 35b3ca5d8..fc737c4b9 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -200,7 +200,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque const eachCell = ns.join('\t').split('\t') let eachRow = [] for (let i=1; i<eachCell.length; i++){ - eachRow.push(eachCell[i]); + eachRow.push(eachCell[i].replace(/\,/g, '')); if (i % headers.length == 0){ csvRows.push(eachRow) eachRow = []; diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx index b6ae15709..7a866d742 100644 --- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx +++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx @@ -91,7 +91,7 @@ export class Histogram extends React.Component<HistogramProps> { this._disposers.chartData = reaction( () => ({ dataSet: this._histogramData, w: this.width, h: this.height }), ({ dataSet, w, h }) => { - if (dataSet) { + if (dataSet!.length>0) { this.drawChart(dataSet, w, h); // redraw annotations when the chart data has changed, or the local or inherited selection has changed @@ -226,10 +226,10 @@ export class Histogram extends React.Component<HistogramProps> { }) return valid; }) - var field = Object.keys(dataSet[0])[0] + var field = dataSet[0]? Object.keys(dataSet[0])[0]: undefined; const data = validData.map((d: { [x: string]: any; }) => { - if (this.numericalData) { return +d[field].replace(/\$/g, '').replace(/\%/g, '') } - return d[field] + if (this.numericalData) { return +d[field!].replace(/\$/g, '').replace(/\%/g, '') } + return d[field!] }) return data; } @@ -241,7 +241,7 @@ export class Histogram extends React.Component<HistogramProps> { var field = Object.keys(dataSet[0])[0] const data = this.data(dataSet); - let uniqueArr = [...new Set(data)] + let uniqueArr: unknown[] = [...new Set(data)] var numBins = uniqueArr.length var startingPoint = 0; var endingPoint = numBins; diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx index 5b6bdc4cf..7d532e790 100644 --- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx @@ -37,7 +37,7 @@ export class PieChart extends React.Component<PieChartProps> { private _disposers: { [key: string]: IReactionDisposer } = {}; private _piechartRef: React.RefObject<HTMLDivElement> = React.createRef(); private _piechartSvg: d3.Selection<SVGGElement, unknown, null, undefined> | undefined; - private numericalData: boolean = false; + private byCategory: boolean = true; // whether the data is organized by category or by specified number percentages/ratios @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 @@ -45,7 +45,7 @@ export class PieChart extends React.Component<PieChartProps> { 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])){ this.numericalData = true } + if (/\d/.test(this.props.pairs[0][ax0])){ this.byCategory = false } return this.props.pairs ?.filter(pair => (!this.incomingLinks.length ? true : Array.from(Object.keys(pair)).some(key => pair[key] && key.startsWith('select')))) .map(pair => ({ [ax0]: (pair[this.props.axes[0]])})) @@ -53,7 +53,7 @@ export class PieChart extends React.Component<PieChartProps> { var ax0 = this.props.axes[0]; var ax1 = this.props.axes[1]; - if (/\d/.test(this.props.pairs[0][ax0])) { this.numericalData = true;} + if (/\d/.test(this.props.pairs[0][ax0])) { this.byCategory = false;} return this.props.pairs ?.filter(pair => (!this.incomingLinks.length ? true : Array.from(Object.keys(pair)).some(key => pair[key] && key.startsWith('select')))) .map(pair => ({ [ax0]: (pair[this.props.axes[0]]), [ax1]: (pair[this.props.axes[1]]) })) @@ -78,7 +78,7 @@ export class PieChart extends React.Component<PieChartProps> { .lastElement(); } @computed get rangeVals(): { xMin?: number; xMax?: number; yMin?: number; yMax?: number } { - if (this.numericalData){ + if (!this.byCategory){ const data = this.data(this._piechartData); return {xMin: Math.min.apply(null, data), xMax: Math.max.apply(null, data), yMin:0, yMax:0} } @@ -91,7 +91,7 @@ export class PieChart extends React.Component<PieChartProps> { this._disposers.chartData = reaction( () => ({ dataSet: this._piechartData, w: this.width, h: this.height }), ({ dataSet, w, h }) => { - if (dataSet) { + if (dataSet!.length>0) { this.drawChart(dataSet, w, h); // redraw annotations when the chart data has changed, or the local or inherited selection has changed @@ -226,10 +226,10 @@ export class PieChart extends React.Component<PieChartProps> { }) return valid; }) - var field = Object.keys(dataSet[0])[0] + var field = dataSet[0]? Object.keys(dataSet[0])[0] : undefined; const data = validData.map((d: { [x: string]: any; }) => { - if (this.numericalData) { return +d[field].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '') } - return d[field] + if (!this.byCategory) { return +d[field!].replace(/\$/g, '').replace(/\%/g, '').replace(/\</g, '') } + return d[field!] }) return data; } @@ -251,24 +251,38 @@ export class PieChart extends React.Component<PieChartProps> { .attr("transform", "translate(" + (width/2 + this.props.margin.left) + "," + height/2 + ")"); - var data = this.data(this._piechartData); + var data = this.data(dataSet); + var pieDataSet = dataSet; + var pie = d3.pie(); var arc = d3.arc() .innerRadius(0) .outerRadius(radius); + + if (this.byCategory){ + let uniqueCategories = [...new Set(data)] + var pieStringDataSet: { frequency: any, label: any }[] = []; + for (let i=0; i<uniqueCategories.length; i++){ + pieStringDataSet.push({frequency: 0, label: uniqueCategories[i]}) + } + for (let i=0; i<data.length; i++){ + let sliceData = pieStringDataSet.filter(each => each.label==data[i]) + sliceData[0].frequency = sliceData[0].frequency + 1; + } + pieDataSet = pieStringDataSet + data = this.data(pieStringDataSet) + } + var trackDuplicates : {[key: string]: any} = {}; + data.forEach((eachData: any) => !trackDuplicates[eachData]? trackDuplicates[eachData] = 0: null) - //Generate groups - var percentField = Object.keys(dataSet[0])[0] - var descriptionField = Object.keys(dataSet[0])[1]! + var percentField = Object.keys(pieDataSet[0])[0] + var descriptionField = Object.keys(pieDataSet[0])[1]! var arcs = g.selectAll("arc") .data(pie(data)) .enter() .append("g") arcs.append("path") - .attr("fill", (data, i)=>{ - let value=data.data; - return d3.schemeSet3[i]? d3.schemeSet3[i]: d3.schemeSet3[i%12]; - }) + .attr("fill", (data, i)=>{ return d3.schemeSet3[i]? d3.schemeSet3[i]: d3.schemeSet3[i%12] }) .attr("d", arc); arcs.append("text") .attr("transform",function(d){ @@ -277,8 +291,20 @@ export class PieChart extends React.Component<PieChartProps> { return "translate("+ (centroid[0]+centroid[0]/(radius*.02)) + "," + (centroid[1]+heightOffset) + ")"; }) .attr("text-anchor", "middle") .text(function(d){ - return dataSet[data.indexOf(d.value)][percentField] - + (!descriptionField? '' : (' - ' + dataSet[data.indexOf(d.value)][descriptionField]))}) + var possibleDataPoints = pieDataSet.filter((each: { [x: string]: any | { valueOf(): number; }; }) => { + try { + return each[percentField].replace(/[^0-9]/g,"")==d.data.toString().replace(/[^0-9]/g,"") + } catch (error) { + return each[percentField]==d.data + }}) + var dataPoint; + if (possibleDataPoints.length==1) dataPoint = possibleDataPoints[0]; + else{ + dataPoint = possibleDataPoints[trackDuplicates[d.data.toString()]] + trackDuplicates[d.data.toString()] = trackDuplicates[d.data.toString()] + 1; + } + return dataPoint[percentField]! + + (!descriptionField? '' : (' - ' + dataPoint[descriptionField]))!}) }; |