Use chartkick globally

* Clean up legacy charting imports
* Update existing donut and line charts
* Create helpers for parsing out existing chart data
* Move chart partials to a more common path
This commit is contained in:
James Mason 2018-12-19 12:59:52 -08:00
parent 3bbac3667f
commit 516e53d9df
29 changed files with 331 additions and 577 deletions

View file

@ -20,8 +20,9 @@
//= require dataTables/bootstrap/3/jquery.dataTables.bootstrap
//= require cocoon
//= require bootstrap
//= require Chart.bundle
//= require chartkick
//= require osem
//= require osem-dashboard
//= require jquery-smooth-scroll
//= require trianglify
//= require tinycolor

View file

@ -1,146 +0,0 @@
$(function() {
var t;
function size(animate){
if (animate == undefined){
animate = false;
}
clearTimeout(t);
t = setTimeout(function(){
$("canvas").each(function(i,el){
$(el).attr({
"width":$(el).parent().width()
});
});
$(".line_chart").each(function(){
draw_line_chart(animate, $(this));
});
$(".doughnut_chart").each(function(){
if($(this).is(":visible")){
draw_doughnut_chart(animate, $(this));
}
});
}, 30);
}
function draw_doughnut_chart(animation, $this){
var options = get_animation({}, animation);
var tmp = $this.data('chart');
if(jQuery.isEmptyObject(tmp)){
// Append error message if there is no data
$this.parent().append("<h4 class=\"text-warning\">No data!</h4>");
// Remove canvas
$this.remove();
}else{
var data = [];
for (var key in tmp) {
data.push(tmp[key]);
}
var ctx = $this.get(0).getContext("2d");
new Chart(ctx).Doughnut(data, options);
}
}
function get_animation(options, animation){
if (!animation){
options.animation = false;
} else {
options.animation = true;
}
return options;
}
function draw_line_chart(animation, $canvas){
var chart_data = create_dataset($canvas);
var weeks = $canvas.parent().data('weeks');
var data = {
labels : weeks,
datasets : chart_data
}
var options = get_animation(wholeNumberAxisFix(data), animation);
var ctx = $canvas.get(0).getContext("2d");
new Chart(ctx).Line(data, options);
}
function wholeNumberAxisFix(data){
var maxValue = false;
for(datasetIndex = 0; datasetIndex < data.datasets.length; ++datasetIndex){
var setMax = Math.max.apply(null, data.datasets[datasetIndex].data);
if (maxValue === false || setMax > maxValue) maxValue = setMax;
}
var steps = maxValue;
var stepWidth = 1;
if (maxValue > 10) {
stepWidth = Math.floor(maxValue / 10);
steps = Math.ceil(maxValue / stepWidth);
}
return { scaleOverride: true, scaleSteps: steps, scaleStepWidth: stepWidth, scaleStartValue: 0 };
}
function create_dataset($canvas){
var selected = getSelectedConferences($canvas);
var chart_data = $canvas.parent().data('chart');
var conferences = $canvas.parent().data('conferences');
var result = [];
for(var i in conferences){
if(selected.indexOf(conferences[i].short_title) >= 0){
var options = {};
options.fillColor = "rgba(255,255,255,0.0)";
options.strokeColor = conferences[i].color;
options.data = chart_data[conferences[i].short_title];
if(options.data == null || options.data.length == 0){
options.data = [0];
}
result.push(options)
}
}
return result
}
function getSelectedConferences($canvas){
var name = $canvas.data('name');
var id = '#' + name + 'Checkboxes'
var selected = [];
var $checkboxes = $(id + ' input');
// If there are checkboxes -> get selected
// Else -> use the active conference
if($checkboxes.length){
$(id + ' input').each(function(){
if($(this).is(":checked")) {
selected.push($(this).attr('name'));
}
});
}else{
var active = $canvas.parent().data('active');
for(i in active){
selected.push(active[i].short_title)
}
}
return selected;
}
$('.conferenceCheckboxes input').change(function(){
var chart_name = $(this).parent().data('chart');
var $canvas = $('#line_chart_' + chart_name);
draw_line_chart(false, $canvas);
});
$(window).on('resize', function(){
size(false);
});
$('#doughnut_tabs a').click(function (e) {
e.preventDefault();
$(this).tab('show');
size(false);
});
size(true);
});

View file

