rgraph-rails 1.0.7 → 1.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/lib/rgraph-rails/version.rb +1 -1
- data/license.txt +4 -16
- data/vendor/assets/javascripts/RGraph.bar.js +3734 -241
- data/vendor/assets/javascripts/RGraph.bipolar.js +2005 -115
- data/vendor/assets/javascripts/RGraph.common.annotate.js +395 -35
- data/vendor/assets/javascripts/RGraph.common.context.js +595 -30
- data/vendor/assets/javascripts/RGraph.common.core.js +5282 -405
- data/vendor/assets/javascripts/RGraph.common.csv.js +276 -19
- data/vendor/assets/javascripts/RGraph.common.deprecated.js +450 -35
- data/vendor/assets/javascripts/RGraph.common.dynamic.js +1395 -86
- data/vendor/assets/javascripts/RGraph.common.effects.js +1545 -90
- data/vendor/assets/javascripts/RGraph.common.key.js +753 -54
- data/vendor/assets/javascripts/RGraph.common.resizing.js +563 -37
- data/vendor/assets/javascripts/RGraph.common.sheets.js +352 -29
- data/vendor/assets/javascripts/RGraph.common.tooltips.js +450 -32
- data/vendor/assets/javascripts/RGraph.common.zoom.js +219 -14
- data/vendor/assets/javascripts/RGraph.drawing.background.js +570 -35
- data/vendor/assets/javascripts/RGraph.drawing.circle.js +544 -35
- data/vendor/assets/javascripts/RGraph.drawing.image.js +755 -52
- data/vendor/assets/javascripts/RGraph.drawing.marker1.js +645 -41
- data/vendor/assets/javascripts/RGraph.drawing.marker2.js +633 -37
- data/vendor/assets/javascripts/RGraph.drawing.marker3.js +514 -36
- data/vendor/assets/javascripts/RGraph.drawing.poly.js +559 -39
- data/vendor/assets/javascripts/RGraph.drawing.rect.js +548 -35
- data/vendor/assets/javascripts/RGraph.drawing.text.js +664 -36
- data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +812 -50
- data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +856 -51
- data/vendor/assets/javascripts/RGraph.fuel.js +964 -58
- data/vendor/assets/javascripts/RGraph.funnel.js +984 -55
- data/vendor/assets/javascripts/RGraph.gantt.js +1354 -77
- data/vendor/assets/javascripts/RGraph.gauge.js +1421 -87
- data/vendor/assets/javascripts/RGraph.hbar.js +2562 -146
- data/vendor/assets/javascripts/RGraph.hprogress.js +1401 -80
- data/vendor/assets/javascripts/RGraph.line.js +4226 -244
- data/vendor/assets/javascripts/RGraph.meter.js +1280 -74
- data/vendor/assets/javascripts/RGraph.modaldialog.js +301 -19
- data/vendor/assets/javascripts/RGraph.odo.js +1264 -71
- data/vendor/assets/javascripts/RGraph.pie.js +2288 -137
- data/vendor/assets/javascripts/RGraph.radar.js +1847 -110
- data/vendor/assets/javascripts/RGraph.rose.js +1977 -108
- data/vendor/assets/javascripts/RGraph.rscatter.js +1432 -80
- data/vendor/assets/javascripts/RGraph.scatter.js +3036 -168
- data/vendor/assets/javascripts/RGraph.semicircularprogress.js +1120 -60
- data/vendor/assets/javascripts/RGraph.svg.bar.js +1067 -0
- data/vendor/assets/javascripts/RGraph.svg.common.ajax.js +247 -0
- data/vendor/assets/javascripts/RGraph.svg.common.core.js +3363 -0
- data/vendor/assets/javascripts/RGraph.svg.common.csv.js +277 -0
- data/vendor/assets/javascripts/RGraph.svg.common.fx.js +1304 -0
- data/vendor/assets/javascripts/RGraph.svg.common.sheets.js +353 -0
- data/vendor/assets/javascripts/RGraph.svg.common.tooltips.js +233 -0
- data/vendor/assets/javascripts/RGraph.svg.hbar.js +1141 -0
- data/vendor/assets/javascripts/RGraph.svg.line.js +1486 -0
- data/vendor/assets/javascripts/RGraph.svg.pie.js +781 -0
- data/vendor/assets/javascripts/RGraph.svg.radar.js +1326 -0
- data/vendor/assets/javascripts/RGraph.svg.semicircularprogress.js +817 -0
- data/vendor/assets/javascripts/RGraph.thermometer.js +1135 -62
- data/vendor/assets/javascripts/RGraph.vprogress.js +1470 -83
- data/vendor/assets/javascripts/RGraph.waterfall.js +1347 -80
- metadata +15 -3
@@ -1,55 +1,754 @@
|
|
1
|
+
// version: 2017-01-02
|
2
|
+
/**
|
3
|
+
* o--------------------------------------------------------------------------------o
|
4
|
+
* | This file is part of the RGraph package - you can learn more at: |
|
5
|
+
* | |
|
6
|
+
* | http://www.rgraph.net |
|
7
|
+
* | |
|
8
|
+
* | RGraph is licensed under the Open Source MIT license. That means that it's |
|
9
|
+
* | totally free to use! |
|
10
|
+
* o--------------------------------------------------------------------------------o
|
11
|
+
*/
|
1
12
|
|
2
|
-
RGraph=window.RGraph||{isRGraph:true};
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
13
|
+
RGraph = window.RGraph || {isRGraph: true};
|
14
|
+
RGraph.HTML = RGraph.HTML || {};
|
15
|
+
|
16
|
+
// Module pattern
|
17
|
+
(function (win, doc, undefined)
|
18
|
+
{
|
19
|
+
var RG = RGraph,
|
20
|
+
ua = navigator.userAgent,
|
21
|
+
ma = Math;
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
/**
|
27
|
+
* Draws the graph key (used by various graphs)
|
28
|
+
*
|
29
|
+
* @param object obj The graph object
|
30
|
+
* @param array key An array of the texts to be listed in the key
|
31
|
+
* @param colors An array of the colors to be used
|
32
|
+
*/
|
33
|
+
RG.drawKey =
|
34
|
+
RG.DrawKey = function (obj, key, colors)
|
35
|
+
{
|
36
|
+
if (!key) {
|
37
|
+
return;
|
38
|
+
}
|
39
|
+
|
40
|
+
var ca = obj.canvas,
|
41
|
+
co = obj.context,
|
42
|
+
prop = obj.properties,
|
43
|
+
|
44
|
+
// Key positioned in the gutter
|
45
|
+
keypos = prop['chart.key.position'],
|
46
|
+
textsize = prop['chart.text.size'],
|
47
|
+
key_non_null = [],
|
48
|
+
colors_non_null = [];
|
49
|
+
|
50
|
+
co.lineWidth = 1;
|
51
|
+
|
52
|
+
co.beginPath();
|
53
|
+
|
54
|
+
/**
|
55
|
+
* Change the older chart.key.vpos to chart.key.position.y
|
56
|
+
*/
|
57
|
+
if (typeof(prop['chart.key.vpos']) == 'number') {
|
58
|
+
obj.Set('chart.key.position.y', prop['chart.key.vpos'] * prop['chart.gutter.top']);
|
59
|
+
}
|
60
|
+
|
61
|
+
/**
|
62
|
+
* Account for null values in the key
|
63
|
+
*/
|
64
|
+
for (var i=0; i<key.length; ++i) {
|
65
|
+
if (key[i] != null) {
|
66
|
+
colors_non_null.push(colors[i]);
|
67
|
+
key_non_null.push(key[i]);
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
key = key_non_null;
|
72
|
+
colors = colors_non_null;
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
/**
|
101
|
+
* This does the actual drawing of the key when it's in the graph
|
102
|
+
*
|
103
|
+
* @param object obj The graph object
|
104
|
+
* @param array key The key items to draw
|
105
|
+
* @param array colors An aray of colors that the key will use
|
106
|
+
*/
|
107
|
+
function DrawKey_graph (obj, key, colors)
|
108
|
+
{
|
109
|
+
var text_size = typeof(prop['chart.key.text.size']) == 'number' ? prop['chart.key.text.size'] : prop['chart.text.size'];
|
110
|
+
var text_italic = prop['chart.key.text.italic'] ? true : false
|
111
|
+
var text_bold = prop['chart.key.text.bold'] ? true : false
|
112
|
+
var text_font = prop['chart.key.text.font'] || prop['chart.key.font'] || prop['chart.text.font'];
|
113
|
+
|
114
|
+
var gutterLeft = obj.gutterLeft;
|
115
|
+
var gutterRight = obj.gutterRight;
|
116
|
+
var gutterTop = obj.gutterTop;
|
117
|
+
var gutterBottom = obj.gutterBottom;
|
118
|
+
var hpos = prop['chart.yaxispos'] == 'right' ? gutterLeft + 10 : ca.width - gutterRight - 10;
|
119
|
+
var vpos = gutterTop + 10;
|
120
|
+
var title = prop['chart.title'];
|
121
|
+
var blob_size = text_size; // The blob of color
|
122
|
+
var hmargin = 8; // This is the size of the gaps between the blob of color and the text
|
123
|
+
var vmargin = 4; // This is the vertical margin of the key
|
124
|
+
var fillstyle = prop['chart.key.background'];
|
125
|
+
var text_color = prop['chart.key.text.color'];
|
126
|
+
var strokestyle = '#333';
|
127
|
+
var height = 0;
|
128
|
+
var width = 0;
|
129
|
+
|
130
|
+
if (!obj.coords) obj.coords = {};
|
131
|
+
obj.coords.key = [];
|
132
|
+
|
133
|
+
|
134
|
+
// Need to set this so that measuring the text works out OK
|
135
|
+
co.font = text_size + 'pt ' + prop['chart.text.font'];
|
136
|
+
|
137
|
+
// Work out the longest bit of text
|
138
|
+
for (i=0; i<key.length; ++i) {
|
139
|
+
width = Math.max(width, co.measureText(key[i]).width);
|
140
|
+
}
|
141
|
+
|
142
|
+
width += 5;
|
143
|
+
width += blob_size;
|
144
|
+
width += 5;
|
145
|
+
width += 5;
|
146
|
+
width += 5;
|
147
|
+
|
148
|
+
/**
|
149
|
+
* Now we know the width, we can move the key left more accurately
|
150
|
+
*/
|
151
|
+
if ( prop['chart.yaxispos'] == 'left'
|
152
|
+
|| (obj.type === 'pie' && !prop['chart.yaxispos'])
|
153
|
+
|| (obj.type === 'hbar' && !prop['chart.yaxispos'])
|
154
|
+
|| (obj.type === 'hbar' && prop['chart.yaxispos'] === 'center')
|
155
|
+
|| (obj.type === 'hbar' && prop['chart.yaxispos'] === 'right')
|
156
|
+
|| (obj.type === 'rscatter' && !prop['chart.yaxispos'])
|
157
|
+
|| (obj.type === 'radar' && !prop['chart.yaxispos'])
|
158
|
+
|| (obj.type === 'rose' && !prop['chart.yaxispos'])
|
159
|
+
|| (obj.type === 'funnel' && !prop['chart.yaxispos'])
|
160
|
+
|| (obj.type === 'vprogress' && !prop['chart.yaxispos'])
|
161
|
+
|| (obj.type === 'hprogress' && !prop['chart.yaxispos'])
|
162
|
+
) {
|
163
|
+
|
164
|
+
hpos -= width;
|
165
|
+
}
|
166
|
+
|
167
|
+
/**
|
168
|
+
* Horizontal alignment
|
169
|
+
*/
|
170
|
+
if (typeof(prop['chart.key.halign']) == 'string') {
|
171
|
+
if (prop['chart.key.halign'] == 'left') {
|
172
|
+
hpos = gutterLeft + 10;
|
173
|
+
} else if (prop['chart.key.halign'] == 'right') {
|
174
|
+
hpos = ca.width - gutterRight - width;
|
175
|
+
}
|
176
|
+
}
|
177
|
+
|
178
|
+
/**
|
179
|
+
* Specific location coordinates
|
180
|
+
*/
|
181
|
+
if (typeof(prop['chart.key.position.x']) == 'number') {
|
182
|
+
hpos = prop['chart.key.position.x'];
|
183
|
+
}
|
184
|
+
|
185
|
+
if (typeof(prop['chart.key.position.y']) == 'number') {
|
186
|
+
vpos = prop['chart.key.position.y'];
|
187
|
+
}
|
188
|
+
|
189
|
+
|
190
|
+
// Stipulate the shadow for the key box
|
191
|
+
if (prop['chart.key.shadow']) {
|
192
|
+
co.shadowColor = prop['chart.key.shadow.color'];
|
193
|
+
co.shadowBlur = prop['chart.key.shadow.blur'];
|
194
|
+
co.shadowOffsetX = prop['chart.key.shadow.offsetx'];
|
195
|
+
co.shadowOffsetY = prop['chart.key.shadow.offsety'];
|
196
|
+
}
|
197
|
+
|
198
|
+
|
199
|
+
|
200
|
+
|
201
|
+
// Draw the box that the key resides in
|
202
|
+
co.beginPath();
|
203
|
+
co.fillStyle = prop['chart.key.background'];
|
204
|
+
co.strokeStyle = 'black';
|
205
|
+
|
206
|
+
if (typeof(prop['chart.key.position.graph.boxed']) == 'undefined' || (typeof(prop['chart.key.position.graph.boxed']) == 'boolean' && prop['chart.key.position.graph.boxed']) ) {
|
207
|
+
if (arguments[3] != false) {
|
208
|
+
|
209
|
+
co.lineWidth = typeof(prop['chart.key.linewidth']) == 'number' ? prop['chart.key.linewidth'] : 1;
|
210
|
+
|
211
|
+
// The older square rectangled key
|
212
|
+
if (prop['chart.key.rounded'] == true) {
|
213
|
+
co.beginPath();
|
214
|
+
co.strokeStyle = strokestyle;
|
215
|
+
RG.strokedCurvyRect(co, Math.round(hpos), Math.round(vpos), width - 5, 5 + ( (text_size + 5) * RG.getKeyLength(key)),4);
|
216
|
+
co.stroke();
|
217
|
+
co.fill();
|
218
|
+
|
219
|
+
RG.NoShadow(obj);
|
220
|
+
|
221
|
+
} else {
|
222
|
+
co.strokeRect(Math.round(hpos), Math.round(vpos), width - 5, 5 + ( (text_size + 5) * RG.getKeyLength(key)));
|
223
|
+
co.fillRect(Math.round(hpos), Math.round(vpos), width - 5, 5 + ( (text_size + 5) * RG.getKeyLength(key)));
|
224
|
+
}
|
225
|
+
}
|
226
|
+
}
|
227
|
+
|
228
|
+
RG.NoShadow(obj);
|
229
|
+
|
230
|
+
co.beginPath();
|
231
|
+
|
232
|
+
/**
|
233
|
+
* Custom colors for the key
|
234
|
+
*/
|
235
|
+
if (prop['chart.key.colors']) {
|
236
|
+
colors = prop['chart.key.colors'];
|
237
|
+
}
|
238
|
+
|
239
|
+
|
240
|
+
|
241
|
+
////////////////////////////////////////////////////////////////////////////////////////////
|
242
|
+
|
243
|
+
|
244
|
+
|
245
|
+
// Draw the labels given
|
246
|
+
for (var i=key.length - 1; i>=0; i--) {
|
247
|
+
|
248
|
+
var j = Number(i) + 1;
|
249
|
+
|
250
|
+
/**
|
251
|
+
* Draw the blob of color
|
252
|
+
*/
|
253
|
+
if (typeof(prop['chart.key.color.shape']) == 'object' && typeof(prop['chart.key.color.shape'][i]) == 'string') {
|
254
|
+
var blob_shape = prop['chart.key.color.shape'][i];
|
255
|
+
|
256
|
+
} else if (typeof(prop['chart.key.color.shape']) == 'string') {
|
257
|
+
var blob_shape = prop['chart.key.color.shape'];
|
258
|
+
} else {
|
259
|
+
var blob_shape = 'square';
|
260
|
+
}
|
261
|
+
|
262
|
+
if (blob_shape == 'circle') {
|
263
|
+
co.beginPath();
|
264
|
+
co.fillStyle = colors[i];
|
265
|
+
co.arc(hpos + 5 + (blob_size / 2), vpos + (5 * j) + (text_size * j) - text_size + (blob_size / 2), blob_size / 2, 0, 6.26, 0);
|
266
|
+
co.fill();
|
267
|
+
|
268
|
+
} else if (blob_shape == 'line') {
|
269
|
+
co.beginPath();
|
270
|
+
co.strokeStyle = colors[i];
|
271
|
+
co.moveTo(hpos + 5, vpos + (5 * j) + (text_size * j) - text_size + (blob_size / 2));
|
272
|
+
co.lineTo(hpos + blob_size + 5, vpos + (5 * j) + (text_size * j) - text_size + (blob_size / 2));
|
273
|
+
co.stroke();
|
274
|
+
|
275
|
+
} else if (blob_shape == 'triangle') {
|
276
|
+
co.beginPath();
|
277
|
+
co.strokeStyle = colors[i];
|
278
|
+
co.moveTo(hpos + 5, vpos + (5 * j) + (text_size * j) - text_size + blob_size);
|
279
|
+
co.lineTo(hpos + (blob_size / 2) + 5, vpos + (5 * j) + (text_size * j) - text_size );
|
280
|
+
co.lineTo(hpos + blob_size + 5, vpos + (5 * j) + (text_size * j) - text_size + blob_size);
|
281
|
+
co.closePath();
|
282
|
+
co.fillStyle = colors[i];
|
283
|
+
co.fill();
|
284
|
+
|
285
|
+
} else {
|
286
|
+
co.fillStyle = colors[i];
|
287
|
+
co.fillRect(hpos + 5, vpos + (5 * j) + (text_size * j) - text_size, text_size, text_size + 1);
|
288
|
+
}
|
289
|
+
|
290
|
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
291
|
+
|
292
|
+
|
293
|
+
|
294
|
+
co.beginPath();
|
295
|
+
co.fillStyle = typeof text_color == 'object' ? text_color[i] : text_color;
|
296
|
+
|
297
|
+
ret = RG.Text2(obj, {
|
298
|
+
'font': text_font,
|
299
|
+
'size': text_size,
|
300
|
+
'bold': text_bold,
|
301
|
+
'italic': text_italic,
|
302
|
+
'x': hpos + blob_size + 5 + 5,
|
303
|
+
'y': vpos + (5 * j) + (text_size * j) + 3,
|
304
|
+
'text': key[i],
|
305
|
+
'accessible': !obj.properties['chart.key.interactive']
|
306
|
+
});
|
307
|
+
|
308
|
+
obj.coords.key[i] = [
|
309
|
+
ret.x,
|
310
|
+
ret.y,
|
311
|
+
ret.width,
|
312
|
+
ret.height,
|
313
|
+
key[i],
|
314
|
+
colors[i],
|
315
|
+
obj
|
316
|
+
];
|
317
|
+
}
|
318
|
+
co.fill();
|
319
|
+
}
|
320
|
+
|
321
|
+
|
322
|
+
|
323
|
+
|
324
|
+
|
325
|
+
|
326
|
+
|
327
|
+
|
328
|
+
|
329
|
+
|
330
|
+
|
331
|
+
|
332
|
+
|
333
|
+
|
334
|
+
|
335
|
+
|
336
|
+
|
337
|
+
|
338
|
+
|
339
|
+
|
340
|
+
|
341
|
+
|
342
|
+
|
343
|
+
/**
|
344
|
+
* This does the actual drawing of the key when it's in the gutter
|
345
|
+
*
|
346
|
+
* @param object obj The graph object
|
347
|
+
* @param array key The key items to draw
|
348
|
+
* @param array colors An aray of colors that the key will use
|
349
|
+
*/
|
350
|
+
function DrawKey_gutter (obj, key, colors)
|
351
|
+
{
|
352
|
+
var text_size = typeof(prop['chart.key.text.size']) == 'number' ? prop['chart.key.text.size'] : prop['chart.text.size'],
|
353
|
+
text_bold = prop['chart.key.text.bold'],
|
354
|
+
text_italic = prop['chart.key.text.italic'],
|
355
|
+
text_font = prop['chart.key.text.font'] || prop['chart.key.font'] || prop['chart.text.font'],
|
356
|
+
text_color = prop['chart.key.text.color'],
|
357
|
+
gutterLeft = obj.gutterLeft,
|
358
|
+
gutterRight = obj.gutterRight,
|
359
|
+
gutterTop = obj.gutterTop,
|
360
|
+
gutterBottom = obj.gutterBottom,
|
361
|
+
hpos = ((ca.width - gutterLeft - gutterRight) / 2) + obj.gutterLeft,
|
362
|
+
vpos = gutterTop - text_size - 5,
|
363
|
+
title = prop['chart.title'],
|
364
|
+
blob_size = text_size, // The blob of color
|
365
|
+
hmargin = 8, // This is the size of the gaps between the blob of color and the text
|
366
|
+
vmargin = 4, // This is the vertical margin of the key
|
367
|
+
fillstyle = prop['chart.key.background'],
|
368
|
+
strokestyle = '#999',
|
369
|
+
length = 0;
|
370
|
+
|
371
|
+
if (!obj.coords) obj.coords = {};
|
372
|
+
obj.coords.key = [];
|
373
|
+
|
374
|
+
|
375
|
+
|
376
|
+
// Need to work out the length of the key first
|
377
|
+
co.font = (obj.properties['chart.key.text.italic'] ? 'italic ' : '') + (obj.properties['chart.key.text.bold'] ? 'bold ' : '') + text_size + 'pt ' + text_font;
|
378
|
+
|
379
|
+
for (i=0; i<key.length; ++i) {
|
380
|
+
length += hmargin;
|
381
|
+
length += blob_size;
|
382
|
+
length += hmargin;
|
383
|
+
length += co.measureText(key[i]).width;
|
384
|
+
}
|
385
|
+
length += hmargin;
|
386
|
+
|
387
|
+
|
388
|
+
|
389
|
+
|
390
|
+
/**
|
391
|
+
* Work out hpos since in the Pie it isn't necessarily dead center
|
392
|
+
*/
|
393
|
+
if (obj.type == 'pie') {
|
394
|
+
if (prop['chart.align'] == 'left') {
|
395
|
+
var hpos = obj.radius + gutterLeft;
|
396
|
+
|
397
|
+
} else if (prop['chart.align'] == 'right') {
|
398
|
+
var hpos = ca.width - obj.radius - gutterRight;
|
399
|
+
|
400
|
+
} else {
|
401
|
+
hpos = ca.width / 2;
|
402
|
+
}
|
403
|
+
}
|
404
|
+
|
405
|
+
|
406
|
+
|
407
|
+
|
408
|
+
|
409
|
+
/**
|
410
|
+
* This makes the key centered
|
411
|
+
*/
|
412
|
+
hpos -= (length / 2);
|
413
|
+
|
414
|
+
|
415
|
+
/**
|
416
|
+
* Override the horizontal/vertical positioning
|
417
|
+
*/
|
418
|
+
if (typeof(prop['chart.key.position.x']) == 'number') {
|
419
|
+
hpos = prop['chart.key.position.x'];
|
420
|
+
}
|
421
|
+
if (typeof(prop['chart.key.position.y']) == 'number') {
|
422
|
+
vpos = prop['chart.key.position.y'];
|
423
|
+
}
|
424
|
+
|
425
|
+
|
426
|
+
|
427
|
+
/**
|
428
|
+
* Draw the box that the key sits in
|
429
|
+
*/
|
430
|
+
if (obj.Get('chart.key.position.gutter.boxed')) {
|
431
|
+
|
432
|
+
if (prop['chart.key.shadow']) {
|
433
|
+
co.shadowColor = prop['chart.key.shadow.color'];
|
434
|
+
co.shadowBlur = prop['chart.key.shadow.blur'];
|
435
|
+
co.shadowOffsetX = prop['chart.key.shadow.offsetx'];
|
436
|
+
co.shadowOffsetY = prop['chart.key.shadow.offsety'];
|
437
|
+
}
|
438
|
+
|
439
|
+
|
440
|
+
co.beginPath();
|
441
|
+
co.fillStyle = fillstyle;
|
442
|
+
co.strokeStyle = strokestyle;
|
443
|
+
|
444
|
+
if (prop['chart.key.rounded']) {
|
445
|
+
RG.strokedCurvyRect(co, hpos, vpos - vmargin, length, text_size + vmargin + vmargin)
|
446
|
+
// Odd... RG.filledCurvyRect(co, hpos, vpos - vmargin, length, text_size + vmargin + vmargin);
|
447
|
+
} else {
|
448
|
+
co.rect(hpos, vpos - vmargin, length, text_size + vmargin + vmargin);
|
449
|
+
}
|
450
|
+
|
451
|
+
co.stroke();
|
452
|
+
co.fill();
|
453
|
+
|
454
|
+
|
455
|
+
RG.NoShadow(obj);
|
456
|
+
}
|
457
|
+
|
458
|
+
|
459
|
+
/**
|
460
|
+
* Draw the blobs of color and the text
|
461
|
+
*/
|
462
|
+
|
463
|
+
// Custom colors for the key
|
464
|
+
if (prop['chart.key.colors']) {
|
465
|
+
colors = prop['chart.key.colors'];
|
466
|
+
}
|
467
|
+
|
468
|
+
for (var i=0, pos=hpos; i<key.length; ++i) {
|
469
|
+
pos += hmargin;
|
470
|
+
|
471
|
+
|
472
|
+
|
473
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
474
|
+
|
475
|
+
|
476
|
+
|
477
|
+
// Draw the blob of color
|
478
|
+
if (typeof(prop['chart.key.color.shape']) == 'object' && typeof(prop['chart.key.color.shape'][i]) == 'string') {
|
479
|
+
var blob_shape = prop['chart.key.color.shape'][i];
|
480
|
+
|
481
|
+
} else if (typeof(prop['chart.key.color.shape']) == 'string') {
|
482
|
+
var blob_shape = prop['chart.key.color.shape'];
|
483
|
+
|
484
|
+
} else {
|
485
|
+
var blob_shape = 'square';
|
486
|
+
}
|
487
|
+
|
488
|
+
|
489
|
+
/**
|
490
|
+
* Draw the blob of color - line
|
491
|
+
*/
|
492
|
+
if (blob_shape =='line') {
|
493
|
+
|
494
|
+
co.beginPath();
|
495
|
+
co.strokeStyle = colors[i];
|
496
|
+
co.moveTo(pos, vpos + (blob_size / 2));
|
497
|
+
co.lineTo(pos + blob_size, vpos + (blob_size / 2));
|
498
|
+
co.stroke();
|
499
|
+
|
500
|
+
// Circle
|
501
|
+
} else if (blob_shape == 'circle') {
|
502
|
+
|
503
|
+
co.beginPath();
|
504
|
+
co.fillStyle = colors[i];
|
505
|
+
co.moveTo(pos, vpos + (blob_size / 2));
|
506
|
+
co.arc(pos + (blob_size / 2), vpos + (blob_size / 2), (blob_size / 2), 0, 6.28, 0);
|
507
|
+
co.fill();
|
508
|
+
|
509
|
+
} else if (blob_shape == 'triangle') {
|
510
|
+
|
511
|
+
co.fillStyle = colors[i];
|
512
|
+
co.beginPath();
|
513
|
+
co.strokeStyle = colors[i];
|
514
|
+
co.moveTo(pos, vpos + blob_size);
|
515
|
+
co.lineTo(pos + (blob_size / 2), vpos);
|
516
|
+
co.lineTo(pos + blob_size, vpos + blob_size);
|
517
|
+
co.closePath();
|
518
|
+
co.fill();
|
519
|
+
|
520
|
+
} else {
|
521
|
+
|
522
|
+
co.beginPath();
|
523
|
+
co.fillStyle = colors[i];
|
524
|
+
co.rect(pos, vpos, blob_size, blob_size);
|
525
|
+
co.fill();
|
526
|
+
}
|
527
|
+
|
528
|
+
|
529
|
+
|
530
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
531
|
+
|
532
|
+
|
533
|
+
|
534
|
+
|
535
|
+
pos += blob_size;
|
536
|
+
|
537
|
+
pos += hmargin;
|
538
|
+
|
539
|
+
co.beginPath();
|
540
|
+
co.fillStyle = (typeof text_color === 'object') ? text_color[i] : text_color;
|
541
|
+
|
542
|
+
var ret = RG.Text2(obj, {
|
543
|
+
'font':text_font,
|
544
|
+
'bold':text_bold,
|
545
|
+
'size':text_size,
|
546
|
+
'italic': text_italic,
|
547
|
+
'x':pos,
|
548
|
+
'y':vpos + text_size + 3,
|
549
|
+
'text': key[i],
|
550
|
+
accessible: !obj.properties['chart.key.interactive']
|
551
|
+
});
|
552
|
+
co.fill();
|
553
|
+
pos += co.measureText(key[i]).width;
|
554
|
+
|
555
|
+
obj.coords.key[i] = [
|
556
|
+
ret.x,
|
557
|
+
ret.y,
|
558
|
+
ret.width,
|
559
|
+
ret.height,
|
560
|
+
key[i],
|
561
|
+
colors[i],
|
562
|
+
obj
|
563
|
+
];
|
564
|
+
}
|
565
|
+
}
|
566
|
+
|
567
|
+
|
568
|
+
|
569
|
+
|
570
|
+
if (keypos && keypos == 'gutter') {
|
571
|
+
DrawKey_gutter(obj, key, colors);
|
572
|
+
} else if (keypos && keypos == 'graph') {
|
573
|
+
DrawKey_graph(obj, key, colors);
|
574
|
+
} else {
|
575
|
+
alert('[COMMON] (' + obj.id + ') Unknown key position: ' + keypos);
|
576
|
+
}
|
577
|
+
|
578
|
+
|
579
|
+
|
580
|
+
|
581
|
+
|
582
|
+
|
583
|
+
if (prop['chart.key.interactive']) {
|
584
|
+
|
585
|
+
if (!RGraph.Drawing || !RGraph.Drawing.Rect) {
|
586
|
+
alert('[INTERACTIVE KEY] The drawing API Rect library does not appear to have been included (which the interactive key uses)');
|
587
|
+
}
|
588
|
+
|
589
|
+
|
590
|
+
|
591
|
+
/**
|
592
|
+
* Check that the RGraph.common.dynamic.js file has been included
|
593
|
+
*/
|
594
|
+
if (!RGraph.InstallWindowMousedownListener) {
|
595
|
+
alert('[INTERACTIVE KEY] The dynamic library does not appear to have been included');
|
596
|
+
}
|
597
|
+
|
598
|
+
|
599
|
+
|
600
|
+
// Determine the maximum width of the labels
|
601
|
+
for (var i=0,len=obj.coords.key.length,maxlen=0; i<len; i+=1) {
|
602
|
+
maxlen = Math.max(maxlen, obj.coords.key[i][2]);
|
603
|
+
}
|
604
|
+
|
605
|
+
|
606
|
+
//obj.coords.key.forEach(function (value, index, arr)
|
607
|
+
//{
|
608
|
+
for (var i=0,len=obj.coords.key.length; i<len; i+=1) {
|
609
|
+
|
610
|
+
// Because the loop would have finished when the i variable is needed - put
|
611
|
+
// the onclick function inside a new context so that the value of the i
|
612
|
+
// variable is what we expect when the key has been clicked
|
613
|
+
(function (idx)
|
614
|
+
{
|
615
|
+
var arr = obj.coords.key;
|
616
|
+
var value = obj.coords.key[idx];
|
617
|
+
var index = idx;
|
618
|
+
|
619
|
+
|
620
|
+
var rect = new RGraph.Drawing.Rect(obj.id,value[0], value[1], prop['chart.key.position'] == 'gutter' ? value[2] : maxlen, value[3])
|
621
|
+
.Set('fillstyle', 'rgba(0,0,0,0)')
|
622
|
+
.Draw();
|
623
|
+
|
624
|
+
rect.onclick = function (e, shape)
|
625
|
+
{
|
626
|
+
var co = rect.context;
|
627
|
+
|
628
|
+
co.fillStyle = prop['chart.key.interactive.highlight.label'];
|
629
|
+
co.fillRect(shape.x, shape.y, shape.width, shape.height);
|
630
|
+
|
631
|
+
if (typeof obj.interactiveKeyHighlight == 'function') {
|
632
|
+
|
633
|
+
obj.Set('chart.key.interactive.index', idx);
|
634
|
+
|
635
|
+
RG.FireCustomEvent(obj, 'onbeforeinteractivekey');
|
636
|
+
obj.interactiveKeyHighlight(index);
|
637
|
+
RG.FireCustomEvent(obj, 'onafterinteractivekey');
|
638
|
+
}
|
639
|
+
}
|
640
|
+
|
641
|
+
rect.onmousemove = function (e, shape)
|
642
|
+
{
|
643
|
+
return true;
|
644
|
+
}
|
645
|
+
})(i);
|
646
|
+
}
|
647
|
+
}
|
648
|
+
};
|
649
|
+
|
650
|
+
|
651
|
+
|
652
|
+
|
653
|
+
/**
|
654
|
+
* Returns the key length, but accounts for null values
|
655
|
+
*
|
656
|
+
* @param array key The key elements
|
657
|
+
*/
|
658
|
+
RG.getKeyLength = function (key)
|
659
|
+
{
|
660
|
+
var length = 0;
|
661
|
+
|
662
|
+
for (var i=0,len=key.length; i<len; i+=1) {
|
663
|
+
if (key[i] != null) {
|
664
|
+
++length;
|
665
|
+
}
|
666
|
+
}
|
667
|
+
|
668
|
+
return length;
|
669
|
+
};
|
670
|
+
|
671
|
+
|
672
|
+
|
673
|
+
|
674
|
+
/**
|
675
|
+
* Create a TABLE based HTML key. There's lots of options so it's
|
676
|
+
* suggested that you consult the documentation page
|
677
|
+
*
|
678
|
+
* @param mixed id This should be a string consisting of the ID of the container
|
679
|
+
* @param object prop An object map of the various properties that you can use to
|
680
|
+
* configure the key. See the documentation page for a list.
|
681
|
+
*/
|
682
|
+
RGraph.HTML.key =
|
683
|
+
RGraph.HTML.Key = function (id, prop)
|
684
|
+
{
|
685
|
+
var div = doc.getElementById(id);
|
686
|
+
|
687
|
+
|
688
|
+
/**
|
689
|
+
* Create the table that becomes the key
|
690
|
+
*/
|
691
|
+
var str = '<table border="0" cellspacing="0" cellpadding="0" id="rgraph_key" style="display: inline;' + (function ()
|
692
|
+
{
|
693
|
+
var style = ''
|
694
|
+
for (i in prop.tableCss) {
|
695
|
+
if (typeof i === 'string') {
|
696
|
+
style = style + i + ': ' + prop.tableCss[i] + ';';
|
697
|
+
}
|
698
|
+
}
|
699
|
+
return style;
|
700
|
+
})() + '" ' + (prop.tableClass ? 'class="' + prop.tableClass + '"' : '') + '>';
|
701
|
+
|
702
|
+
|
703
|
+
|
704
|
+
/**
|
705
|
+
* Add the individual key elements
|
706
|
+
*/
|
707
|
+
for (var i=0; i<prop.labels.length; i+=1) {
|
708
|
+
str += '<tr><td><div style="' + (function ()
|
709
|
+
{
|
710
|
+
var style = '';
|
711
|
+
|
712
|
+
for (var j in prop.blobCss) {
|
713
|
+
if (typeof j === 'string') {
|
714
|
+
style = style + j + ': ' + prop.blobCss[j] + ';';
|
715
|
+
}
|
716
|
+
}
|
717
|
+
|
718
|
+
return style;
|
719
|
+
})() + 'display: inline-block; margin-right: 5px; margin-top: 4px; width: 15px; height: 15px; background-color: ' + prop.colors[i] + '"' + (prop.blobClass ? 'class="' + prop.blobClass + '"' : '') + '> </div><td>' + (prop.links && prop.links[i] ? '<a href="' + prop.links[i] + '">' : '') + '<span ' + (prop.labelClass ? 'class="' + prop.labelClass + '"' : '') + '" ' + (function ()
|
720
|
+
{
|
721
|
+
var style = '';
|
722
|
+
|
723
|
+
for (var j in prop.labelCss) {
|
724
|
+
if (typeof j === 'string') {
|
725
|
+
style = style + j + ': ' + prop.labelCss[j] + ';';
|
726
|
+
}
|
727
|
+
}
|
728
|
+
|
729
|
+
return style;
|
730
|
+
})() + (function ()
|
731
|
+
{
|
732
|
+
var style = '';
|
733
|
+
|
734
|
+
if (prop['labelCss_' + i]) {
|
735
|
+
for (var j in prop['labelCss_' + i]) {
|
736
|
+
style = style + j + ': ' + prop['labelCss_' + i][j] + ';';
|
737
|
+
}
|
738
|
+
}
|
739
|
+
|
740
|
+
return style ? 'style="' + style + '"' : '';
|
741
|
+
})() + '>' + prop.labels[i] + '</span>' + (prop.links && prop.links[i] ? '</a>' : '') + '</td></tr>';
|
742
|
+
}
|
743
|
+
|
744
|
+
div.innerHTML += (str + '</table>');
|
745
|
+
|
746
|
+
// Return the TABLE object that is the HTML key
|
747
|
+
return doc.getElementById('rgraph_key');
|
748
|
+
};
|
749
|
+
|
750
|
+
|
751
|
+
|
752
|
+
|
753
|
+
// End module pattern
|
754
|
+
})(window, document);
|