diff --git a/app/controllers/problems_controller.rb b/app/controllers/problems_controller.rb
--- a/app/controllers/problems_controller.rb
+++ b/app/controllers/problems_controller.rb
@@ -148,6 +148,9 @@
@summary = { attempt: user.count, solve: 0 }
user.each_value { |v| @summary[:solve] += 1 if v == 1 }
+
+ #for new graph
+ @chart_dataset = @problem.get_jschart_history.to_json.html_safe
end
def manage
diff --git a/app/controllers/report_controller.rb b/app/controllers/report_controller.rb
--- a/app/controllers/report_controller.rb
+++ b/app/controllers/report_controller.rb
@@ -248,7 +248,7 @@
#@histogram = { data: Array.new(range,0), summary: {} }
@summary = {count: 0, solve: 0, attempt: 0}
user = Hash.new(0)
- Submission.where(problem_id: @problem.id).find_each do |sub|
+ Submission.where(problem_id: @problem.id).includes(:language).each do |sub|
#histogram
d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
#@histogram[:data][d.to_i] += 1 if d < range
@@ -257,7 +257,8 @@
@summary[:count] += 1
user[sub.user_id] = [user[sub.user_id], (sub.points >= @problem.full_score) ? 1 : 0].max
- lang = Language.find_by_id(sub.language_id)
+ #lang = Language.find_by_id(sub.language_id)
+ lang = sub.language
next unless lang
next unless sub.points >= @problem.full_score
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -130,27 +130,21 @@
def stat
@user = User.find(params[:id])
- @submission = Submission.joins(:problem).where(user_id: params[:id])
+ @submission = Submission.joins(:problem).includes(:problem).includes(:language).where(user_id: params[:id])
@submission = @submission.where('problems.available = true') unless current_user.admin?
- range = 120
- @histogram = { data: Array.new(range,0), summary: {} }
@summary = {count: 0, solve: 0, attempt: 0}
problem = Hash.new(0)
@submission.find_each do |sub|
- #histogram
- d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
- @histogram[:data][d.to_i] += 1 if d < range
-
@summary[:count] += 1
next unless sub.problem
problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max
end
- @histogram[:summary][:max] = [@histogram[:data].max,1].max
@summary[:attempt] = problem.count
problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
+ @chart_dataset = @user.get_jschart_user_sub_history.to_json.html_safe
end
def toggle_activate
diff --git a/app/models/user.rb b/app/models/user.rb
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -314,6 +314,21 @@
User.update_all(:last_ip => nil)
end
+ def get_jschart_user_sub_history
+ start = 4.month.ago.beginning_of_day
+ start_date = start.to_date
+ count = Submission.where(user: self).where('submitted_at >= ?', start).group('DATE(submitted_at)').count
+ i = 0
+ label = []
+ value = []
+ while (start_date + i < Time.zone.now.to_date)
+ label << (start_date+i).strftime("%d-%b")
+ value << (count[start_date+i] || 0)
+ i+=1
+ end
+ return {labels: label,datasets: [label:'sub',data: value, backgroundColor: 'rgba(54, 162, 235, 0.2)', borderColor: 'rgb(75, 192, 192)']}
+ end
+
#create multiple user, one per lines of input
def self.create_from_list(lines)
error_logins = []
diff --git a/app/views/application/_bar_graph.html.haml b/app/views/application/_bar_graph.html.haml
deleted file mode 100644
--- a/app/views/application/_bar_graph.html.haml
+++ /dev/null
@@ -1,44 +0,0 @@
-- param = {} unless param
-- graph_height = param[:graph_height] || 100
-- bar_width = param[:bar_width] || 14
-- graph_width = (bar_width * histogram[:data].count) + 20
-:css
- .hist_bar {
- width: #{bar_width-1}px;
- position: absolute;
- background-color: lightblue;
- }
- .hist_fill {
- width: #{bar_width-1}px;
- position: absolute;
- background-color: #eee;
- }
- .hist_text {
- position: absolute;
- font-size:5px;
- }
-
-%div{style: "position: relative; width: #{graph_width}px; height: 125px; background-color:#fff;" }
- //draw background
- - histogram[:data].each_index do |i|
- - height = histogram[:data][i] * graph_height / histogram[:summary][:max]
- - top = graph_height - height
- - left = graph_width - (i+1)*bar_width
- %div.hist_fill{style: "top: 0px; height: #{graph_height - height}px; left: #{left}px;" }
- // draw horizontal line
- - line = 3
- - line.times do |i|
- - top = graph_height - graph_height * (i+0.5)/ line
- %div{style: "position:absolute;width: #{graph_width-21}px;height: 1px;left: 20px;top:#{top}px;background-color: #333;"}
- %div.hist_text{style: "position:absolute;left: 0px;top:#{top-6}px"}
- =((i+0.5) * histogram[:summary][:max] / line).to_i
- // draw the actual bar and text
- - @histogram[:data].each_index do |i|
- - height = histogram[:data][i] * graph_height / histogram[:summary][:max]
- - top = graph_height - height
- - left = graph_width - (i+1)*bar_width
- %div.hist_bar{style: "top: #{top}px; height: #{height}px; left: #{left}px; dae: #{histogram[:data][i]}" }
- - if i % 7 == 1
- %div.hist_text{style: "top:#{graph_height + 5}px;left: #{left}px;"} #{(Time.zone.today - i.day).strftime('%-d')}
- - if (Time.now.in_time_zone - i.day).day == 15
- %div.hist_text{style: "top:#{graph_height + 15}px;left: #{left}px;"} #{(Time.zone.today - i.day).strftime('%b')}
diff --git a/app/views/application/_submission_short.html.haml b/app/views/application/_submission_short.html.haml
--- a/app/views/application/_submission_short.html.haml
+++ b/app/views/application/_submission_short.html.haml
@@ -3,21 +3,21 @@
- else
- if local_assigns[:show_id]
.row
- .col-3.text-secondary
- Sub ID:
- %strong.col-9= submission.id
+ .col-3.fw-bold
+ Sub ID
+ .col-9.text-secondary-x= submission.id
- unless submission.graded_at
.row
- .col-3.text-secondary= t 'main.submitted_at'
- %strong.col-9= format_full_time_ago(submission.submitted_at.localtime)
+ .col-3.fw-bold= t 'main.submitted_at'
+ .col-9.text-secondary-x= format_full_time_ago(submission.submitted_at.localtime)
- else
.row
- .col-3.text-secondary= t 'main.graded_at'
- %strong.col-9= format_full_time_ago(submission.graded_at.localtime)
+ .col-3.fw-bold= t 'main.graded_at'
+ .col-9.text-secondary-x= format_full_time_ago(submission.graded_at.localtime)
- if GraderConfiguration['ui.show_score']
.row
- .col-3.text-secondary=t 'main.score'
- %strong.col-9
+ .col-3.fw-bold=t 'main.score'
+ .col-9.text-secondary-x
= (submission.points*100/submission.problem.full_score).to_i
%tt.grader-comment
= " [#{submission.grader_comment}]"
diff --git a/app/views/problems/manage.html.haml b/app/views/problems/manage.html.haml
--- a/app/views/problems/manage.html.haml
+++ b/app/views/problems/manage.html.haml
@@ -2,51 +2,29 @@
= stylesheet_link_tag 'problems'
= javascript_include_tag 'local_jquery'
-:javascript
- $(document).ready( function() {
- function shiftclick(start,stop,value) {
- $('tr input').each( function(id,input) {
- var $input=$(input);
- var iid=parseInt($input.attr('id').split('-')[2]);
- if(iid>=start&&iid<=stop){
- $input.prop('checked',value)
- }
- });
- }
-
- $('tr input').click( function(e) {
- if (e.shiftKey) {
- stop = parseInt($(this).attr('id').split('-')[2]);
- var orig_stop = stop
- if (typeof start !== 'undefined') {
- if (start > stop) {
- var tmp = start;
- start = stop;
- stop = tmp;
- }
- shiftclick(start,stop,$(this).is(':checked') )
- }
- start = orig_stop
- } else {
- start = parseInt($(this).attr('id').split('-')[2]);
- }
- });
- });
%h1 Manage problems
%p= link_to '[Back to problem list]', problems_path
-= form_tag :action=>'do_manage' do
- .panel.panel-primary
- .panel-heading
+= form_with url: do_manage_problems_path do |f|
+ .card.border-primary.mb-2
+ .card-header.text-bg-primary.border-primary
Action
- .panel-body
+ .card-body
.submit-box
What do you want to do to the selected problem?
%br/
(You can shift-click to select a range of problems)
+ .row
+ .col-md-auto
+ = f.check_box :change_date_added, class: 'form-check-input'
+ .col-md-auto
+ .form-check-label
+ Change "Date added" to
+ .col-md-auto
+
%ul.form-inline
%li
Change "Date added" to
@@ -107,13 +85,45 @@
= "(#{contest.name} [#{link_to 'x', :action => 'remove_contest', :id => problem.id, :contest_id => contest.id }])"
:javascript
- $('.input-group.date').datetimepicker({
- format: 'DD/MMM/YYYY',
- showTodayButton: true,
- locale: 'en',
- widgetPositioning: {horizontal: 'auto', vertical: 'bottom'},
+
+ $(document).on('import-map-loaded', function() {
+ function shiftclick(start,stop,value) {
+ $('tr input').each( function(id,input) {
+ var $input=$(input);
+ var iid=parseInt($input.attr('id').split('-')[2]);
+ if(iid>=start&&iid<=stop){
+ $input.prop('checked',value)
+ }
+ });
+ }
+ $('tr input').click( function(e) {
+ if (e.shiftKey) {
+ stop = parseInt($(this).attr('id').split('-')[2]);
+ var orig_stop = stop
+ if (typeof start !== 'undefined') {
+ if (start > stop) {
+ var tmp = start;
+ start = stop;
+ stop = tmp;
+ }
+ shiftclick(start,stop,$(this).is(':checked') )
+ }
+ start = orig_stop
+ } else {
+ start = parseInt($(this).attr('id').split('-')[2]);
+ }
+ });
+
+ $('.input-group.date').datetimepicker({
+ format: 'DD/MMM/YYYY',
+ showTodayButton: true,
+ locale: 'en',
+ widgetPositioning: {horizontal: 'auto', vertical: 'bottom'},
+
+ });
+
+ $('.datatable').DataTable({
+ paging: false
+ });
});
- $('.datatable').DataTable({
- paging: false
- });
diff --git a/app/views/problems/stat.html.haml b/app/views/problems/stat.html.haml
--- a/app/views/problems/stat.html.haml
+++ b/app/views/problems/stat.html.haml
@@ -4,28 +4,34 @@
}
%h1 Problem stat: #{@problem.name}
-%h2 Overview
+
+.row.mb-3
+ .col-md-8
+ .card
+ .card-body
+ %h2.card-title Submission History
+ %canvas#chart{height: '50px'}
-.row
- .col-md-2
- %strong Name:
- .col-md-10
- = @problem.full_name #in_place_editor_field :problem, :full_name, {}, :rows=>1
- = link_to_description_if_any "[#{t 'main.problem_desc'}] ".html_safe, @problem
-.row
- .col-md-2.strong
- %strong Submissions:
- .col-md-10
- = @submissions.count
-.row
- .col-md-2.strong
- %strong Solved/Attemped User
- .col-md-10
- #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
-
-
-%h2 Submissions Count
-= render partial: 'application/bar_graph', locals: { histogram: @histogram }
+ .col-md-4
+ .card
+ .card-body
+ %h2.card-title General Info
+ .row
+ .col-sm-6
+ Name
+ .col-sm-6
+ = @problem.full_name #in_place_editor_field :problem, :full_name, {}, :rows=>1
+ = link_to_description_if_any "[#{t 'main.problem_desc'}] ".html_safe, @problem
+ .row
+ .col-sm-6
+ Subs
+ .col-sm-6
+ = @submissions.count
+ .row
+ .col-sm-6
+ Solved/Attempted User
+ .col-sm-6
+ #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
%h2 Submissions
- if @submissions and @submissions.count > 0
@@ -58,6 +64,27 @@
No submission
:javascript
- $("#main_table").DataTable({
- paging: false
+ $(document).on('import-map-loaded',(e) => {
+ //init datatable
+ $("#main_table").DataTable({
+ paging: false
+ });
+
+ //history graph
+ data = #{@chart_dataset}
+ config = {
+ type: 'bar',
+ data: data,
+ options: {
+ plugins: {
+ legend: {
+ display: false
+ },
+ },
+ }
+ }
+ Chart.defaults.font.size = 15
+ //Chart.defaults.font.family = 'Sarabun Light'
+ chart = new Chart($('#chart'),config)
});
+
diff --git a/app/views/users/stat.html.haml b/app/views/users/stat.html.haml
--- a/app/views/users/stat.html.haml
+++ b/app/views/users/stat.html.haml
@@ -1,42 +1,46 @@
-- content_for :header do
- = javascript_include_tag 'local_jquery'
-
-:javascript
- $(function () {
- $('#submission_table').tablesorter({widgets: ['zebra']});
- });
:css
.fix-width {
font-family: Droid Sans Mono,Consolas, monospace, mono, Courier New, Courier;
}
-%h1= @user.full_name
+%h1 User stats
+%h5.text-secondary= @user.login
+
+.row.my-3
+ .col-md-8
+ .card
+ .card-body
+ %h2.card-title Sub Info
+ %canvas#chart{height: '50px'}
-Login: #{@user.login}
-Full name: #{@user.full_name}
+ .col-md-4
+ .card
+ .card-body
+ %h2.card-title General Info
+ .row
+ .col-sm-6.fw-bold
+ Login
+ .col-sm-6
+ = @user.login
+ .row
+ .col-sm-6.fw-bold
+ Full name
+ .col-sm-6
+ = @user.full_name
+ .row
+ .col-sm-6.fw-bold
+ Subs
+ .col-sm-6
+ = @summary[:count]
+ .row
+ .col-sm-6.fw-bold
+ Solved/Attempted Problem
+ .col-sm-6
+ #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
-%h2 Problem Stat
-%table.info
- %thead
- %tr.info-head
- %th Stat
- %th Value
- %tbody
- %tr{class: cycle('info-even','info-odd')}
- %td.info_param Submissions
- %td= @summary[:count]
- %tr{class: cycle('info-even','info-odd')}
- %td.info_param Solved/Attempted Problem
- %td #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
-
-%h2 Submission History
-
-=render partial: 'application/bar_graph', locals: {histogram: @histogram, param: {bar_width: 7}}
-
-
-%table#submission_table.table.table-striped
+%table#main_table.table.table-striped
%thead
%tr
%th ID
@@ -65,6 +69,27 @@
:javascript
- $("#submission_table").DataTable({
- paging: false
+ $(document).on('import-map-loaded',(e) => {
+ //init datatable
+ $("#main_table").DataTable({
+ paging: false
+ });
+
+ //history graph
+ data = #{@chart_dataset}
+ config = {
+ type: 'bar',
+ data: data,
+ options: {
+ plugins: {
+ legend: {
+ display: false
+ },
+ },
+ }
+ }
+ Chart.defaults.font.size = 15
+ //Chart.defaults.font.family = 'Sarabun Light'
+ chart = new Chart($('#chart'),config)
});
+