@ -37,43 +37,33 @@ module Admin
@top_submitter = Conference.get_top_submitter
@submissions = {}
@cfp_weeks = [0]
@registrations = {}
@registration_weeks = [0]
@tickets = {}
@ticket_weeks = [0]
@registrations = []
@submissions = []
@tickets = []
@conferences.each do |c|
# Event submissions over time chart
@submissions[c.short_title] = c.get_submissions_per_week
@cfp_weeks.push(@submissions[c.short_title].length)
# Conference registrations over time chart
@registrations[c.short_title] = c.get_registrations_per_week
@registration_weeks.push(@registrations[c.short_title].length)
@registrations << {
name: c.short_title,
data: c.get_registrations_per_week
}
# Event submissions over time chart
@submissions << {
name: c.short_title,
data: c.get_submissions_per_week
}
# Tickets sold over time chart
@tickets[c.short_title] = c.get_tickets_sold_per_week
@ticket_weeks.push(@tickets[c.short_title].length)
@tickets << {
name: c.short_title,
data: c.get_tickets_sold_per_week
}
end
@cfp_weeks = @cfp_weeks.max
@submissions = normalize_array_length(@submissions, @cfp_weeks)
@cfp_weeks = @cfp_weeks > 0 ? (1..@cfp_weeks).to_a : 1
@registration_weeks = @registration_weeks.max
@registrations = normalize_array_length(@registrations, @registration_weeks)
@registration_weeks = @registration_weeks > 0 ? (1..@registration_weeks).to_a : 1
@ticket_weeks = @ticket_weeks.max
@tickets = normalize_array_length(@tickets, @ticket_weeks)
@ticket_weeks = @ticket_weeks > 0 ? (1..@ticket_weeks).to_a : 1
@event_distribution = Conference.event_distribution
@user_distribution = Conference.user_distribution
@event_distribution_colors = Event::COLORS.values
@user_distribution = User.distribution
@user_distribution_colors = User::DISTRIBUTION_COLORS.values
end
def new
@ -138,35 +128,9 @@ module Admin
@conference_progress = @conference.get_status
# Line charts
@registrations = {@conference.short_title => @conference.get_registrations_per_week}
@registration_weeks = [0]
@registration_weeks.push(@registrations[@conference.short_title].length)
@registration_weeks = @registration_weeks.max
@registrations = normalize_array_length(@registrations, @registration_weeks)
@registration_weeks = @registration_weeks > 0 ? (1..@registration_weeks).to_a : 1
@submissions = Conference.get_event_state_line_colors
@submissions_data = @conference.get_submissions_data
@cfp_weeks = 0
if @submissions_data['Weeks']
@cfp_weeks = @submissions_data['Weeks']
@submissions_data = @submissions_data.except('Weeks')
end
@tickets_data = @conference.get_tickets_data
@ticket_weeks = 0
if @tickets_data['Weeks']
@ticket_weeks = @tickets_data['Weeks']
@tickets_data = @tickets_data.except('Weeks')
end
# Set line color using a hash function
@tickets = []
@tickets_data.each_key do |title|
@tickets.append(short_title: title, color: "\##{Digest::MD5.hexdigest(title)[0..5]}")
end
@registrations = @conference.get_registrations_per_week
@submissions = @conference.get_submissions_data
@tickets = @conference.get_tickets_data
# Doughnut charts
@event_type_distribution = @conference.event_type_distribution

View file

@ -16,6 +16,7 @@ module Admin
@event_types = @program.event_types
@tracks_distribution_confirmed = @conference.tracks_distribution(:confirmed)
@event_distribution = @conference.event_distribution
@event_distribution_colors = Event::COLORS.values
@scheduled_event_distribution = @conference.scheduled_event_distribution
@file_name = "events_for_#{@conference.short_title}"
@event_export_option = params[:event_export_option]

View file

@ -0,0 +1,17 @@
# frozen_string_literal: true
module ChartHelper
def chart_values(distribution_hash)
Hash[
distribution_hash.collect do |key, data|
[key, data['value']]
end
]
end
def chart_colors(distribution_hash)
distribution_hash.collect do |_key, data|
data['color']
end
end
end

View file

