g.raphael-rails 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+ })();