Add criteria color setting.(points' color in plot)

This commit is contained in:
BoHung Chiu 2021-11-09 00:55:55 +08:00
parent 4be6dc74f9
commit dedbe340ac
7 changed files with 222 additions and 32 deletions

View File

@ -84,7 +84,7 @@ class Admin::SurveysController < OrbitAdminController
total = 0
@survey.survey_questions.each do |ques|
ques.survey_question_options.each do |opt|
p = (opt.points == nil ? 0 : opt.points) rescue 0
p = (opt.points == nil ? 0 : opt.points) * ques.weight rescue 0
total = total + p
end
end
@ -118,15 +118,20 @@ class Admin::SurveysController < OrbitAdminController
total = 0
@survey.survey_questions.each do |ques|
ques.survey_question_options.each do |opt|
p = (opt.points == nil ? 0 : opt.points) rescue 0
p = (opt.points == nil ? 0 : opt.points) * ques.weight rescue 0
total = total + p
end
end
@survey.total_points = total
respond_to do |format|
if @survey.update_attributes(survey_params)
@survey.update_answer_score
@survey.update_total_weight
Thread.new do
@survey.update_answer_score
@survey.update_total_weight
if @survey.need_assign_color && @survey.need_update_color
@survey.update_answers_color
end
end
if params[:et] == "result"
format.html { redirect_to(set_answers_admin_survey_path(@survey.id)) }
else
@ -262,7 +267,6 @@ class Admin::SurveysController < OrbitAdminController
format.xml { render :xml => @survey, :status => :created, :location => @new_survey }
end
end
private
def set_survey

View File

@ -257,6 +257,48 @@ class SurveysController < ApplicationController
@answer_model.scored_points = total
@answer_model.individual_total = individual_total
@answer_model.consent_used = answer[:consent_used]
if @survey.need_assign_color
tmp_result_criteria = @survey.result_criteria.map{|c| {"q"=>c["questions"].map{|q| q.to_i},"r"=>c["range"].map{|r| r.to_i},"c"=>c["color"].blank? ? '#ffffff' : c["color"],"t"=>c["type"].to_i}}
survey_questions_count = @survey.survey_questions.count
weight_relations = @survey.survey_questions.map{|q| [q.id.to_s,(q.weight.nil? ? 1 : q.weight)]}.to_h
if tmp_result_criteria.select{|criteria| (criteria["q"][0] != 1 || criteria["q"][1] != survey_questions_count rescue true)}.count != 0
answer_model_attrs = answer
tmp_result_criteria.each do |c|
total_weight = 0
range = (c["r"].count != 2 ? [0,100] : c["r"])
questions = c["q"].map{|q| (q == 0 ? 0 : q - 1)}
total = 0
questions.each do |x|
if c["t"] == 1
k = weight_relations.keys[x]
if k && answer_model_attrs.has_key?(k)
total_weight += weight_relations[k]
end
end
total += a.individual_total[x].to_i
end
if c["t"] == 0
if (range[0]..range[1]).cover?(total)
@answer_model.color = c["color"]
break
end
else
avg = (total / total_weight rescue 0)
if (range[0]..range[1]).cover?(avg)
@answer_model.color = c["color"]
break
end
end
end
else
tmp_result_criteria.each do |c|
if (c["r"][0]..c["r"][1]).cover?(@answer_model.scored_points)
@answer_model.color = c["color"]
break
end
end
end
end
@answer_model.save!
params[:url] = params[:show_page_url]
OrbitHelper.set_params(params,current_user)

View File

@ -12,6 +12,8 @@ class QuestionnaireSurvey
include OrbitCategory::Categorizable
scope :can_display, ->{where(is_hidden: false)}
field :need_assign_color, :type => Boolean, :default => false
field :need_update_color, :type => Boolean, :default => false
field :enable_consent_feature, :type => Boolean, :default => false
field :consent_contents, :type => String, :default => "", :localize => true
field :already_fix_data, :type => Boolean, :default => false
@ -51,7 +53,7 @@ class QuestionnaireSurvey
accepts_nested_attributes_for :survey_questions, :allow_destroy => true
before_save :check_deadline#, :update_avliable_language
before_save :check_deadline, :check_need_update #, :update_avliable_language
has_many :survey_paginations, :autosave => true, :dependent => :destroy
accepts_nested_attributes_for :survey_paginations, :allow_destroy => true
@ -63,6 +65,71 @@ class QuestionnaireSurvey
self.updated_at = DateTime.now
end
end
def check_need_update
if self.result_criteria_changed?
old_colors = self.result_criteria_was.map{|c| c["color"].blank? ? '#ffffff' : c["color"]}
new_colors = self.result_criteria.map{|c| c["color"].blank? ? '#ffffff' : c["color"]}
new_colors_uniq_count = new_colors.uniq.count
self.need_assign_color = (new_colors_uniq_count > 1)
if old_colors != new_colors
self.need_update_color = true
elsif new_colors_uniq_count > 1
old_questions = self.result_criteria_was.map{|c| c["questions"]}
old_range = self.result_criteria_was.map{|c| c["range"]}
new_questions = self.result_criteria.map{|c| c["questions"]}
new_range = self.result_criteria.map{|c| c["range"]}
if old_questions != new_questions || old_range != new_range
self.need_update_color = true
end
end
end
end
def update_answers_color
puts "Updating answer's color"
tmp_result_criteria = self.result_criteria.map{|c| {"q"=>c["questions"].map{|q| q.to_i},"r"=>c["range"].map{|r| r.to_i},"c"=>c["color"].blank? ? '#ffffff' : c["color"],"t"=>c["type"].to_i}}
survey_questions_count = self.survey_questions.count
weight_relations = self.survey_questions.map{|q| [q.id.to_s,(q.weight.nil? ? 1 : q.weight)]}.to_h
if tmp_result_criteria.select{|criteria| (criteria["q"][0] != 1 || criteria["q"][1] != survey_questions_count rescue true)}.count != 0
self.survey_answers.each do |a|
answer_model_attrs = a.attributes
tmp_result_criteria.each do |c|
total_weight = 0
range = (c["r"].count != 2 ? [0,100] : c["r"])
questions = c["q"].map{|q| (q == 0 ? 0 : q - 1)}
total = 0
questions.each do |x|
if c["t"] == 1
k = weight_relations.keys[x]
if k && answer_model_attrs.has_key?(k)
total_weight += weight_relations[k]
end
end
total += a.individual_total[x].to_i
end
if c["t"] == 0
if (range[0]..range[1]).cover?(total)
a.color = c["color"]
a.save
break
end
else
avg = (total / total_weight rescue 0)
if (range[0]..range[1]).cover?(avg)
a.color = c["color"]
a.save
break
end
end
end
end
else
tmp_result_criteria.each do |c|
range = (c["r"].count != 2 ? [0,100] : c["r"])
self.survey_answers.where(:scored_points.gte=>c["r"][0]).and(:scored_points.lte=>c["r"][1]).update_all(:color=>c["c"])
end
end
self.update(:need_update_color=>false)
end
def get_answer_repeat
self.needs_login && self.answer_repeat
end
@ -120,7 +187,7 @@ class QuestionnaireSurvey
answers =(0...survey_answers.count).map{{}}
survey_answers.each_with_index do |answer,i|
answers[i]["name"] = User.find(answer.user).member_name rescue ""
answers[i]["agree"] = I18n.t("survey.#{answer.consent_used}")
answers[i]["agree"] = I18n.t("self.#{answer.consent_used}")
end
SurveysHelper.set_locale(I18n.locale)
survey_questions.each do |question|
@ -378,6 +445,7 @@ class QuestionnaireSurvey
end
def update_answer_score
if self.survey_questions.where(:need_update_score => true).count != 0
self.update(:need_update_color=>true)
puts "Updating answer's scores"
tmp_weights = []
tmp_score_data = self.survey_questions.map do |question|

View File

@ -9,6 +9,7 @@ class SurveyAnswer
field :avg_points, type: Integer
field :individual_total, type: Array, :default => []
field :select_question, type: Array, :default => []
field :color, type: String
belongs_to :questionnaire_survey
after_create do
if self.questionnaire_survey

View File

@ -93,11 +93,21 @@
}
</style>
<script>
<% data = @survey_answers.order_by(:updated_at=>1).map{|sa| [sa.updated_at.to_i * 1000 , sa.scored_points ]} %>
var min_time = <%= data[0][0] rescue 0 %>;
var max_time = <%= data[-1][0] rescue 0 %>;
var min_y = <%= data.map{|a| a[1]}.min.to_i %>;
var max_y = <%= data.map{|a| a[1]}.max.to_i %>;
<% if @survey.need_assign_color %>
<% data = @survey_answers.order_by(:updated_at=>1).group_by(&:color).map{|k,sas| [k, sas.map{|sa| [sa.updated_at.to_i * 1000 , sa.scored_points ]} ] }.to_h %>
var min_time = <%= data.map{|k,d| d[0][0] rescue 0}.min %>;
var max_time = <%= data.map{|k,d| d[-1][0] rescue 0}.max %>;
<% all_data = data.values.flatten(1) %>
<% y_data = all_data.map{|v| v[1]} %>
var min_y = <%= y_data.min.to_i %>;
var max_y = <%= y_data.max.to_i %>;
<% else %>
<% data = @survey_answers.order_by(:updated_at=>1).map{|sa| [sa.updated_at.to_i * 1000 , sa.scored_points ]} %>
var min_time = <%= data[0][0] rescue 0 %>;
var max_time = <%= data[-1][0] rescue 0 %>;
var min_y = <%= data.map{|a| a[1]}.min.to_i %>;
var max_y = <%= data.map{|a| a[1]}.max.to_i %>;
<% end %>
var xaxes = [{
mode: "time",
axisLabelUseCanvas: false,
@ -138,7 +148,8 @@
},
points: {
radius: 5,
show: true
show: true,
fillColor: '#ffffff'
},
downsample: {
threshold: 0
@ -158,8 +169,8 @@
interactive: true,
enableTouch: true
},
colors: ["#708fff","#ffc107","#96478c","#1e7e34"],
polycolors: ["#3f66f4","#ffc107","#dc3545","#1e7e34"],
colors: ["#708fff"], //["#708fff","#ffc107","#96478c","#1e7e34"],
polycolors: ["#3f66f4"],//["#3f66f4","#ffc107","#dc3545","#1e7e34"],
// legend: {
// show: true,
// noColumns: 1
@ -168,8 +179,33 @@
zero: false
}
};
<% all_colors = @survey.result_criteria.map{|c| c["color"]}.select{|c| c.present?}.uniq %>
var points_fillColor = "#ffffff";
var need_split_data = false;
<% if all_colors.count == 1 %>
points_fillColor = "<%=all_colors[0]%>";
<% end %>
// options['legend']['container'] = $('.legend-container')[0];
var chart_data = [{"label": "<%=@user.member_name rescue "NA" %>", "data": <%= data.to_json.html_safe %>}];
<% if @survey.need_assign_color %>
options["series"]["lines"]["show"] = false;
<% label_name = @user.member_name rescue "NA" %>
var chart_data = <%= ([{"label"=> label_name, "data"=> all_data,
"color"=> "#708fff",
"lines"=> {
"show"=> true,
"lineWidth"=> 2,
"steps"=> false ,
"is_sort"=> true
}}] + data.map{|color,d| tmp_color=(color.blank? ? "#ffffff" : color);{"label"=>label_name, "data"=>d, "color"=> (tmp_color == "#ffffff" ? "#708fff" : tmp_color), "points"=>{
"show"=> true,
"fillColor"=> tmp_color
}}}).to_json.html_safe %>;
<% else %>
var chart_data = [{"label": "<%=@user.member_name rescue "NA" %>", "data": <%= data.to_json.html_safe %>,"points": {
show: true,
fillColor: points_fillColor
}}];
<% end %>
$(document).ready(function(){
var chart_height = $(window).outerWidth(true)*0.2;
$("#resultchart-container").height(chart_height).plot(chart_data,options);
@ -255,7 +291,7 @@
<% types << type %>
<% end %>
<% else %>
<% if (criteria["range"][0].to_i..criteria["range"][1].to_i).cover?(total_criteria_score / total_weight) %>
<% if ((criteria["range"][0].to_i..criteria["range"][1].to_i).cover?(total_criteria_score / total_weight) rescue false) %>
<% tmp_msgs << criteria["msg"] %>
<% types << type %>
<% end %>

View File

@ -77,8 +77,8 @@
<% if @survey.result_criteria.blank? %>
<div class="criteria-block">
<div class="criteria" style="margin-left:0px;display:block;">
<label style="padding-left:0px;" for="" class="radio inline"> Question from : <input name="questionnaire_survey[result_criteria][0][questions][]" class="span1" max="<%= @surveysurvey_questionscount %>" type="number" min="1"></label>
<label for="" class="radio inline"> Question to : <input name="questionnaire_survey[result_criteria][0][questions][]" class="span1" min="1" max="<%= @survey.survey_questions.count %>" type="number"></label>
<label style="padding-left:0px;" for="" class="radio inline"> Question from : <input name="questionnaire_survey[result_criteria][0][questions][]" class="span1" max="<%= @surveysurvey_questionscount %>" type="number" min="1" value="1"></label>
<label for="" class="radio inline"> Question to : <input name="questionnaire_survey[result_criteria][0][questions][]" class="span1" min="1" max="<%= @survey.survey_questions.count %>" value="<%= @survey.survey_questions.count %>" type="number"></label>
</div>
<div class="criteria" style="margin-left:0px;display:block;">
<label style="padding-left:0px;" for="" class="radio inline"> Type : <select name="questionnaire_survey[result_criteria][0][type]">
@ -107,13 +107,16 @@
<% end %>
</select></label>
</div>
<div class="criteria" style="margin-left:0px;display:block;margin-bottom:50px;">
<div class="criteria" style="margin-left:0px;display:block;">
<label style="padding-left:0px;" for="" class="radio inline"> From : <input name="questionnaire_survey[result_criteria][<%= idx %>][range][]" class="span1" max="<%= @survey.total_points %>" type="number" value="<%= criteria["range"][0] rescue "" %>"></label>
<label for="" class="radio inline"> To : <input name="questionnaire_survey[result_criteria][<%= idx %>][range][]" class="span1" max="<%= @survey.total_points %>" type="number" value="<%= criteria["range"][1] rescue "" %>"></label>
<% if idx != 0 %>
<a href="" style="margin-left:5px;" class="btn btn-danger delete-critera"><i class="icon icon-trash"></i></a>
<% end %>
</div>
<div class="criteria" style="margin-left:0px;display:block;margin-bottom:50px;">
<label style="padding-left:0px;" for="" class="radio inline"> Color : <input type="color" name="questionnaire_survey[result_criteria][<%= idx %>][color]" value="<%=criteria["color"].blank? ? "#ffffff" : criteria["color"] %>"></label>
</div>
<div class="criteria">
<label for="" class="radio inline">
<textarea class="ckeditor" id="questionnaire_survey_result_criteria_<%= idx %>_msg" name="questionnaire_survey[result_criteria][<%= idx %>][msg]"><%= criteria["msg"] rescue "" %></textarea>
@ -144,11 +147,11 @@
$(".selectable[data-type=" + selectedOption.value + "]").removeClass("hide");
}
var index = <%= @survey.result_criteria.count == 0 ? 1 : @survey.result_criteria.count + 1 %>,
html = '<div class="criteria-block"><div><label style="padding-left:0px;" for="" class="radio inline"> Questions from : <input name="questionnaire_survey[result_criteria][{index}][questions][]" class="span1" min="1" max="<%= @survey.survey_questions.count %>" type="number"></label><label for="" class="radio inline"> Questions to : <input name="questionnaire_survey[result_criteria][{index}][questions][]" class="span1" min="1" max="<%= @survey.survey_questions.count %>" type="number"></label></div><div data-critera-number="criteria_{index}" class="criteria" style="margin-left:0px;display:block;"><label style="padding-left:0px;" for="" class="radio inline"> Type : <select name="questionnaire_survey[result_criteria][{index}][type]">'
html = '<div class="criteria-block"><div><label style="padding-left:0px;" for="" class="radio inline"> Questions from : <input name="questionnaire_survey[result_criteria][{index}][questions][]" class="span1" min="1" max="<%= @survey.survey_questions.count %>" type="number" value="1"></label><label for="" class="radio inline"> Questions to : <input name="questionnaire_survey[result_criteria][{index}][questions][]" class="span1" min="1" max="<%= @survey.survey_questions.count %>" type="number" value="<%= @survey.survey_questions.count %>"></label></div><div data-critera-number="criteria_{index}" class="criteria" style="margin-left:0px;display:block;"><label style="padding-left:0px;" for="" class="radio inline"> Type : <select name="questionnaire_survey[result_criteria][{index}][type]">'
<% [0,1].each do |i| %>
html += '<option value="<%=i%>"><%=t("survey.type.#{i}")%></option>'
<% end %>
html += '</select></label></div><div data-critera-number="criteria_{index}" class="criteria" style="width:800px;"><label style="padding-left:0px;" for="" class="radio inline"> From : <input name="questionnaire_survey[result_criteria][{index}][range][]" class="span1" max="<%= @survey.total_points %>" type="number"></label><label for="" class="radio inline"> To : <input name="questionnaire_survey[result_criteria][{index}][range][]" class="span1" max="<%= @survey.total_points %>" type="number"></label><a href="" style="margin-left:5px;" class="btn btn-primary delete-critera"><i class="icon icon-trash"></i></a><span class="radio inline">Save to add text</span></div></div>';
html += '</select></label></div><div data-critera-number="criteria_{index}" class="criteria" style="width:800px;"><label style="padding-left:0px;" for="" class="radio inline"> From : <input name="questionnaire_survey[result_criteria][{index}][range][]" class="span1" max="<%= @survey.total_points %>" type="number"></label><label for="" class="radio inline"> To : <input name="questionnaire_survey[result_criteria][{index}][range][]" class="span1" max="<%= @survey.total_points %>" type="number"></label><a href="" style="margin-left:5px;" class="btn btn-primary delete-critera"><i class="icon icon-trash"></i></a><span class="radio inline">Save to add text</span></div><div class="criteria" style="margin-left:0px;display:block;"><label style="padding-left:0px;" for="" class="radio inline"> Color : <input type="color" name="questionnaire_survey[result_criteria][{index}][color]" value="#ffffff"></label></div></div>';
$("#add-criteria").on("click",function(){
var newhtml = html.replace(/{index}/g,index);

View File

@ -76,11 +76,21 @@
}
</style>
<script>
<% data = @survey_answers.order_by(:updated_at=>1).map{|sa| [sa.updated_at.to_i * 1000 , sa.scored_points ]} %>
var min_time = <%= data[0][0] rescue 0 %>;
var max_time = <%= data[-1][0] rescue 0 %>;
var min_y = <%= data.map{|a| a[1]}.min.to_i %>;
var max_y = <%= data.map{|a| a[1]}.max.to_i %>;
<% if @survey.need_assign_color %>
<% data = @survey_answers.order_by(:updated_at=>1).group_by(&:color).map{|k,sas| [k, sas.map{|sa| [sa.updated_at.to_i * 1000 , sa.scored_points ]} ] }.to_h %>
var min_time = <%= data.map{|k,d| d[0][0] rescue 0}.min %>;
var max_time = <%= data.map{|k,d| d[-1][0] rescue 0}.max %>;
<% all_data = data.values.flatten(1) %>
<% y_data = all_data.map{|v| v[1]} %>
var min_y = <%= y_data.min.to_i %>;
var max_y = <%= y_data.max.to_i %>;
<% else %>
<% data = @survey_answers.order_by(:updated_at=>1).map{|sa| [sa.updated_at.to_i * 1000 , sa.scored_points ]} %>
var min_time = <%= data[0][0] rescue 0 %>;
var max_time = <%= data[-1][0] rescue 0 %>;
var min_y = <%= data.map{|a| a[1]}.min.to_i %>;
var max_y = <%= data.map{|a| a[1]}.max.to_i %>;
<% end %>
var xaxes = [{
mode: "time",
axisLabelUseCanvas: false,
@ -121,7 +131,8 @@
},
points: {
radius: 5,
show: true
show: true,
fillColor: '#ffffff'
},
downsample: {
threshold: 0
@ -141,8 +152,8 @@
interactive: true,
enableTouch: true
},
colors: ["#708fff","#ffc107","#96478c","#1e7e34"],
polycolors: ["#3f66f4","#ffc107","#dc3545","#1e7e34"],
colors: ["#708fff"], //["#708fff","#ffc107","#96478c","#1e7e34"],
polycolors: ["#3f66f4"],//["#3f66f4","#ffc107","#dc3545","#1e7e34"],
// legend: {
// show: true,
// noColumns: 1
@ -151,8 +162,33 @@
zero: false
}
};
<% all_colors = @survey.result_criteria.map{|c| c["color"]}.select{|c| c.present?}.uniq %>
var points_fillColor = "#ffffff";
var need_split_data = false;
<% if all_colors.count == 1 %>
points_fillColor = "<%=all_colors[0]%>";
<% end %>
// options['legend']['container'] = $('.legend-container')[0];
var chart_data = [{"label": "<%=@user.member_name rescue "NA" %>", "data": <%= data.to_json.html_safe %>}];
<% if @survey.need_assign_color %>
options["series"]["lines"]["show"] = false;
<% label_name = @user.member_name rescue "NA" %>
var chart_data = <%= ([{"label"=> label_name, "data"=> all_data,
"color"=> "#708fff",
"lines"=> {
"show"=> true,
"lineWidth"=> 2,
"steps"=> false ,
"is_sort"=> true
}}] + data.map{|color,d| tmp_color=(color.blank? ? "#ffffff" : color);{"label"=>label_name, "data"=>d, "color"=> (tmp_color == "#ffffff" ? "#708fff" : tmp_color), "points"=>{
"show"=> true,
"fillColor"=> tmp_color
}}}).to_json.html_safe %>;
<% else %>
var chart_data = [{"label": "<%=@user.member_name rescue "NA" %>", "data": <%= data.to_json.html_safe %>,"points": {
show: true,
fillColor: points_fillColor
}}];
<% end %>
$(document).ready(function(){
var chart_height = $(window).outerWidth(true)*0.2;
$("#resultchart-container").height(chart_height).plot(chart_data,options);
@ -239,7 +275,7 @@
<% types << type %>
<% end %>
<% else %>
<% if (criteria["range"][0].to_i..criteria["range"][1].to_i).cover?(total_criteria_score / total_weight) %>
<% if ((criteria["range"][0].to_i..criteria["range"][1].to_i).cover?(total_criteria_score / total_weight) rescue false) %>
<% tmp_msgs << criteria["msg"] %>
<% types << type %>
<% end %>