Description:
wip
Commit status:
[Not Reviewed]
References:
Diff options:
Comments:
0 Commit comments
0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
r880:31e27f513ce9 - - 9 files changed: 191 inserted, 160 deleted
@@ -148,6 +148,9 | |||
|
148 | 148 | |
|
149 | 149 | @summary = { attempt: user.count, solve: 0 } |
|
150 | 150 | user.each_value { |v| @summary[:solve] += 1 if v == 1 } |
|
151 | + | |
|
152 | + #for new graph | |
|
153 | + @chart_dataset = @problem.get_jschart_history.to_json.html_safe | |
|
151 | 154 | end |
|
152 | 155 | |
|
153 | 156 | def manage |
@@ -248,7 +248,7 | |||
|
248 | 248 | #@histogram = { data: Array.new(range,0), summary: {} } |
|
249 | 249 | @summary = {count: 0, solve: 0, attempt: 0} |
|
250 | 250 | user = Hash.new(0) |
|
251 |
- Submission.where(problem_id: @problem.id). |
|
|
251 | + Submission.where(problem_id: @problem.id).includes(:language).each do |sub| | |
|
252 | 252 | #histogram |
|
253 | 253 | d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60 |
|
254 | 254 | #@histogram[:data][d.to_i] += 1 if d < range |
@@ -257,7 +257,8 | |||
|
257 | 257 | @summary[:count] += 1 |
|
258 | 258 | user[sub.user_id] = [user[sub.user_id], (sub.points >= @problem.full_score) ? 1 : 0].max |
|
259 | 259 | |
|
260 | - lang = Language.find_by_id(sub.language_id) | |
|
260 | + #lang = Language.find_by_id(sub.language_id) | |
|
261 | + lang = sub.language | |
|
261 | 262 | next unless lang |
|
262 | 263 | next unless sub.points >= @problem.full_score |
|
263 | 264 |
@@ -130,27 +130,21 | |||
|
130 | 130 | |
|
131 | 131 | def stat |
|
132 | 132 | @user = User.find(params[:id]) |
|
133 | - @submission = Submission.joins(:problem).where(user_id: params[:id]) | |
|
133 | + @submission = Submission.joins(:problem).includes(:problem).includes(:language).where(user_id: params[:id]) | |
|
134 | 134 | @submission = @submission.where('problems.available = true') unless current_user.admin? |
|
135 | 135 | |
|
136 | - range = 120 | |
|
137 | - @histogram = { data: Array.new(range,0), summary: {} } | |
|
138 | 136 | @summary = {count: 0, solve: 0, attempt: 0} |
|
139 | 137 | problem = Hash.new(0) |
|
140 | 138 | |
|
141 | 139 | @submission.find_each do |sub| |
|
142 | - #histogram | |
|
143 | - d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60 | |
|
144 | - @histogram[:data][d.to_i] += 1 if d < range | |
|
145 | - | |
|
146 | 140 | @summary[:count] += 1 |
|
147 | 141 | next unless sub.problem |
|
148 | 142 | problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max |
|
149 | 143 | end |
|
150 | 144 | |
|
151 | - @histogram[:summary][:max] = [@histogram[:data].max,1].max | |
|
152 | 145 | @summary[:attempt] = problem.count |
|
153 | 146 | problem.each_value { |v| @summary[:solve] += 1 if v == 1 } |
|
147 | + @chart_dataset = @user.get_jschart_user_sub_history.to_json.html_safe | |
|
154 | 148 | end |
|
155 | 149 | |
|
156 | 150 | def toggle_activate |
@@ -314,6 +314,21 | |||
|
314 | 314 | User.update_all(:last_ip => nil) |
|
315 | 315 | end |
|
316 | 316 | |
|
317 | + def get_jschart_user_sub_history | |
|
318 | + start = 4.month.ago.beginning_of_day | |
|
319 | + start_date = start.to_date | |
|
320 | + count = Submission.where(user: self).where('submitted_at >= ?', start).group('DATE(submitted_at)').count | |
|
321 | + i = 0 | |
|
322 | + label = [] | |
|
323 | + value = [] | |
|
324 | + while (start_date + i < Time.zone.now.to_date) | |
|
325 | + label << (start_date+i).strftime("%d-%b") | |
|
326 | + value << (count[start_date+i] || 0) | |
|
327 | + i+=1 | |
|
328 | + end | |
|
329 | + return {labels: label,datasets: [label:'sub',data: value, backgroundColor: 'rgba(54, 162, 235, 0.2)', borderColor: 'rgb(75, 192, 192)']} | |
|
330 | + end | |
|
331 | + | |
|
317 | 332 | #create multiple user, one per lines of input |
|
318 | 333 | def self.create_from_list(lines) |
|
319 | 334 | error_logins = [] |
@@ -3,21 +3,21 | |||
|
3 | 3 | - else |
|
4 | 4 | - if local_assigns[:show_id] |
|
5 | 5 | .row |
|
6 |
- .col-3. |
|
|
7 |
- Sub ID |
|
|
8 |
- |
|
|
6 | + .col-3.fw-bold | |
|
7 | + Sub ID | |
|
8 | + .col-9.text-secondary-x= submission.id | |
|
9 | 9 | - unless submission.graded_at |
|
10 | 10 | .row |
|
11 |
- .col-3. |
|
|
12 |
- |
|
|
11 | + .col-3.fw-bold= t 'main.submitted_at' | |
|
12 | + .col-9.text-secondary-x= format_full_time_ago(submission.submitted_at.localtime) | |
|
13 | 13 | - else |
|
14 | 14 | .row |
|
15 |
- .col-3. |
|
|
16 |
- |
|
|
15 | + .col-3.fw-bold= t 'main.graded_at' | |
|
16 | + .col-9.text-secondary-x= format_full_time_ago(submission.graded_at.localtime) | |
|
17 | 17 | - if GraderConfiguration['ui.show_score'] |
|
18 | 18 | .row |
|
19 |
- .col-3. |
|
|
20 | - %strong.col-9 | |
|
19 | + .col-3.fw-bold=t 'main.score' | |
|
20 | + .col-9.text-secondary-x | |
|
21 | 21 | = (submission.points*100/submission.problem.full_score).to_i |
|
22 | 22 | %tt.grader-comment |
|
23 | 23 | = " [#{submission.grader_comment}]" |
@@ -2,51 +2,29 | |||
|
2 | 2 | = stylesheet_link_tag 'problems' |
|
3 | 3 | = javascript_include_tag 'local_jquery' |
|
4 | 4 | |
|
5 | - :javascript | |
|
6 | - $(document).ready( function() { | |
|
7 | - function shiftclick(start,stop,value) { | |
|
8 | - $('tr input').each( function(id,input) { | |
|
9 | - var $input=$(input); | |
|
10 | - var iid=parseInt($input.attr('id').split('-')[2]); | |
|
11 | - if(iid>=start&&iid<=stop){ | |
|
12 | - $input.prop('checked',value) | |
|
13 | - } | |
|
14 | - }); | |
|
15 | - } | |
|
16 | - | |
|
17 | - $('tr input').click( function(e) { | |
|
18 | - if (e.shiftKey) { | |
|
19 | - stop = parseInt($(this).attr('id').split('-')[2]); | |
|
20 | - var orig_stop = stop | |
|
21 | - if (typeof start !== 'undefined') { | |
|
22 | - if (start > stop) { | |
|
23 | - var tmp = start; | |
|
24 | - start = stop; | |
|
25 | - stop = tmp; | |
|
26 | - } | |
|
27 | - shiftclick(start,stop,$(this).is(':checked') ) | |
|
28 | - } | |
|
29 | - start = orig_stop | |
|
30 | - } else { | |
|
31 | - start = parseInt($(this).attr('id').split('-')[2]); | |
|
32 | - } | |
|
33 | - }); | |
|
34 | - }); | |
|
35 | 5 | |
|
36 | 6 | |
|
37 | 7 | %h1 Manage problems |
|
38 | 8 | |
|
39 | 9 | %p= link_to '[Back to problem list]', problems_path |
|
40 | 10 | |
|
41 | - = form_tag :action=>'do_manage' do | |
|
42 | - .panel.panel-primary | |
|
43 | - .panel-heading | |
|
11 | + = form_with url: do_manage_problems_path do |f| | |
|
12 | + .card.border-primary.mb-2 | |
|
13 | + .card-header.text-bg-primary.border-primary | |
|
44 | 14 | Action |
|
45 |
- . |
|
|
15 | + .card-body | |
|
46 | 16 | .submit-box |
|
47 | 17 | What do you want to do to the selected problem? |
|
48 | 18 | %br/ |
|
49 | 19 | (You can shift-click to select a range of problems) |
|
20 | + .row | |
|
21 | + .col-md-auto | |
|
22 | + = f.check_box :change_date_added, class: 'form-check-input' | |
|
23 | + .col-md-auto | |
|
24 | + .form-check-label | |
|
25 | + Change "Date added" to | |
|
26 | + .col-md-auto | |
|
27 | + | |
|
50 | 28 | %ul.form-inline |
|
51 | 29 | %li |
|
52 | 30 | Change "Date added" to |
@@ -107,13 +85,45 | |||
|
107 | 85 | = "(#{contest.name} [#{link_to 'x', :action => 'remove_contest', :id => problem.id, :contest_id => contest.id }])" |
|
108 | 86 | |
|
109 | 87 | :javascript |
|
110 | - $('.input-group.date').datetimepicker({ | |
|
111 | - format: 'DD/MMM/YYYY', | |
|
112 | - showTodayButton: true, | |
|
113 | - locale: 'en', | |
|
114 | - widgetPositioning: {horizontal: 'auto', vertical: 'bottom'}, | |
|
88 | + | |
|
89 | + $(document).on('import-map-loaded', function() { | |
|
90 | + function shiftclick(start,stop,value) { | |
|
91 | + $('tr input').each( function(id,input) { | |
|
92 | + var $input=$(input); | |
|
93 | + var iid=parseInt($input.attr('id').split('-')[2]); | |
|
94 | + if(iid>=start&&iid<=stop){ | |
|
95 | + $input.prop('checked',value) | |
|
96 | + } | |
|
97 | + }); | |
|
98 | + } | |
|
115 | 99 | |
|
100 | + $('tr input').click( function(e) { | |
|
101 | + if (e.shiftKey) { | |
|
102 | + stop = parseInt($(this).attr('id').split('-')[2]); | |
|
103 | + var orig_stop = stop | |
|
104 | + if (typeof start !== 'undefined') { | |
|
105 | + if (start > stop) { | |
|
106 | + var tmp = start; | |
|
107 | + start = stop; | |
|
108 | + stop = tmp; | |
|
109 | + } | |
|
110 | + shiftclick(start,stop,$(this).is(':checked') ) | |
|
111 | + } | |
|
112 | + start = orig_stop | |
|
113 | + } else { | |
|
114 | + start = parseInt($(this).attr('id').split('-')[2]); | |
|
115 | + } | |
|
116 | + }); | |
|
117 | + | |
|
118 | + $('.input-group.date').datetimepicker({ | |
|
119 | + format: 'DD/MMM/YYYY', | |
|
120 | + showTodayButton: true, | |
|
121 | + locale: 'en', | |
|
122 | + widgetPositioning: {horizontal: 'auto', vertical: 'bottom'}, | |
|
123 | + | |
|
124 | + }); | |
|
125 | + | |
|
126 | + $('.datatable').DataTable({ | |
|
127 | + paging: false | |
|
128 | + }); | |
|
116 | 129 | }); |
|
117 | - $('.datatable').DataTable({ | |
|
118 | - paging: false | |
|
119 | - }); |
@@ -4,28 +4,34 | |||
|
4 | 4 | } |
|
5 | 5 | |
|
6 | 6 | %h1 Problem stat: #{@problem.name} |
|
7 | - %h2 Overview | |
|
7 | + | |
|
8 | + .row.mb-3 | |
|
9 | + .col-md-8 | |
|
10 | + .card | |
|
11 | + .card-body | |
|
12 | + %h2.card-title Submission History | |
|
13 | + %canvas#chart{height: '50px'} | |
|
8 | 14 | |
|
9 | - .row | |
|
10 | - .col-md-2 | |
|
11 | - %strong Name: | |
|
12 | - .col-md-10 | |
|
13 | - = @problem.full_name #in_place_editor_field :problem, :full_name, {}, :rows=>1 | |
|
14 | - = link_to_description_if_any "[#{t 'main.problem_desc'}] <span class='glyphicon glyphicon-file'></span>".html_safe, @problem | |
|
15 | - .row | |
|
16 | - .col-md-2.strong | |
|
17 | - %strong Submissions: | |
|
18 | - .col-md-10 | |
|
19 | - = @submissions.count | |
|
20 | - .row | |
|
21 | - .col-md-2.strong | |
|
22 | - %strong Solved/Attemped User | |
|
23 | - .col-md-10 | |
|
24 | - #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%) | |
|
25 | - | |
|
26 | - | |
|
27 | - %h2 Submissions Count | |
|
28 | - = render partial: 'application/bar_graph', locals: { histogram: @histogram } | |
|
15 | + .col-md-4 | |
|
16 | + .card | |
|
17 | + .card-body | |
|
18 | + %h2.card-title General Info | |
|
19 | + .row | |
|
20 | + .col-sm-6 | |
|
21 | + Name | |
|
22 | + .col-sm-6 | |
|
23 | + = @problem.full_name #in_place_editor_field :problem, :full_name, {}, :rows=>1 | |
|
24 | + = link_to_description_if_any "[#{t 'main.problem_desc'}] <span class='glyphicon glyphicon-file'></span>".html_safe, @problem | |
|
25 | + .row | |
|
26 | + .col-sm-6 | |
|
27 | + Subs | |
|
28 | + .col-sm-6 | |
|
29 | + = @submissions.count | |
|
30 | + .row | |
|
31 | + .col-sm-6 | |
|
32 | + Solved/Attempted User | |
|
33 | + .col-sm-6 | |
|
34 | + #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%) | |
|
29 | 35 | |
|
30 | 36 | %h2 Submissions |
|
31 | 37 | - if @submissions and @submissions.count > 0 |
@@ -58,6 +64,27 | |||
|
58 | 64 | No submission |
|
59 | 65 | |
|
60 | 66 | :javascript |
|
61 | - $("#main_table").DataTable({ | |
|
62 | - paging: false | |
|
67 | + $(document).on('import-map-loaded',(e) => { | |
|
68 | + //init datatable | |
|
69 | + $("#main_table").DataTable({ | |
|
70 | + paging: false | |
|
71 | + }); | |
|
72 | + | |
|
73 | + //history graph | |
|
74 | + data = #{@chart_dataset} | |
|
75 | + config = { | |
|
76 | + type: 'bar', | |
|
77 | + data: data, | |
|
78 | + options: { | |
|
79 | + plugins: { | |
|
80 | + legend: { | |
|
81 | + display: false | |
|
82 | + }, | |
|
83 | + }, | |
|
84 | + } | |
|
85 | + } | |
|
86 | + Chart.defaults.font.size = 15 | |
|
87 | + //Chart.defaults.font.family = 'Sarabun Light' | |
|
88 | + chart = new Chart($('#chart'),config) | |
|
63 | 89 | }); |
|
90 | + |
@@ -1,42 +1,46 | |||
|
1 | - - content_for :header do | |
|
2 | - = javascript_include_tag 'local_jquery' | |
|
3 | - | |
|
4 | - :javascript | |
|
5 | - $(function () { | |
|
6 | - $('#submission_table').tablesorter({widgets: ['zebra']}); | |
|
7 | - }); | |
|
8 | 1 |
|
|
9 | 2 | :css |
|
10 | 3 | .fix-width { |
|
11 | 4 | font-family: Droid Sans Mono,Consolas, monospace, mono, Courier New, Courier; |
|
12 | 5 | } |
|
13 | 6 | |
|
14 | - %h1= @user.full_name | |
|
7 | + %h1 User stats | |
|
8 | + %h5.text-secondary= @user.login | |
|
9 | + | |
|
10 | + .row.my-3 | |
|
11 | + .col-md-8 | |
|
12 | + .card | |
|
13 | + .card-body | |
|
14 | + %h2.card-title Sub Info | |
|
15 | + %canvas#chart{height: '50px'} | |
|
15 | 16 | |
|
16 | - <b>Login:</b> #{@user.login} <br/> | |
|
17 | - <b>Full name:</b> #{@user.full_name} <br /> | |
|
17 | + .col-md-4 | |
|
18 | + .card | |
|
19 | + .card-body | |
|
20 | + %h2.card-title General Info | |
|
21 | + .row | |
|
22 | + .col-sm-6.fw-bold | |
|
23 | + Login | |
|
24 | + .col-sm-6 | |
|
25 | + = @user.login | |
|
26 | + .row | |
|
27 | + .col-sm-6.fw-bold | |
|
28 | + Full name | |
|
29 | + .col-sm-6 | |
|
30 | + = @user.full_name | |
|
31 | + .row | |
|
32 | + .col-sm-6.fw-bold | |
|
33 | + Subs | |
|
34 | + .col-sm-6 | |
|
35 | + = @summary[:count] | |
|
36 | + .row | |
|
37 | + .col-sm-6.fw-bold | |
|
38 | + Solved/Attempted Problem | |
|
39 | + .col-sm-6 | |
|
40 | + #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%) | |
|
18 | 41 | |
|
19 | 42 | |
|
20 | - %h2 Problem Stat | |
|
21 | - %table.info | |
|
22 | - %thead | |
|
23 | - %tr.info-head | |
|
24 | - %th Stat | |
|
25 | - %th Value | |
|
26 | - %tbody | |
|
27 | - %tr{class: cycle('info-even','info-odd')} | |
|
28 | - %td.info_param Submissions | |
|
29 | - %td= @summary[:count] | |
|
30 | - %tr{class: cycle('info-even','info-odd')} | |
|
31 | - %td.info_param Solved/Attempted Problem | |
|
32 | - %td #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%) | |
|
33 | - | |
|
34 | - %h2 Submission History | |
|
35 | - | |
|
36 | - =render partial: 'application/bar_graph', locals: {histogram: @histogram, param: {bar_width: 7}} | |
|
37 | - | |
|
38 | - | |
|
39 | - %table#submission_table.table.table-striped | |
|
43 | + %table#main_table.table.table-striped | |
|
40 | 44 | %thead |
|
41 | 45 | %tr |
|
42 | 46 | %th ID |
@@ -65,6 +69,27 | |||
|
65 | 69 | |
|
66 | 70 | |
|
67 | 71 | :javascript |
|
68 | - $("#submission_table").DataTable({ | |
|
69 | - paging: false | |
|
72 | + $(document).on('import-map-loaded',(e) => { | |
|
73 | + //init datatable | |
|
74 | + $("#main_table").DataTable({ | |
|
75 | + paging: false | |
|
76 | + }); | |
|
77 | + | |
|
78 | + //history graph | |
|
79 | + data = #{@chart_dataset} | |
|
80 | + config = { | |
|
81 | + type: 'bar', | |
|
82 | + data: data, | |
|
83 | + options: { | |
|
84 | + plugins: { | |
|
85 | + legend: { | |
|
86 | + display: false | |
|
87 | + }, | |
|
88 | + }, | |
|
89 | + } | |
|
90 | + } | |
|
91 | + Chart.defaults.font.size = 15 | |
|
92 | + //Chart.defaults.font.family = 'Sarabun Light' | |
|
93 | + chart = new Chart($('#chart'),config) | |
|
70 | 94 | }); |
|
95 | + |
deleted file |
You need to be logged in to leave comments.
Login now