@ -176,24 +176,22 @@ class Conference < ApplicationRecord
# ====Returns
# * +Array+ -> e.g. 'Submitted' => [0, 3, 3, 5] -> first week 0 events, second week 3 events.
def get_submissions_data
result = {}
if program&.cfp && program&.events
result = get_events_per_week_by_state
return [] unless program&.cfp && program&.events
start_week = program.cfp.start_week
end_week = end_date.strftime('%W').to_i
weeks = weeks(start_week, end_week)
result.each do |state, values|
if state == 'Submitted'
result['Submitted'] = pad_array_left_kumulative(start_week, values)
else
result[state] = pad_array_left_not_kumulative(start_week, values)
end
start_week = program.cfp.start_week
get_events_per_week_by_state.collect do |state, values|
if state == 'Submitted'
{
name: 'Submitted',
data: add_week_indices(pad_array_left_kumulative(start_week, values))
}
else
{
name: state,
data: add_week_indices(pad_array_left_not_kumulative(start_week, values))
}
end
result['Weeks'] = weeks > 0 ? (1..weeks).to_a : 0
end
result
end
##
@ -202,19 +200,15 @@ class Conference < ApplicationRecord
# ====Returns
# * +Array+ -> e.g. [0, 3, 3, 5] -> first week 0, second week 3 registrations
def get_registrations_per_week
result = []
return [] unless registrations &&
registration_period &&
registration_period.start_date &&
registration_period.end_date
if registrations &&
registration_period &&
registration_period.start_date &&
registration_period.end_date
reg = registrations.group(:week).order(:week).count
start_week = get_registration_start_week
weeks = registration_weeks
result = calculate_items_per_week(start_week, weeks, reg)
end
result
reg = registrations.group(:week).order(:week).count
start_week = get_registration_start_week
weeks = registration_weeks
calculate_items_per_week(start_week, weeks, reg)
end
##
@ -223,15 +217,12 @@ class Conference < ApplicationRecord
# ====Returns
# * +Array+ -> e.g. [0, 3, 3, 5] -> first week 0, second week 3 tickets sold
def get_tickets_sold_per_week
result = []
return [] unless tickets && ticket_purchases && registration_period
if tickets && ticket_purchases && registration_period
tickets_sold = ticket_purchases.paid.group(:week).sum(:quantity)
start_week = get_registration_start_week
weeks = registration_weeks
result = calculate_items_per_week(start_week, weeks, tickets_sold)
end
result
tickets_sold = ticket_purchases.paid.group(:week).sum(:quantity)
start_week = get_registration_start_week
weeks = registration_weeks
calculate_items_per_week(start_week, weeks, tickets_sold)
end
##
@ -241,33 +232,32 @@ class Conference < ApplicationRecord
# ====Returns
# * +Array+ -> e.g. 'Free Access' => [0, 3, 3, 5] -> first week 0 tickets sold, second week 3 tickets sold.
def get_tickets_data
result = {}
if tickets && ticket_purchases && registration_period
tickets_per_ticket_id_and_week = ticket_purchases.paid.group(:ticket_id, :week).sum(:quantity)
return [] unless tickets && ticket_purchases && registration_period
start_week = get_registration_start_week
weeks = registration_weeks
tickets_per_ticket_id_and_week = ticket_purchases.paid.group(:ticket_id, :week).sum(:quantity)
tickets_by_id_per_week = {}
start_week = get_registration_start_week
weeks = registration_weeks
tickets.each do |ticket|
tickets_by_id_per_week[ticket.id] = {}
(start_week...(start_week + weeks)).each do |week|
tickets_by_id_per_week[ticket.id][week] = 0
end
tickets_by_id_per_week = {}
tickets.each do |ticket|
tickets_by_id_per_week[ticket.id] = {}
(start_week...(start_week + weeks)).each do |week|
tickets_by_id_per_week[ticket.id][week] = 0
end
tickets_per_ticket_id_and_week.each do |ticket_week, value|
tickets_by_id_per_week[ticket_week[0]][ticket_week[1]] = value
end
tickets_by_id_per_week.each do |ticket, values|
result[Ticket.find(ticket).title] = pad_array_left_not_kumulative(start_week, values)
end
result['Weeks'] = weeks > 0 ? (1..weeks).to_a : 0
end
result
tickets_per_ticket_id_and_week.each do |ticket_week, value|
tickets_by_id_per_week[ticket_week[0]][ticket_week[1]] = value
end
tickets_by_id_per_week.collect do |ticket, values|
{
name: Ticket.find(ticket).title,
data: add_week_indices(pad_array_left_not_kumulative(start_week, values))
}
end
end
##
@ -400,7 +390,9 @@ class Conference < ApplicationRecord
# ====Returns
# * +hash+ -> hash
def event_distribution
Conference.calculate_event_distribution_hash(program.events.select(:state).group(:state).count)
Conference.calculate_event_distribution_hash(
program.events.select(:state).group(:state).count
)
end
##
@ -465,22 +457,6 @@ class Conference < ApplicationRecord
result
end
##
# Returns a hash with user distribution => {value: count of user state, color: color}
# active: signed in during the last 3 months
# unconfirmed: registered but not confirmed
# dead: not signed in during the last year
#
# ====Returns
# * +hash+ -> hash
def self.user_distribution
active_user = User.where('last_sign_in_at > ?', Date.today - 3.months).count
unconfirmed_user = User.where('confirmed_at IS NULL').count
dead_user = User.where('last_sign_in_at < ?', Date.today - 1.year).count
calculate_user_distribution_hash(active_user, unconfirmed_user, dead_user)
end
##
# Returns a hash with per ticket sales => { "Title" => { value: number of tickets sold,
# color: generated from the title using a hash function }, ...}
@ -1110,20 +1086,19 @@ class Conference < ApplicationRecord
end
##
# Helper method. Calculates hash with corresponding colors of event state distribution.
# Helper method. Calculates hash of all event states in a consistent order.
#
# ====Returns
# * +hash+ -> hash
def self.calculate_event_distribution_hash(states)
result = {}
states.each do |key, value|
result[key.capitalize] =
{
'value' => value,
'color' => Event.get_state_color(key)
}
end
result
def self.calculate_event_distribution_hash(counts)
return {} if counts.values.sum == 0
Hash[
Event.state_machine.states.collect do |state|
state_name = state.name.to_s
[state_name.capitalize, counts[state_name] || 0]
end
]
end
##
@ -1211,6 +1186,12 @@ class Conference < ApplicationRecord
result += Array.new(weeks - result.length, sum)
end
result
add_week_indices(result)
end
def add_week_indices(values)
Hash[
values.collect.with_index { |value, index| ["Wk #{index + 1}", value] }
]
end
end

