diff --git a/app/assets/javascripts/external_users.js b/app/assets/javascripts/external_users.js
new file mode 100644
index 00000000..8e4ec52e
--- /dev/null
+++ b/app/assets/javascripts/external_users.js
@@ -0,0 +1,32 @@
+$(function() {
+ var grid = $('#tag-grid');
+
+ if ($.isController('external_users') && grid.isPresent()) {
+ var spinner = $('#loading');
+ var noElements = $('#no-elements');
+
+ var buildTagContainer = function(tag) {
+ return '\
+
\
+
' + tag.key + '
\
+
\
+
' + tag.value + '%
\
+
\
+
';
+ };
+
+ var jqxhr = $.ajax(window.location.href + '/tag_statistics', {
+ dataType: 'json',
+ method: 'GET'
+ });
+ jqxhr.done(function(response) {
+ spinner.hide();
+ if (response.length === 0) {
+ noElements.show();
+ } else {
+ var elements = response.map(buildTagContainer);
+ grid.append(elements);
+ }
+ });
+ }
+});
diff --git a/app/assets/stylesheets/base.css.scss b/app/assets/stylesheets/base.css.scss
index a0fbd88b..127b36ca 100644
--- a/app/assets/stylesheets/base.css.scss
+++ b/app/assets/stylesheets/base.css.scss
@@ -59,3 +59,34 @@ span.caret {
.markdown {
height: 200px;
}
+
+.spinner {
+ width: 40px;
+ height: 40px;
+ background-color: #333;
+
+ margin: 100px auto;
+ -webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
+ animation: sk-rotateplane 1.2s infinite ease-in-out;
+}
+
+@-webkit-keyframes sk-rotateplane {
+ 0% { -webkit-transform: perspective(120px) }
+ 50% { -webkit-transform: perspective(120px) rotateY(180deg) }
+ 100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) }
+}
+
+@keyframes sk-rotateplane {
+ 0% {
+ transform: perspective(120px) rotateX(0deg) rotateY(0deg);
+ -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)
+ }
+ 50% {
+ transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
+ -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)
+ }
+ 100% {
+ transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
+ -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
+ }
+}
diff --git a/app/assets/stylesheets/external_users.css.scss b/app/assets/stylesheets/external_users.css.scss
new file mode 100644
index 00000000..05bc0b35
--- /dev/null
+++ b/app/assets/stylesheets/external_users.css.scss
@@ -0,0 +1,16 @@
+#no-elements {
+ display: none;
+}
+
+#tag-grid {
+ display: grid;
+ grid-template-columns: 25% 25% 25% 25%;
+ grid-column-gap: 10px;
+ grid-row-gap: 15px;
+
+ .progress {
+ .progress-bar {
+ min-width: 2em;
+ }
+ }
+}
diff --git a/app/assets/stylesheets/statistics.css.scss b/app/assets/stylesheets/statistics.css.scss
index 2fc9d69d..4dee2b34 100644
--- a/app/assets/stylesheets/statistics.css.scss
+++ b/app/assets/stylesheets/statistics.css.scss
@@ -120,34 +120,3 @@ tr.highlight {
}
}
}
-
-.spinner {
- width: 40px;
- height: 40px;
- background-color: #333;
-
- margin: 100px auto;
- -webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
- animation: sk-rotateplane 1.2s infinite ease-in-out;
-}
-
-@-webkit-keyframes sk-rotateplane {
- 0% { -webkit-transform: perspective(120px) }
- 50% { -webkit-transform: perspective(120px) rotateY(180deg) }
- 100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) }
-}
-
-@keyframes sk-rotateplane {
- 0% {
- transform: perspective(120px) rotateX(0deg) rotateY(0deg);
- -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)
- }
- 50% {
- transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
- -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)
- }
- 100% {
- transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
- -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
- }
-}
diff --git a/app/controllers/external_users_controller.rb b/app/controllers/external_users_controller.rb
index 22d70988..4ef53f6d 100644
--- a/app/controllers/external_users_controller.rb
+++ b/app/controllers/external_users_controller.rb
@@ -63,4 +63,20 @@ class ExternalUsersController < ApplicationController
}
end
+ def tag_statistics
+ @user = ExternalUser.find(params[:id])
+ authorize!
+
+ statistics = []
+ tags = ProxyExercise.new().get_user_knowledge_and_max_knowledge(@user, @user.participations.uniq.compact)
+ tags[:user_topic_knowledge].each_pair do |key, value|
+ statistics.append({:key => key.name.to_s, :value => (100.0 / tags[:max_topic_knowledge][key] * value).round})
+ end
+ statistics.sort_by! {|item| -item[:value]}
+
+ respond_to do |format|
+ format.json { render(json: statistics) }
+ end
+ end
+
end
diff --git a/app/models/concerns/user.rb b/app/models/concerns/user.rb
index 89855062..78299717 100644
--- a/app/models/concerns/user.rb
+++ b/app/models/concerns/user.rb
@@ -8,6 +8,7 @@ module User
has_many :exercises, as: :user
has_many :file_types, as: :user
has_many :submissions, as: :user
+ has_many :participations, through: :submissions, source: :exercise, as: :user
has_many :user_proxy_exercise_exercises, as: :user
has_many :user_exercise_interventions, as: :user
has_many :interventions, through: :user_exercise_interventions
diff --git a/app/models/proxy_exercise.rb b/app/models/proxy_exercise.rb
index 9c84e3ad..3d9197fb 100644
--- a/app/models/proxy_exercise.rb
+++ b/app/models/proxy_exercise.rb
@@ -214,8 +214,8 @@ class ProxyExercise < ActiveRecord::Base
ex.tags.each do |t|
tags_counter[t] += 1
tag_diminishing_return_factor = tag_diminishing_return_function(tags_counter[t], all_used_tags_with_count[t])
- tag_ratio = ex.exercise_tags.where(tag: t).first.factor.to_f / ex.exercise_tags.inject(0){|sum, et| sum += et.factor }.to_f
- Rails.logger.debug("tag: #{t}, factor: #{ex.exercise_tags.where(tag: t).first.factor}, sumall: #{ex.exercise_tags.inject(0){|sum, et| sum += et.factor }}")
+ tag_ratio = ex.exercise_tags.where(tag: t).first.factor.to_f / ex.exercise_tags.inject(0){|sum, et| sum + et.factor }.to_f
+ Rails.logger.debug("tag: #{t}, factor: #{ex.exercise_tags.where(tag: t).first.factor}, sumall: #{ex.exercise_tags.inject(0){|sum, et| sum + et.factor }}")
Rails.logger.debug("tag #{t}, count #{tags_counter[t]}, max: #{all_used_tags_with_count[t]}, factor: #{tag_diminishing_return_factor}")
Rails.logger.debug("tag_ratio #{tag_ratio}")
topic_knowledge_ratio = ex.expected_difficulty * tag_ratio
@@ -226,11 +226,10 @@ class ProxyExercise < ActiveRecord::Base
end
{user_topic_knowledge: topic_knowledge_loss_user, max_topic_knowledge: topic_knowledge_max}
end
- private :get_user_knowledge_and_max_knowledge
def tag_diminishing_return_function(count_tag, total_count_tag)
total_count_tag += 1 # bonus exercise comes on top
- return 1/(1+(Math::E**(-3/(0.5*total_count_tag)*(count_tag-0.5*total_count_tag))))
+ 1 / (1 + (Math::E**(-3 / (0.5 * total_count_tag) * (count_tag - 0.5 * total_count_tag))))
end
def select_easiest_exercise(exercises)
diff --git a/app/policies/external_user_policy.rb b/app/policies/external_user_policy.rb
index 2e11060b..4257fa4b 100644
--- a/app/policies/external_user_policy.rb
+++ b/app/policies/external_user_policy.rb
@@ -2,4 +2,8 @@ class ExternalUserPolicy < AdminOnlyPolicy
def statistics?
admin?
end
+
+ def tag_statistics?
+ admin?
+ end
end
diff --git a/app/views/external_users/show.html.slim b/app/views/external_users/show.html.slim
index 5af691c1..f0028745 100644
--- a/app/views/external_users/show.html.slim
+++ b/app/views/external_users/show.html.slim
@@ -4,5 +4,12 @@ h1 = @user.name
//= row(label: 'external_user.email', value: @user.email)
= row(label: 'external_user.consumer', value: link_to(@user.consumer, @user.consumer))
-br
-= link_to(t('shared.statistics'), statistics_external_user_path(@user))
+h4 = link_to(t('.exercise_statistics'), statistics_external_user_path(@user))
+
+h4 = t('.tag_statistics')
+#loading
+ .spinner
+ = t('.loading_tag_statistics')
+#no-elements
+ = t('.empty_tag_statistics')
+#tag-grid
diff --git a/config/locales/de.yml b/config/locales/de.yml
index c3f7dc15..eed4d500 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -378,6 +378,11 @@ de:
score: Bewertung
runs: Abgaben
worktime: Arbeitszeit
+ show:
+ loading_tag_statistics: "Lade Lernbereichstatistiken"
+ tag_statistics: "Lernbereichstatistiken"
+ empty_tag_statistics: "Keine Statistiken verfügbar"
+ exercise_statistics: "Aufgabenstatistiken"
files:
roles:
main_file: Hauptdatei
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 494dd163..9fed1190 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -378,6 +378,11 @@ en:
score: Score
runs: Submissions
worktime: Working Time
+ show:
+ loading_tag_statistics: "Loading tag statistics..."
+ tag_statistics: "Tag Statistics"
+ empty_tag_statistics: "No statistics available"
+ exercise_statistics: "Exercise Statistics"
files:
roles:
main_file: Main File
diff --git a/config/routes.rb b/config/routes.rb
index 4ab758d9..6703d8c1 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -128,6 +128,9 @@ Rails.application.routes.draw do
resources :external_users, only: [:index, :show], concerns: :statistics do
resources :exercises, concerns: :statistics
+ member do
+ get :tag_statistics
+ end
end
namespace :code_ocean do