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,258 @@
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
+
8
+ (function () {
9
+ var colorValue = function (value, total, s, b) {
10
+ return 'hsb(' + [Math.min((1 - value / total) * .4, 1), s || .75, b || .75] + ')';
11
+ };
12
+
13
+ function Dotchart(paper, x, y, width, height, valuesx, valuesy, size, opts) {
14
+
15
+ function drawAxis(ax) {
16
+ +ax[0] && (ax[0] = chartinst.axis(x + gutter, y + gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 2, opts.axisxlabels || null, opts.axisxtype || "t", null, paper));
17
+ +ax[1] && (ax[1] = chartinst.axis(x + width - gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 3, opts.axisylabels || null, opts.axisytype || "t", null, paper));
18
+ +ax[2] && (ax[2] = chartinst.axis(x + gutter, y + height - gutter + maxR, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 0, opts.axisxlabels || null, opts.axisxtype || "t", null, paper));
19
+ +ax[3] && (ax[3] = chartinst.axis(x + gutter - maxR, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 1, opts.axisylabels || null, opts.axisytype || "t", null, paper));
20
+ }
21
+
22
+ //providing defaults
23
+
24
+ opts = opts || {};
25
+ var chartinst = this;
26
+ var xdim = chartinst.snapEnds(Math.min.apply(Math, valuesx), Math.max.apply(Math, valuesx), valuesx.length - 1),
27
+ minx = xdim.from,
28
+ maxx = xdim.to,
29
+ gutter = opts.gutter || 10,
30
+ ydim = chartinst.snapEnds(Math.min.apply(Math, valuesy), Math.max.apply(Math, valuesy), valuesy.length - 1),
31
+ miny = ydim.from,
32
+ maxy = ydim.to,
33
+ len = Math.max(valuesx.length, valuesy.length, size.length),
34
+ symbol = paper[opts.symbol] || "circle",
35
+ res = paper.set(),
36
+ series = paper.set(),
37
+ max = opts.max || 100,
38
+ top = Math.max.apply(Math, size),
39
+ R = [],
40
+ k = Math.sqrt(top / Math.PI) * 2 / max;
41
+
42
+ for (var i = 0; i < len; i++) {
43
+ R[i] = Math.min(Math.sqrt(size[i] / Math.PI) * 2 / k, max);
44
+ }
45
+
46
+ gutter = Math.max.apply(Math, R.concat(gutter));
47
+
48
+ /*\
49
+ * dotchart.axis
50
+ [ object ]
51
+ **
52
+ * Set containing Elements of the chart axis. Only exists if `'axis'` definition string was passed to @Paper.dotchart
53
+ **
54
+ \*/
55
+ var axis = paper.set(),
56
+ maxR = Math.max.apply(Math, R);
57
+
58
+ if (opts.axis) {
59
+ var ax = (opts.axis + "").split(/[,\s]+/);
60
+
61
+ drawAxis.call(chartinst, ax);
62
+
63
+ var g = [], b = [];
64
+
65
+ for (var i = 0, ii = ax.length; i < ii; i++) {
66
+ var bb = ax[i].all ? ax[i].all.getBBox()[["height", "width"][i % 2]] : 0;
67
+
68
+ g[i] = bb + gutter;
69
+ b[i] = bb;
70
+ }
71
+
72
+ gutter = Math.max.apply(Math, g.concat(gutter));
73
+
74
+ for (var i = 0, ii = ax.length; i < ii; i++) if (ax[i].all) {
75
+ ax[i].remove();
76
+ ax[i] = 1;
77
+ }
78
+
79
+ drawAxis.call(chartinst, ax);
80
+
81
+ for (var i = 0, ii = ax.length; i < ii; i++) if (ax[i].all) {
82
+ axis.push(ax[i].all);
83
+ }
84
+
85
+ res.axis = axis;
86
+ }
87
+
88
+ var kx = (width - gutter * 2) / ((maxx - minx) || 1),
89
+ ky = (height - gutter * 2) / ((maxy - miny) || 1);
90
+
91
+ for (var i = 0, ii = valuesy.length; i < ii; i++) {
92
+ var sym = paper.raphael.is(symbol, "array") ? symbol[i] : symbol,
93
+ X = x + gutter + (valuesx[i] - minx) * kx,
94
+ Y = y + height - gutter - (valuesy[i] - miny) * ky;
95
+
96
+ sym && R[i] && series.push(paper[sym](X, Y, R[i]).attr({ fill: opts.heat ? colorValue(R[i], maxR) : chartinst.colors[0], "fill-opacity": opts.opacity ? R[i] / max : 1, stroke: "none" }));
97
+ }
98
+
99
+ var covers = paper.set();
100
+
101
+ for (var i = 0, ii = valuesy.length; i < ii; i++) {
102
+ var X = x + gutter + (valuesx[i] - minx) * kx,
103
+ Y = y + height - gutter - (valuesy[i] - miny) * ky;
104
+
105
+ covers.push(paper.circle(X, Y, maxR).attr(chartinst.shim));
106
+ opts.href && opts.href[i] && covers[i].attr({href: opts.href[i]});
107
+ covers[i].r = +R[i].toFixed(3);
108
+ covers[i].x = +X.toFixed(3);
109
+ covers[i].y = +Y.toFixed(3);
110
+ covers[i].X = valuesx[i];
111
+ covers[i].Y = valuesy[i];
112
+ covers[i].value = size[i] || 0;
113
+ covers[i].dot = series[i];
114
+ }
115
+
116
+ /*\
117
+ * dotchart.covers
118
+ [ object ]
119
+ **
120
+ * Set of Elements positioned above the symbols and mirroring them in size and shape. Covers are used as a surface for events capturing. Each cover has a property `'dot'` being a reference to the actual data-representing symbol.
121
+ **
122
+ **
123
+ \*/
124
+ res.covers = covers;
125
+ /*\
126
+ * dotchart.series
127
+ [ object ]
128
+ **
129
+ * Set of Elements containing the actual data-representing symbols.
130
+ **
131
+ **
132
+ \*/
133
+ res.series = series;
134
+ res.push(series, axis, covers);
135
+
136
+ /*\
137
+ * dotchart.hover
138
+ [ method ]
139
+ > Parameters
140
+ - mouseover handler (function) handler for the event
141
+ - mouseout handler (function) handler for the event
142
+ * Conveniece method to set up hover-in and hover-out event handlers
143
+ = (object) @dotchart object
144
+ **
145
+ \*/
146
+ res.hover = function (fin, fout) {
147
+ covers.mouseover(fin).mouseout(fout);
148
+ return this;
149
+ };
150
+
151
+ /*\
152
+ * dotchart.click
153
+ [ method ]
154
+ > Parameters
155
+ - click handler (function) handler for the event
156
+ * Conveniece method to set up click event handler
157
+ = (object) @dotchart object
158
+ **
159
+ \*/
160
+ res.click = function (f) {
161
+ covers.click(f);
162
+ return this;
163
+ };
164
+
165
+ /*\
166
+ * dotchart.each
167
+ [ method ]
168
+ > Parameters
169
+ - callback (function) called for every item in @dotchart.covers.
170
+ - this (object) callback is executed in a context of a cover element object
171
+ * Conveniece method iterating on every symbol in the chart
172
+ = (object) @dotchart object
173
+ **
174
+ \*/
175
+ res.each = function (f) {
176
+ if (!paper.raphael.is(f, "function")) {
177
+ return this;
178
+ }
179
+
180
+ for (var i = covers.length; i--;) {
181
+ f.call(covers[i]);
182
+ }
183
+
184
+ return this;
185
+ };
186
+
187
+ /*\
188
+ * dotchart.href
189
+ [ method ]
190
+ > Parameters
191
+ - map (array) Array of objects `{x: 1, y: 20, value: 15, href: "http://www.raphaeljs.com"}`
192
+ * Iterates on all @dotchart.covers elements. If x, y and value on the object are the same as on the cover it sets up a link on a symbol using the passef `href`.
193
+ = (object) @dotchart object
194
+ **
195
+ \*/
196
+ res.href = function (map) {
197
+ var cover;
198
+
199
+ for (var i = covers.length; i--;) {
200
+ cover = covers[i];
201
+
202
+ if (cover.X == map.x && cover.Y == map.y && cover.value == map.value) {
203
+ cover.attr({href: map.href});
204
+ }
205
+ }
206
+ };
207
+ return res;
208
+ };
209
+
210
+ //inheritance
211
+ var F = function() {};
212
+ F.prototype = Raphael.g
213
+ Dotchart.prototype = new F;
214
+
215
+ /*
216
+ * dotchart method on paper
217
+ */
218
+ /*\
219
+ * Paper.dotchart
220
+ [ method ]
221
+ **
222
+ * Plots a dot chart
223
+ **
224
+ > Parameters
225
+ - x (number) x coordinate of the chart
226
+ - y (number) y coordinate of the chart
227
+ - width (number) width of the chart (respected by all elements in the set)
228
+ - height (number) height of the chart (respected by all elements in the set)
229
+ - valuesx (array) values used to plot x asis
230
+ - valuesy (array) values used to plot y asis
231
+ - size (array) values used as data
232
+ - opts (object) options for the chart
233
+ > Possible options
234
+ o {
235
+ o max (number) maximum diameter of a dot [default: 100]
236
+ o symbol (string) symbol used for rendering on the chart. The only possible option is `'circle'` [default]
237
+ o gutter (number) distance between symbols on the chart [default: 10]
238
+ o heat (boolean) whether or not to enable coloring higher value symbols with warmer hue [default: false]
239
+ o opacity (number) opacity of the symbols [default: 1]
240
+ o href (array) array of URLs to set up click-throughs on the symbols
241
+ o axis (string) Which axes should be renedered. String of four values evaluated in order `'top right bottom left'` e.g. `'0 0 1 1'`.
242
+ o axisxstep (number) the number of steps to plot on the axis X
243
+ o axisystep (number) the number of steps to plot on the axis Y
244
+ o axisxlabels (array) labels to be rendered instead of numeric values on axis X
245
+ o axisylabels (array) labels to be rendered instead of numeric values on axis Y
246
+ o axisxtype (string) Possible values: `'t'` [default], `'|'`, `' '`, `'-'`, `'+'`
247
+ o axisytype (string) Possible values: `'t'` [default], `'|'`, `' '`, `'-'`, `'+'`
248
+ o }
249
+ **
250
+ = (object) @dotchart object
251
+ > Usage
252
+ | //life, expectancy, country and spending per capita (fictional data)
253
+ | r.dotchart(0, 0, 620, 260, [76, 70, 67, 71, 69], [0, 1, 2, 3, 4], [100, 120, 140, 160, 500], {max: 10, axisylabels: ['Mexico', 'Argentina', 'Cuba', 'Canada', 'United States of America'], heat: true, axis: '0 0 1 1'})
254
+ \*/
255
+ Raphael.fn.dotchart = function(x, y, width, height, valuesx, valuesy, size, opts) {
256
+ return new Dotchart(this, x, y, width, height, valuesx, valuesy, size, opts);
257
+ }
258
+ })();
@@ -0,0 +1,489 @@
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
+
8
+ (function () {
9
+
10
+ function shrink(values, dim) {
11
+ var k = values.length / dim,
12
+ j = 0,
13
+ l = k,
14
+ sum = 0,
15
+ res = [];
16
+
17
+ while (j < values.length) {
18
+ l--;
19
+
20
+ if (l < 0) {
21
+ sum += values[j] * (1 + l);
22
+ res.push(sum / k);
23
+ sum = values[j++] * -l;
24
+ l += k;
25
+ } else {
26
+ sum += values[j++] * 1;
27
+ }
28
+ }
29
+ return res;
30
+ }
31
+
32
+ function getAnchors(p1x, p1y, p2x, p2y, p3x, p3y) {
33
+ var l1 = (p2x - p1x) / 2,
34
+ l2 = (p3x - p2x) / 2,
35
+ a = Math.atan((p2x - p1x) / Math.abs(p2y - p1y)),
36
+ b = Math.atan((p3x - p2x) / Math.abs(p2y - p3y));
37
+
38
+ a = p1y < p2y ? Math.PI - a : a;
39
+ b = p3y < p2y ? Math.PI - b : b;
40
+
41
+ var alpha = Math.PI / 2 - ((a + b) % (Math.PI * 2)) / 2,
42
+ dx1 = l1 * Math.sin(alpha + a),
43
+ dy1 = l1 * Math.cos(alpha + a),
44
+ dx2 = l2 * Math.sin(alpha + b),
45
+ dy2 = l2 * Math.cos(alpha + b);
46
+
47
+ return {
48
+ x1: p2x - dx1,
49
+ y1: p2y + dy1,
50
+ x2: p2x + dx2,
51
+ y2: p2y + dy2
52
+ };
53
+ }
54
+
55
+ function Linechart(paper, x, y, width, height, valuesx, valuesy, opts) {
56
+
57
+ var chartinst = this;
58
+
59
+ opts = opts || {};
60
+
61
+ if (!paper.raphael.is(valuesx[0], "array")) {
62
+ valuesx = [valuesx];
63
+ }
64
+
65
+ if (!paper.raphael.is(valuesy[0], "array")) {
66
+ valuesy = [valuesy];
67
+ }
68
+
69
+ var gutter = opts.gutter || 10,
70
+ len = Math.max(valuesx[0].length, valuesy[0].length),
71
+ symbol = opts.symbol || "",
72
+ colors = opts.colors || chartinst.colors,
73
+ columns = null,
74
+ dots = null,
75
+ chart = paper.set(),
76
+ path = [];
77
+
78
+ for (var i = 0, ii = valuesy.length; i < ii; i++) {
79
+ len = Math.max(len, valuesy[i].length);
80
+ }
81
+
82
+ /*\
83
+ * linechart.shades
84
+ [ object ]
85
+ **
86
+ * Set containing Elements corresponding to shades plotted in the chart (if `opts.shade` was `true`).
87
+ **
88
+ **
89
+ \*/
90
+ var shades = paper.set();
91
+
92
+ for (i = 0, ii = valuesy.length; i < ii; i++) {
93
+ if (opts.shade) {
94
+ shades.push(paper.path().attr({ stroke: "none", fill: colors[i], opacity: opts.nostroke ? 1 : .3 }));
95
+ }
96
+
97
+ if (valuesy[i].length > width - 2 * gutter) {
98
+ valuesy[i] = shrink(valuesy[i], width - 2 * gutter);
99
+ len = width - 2 * gutter;
100
+ }
101
+
102
+ if (valuesx[i] && valuesx[i].length > width - 2 * gutter) {
103
+ valuesx[i] = shrink(valuesx[i], width - 2 * gutter);
104
+ }
105
+ }
106
+
107
+ var allx = Array.prototype.concat.apply([], valuesx),
108
+ ally = Array.prototype.concat.apply([], valuesy),
109
+ xdim = chartinst.snapEnds(Math.min.apply(Math, allx), Math.max.apply(Math, allx), valuesx[0].length - 1),
110
+ minx = xdim.from,
111
+ maxx = xdim.to,
112
+ ydim = chartinst.snapEnds(Math.min.apply(Math, ally), Math.max.apply(Math, ally), valuesy[0].length - 1),
113
+ miny = ydim.from,
114
+ maxy = ydim.to,
115
+ kx = (width - gutter * 2) / ((maxx - minx) || 1),
116
+ ky = (height - gutter * 2) / ((maxy - miny) || 1);
117
+
118
+ /*\
119
+ * linechart.axis
120
+ [ object ]
121
+ **
122
+ * Set containing Elements of the chart axis. The set is populated if `'axis'` definition string was passed to @Paper.linechart
123
+ **
124
+ **
125
+ \*/
126
+ var axis = paper.set();
127
+
128
+ if (opts.axis) {
129
+ var ax = (opts.axis + "").split(/[,\s]+/);
130
+ +ax[0] && axis.push(chartinst.axis(x + gutter, y + gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 2, paper));
131
+ +ax[1] && axis.push(chartinst.axis(x + width - gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 3, paper));
132
+ +ax[2] && axis.push(chartinst.axis(x + gutter, y + height - gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 0, paper));
133
+ +ax[3] && axis.push(chartinst.axis(x + gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 1, paper));
134
+ }
135
+
136
+ /*\
137
+ * linechart.lines
138
+ [ object ]
139
+ **
140
+ * Set containing Elements corresponding to lines plotted in the chart.
141
+ **
142
+ **
143
+ \*/
144
+ var lines = paper.set(),
145
+ /*\
146
+ * linechart.symbols
147
+ [ object ]
148
+ **
149
+ * Set containing Elements corresponding to symbols plotted in the chart.
150
+ **
151
+ **
152
+ \*/
153
+ symbols = paper.set(),
154
+ line;
155
+
156
+ for (i = 0, ii = valuesy.length; i < ii; i++) {
157
+ if (!opts.nostroke) {
158
+ lines.push(line = paper.path().attr({
159
+ stroke: colors[i],
160
+ "stroke-width": opts.width || 2,
161
+ "stroke-linejoin": "round",
162
+ "stroke-linecap": "round",
163
+ "stroke-dasharray": opts.dash || ""
164
+ }));
165
+ }
166
+
167
+ var sym = Raphael.is(symbol, "array") ? symbol[i] : symbol,
168
+ symset = paper.set();
169
+
170
+ path = [];
171
+
172
+ for (var j = 0, jj = valuesy[i].length; j < jj; j++) {
173
+ var X = x + gutter + ((valuesx[i] || valuesx[0])[j] - minx) * kx,
174
+ Y = y + height - gutter - (valuesy[i][j] - miny) * ky;
175
+
176
+ (Raphael.is(sym, "array") ? sym[j] : sym) && symset.push(paper[Raphael.is(sym, "array") ? sym[j] : sym](X, Y, (opts.width || 2) * 3).attr({ fill: colors[i], stroke: "none" }));
177
+
178
+ if (opts.smooth) {
179
+ if (j && j != jj - 1) {
180
+ var X0 = x + gutter + ((valuesx[i] || valuesx[0])[j - 1] - minx) * kx,
181
+ Y0 = y + height - gutter - (valuesy[i][j - 1] - miny) * ky,
182
+ X2 = x + gutter + ((valuesx[i] || valuesx[0])[j + 1] - minx) * kx,
183
+ Y2 = y + height - gutter - (valuesy[i][j + 1] - miny) * ky,
184
+ a = getAnchors(X0, Y0, X, Y, X2, Y2);
185
+
186
+ path = path.concat([a.x1, a.y1, X, Y, a.x2, a.y2]);
187
+ }
188
+
189
+ if (!j) {
190
+ path = ["M", X, Y, "C", X, Y];
191
+ }
192
+ } else {
193
+ path = path.concat([j ? "L" : "M", X, Y]);
194
+ }
195
+ }
196
+
197
+ if (opts.smooth) {
198
+ path = path.concat([X, Y, X, Y]);
199
+ }
200
+
201
+ symbols.push(symset);
202
+
203
+ if (opts.shade) {
204
+ shades[i].attr({ path: path.concat(["L", X, y + height - gutter, "L", x + gutter + ((valuesx[i] || valuesx[0])[0] - minx) * kx, y + height - gutter, "z"]).join(",") });
205
+ }
206
+
207
+ !opts.nostroke && line.attr({ path: path.join(",") });
208
+ }
209
+
210
+ function createColumns(f) {
211
+ // unite Xs together
212
+ var Xs = [];
213
+
214
+ for (var i = 0, ii = valuesx.length; i < ii; i++) {
215
+ Xs = Xs.concat(valuesx[i]);
216
+ }
217
+
218
+ Xs.sort(function(a,b) { return a - b; });
219
+ // remove duplicates
220
+
221
+ var Xs2 = [],
222
+ xs = [];
223
+
224
+ for (i = 0, ii = Xs.length; i < ii; i++) {
225
+ Xs[i] != Xs[i - 1] && Xs2.push(Xs[i]) && xs.push(x + gutter + (Xs[i] - minx) * kx);
226
+ }
227
+
228
+ Xs = Xs2;
229
+ ii = Xs.length;
230
+
231
+ var cvrs = f || paper.set();
232
+
233
+ for (i = 0; i < ii; i++) {
234
+ var X = xs[i] - (xs[i] - (xs[i - 1] || x)) / 2,
235
+ w = ((xs[i + 1] || x + width) - xs[i]) / 2 + (xs[i] - (xs[i - 1] || x)) / 2,
236
+ C;
237
+
238
+ f ? (C = {}) : cvrs.push(C = paper.rect(X - 1, y, Math.max(w + 1, 1), height).attr({ stroke: "none", fill: "#000", opacity: 0 }));
239
+ C.values = [];
240
+ C.symbols = paper.set();
241
+ C.y = [];
242
+ C.x = xs[i];
243
+ C.axis = Xs[i];
244
+
245
+ for (var j = 0, jj = valuesy.length; j < jj; j++) {
246
+ Xs2 = valuesx[j] || valuesx[0];
247
+
248
+ for (var k = 0, kk = Xs2.length; k < kk; k++) {
249
+ if (Xs2[k] == Xs[i]) {
250
+ C.values.push(valuesy[j][k]);
251
+ C.y.push(y + height - gutter - (valuesy[j][k] - miny) * ky);
252
+ C.symbols.push(chart.symbols[j][k]);
253
+ }
254
+ }
255
+ }
256
+
257
+ f && f.call(C);
258
+ }
259
+
260
+ !f && (columns = cvrs);
261
+ }
262
+
263
+ function createDots(f) {
264
+ var cvrs = f || paper.set(),
265
+ C;
266
+
267
+ for (var i = 0, ii = valuesy.length; i < ii; i++) {
268
+ for (var j = 0, jj = valuesy[i].length; j < jj; j++) {
269
+ var X = x + gutter + ((valuesx[i] || valuesx[0])[j] - minx) * kx,
270
+ nearX = x + gutter + ((valuesx[i] || valuesx[0])[j ? j - 1 : 1] - minx) * kx,
271
+ Y = y + height - gutter - (valuesy[i][j] - miny) * ky;
272
+ f ? (C = {}) : cvrs.push(C = paper.circle(X, Y, Math.abs(nearX - X) / 2).attr({ stroke: "#000", fill: "#000", opacity: 1 }));
273
+ C.x = X;
274
+ C.y = Y;
275
+ C.value = valuesy[i][j];
276
+ C.line = chart.lines[i];
277
+ C.shade = chart.shades[i];
278
+ C.symbol = chart.symbols[i][j];
279
+ C.symbols = chart.symbols[i];
280
+ C.axis = (valuesx[i] || valuesx[0])[j];
281
+ f && f.call(C);
282
+ }
283
+ }
284
+
285
+ !f && (dots = cvrs);
286
+ }
287
+
288
+ chart.push(lines, shades, symbols, axis, columns, dots);
289
+ chart.lines = lines;
290
+ chart.shades = shades;
291
+ chart.symbols = symbols;
292
+ chart.axis = axis;
293
+
294
+ /*\
295
+ * linechart.hoverColumn
296
+ [ method ]
297
+ > Parameters
298
+ - mouseover handler (function) handler for the event
299
+ - mouseout handler (function) handler for the event
300
+ - this (object) callback is executed in a context of a cover element
301
+ * Conveniece method to set up hover-in and hover-out event handlers on the entire area of the chart.
302
+ * The handlers are passed a event object containing
303
+ o {
304
+ o x (number) x coordinate on all lines in the chart
305
+ o y (array) y coordinates of all lines corresponding to the x
306
+ o }
307
+ = (object) @linechart object
308
+ **
309
+ \*/
310
+
311
+ chart.hoverColumn = function (fin, fout) {
312
+ !columns && createColumns();
313
+ columns.mouseover(fin).mouseout(fout);
314
+ return this;
315
+ };
316
+
317
+ /*\
318
+ * linechart.clickColumn
319
+ [ method ]
320
+ > Parameters
321
+ - click handler (function) handler for the event
322
+ - this (object) callback is executed in a context of a cover element
323
+ * Conveniece method to set up click event handler on the antire area of the chart.
324
+ * The handler is passed a event object containing
325
+ o {
326
+ o x (number) x coordinate on all lines in the chart
327
+ o y (array) y coordinates of all lines corresponding to the x
328
+ o }
329
+ = (object) @linechart object
330
+ **
331
+ \*/
332
+ chart.clickColumn = function (f) {
333
+ !columns && createColumns();
334
+ columns.click(f);
335
+ return this;
336
+ };
337
+
338
+ /*\
339
+ * linechart.hrefColumn
340
+ [ method ]
341
+ > Parameters
342
+ - cols (object) object containing values as keys and URLs as values, e.g. {1: 'http://www.raphaeljs.com', 2: 'http://g.raphaeljs.com'}
343
+ * Creates click-throughs on the whole area of the chart corresponding to x values
344
+ = (object) @linechart object
345
+ **
346
+ \*/
347
+ chart.hrefColumn = function (cols) {
348
+ var hrefs = paper.raphael.is(arguments[0], "array") ? arguments[0] : arguments;
349
+
350
+ if (!(arguments.length - 1) && typeof cols == "object") {
351
+ for (var x in cols) {
352
+ for (var i = 0, ii = columns.length; i < ii; i++) if (columns[i].axis == x) {
353
+ columns[i].attr("href", cols[x]);
354
+ }
355
+ }
356
+ }
357
+
358
+ !columns && createColumns();
359
+
360
+ for (i = 0, ii = hrefs.length; i < ii; i++) {
361
+ columns[i] && columns[i].attr("href", hrefs[i]);
362
+ }
363
+
364
+ return this;
365
+ };
366
+
367
+ /*\
368
+ * linechart.hover
369
+ [ method ]
370
+ > Parameters
371
+ - mouseover handler (function) handler for the event
372
+ - mouseout handler (function) handler for the event
373
+ * Conveniece method to set up hover-in and hover-out event handlers working on the lines of the chart.
374
+ * Use @linechart.hoverColumn to work with the entire chart area.
375
+ = (object) @linechart object
376
+ **
377
+ \*/
378
+ chart.hover = function (fin, fout) {
379
+ !dots && createDots();
380
+ dots.mouseover(fin).mouseout(fout);
381
+ return this;
382
+ };
383
+
384
+ /*\
385
+ * linechart.click
386
+ [ method ]
387
+ > Parameters
388
+ - click handler (function) handler for the event
389
+ - this (object) callback is executed in a context of a cover element
390
+ * Conveniece method to set up click event handler on the lines of the chart
391
+ * Use @linechart.clickColumn to work with the entire chart area.
392
+ = (object) @linechart object
393
+ **
394
+ \*/
395
+ chart.click = function (f) {
396
+ !dots && createDots();
397
+ dots.click(f);
398
+ return this;
399
+ };
400
+
401
+ /*\
402
+ * linechart.each
403
+ [ method ]
404
+ > Parameters
405
+ - callback (function) function executed for every data point
406
+ - this (object) context of the callback function.
407
+ o {
408
+ o x (number) x coordinate of the data point
409
+ o y (number) y coordinate of the data point
410
+ o value (number) value represented by the data point
411
+ o }
412
+ * Iterates over each unique data point plotted on every line on the chart.
413
+ = (object) @linechart object
414
+ **
415
+ \*/
416
+ chart.each = function (f) {
417
+ createDots(f);
418
+ return this;
419
+ };
420
+
421
+ /*\
422
+ * linechart.eachColumn
423
+ [ method ]
424
+ > Parameters
425
+ - callback (function) function executed for every column
426
+ - this (object) context of the callback function.
427
+ o {
428
+ o x (number) x coordinate of the data point
429
+ o y (array) y coordinates of data points existing for the given x
430
+ o values (array) values represented by the data points existing for the given x
431
+ o }
432
+ * Iterates over each column area (area plotted above the chart).
433
+ = (object) @linechart object
434
+ **
435
+ \*/
436
+ chart.eachColumn = function (f) {
437
+ createColumns(f);
438
+ return this;
439
+ };
440
+
441
+ return chart;
442
+ };
443
+
444
+ //inheritance
445
+ var F = function() {};
446
+ F.prototype = Raphael.g;
447
+ Linechart.prototype = new F;
448
+
449
+ /*
450
+ * linechart method on paper
451
+ */
452
+ /*\
453
+ * Paper.linechart
454
+ [ method ]
455
+ **
456
+ * Creates a line chart
457
+ **
458
+ > Parameters
459
+ **
460
+ - x (number) x coordinate of the chart
461
+ - y (number) y coordinate of the chart
462
+ - width (number) width of the chart (including the axis)
463
+ - height (number) height of the chart (including the axis)
464
+ - valuesx (array) values to plot on axis x
465
+ - valuesy (array) values to plot on axis y
466
+ - opts (object) options for the chart
467
+ o {
468
+ o gutter (number) distance between symbols on the chart
469
+ o symbol (string) (array) symbol to be plotted as nodes of the chart, if array are passed symbols are printed iteratively. Currently `'circle'` and `''` (no symbol) are the only supported options.
470
+ o width (number) controls the size of the plotted symbol. Also controls the thickness of the line using a formula stroke-width=width/2. This option is likely to change in the future versions of g.raphael.
471
+ o colors (array) colors to plot data series. Raphael default colors are used if not passed
472
+ o shade (boolean) whether or not to plot a shade of the chart [default: false]. Currently only a shade between the line and x axis is supported.
473
+ o nostroke (boolean) whether or not to plot lines [default: false]. Only practical when shade is enabled.
474
+ o dash (string) changes display of the line from continues to dashed or dotted (Possible values are the same as stroke-dasharray attribute, see @Element.attr).
475
+ o smooth (boolean) changes display of the line from point-to-point straight lines to curves (type C, see @Paper.path).
476
+ o axis (string) Which axes should be renedered. String of four values evaluated in order `'top right bottom left'` e.g. `'0 0 1 1'`.
477
+ o axisxstep (number) distance between values on axis X
478
+ o axisystep (number) distance between values on axis Y
479
+ o }
480
+ **
481
+ = (object) path element of the popup
482
+ > Usage
483
+ | r.linechart(0, 0, 99, 99, [1,2,3,4,5], [[1,2,3,4,5], [1,3,9,16,25], [100,50,25,12,6]], {smooth: true, colors: ['#F00', '#0F0', '#FF0'], symbol: 'circle'});
484
+ \*/
485
+ Raphael.fn.linechart = function(x, y, width, height, valuesx, valuesy, opts) {
486
+ return new Linechart(this, x, y, width, height, valuesx, valuesy, opts);
487
+ }
488
+
489
+ })();