diff --git a/js/components/PieChart.js b/js/components/PieChart.js new file mode 100644 index 0000000..d80fac9 --- /dev/null +++ b/js/components/PieChart.js @@ -0,0 +1,136 @@ +var d3 = require('d3'); +var React = require('react'); + +var Slice = React.createClass({ + displayName: "Slice", + render: function() { + if (this.props.angle > Math.PI*2 - 0.00001) { + var slice = (); + } else { + var center = this.props.cx + " " + this.props.cy; + var dx = Math.cos(this.props.angle)*this.props.radius - this.props.radius; + var dy = Math.sin(this.props.angle)*this.props.radius - 0.00001; + var large_arc_flag = this.props.angle > Math.PI ? 1 : 0; + var rotateDegrees = this.props.startAngle * 180 / Math.PI; + + slice = (); + } + return ( + + {this.props.title} + {slice} + + ); + } +}); + +module.exports = React.createClass({ + displayName: "PieChart", + sortedSeries: function(series) { + // Return an array of the series names, from highest to lowest sums (in + // absolute terms) + + var seriesNames = []; + var seriesValues = {}; + for (var child in series) { + if (series.hasOwnProperty(child)) { + seriesNames.push(child); + seriesValues[child] = series[child].reduce(function(accum, curr, i, arr) { + return accum + curr; + }, 0); + } + } + seriesNames.sort(function(a, b) { + return seriesValues[b] - seriesValues[a]; + }); + + return [seriesNames, seriesValues]; + }, + render: function() { + height = 400; + width = 600; + legendWidth = 100; + xMargin = 70; + yMargin = 70; + height -= yMargin*2; + width -= xMargin*2; + var radius = Math.min(height, width)/2; + + var sortedSeriesValues = this.sortedSeries(this.props.report.FlattenedSeries); + var sortedSeries = sortedSeriesValues[0]; + var seriesValues = sortedSeriesValues[1]; + var r = d3.scaleLinear() + .range([0, 2*Math.PI]) + .domain([0, sortedSeries.reduce(function(accum, curr, i, arr) { + return accum + Math.abs(seriesValues[curr]); + }, 0)]); + + var slices = []; + + // Add all the slices + var legendMap = {}; + var childId=1; + var startAngle = 0; + for (var i=0; i < sortedSeries.length; i++) { + var child = sortedSeries[i]; + var value = seriesValues[child]; + if (value == 0) + continue; + + var sliceClasses = "chart-element chart-color" + (childId % 12); + var self = this; + var sliceOnClick = function() { + var childName = child; + var onSelectSeries = self.props.onSelectSeries; + return function() { + onSelectSeries(childName); + }; + }(); + + var radians = r(Math.abs(value)); + var title = child + ": " + value; + + slices.push(( + + )); + legendMap[child] = childId; + childId++; + startAngle += radians; + } + + var legend = []; + for (var series in legendMap) { + var legendClasses = "chart-color" + (legendMap[series] % 12); + var legendY = (legendMap[series] - 1)*15; + legend.push(( + + )); + legend.push(( + {series} + )); + } + + return ( + + + {slices} + + + {legend} + + + ); + } +});