View file

@ -83,6 +83,15 @@ class Event < ApplicationRecord
end
end
COLORS = {
new: '#0000FF', # blue
withdrawn: '#FF8000', # orange
unconfirmed: '#FFFF00', # yellow
confirmed: '#00FF00', # green
canceled: '#848484', # grey
rejected: '#FF0000' # red
}.freeze
##
# Checkes if the event has a start_time and a room for the selected schedule if there is any
# ====Returns
@ -176,16 +185,7 @@ class Event < ApplicationRecord
end
def self.get_state_color(state)
color = {
new: '#0000FF', # blue
withdrawn: '#FF8000', # orange
confirmed: '#00FF00', # green
unconfirmed: '#FFFF00', # yellow
rejected: '#FF0000', # red
canceled: '#848484' # grey
}[state.to_sym]
color || '#00FFFF' # azure
COLORS[state.to_sym] || '#00FFFF' # azure
end
def update_state(transition, mail = false, subject = false, send_mail = false, send_mail_param)

View file

@ -32,6 +32,13 @@ class User < ApplicationRecord
# add scope
scope :comment_notifiable, ->(conference) {joins(:roles).where('roles.name IN (?)', [:organizer, :cfp]).where('roles.resource_type = ? AND roles.resource_id = ?', 'Conference', conference.id)}
# scopes for user distributions
scope :active, lambda {
where('last_sign_in_at > ?', Date.today - 3.months).where(is_disabled: false)
}
scope :unconfirmed, -> { where('confirmed_at IS NULL') }
scope :dead, -> { where('last_sign_in_at < ?', Date.today - 1.year) }
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
@ -79,7 +86,6 @@ class User < ApplicationRecord
accepts_nested_attributes_for :roles
scope :admin, -> { where(is_admin: true) }
scope :active, -> { where(is_disabled: false) }
validates :email, presence: true
@ -91,6 +97,12 @@ class User < ApplicationRecord
validate :biography_limit
DISTRIBUTION_COLORS = {
'Active' => 'green',
'Unconfirmed' => 'red',
'Dead' => 'black'
}.freeze
##
# Checkes if the user attended the event
# This is used for events that require registration
@ -152,6 +164,22 @@ class User < ApplicationRecord
user
end
##
# Returns a hash with user distribution => {value: count of user state, color: color}
# active: signed in during the last 3 months
# unconfirmed: registered but not confirmed
# dead: not signed in during the last year
#
# ====Returns
# * +hash+ -> hash
def self.distribution
{
'Active' => User.active.count,
'Unconfirmed' => User.unconfirmed.count,
'Dead' => User.dead.count
}
end
def self.find_for_database_authentication(warden_conditions)
conditions = warden_conditions.dup
login = conditions.delete(:login)

