Commit 0f83170d by Anto Stupak Committed by Vasyl Nakvasiuk

word cloud: return percents. Additional attribute and labels for text on hover are added

parent c70fa41d
......@@ -214,7 +214,13 @@ define('WordCloudMain', ['logme'], function (logme) {
studentWordsStr,
// By default we do not scale.
scale = 1;
scale = 1,
// Caсhing of DOM element
cloudSectionEl = this.wordCloudEl.find('.result_cloud_section'),
// Needed for caсhing of d3 group elements
groupEl;
// If bounding rectangle is given, scale based on the bounding box of all the words.
if (bounds) {
......@@ -227,26 +233,47 @@ define('WordCloudMain', ['logme'], function (logme) {
}
$.each(response.student_words, function (word, stat) {
studentWordsKeys.push('<strong>' + word + '</strong> (' + (100 * (stat / response.total_count)).toFixed(2) + '%)');
var percent = (response.display_percents) ? ' ' + (Math.round(100 * (stat / response.total_count))) + '%' : '';
studentWordsKeys.push('<strong>' + word + '</strong>' + percent);
});
studentWordsStr = '' + studentWordsKeys.join(', ');
this.wordCloudEl.find('.result_cloud_section').addClass('active');
cloudSectionEl
.addClass('active')
.find('.your_words').html(studentWordsStr)
.find('.total_num_words').html(response.total_count);
this.wordCloudEl.find('.result_cloud_section').find('.your_words').html(studentWordsStr);
this.wordCloudEl.find('.result_cloud_section').find('.total_num_words').html(response.total_count);
$(this.wordCloudEl.find('.result_cloud_section').attr('id') + ' .word_cloud').empty();
$(cloudSectionEl.attr('id') + ' .word_cloud').empty();
// Actual drawing of word cloud.
d3.select('#' + this.wordCloudEl.find('.result_cloud_section').attr('id') + ' .word_cloud').append('svg')
.attr('width', this.width)
.attr('height', this.height)
.append('g')
.attr('transform', 'translate(' + (0.5 * this.width) + ',' + (0.5 * this.height) + ')')
.selectAll('text')
.data(words)
.enter().append('text')
groupEl = d3.select('#' + cloudSectionEl.attr('id') + ' .word_cloud').append('svg')
.attr('width', this.width)
.attr('height', this.height)
.append('g')
.attr('transform', 'translate(' + (0.5 * this.width) + ',' + (0.5 * this.height) + ')')
.selectAll('text')
.data(words)
.enter().append('g');
groupEl
.append('title')
.text(function (d) {
var res = '';
$.each(response.top_words, function(index, value){
if (value.text === d.text) {
res = value.percent + '%';
return;
}
});
return res;
});
groupEl
.append('text')
.style('font-size', function (d) {
return d.size + 'px';
})
......@@ -258,7 +285,7 @@ define('WordCloudMain', ['logme'], function (logme) {
.attr('transform', function (d) {
return 'translate(' + [d.x, d.y] + ')rotate(' + d.rotate + ')scale(' + scale + ')';
})
.text(function (d) {
.text(function (d) {
return d.text;
});
}; // End-of: WordCloudMain.prototype.drawWordCloud = function (words, bounds) {
......
......@@ -20,11 +20,17 @@ from xblock.core import Scope, String, Object, Boolean, List, Integer
log = logging.getLogger(__name__)
def pretty_bool(value):
BOOL_DICT = [True, "True", "true", "T", "t", "1"]
return value in BOOL_DICT
class WordCloudFields(object):
# Name of poll to use in links to this poll
display_name = String(help="Display name for this module", scope=Scope.settings)
num_inputs = Integer(help="Number of inputs", scope=Scope.settings, default=5)
num_top_words = Integer(help="Number of max words, which will be displayed.", scope=Scope.settings, default=250)
display_percents = Boolean(help="Dispaly usage percents for each word.", scope=Scope.settings, default=True)
submitted = Boolean(help="Whether this student has posted words to the cloud", scope=Scope.user_state, default=False)
student_words = List(help="Student answer", scope=Scope.user_state, default=[])
......@@ -49,19 +55,22 @@ class WordCloudModule(WordCloudFields, XModule):
def get_state(self):
"""Return success json answer for client."""
if self.submitted:
total_count = sum(self.all_words.itervalues())
return json.dumps({
'status': 'success',
'submitted': True,
'display_percents': pretty_bool(self.display_percents),
'student_words': {
word: self.all_words[word] for word in self.student_words
},
'total_count': sum(self.all_words.itervalues()),
'top_words': self.prepare_words(self.top_words)
'total_count': total_count,
'top_words': self.prepare_words(self.top_words, total_count)
})
else:
return json.dumps({
'status': 'success',
'submitted': False,
'display_percents': False,
'student_words': {},
'total_count': 0,
'top_words': {}
......@@ -71,10 +80,10 @@ class WordCloudModule(WordCloudFields, XModule):
"""Convert raw word to suitable word."""
return word.strip().lower()
def prepare_words(self, words):
def prepare_words(self, words, total_count):
"""Convert words dictionary for client API."""
return [
{'text': word, 'size': count} for
{'text': word, 'size': count, 'percent': round(100 * (count / float(total_count)))} for
word, count in words.iteritems()
]
......@@ -185,5 +194,6 @@ class WordCloudDescriptor(WordCloudFields, MakoModuleDescriptor, XmlDescriptor):
xml_object.set('display_name', self.display_name)
xml_object.set('num_inputs', self.num_inputs)
xml_object.set('num_top_words', self.num_top_words)
xml_object.set('display_percents', pretty_bool(self.display_percents))
return xml_object
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment