This is an automated email from the git hooks/post-receive script. New change to branch feature/R7776-cloudTags-in-homepage in repository coselmar. See http://git.codelutin.com/coselmar.git from 19f5785 refs-40 #7776 mise en place d'un service rest renvoyant les mots les plus courrant de l'application new 3f4d90b refs-80 #7776 mise en plac du nuage de mot sur l'ui The 1 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit 3f4d90b5b2416d830c3063c5a895b09f66a71aaa Author: Yannick Martel <martel@©odelutin.com> Date: Wed Dec 16 16:24:48 2015 +0100 refs-80 #7776 mise en plac du nuage de mot sur l'ui Summary of changes: coselmar-ui/pom.xml | 6 + coselmar-ui/src/main/webapp/css/jqcloud-2.0.0.css | 59 +++ coselmar-ui/src/main/webapp/index.html | 8 + coselmar-ui/src/main/webapp/js/angular-jqcloud.js | 59 +++ .../src/main/webapp/js/coselmar-controllers.js | 10 +- ...r-constants.js => coselmar-general-services.js} | 24 +- coselmar-ui/src/main/webapp/js/coselmar.js | 2 +- coselmar-ui/src/main/webapp/js/jqcloud-2.0.0.js | 528 +++++++++++++++++++++ coselmar-ui/src/main/webapp/views/home.html | 5 + pom.xml | 8 + 10 files changed, 702 insertions(+), 7 deletions(-) create mode 100644 coselmar-ui/src/main/webapp/css/jqcloud-2.0.0.css create mode 100644 coselmar-ui/src/main/webapp/js/angular-jqcloud.js copy coselmar-ui/src/main/webapp/js/{coselmar-constants.js => coselmar-general-services.js} (63%) create mode 100644 coselmar-ui/src/main/webapp/js/jqcloud-2.0.0.js -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/R7776-cloudTags-in-homepage in repository coselmar. See http://git.codelutin.com/coselmar.git commit 3f4d90b5b2416d830c3063c5a895b09f66a71aaa Author: Yannick Martel <martel@©odelutin.com> Date: Wed Dec 16 16:24:48 2015 +0100 refs-80 #7776 mise en plac du nuage de mot sur l'ui --- coselmar-ui/pom.xml | 6 + coselmar-ui/src/main/webapp/css/jqcloud-2.0.0.css | 59 +++ coselmar-ui/src/main/webapp/index.html | 8 + coselmar-ui/src/main/webapp/js/angular-jqcloud.js | 59 +++ .../src/main/webapp/js/coselmar-controllers.js | 10 +- .../main/webapp/js/coselmar-general-services.js | 43 ++ coselmar-ui/src/main/webapp/js/coselmar.js | 2 +- coselmar-ui/src/main/webapp/js/jqcloud-2.0.0.js | 528 +++++++++++++++++++++ coselmar-ui/src/main/webapp/views/home.html | 5 + pom.xml | 8 + 10 files changed, 726 insertions(+), 2 deletions(-) diff --git a/coselmar-ui/pom.xml b/coselmar-ui/pom.xml index 39622e7..10ae37c 100644 --- a/coselmar-ui/pom.xml +++ b/coselmar-ui/pom.xml @@ -93,6 +93,12 @@ <scope>runtime</scope> </dependency> + <!--<dependency>--> + <!--<groupId>org.webjars.bower</groupId>--> + <!--<artifactId>jqcloud2</artifactId>--> + <!--<scope>runtime</scope>--> + <!--</dependency>--> + </dependencies> <build> diff --git a/coselmar-ui/src/main/webapp/css/jqcloud-2.0.0.css b/coselmar-ui/src/main/webapp/css/jqcloud-2.0.0.css new file mode 100644 index 0000000..3f276ed --- /dev/null +++ b/coselmar-ui/src/main/webapp/css/jqcloud-2.0.0.css @@ -0,0 +1,59 @@ +/* + * #%L + * ! + * jQCloud + * Copyright 2011 Luca Ongaro (http://www.lucaongaro.eu) + * Copyright 2013 Daniel White (http://www.developerdan.com) + * Copyright 2014 Damien "Mistic" Sorel (http://www.strangeplanet.fr) + * Licensed under MIT (http://opensource.org/licenses/MIT) + * #L% + */ + +/* layout */ +div.jqcloud { + overflow: hidden; + position: relative; +} + +div.jqcloud span { + padding: 0; +} + +/* fonts */ +div.jqcloud { + font-family: "Helvetica", "Arial", sans-serif; + font-size: 10px; + line-height: normal; +} + +div.jqcloud a { + font-size: inherit; + text-decoration: none; +} + +div.jqcloud span.w10 { font-size: 550%; } +div.jqcloud span.w9 { font-size: 500%; } +div.jqcloud span.w8 { font-size: 450%; } +div.jqcloud span.w7 { font-size: 400%; } +div.jqcloud span.w6 { font-size: 350%; } +div.jqcloud span.w5 { font-size: 300%; } +div.jqcloud span.w4 { font-size: 250%; } +div.jqcloud span.w3 { font-size: 200%; } +div.jqcloud span.w2 { font-size: 150%; } +div.jqcloud span.w1 { font-size: 100%; } + +/* colors */ +div.jqcloud { color: #09f; } +div.jqcloud a { color: inherit; } +div.jqcloud a:hover { color: #0df; } +div.jqcloud a:hover { color: #0cf; } +div.jqcloud span.w10 { color: #0cf; } +div.jqcloud span.w9 { color: #0cf; } +div.jqcloud span.w8 { color: #0cf; } +div.jqcloud span.w7 { color: #39d; } +div.jqcloud span.w6 { color: #90c5f0; } +div.jqcloud span.w5 { color: #90a0dd; } +div.jqcloud span.w4 { color: #90c5f0; } +div.jqcloud span.w3 { color: #a0ddff; } +div.jqcloud span.w2 { color: #99ccee; } +div.jqcloud span.w1 { color: #aab5f0; } \ No newline at end of file diff --git a/coselmar-ui/src/main/webapp/index.html b/coselmar-ui/src/main/webapp/index.html index f5e6678..ce47b70 100644 --- a/coselmar-ui/src/main/webapp/index.html +++ b/coselmar-ui/src/main/webapp/index.html @@ -30,6 +30,8 @@ <link rel="stylesheet" href="webjars/angular-notify/2.5.0/angular-notify.min.css"> <link rel="stylesheet" href="webjars/bootstrap/3.3.6/css/bootstrap.css"> <link rel="stylesheet" href="webjars/font-awesome/4.5.0/css/font-awesome.css"> + <link rel="stylesheet" href="webjars/jqcloud2/2.0.1/jqcloud/jqcloud.css"> + <link rel="stylesheet" href="css/jqcloud-2.0.0.css"> <link rel="stylesheet" href="css/coselmar.css"> <script src="webjars/jquery/2.1.4/jquery.js"></script> @@ -50,14 +52,20 @@ <link rel="stylesheet" href="webjars/angular-ui-select/0.13.1/select.css"> <script src="webjars/angular-ui-bootstrap/0.14.3/ui-bootstrap.js"></script> <script src="webjars/angular-ui-bootstrap/0.14.3/ui-bootstrap-tpls.js"></script> + <script src="webjars/jqcloud2/2.0.1/jqcloud/jqcloud-2.0.1.js"></script> + <script src="js/jqcloud-2.0.0.js"></script> <script src="js/angular-jwt.js"></script> + <script src="js/angular-jqcloud.js"></script> + <script src="i18n/en.js"></script> <script src="i18n/fr.js"></script> + <script src="js/coselmar.js"></script> <script src="js/coselmar-constants.js"></script> <script src="js/coselmar-controllers.js"></script> <script src="js/coselmar-services.js"></script> + <script src="js/coselmar-general-services.js"></script> <script src="js/coselmar-user-services.js"></script> <script src="js/coselmar-questions-services.js"></script> <script src="js/coselmar-admin-services.js"></script> diff --git a/coselmar-ui/src/main/webapp/js/angular-jqcloud.js b/coselmar-ui/src/main/webapp/js/angular-jqcloud.js new file mode 100644 index 0000000..8a02bd0 --- /dev/null +++ b/coselmar-ui/src/main/webapp/js/angular-jqcloud.js @@ -0,0 +1,59 @@ +/*! + * #%L + * Angular jQCloud 1.0.2 + * For jQCloud 2 (https://github.com/mistic100/jQCloud) + * Copyright 2014 Damien "Mistic" Sorel (http://www.strangeplanet.fr) + * Licensed under MIT (http://opensource.org/licenses/MIT) + * #L% + */ + +angular.module('angular-jqcloud', []).directive('jqcloud', ['$parse', function($parse) { + // get existing options + var defaults = jQuery.fn.jQCloud.defaults.get(), + jqcOptions = []; + + for (var opt in defaults) { + if (defaults.hasOwnProperty(opt)) { + jqcOptions.push(opt); + } + } + + return { + restrict: 'E', + template: '<div></div>', + replace: true, + scope: { + words: '=words', + afterCloudRender: '&' + }, + link: function($scope, $elem, $attr) { + var options = {}; + + for (var i=0, l=jqcOptions.length; i<l; i++) { + var opt = jqcOptions[i]; + var attr = $attr[opt] || $elem.attr(opt); + if (attr !== undefined) { + options[opt] = $parse(attr)(); + } + } + + if ($scope.afterCloudRender) { + options.afterCloudRender = $scope.afterCloudRender; + } + + jQuery($elem).jQCloud($scope.words, options); + + $scope.$watchCollection('words', function() { + $scope.$evalAsync(function() { + var words = []; + $.extend(words,$scope.words); + jQuery($elem).jQCloud('update', words); + }); + }); + + $elem.bind('$destroy', function() { + jQuery($elem).jQCloud('destroy'); + }); + } + }; +}]); \ No newline at end of file diff --git a/coselmar-ui/src/main/webapp/js/coselmar-controllers.js b/coselmar-ui/src/main/webapp/js/coselmar-controllers.js index 0f40bf1..c8ba720 100644 --- a/coselmar-ui/src/main/webapp/js/coselmar-controllers.js +++ b/coselmar-ui/src/main/webapp/js/coselmar-controllers.js @@ -115,9 +115,10 @@ coselmarControllers.controller("unauthorizedCtrl", ['$scope', '$location', funct }]); // Controller for home when user connected, load 5 last projects -coselmarControllers.controller("homeConnectedCtrl", ['$scope', 'questionsService', function ($scope, questionsService) { +coselmarControllers.controller("homeConnectedCtrl", ['$scope', 'questionsService', 'generalService', function ($scope, questionsService, generalService) { $scope.closedQuestions = []; + $scope.topWords = [{text:"coselmar", weight: 10}, {text: "Ifremer", weight: 5}]; if ($scope.context && $scope.context.currentUser) { @@ -145,6 +146,13 @@ coselmarControllers.controller("homeConnectedCtrl", ['$scope', 'questionsService }); } + generalService.getTopWords(function(result) { + $scope.topWords = result.data; + }, function(fail) { + $scope.topWords = []; + }); + + }]); ///////////////////////////////////////////////// diff --git a/coselmar-ui/src/main/webapp/js/coselmar-general-services.js b/coselmar-ui/src/main/webapp/js/coselmar-general-services.js new file mode 100644 index 0000000..def2091 --- /dev/null +++ b/coselmar-ui/src/main/webapp/js/coselmar-general-services.js @@ -0,0 +1,43 @@ +/* + * #%L + * Coselmar :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Ifremer, Code Lutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +coselmarServices.factory('generalService', ['$http', 'coselmar-config', function($http, coselmarConfig){ + return new GeneralService($http, coselmarConfig); +}]); + +function GeneralService(http, config){ + + this.http = http; + + var baseURL = config.BASE_URL + "/general"; + + this.getTopWords = function(successFunction, failFunction) { + + var topWordsUrl = baseURL + "/topwords"; + + http.get(topWordsUrl).then(successFunction, failFunction); + + }; + +}; \ No newline at end of file diff --git a/coselmar-ui/src/main/webapp/js/coselmar.js b/coselmar-ui/src/main/webapp/js/coselmar.js index d5b7b22..8904db3 100644 --- a/coselmar-ui/src/main/webapp/js/coselmar.js +++ b/coselmar-ui/src/main/webapp/js/coselmar.js @@ -23,7 +23,7 @@ */ var coselmarApp = angular.module("coselmarApp", ['ngRoute', 'ngResource', 'ngMessages', 'ngAnimate', 'pascalprecht.translate', 'tmh.dynamicLocale', 'cgNotify', - 'angular-jwt', 'coselmarControllers', 'coselmarServices']); + 'angular-jwt', 'angular-jqcloud', 'coselmarControllers', 'coselmarServices']); coselmarApp.config(['$routeProvider', function($routeProvider) { $routeProvider diff --git a/coselmar-ui/src/main/webapp/js/jqcloud-2.0.0.js b/coselmar-ui/src/main/webapp/js/jqcloud-2.0.0.js new file mode 100644 index 0000000..5c9cc4f --- /dev/null +++ b/coselmar-ui/src/main/webapp/js/jqcloud-2.0.0.js @@ -0,0 +1,528 @@ +/* + * #%L + * ! + * jQCloud + * Copyright 2011 Luca Ongaro (http://www.lucaongaro.eu) + * Copyright 2013 Daniel White (http://www.developerdan.com) + * Copyright 2014 Damien "Mistic" Sorel (http://www.strangeplanet.fr) + * Licensed under MIT (http://opensource.org/licenses/MIT) + * #L% + */ + +/*jshint -W055 *//* non standard constructor name */ + +(function($) { + "use strict"; + + /* + * Plugin class + */ + var jQCloud = function (element, word_array, options) { + this.$element = $(element); + + this.word_array = word_array || []; + this.options = options; + + this.sizeGenerator = null; + this.colorGenerator = null; + + // Data used internally + this.data = { + placed_words: [], + timeouts: {}, + namespace: null, + step: null, + angle: null, + aspect_ratio: null, + max_weight: null, + min_weight: null, + sizes: [], + colors: [] + }; + + this.initialize(); + }; + + jQCloud.DEFAULTS = { + width: 100, + height: 100, + center: { x: 0.5, y: 0.5 }, + steps: 10, + delay: null, + shape: 'elliptic', + classPattern: 'w{n}', + encodeURI: true, + removeOverflowing: true, + afterCloudRender: null, + autoResize: false, + colors: null, + fontSize: null, + template: null + }; + + jQCloud.prototype = { + initialize: function() { + // Set/Get dimensions + if (this.options.width) { + this.$element.width(this.options.width); + } + else { + this.options.width = this.$element.width(); + } + if (this.options.height) { + this.$element.height(this.options.height); + } + else { + this.options.height = this.$element.height(); + } + + // Default options value + this.options = $.extend(true, {}, jQCloud.DEFAULTS, this.options); + + // Ensure delay + if (this.options.delay === null) { + this.options.delay = this.word_array.length > 50 ? 10 : 0; + } + + // Backward compatibility + if (this.options.center.x > 1) { + this.options.center.x = this.options.center.x / this.options.width; + this.options.center.y = this.options.center.y / this.options.height; + } + + // Create colorGenerator function from options + // Direct function + if (typeof this.options.colors == 'function') { + this.colorGenerator = this.options.colors; + } + // Array of sizes + else if ($.isArray(this.options.colors)) { + var cl = this.options.colors.length; + if (cl > 0) { + // Fill the sizes array to X items + if (cl < this.options.steps) { + for (var i=cl; i<this.options.steps; i++) { + this.options.colors[i] = this.options.colors[cl-1]; + } + } + + this.colorGenerator = function(weight) { + return this.options.colors[this.options.steps - weight]; + }; + } + } + + // Create sizeGenerator function from options + // Direct function + if (typeof this.options.fontSize == 'function') { + this.sizeGenerator = this.options.fontSize; + } + // Object with 'from' and 'to' + else if ($.isPlainObject(this.options.fontSize)) { + this.sizeGenerator = function(width, height, weight) { + var max = width * this.options.fontSize.from, + min = width * this.options.fontSize.to; + return Math.round(min + (max - min) * 1.0 / (this.options.steps-1) * (weight - 1)) + 'px'; + }; + } + // Array of sizes + else if ($.isArray(this.options.fontSize)) { + var sl = this.options.fontSize.length; + if (sl > 0) { + // Fill the sizes array to X items + if (sl < this.options.steps) { + for (var j=sl; j<this.options.steps; j++) { + this.options.fontSize[j] = this.options.fontSize[sl-1]; + } + } + + this.sizeGenerator = function(width, height, weight) { + return this.options.fontSize[this.options.steps - weight]; + }; + } + } + + this.data.angle = Math.random() * 6.28; + this.data.step = (this.options.shape === 'rectangular') ? 18.0 : 2.0; + this.data.aspect_ratio = this.options.width / this.options.height; + this.clearTimeouts(); + + // Namespace word ids to avoid collisions between multiple clouds + this.data.namespace = (this.$element.attr('id') || Math.floor((Math.random()*1000000)).toString(36)) + '_word_'; + + this.$element.addClass('jqcloud'); + + // Container's CSS position cannot be 'static' + if (this.$element.css('position') === 'static') { + this.$element.css('position', 'relative'); + } + + // Delay execution so that the browser can render the page before the computatively intensive word cloud drawing + this.createTimeout($.proxy(this.drawWordCloud, this), 10); + + // Attach window resize event + if (this.options.autoResize) { + $(window).on('resize', throttle(function() { + var new_size = { + width: this.$element.width(), + height: this.$element.height() + }; + + if (new_size.width != this.options.width || new_size.height != this.options.height) { + this.options.width = new_size.width; + this.options.height = new_size.height; + this.data.aspect_ratio = this.options.width / this.options.height; + + this.update(this.word_array); + } + }, 50, this)); + } + }, + + // Helper function to keep track of timeouts so they can be destroyed + createTimeout: function(callback, time) { + var timeout = setTimeout($.proxy(function(){ + delete this.data.timeouts[timeout]; + callback(); + }, this), time); + this.data.timeouts[timeout] = true; + }, + + // Destroy all timeouts + clearTimeouts: function() { + $.each(this.data.timeouts, function(key){ + clearTimeout(key); + }); + this.data.timeouts = {}; + }, + + // Pairwise overlap detection + overlapping: function(a, b) { + if (Math.abs(2.0*a.left + a.width - 2.0*b.left - b.width) < a.width + b.width) { + if (Math.abs(2.0*a.top + a.height - 2.0*b.top - b.height) < a.height + b.height) { + return true; + } + } + return false; + }, + + // Helper function to test if an element overlaps others + hitTest: function(elem) { + // Check elements for overlap one by one, stop and return false as soon as an overlap is found + for(var i=0, l=this.data.placed_words.length; i<l; i++) { + if (this.overlapping(elem, this.data.placed_words[i])) { + return true; + } + } + return false; + }, + + // Initialize the drawing of the whole cloud + drawWordCloud: function() { + var i, l; + + this.$element.children('[id^="' + this.data.namespace + '"]').remove(); + + if (this.word_array.length === 0) { + return; + } + + // Make sure every weight is a number before sorting + for (i=0, l=this.word_array.length; i<l; i++) { + this.word_array[i].weight = parseFloat(this.word_array[i].weight, 10); + } + + // Sort word_array from the word with the highest weight to the one with the lowest + this.word_array.sort(function(a, b) { + return b.weight - a.weight; + }); + + // Kepp trace of bounds + this.data.max_weight = this.word_array[0].weight; + this.data.min_weight = this.word_array[this.word_array.length - 1].weight; + + // Generate colors + this.data.colors = []; + if (this.colorGenerator) { + for (i=0; i<this.options.steps; i++) { + this.data.colors.push(this.colorGenerator(i+1)); + } + } + + // Generate font sizes + this.data.sizes = []; + if (this.sizeGenerator) { + for (i=0; i<this.options.steps; i++) { + this.data.sizes.push(this.sizeGenerator(this.options.width, this.options.height, i+1)); + } + } + + // Iterate drawOneWord on every word, immediately or with delay + if (this.options.delay > 0){ + this.drawOneWordDelayed(); + } + else { + for (i=0, l=this.word_array.length; i<l; i++) { + this.drawOneWord(i, this.word_array[i]); + } + + if (typeof this.options.afterCloudRender === 'function') { + this.options.afterCloudRender.call(this.$element); + } + } + }, + + // Function to draw a word, by moving it in spiral until it finds a suitable empty place + drawOneWord: function(index, word) { + var word_id = this.data.namespace + index, + word_selector = '#' + word_id, + + // option.shape == 'elliptic' + angle = this.data.angle, + radius = 0.0, + + // option.shape == 'rectangular' + steps_in_direction = 0.0, + quarter_turns = 0.0, + + weight = Math.floor(this.options.steps / 2), + word_span, + word_size, + word_style; + + // Create word attr object + word.attr = $.extend({}, word.html, { id: word_id }); + + // Linearly map the original weight to a discrete scale from 1 to 10 + // Only if weights are different + if (this.data.max_weight != this.data.min_weight) { + weight = Math.round((word.weight - this.data.min_weight) * 1.0 * (this.options.steps-1) / (this.data.max_weight - this.data.min_weight)) + 1; + } + word_span = $('<span>').attr(word.attr); + + // Apply class + if (this.options.classPattern) { + word_span.addClass(this.options.classPattern.replace('{n}', weight)); + } + + // Apply color + if (this.data.colors.length) { + word_span.css('color', this.data.colors[weight-1]); + } + + // Apply size + if (this.data.sizes.length) { + word_span.css('font-size', this.data.sizes[weight-1]); + } + + //Render using template function if provided. + if (this.options.template) { + word_span.html(this.options.template(word)); + } else if (word.link) { + // Append link if word.link attribute was set + // If link is a string, then use it as the link href + if (typeof word.link === 'string') { + word.link = { href: word.link }; + } + + if (this.options.encodeURI) { + word.link.href = encodeURI(word.link.href).replace(/'/g, '%27'); + } + + word_span.append($('<a>').attr(word.link).text(word.text)); + } + else { + word_span.text(word.text); + } + + // Bind handlers to words + if (word.handlers) { + word_span.on(word.handlers); + } + + this.$element.append(word_span); + + word_size = { + width: word_span.outerWidth(), + height: word_span.outerHeight() + }; + word_size.left = this.options.center.x*this.options.width - word_size.width / 2.0; + word_size.top = this.options.center.y*this.options.height - word_size.height / 2.0; + + // Save a reference to the style property, for better performance + word_style = word_span[0].style; + word_style.position = 'absolute'; + word_style.left = word_size.left + 'px'; + word_style.top = word_size.top + 'px'; + + while(this.hitTest(word_size)) { + // option shape is 'rectangular' so move the word in a rectangular spiral + if (this.options.shape === 'rectangular') { + steps_in_direction++; + + if (steps_in_direction * this.data.step > (1 + Math.floor(quarter_turns / 2.0)) * this.data.step * ((quarter_turns % 4 % 2) === 0 ? 1 : this.data.aspect_ratio)) { + steps_in_direction = 0.0; + quarter_turns++; + } + + switch(quarter_turns % 4) { + case 1: + word_size.left += this.data.step * this.data.aspect_ratio + Math.random() * 2.0; + break; + case 2: + word_size.top -= this.data.step + Math.random() * 2.0; + break; + case 3: + word_size.left -= this.data.step * this.data.aspect_ratio + Math.random() * 2.0; + break; + case 0: + word_size.top += this.data.step + Math.random() * 2.0; + break; + } + } + // Default settings: elliptic spiral shape + else { + radius += this.data.step; + angle += (index % 2 === 0 ? 1 : -1) * this.data.step; + + word_size.left = this.options.center.x*this.options.width - (word_size.width / 2.0) + (radius*Math.cos(angle)) * this.data.aspect_ratio; + word_size.top = this.options.center.y*this.options.height + radius*Math.sin(angle) - (word_size.height / 2.0); + } + word_style.left = word_size.left + 'px'; + word_style.top = word_size.top + 'px'; + } + + // Don't render word if part of it would be outside the container + if (this.options.removeOverflowing && ( + word_size.left < 0 || word_size.top < 0 || + (word_size.left + word_size.width) > this.options.width || + (word_size.top + word_size.height) > this.options.height + ) + ) { + word_span.remove(); + return; + } + + // Save position for further usage + this.data.placed_words.push(word_size); + + if (typeof word.afterWordRender === 'function') { + word.afterWordRender.call(word_span); + } + }, + + // Draw one word then recall the function after a delay + drawOneWordDelayed: function(index) { + index = index || 0; + + // if not visible then do not attempt to draw + if (!this.$element.is(':visible')) { + this.createTimeout($.proxy(function(){ + this.drawOneWordDelayed(index); + }, this), 10); + + return; + } + + if (index < this.word_array.length) { + this.drawOneWord(index, this.word_array[index]); + + this.createTimeout($.proxy(function(){ + this.drawOneWordDelayed(index + 1); + }, this), this.options.delay); + } + else { + if (typeof this.options.afterCloudRender == 'function') { + this.options.afterCloudRender.call(this.$element); + } + } + }, + + // Destroy any data and objects added by the plugin + destroy: function() { + this.clearTimeouts(); + this.$element.removeClass('jqcloud'); + this.$element.removeData('jqcloud'); + this.$element.children('[id^="' + this.data.namespace + '"]').remove(); + }, + + // Update the list of words + update: function(word_array) { + this.word_array = word_array; + this.data.placed_words = []; + + this.clearTimeouts(); + this.drawWordCloud(); + } + }; + + /* + * Apply throttling to a callback + * @param callback {function} + * @param delay {int} milliseconds + * @param context {object|null} + * @return {function} + */ + function throttle(callback, delay, context) { + var state = { + pid: null, + last: 0 + }; + + return function() { + var elapsed = new Date().getTime() - state.last, + args = arguments, + that = this; + + function exec() { + state.last = new Date().getTime(); + return callback.apply(context || that, Array.prototype.slice.call(args)); + } + + if (elapsed > delay) { + return exec(); + } + else { + clearTimeout(state.pid); + state.pid = setTimeout(exec, delay - elapsed); + } + }; + } + + /* + * jQuery plugin + */ + $.fn.jQCloud = function(word_array, option) { + var args = arguments; + + return this.each(function () { + var $this = $(this), + data = $this.data('jqcloud'); + + if (!data && word_array === 'destroy') { + // Don't even try to initialize when called with 'destroy' + return; + } + if (!data) { + var options = typeof option === 'object' ? option : {}; + $this.data('jqcloud', (data = new jQCloud(this, word_array, options))); + } + else if (typeof word_array === 'string') { + data[word_array].apply(data, Array.prototype.slice.call(args, 1)); + } + }); + }; + + $.fn.jQCloud.defaults = { + set: function(options) { + $.extend(true, jQCloud.DEFAULTS, options); + }, + get: function(key) { + var options = jQCloud.DEFAULTS; + if (key) { + options = options[key]; + } + return $.extend(true, {}, options); + } + }; +})(jQuery); \ No newline at end of file diff --git a/coselmar-ui/src/main/webapp/views/home.html b/coselmar-ui/src/main/webapp/views/home.html index f11dc65..01e1c61 100644 --- a/coselmar-ui/src/main/webapp/views/home.html +++ b/coselmar-ui/src/main/webapp/views/home.html @@ -110,4 +110,9 @@ </table> <p ng-if="questions && questions.length == 0" translate="common.search.noResult" class="info"/> </div> + + <!-- FIXME Leo #CSS --> + <div align="center"> + <jqcloud words="topWords" width="500" height="350" steps="21" font-size="{from:0.09, to:0.04}"></jqcloud> + </div> </div> diff --git a/pom.xml b/pom.xml index f8b4d12..f68d67a 100644 --- a/pom.xml +++ b/pom.xml @@ -166,6 +166,7 @@ <!-- XXX ymartel 20151202 : cannot upgrade httpcomponents deps for the moment, still needed for webmotion test --> <fluent-hc.version>4.2.3</fluent-hc.version> <httpcore.version>4.2.3</httpcore.version> + <jqcloud2Version>2.0.1</jqcloud2Version> </properties> <repositories> @@ -475,6 +476,13 @@ <scope>runtime</scope> </dependency> + <dependency> + <groupId>org.webjars.bower</groupId> + <artifactId>jqcloud2</artifactId> + <version>${jqcloud2Version}</version> + <scope>runtime</scope> + </dependency> + <!-- Others --> <dependency> <groupId>com.github.spullara.mustache.java</groupId> -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.
participants (1)
-
codelutin.com scm