View file

@ -1,23 +0,0 @@
.text-center
%h4 #{title}
%canvas.doughnut_chart{ id: "dough_#{title.parameterize.underscore}", 'data-chart' => data.to_json }
- if data
- data.each do |key, value|
%span{ 'style' => "border-bottom: 3px solid #{value['color']}" } #{key}: #{value['value']}
:javascript
$(document).ready( function(){
var d = $("#dough_#{title.parameterize.underscore}");
var dt = d.get(0).getContext('2d');
$(window).resize( respondCanvas );
function respondCanvas(){
dt.canvas.width = 150;
dt.canvas.height = 150;
}
respondCanvas();
});

View file

@ -1,47 +0,0 @@
.row
.col-md-12
.text-center
%h4
= title
.row
.col-md-12
.chart_data{ 'data-chart' => "#{y.to_json}", 'data-conferences' => "#{conferences.to_json}",
'data-deactive' => "#{deactive_conferences.to_json}", 'data-weeks' => "#{x.to_json}",
'data-active' => "#{active_conferences.to_json}" }
%canvas.line_chart{ id: "line_chart_#{name}", 'data-name' => "#{name}" }
.row
.col-md-12
.text-center
= unit
.row
.col-md-12
.conferenceCheckboxes{ id: "#{name}Checkboxes", 'data-name' => "#{name}" }
- if active_conferences && deactive_conferences && conferences && conferences.length > 1
- active_conferences.each do |conference|
%div
%span{ 'style' => "border-bottom: 3px solid #{conference[:color]};", 'data-chart' => "#{name}" }
%input{ 'type' => 'checkbox', 'name' => "#{conference[:short_title]}", 'checked' => 'checked' }
#{conference[:short_title]}
- deactive_conferences.each do |conference|
%div
%span{ 'style' => "border-bottom: 3px solid #{conference[:color]};", 'data-chart' => "#{name}" }
%input{ 'type' => 'checkbox', 'name' => "#{conference[:short_title]}" }
#{conference[:short_title]}
:javascript
$(document).ready( function(){
var c = $("#line_chart_#{name}");
var ct = c.get(0).getContext('2d');
var container = $(c).parent();
$(window).resize( respondCanvas );
function respondCanvas(){
c.attr('width', $(container).width() );
c.attr('height', $(container).height() );
}
respondCanvas();
});

View file

@ -1,52 +1,32 @@
= javascript_include_tag 'Chart.min'
.row
.col-sm-3.col-xs-3
= render "shared/big_statistic",
= render "big_statistic",
icon: "user", subtitle: "User", value: @total_user, delta: @new_user
.col-sm-3.col-xs-3
= render "shared/big_statistic",
= render "big_statistic",
icon: "check-square", subtitle: "Registration", value: @total_reg, delta: @new_reg
.col-sm-3.col-xs-3
= render "shared/big_statistic",
= render "big_statistic",
icon: "file-text", subtitle: "Submission", value: @total_submissions, delta: @new_submissions
.col-sm-3.col-xs-3
= render "shared/big_statistic",
= render "big_statistic",
icon: "archive", subtitle: "Withdrawn", value: @total_withdrawn, delta: @new_withdrawn, reverse: true
.row#registrations
.col-md-8
= render partial: 'line_chart', locals: { title: 'Registrations over time',
name: 'registrations',
conferences: @conferences,
active_conferences: @active_conferences,
deactive_conferences: @deactive_conferences,
y: @registrations,
x: @registration_weeks,
unit: 'weeks' }
= render 'line_chart', title: 'Registrations per week', data: @registrations
.col-md-4
= render partial: 'doughnut_chart', locals: { title: 'Events', data: @event_distribution }
= render 'donut_chart', title: 'Events',
data: @event_distribution, colors: @event_distribution_colors
.row#submissions
.col-md-8
= render partial: 'line_chart', locals: { title: 'Submissions over time',
name: 'submissions',
conferences: @conferences,
active_conferences: @active_conferences,
deactive_conferences: @deactive_conferences,
y: @submissions,
x: @cfp_weeks,
unit: 'weeks' }
= render 'line_chart', title: 'Submissions per week', data: @submissions
.col-md-4
= render partial: 'doughnut_chart', locals: { title: 'User', data: @user_distribution }
= render 'donut_chart', title: 'Users',
data: @user_distribution, colors: @user_distribution_colors
.row#tickets
.col-md-8
= render partial: 'line_chart', locals: { title: 'Tickets sold over time',
name: 'tickets',
conferences: @conferences,
active_conferences: @active_conferences,
deactive_conferences: @deactive_conferences,
y: @tickets,
x: @ticket_weeks,
unit: 'weeks' }
= render 'line_chart', title: 'Tickets sold per week', data: @tickets
%br
.row
.col-md-8

