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.tsx46
1 files changed, 44 insertions, 2 deletions
diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
index 7d532e790..0d3c74c32 100644
--- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx
+++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
@@ -252,7 +252,13 @@ export class PieChart extends React.Component<PieChartProps> {
"translate(" + (width/2 + this.props.margin.left) + "," + height/2 + ")");
var data = this.data(dataSet);
- var pieDataSet = dataSet;
+ var pieDataSet = dataSet.filter((d: { [x: string]: unknown; }) => {
+ var valid = true;
+ Object.keys(dataSet[0]).map(key => {
+ if (!d[key] || Number.isNaN(d[key])) valid = false;
+ })
+ return valid;
+ });
var pie = d3.pie();
var arc = d3.arc()
@@ -275,6 +281,40 @@ export class PieChart extends React.Component<PieChartProps> {
var trackDuplicates : {[key: string]: any} = {};
data.forEach((eachData: any) => !trackDuplicates[eachData]? trackDuplicates[eachData] = 0: null)
+ const onPointClick = action((e: any) => {
+ // check the 4 'corners' of each slice and see if the pointer is within those bounds to get the slice the user clicked on
+ const pointer = d3.pointer(e);
+ var selectedSlice;
+ var index = -1;
+ const selected = svg.selectAll('.slice').filter((d: any) => {
+ index++;
+ var p1 = [0,0];
+ var p3 = [arc.centroid(d)[0]*2, arc.centroid(d)[1]*2];
+ var p2 = [radius*Math.sin(d.startAngle), -radius*Math.cos(d.startAngle)];
+ var p4 = [radius*Math.sin(d.endAngle), -radius*Math.cos(d.endAngle)];
+
+ // draw an imaginary horizontal line from the pointer to see how many times it crosses a slice edge
+ var lineCrossCount = 0;
+ // if for all 4 lines
+ if (Math.min(p1[1], p2[1])<=pointer[1] && pointer[1]<=Math.max(p1[1], p2[1])){ // within y bounds
+ if (pointer[0] <= (pointer[1]-p1[1])*(p2[0]-p1[0])/(p2[1]-p1[1])+p1[0]) lineCrossCount++; } // intercepts x
+ if (Math.min(p2[1], p3[1])<=pointer[1] && pointer[1]<=Math.max(p2[1], p3[1])){
+ if (pointer[0] <= (pointer[1]-p2[1])*(p3[0]-p2[0])/(p3[1]-p2[1])+p2[0]) lineCrossCount++; }
+ if (Math.min(p3[1], p4[1])<=pointer[1] && pointer[1]<=Math.max(p3[1], p4[1])){
+ if (pointer[0] <= (pointer[1]-p3[1])*(p4[0]-p3[0])/(p4[1]-p3[1])+p3[0]) lineCrossCount++; }
+ if (Math.min(p4[1], p1[1])<=pointer[1] && pointer[1]<=Math.max(p4[1], p1[1])){
+ if (pointer[0] <= (pointer[1]-p4[1])*(p1[0]-p4[0])/(p1[1]-p4[1])+p4[0]) lineCrossCount++; }
+ if (lineCrossCount % 2 != 0) {
+ selectedSlice = pieDataSet[index];
+ return true;
+ }
+ return false;
+ });
+ console.log('selectedSlice', selectedSlice)
+
+ selected.attr('class')=='slice hover'? selected.attr('class', 'slice'): selected.attr('class', 'slice hover')
+ });
+
var percentField = Object.keys(pieDataSet[0])[0]
var descriptionField = Object.keys(pieDataSet[0])[1]!
var arcs = g.selectAll("arc")
@@ -283,7 +323,9 @@ export class PieChart extends React.Component<PieChartProps> {
.append("g")
arcs.append("path")
.attr("fill", (data, i)=>{ return d3.schemeSet3[i]? d3.schemeSet3[i]: d3.schemeSet3[i%12] })
- .attr("d", arc);
+ .attr("class", `${pieDataSet[0][percentField]} slice`)
+ .attr("d", arc)
+ .on('click', onPointClick)
arcs.append("text")
.attr("transform",function(d){
var centroid = arc.centroid(d as unknown as d3.DefaultArcObject)