pizza-rails 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +46 -0
- data/Rakefile +1 -0
- data/lib/pizza/rails.rb +8 -0
- data/lib/pizza/rails/version.rb +5 -0
- data/pizza-rails.gemspec +23 -0
- data/vendor/assets/javascripts/pizza.js +2 -0
- data/vendor/assets/javascripts/pizza/bar.js +208 -0
- data/vendor/assets/javascripts/pizza/line.js +259 -0
- data/vendor/assets/javascripts/pizza/pie.js +225 -0
- data/vendor/assets/javascripts/pizza/pizza.js +256 -0
- data/vendor/assets/stylesheets/pizza.scss +53 -0
- metadata +117 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6f24edb8d0ccb3d5eb703a1da92860069662b208
|
4
|
+
data.tar.gz: 8b249f04b5dccb472557a52f1baf620dbcb05095
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 571f09781888bd95439054d38e56b83c32ed36dac03434f7a7b55698dac05f02c84d0a6bd23540c436b1de8394aba05fb3543e4e22ecb15b4f1de5fa689645ba
|
7
|
+
data.tar.gz: 18bc7e8c8b17dc2d1950c3e4b42a6293720b6c124129b3e95274202856078feabeb81b2047f19ec7814333e8a1200a699544514ed77d3f269e433eb86f88d921
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Eric Roberts
|
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,46 @@
|
|
1
|
+
# Pizza::Rails
|
2
|
+
|
3
|
+
Pizza is a responsive pie, donut, bar, and line graph charting library based on the Snap SVG framework from Adobe. It focuses on easy integration via HTML markup and CSS instead of JavaScript objects, although you can pass JavaScript objects to Pizza as well.
|
4
|
+
|
5
|
+
http://zurb.com/playground/pizza-amore-charts-and-graphs
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'pizza-rails', github: 'ericroberts/pizza-rails'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install pizza-rails
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Add the following to your application.js
|
24
|
+
|
25
|
+
//= require snap
|
26
|
+
//= require pizza
|
27
|
+
|
28
|
+
Add the following to your application.css
|
29
|
+
|
30
|
+
*= require pizza
|
31
|
+
|
32
|
+
Or, if using SCSS:
|
33
|
+
|
34
|
+
@import "pizza";
|
35
|
+
|
36
|
+
If you're using SASS/SCSS there are more details for styling you can checkout at the full docs below.
|
37
|
+
|
38
|
+
See full docs at http://zurb.com/playground/pizza-amore-charts-and-graphs
|
39
|
+
|
40
|
+
## Contributing
|
41
|
+
|
42
|
+
1. Fork it
|
43
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
44
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
45
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
46
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/pizza/rails.rb
ADDED
data/pizza-rails.gemspec
ADDED
@@ -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 'pizza/rails/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "pizza-rails"
|
8
|
+
spec.version = Pizza::Rails::VERSION
|
9
|
+
spec.authors = ["Eric Roberts"]
|
10
|
+
spec.email = ["ericroberts@gmail.com"]
|
11
|
+
spec.description = %q{Pizza is a responsive pie, donut, bar, and line graph charting library based on the Snap SVG framework from Adobe. It focuses on easy integration via HTML markup and CSS instead of JavaScript objects, although you can pass JavaScript objects to Pizza as well.}
|
12
|
+
spec.summary = %q{Rails wrapper for Pizza by Zurb}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
20
|
+
spec.add_development_dependency "rake"
|
21
|
+
spec.add_dependency "railties", ">= 3"
|
22
|
+
spec.add_dependency "snapsvg-rails", ">= 0.2.0"
|
23
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
$.extend(Pizza, {
|
2
|
+
bar: function (legend) {
|
3
|
+
var settings = legend.data('settings'),
|
4
|
+
svg = this.svg(legend, settings),
|
5
|
+
data = legend.data('graph-data'),
|
6
|
+
current_offset = 0,
|
7
|
+
container = $(this.identifier(legend)),
|
8
|
+
base_width = container.outerWidth(),
|
9
|
+
base_height = container.outerHeight(),
|
10
|
+
max = min = 0,
|
11
|
+
total = 0,
|
12
|
+
spacer = settings.bar_spacer * (settings.bar_spacer/ base_width),
|
13
|
+
interval = (base_width - (data.length * spacer)) / data.length;
|
14
|
+
|
15
|
+
if (interval < 10) {
|
16
|
+
spacer = 1;
|
17
|
+
interval = (base_width - (data.length * spacer)) / data.length;
|
18
|
+
}
|
19
|
+
|
20
|
+
for (var i = 0; i < data.length; i++) {
|
21
|
+
if (max < data[i].value) max = data[i].value;
|
22
|
+
if (min > data[i].value) min = data[i].value;
|
23
|
+
total += data[i].value;
|
24
|
+
}
|
25
|
+
|
26
|
+
var existing_group = $('g[data-id=bars]', svg);
|
27
|
+
|
28
|
+
if (existing_group.length > 0) {
|
29
|
+
var g = existing_group[0];
|
30
|
+
} else {
|
31
|
+
var g = this.svg_obj('g');
|
32
|
+
g.setAttribute('data-id', 'bars');
|
33
|
+
}
|
34
|
+
|
35
|
+
if (settings.show_grid) {
|
36
|
+
this.assemble_grid(svg, min, max, base_width, base_height, settings);
|
37
|
+
}
|
38
|
+
|
39
|
+
g.setAttribute('transform', 'translate(0, ' + (base_height) +') scale(1, -1)');
|
40
|
+
|
41
|
+
for (var i = 0; i < data.length; i++) {
|
42
|
+
var y = (base_height) * (data[i].value / max);
|
43
|
+
|
44
|
+
var existing_rect = $('rect[data-id=r' + i +']', g);
|
45
|
+
|
46
|
+
if (existing_rect.length > 0) {
|
47
|
+
var rect = existing_rect[0];
|
48
|
+
} else {
|
49
|
+
var rect = this.svg_obj('rect');
|
50
|
+
rect.setAttribute('data-id', 'r' + i);
|
51
|
+
}
|
52
|
+
|
53
|
+
if (current_offset === 0) {
|
54
|
+
var new_offset = current_offset;
|
55
|
+
} else {
|
56
|
+
var new_offset = current_offset + spacer;
|
57
|
+
}
|
58
|
+
|
59
|
+
rect.setAttribute('data-y', y);
|
60
|
+
|
61
|
+
this.set_attr(rect, {
|
62
|
+
x : new_offset,
|
63
|
+
y : 0,
|
64
|
+
width : interval,
|
65
|
+
height : 0,
|
66
|
+
fill: data[i].color,
|
67
|
+
stroke: settings.stroke_color,
|
68
|
+
'strokeWidth': settings.stroke_width
|
69
|
+
});
|
70
|
+
|
71
|
+
Snap(rect).animate({height: y}, 1500, mina[settings.animation_type]);
|
72
|
+
|
73
|
+
current_offset = new_offset + interval;
|
74
|
+
|
75
|
+
if (existing_group.length < 1) {
|
76
|
+
g.appendChild(rect);
|
77
|
+
this.animate_bar(Snap(rect), y, settings);
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
if (existing_group.length < 1) {
|
82
|
+
svg.appendChild(g);
|
83
|
+
}
|
84
|
+
|
85
|
+
return [legend, svg];
|
86
|
+
},
|
87
|
+
|
88
|
+
animate_bar : function (el, y, settings) {
|
89
|
+
var self = this,
|
90
|
+
$el = $(el),
|
91
|
+
new_y = y + 15;
|
92
|
+
|
93
|
+
el.hover(function (e) {
|
94
|
+
var path = Snap(e.target);
|
95
|
+
|
96
|
+
path.animate({
|
97
|
+
height: new_y
|
98
|
+
}, settings.animation_speed, mina[settings.animation_type]);
|
99
|
+
|
100
|
+
}, function (e) {
|
101
|
+
var path = Snap(e.target);
|
102
|
+
|
103
|
+
path.animate({
|
104
|
+
height: y
|
105
|
+
}, settings.animation_speed, mina[settings.animation_type]);
|
106
|
+
});
|
107
|
+
|
108
|
+
},
|
109
|
+
|
110
|
+
assemble_grid : function (svg, min, max, width, height, settings) {
|
111
|
+
var existing_group = $('g[data-id=bars]', svg);
|
112
|
+
|
113
|
+
if (existing_group.length > 0) {
|
114
|
+
var line_g = $('g[data-id=grid]', svg)[0],
|
115
|
+
text_g = $('g[data-id=labels]', svg)[0];
|
116
|
+
} else {
|
117
|
+
var line_g = this.svg_obj('g'),
|
118
|
+
text_g = this.svg_obj('g');
|
119
|
+
|
120
|
+
line_g.setAttribute('data-id', 'grid');
|
121
|
+
text_g.setAttribute('data-id', 'labels');
|
122
|
+
}
|
123
|
+
|
124
|
+
var ticks = this.ticks(min, max, settings.bar_intervals),
|
125
|
+
ticks_length = i = ticks.length,
|
126
|
+
interval = height/(ticks_length-1),
|
127
|
+
total_tick_height = 0;
|
128
|
+
|
129
|
+
while (i--) {
|
130
|
+
if (existing_group.length > 0) {
|
131
|
+
var line = $('line[data-id=l' + i + ']', line_g)[0],
|
132
|
+
text = $('text[data-id=t' + i + ']', text_g)[0];
|
133
|
+
} else {
|
134
|
+
var line = this.svg_obj('line'),
|
135
|
+
text = this.svg_obj('text');
|
136
|
+
|
137
|
+
line.setAttribute('data-id', 'l' + i);
|
138
|
+
text.setAttribute('data-id', 't' + i);
|
139
|
+
}
|
140
|
+
|
141
|
+
var line_height = total_tick_height + interval;
|
142
|
+
|
143
|
+
this.set_attr(line, {
|
144
|
+
x1 : 0,
|
145
|
+
x2 : width,
|
146
|
+
y1 : line_height,
|
147
|
+
y2 : line_height,
|
148
|
+
stroke : 'gray',
|
149
|
+
'stroke-width' : 1,
|
150
|
+
'stroke-dasharray' : '5,5'
|
151
|
+
})
|
152
|
+
.set_attr(text, {
|
153
|
+
x : -8,
|
154
|
+
y : line_height + 5,
|
155
|
+
'text-anchor': 'end'
|
156
|
+
});
|
157
|
+
|
158
|
+
text.innerHTML = ticks[i];
|
159
|
+
|
160
|
+
if (existing_group.length < 1) {
|
161
|
+
line_g.appendChild(line);
|
162
|
+
text_g.appendChild(text);
|
163
|
+
}
|
164
|
+
|
165
|
+
total_tick_height = line_height;
|
166
|
+
}
|
167
|
+
|
168
|
+
line_g.setAttribute('transform', 'translate(0, -' + total_tick_height / ticks_length + ')');
|
169
|
+
text_g.setAttribute('transform', 'translate(0, -' + total_tick_height / ticks_length + ')');
|
170
|
+
|
171
|
+
if (existing_group.length < 1) {
|
172
|
+
svg.appendChild(line_g);
|
173
|
+
svg.appendChild(text_g);
|
174
|
+
}
|
175
|
+
|
176
|
+
},
|
177
|
+
|
178
|
+
bar_events : function () {
|
179
|
+
var self = this;
|
180
|
+
|
181
|
+
$(this.scope).on('mouseenter.pizza mouseleave.pizza touchstart.pizza', '[data-bar-id] li', function (e) {
|
182
|
+
var parent = $(this).parent(),
|
183
|
+
path = $('#' + parent.attr('data-bar-id') + ' rect[data-id=r' + $(this).index() + ']')[0],
|
184
|
+
settings = $(this).parent().data('settings'),
|
185
|
+
new_height = parseInt(path.getAttribute('data-y'), 10) + 15;
|
186
|
+
|
187
|
+
if (/start/i.test(e.type)) {
|
188
|
+
$(path).siblings('rect').each(function () {
|
189
|
+
if (this.nodeName) {
|
190
|
+
Snap(path).animate({
|
191
|
+
height: path.getAttribute('data-y')
|
192
|
+
}, settings.animation_speed, mina[settings.animation_type]);
|
193
|
+
}
|
194
|
+
});
|
195
|
+
}
|
196
|
+
|
197
|
+
if (/enter|start/i.test(e.type)) {
|
198
|
+
Snap(path).animate({
|
199
|
+
height: new_height
|
200
|
+
}, settings.animation_speed, mina[settings.animation_type]);
|
201
|
+
} else {
|
202
|
+
Snap(path).animate({
|
203
|
+
height: path.getAttribute('data-y')
|
204
|
+
}, settings.animation_speed, mina[settings.animation_type]);
|
205
|
+
}
|
206
|
+
});
|
207
|
+
}
|
208
|
+
});
|
@@ -0,0 +1,259 @@
|
|
1
|
+
$.extend(Pizza, {
|
2
|
+
line : function (legend) {
|
3
|
+
var settings = legend.data('settings'),
|
4
|
+
svg = this.svg(legend, settings),
|
5
|
+
container = $(this.identifier(legend)),
|
6
|
+
width = container.outerWidth(),
|
7
|
+
height = container.outerHeight(),
|
8
|
+
data = legend.data('graph-data'),
|
9
|
+
max_x = max_y = min_x = min_y = total_x = total_y = 0,
|
10
|
+
i = data.length,
|
11
|
+
points = '';
|
12
|
+
|
13
|
+
for (var i = 0; i < data.length; i++) {
|
14
|
+
if (data[i].x > max_x) max_x = data[i].x;
|
15
|
+
if (data[i].y > max_y) max_y = data[i].y;
|
16
|
+
if (min_x > data[i].x) min_x = data[i].x;
|
17
|
+
if (min_y > data[i].y) min_y = data[i].y;
|
18
|
+
total_x += data[i].x;
|
19
|
+
total_y += data[i].y;
|
20
|
+
}
|
21
|
+
|
22
|
+
var existing_group = $('g[data-id=line]', svg);
|
23
|
+
|
24
|
+
if (existing_group.length > 0) {
|
25
|
+
var line_g = $('g[data-id=line]', svg)[0],
|
26
|
+
circle_g = $('g[data-id=points]', svg)[0],
|
27
|
+
polyline = $('path[data-id=path]', line_g)[0];
|
28
|
+
} else {
|
29
|
+
var polyline = this.svg_obj('path'),
|
30
|
+
line_g = this.svg_obj('g'),
|
31
|
+
circle_g = this.svg_obj('g');
|
32
|
+
|
33
|
+
line_g.setAttribute('data-id', 'line');
|
34
|
+
circle_g.setAttribute('data-id', 'points');
|
35
|
+
polyline.setAttribute('data-id', 'path');
|
36
|
+
}
|
37
|
+
|
38
|
+
for (var i = 0; i < data.length; i++) {
|
39
|
+
if (existing_group.length > 0) {
|
40
|
+
var circle = $('circle[data-id=c' + i + ']', circle_g)[0];
|
41
|
+
} else {
|
42
|
+
var circle = this.svg_obj('circle');
|
43
|
+
|
44
|
+
circle.setAttribute('data-id', 'c' + i);
|
45
|
+
}
|
46
|
+
|
47
|
+
var x = (data[i].x / max_x) * width,
|
48
|
+
y = (data[i].y / max_y) * height;
|
49
|
+
|
50
|
+
points += x + ',' + y + ' ';
|
51
|
+
this.set_attr(circle, {cx: x, cy: y,r: 0,fill: data[i.color],
|
52
|
+
'data-value': data[i].x + ', ' + data[i].y,
|
53
|
+
'data-tooltip': '',
|
54
|
+
'title': data[i].x + ', ' + data[i].y,
|
55
|
+
'class': 'has-tip tip-top'});
|
56
|
+
|
57
|
+
Snap(circle).animate({
|
58
|
+
r: 4
|
59
|
+
}, 1500, mina[settings.animation_type]);
|
60
|
+
|
61
|
+
this.animate(Snap(circle), x, y, settings, 2);
|
62
|
+
|
63
|
+
if (existing_group.length < 1) {
|
64
|
+
circle_g.appendChild(circle);
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
this.flip(circle_g, height);
|
69
|
+
this.flip(line_g, height);
|
70
|
+
|
71
|
+
if (settings.show_grid) {
|
72
|
+
this.assemble_grid_x(svg, min_x, max_x, width, height, settings);
|
73
|
+
this.assemble_grid_y(svg, min_y, max_y, width, height, settings);
|
74
|
+
}
|
75
|
+
var v = this.points_to_path(points);
|
76
|
+
|
77
|
+
this.set_attr(polyline, {d:v, fill: 'none', stroke: 'black', 'stroke-width': 2});
|
78
|
+
|
79
|
+
if (existing_group.length < 1) {
|
80
|
+
line_g.appendChild(polyline);
|
81
|
+
svg.appendChild(line_g);
|
82
|
+
}
|
83
|
+
|
84
|
+
if (existing_group.length < 1) {
|
85
|
+
svg.appendChild(circle_g);
|
86
|
+
}
|
87
|
+
|
88
|
+
return [legend, svg];
|
89
|
+
},
|
90
|
+
|
91
|
+
assemble_grid_x : function (svg, min, max, width, height, settings) {
|
92
|
+
var existing_group = $('g[data-id=gridx]', svg);
|
93
|
+
|
94
|
+
if (existing_group.length > 0) {
|
95
|
+
var line_g = existing_group[0],
|
96
|
+
text_g = $('g[data-id=labelx]', svg)[0];
|
97
|
+
} else {
|
98
|
+
var line_g = this.svg_obj('g'),
|
99
|
+
text_g = this.svg_obj('g');
|
100
|
+
|
101
|
+
line_g.setAttribute('data-id', 'gridx');
|
102
|
+
text_g.setAttribute('data-id', 'labelx');
|
103
|
+
}
|
104
|
+
|
105
|
+
var ticks = this.ticks(min, max, settings.bar_intervals).reverse(),
|
106
|
+
ticks_length = i = ticks.length,
|
107
|
+
total_tick_width = 0,
|
108
|
+
interval = width/(ticks_length-1);
|
109
|
+
|
110
|
+
while (i--) {
|
111
|
+
if (existing_group.length > 0) {
|
112
|
+
var line = $('line[data-id=l' + i + ']', line_g)[0],
|
113
|
+
text = $('text[data-id=t' + i + ']', text_g)[0];
|
114
|
+
} else {
|
115
|
+
var line = this.svg_obj('line'),
|
116
|
+
text = this.svg_obj('text');
|
117
|
+
|
118
|
+
line.setAttribute('data-id', 'l' + i);
|
119
|
+
text.setAttribute('data-id', 't' + i);
|
120
|
+
}
|
121
|
+
|
122
|
+
var line_width = total_tick_width + interval;
|
123
|
+
|
124
|
+
this.set_attr(line, {
|
125
|
+
x1 : line_width,
|
126
|
+
x2 : line_width,
|
127
|
+
y1 : 0,
|
128
|
+
y2 : height,
|
129
|
+
stroke : 'gray',
|
130
|
+
'stroke-width' : 1,
|
131
|
+
'stroke-dasharray' : '5,5'
|
132
|
+
})
|
133
|
+
.set_attr(text, {
|
134
|
+
y: height + 20,
|
135
|
+
x: line_width - interval,
|
136
|
+
'text-anchor': 'middle'
|
137
|
+
});
|
138
|
+
|
139
|
+
if (existing_group.length < 1) {
|
140
|
+
text.innerHTML = ticks[i];
|
141
|
+
text_g.appendChild(text);
|
142
|
+
line_g.appendChild(line);
|
143
|
+
}
|
144
|
+
|
145
|
+
total_tick_width = line_width;
|
146
|
+
}
|
147
|
+
|
148
|
+
line_g.setAttribute('transform', 'translate(-' + interval + ', 0)');
|
149
|
+
|
150
|
+
if (existing_group.length < 1) {
|
151
|
+
svg.appendChild(line_g);
|
152
|
+
svg.appendChild(text_g);
|
153
|
+
}
|
154
|
+
},
|
155
|
+
|
156
|
+
assemble_grid_y : function (svg, min, max, width, height, settings) {
|
157
|
+
var existing_group = $('g[data-id=gridy]', svg);
|
158
|
+
|
159
|
+
if (existing_group.length > 0) {
|
160
|
+
var line_g = existing_group[0],
|
161
|
+
text_g = $('g[data-id=labely]', svg)[0];
|
162
|
+
} else {
|
163
|
+
var line_g = this.svg_obj('g'),
|
164
|
+
text_g = this.svg_obj('g');
|
165
|
+
|
166
|
+
line_g.setAttribute('data-id', 'gridy');
|
167
|
+
text_g.setAttribute('data-id', 'labely');
|
168
|
+
}
|
169
|
+
|
170
|
+
var ticks = this.ticks(min, max, settings.bar_intervals),
|
171
|
+
ticks_length = i = ticks.length,
|
172
|
+
total_tick_height = 0;
|
173
|
+
|
174
|
+
while (i--) {
|
175
|
+
if (existing_group.length > 0) {
|
176
|
+
var line = $('line[data-id=l' + i + ']', line_g)[0],
|
177
|
+
text = $('text[data-id=t' + i + ']', text_g)[0];
|
178
|
+
} else {
|
179
|
+
var line = this.svg_obj('line'),
|
180
|
+
text = this.svg_obj('text');
|
181
|
+
|
182
|
+
line.setAttribute('data-id', 'l' + i);
|
183
|
+
text.setAttribute('data-id', 't' + i);
|
184
|
+
}
|
185
|
+
|
186
|
+
var line_height = total_tick_height + (height/(ticks_length-1));
|
187
|
+
|
188
|
+
this.set_attr(line, {
|
189
|
+
x1 : 0,
|
190
|
+
x2 : width,
|
191
|
+
y1 : line_height,
|
192
|
+
y2 : line_height,
|
193
|
+
stroke : 'gray',
|
194
|
+
'stroke-width' : 1,
|
195
|
+
'stroke-dasharray' : '5,5'
|
196
|
+
})
|
197
|
+
.set_attr(text, {
|
198
|
+
x : -8,
|
199
|
+
y : line_height + 5,
|
200
|
+
'text-anchor': 'end'
|
201
|
+
});
|
202
|
+
|
203
|
+
if (existing_group.length < 1) {
|
204
|
+
text_g.appendChild(text);
|
205
|
+
line_g.appendChild(line);
|
206
|
+
text.innerHTML = ticks[i];
|
207
|
+
}
|
208
|
+
|
209
|
+
total_tick_height = line_height;
|
210
|
+
}
|
211
|
+
|
212
|
+
line_g.setAttribute('transform', 'translate(0, -' + total_tick_height / ticks_length + ')');
|
213
|
+
text_g.setAttribute('transform', 'translate(0, -' + total_tick_height / ticks_length + ')');
|
214
|
+
|
215
|
+
if (existing_group.length < 1) {
|
216
|
+
svg.appendChild(line_g);
|
217
|
+
svg.appendChild(text_g);
|
218
|
+
}
|
219
|
+
|
220
|
+
},
|
221
|
+
|
222
|
+
points_to_path : function (points) {
|
223
|
+
var points = points.split(/\s+|,/);
|
224
|
+
var x0=points.shift(), y0=points.shift();
|
225
|
+
var pathdata = 'M'+x0+','+y0+'L'+points.join(' ');
|
226
|
+
return ['M'+x0+','+y0+'L'].concat(points).join(' ');
|
227
|
+
},
|
228
|
+
|
229
|
+
line_events : function () {
|
230
|
+
$(this.scope).on('mouseenter.pizza mouseleave.pizza touchstart.pizza', '[data-line-id] li', function (e) {
|
231
|
+
var parent = $(this).parent(),
|
232
|
+
path = $('#' + parent.data('line-id') + ' circle[data-id="c' + $(this).index() + '"]')[0],
|
233
|
+
settings = $(this).parent().data('settings');
|
234
|
+
|
235
|
+
if (/start/i.test(e.type)) {
|
236
|
+
$(path).siblings('circle').each(function () {
|
237
|
+
if (this.nodeName) {
|
238
|
+
Snap(path).animate({
|
239
|
+
transform: 's1 1 ' + path.getAttribute('cx') + ' ' + path.getAttribute('cy')
|
240
|
+
}, settings.animation_speed, mina[settings.animation_type]);
|
241
|
+
}
|
242
|
+
});
|
243
|
+
}
|
244
|
+
|
245
|
+
if (/enter|start/i.test(e.type)) {
|
246
|
+
Snap(path).animate({
|
247
|
+
transform: 's2 2 ' + path.getAttribute('cx') + ' ' + path.getAttribute('cy')
|
248
|
+
}, settings.animation_speed, mina[settings.animation_type]);
|
249
|
+
$(path).trigger('mouseenter')
|
250
|
+
} else {
|
251
|
+
Snap(path).animate({
|
252
|
+
transform: 's1 1 ' + path.getAttribute('cx') + ' ' + path.getAttribute('cy')
|
253
|
+
}, settings.animation_speed, mina[settings.animation_type]);
|
254
|
+
$(path).trigger('mouseout')
|
255
|
+
}
|
256
|
+
});
|
257
|
+
}
|
258
|
+
|
259
|
+
});
|
@@ -0,0 +1,225 @@
|
|
1
|
+
$.extend(Pizza, {
|
2
|
+
pie : function (legend) {
|
3
|
+
// pie chart concept from JavaScript the
|
4
|
+
// Definitive Guide 6th edition by David Flanagan
|
5
|
+
var settings = legend.data('settings'),
|
6
|
+
svg = this.svg(legend, settings),
|
7
|
+
data = legend.data('graph-data'),
|
8
|
+
total = 0,
|
9
|
+
angles = [],
|
10
|
+
start_angle = 0,
|
11
|
+
container = $(this.identifier(legend)),
|
12
|
+
base = container.outerWidth();
|
13
|
+
|
14
|
+
for (var i = 0; i < data.length; i++) {
|
15
|
+
total += data[i].value;
|
16
|
+
}
|
17
|
+
|
18
|
+
for (var i = 0; i < data.length; i++) {
|
19
|
+
angles[i] = data[i].value / total * Math.PI * 2;
|
20
|
+
}
|
21
|
+
|
22
|
+
if(angles.length == 1) angles[0] = Math.PI * 2 - 0.0001; // if 1
|
23
|
+
|
24
|
+
for (var i = 0; i < data.length; i++) {
|
25
|
+
var end_angle = start_angle + angles[i];
|
26
|
+
var cx = (base / 2),
|
27
|
+
cy = (base / 2),
|
28
|
+
r = ((base / 2) * 0.85);
|
29
|
+
|
30
|
+
if (!settings.donut) {
|
31
|
+
// Compute the two points where our wedge intersects the circle
|
32
|
+
// These formulas are chosen so that an angle of 0 is at 12 o'clock
|
33
|
+
// and positive angles increase clockwise
|
34
|
+
var x1 = cx + r * Math.sin(start_angle);
|
35
|
+
var y1 = cy - r * Math.cos(start_angle);
|
36
|
+
var x2 = cx + r * Math.sin(end_angle);
|
37
|
+
var y2 = cy - r * Math.cos(end_angle);
|
38
|
+
|
39
|
+
// This is a flag for angles larger than than a half circle
|
40
|
+
// It is required by the SVG arc drawing component
|
41
|
+
var big = 0;
|
42
|
+
if (end_angle - start_angle > Math.PI) big = 1;
|
43
|
+
|
44
|
+
// This string holds the path details
|
45
|
+
var d = "M" + cx + "," + cy + // Start at circle center
|
46
|
+
" L" + x1 + "," + y1 + // Draw line to (x1,y1)
|
47
|
+
" A" + r + "," + r + // Draw an arc of radius r
|
48
|
+
" 0 " + big + " 1 " + // Arc details...
|
49
|
+
x2 + "," + y2 + // Arc goes to to (x2,y2)
|
50
|
+
" Z"; // Close path back to (cx,cy)
|
51
|
+
}
|
52
|
+
|
53
|
+
var existing_path = $('path[data-id="s' + i + '"]', svg);
|
54
|
+
|
55
|
+
if (existing_path.length > 0) {
|
56
|
+
var path = existing_path[0];
|
57
|
+
} else {
|
58
|
+
var path = this.svg_obj('path');
|
59
|
+
}
|
60
|
+
|
61
|
+
var percent = (data[i].value / total) * 100.0;
|
62
|
+
|
63
|
+
var existing_text = $('text[data-id="s' + i + '"]', svg);
|
64
|
+
|
65
|
+
if (existing_text.length > 0) {
|
66
|
+
var text = existing_text[0];
|
67
|
+
|
68
|
+
text.setAttribute('x', cx + (r + settings.percent_offset) * Math.sin(start_angle + (angles[i] / 2)));
|
69
|
+
text.setAttribute('y', cy - (r + settings.percent_offset) * Math.cos(start_angle + (angles[i] / 2)));
|
70
|
+
|
71
|
+
} else {
|
72
|
+
|
73
|
+
if (data[i].text) {
|
74
|
+
var visible_text = this.parse_options(data[i].text, percent, data[i].value);
|
75
|
+
} else {
|
76
|
+
var visible_text = Math.ceil(percent) + '%';
|
77
|
+
}
|
78
|
+
var text = this.svg_obj('text');
|
79
|
+
|
80
|
+
text.setAttribute('x', cx + (r + settings.percent_offset) * Math.sin(start_angle + (angles[i] / 2)));
|
81
|
+
text.setAttribute('y', cy - (r + settings.percent_offset) * Math.cos(start_angle + (angles[i] / 2)));
|
82
|
+
text.innerHTML = visible_text;
|
83
|
+
}
|
84
|
+
|
85
|
+
text.setAttribute('text-anchor', 'middle');
|
86
|
+
|
87
|
+
if (settings.always_show_text) {
|
88
|
+
Snap(text).animate({
|
89
|
+
opacity: 1
|
90
|
+
}, settings.animation_speed);
|
91
|
+
} else {
|
92
|
+
Snap(text).attr({
|
93
|
+
opacity: 0
|
94
|
+
}, settings.animation_speed);
|
95
|
+
}
|
96
|
+
|
97
|
+
text.setAttribute('data-id', 's' + i);
|
98
|
+
|
99
|
+
if (settings.donut) {
|
100
|
+
this.annular_sector(path, {
|
101
|
+
centerX:cx, centerY:cy,
|
102
|
+
startDegrees:start_angle, endDegrees:end_angle,
|
103
|
+
innerRadius: (r * settings.donut_inner_ratio), outerRadius:r
|
104
|
+
});
|
105
|
+
} else {
|
106
|
+
path.setAttribute('d', d);
|
107
|
+
}
|
108
|
+
|
109
|
+
this.set_attr(path, {
|
110
|
+
fill: data[i].color,
|
111
|
+
stroke: settings.stroke_color,
|
112
|
+
'strokeWidth': settings.stroke_width,
|
113
|
+
'data-cx' : cx,
|
114
|
+
'data-cy' : cy,
|
115
|
+
'data-id' : 's' + i
|
116
|
+
});
|
117
|
+
|
118
|
+
var existing_group = $('g[data-id=g' + i + ']', svg);
|
119
|
+
|
120
|
+
if (existing_group.length < 1) {
|
121
|
+
var g = this.svg_obj('g');
|
122
|
+
|
123
|
+
g.setAttribute('data-id', 'g' + i);
|
124
|
+
g.appendChild(path);
|
125
|
+
g.appendChild(text);
|
126
|
+
svg.appendChild(g);
|
127
|
+
|
128
|
+
this.animate(Snap(path), cx, cy, settings);
|
129
|
+
}
|
130
|
+
|
131
|
+
// The next wedge begins where this one ends
|
132
|
+
start_angle = end_angle;
|
133
|
+
}
|
134
|
+
|
135
|
+
return [legend, svg];
|
136
|
+
},
|
137
|
+
|
138
|
+
annular_sector : function (path, options) {
|
139
|
+
var opts = optionsWithDefaults(options);
|
140
|
+
|
141
|
+
var p = [ // points
|
142
|
+
[opts.cx + opts.r2*Math.sin(opts.startRadians),
|
143
|
+
opts.cy - opts.r2*Math.cos(opts.startRadians)],
|
144
|
+
[opts.cx + opts.r2*Math.sin(opts.closeRadians),
|
145
|
+
opts.cy - opts.r2*Math.cos(opts.closeRadians)],
|
146
|
+
[opts.cx + opts.r1*Math.sin(opts.closeRadians),
|
147
|
+
opts.cy - opts.r1*Math.cos(opts.closeRadians)],
|
148
|
+
[opts.cx + opts.r1*Math.sin(opts.startRadians),
|
149
|
+
opts.cy - opts.r1*Math.cos(opts.startRadians)],
|
150
|
+
];
|
151
|
+
|
152
|
+
var angleDiff = opts.closeRadians - opts.startRadians;
|
153
|
+
var largeArc = (angleDiff % (Math.PI*2)) > Math.PI ? 1 : 0;
|
154
|
+
var cmds = [];
|
155
|
+
cmds.push("M"+p[0].join()); // Move to P0
|
156
|
+
cmds.push("A"+[opts.r2,opts.r2,0,largeArc,1,p[1]].join()); // Arc to P1
|
157
|
+
cmds.push("L"+p[2].join()); // Line to P2
|
158
|
+
cmds.push("A"+[opts.r1,opts.r1,0,largeArc,0,p[3]].join()); // Arc to P3
|
159
|
+
cmds.push("z"); // Close path (Line to P0)
|
160
|
+
path.setAttribute('d',cmds.join(' '));
|
161
|
+
|
162
|
+
function optionsWithDefaults(o){
|
163
|
+
// Create a new object so that we don't mutate the original
|
164
|
+
var o2 = {
|
165
|
+
cx : o.centerX || 0,
|
166
|
+
cy : o.centerY || 0,
|
167
|
+
startRadians : (o.startDegrees || 0),
|
168
|
+
closeRadians : (o.endDegrees || 0),
|
169
|
+
};
|
170
|
+
|
171
|
+
var t = o.thickness!==undefined ? o.thickness : 100;
|
172
|
+
if (o.innerRadius!==undefined) o2.r1 = o.innerRadius;
|
173
|
+
else if (o.outerRadius!==undefined) o2.r1 = o.outerRadius - t;
|
174
|
+
else o2.r1 = 200 - t;
|
175
|
+
if (o.outerRadius!==undefined) o2.r2 = o.outerRadius;
|
176
|
+
else o2.r2 = o2.r1 + t;
|
177
|
+
|
178
|
+
if (o2.r1<0) o2.r1 = 0;
|
179
|
+
if (o2.r2<0) o2.r2 = 0;
|
180
|
+
|
181
|
+
return o2;
|
182
|
+
}
|
183
|
+
},
|
184
|
+
|
185
|
+
pie_events : function () {
|
186
|
+
$(this.scope).on('mouseenter.pizza mouseleave.pizza touchstart.pizza', '[data-pie-id] li', function (e) {
|
187
|
+
var parent = $(this).parent(),
|
188
|
+
path = $('#' + parent.attr('data-pie-id') + ' path[data-id="s' + $(this).index() + '"]')[0],
|
189
|
+
text = path.nextSibling,
|
190
|
+
settings = $(this).parent().data('settings');
|
191
|
+
|
192
|
+
if (/start/i.test(e.type)) {
|
193
|
+
$(path).siblings('path').each(function () {
|
194
|
+
if (this.nodeName) {
|
195
|
+
Snap(path).animate({
|
196
|
+
transform: 's1 1 ' + path.getAttribute('data-cx') + ' ' + path.getAttribute('data-cy')
|
197
|
+
}, settings.animation_speed, mina[settings.animation_type]);
|
198
|
+
Snap($(this).next()[0]).animate({
|
199
|
+
opacity: 0
|
200
|
+
}, settings.animation_speed);
|
201
|
+
}
|
202
|
+
});
|
203
|
+
}
|
204
|
+
|
205
|
+
if (/enter|start/i.test(e.type)) {
|
206
|
+
Snap(path).animate({
|
207
|
+
transform: 's1.05 1.05 ' + path.getAttribute('data-cx') + ' ' + path.getAttribute('data-cy')
|
208
|
+
}, settings.animation_speed, mina[settings.animation_type]);
|
209
|
+
|
210
|
+
if (settings.show_text) {
|
211
|
+
Snap(text).animate({
|
212
|
+
opacity: 1
|
213
|
+
}, settings.animation_speed);
|
214
|
+
}
|
215
|
+
} else {
|
216
|
+
Snap(path).animate({
|
217
|
+
transform: 's1 1 ' + path.getAttribute('data-cx') + ' ' + path.getAttribute('data-cy')
|
218
|
+
}, settings.animation_speed, mina[settings.animation_type]);
|
219
|
+
Snap(text).animate({
|
220
|
+
opacity: 0
|
221
|
+
}, settings.animation_speed);
|
222
|
+
}
|
223
|
+
});
|
224
|
+
}
|
225
|
+
});
|
@@ -0,0 +1,256 @@
|
|
1
|
+
var Pizza = {
|
2
|
+
version : '0.2.1',
|
3
|
+
|
4
|
+
settings : {
|
5
|
+
donut: false,
|
6
|
+
donut_inner_ratio: 0.4, // between 0 and 1
|
7
|
+
percent_offset: 35, // relative to radius
|
8
|
+
show_text: true, // show or hide the percentage on the chart.
|
9
|
+
animation_speed: 500,
|
10
|
+
always_show_text: false,
|
11
|
+
show_grid: true,
|
12
|
+
bar_spacer: 100,
|
13
|
+
bar_intervals: 6,
|
14
|
+
animation_type: 'elastic' // options: backin, backout, bounce, easein,
|
15
|
+
// easeinout, easeout, linear
|
16
|
+
},
|
17
|
+
|
18
|
+
NS : 'http://www.w3.org/2000/svg',
|
19
|
+
|
20
|
+
init : function (scope, options) {
|
21
|
+
var self = this;
|
22
|
+
this.scope = scope || document.body;
|
23
|
+
|
24
|
+
var charts = $('[data-pie-id], [data-line-id], [data-bar-id]', this.scope);
|
25
|
+
|
26
|
+
$.extend(true, this.settings, options);
|
27
|
+
|
28
|
+
if (charts.length > 0) {
|
29
|
+
charts.each(function () {
|
30
|
+
return self.build($(this), options);
|
31
|
+
});
|
32
|
+
} else if ($(this.scope).is('[data-pie-id]')
|
33
|
+
|| $(this.scope).is('[data-line-id]')
|
34
|
+
|| $(this.scope).is('[data-bar-id]')) {
|
35
|
+
this.build($(this.scope), options);
|
36
|
+
}
|
37
|
+
|
38
|
+
this.events();
|
39
|
+
},
|
40
|
+
|
41
|
+
events : function () {
|
42
|
+
var self = this;
|
43
|
+
|
44
|
+
$(window).off('.pizza').on('resize.pizza', self.throttle(function () {
|
45
|
+
self.init();
|
46
|
+
}, 500));
|
47
|
+
|
48
|
+
$(this.scope).off('.pizza');
|
49
|
+
|
50
|
+
this.pie_events();
|
51
|
+
this.line_events();
|
52
|
+
this.bar_events();
|
53
|
+
},
|
54
|
+
|
55
|
+
build : function(legend, options) {
|
56
|
+
legend.data('settings', $.extend({}, this.settings, options, legend.data('options')));
|
57
|
+
|
58
|
+
this.data(legend, options || {});
|
59
|
+
|
60
|
+
if (legend.data('pie-id')) {
|
61
|
+
this.update_DOM(this.pie(legend));
|
62
|
+
} else if (legend.data('line-id')) {
|
63
|
+
this.update_DOM(this.line(legend));
|
64
|
+
} else if (legend.data('bar-id')) {
|
65
|
+
this.update_DOM(this.bar(legend));
|
66
|
+
}
|
67
|
+
},
|
68
|
+
|
69
|
+
data : function (legend, options) {
|
70
|
+
var data = [],
|
71
|
+
count = 0;
|
72
|
+
|
73
|
+
$('li', legend).each(function () {
|
74
|
+
var segment = $(this);
|
75
|
+
|
76
|
+
if (options.data) {
|
77
|
+
data.push({
|
78
|
+
value: options.data[segment.index()],
|
79
|
+
text: segment.data('text'),
|
80
|
+
color: segment.css('color'),
|
81
|
+
segment: segment
|
82
|
+
});
|
83
|
+
} else {
|
84
|
+
data.push({
|
85
|
+
x : segment.data('x'),
|
86
|
+
y : segment.data('y'),
|
87
|
+
value: segment.data('value'),
|
88
|
+
text: segment.data('text'),
|
89
|
+
color: segment.css('color'),
|
90
|
+
segment: segment
|
91
|
+
});
|
92
|
+
}
|
93
|
+
});
|
94
|
+
|
95
|
+
return legend.data('graph-data', data);
|
96
|
+
},
|
97
|
+
|
98
|
+
update_DOM : function (parts) {
|
99
|
+
var legend = parts[0],
|
100
|
+
graph = parts[1];
|
101
|
+
|
102
|
+
return $(this.identifier(legend)).html(graph);
|
103
|
+
},
|
104
|
+
|
105
|
+
animate : function (el, cx, cy, settings, scale) {
|
106
|
+
var self = this,
|
107
|
+
scale = scale || 1.05;
|
108
|
+
|
109
|
+
el.hover(function (e) {
|
110
|
+
var path = Snap(e.target),
|
111
|
+
text = Snap(path.node.nextSibling);
|
112
|
+
|
113
|
+
path.animate({
|
114
|
+
transform: 's' + scale + ' ' + scale + ' ' + cx + ' ' + cy
|
115
|
+
}, settings.animation_speed, mina[settings.animation_type]);
|
116
|
+
|
117
|
+
if (!/text/.test(text.node.nodeName)) return;
|
118
|
+
|
119
|
+
text.touchend(function () {
|
120
|
+
Snap(path).animate({
|
121
|
+
transform: 's' + scale + ' ' + scale + ' ' + cx + ' ' + cy
|
122
|
+
}, settings.animation_speed, mina[settings.animation_type]);
|
123
|
+
});
|
124
|
+
|
125
|
+
if (settings.show_text) {
|
126
|
+
text.animate({
|
127
|
+
opacity: 1
|
128
|
+
}, settings.animation_speed);
|
129
|
+
text.touchend(function () {
|
130
|
+
text.animate({
|
131
|
+
opacity: 1
|
132
|
+
}, settings.animation_speed);
|
133
|
+
});
|
134
|
+
}
|
135
|
+
|
136
|
+
}, function (e) {
|
137
|
+
var path = Snap(e.target),
|
138
|
+
text = Snap(path.node.nextSibling);
|
139
|
+
|
140
|
+
path.animate({
|
141
|
+
transform: 's1 1 ' + cx + ' ' + cy
|
142
|
+
}, settings.animation_speed, mina[settings.animation_type]);
|
143
|
+
|
144
|
+
if (!/text/.test(text.node.nodeName)) return;
|
145
|
+
|
146
|
+
text.animate({
|
147
|
+
opacity: 0
|
148
|
+
}, settings.animation_speed);
|
149
|
+
});
|
150
|
+
|
151
|
+
},
|
152
|
+
|
153
|
+
parse_options : function (string, percent, value) {
|
154
|
+
var matches = string.match(/{{(percent|value)}}/g),
|
155
|
+
output = '';
|
156
|
+
|
157
|
+
for (var i = 0; i < matches.length; i++) {
|
158
|
+
|
159
|
+
if (/percent/i.test(matches[i])) {
|
160
|
+
output = string.replace(matches[i], [Math.ceil(percent), '%'].join(''));
|
161
|
+
}
|
162
|
+
|
163
|
+
if (/value/i.test(matches[i])) {
|
164
|
+
output = output.replace(matches[i], value);
|
165
|
+
}
|
166
|
+
}
|
167
|
+
|
168
|
+
return output;
|
169
|
+
},
|
170
|
+
|
171
|
+
svg : function (legend, settings) {
|
172
|
+
var container = $(this.identifier(legend)),
|
173
|
+
svg = $('svg', container),
|
174
|
+
width = container.width(),
|
175
|
+
pie = legend.attr('data-pie-id'),
|
176
|
+
height = container.height();
|
177
|
+
|
178
|
+
if (svg.length > 0) {
|
179
|
+
svg = svg[0];
|
180
|
+
} else {
|
181
|
+
var svg = this.svg_obj('svg');
|
182
|
+
svg.width = width;
|
183
|
+
svg.height = height;
|
184
|
+
}
|
185
|
+
|
186
|
+
if (pie) {
|
187
|
+
var view_box = '-' + settings.percent_offset + ' -' + settings.percent_offset + ' ' +
|
188
|
+
(width + (settings.percent_offset * 1.5)) + ' ' +
|
189
|
+
(width + (settings.percent_offset * 1.5));
|
190
|
+
} else {
|
191
|
+
var view_box = '-' + settings.percent_offset + ' -' + settings.percent_offset + ' ' +
|
192
|
+
(width + (settings.percent_offset * 1.6)) + ' ' +
|
193
|
+
(height + (settings.percent_offset * 1.6));
|
194
|
+
}
|
195
|
+
|
196
|
+
this.set_attr(svg, {width: '100%', height: '100%', viewBox: view_box});
|
197
|
+
|
198
|
+
return svg;
|
199
|
+
},
|
200
|
+
|
201
|
+
identifier : function (legend) {
|
202
|
+
id = legend.data('pie-id') || legend.data('bar-id') || legend.data('line-id');
|
203
|
+
return '#' + id;
|
204
|
+
},
|
205
|
+
|
206
|
+
throttle : function(fun, delay) {
|
207
|
+
var timer = null;
|
208
|
+
return function () {
|
209
|
+
var context = this, args = arguments;
|
210
|
+
clearTimeout(timer);
|
211
|
+
timer = setTimeout(function () {
|
212
|
+
fun.apply(context, args);
|
213
|
+
}, delay);
|
214
|
+
};
|
215
|
+
},
|
216
|
+
|
217
|
+
svg_obj : function (type) {
|
218
|
+
return document.createElementNS(this.NS, type);
|
219
|
+
},
|
220
|
+
|
221
|
+
ticks: function (min, max, count) {
|
222
|
+
var span = max - min,
|
223
|
+
step = Math.pow(10, Math.floor(Math.log(span / count) / Math.LN10)),
|
224
|
+
err = count / span * step;
|
225
|
+
|
226
|
+
// Filter ticks to get closer to the desired count.
|
227
|
+
if (err <= .15) step *= 10;
|
228
|
+
else if (err <= .35) step *= 5;
|
229
|
+
else if (err <= .75) step *= 2;
|
230
|
+
|
231
|
+
// Round start and stop values to step interval.
|
232
|
+
var tstart = Math.ceil(min / step) * step,
|
233
|
+
tstop = Math.floor(max / step) * step + step * .5,
|
234
|
+
ticks = [],
|
235
|
+
x;
|
236
|
+
|
237
|
+
// now generate ticks
|
238
|
+
for (i=tstart; i < tstop; i += step) {
|
239
|
+
ticks.push(i);
|
240
|
+
}
|
241
|
+
return ticks;
|
242
|
+
},
|
243
|
+
|
244
|
+
set_attr : function (node, attrs) {
|
245
|
+
|
246
|
+
for (attr in attrs) {
|
247
|
+
node.setAttribute(attr, attrs[attr]);
|
248
|
+
}
|
249
|
+
|
250
|
+
return this;
|
251
|
+
},
|
252
|
+
|
253
|
+
flip : function (node, h) {
|
254
|
+
node.setAttribute('transform', 'translate(0, ' + h +') scale(1, -1)');
|
255
|
+
}
|
256
|
+
};
|
@@ -0,0 +1,53 @@
|
|
1
|
+
// Pie Chart Variables
|
2
|
+
$pie-color: #f45c5c !default;
|
3
|
+
|
4
|
+
@mixin darkened-children($num-children, $color) {
|
5
|
+
@for $i from 1 through $num-children {
|
6
|
+
$color: scale-color($color, $lightness: -10%);
|
7
|
+
& > *:nth-child(#{$num-children}n+#{$i}) { // This causes looping to occur after there are $num-children child elements.
|
8
|
+
color: $color;
|
9
|
+
}
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
@mixin lightened-children($num-children, $color) {
|
14
|
+
@for $i from 1 through $num-children {
|
15
|
+
$color: scale-color($color, $lightness: 10%);
|
16
|
+
& > *:nth-child(#{$num-children}n+#{$i}) { // This causes looping to occur after there are $num-children child elements.
|
17
|
+
color: $color;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
[data-pie-id], [data-bar-id], [data-line-id] {
|
23
|
+
@include darkened-children(7, $pie-color);
|
24
|
+
}
|
25
|
+
|
26
|
+
// Set the SVG to 100% width to smooth responsive resizing (optional)
|
27
|
+
#pie, #donut, #bar {
|
28
|
+
max-height: 450px;
|
29
|
+
}
|
30
|
+
|
31
|
+
#bar {
|
32
|
+
// height: 300px;
|
33
|
+
}
|
34
|
+
|
35
|
+
svg {
|
36
|
+
width: 100%;
|
37
|
+
height: auto;
|
38
|
+
}
|
39
|
+
|
40
|
+
.tooltip {
|
41
|
+
margin-left: -5px;
|
42
|
+
border-radius: 3px;
|
43
|
+
padding: 5px;
|
44
|
+
}
|
45
|
+
|
46
|
+
// svg text {
|
47
|
+
// fill: $label-color;
|
48
|
+
// }
|
49
|
+
|
50
|
+
ul[data-pie-id] {
|
51
|
+
list-style: none;
|
52
|
+
padding: 10px;
|
53
|
+
}
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pizza-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eric Roberts
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-04-17 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
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: railties
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: snapsvg-rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.2.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.2.0
|
69
|
+
description: Pizza is a responsive pie, donut, bar, and line graph charting library
|
70
|
+
based on the Snap SVG framework from Adobe. It focuses on easy integration via HTML
|
71
|
+
markup and CSS instead of JavaScript objects, although you can pass JavaScript objects
|
72
|
+
to Pizza as well.
|
73
|
+
email:
|
74
|
+
- ericroberts@gmail.com
|
75
|
+
executables: []
|
76
|
+
extensions: []
|
77
|
+
extra_rdoc_files: []
|
78
|
+
files:
|
79
|
+
- .gitignore
|
80
|
+
- Gemfile
|
81
|
+
- LICENSE.txt
|
82
|
+
- README.md
|
83
|
+
- Rakefile
|
84
|
+
- lib/pizza/rails.rb
|
85
|
+
- lib/pizza/rails/version.rb
|
86
|
+
- pizza-rails.gemspec
|
87
|
+
- vendor/assets/javascripts/pizza.js
|
88
|
+
- vendor/assets/javascripts/pizza/bar.js
|
89
|
+
- vendor/assets/javascripts/pizza/line.js
|
90
|
+
- vendor/assets/javascripts/pizza/pie.js
|
91
|
+
- vendor/assets/javascripts/pizza/pizza.js
|
92
|
+
- vendor/assets/stylesheets/pizza.scss
|
93
|
+
homepage: ''
|
94
|
+
licenses:
|
95
|
+
- MIT
|
96
|
+
metadata: {}
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 2.1.10
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: Rails wrapper for Pizza by Zurb
|
117
|
+
test_files: []
|