View file

@ -1,21 +1,19 @@
= javascript_include_tag 'Chart.min'
%h1
%span.fa.fa-tachometer
Dashboard for #{@conference.title}
%hr
.row
.col-sm-3.col-xs-3
= render "shared/big_statistic",
= render "big_statistic",
icon: "user", subtitle: "Registration", value: @total_reg, delta: @new_reg
.col-sm-3.col-xs-3
= render "shared/big_statistic",
= render "big_statistic",
icon: "check-square", subtitle: "Submission", value: @total_submissions, delta: @new_submissions
.col-sm-3.col-xs-3
= render "shared/big_statistic",
= render "big_statistic",
icon: "file-text", subtitle: "Hour", value: @program_length, delta: @new_program_length
.col-sm-3.col-xs-3
= render "shared/big_statistic",
= render "big_statistic",
icon: "archive", subtitle: "Withdrawn", value: @total_withdrawn, delta: @new_withdrawn
.row
@ -24,37 +22,19 @@
.col-md-8
.row#registrations
.col-md-12
= render partial: 'line_chart', locals: { title: 'Registrations over time',
name: 'registrations',
conferences: [@conference],
active_conferences: [@conference],
deactive_conferences: [],
y: @registrations,
x: @registration_weeks,
unit: 'weeks' }
= render 'line_chart',
title: 'Registrations per week', data: @registrations
.row#submissions
.col-md-12
= render partial: 'line_chart', locals: { title: 'Submissions over time',
name: 'submissions',
conferences: @submissions,
active_conferences: @submissions,
deactive_conferences: [],
y: @submissions_data,
x: @cfp_weeks,
unit: 'weeks' }
= render 'line_chart',
title: 'Submissions per week', data: @submissions
.col-md-4
= render partial: 'todo_list', locals: { conference_progress: @conference_progress,
conference: @conference }
= render 'todo_list',
conference_progress: @conference_progress, conference: @conference
.row#tickets
.col-md-8
= render partial: 'line_chart', locals: { title: 'Tickets sold over time',
name: 'tickets',
conferences: @tickets,
active_conferences: @tickets,
deactive_conferences: [],
y: @tickets_data,
x: @ticket_weeks,
unit: 'weeks' }
= render 'line_chart',
title: 'Tickets sold per week', data: @tickets
%br
.row
.col-md-12#doughnut
@ -75,27 +55,36 @@
.tab-pane.active#distribution_all
.row
.col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Event types', data: @event_type_distribution}
= render 'donut_chart', title: 'Event types',
combined_data: @event_type_distribution
.col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Difficulty levels', data: @difficulty_levels_distribution}
= render 'donut_chart', title: 'Difficulty levels',
combined_data: @difficulty_levels_distribution
.col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Tracks', data: @tracks_distribution}
= render 'donut_chart', title: 'Tracks',
combined_data: @tracks_distribution
.tab-pane#distribution_confirmed
.row
.col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Event types', data: @event_type_distribution_confirmed}
= render 'donut_chart', title: 'Event types',
combined_data: @event_type_distribution_confirmed
.col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Difficulty levels', data: @difficulty_levels_distribution_confirmed}
= render 'donut_chart', title: 'Difficulty levels',
combined_data: @difficulty_levels_distribution_confirmed
.col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Tracks', data: @tracks_distribution_confirmed}
= render 'donut_chart', title: 'Tracks',
combined_data: @tracks_distribution_confirmed
.tab-pane#distribution_withdrawn
.row
.col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Event types', data: @event_type_distribution_withdrawn}
= render 'donut_chart', title: 'Event types',
combined_data: @event_type_distribution_withdrawn
.col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Difficulty levels', data: @difficulty_levels_distribution_withdrawn}
= render 'donut_chart', title: 'Difficulty levels',
combined_data: @difficulty_levels_distribution_withdrawn
.col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Tracks', data: @tracks_distribution_withdrawn}
= render 'donut_chart', title: 'Tracks',
combined_data: @tracks_distribution_withdrawn
.row
.col-md-8

