final registrations stats

Conflicts:

	app/views/admin/stats/index.html.haml
This commit is contained in:
differentreality 2013-09-09 20:05:51 +03:00
parent c26a0a0bc9
commit 9cf5c59f28
4 changed files with 172 additions and 74 deletions

View file

@ -0,0 +1,82 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// Where to put the chart
var svg = d3.select("#charts").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var registered = '<%= h @pre_registered%>';
var data = [
{"status":"did not attend","value":'<%= h @pre_registered - @pre_registered_attended %>'},
{"status":"attended","value":'<%= h @pre_registered_attended %>'}
];
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d3.round(d.data.value / registered * 100) + "%"; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#charts").append("svg")
.attr("class", "legend")
.attr("width", radius*2)
.attr("height", 230)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d; });
</script>

View file

@ -0,0 +1,86 @@
<script>
var registered = '<%= h @registrations.count%>';
var data = <%=raw @mydays.to_json %>;
var valueLabelWidth = 40; // space reserved for value labels (right)
var barHeight = 24; // height of one bar
var barLabelWidth = 100; // space reserved for bar labels
var barLabelPadding = 8; // padding between bar and bar labels (left)
var gridLabelHeight = 18; // space reserved for gridline labels
var gridChartOffset = 3; // space between start of grid and first bar
var maxBarWidth = 420; // width of the bar with the max value
// accessor functions
var barLabel = function(d) { return d['status']; };
var barValue = function(d) { return d['value'] / registered * 100; };
var barValues = function(d) { return d['value']; };
// scales
var yScale = d3.scale.ordinal().domain(d3.range(0, data.length)).rangeBands([0, data.length * barHeight]);
var y = function(d, i) { return yScale(i); };
var yText = function(d, i) { return y(d, i) + yScale.rangeBand() / 2; };
var x = d3.scale.linear().domain([0, 100]).range([0, maxBarWidth]);
// svg container element
var chart = d3.select('#c2').append("svg")
.attr('width', maxBarWidth + barLabelWidth + valueLabelWidth)
.attr('height', gridLabelHeight + gridChartOffset + data.length * barHeight);
/*
// grid line labels
var gridContainer = chart.append('g')
.attr('transform', 'translate(' + barLabelWidth + ',' + gridLabelHeight + ')');
gridContainer.selectAll("text").data(x.ticks(10)).enter().append("text")
.attr("x", x)
.attr("dy", -3)
.attr("text-anchor", "middle")
.text(String);
// vertical grid lines
gridContainer.selectAll("line").data(x.ticks(10)).enter().append("line")
.attr("x1", x)
.attr("x2", x)
.attr("y1", 0)
.attr("y2", yScale.rangeExtent()[1] + gridChartOffset)
.style("stroke", "#ccc");*/
// bar labels
var labelsContainer = chart.append('g')
.attr('transform', 'translate(' + (barLabelWidth - barLabelPadding) + ',' + (gridLabelHeight + gridChartOffset) + ')');
labelsContainer.selectAll('text').data(data).enter().append('text')
.attr('y', yText)
.attr('stroke', 'none')
.attr('fill', 'black')
.attr("dy", ".35em") // vertical-align: middle
.attr('text-anchor', 'end')
.text(barLabel);
// bars
var barsContainer = chart.append('g')
.attr('transform', 'translate(' + barLabelWidth + ',' + (gridLabelHeight + gridChartOffset) + ')');
barsContainer.selectAll("rect").data(data).enter().append("rect")
.attr('y', y)
.attr('height', yScale.rangeBand())
.attr('width', function(d) { return x(barValue(d)); })
.attr('stroke', 'white')
.attr('fill', 'steelblue');
// bar value labels
barsContainer.selectAll("text").data(data).enter().append("text")
.attr("x", function(d) { return x(barValue(d)); })
.attr("y", yText)
.attr("dx", 3) // padding-left
.attr("dy", ".35em") // vertical-align: middle
.attr("text-anchor", "start") // text-align: right
.attr("fill", "black")
.attr("stroke", "none")
.text(function(d) { return d3.round(barValues(d), 2) + " registrations (" + d3.round(barValue(d), 0) + "%)"; });
// start line
barsContainer.append("line")
.attr("y1", -gridChartOffset)
.attr("y2", yScale.rangeExtent()[1] + gridChartOffset)
.style("stroke", "#000");
</script>

View file

@ -1,72 +1,2 @@
.row-fluid
.span12
%h3
Total Registrations
- if @registered
= "(#{@registered})"
- if @attendees
= " - Attendees (#{@attendees})"
.row-fluid
.span3
%table.table.table-bordered.table-striped
%thead
%th General Stats
%th #
%tr
%td Registered attended
%td= @pre_registered_attended
%tr
%td Registered not attended
%td= @pre_registered - @pre_registered_attended
%tr
%td Attended with partner
%td= @attended_with_partner
%tr
%td Registred to attend with partner
%td= @registered_with_partner
%tr
%td Handicapped Access for
%td= @handicapped_access
%tr
%td Staying at suggested hotel
%td= @suggested_hotel_stay
.span3
- if @conference.use_dietary_choices == true
- diet_choices = []
- @conference.dietary_choices.each do |d|
- count = diet_count(d.id)
- if count > 0
- diet_choices << [d.title, count]
- if diet_choices.any?
%table.table.table-bordered.table-striped
%thead
%th Dietary Choice
%th #
%th Percentage
- diet_choices.each do |d|
%tr
%td= d[0]
%td= d[1]
%td
- if @registered and @registered > 0
= "#{d[1] * 100 / @registered}% of registered"
- if @attendees and @attendees > 0
%br
= "#{d[1] * 100 / @attendees}% of attendees"
.span3
- if @conference.social_events.count > 0
- social_events = []
- @conference.social_events.each do |social_event|
- count = social_event_count(social_event)
- if count > 0
- social_events << [social_event.title, count]
- if social_events.any?
%table.table.table-bordered.table-striped
%thead
%th Social Event
%th #
- social_events.each do |s|
%tr
%td= s[0]
%td= s[1]
= render :partial => "registered_attended"
= render :partial => "registered_time"

View file

@ -15,8 +15,8 @@
= render :partial => 'speakers'
.tab-pane#tickets
= render :partial => 'tickets'
:javascript
:javascript
$('#myTab a').click(function (e) {
e.preventDefault();
$(this).tab('show');