jquery_visualize 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +79 -0
- data/Rakefile +1 -0
- data/app/assets/images/jquery_visualize/chartbg-vanilla.png +0 -0
- data/app/assets/images/jquery_visualize/chartbg.png +0 -0
- data/app/assets/javascripts/jquery_visualize/index.js +463 -0
- data/app/assets/stylesheets/jquery_visualize/index.css +32 -0
- data/jquery_visualize.gemspec +23 -0
- data/lib/jquery_visualize.rb +6 -0
- data/lib/jquery_visualize/version.rb +3 -0
- metadata +84 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 794e343f90b91b632c064c785851105efb088928
|
4
|
+
data.tar.gz: 17672638a7816946dd5c62ac7a10f2be401760bf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e86727a603e9129545c9599d52ae003eba04ff3711e4fb82d29ff9178f0e4a1dfcb8f827ac9f488de6b489af654daf12ab9ad03c56588ed2d0f25b016cbfa236
|
7
|
+
data.tar.gz: d7ece996f3619d242b2c122162bb651d8d22ac6cb82b67c1370b4aee69c981d91239c5d00782e7c8e92f0df29af99b1f58366be8fe9e0b8269cb81ea8e9905e2
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Sergey Chernyakov
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# JqueryVisualize
|
2
|
+
|
3
|
+
This is gem for jQuery-Visualize plugin.
|
4
|
+
https://github.com/filamentgroup/jQuery-Visualize
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
gem 'jquery_visualize'
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install jquery_visualize
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
How to use Visualize
|
23
|
+
|
24
|
+
First, you'll need to create the table markup:
|
25
|
+
|
26
|
+
<table>
|
27
|
+
<caption>2009 Employee Sales by Department</caption>
|
28
|
+
<thead>
|
29
|
+
<tr>
|
30
|
+
<td></td>
|
31
|
+
<th scope="col">food</th>
|
32
|
+
<th scope="col">auto</th>
|
33
|
+
<th scope="col">household</th>
|
34
|
+
<th scope="col">furniture</th>
|
35
|
+
<th scope="col">kitchen</th>
|
36
|
+
<th scope="col">bath</th>
|
37
|
+
</tr>
|
38
|
+
</thead>
|
39
|
+
<tbody>
|
40
|
+
<tr>
|
41
|
+
<th scope="row">Mary</th>
|
42
|
+
<td>190</td>
|
43
|
+
<td>160</td>
|
44
|
+
<td>40</td>
|
45
|
+
<td>120</td>
|
46
|
+
<td>30</td>
|
47
|
+
<td>70</td>
|
48
|
+
</tr>
|
49
|
+
<tr>
|
50
|
+
<th scope="row">Tom</th>
|
51
|
+
<td>3</td>
|
52
|
+
<td>40</td>
|
53
|
+
<td>30</td>
|
54
|
+
<td>45</td>
|
55
|
+
<td>35</td>
|
56
|
+
<td>49</td>
|
57
|
+
</tr>
|
58
|
+
...repetitive rows removed for brevity.
|
59
|
+
</tbody>
|
60
|
+
</table>
|
61
|
+
|
62
|
+
Note that we've used a caption element to summarize the table data. This will be used by the Visualize plugin to create a title on your graph. We've also defined our table headings using th elements, letting the script know which cells it should use as the titles for a data set.
|
63
|
+
|
64
|
+
Now that we have our HTML table, we can generate a chart. Just attach jQuery and our Visualize plugin's JavaScript and CSS files to your page, and call the visualize() method on the table, like this:
|
65
|
+
|
66
|
+
$('table').visualize();
|
67
|
+
|
68
|
+
That's it! By default, the Visualize plugin will generate the first bar chart shown above and append it to your page directly after the table.
|
69
|
+
|
70
|
+
Documentation:
|
71
|
+
http://www.filamentgroup.com/lab/update_to_jquery_visualize_accessible_charts_with_html5_from_designing_with/
|
72
|
+
|
73
|
+
## Contributing
|
74
|
+
|
75
|
+
1. Fork it
|
76
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
77
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
78
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
79
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
Binary file
|
Binary file
|
@@ -0,0 +1,463 @@
|
|
1
|
+
/*
|
2
|
+
* --------------------------------------------------------------------
|
3
|
+
* jQuery inputToButton plugin
|
4
|
+
* Author: Scott Jehl, scott@filamentgroup.com
|
5
|
+
* Copyright (c) 2009 Filament Group
|
6
|
+
* licensed under MIT (filamentgroup.com/examples/mit-license.txt)
|
7
|
+
* --------------------------------------------------------------------
|
8
|
+
*/
|
9
|
+
(function($) {
|
10
|
+
$.fn.visualize = function(options, container){
|
11
|
+
return $(this).each(function(){
|
12
|
+
//configuration
|
13
|
+
var o = $.extend({
|
14
|
+
type: 'bar', //also available: area, pie, line
|
15
|
+
width: $(this).width(), //height of canvas - defaults to table height
|
16
|
+
height: $(this).height(), //height of canvas - defaults to table height
|
17
|
+
appendTitle: true, //table caption text is added to chart
|
18
|
+
title: null, //grabs from table caption if null
|
19
|
+
appendKey: true, //color key is added to chart
|
20
|
+
rowFilter: '*',
|
21
|
+
colFilter: '*',
|
22
|
+
colors: ['#be1e2d','#666699','#92d5ea','#ee8310','#8d10ee','#5a3b16','#26a4ed','#f45a90','#e9e744'],
|
23
|
+
textColors: [], //corresponds with colors array. null/undefined items will fall back to CSS
|
24
|
+
parseDirection: 'x', //which direction to parse the table data
|
25
|
+
pieMargin: 20, //pie charts only - spacing around pie
|
26
|
+
pieLabelsAsPercent: true,
|
27
|
+
pieLabelPos: 'inside',
|
28
|
+
lineWeight: 4, //for line and area - stroke weight
|
29
|
+
barGroupMargin: 10,
|
30
|
+
barMargin: 1, //space around bars in bar chart (added to both sides of bar)
|
31
|
+
yLabelInterval: 30 //distance between y labels
|
32
|
+
},options);
|
33
|
+
|
34
|
+
//reset width, height to numbers
|
35
|
+
o.width = parseFloat(o.width);
|
36
|
+
o.height = parseFloat(o.height);
|
37
|
+
|
38
|
+
|
39
|
+
var self = $(this);
|
40
|
+
|
41
|
+
//function to scrape data from html table
|
42
|
+
function scrapeTable(){
|
43
|
+
var colors = o.colors;
|
44
|
+
var textColors = o.textColors;
|
45
|
+
var tableData = {
|
46
|
+
dataGroups: function(){
|
47
|
+
var dataGroups = [];
|
48
|
+
if(o.parseDirection == 'x'){
|
49
|
+
self.find('tr:gt(0)').filter(o.rowFilter).each(function(i){
|
50
|
+
dataGroups[i] = {};
|
51
|
+
dataGroups[i].points = [];
|
52
|
+
dataGroups[i].color = colors[i];
|
53
|
+
if(textColors[i]){ dataGroups[i].textColor = textColors[i]; }
|
54
|
+
$(this).find('td').filter(o.colFilter).each(function(){
|
55
|
+
dataGroups[i].points.push( parseFloat($(this).text()) );
|
56
|
+
});
|
57
|
+
});
|
58
|
+
}
|
59
|
+
else {
|
60
|
+
var cols = self.find('tr:eq(1) td').filter(o.colFilter).size();
|
61
|
+
for(var i=0; i<cols; i++){
|
62
|
+
dataGroups[i] = {};
|
63
|
+
dataGroups[i].points = [];
|
64
|
+
dataGroups[i].color = colors[i];
|
65
|
+
if(textColors[i]){ dataGroups[i].textColor = textColors[i]; }
|
66
|
+
self.find('tr:gt(0)').filter(o.rowFilter).each(function(){
|
67
|
+
dataGroups[i].points.push( $(this).find('td').filter(o.colFilter).eq(i).text()*1 );
|
68
|
+
});
|
69
|
+
};
|
70
|
+
}
|
71
|
+
return dataGroups;
|
72
|
+
},
|
73
|
+
allData: function(){
|
74
|
+
var allData = [];
|
75
|
+
$(this.dataGroups()).each(function(){
|
76
|
+
allData.push(this.points);
|
77
|
+
});
|
78
|
+
return allData;
|
79
|
+
},
|
80
|
+
dataSum: function(){
|
81
|
+
var dataSum = 0;
|
82
|
+
var allData = this.allData().join(',').split(',');
|
83
|
+
$(allData).each(function(){
|
84
|
+
dataSum += parseFloat(this);
|
85
|
+
});
|
86
|
+
return dataSum
|
87
|
+
},
|
88
|
+
topValue: function(){
|
89
|
+
var topValue = 0;
|
90
|
+
var allData = this.allData().join(',').split(',');
|
91
|
+
$(allData).each(function(){
|
92
|
+
if(parseFloat(this,10)>topValue) topValue = parseFloat(this);
|
93
|
+
});
|
94
|
+
return topValue;
|
95
|
+
},
|
96
|
+
bottomValue: function(){
|
97
|
+
var bottomValue = 0;
|
98
|
+
var allData = this.allData().join(',').split(',');
|
99
|
+
$(allData).each(function(){
|
100
|
+
if(this<bottomValue) bottomValue = parseFloat(this);
|
101
|
+
});
|
102
|
+
return bottomValue;
|
103
|
+
},
|
104
|
+
memberTotals: function(){
|
105
|
+
var memberTotals = [];
|
106
|
+
var dataGroups = this.dataGroups();
|
107
|
+
$(dataGroups).each(function(l){
|
108
|
+
var count = 0;
|
109
|
+
$(dataGroups[l].points).each(function(m){
|
110
|
+
count +=dataGroups[l].points[m];
|
111
|
+
});
|
112
|
+
memberTotals.push(count);
|
113
|
+
});
|
114
|
+
return memberTotals;
|
115
|
+
},
|
116
|
+
yTotals: function(){
|
117
|
+
var yTotals = [];
|
118
|
+
var dataGroups = this.dataGroups();
|
119
|
+
var loopLength = this.xLabels().length;
|
120
|
+
for(var i = 0; i<loopLength; i++){
|
121
|
+
yTotals[i] =[];
|
122
|
+
var thisTotal = 0;
|
123
|
+
$(dataGroups).each(function(l){
|
124
|
+
yTotals[i].push(this.points[i]);
|
125
|
+
});
|
126
|
+
yTotals[i].join(',').split(',');
|
127
|
+
$(yTotals[i]).each(function(){
|
128
|
+
thisTotal += parseFloat(this);
|
129
|
+
});
|
130
|
+
yTotals[i] = thisTotal;
|
131
|
+
|
132
|
+
}
|
133
|
+
return yTotals;
|
134
|
+
},
|
135
|
+
topYtotal: function(){
|
136
|
+
var topYtotal = 0;
|
137
|
+
var yTotals = this.yTotals().join(',').split(',');
|
138
|
+
$(yTotals).each(function(){
|
139
|
+
if(parseFloat(this,10)>topYtotal) topYtotal = parseFloat(this);
|
140
|
+
});
|
141
|
+
return topYtotal;
|
142
|
+
},
|
143
|
+
totalYRange: function(){
|
144
|
+
return this.topValue() - this.bottomValue();
|
145
|
+
},
|
146
|
+
xLabels: function(){
|
147
|
+
var xLabels = [];
|
148
|
+
if(o.parseDirection == 'x'){
|
149
|
+
self.find('tr:eq(0) th').filter(o.colFilter).each(function(){
|
150
|
+
xLabels.push($(this).html());
|
151
|
+
});
|
152
|
+
}
|
153
|
+
else {
|
154
|
+
self.find('tr:gt(0) th').filter(o.rowFilter).each(function(){
|
155
|
+
xLabels.push($(this).html());
|
156
|
+
});
|
157
|
+
}
|
158
|
+
return xLabels;
|
159
|
+
},
|
160
|
+
yLabels: function(){
|
161
|
+
var yLabels = [];
|
162
|
+
yLabels.push(bottomValue);
|
163
|
+
var numLabels = Math.round(o.height / o.yLabelInterval);
|
164
|
+
var loopInterval = Math.ceil(totalYRange / numLabels) || 1;
|
165
|
+
while( yLabels[yLabels.length-1] < topValue - loopInterval){
|
166
|
+
yLabels.push(yLabels[yLabels.length-1] + loopInterval);
|
167
|
+
}
|
168
|
+
yLabels.push(topValue);
|
169
|
+
return yLabels;
|
170
|
+
}
|
171
|
+
};
|
172
|
+
|
173
|
+
return tableData;
|
174
|
+
};
|
175
|
+
|
176
|
+
|
177
|
+
//function to create a chart
|
178
|
+
var createChart = {
|
179
|
+
pie: function(){
|
180
|
+
|
181
|
+
canvasContain.addClass('visualize-pie');
|
182
|
+
|
183
|
+
if(o.pieLabelPos == 'outside'){ canvasContain.addClass('visualize-pie-outside'); }
|
184
|
+
|
185
|
+
var centerx = Math.round(canvas.width()/2);
|
186
|
+
var centery = Math.round(canvas.height()/2);
|
187
|
+
var radius = centery - o.pieMargin;
|
188
|
+
var counter = 0.0;
|
189
|
+
var toRad = function(integer){ return (Math.PI/180)*integer; };
|
190
|
+
var labels = $('<ul class="visualize-labels"></ul>')
|
191
|
+
.insertAfter(canvas);
|
192
|
+
|
193
|
+
//draw the pie pieces
|
194
|
+
$.each(memberTotals, function(i){
|
195
|
+
var fraction = (this <= 0 || isNaN(this))? 0 : this / dataSum;
|
196
|
+
ctx.beginPath();
|
197
|
+
ctx.moveTo(centerx, centery);
|
198
|
+
ctx.arc(centerx, centery, radius,
|
199
|
+
counter * Math.PI * 2 - Math.PI * 0.5,
|
200
|
+
(counter + fraction) * Math.PI * 2 - Math.PI * 0.5,
|
201
|
+
false);
|
202
|
+
ctx.lineTo(centerx, centery);
|
203
|
+
ctx.closePath();
|
204
|
+
ctx.fillStyle = dataGroups[i].color;
|
205
|
+
ctx.fill();
|
206
|
+
// draw labels
|
207
|
+
var sliceMiddle = (counter + fraction/2);
|
208
|
+
var distance = o.pieLabelPos == 'inside' ? radius/1.5 : radius + radius / 5;
|
209
|
+
var labelx = Math.round(centerx + Math.sin(sliceMiddle * Math.PI * 2) * (distance));
|
210
|
+
var labely = Math.round(centery - Math.cos(sliceMiddle * Math.PI * 2) * (distance));
|
211
|
+
var leftRight = (labelx > centerx) ? 'right' : 'left';
|
212
|
+
var topBottom = (labely > centery) ? 'bottom' : 'top';
|
213
|
+
var percentage = parseFloat((fraction*100).toFixed(2));
|
214
|
+
|
215
|
+
if(percentage){
|
216
|
+
var labelval = (o.pieLabelsAsPercent) ? percentage + '%' : this;
|
217
|
+
var labeltext = $('<span class="visualize-label">' + labelval +'</span>')
|
218
|
+
.css(leftRight, 0)
|
219
|
+
.css(topBottom, 0);
|
220
|
+
if(labeltext)
|
221
|
+
var label = $('<li class="visualize-label-pos"></li>')
|
222
|
+
.appendTo(labels)
|
223
|
+
.css({left: labelx, top: labely})
|
224
|
+
.append(labeltext);
|
225
|
+
labeltext
|
226
|
+
.css('font-size', radius / 8)
|
227
|
+
.css('margin-'+leftRight, -labeltext.width()/2)
|
228
|
+
.css('margin-'+topBottom, -labeltext.outerHeight()/2);
|
229
|
+
|
230
|
+
if(dataGroups[i].textColor){ labeltext.css('color', dataGroups[i].textColor); }
|
231
|
+
}
|
232
|
+
counter+=fraction;
|
233
|
+
});
|
234
|
+
},
|
235
|
+
|
236
|
+
line: function(area){
|
237
|
+
|
238
|
+
if(area){ canvasContain.addClass('visualize-area'); }
|
239
|
+
else{ canvasContain.addClass('visualize-line'); }
|
240
|
+
|
241
|
+
//write X labels
|
242
|
+
var xInterval = canvas.width() / (xLabels.length -1);
|
243
|
+
var xlabelsUL = $('<ul class="visualize-labels-x"></ul>')
|
244
|
+
.width(canvas.width())
|
245
|
+
.height(canvas.height())
|
246
|
+
.insertBefore(canvas);
|
247
|
+
$.each(xLabels, function(i){
|
248
|
+
var thisLi = $('<li><span>'+this+'</span></li>')
|
249
|
+
.prepend('<span class="line" />')
|
250
|
+
.css('left', xInterval * i)
|
251
|
+
.appendTo(xlabelsUL);
|
252
|
+
var label = thisLi.find('span:not(.line)');
|
253
|
+
var leftOffset = label.width()/-2;
|
254
|
+
if(i == 0){ leftOffset = 0; }
|
255
|
+
else if(i== xLabels.length-1){ leftOffset = -label.width(); }
|
256
|
+
label
|
257
|
+
.css('margin-left', leftOffset)
|
258
|
+
.addClass('label');
|
259
|
+
});
|
260
|
+
|
261
|
+
//write Y labels
|
262
|
+
var yScale = canvas.height() / totalYRange;
|
263
|
+
var liBottom = canvas.height() / (yLabels.length-1);
|
264
|
+
var ylabelsUL = $('<ul class="visualize-labels-y"></ul>')
|
265
|
+
.width(canvas.width())
|
266
|
+
.height(canvas.height())
|
267
|
+
.insertBefore(canvas);
|
268
|
+
|
269
|
+
$.each(yLabels, function(i){
|
270
|
+
var thisLi = $('<li><span>'+this+'</span></li>')
|
271
|
+
.prepend('<span class="line" />')
|
272
|
+
.css('bottom',liBottom*i)
|
273
|
+
.prependTo(ylabelsUL);
|
274
|
+
var label = thisLi.find('span:not(.line)');
|
275
|
+
var topOffset = label.height()/-2;
|
276
|
+
if(i == 0){ topOffset = -label.height(); }
|
277
|
+
else if(i== yLabels.length-1){ topOffset = 0; }
|
278
|
+
label
|
279
|
+
.css('margin-top', topOffset)
|
280
|
+
.addClass('label');
|
281
|
+
});
|
282
|
+
|
283
|
+
//start from the bottom left
|
284
|
+
ctx.translate(0,zeroLoc);
|
285
|
+
//iterate and draw
|
286
|
+
$.each(dataGroups,function(h){
|
287
|
+
ctx.beginPath();
|
288
|
+
ctx.lineWidth = o.lineWeight;
|
289
|
+
ctx.lineJoin = 'round';
|
290
|
+
var points = this.points;
|
291
|
+
var integer = 0;
|
292
|
+
ctx.moveTo(0,-(points[0]*yScale));
|
293
|
+
$.each(points, function(){
|
294
|
+
ctx.lineTo(integer,-(this*yScale));
|
295
|
+
integer+=xInterval;
|
296
|
+
});
|
297
|
+
ctx.strokeStyle = this.color;
|
298
|
+
ctx.stroke();
|
299
|
+
if(area){
|
300
|
+
ctx.lineTo(integer,0);
|
301
|
+
ctx.lineTo(0,0);
|
302
|
+
ctx.closePath();
|
303
|
+
ctx.fillStyle = this.color;
|
304
|
+
ctx.globalAlpha = .3;
|
305
|
+
ctx.fill();
|
306
|
+
ctx.globalAlpha = 1.0;
|
307
|
+
}
|
308
|
+
else {ctx.closePath();}
|
309
|
+
});
|
310
|
+
},
|
311
|
+
|
312
|
+
area: function(){
|
313
|
+
createChart.line(true);
|
314
|
+
},
|
315
|
+
|
316
|
+
bar: function(){
|
317
|
+
|
318
|
+
canvasContain.addClass('visualize-bar');
|
319
|
+
|
320
|
+
//write X labels
|
321
|
+
var xInterval = canvas.width() / (xLabels.length);
|
322
|
+
var xlabelsUL = $('<ul class="visualize-labels-x"></ul>')
|
323
|
+
.width(canvas.width())
|
324
|
+
.height(canvas.height())
|
325
|
+
.insertBefore(canvas);
|
326
|
+
$.each(xLabels, function(i){
|
327
|
+
var thisLi = $('<li><span class="label">'+this+'</span></li>')
|
328
|
+
.prepend('<span class="line" />')
|
329
|
+
.css('left', xInterval * i)
|
330
|
+
.width(xInterval)
|
331
|
+
.appendTo(xlabelsUL);
|
332
|
+
var label = thisLi.find('span.label');
|
333
|
+
label.addClass('label');
|
334
|
+
});
|
335
|
+
|
336
|
+
//write Y labels
|
337
|
+
var yScale = canvas.height() / totalYRange;
|
338
|
+
var liBottom = canvas.height() / (yLabels.length-1);
|
339
|
+
var ylabelsUL = $('<ul class="visualize-labels-y"></ul>')
|
340
|
+
.width(canvas.width())
|
341
|
+
.height(canvas.height())
|
342
|
+
.insertBefore(canvas);
|
343
|
+
$.each(yLabels, function(i){
|
344
|
+
var thisLi = $('<li><span>'+this+'</span></li>')
|
345
|
+
.prepend('<span class="line" />')
|
346
|
+
.css('bottom',liBottom*i)
|
347
|
+
.prependTo(ylabelsUL);
|
348
|
+
var label = thisLi.find('span:not(.line)');
|
349
|
+
var topOffset = label.height()/-2;
|
350
|
+
if(i == 0){ topOffset = -label.height(); }
|
351
|
+
else if(i== yLabels.length-1){ topOffset = 0; }
|
352
|
+
label
|
353
|
+
.css('margin-top', topOffset)
|
354
|
+
.addClass('label');
|
355
|
+
});
|
356
|
+
|
357
|
+
//start from the bottom left
|
358
|
+
ctx.translate(0,zeroLoc);
|
359
|
+
//iterate and draw
|
360
|
+
for(var h=0; h<dataGroups.length; h++){
|
361
|
+
ctx.beginPath();
|
362
|
+
var linewidth = (xInterval-o.barGroupMargin*2) / dataGroups.length; //removed +1
|
363
|
+
var strokeWidth = linewidth - (o.barMargin*2);
|
364
|
+
ctx.lineWidth = strokeWidth;
|
365
|
+
var points = dataGroups[h].points;
|
366
|
+
var integer = 0;
|
367
|
+
for(var i=0; i<points.length; i++){
|
368
|
+
var xVal = (integer-o.barGroupMargin)+(h*linewidth)+linewidth/2;
|
369
|
+
xVal += o.barGroupMargin*2;
|
370
|
+
|
371
|
+
ctx.moveTo(xVal, 0);
|
372
|
+
ctx.lineTo(xVal, Math.round(-points[i]*yScale));
|
373
|
+
integer+=xInterval;
|
374
|
+
}
|
375
|
+
ctx.strokeStyle = dataGroups[h].color;
|
376
|
+
ctx.stroke();
|
377
|
+
ctx.closePath();
|
378
|
+
}
|
379
|
+
}
|
380
|
+
};
|
381
|
+
|
382
|
+
//create new canvas, set w&h attrs (not inline styles)
|
383
|
+
var canvasNode = document.createElement("canvas");
|
384
|
+
canvasNode.setAttribute('height',o.height);
|
385
|
+
canvasNode.setAttribute('width',o.width);
|
386
|
+
var canvas = $(canvasNode);
|
387
|
+
|
388
|
+
//get title for chart
|
389
|
+
var title = o.title || self.find('caption').text();
|
390
|
+
|
391
|
+
//create canvas wrapper div, set inline w&h, append
|
392
|
+
var canvasContain = (container || $('<div class="visualize" role="img" aria-label="Chart representing data from the table: '+ title +'" />'))
|
393
|
+
.height(o.height)
|
394
|
+
.width(o.width)
|
395
|
+
.append(canvas);
|
396
|
+
|
397
|
+
//scrape table (this should be cleaned up into an obj)
|
398
|
+
var tableData = scrapeTable();
|
399
|
+
var dataGroups = tableData.dataGroups();
|
400
|
+
var allData = tableData.allData();
|
401
|
+
var dataSum = tableData.dataSum();
|
402
|
+
var topValue = tableData.topValue();
|
403
|
+
var bottomValue = tableData.bottomValue();
|
404
|
+
var memberTotals = tableData.memberTotals();
|
405
|
+
var totalYRange = tableData.totalYRange();
|
406
|
+
var zeroLoc = o.height * (topValue/totalYRange);
|
407
|
+
var xLabels = tableData.xLabels();
|
408
|
+
var yLabels = tableData.yLabels();
|
409
|
+
|
410
|
+
//title/key container
|
411
|
+
if(o.appendTitle || o.appendKey){
|
412
|
+
var infoContain = $('<div class="visualize-info"></div>')
|
413
|
+
.appendTo(canvasContain);
|
414
|
+
}
|
415
|
+
|
416
|
+
//append title
|
417
|
+
if(o.appendTitle){
|
418
|
+
$('<div class="visualize-title">'+ title +'</div>').appendTo(infoContain);
|
419
|
+
}
|
420
|
+
|
421
|
+
|
422
|
+
//append key
|
423
|
+
if(o.appendKey){
|
424
|
+
var newKey = $('<ul class="visualize-key"></ul>');
|
425
|
+
var selector;
|
426
|
+
if(o.parseDirection == 'x'){
|
427
|
+
selector = self.find('tr:gt(0) th').filter(o.rowFilter);
|
428
|
+
}
|
429
|
+
else{
|
430
|
+
selector = self.find('tr:eq(0) th').filter(o.colFilter);
|
431
|
+
}
|
432
|
+
|
433
|
+
selector.each(function(i){
|
434
|
+
$('<li><span class="visualize-key-color" style="background: '+dataGroups[i].color+'"></span><span class="visualize-key-label">'+ $(this).text() +'</span></li>')
|
435
|
+
.appendTo(newKey);
|
436
|
+
});
|
437
|
+
newKey.appendTo(infoContain);
|
438
|
+
};
|
439
|
+
|
440
|
+
//append new canvas to page
|
441
|
+
|
442
|
+
if(!container){canvasContain.insertAfter(this); }
|
443
|
+
if( typeof(G_vmlCanvasManager) != 'undefined' ){ G_vmlCanvasManager.init(); G_vmlCanvasManager.initElement(canvas[0]); }
|
444
|
+
|
445
|
+
//set up the drawing board
|
446
|
+
var ctx = canvas[0].getContext('2d');
|
447
|
+
|
448
|
+
//create chart
|
449
|
+
createChart[o.type]();
|
450
|
+
|
451
|
+
//clean up some doubled lines that sit on top of canvas borders (done via JS due to IE)
|
452
|
+
$('.visualize-line li:first-child span.line, .visualize-line li:last-child span.line, .visualize-area li:first-child span.line, .visualize-area li:last-child span.line, .visualize-bar li:first-child span.line,.visualize-bar .visualize-labels-y li:last-child span.line').css('border','none');
|
453
|
+
if(!container){
|
454
|
+
//add event for updating
|
455
|
+
canvasContain.bind('visualizeRefresh', function(){
|
456
|
+
self.visualize(o, $(this).empty());
|
457
|
+
});
|
458
|
+
}
|
459
|
+
}).next(); //returns canvas(es)
|
460
|
+
};
|
461
|
+
})(jQuery);
|
462
|
+
|
463
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
/*plugin styles*/
|
2
|
+
.visualize { border: 1px solid #888; position: relative; background: #fafafa; }
|
3
|
+
.visualize canvas { position: absolute; }
|
4
|
+
.visualize ul,.visualize li { margin: 0; padding: 0;}
|
5
|
+
|
6
|
+
/*table title, key elements*/
|
7
|
+
.visualize .visualize-info { padding: 3px 5px; background: #fafafa; border: 1px solid #888; position: absolute; top: -20px; right: 10px; opacity: .8; }
|
8
|
+
.visualize .visualize-title { display: block; color: #333; margin-bottom: 3px; font-size: 1.1em; }
|
9
|
+
.visualize ul.visualize-key { list-style: none; }
|
10
|
+
.visualize ul.visualize-key li { list-style: none; float: left; margin-right: 10px; padding-left: 10px; position: relative;}
|
11
|
+
.visualize ul.visualize-key .visualize-key-color { width: 6px; height: 6px; left: 0; position: absolute; top: 50%; margin-top: -3px; }
|
12
|
+
.visualize ul.visualize-key .visualize-key-label { color: #000; }
|
13
|
+
|
14
|
+
/*pie labels*/
|
15
|
+
.visualize-pie .visualize-labels { list-style: none; }
|
16
|
+
.visualize-pie .visualize-label-pos, .visualize-pie .visualize-label { position: absolute; margin: 0; padding:0; }
|
17
|
+
.visualize-pie .visualize-label { display: block; color: #fff; font-weight: bold; font-size: 1em; }
|
18
|
+
.visualize-pie-outside .visualize-label { color: #000; font-weight: normal; }
|
19
|
+
|
20
|
+
/*line,bar, area labels*/
|
21
|
+
.visualize-labels-x,.visualize-labels-y { position: absolute; left: 0; top: 0; list-style: none; }
|
22
|
+
.visualize-labels-x li, .visualize-labels-y li { position: absolute; bottom: 0; }
|
23
|
+
.visualize-labels-x li span.label, .visualize-labels-y li span.label { position: absolute; color: #555; }
|
24
|
+
.visualize-labels-x li span.line, .visualize-labels-y li span.line { position: absolute; border: 0 solid #ccc; }
|
25
|
+
.visualize-labels-x li { height: 100%; }
|
26
|
+
.visualize-labels-x li span.label { top: 100%; margin-top: 5px; }
|
27
|
+
.visualize-labels-x li span.line { border-left-width: 1px; height: 100%; display: block; }
|
28
|
+
.visualize-labels-x li span.line { border: 0;} /*hide vertical lines on area, line, bar*/
|
29
|
+
.visualize-labels-y li { width: 100%; }
|
30
|
+
.visualize-labels-y li span.label { right: 100%; margin-right: 5px; display: block; width: 100px; text-align: right; }
|
31
|
+
.visualize-labels-y li span.line { border-top-width: 1px; width: 100%; }
|
32
|
+
.visualize-bar .visualize-labels-x li span.label { width: 100%; text-align: center; }
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'jquery_visualize/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "jquery_visualize"
|
8
|
+
spec.version = JqueryVisualize::VERSION
|
9
|
+
spec.authors = ["Sergey Chernyakov"]
|
10
|
+
spec.email = ["chernyakov.sergey@gmail.com"]
|
11
|
+
spec.description = %q{This is gem for jQuery-Visualize plugin.}
|
12
|
+
spec.summary = %q{https://github.com/filamentgroup/jQuery-Visualize}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jquery_visualize
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sergey Chernyakov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-06-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: This is gem for jQuery-Visualize plugin.
|
42
|
+
email:
|
43
|
+
- chernyakov.sergey@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- .gitignore
|
49
|
+
- Gemfile
|
50
|
+
- LICENSE.txt
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- app/assets/images/jquery_visualize/chartbg-vanilla.png
|
54
|
+
- app/assets/images/jquery_visualize/chartbg.png
|
55
|
+
- app/assets/javascripts/jquery_visualize/index.js
|
56
|
+
- app/assets/stylesheets/jquery_visualize/index.css
|
57
|
+
- jquery_visualize.gemspec
|
58
|
+
- lib/jquery_visualize.rb
|
59
|
+
- lib/jquery_visualize/version.rb
|
60
|
+
homepage: ''
|
61
|
+
licenses:
|
62
|
+
- MIT
|
63
|
+
metadata: {}
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 2.0.3
|
81
|
+
signing_key:
|
82
|
+
specification_version: 4
|
83
|
+
summary: https://github.com/filamentgroup/jQuery-Visualize
|
84
|
+
test_files: []
|