g.raphael-rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f253b068223b8b077c314aaeb19afea1a2c48d48
4
+ data.tar.gz: 75f5d572464694d6ab95444a7dcc8a07591af4d1
5
+ SHA512:
6
+ metadata.gz: 770f100d3a2c5bbe978719fe65d4b53785423e21e80e10d55158a812c01780058b1940ea33d67d064b26bbaadf3e92902d015bb4da8655e3dcfd3e1ca9438884
7
+ data.tar.gz: 2bf9076d9e8b55bb63a76e02c26cb31adb1b15edbb5b55403ceae6236914be0bed7b11112da581ad568cf8f718d5cc266b1cff3e8828e34cbbef811aa065d1ff
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in graphael.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Tymon Tobolski
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.
@@ -0,0 +1,3 @@
1
+ # graphael-rails
2
+
3
+ [g.Raphael](https://github.com/DmitryBaranovskiy/g.raphael) packaged for Rails assets pipeline
@@ -0,0 +1,14 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ desc "Fetch all files from https://raw.github.com/DmitryBaranovskiy/g.raphael/master/"
4
+ task :fetch do
5
+ source = "https://raw.github.com/DmitryBaranovskiy/g.raphael/master/g.raphael.js"
6
+ target = "vendor/assets/javascripts/graphael.js"
7
+ sh "curl #{source} > #{target}"
8
+
9
+ ['bar', 'dot', 'line', 'pie'].each do |script|
10
+ source = "https://raw.github.com/DmitryBaranovskiy/g.raphael/master/g.#{script}.js"
11
+ target = "vendor/assets/javascripts/graphael-#{script}.js"
12
+ sh "curl #{source} > #{target}"
13
+ end
14
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'graphael/rails/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "g.raphael-rails"
8
+ spec.version = Graphael::Rails::VERSION
9
+ spec.authors = ["Vincent Pochet"]
10
+ spec.email = ["vincent.pochet@gmail.com"]
11
+ spec.description = %q{gRaphael packaged for Rails assets pipeline}
12
+ spec.summary = %q{gRaphael packaged for Rails assets pipeline}
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_dependency "raphael-rails"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ end
@@ -0,0 +1,6 @@
1
+ require "raphael-rails"
2
+
3
+ module Graphael::Rails
4
+ class Engine < ::Rails::Engine
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Graphael
2
+ module Rails
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ //= require graphael
2
+ //= require graphael-bar
3
+ //= require graphael-dot
4
+ //= require graphael-line
5
+ //= require graphael-pie
@@ -0,0 +1,674 @@
1
+ /*!
2
+ * g.Raphael 0.51 - Charting library, based on Raphaël
3
+ *
4
+ * Copyright (c) 2009-2012 Dmitry Baranovskiy (http://g.raphaeljs.com)
5
+ * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
6
+ */
7
+ (function () {
8
+ var mmin = Math.min,
9
+ mmax = Math.max;
10
+
11
+ function finger(x, y, width, height, dir, ending, isPath, paper) {
12
+ var path,
13
+ ends = { round: 'round', sharp: 'sharp', soft: 'soft', square: 'square' };
14
+
15
+ // dir 0 for horizontal and 1 for vertical
16
+ if ((dir && !height) || (!dir && !width)) {
17
+ return isPath ? "" : paper.path();
18
+ }
19
+
20
+ ending = ends[ending] || "square";
21
+ height = Math.round(height);
22
+ width = Math.round(width);
23
+ x = Math.round(x);
24
+ y = Math.round(y);
25
+
26
+ switch (ending) {
27
+ case "round":
28
+ if (!dir) {
29
+ var r = ~~(height / 2);
30
+
31
+ if (width < r) {
32
+ r = width;
33
+ path = [
34
+ "M", x + .5, y + .5 - ~~(height / 2),
35
+ "l", 0, 0,
36
+ "a", r, ~~(height / 2), 0, 0, 1, 0, height,
37
+ "l", 0, 0,
38
+ "z"
39
+ ];
40
+ } else {
41
+ path = [
42
+ "M", x + .5, y + .5 - r,
43
+ "l", width - r, 0,
44
+ "a", r, r, 0, 1, 1, 0, height,
45
+ "l", r - width, 0,
46
+ "z"
47
+ ];
48
+ }
49
+ } else {
50
+ r = ~~(width / 2);
51
+
52
+ if (height < r) {
53
+ r = height;
54
+ path = [
55
+ "M", x - ~~(width / 2), y,
56
+ "l", 0, 0,
57
+ "a", ~~(width / 2), r, 0, 0, 1, width, 0,
58
+ "l", 0, 0,
59
+ "z"
60
+ ];
61
+ } else {
62
+ path = [
63
+ "M", x - r, y,
64
+ "l", 0, r - height,
65
+ "a", r, r, 0, 1, 1, width, 0,
66
+ "l", 0, height - r,
67
+ "z"
68
+ ];
69
+ }
70
+ }
71
+ break;
72
+ case "sharp":
73
+ if (!dir) {
74
+ var half = ~~(height / 2);
75
+
76
+ path = [
77
+ "M", x, y + half,
78
+ "l", 0, -height, mmax(width - half, 0), 0, mmin(half, width), half, -mmin(half, width), half + (half * 2 < height),
79
+ "z"
80
+ ];
81
+ } else {
82
+ half = ~~(width / 2);
83
+ path = [
84
+ "M", x + half, y,
85
+ "l", -width, 0, 0, -mmax(height - half, 0), half, -mmin(half, height), half, mmin(half, height), half,
86
+ "z"
87
+ ];
88
+ }
89
+ break;
90
+ case "square":
91
+ if (!dir) {
92
+ path = [
93
+ "M", x, y + ~~(height / 2),
94
+ "l", 0, -height, width, 0, 0, height,
95
+ "z"
96
+ ];
97
+ } else {
98
+ path = [
99
+ "M", x + ~~(width / 2), y,
100
+ "l", 1 - width, 0, 0, -height, width - 1, 0,
101
+ "z"
102
+ ];
103
+ }
104
+ break;
105
+ case "soft":
106
+ if (!dir) {
107
+ r = mmin(width, Math.round(height / 5));
108
+ path = [
109
+ "M", x + .5, y + .5 - ~~(height / 2),
110
+ "l", width - r, 0,
111
+ "a", r, r, 0, 0, 1, r, r,
112
+ "l", 0, height - r * 2,
113
+ "a", r, r, 0, 0, 1, -r, r,
114
+ "l", r - width, 0,
115
+ "z"
116
+ ];
117
+ } else {
118
+ r = mmin(Math.round(width / 5), height);
119
+ path = [
120
+ "M", x - ~~(width / 2), y,
121
+ "l", 0, r - height,
122
+ "a", r, r, 0, 0, 1, r, -r,
123
+ "l", width - 2 * r, 0,
124
+ "a", r, r, 0, 0, 1, r, r,
125
+ "l", 0, height - r,
126
+ "z"
127
+ ];
128
+ }
129
+ }
130
+
131
+ if (isPath) {
132
+ return path.join(",");
133
+ } else {
134
+ return paper.path(path);
135
+ }
136
+ }
137
+
138
+ /*\
139
+ * Paper.vbarchart
140
+ [ method ]
141
+ **
142
+ * Creates a vertical bar chart
143
+ **
144
+ > Parameters
145
+ **
146
+ - x (number) x coordinate of the chart
147
+ - y (number) y coordinate of the chart
148
+ - width (number) width of the chart (respected by all elements in the set)
149
+ - height (number) height of the chart (respected by all elements in the set)
150
+ - values (array) values
151
+ - opts (object) options for the chart
152
+ o {
153
+ o type (string) type of endings of the bar. Default: 'square'. Other options are: 'round', 'sharp', 'soft'.
154
+ o gutter (number)(string) default '20%' (WHAT DOES IT DO?)
155
+ o vgutter (number)
156
+ o colors (array) colors be used repeatedly to plot the bars. If multicolumn bar is used each sequence of bars with use a different color.
157
+ o stacked (boolean) whether or not to tread values as in a stacked bar chart
158
+ o to
159
+ o stretch (boolean)
160
+ o }
161
+ **
162
+ = (object) path element of the popup
163
+ > Usage
164
+ | r.vbarchart(0, 0, 620, 260, [76, 70, 67, 71, 69], {})
165
+ \*/
166
+
167
+ function VBarchart(paper, x, y, width, height, values, opts) {
168
+ opts = opts || {};
169
+
170
+ var chartinst = this,
171
+ type = opts.type || "square",
172
+ gutter = parseFloat(opts.gutter || "20%"),
173
+ chart = paper.set(),
174
+ bars = paper.set(),
175
+ covers = paper.set(),
176
+ covers2 = paper.set(),
177
+ total = Math.max.apply(Math, values),
178
+ stacktotal = [],
179
+ multi = 0,
180
+ colors = opts.colors || chartinst.colors,
181
+ len = values.length;
182
+
183
+ if (Raphael.is(values[0], "array")) {
184
+ total = [];
185
+ multi = len;
186
+ len = 0;
187
+
188
+ for (var i = values.length; i--;) {
189
+ bars.push(paper.set());
190
+ total.push(Math.max.apply(Math, values[i]));
191
+ len = Math.max(len, values[i].length);
192
+ }
193
+
194
+ if (opts.stacked) {
195
+ for (var i = len; i--;) {
196
+ var tot = 0;
197
+
198
+ for (var j = values.length; j--;) {
199
+ tot +=+ values[j][i] || 0;
200
+ }
201
+
202
+ stacktotal.push(tot);
203
+ }
204
+ }
205
+
206
+ for (var i = values.length; i--;) {
207
+ if (values[i].length < len) {
208
+ for (var j = len; j--;) {
209
+ values[i].push(0);
210
+ }
211
+ }
212
+ }
213
+
214
+ total = Math.max.apply(Math, opts.stacked ? stacktotal : total);
215
+ }
216
+
217
+ total = (opts.to) || total;
218
+
219
+ var barwidth = width / (len * (100 + gutter) + gutter) * 100,
220
+ barhgutter = barwidth * gutter / 100,
221
+ barvgutter = opts.vgutter == null ? 20 : opts.vgutter,
222
+ stack = [],
223
+ X = x + barhgutter,
224
+ Y = (height - 2 * barvgutter) / total;
225
+
226
+ if (!opts.stretch) {
227
+ barhgutter = Math.round(barhgutter);
228
+ barwidth = Math.floor(barwidth);
229
+ }
230
+
231
+ !opts.stacked && (barwidth /= multi || 1);
232
+
233
+ for (var i = 0; i < len; i++) {
234
+ stack = [];
235
+
236
+ for (var j = 0; j < (multi || 1); j++) {
237
+ var h = Math.round((multi ? values[j][i] : values[i]) * Y),
238
+ top = y + height - barvgutter - h,
239
+ bar = finger(Math.round(X + barwidth / 2), top + h, barwidth, h, true, type, null, paper).attr({ stroke: "none", fill: colors[multi ? j : i] });
240
+
241
+ if (multi) {
242
+ bars[j].push(bar);
243
+ } else {
244
+ bars.push(bar);
245
+ }
246
+
247
+ bar.y = top;
248
+ bar.x = Math.round(X + barwidth / 2);
249
+ bar.w = barwidth;
250
+ bar.h = h;
251
+ bar.value = multi ? values[j][i] : values[i];
252
+
253
+ if (!opts.stacked) {
254
+ X += barwidth;
255
+ } else {
256
+ stack.push(bar);
257
+ }
258
+ }
259
+
260
+ if (opts.stacked) {
261
+ var cvr;
262
+
263
+ covers2.push(cvr = paper.rect(stack[0].x - stack[0].w / 2, y, barwidth, height).attr(chartinst.shim));
264
+ cvr.bars = paper.set();
265
+
266
+ var size = 0;
267
+
268
+ for (var s = stack.length; s--;) {
269
+ stack[s].toFront();
270
+ }
271
+
272
+ for (var s = 0, ss = stack.length; s < ss; s++) {
273
+ var bar = stack[s],
274
+ cover,
275
+ h = (size + bar.value) * Y,
276
+ path = finger(bar.x, y + height - barvgutter - !!size * .5, barwidth, h, true, type, 1, paper);
277
+
278
+ cvr.bars.push(bar);
279
+ size && bar.attr({path: path});
280
+ bar.h = h;
281
+ bar.y = y + height - barvgutter - !!size * .5 - h;
282
+ covers.push(cover = paper.rect(bar.x - bar.w / 2, bar.y, barwidth, bar.value * Y).attr(chartinst.shim));
283
+ cover.bar = bar;
284
+ cover.value = bar.value;
285
+ size += bar.value;
286
+ }
287
+
288
+ X += barwidth;
289
+ }
290
+
291
+ X += barhgutter;
292
+ }
293
+
294
+ covers2.toFront();
295
+ X = x + barhgutter;
296
+
297
+ if (!opts.stacked) {
298
+ for (var i = 0; i < len; i++) {
299
+ for (var j = 0; j < (multi || 1); j++) {
300
+ var cover;
301
+
302
+ covers.push(cover = paper.rect(Math.round(X), y + barvgutter, barwidth, height - barvgutter).attr(chartinst.shim));
303
+ cover.bar = multi ? bars[j][i] : bars[i];
304
+ cover.value = cover.bar.value;
305
+ X += barwidth;
306
+ }
307
+
308
+ X += barhgutter;
309
+ }
310
+ }
311
+
312
+ chart.label = function (labels, isBottom) {
313
+ labels = labels || [];
314
+ this.labels = paper.set();
315
+
316
+ var L, l = -Infinity;
317
+
318
+ if (opts.stacked) {
319
+ for (var i = 0; i < len; i++) {
320
+ var tot = 0;
321
+
322
+ for (var j = 0; j < (multi || 1); j++) {
323
+ tot += multi ? values[j][i] : values[i];
324
+
325
+ if (j == multi - 1) {
326
+ var label = paper.labelise(labels[i], tot, total);
327
+
328
+ L = paper.text(bars[i * (multi || 1) + j].x, y + height - barvgutter / 2, label).attr(txtattr).insertBefore(covers[i * (multi || 1) + j]);
329
+
330
+ var bb = L.getBBox();
331
+
332
+ if (bb.x - 7 < l) {
333
+ L.remove();
334
+ } else {
335
+ this.labels.push(L);
336
+ l = bb.x + bb.width;
337
+ }
338
+ }
339
+ }
340
+ }
341
+ } else {
342
+ for (var i = 0; i < len; i++) {
343
+ for (var j = 0; j < (multi || 1); j++) {
344
+ var label = paper.labelise(multi ? labels[j] && labels[j][i] : labels[i], multi ? values[j][i] : values[i], total);
345
+
346
+ L = paper.text(bars[i * (multi || 1) + j].x, isBottom ? y + height - barvgutter / 2 : bars[i * (multi || 1) + j].y - 10, label).attr(txtattr).insertBefore(covers[i * (multi || 1) + j]);
347
+
348
+ var bb = L.getBBox();
349
+
350
+ if (bb.x - 7 < l) {
351
+ L.remove();
352
+ } else {
353
+ this.labels.push(L);
354
+ l = bb.x + bb.width;
355
+ }
356
+ }
357
+ }
358
+ }
359
+ return this;
360
+ };
361
+
362
+ chart.hover = function (fin, fout) {
363
+ covers2.hide();
364
+ covers.show();
365
+ covers.mouseover(fin).mouseout(fout);
366
+ return this;
367
+ };
368
+
369
+ chart.hoverColumn = function (fin, fout) {
370
+ covers.hide();
371
+ covers2.show();
372
+ fout = fout || function () {};
373
+ covers2.mouseover(fin).mouseout(fout);
374
+ return this;
375
+ };
376
+
377
+ chart.click = function (f) {
378
+ covers2.hide();
379
+ covers.show();
380
+ covers.click(f);
381
+ return this;
382
+ };
383
+
384
+ chart.each = function (f) {
385
+ if (!Raphael.is(f, "function")) {
386
+ return this;
387
+ }
388
+ for (var i = covers.length; i--;) {
389
+ f.call(covers[i]);
390
+ }
391
+ return this;
392
+ };
393
+
394
+ chart.eachColumn = function (f) {
395
+ if (!Raphael.is(f, "function")) {
396
+ return this;
397
+ }
398
+ for (var i = covers2.length; i--;) {
399
+ f.call(covers2[i]);
400
+ }
401
+ return this;
402
+ };
403
+
404
+ chart.clickColumn = function (f) {
405
+ covers.hide();
406
+ covers2.show();
407
+ covers2.click(f);
408
+ return this;
409
+ };
410
+
411
+ chart.push(bars, covers, covers2);
412
+ chart.bars = bars;
413
+ chart.covers = covers;
414
+ return chart;
415
+ };
416
+
417
+ //inheritance
418
+ var F = function() {};
419
+ F.prototype = Raphael.g;
420
+ HBarchart.prototype = VBarchart.prototype = new F; //prototype reused by hbarchart
421
+
422
+ Raphael.fn.barchart = function(x, y, width, height, values, opts) {
423
+ return new VBarchart(this, x, y, width, height, values, opts);
424
+ };
425
+
426
+ /*\
427
+ * Paper.barchart
428
+ [ method ]
429
+ **
430
+ * Creates a horizontal bar chart
431
+ **
432
+ > Parameters
433
+ **
434
+ - x (number) x coordinate of the chart
435
+ - y (number) y coordinate of the chart
436
+ - width (number) width of the chart (respected by all elements in the set)
437
+ - height (number) height of the chart (respected by all elements in the set)
438
+ - values (array) values
439
+ - opts (object) options for the chart
440
+ o {
441
+ o type (string) type of endings of the bar. Default: 'square'. Other options are: 'round', 'sharp', 'soft'.
442
+ o gutter (number)(string) default '20%' (WHAT DOES IT DO?)
443
+ o vgutter (number)
444
+ o colors (array) colors be used repeatedly to plot the bars. If multicolumn bar is used each sequence of bars with use a different color.
445
+ o stacked (boolean) whether or not to tread values as in a stacked bar chart
446
+ o to
447
+ o stretch (boolean)
448
+ o }
449
+ **
450
+ = (object) path element of the popup
451
+ > Usage
452
+ | r.barchart(0, 0, 620, 260, [76, 70, 67, 71, 69], {})
453
+ \*/
454
+
455
+ function HBarchart(paper, x, y, width, height, values, opts) {
456
+ opts = opts || {};
457
+
458
+ var chartinst = this,
459
+ type = opts.type || "square",
460
+ gutter = parseFloat(opts.gutter || "20%"),
461
+ chart = paper.set(),
462
+ bars = paper.set(),
463
+ covers = paper.set(),
464
+ covers2 = paper.set(),
465
+ total = Math.max.apply(Math, values),
466
+ stacktotal = [],
467
+ multi = 0,
468
+ colors = opts.colors || chartinst.colors,
469
+ len = values.length;
470
+
471
+ if (Raphael.is(values[0], "array")) {
472
+ total = [];
473
+ multi = len;
474
+ len = 0;
475
+
476
+ for (var i = values.length; i--;) {
477
+ bars.push(paper.set());
478
+ total.push(Math.max.apply(Math, values[i]));
479
+ len = Math.max(len, values[i].length);
480
+ }
481
+
482
+ if (opts.stacked) {
483
+ for (var i = len; i--;) {
484
+ var tot = 0;
485
+ for (var j = values.length; j--;) {
486
+ tot +=+ values[j][i] || 0;
487
+ }
488
+ stacktotal.push(tot);
489
+ }
490
+ }
491
+
492
+ for (var i = values.length; i--;) {
493
+ if (values[i].length < len) {
494
+ for (var j = len; j--;) {
495
+ values[i].push(0);
496
+ }
497
+ }
498
+ }
499
+
500
+ total = Math.max.apply(Math, opts.stacked ? stacktotal : total);
501
+ }
502
+
503
+ total = (opts.to) || total;
504
+
505
+ var barheight = Math.floor(height / (len * (100 + gutter) + gutter) * 100),
506
+ bargutter = Math.floor(barheight * gutter / 100),
507
+ stack = [],
508
+ Y = y + bargutter,
509
+ X = (width - 1) / total;
510
+
511
+ !opts.stacked && (barheight /= multi || 1);
512
+
513
+ for (var i = 0; i < len; i++) {
514
+ stack = [];
515
+
516
+ for (var j = 0; j < (multi || 1); j++) {
517
+ var val = multi ? values[j][i] : values[i],
518
+ bar = finger(x, Y + barheight / 2, Math.round(val * X), barheight - 1, false, type, null, paper).attr({stroke: "none", fill: colors[multi ? j : i]});
519
+
520
+ if (multi) {
521
+ bars[j].push(bar);
522
+ } else {
523
+ bars.push(bar);
524
+ }
525
+
526
+ bar.x = x + Math.round(val * X);
527
+ bar.y = Y + barheight / 2;
528
+ bar.w = Math.round(val * X);
529
+ bar.h = barheight;
530
+ bar.value = +val;
531
+
532
+ if (!opts.stacked) {
533
+ Y += barheight;
534
+ } else {
535
+ stack.push(bar);
536
+ }
537
+ }
538
+
539
+ if (opts.stacked) {
540
+ var cvr = paper.rect(x, stack[0].y - stack[0].h / 2, width, barheight).attr(chartinst.shim);
541
+
542
+ covers2.push(cvr);
543
+ cvr.bars = paper.set();
544
+
545
+ var size = 0;
546
+
547
+ for (var s = stack.length; s--;) {
548
+ stack[s].toFront();
549
+ }
550
+
551
+ for (var s = 0, ss = stack.length; s < ss; s++) {
552
+ var bar = stack[s],
553
+ cover,
554
+ val = Math.round((size + bar.value) * X),
555
+ path = finger(x, bar.y, val, barheight - 1, false, type, 1, paper);
556
+
557
+ cvr.bars.push(bar);
558
+ size && bar.attr({ path: path });
559
+ bar.w = val;
560
+ bar.x = x + val;
561
+ covers.push(cover = paper.rect(x + size * X, bar.y - bar.h / 2, bar.value * X, barheight).attr(chartinst.shim));
562
+ cover.bar = bar;
563
+ size += bar.value;
564
+ }
565
+
566
+ Y += barheight;
567
+ }
568
+
569
+ Y += bargutter;
570
+ }
571
+
572
+ covers2.toFront();
573
+ Y = y + bargutter;
574
+
575
+ if (!opts.stacked) {
576
+ for (var i = 0; i < len; i++) {
577
+ for (var j = 0; j < (multi || 1); j++) {
578
+ var cover = paper.rect(x, Y, width, barheight).attr(chartinst.shim);
579
+
580
+ covers.push(cover);
581
+ cover.bar = multi ? bars[j][i] : bars[i];
582
+ cover.value = cover.bar.value;
583
+ Y += barheight;
584
+ }
585
+
586
+ Y += bargutter;
587
+ }
588
+ }
589
+
590
+ chart.label = function (labels, isRight) {
591
+ labels = labels || [];
592
+ this.labels = paper.set();
593
+
594
+ for (var i = 0; i < len; i++) {
595
+ for (var j = 0; j < multi; j++) {
596
+ var label = paper.labelise(multi ? labels[j] && labels[j][i] : labels[i], multi ? values[j][i] : values[i], total),
597
+ X = isRight ? bars[i * (multi || 1) + j].x - barheight / 2 + 3 : x + 5,
598
+ A = isRight ? "end" : "start",
599
+ L;
600
+
601
+ this.labels.push(L = paper.text(X, bars[i * (multi || 1) + j].y, label).attr(txtattr).attr({ "text-anchor": A }).insertBefore(covers[0]));
602
+
603
+ if (L.getBBox().x < x + 5) {
604
+ L.attr({x: x + 5, "text-anchor": "start"});
605
+ } else {
606
+ bars[i * (multi || 1) + j].label = L;
607
+ }
608
+ }
609
+ }
610
+
611
+ return this;
612
+ };
613
+
614
+ chart.hover = function (fin, fout) {
615
+ covers2.hide();
616
+ covers.show();
617
+ fout = fout || function () {};
618
+ covers.mouseover(fin).mouseout(fout);
619
+ return this;
620
+ };
621
+
622
+ chart.hoverColumn = function (fin, fout) {
623
+ covers.hide();
624
+ covers2.show();
625
+ fout = fout || function () {};
626
+ covers2.mouseover(fin).mouseout(fout);
627
+ return this;
628
+ };
629
+
630
+ chart.each = function (f) {
631
+ if (!Raphael.is(f, "function")) {
632
+ return this;
633
+ }
634
+ for (var i = covers.length; i--;) {
635
+ f.call(covers[i]);
636
+ }
637
+ return this;
638
+ };
639
+
640
+ chart.eachColumn = function (f) {
641
+ if (!Raphael.is(f, "function")) {
642
+ return this;
643
+ }
644
+ for (var i = covers2.length; i--;) {
645
+ f.call(covers2[i]);
646
+ }
647
+ return this;
648
+ };
649
+
650
+ chart.click = function (f) {
651
+ covers2.hide();
652
+ covers.show();
653
+ covers.click(f);
654
+ return this;
655
+ };
656
+
657
+ chart.clickColumn = function (f) {
658
+ covers.hide();
659
+ covers2.show();
660
+ covers2.click(f);
661
+ return this;
662
+ };
663
+
664
+ chart.push(bars, covers, covers2);
665
+ chart.bars = bars;
666
+ chart.covers = covers;
667
+ return chart;
668
+ };
669
+
670
+ Raphael.fn.hbarchart = function(x, y, width, height, values, opts) {
671
+ return new HBarchart(this, x, y, width, height, values, opts);
672
+ };
673
+
674
+ })();