View file

@ -1,5 +1,3 @@
= javascript_include_tag 'Chart.min'
.row
.col-md-12
.page-header
@ -47,17 +45,14 @@
= f.submit 'Add', class: 'btn btn-primary'
.row
.col-md-4
= render 'admin/conferences/doughnut_chart',
title: 'Events state',
data: @event_distribution
= render 'donut_chart', title: 'Events state',
data: @event_distribution, colors: @event_distribution_colors
.col-md-4
= render 'admin/conferences/doughnut_chart',
title: 'Confirmed events scheduled',
data: @scheduled_event_distribution
= render 'donut_chart', title: 'Confirmed events scheduled',
combined_data: @scheduled_event_distribution
.col-md-4
= render 'admin/conferences/doughnut_chart',
title: 'Tracks of confirmed events',
data: @tracks_distribution_confirmed
= render 'donut_chart', title: 'Tracks of confirmed events',
combined_data: @tracks_distribution_confirmed
.row
.col-md-12
.margin-event-table

View file

@ -1,5 +1,3 @@
= javascript_include_tag 'Chart.min'
.container
.row
.col-md-12.page-header
@ -9,11 +7,11 @@
Tickets sold for the conference
.row
.col-md-4
= render partial: 'admin/conferences/doughnut_chart',
locals: { title: 'Tickets sold', data: @tickets_sold_distribution }
= render 'donut_chart', title: 'Tickets sold',
combined_data: @tickets_sold_distribution
.col-md-4
= render partial: 'admin/conferences/doughnut_chart',
locals: {title: 'Tickets turnover', data: @tickets_turnover_distribution}
= render 'donut_chart', title: 'Tickets turnover',
combined_data: @tickets_turnover_distribution
%br
- if @physical_tickets.any?
.row

View file

@ -1,5 +1,3 @@
= javascript_include_tag 'Chart.min'
.row
.col-md-12
.page-header
@ -14,10 +12,12 @@
%p.text-muted
All the people who registered to your event
.col-md-4
= render partial: 'admin/conferences/doughnut_chart', locals: {title: 'Affiliation', data: @affiliation_distribution}
= render 'donut_chart', title: 'Affiliation',
combined_data: @affiliation_distribution
- unless @conference.pending?
.col-md-4
= render partial: 'admin/conferences/doughnut_chart', locals: {title: 'Attended registrations', data: @registration_distribution}
= render 'donut_chart', title: 'Attended registrations',
combined_data: @registration_distribution
.row
.col-md-12
%div.margin-event-table

View file

@ -1,6 +1,3 @@
= javascript_include_tag "//www.google.com/jsapi", "chartkick"
= javascript_include_tag 'chartkick'
= bar_chart @survey.survey_questions.map{ |q| [q.title, q.survey_replies.count] }
- @survey.survey_questions.each.with_index(1) do |survey_question, question_index|

View file

@ -0,0 +1,16 @@
:ruby
combined_data ||= {}
data ||= chart_values(combined_data)
colors ||= chart_colors(combined_data)
options = {
donut: true,
legend: 'bottom',
download: true,
messages: { empty: 'No data' }
}
options[:colors] = colors if colors.present?
.text-center
%h4= title
= pie_chart data, options

View file

@ -0,0 +1,15 @@
:ruby
options = {
legend: 'bottom',
download: true,
messages: { empty: 'No data' }
}
.row
.col-md-12
.text-center
%h4
= title
.row
.col-md-12
= line_chart data, options

View file

@ -50,4 +50,5 @@
Performance data is available on
#{link_to "Skylight", ENV["SKYLIGHT_PUBLIC_DASHBOARD_URL"]}.
= yield :script_body
= yield :charts_js
= piwik_tracking_tag