jqcloud-rails 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.md +17 -0
- data/Rakefile +4 -0
- data/jqcloud-rails.gemspec +22 -0
- data/lib/jqcloud-rails.rb +3 -0
- data/lib/jqcloud/rails.rb +6 -0
- data/lib/jqcloud/rails/engine.rb +6 -0
- data/lib/jqcloud/rails/version.rb +6 -0
- data/vendor/assets/javascripts/jqcloud.js +220 -0
- data/vendor/assets/stylesheets/jqcloud.css +60 -0
- metadata +78 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg
|
data/README.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# jqcloud-rails
|
2
|
+
|
3
|
+
jqcloud.js for Rails 3.1+ asset pipeline.
|
4
|
+
|
5
|
+
### Installation
|
6
|
+
|
7
|
+
In your Gemfile, add this line:
|
8
|
+
|
9
|
+
gem "jqcloud-rails"
|
10
|
+
|
11
|
+
Then, run `bundle install`.
|
12
|
+
|
13
|
+
You're done!
|
14
|
+
|
15
|
+
### Special Thanks
|
16
|
+
|
17
|
+
https://github.com/DukeLeNoir/jQCloud
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/jqcloud/rails/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "jqcloud-rails"
|
6
|
+
s.version = JQCloud::Rails::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["Archit Baweja"]
|
9
|
+
s.email = ["architbaweja@gmail.com"]
|
10
|
+
s.homepage = "http://rubygems.org/gems/jqcloud-rails"
|
11
|
+
s.summary = "jQCloud for Rails Asset pipeline"
|
12
|
+
s.description = "Provides easy installation and usage of jQCloud javascript library for your Rails 3.1+ application."
|
13
|
+
|
14
|
+
s.required_rubygems_version = ">= 1.3.6"
|
15
|
+
|
16
|
+
s.add_dependency "jquery-rails"
|
17
|
+
s.add_development_dependency "rails", "~> 3.1"
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.executables = `git ls-files`.split("\n").select{|f| f =~ /^bin/}
|
21
|
+
s.require_path = 'lib'
|
22
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
/*!
|
2
|
+
* jQCloud Plugin for jQuery
|
3
|
+
*
|
4
|
+
* Version 1.0.0
|
5
|
+
*
|
6
|
+
* Copyright 2011, Luca Ongaro
|
7
|
+
* Licensed under the MIT license.
|
8
|
+
*
|
9
|
+
* Date: Tue Apr 17 16:03:49 +0200 2012
|
10
|
+
*/
|
11
|
+
|
12
|
+
(function( $ ) {
|
13
|
+
"use strict";
|
14
|
+
$.fn.jQCloud = function(word_array, options) {
|
15
|
+
// Reference to the container element
|
16
|
+
var $this = this;
|
17
|
+
// Namespace word ids to avoid collisions between multiple clouds
|
18
|
+
var cloud_namespace = $this.attr('id') || Math.floor((Math.random()*1000000)).toString(36);
|
19
|
+
|
20
|
+
// Default options value
|
21
|
+
var default_options = {
|
22
|
+
width: $this.width(),
|
23
|
+
height: $this.height(),
|
24
|
+
center: {
|
25
|
+
x: ((options && options.width) ? options.width : $this.width()) / 2.0,
|
26
|
+
y: ((options && options.height) ? options.height : $this.height()) / 2.0
|
27
|
+
},
|
28
|
+
delayedMode: word_array.length > 50,
|
29
|
+
shape: false // It defaults to elliptic shape
|
30
|
+
};
|
31
|
+
|
32
|
+
options = $.extend(default_options, options || {});
|
33
|
+
|
34
|
+
// Add the "jqcloud" class to the container for easy CSS styling, set container width/height
|
35
|
+
$this.addClass("jqcloud").width(options.width).height(options.height);
|
36
|
+
|
37
|
+
// Container's CSS position cannot be 'static'
|
38
|
+
if ($this.css("position") === "static") {
|
39
|
+
$this.css("position", "relative");
|
40
|
+
}
|
41
|
+
|
42
|
+
var drawWordCloud = function() {
|
43
|
+
// Helper function to test if an element overlaps others
|
44
|
+
var hitTest = function(elem, other_elems){
|
45
|
+
// Pairwise overlap detection
|
46
|
+
var overlapping = function(a, b){
|
47
|
+
if (Math.abs(2.0*a.offsetLeft + a.offsetWidth - 2.0*b.offsetLeft - b.offsetWidth) < a.offsetWidth + b.offsetWidth) {
|
48
|
+
if (Math.abs(2.0*a.offsetTop + a.offsetHeight - 2.0*b.offsetTop - b.offsetHeight) < a.offsetHeight + b.offsetHeight) {
|
49
|
+
return true;
|
50
|
+
}
|
51
|
+
}
|
52
|
+
return false;
|
53
|
+
};
|
54
|
+
var i = 0;
|
55
|
+
// Check elements for overlap one by one, stop and return false as soon as an overlap is found
|
56
|
+
for(i = 0; i < other_elems.length; i++) {
|
57
|
+
if (overlapping(elem, other_elems[i])) {
|
58
|
+
return true;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
return false;
|
62
|
+
};
|
63
|
+
|
64
|
+
// Make sure every weight is a number before sorting
|
65
|
+
for (var i = 0; i < word_array.length; i++) {
|
66
|
+
word_array[i].weight = parseFloat(word_array[i].weight, 10);
|
67
|
+
}
|
68
|
+
|
69
|
+
// Sort word_array from the word with the highest weight to the one with the lowest
|
70
|
+
word_array.sort(function(a, b) { if (a.weight < b.weight) {return 1;} else if (a.weight > b.weight) {return -1;} else {return 0;} });
|
71
|
+
|
72
|
+
var step = (options.shape === "rectangular") ? 18.0 : 2.0,
|
73
|
+
already_placed_words = [],
|
74
|
+
aspect_ratio = options.width / options.height;
|
75
|
+
|
76
|
+
// Function to draw a word, by moving it in spiral until it finds a suitable empty place. This will be iterated on each word.
|
77
|
+
var drawOneWord = function(index, word) {
|
78
|
+
// Define the ID attribute of the span that will wrap the word, and the associated jQuery selector string
|
79
|
+
var word_id = cloud_namespace + "_word_" + index,
|
80
|
+
word_selector = "#" + word_id,
|
81
|
+
angle = 6.28 * Math.random(),
|
82
|
+
radius = 0.0,
|
83
|
+
|
84
|
+
// Only used if option.shape == 'rectangular'
|
85
|
+
steps_in_direction = 0.0,
|
86
|
+
quarter_turns = 0.0,
|
87
|
+
|
88
|
+
weight = 5,
|
89
|
+
custom_class = "",
|
90
|
+
inner_html = "",
|
91
|
+
word_span = "";
|
92
|
+
|
93
|
+
// Extend word html options with defaults
|
94
|
+
word.html = $.extend(word.html, {id: word_id});
|
95
|
+
|
96
|
+
// If custom class was specified, put them into a variable and remove it from html attrs, to avoid overwriting classes set by jQCloud
|
97
|
+
if(word.html && word.html["class"]) {
|
98
|
+
custom_class = word.html["class"];
|
99
|
+
delete word.html["class"];
|
100
|
+
}
|
101
|
+
|
102
|
+
// Check is min(weight) > max(weight) otherwise use default
|
103
|
+
if (word_array[0].weight > word_array[word_array.length - 1].weight) {
|
104
|
+
// Linearly map the original weight to a discrete scale from 1 to 10
|
105
|
+
weight = Math.round((word.weight - word_array[word_array.length - 1].weight) /
|
106
|
+
(word_array[0].weight - word_array[word_array.length - 1].weight) * 9.0) + 1;
|
107
|
+
}
|
108
|
+
word_span = $('<span>').attr(word.html).addClass('w' + weight + " " + custom_class);
|
109
|
+
|
110
|
+
// Append link if word.url attribute was set
|
111
|
+
if (word.link) {
|
112
|
+
// If link is a string, then use it as the link href
|
113
|
+
if(typeof word.link === "string") {
|
114
|
+
word.link = {href: word.link};
|
115
|
+
}
|
116
|
+
|
117
|
+
// Extend link html options with defaults
|
118
|
+
word.link = $.extend(word.link, {href: encodeURI(word.link.href).replace(/'/g, "%27")});
|
119
|
+
|
120
|
+
inner_html = $('<a>').attr(word.link).text(word.text);
|
121
|
+
} else {
|
122
|
+
inner_html = word.text;
|
123
|
+
}
|
124
|
+
word_span.append(inner_html);
|
125
|
+
|
126
|
+
// Bind handlers to words
|
127
|
+
if (!!word.handlers) {
|
128
|
+
for (var prop in word.handlers) {
|
129
|
+
if (word.handlers.hasOwnProperty(prop) && typeof word.handlers[prop] === 'function') {
|
130
|
+
$(word_span).bind(prop, word.handlers[prop]);
|
131
|
+
}
|
132
|
+
}
|
133
|
+
}
|
134
|
+
|
135
|
+
$this.append(word_span);
|
136
|
+
|
137
|
+
var width = word_span.width(),
|
138
|
+
height = word_span.height(),
|
139
|
+
left = options.center.x - width / 2.0,
|
140
|
+
top = options.center.y - height / 2.0;
|
141
|
+
|
142
|
+
// Save a reference to the style property, for better performance
|
143
|
+
var word_style = word_span[0].style;
|
144
|
+
word_style.position = "absolute";
|
145
|
+
word_style.left = left + "px";
|
146
|
+
word_style.top = top + "px";
|
147
|
+
|
148
|
+
while(hitTest(document.getElementById(word_id), already_placed_words)) {
|
149
|
+
// option shape is 'rectangular' so move the word in a rectangular spiral
|
150
|
+
if (options.shape === "rectangular") {
|
151
|
+
steps_in_direction++;
|
152
|
+
if (steps_in_direction * step > (1 + Math.floor(quarter_turns / 2.0)) * step * ((quarter_turns % 4 % 2) === 0 ? 1 : aspect_ratio)) {
|
153
|
+
steps_in_direction = 0.0;
|
154
|
+
quarter_turns++;
|
155
|
+
}
|
156
|
+
switch(quarter_turns % 4) {
|
157
|
+
case 1:
|
158
|
+
left += step * aspect_ratio + Math.random() * 2.0;
|
159
|
+
break;
|
160
|
+
case 2:
|
161
|
+
top -= step + Math.random() * 2.0;
|
162
|
+
break;
|
163
|
+
case 3:
|
164
|
+
left -= step * aspect_ratio + Math.random() * 2.0;
|
165
|
+
break;
|
166
|
+
case 0:
|
167
|
+
top += step + Math.random() * 2.0;
|
168
|
+
break;
|
169
|
+
}
|
170
|
+
} else { // Default settings: elliptic spiral shape
|
171
|
+
radius += step;
|
172
|
+
angle += (index % 2 === 0 ? 1 : -1)*step;
|
173
|
+
|
174
|
+
left = options.center.x - (width / 2.0) + (radius*Math.cos(angle)) * aspect_ratio;
|
175
|
+
top = options.center.y + radius*Math.sin(angle) - (height / 2.0);
|
176
|
+
}
|
177
|
+
word_style.left = left + "px";
|
178
|
+
word_style.top = top + "px";
|
179
|
+
}
|
180
|
+
already_placed_words.push(document.getElementById(word_id));
|
181
|
+
|
182
|
+
// Invoke callback if existing
|
183
|
+
if ($.isFunction(word.afterWordRender)) {
|
184
|
+
word.afterWordRender.call(word_span);
|
185
|
+
}
|
186
|
+
};
|
187
|
+
|
188
|
+
var drawOneWordDelayed = function(index) {
|
189
|
+
index = index || 0;
|
190
|
+
if (!$this.is(':visible')) { // if not visible then do not attempt to draw
|
191
|
+
setTimeout(function(){drawOneWordDelayed(index);},10);
|
192
|
+
return;
|
193
|
+
}
|
194
|
+
if (index < word_array.length) {
|
195
|
+
drawOneWord(index, word_array[index]);
|
196
|
+
setTimeout(function(){drawOneWordDelayed(index + 1);}, 10);
|
197
|
+
} else {
|
198
|
+
if ($.isFunction(options.afterCloudRender)) {
|
199
|
+
options.afterCloudRender.call($this);
|
200
|
+
}
|
201
|
+
}
|
202
|
+
};
|
203
|
+
|
204
|
+
// Iterate drawOneWord on every word. The way the iteration is done depends on the drawing mode (delayedMode is true or false)
|
205
|
+
if (options.delayedMode){
|
206
|
+
drawOneWordDelayed();
|
207
|
+
}
|
208
|
+
else {
|
209
|
+
$.each(word_array, drawOneWord);
|
210
|
+
if ($.isFunction(options.afterCloudRender)) {
|
211
|
+
options.afterCloudRender.call($this);
|
212
|
+
}
|
213
|
+
}
|
214
|
+
};
|
215
|
+
|
216
|
+
// Delay execution so that the browser can render the page before the computatively intensive word cloud drawing
|
217
|
+
setTimeout(function(){drawWordCloud();}, 10);
|
218
|
+
return $this;
|
219
|
+
};
|
220
|
+
})(jQuery);
|
@@ -0,0 +1,60 @@
|
|
1
|
+
div.jqcloud {
|
2
|
+
font-family: "Helvetica", "Arial", sans-serif;
|
3
|
+
color: #09f;
|
4
|
+
overflow: hidden;
|
5
|
+
position: relative;
|
6
|
+
}
|
7
|
+
div.jqcloud a {
|
8
|
+
color: inherit;
|
9
|
+
font-size: inherit;
|
10
|
+
text-decoration: none;
|
11
|
+
}
|
12
|
+
div.jqcloud a:hover {
|
13
|
+
color: #0df;
|
14
|
+
}
|
15
|
+
div.jqcloud a:hover {
|
16
|
+
color: #0cf;
|
17
|
+
}
|
18
|
+
div.jqcloud span {
|
19
|
+
padding: 0;
|
20
|
+
}
|
21
|
+
div.jqcloud span.w10 {
|
22
|
+
font-size: 54px;
|
23
|
+
color: #0cf;
|
24
|
+
}
|
25
|
+
div.jqcloud span.w9 {
|
26
|
+
font-size: 50px;
|
27
|
+
color: #0cf;
|
28
|
+
}
|
29
|
+
div.jqcloud span.w8 {
|
30
|
+
font-size: 44px;
|
31
|
+
color: #0cf;
|
32
|
+
}
|
33
|
+
div.jqcloud span.w7 {
|
34
|
+
font-size: 40px;
|
35
|
+
color: #39d;
|
36
|
+
}
|
37
|
+
div.jqcloud span.w6 {
|
38
|
+
font-size: 34px;
|
39
|
+
color: #90c5f0;
|
40
|
+
}
|
41
|
+
div.jqcloud span.w5 {
|
42
|
+
font-size: 30px;
|
43
|
+
color: #90a0dd;
|
44
|
+
}
|
45
|
+
div.jqcloud span.w4 {
|
46
|
+
font-size: 24px;
|
47
|
+
color: #90c5f0;
|
48
|
+
}
|
49
|
+
div.jqcloud span.w3 {
|
50
|
+
font-size: 20px;
|
51
|
+
color: #a0ddff;
|
52
|
+
}
|
53
|
+
div.jqcloud span.w2 {
|
54
|
+
font-size: 14px;
|
55
|
+
color: #99ccee;
|
56
|
+
}
|
57
|
+
div.jqcloud span.w1 {
|
58
|
+
font-size: 10px;
|
59
|
+
color: #aab5f0;
|
60
|
+
}
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jqcloud-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Archit Baweja
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-26 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: jquery-rails
|
16
|
+
requirement: &70141681960560 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70141681960560
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rails
|
27
|
+
requirement: &70141681959220 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '3.1'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70141681959220
|
36
|
+
description: Provides easy installation and usage of jQCloud javascript library for
|
37
|
+
your Rails 3.1+ application.
|
38
|
+
email:
|
39
|
+
- architbaweja@gmail.com
|
40
|
+
executables: []
|
41
|
+
extensions: []
|
42
|
+
extra_rdoc_files: []
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- README.md
|
46
|
+
- Rakefile
|
47
|
+
- jqcloud-rails.gemspec
|
48
|
+
- lib/jqcloud-rails.rb
|
49
|
+
- lib/jqcloud/rails.rb
|
50
|
+
- lib/jqcloud/rails/engine.rb
|
51
|
+
- lib/jqcloud/rails/version.rb
|
52
|
+
- vendor/assets/javascripts/jqcloud.js
|
53
|
+
- vendor/assets/stylesheets/jqcloud.css
|
54
|
+
homepage: http://rubygems.org/gems/jqcloud-rails
|
55
|
+
licenses: []
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options: []
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: 1.3.6
|
72
|
+
requirements: []
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 1.8.17
|
75
|
+
signing_key:
|
76
|
+
specification_version: 3
|
77
|
+
summary: jQCloud for Rails Asset pipeline
|
78
|
+
test_files: []
|