rgraph-rails 4.62 → 4.64
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.
- checksums.yaml +5 -5
- data/README.md +3 -4
- data/lib/rgraph-rails/version.rb +1 -1
- data/vendor/assets/javascripts/RGraph.bar.js +240 -3742
- data/vendor/assets/javascripts/RGraph.bipolar.js +165 -2005
- data/vendor/assets/javascripts/RGraph.common.annotate.js +35 -395
- data/vendor/assets/javascripts/RGraph.common.context.js +30 -595
- data/vendor/assets/javascripts/RGraph.common.core.js +418 -5359
- data/vendor/assets/javascripts/RGraph.common.csv.js +20 -276
- data/vendor/assets/javascripts/RGraph.common.deprecated.js +35 -450
- data/vendor/assets/javascripts/RGraph.common.dynamic.js +88 -1395
- data/vendor/assets/javascripts/RGraph.common.effects.js +90 -1545
- data/vendor/assets/javascripts/RGraph.common.key.js +52 -753
- data/vendor/assets/javascripts/RGraph.common.resizing.js +37 -563
- data/vendor/assets/javascripts/RGraph.common.sheets.js +29 -352
- data/vendor/assets/javascripts/RGraph.common.tooltips.js +32 -450
- data/vendor/assets/javascripts/RGraph.common.zoom.js +14 -219
- data/vendor/assets/javascripts/RGraph.cornergauge.js +71 -0
- data/vendor/assets/javascripts/RGraph.drawing.background.js +34 -570
- data/vendor/assets/javascripts/RGraph.drawing.circle.js +33 -544
- data/vendor/assets/javascripts/RGraph.drawing.image.js +51 -755
- data/vendor/assets/javascripts/RGraph.drawing.marker1.js +37 -645
- data/vendor/assets/javascripts/RGraph.drawing.marker2.js +36 -633
- data/vendor/assets/javascripts/RGraph.drawing.marker3.js +35 -514
- data/vendor/assets/javascripts/RGraph.drawing.poly.js +37 -559
- data/vendor/assets/javascripts/RGraph.drawing.rect.js +33 -548
- data/vendor/assets/javascripts/RGraph.drawing.text.js +36 -664
- data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +50 -812
- data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +51 -856
- data/vendor/assets/javascripts/RGraph.fuel.js +58 -964
- data/vendor/assets/javascripts/RGraph.funnel.js +55 -984
- data/vendor/assets/javascripts/RGraph.gantt.js +77 -1354
- data/vendor/assets/javascripts/RGraph.gauge.js +85 -1421
- data/vendor/assets/javascripts/RGraph.hbar.js +162 -2788
- data/vendor/assets/javascripts/RGraph.hprogress.js +80 -1401
- data/vendor/assets/javascripts/RGraph.line.js +249 -4248
- data/vendor/assets/javascripts/RGraph.meter.js +74 -1280
- data/vendor/assets/javascripts/RGraph.modaldialog.js +19 -301
- data/vendor/assets/javascripts/RGraph.odo.js +71 -1264
- data/vendor/assets/javascripts/RGraph.pie.js +137 -2288
- data/vendor/assets/javascripts/RGraph.radar.js +110 -1847
- data/vendor/assets/javascripts/RGraph.rose.js +108 -1977
- data/vendor/assets/javascripts/RGraph.rscatter.js +80 -1432
- data/vendor/assets/javascripts/RGraph.scatter.js +172 -3163
- data/vendor/assets/javascripts/RGraph.semicircularprogress.js +60 -1120
- data/vendor/assets/javascripts/RGraph.svg.bar.js +66 -1735
- data/vendor/assets/javascripts/RGraph.svg.common.ajax.js +21 -246
- data/vendor/assets/javascripts/RGraph.svg.common.core.js +255 -3937
- data/vendor/assets/javascripts/RGraph.svg.common.csv.js +20 -276
- data/vendor/assets/javascripts/RGraph.svg.common.fx.js +68 -1303
- data/vendor/assets/javascripts/RGraph.svg.common.key.js +19 -205
- data/vendor/assets/javascripts/RGraph.svg.common.sheets.js +29 -352
- data/vendor/assets/javascripts/RGraph.svg.common.tooltips.js +22 -273
- data/vendor/assets/javascripts/RGraph.svg.funnel.js +32 -0
- data/vendor/assets/javascripts/RGraph.svg.hbar.js +59 -1400
- data/vendor/assets/javascripts/RGraph.svg.line.js +70 -1580
- data/vendor/assets/javascripts/RGraph.svg.pie.js +55 -1131
- data/vendor/assets/javascripts/RGraph.svg.radar.js +57 -1502
- data/vendor/assets/javascripts/RGraph.svg.rose.js +66 -1817
- data/vendor/assets/javascripts/RGraph.svg.scatter.js +58 -1261
- data/vendor/assets/javascripts/RGraph.svg.semicircularprogress.js +28 -865
- data/vendor/assets/javascripts/RGraph.svg.waterfall.js +45 -1252
- data/vendor/assets/javascripts/RGraph.thermometer.js +63 -1136
- data/vendor/assets/javascripts/RGraph.vprogress.js +83 -1470
- data/vendor/assets/javascripts/RGraph.waterfall.js +83 -1347
- metadata +5 -4
- data/vendor/assets/javascripts/financial-data.js +0 -1067
@@ -1,247 +1,22 @@
|
|
1
|
-
// version: 2017-05-08
|
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
|
-
*/
|
12
1
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
(function
|
19
|
-
{
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
{
|
35
|
-
// Mozilla, Safari, ...
|
36
|
-
if (window.XMLHttpRequest) {
|
37
|
-
var httpRequest = new XMLHttpRequest();
|
38
|
-
|
39
|
-
// MSIE
|
40
|
-
} else if (window.ActiveXObject) {
|
41
|
-
var httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
|
42
|
-
}
|
43
|
-
|
44
|
-
httpRequest.onreadystatechange = function ()
|
45
|
-
{
|
46
|
-
if (this.readyState == 4 && this.status == 200) {
|
47
|
-
this.__user_callback__ = callback;
|
48
|
-
this.__user_callback__(this.responseText);
|
49
|
-
}
|
50
|
-
}
|
51
|
-
|
52
|
-
httpRequest.open('GET', url, true);
|
53
|
-
httpRequest.send();
|
54
|
-
};
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
/**
|
66
|
-
* Makes an AJAX POST request. It calls the given callback (a function) when ready
|
67
|
-
*
|
68
|
-
* @param string url The URL to retrieve
|
69
|
-
* @param object data The POST data
|
70
|
-
* @param function callback A function that is called when the response is ready, there's an example below
|
71
|
-
* called "myCallback".
|
72
|
-
*/
|
73
|
-
RG.SVG.AJAX.POST = function (url, data, callback)
|
74
|
-
{
|
75
|
-
// Used when building the POST string
|
76
|
-
var crumbs = [];
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
// Mozilla, Safari, ...
|
84
|
-
if (window.XMLHttpRequest) {
|
85
|
-
var httpRequest = new XMLHttpRequest();
|
86
|
-
|
87
|
-
// MSIE
|
88
|
-
} else if (window.ActiveXObject) {
|
89
|
-
var httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
|
90
|
-
}
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
httpRequest.onreadystatechange = function ()
|
97
|
-
{
|
98
|
-
if (this.readyState == 4 && this.status == 200) {
|
99
|
-
this.__user_callback__ = callback;
|
100
|
-
this.__user_callback__(this.responseText);
|
101
|
-
}
|
102
|
-
}
|
103
|
-
|
104
|
-
httpRequest.open('POST', url, true);
|
105
|
-
httpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
|
106
|
-
|
107
|
-
for (i in data) {
|
108
|
-
if (typeof i == 'string') {
|
109
|
-
crumbs.push(i + '=' + encodeURIComponent(data[i]));
|
110
|
-
}
|
111
|
-
}
|
112
|
-
|
113
|
-
httpRequest.send(crumbs.join('&'));
|
114
|
-
};
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
/**
|
126
|
-
* Uses the above function but calls the call back passing a number as its argument
|
127
|
-
*
|
128
|
-
* @param url string The URL to fetch
|
129
|
-
* @param callback function Your callback function (which is passed the number as an argument)
|
130
|
-
*/
|
131
|
-
RG.SVG.AJAX.getNumber = function (url, callback)
|
132
|
-
{
|
133
|
-
RG.SVG.AJAX(url, function ()
|
134
|
-
{
|
135
|
-
var num = parseFloat(this.responseText);
|
136
|
-
|
137
|
-
callback(num);
|
138
|
-
});
|
139
|
-
};
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
/**
|
151
|
-
* Uses the above function but calls the call back passing a string as its argument
|
152
|
-
*
|
153
|
-
* @param url string The URL to fetch
|
154
|
-
* @param callback function Your callback function (which is passed the string as an argument)
|
155
|
-
*/
|
156
|
-
RG.SVG.AJAX.getString = function (url, callback)
|
157
|
-
{
|
158
|
-
RG.SVG.AJAX(url, function ()
|
159
|
-
{
|
160
|
-
var str = String(this.responseText);
|
161
|
-
|
162
|
-
callback(str);
|
163
|
-
});
|
164
|
-
};
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
/**
|
176
|
-
* Uses the above function but calls the call back passing JSON (ie a JavaScript object ) as its argument
|
177
|
-
*
|
178
|
-
* @param url string The URL to fetch
|
179
|
-
* @param callback function Your callback function (which is passed the JSON object as an argument)
|
180
|
-
*/
|
181
|
-
RG.SVG.AJAX.getJSON = function (url, callback)
|
182
|
-
{
|
183
|
-
RG.SVG.AJAX(url, function ()
|
184
|
-
{
|
185
|
-
var json = eval('(' + this.responseText + ')');
|
186
|
-
|
187
|
-
callback(json);
|
188
|
-
});
|
189
|
-
};
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
/**
|
201
|
-
* Uses the above RGraph.AJAX function but calls the call back passing an array as its argument.
|
202
|
-
* Useful if you're retrieving CSV data
|
203
|
-
*
|
204
|
-
* @param url string The URL to fetch
|
205
|
-
* @param callback function Your callback function (which is passed the CSV/array as an argument)
|
206
|
-
*/
|
207
|
-
RG.SVG.AJAX.getCSV = function (url, callback)
|
208
|
-
{
|
209
|
-
var seperator = (typeof arguments[2] === 'string' ? arguments[2] : ','),
|
210
|
-
lineSep = (typeof arguments[3] === 'string' ? arguments[3] : "\r?\n");
|
211
|
-
|
212
|
-
RG.SVG.AJAX(url, function ()
|
213
|
-
{
|
214
|
-
var text = this.responseText,
|
215
|
-
regexp = new RegExp(seperator),
|
216
|
-
lines = this.responseText.split(lineSep),
|
217
|
-
rows = [];
|
218
|
-
|
219
|
-
for (var i=0; i<lines.length; ++i) {
|
220
|
-
|
221
|
-
var row = lines[i].split(seperator);
|
222
|
-
|
223
|
-
for (var j=0,len=row.length;j<len;++j) {
|
224
|
-
if (row[j].match(/^[0-9.]+$/)) {
|
225
|
-
row[j] = parseFloat(row[j]);
|
226
|
-
}
|
227
|
-
}
|
228
|
-
|
229
|
-
rows.push(row);
|
230
|
-
}
|
231
|
-
|
232
|
-
|
233
|
-
callback(rows);
|
234
|
-
});
|
235
|
-
};
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
// End module pattern
|
247
|
-
})(window, document);
|
2
|
+
RGraph=window.RGraph||{isRGraph:true,isRGraphSVG:true};RGraph.SVG=RGraph.SVG||{};RGraph.SVG.AJAX=RGraph.SVG.AJAX||{};(function(win,doc,undefined)
|
3
|
+
{var RG=RGraph,ua=navigator.userAgent,ma=Math;RG.SVG.AJAX=function(url,callback)
|
4
|
+
{if(window.XMLHttpRequest){var httpRequest=new XMLHttpRequest();}else if(window.ActiveXObject){var httpRequest=new ActiveXObject("Microsoft.XMLHTTP");}
|
5
|
+
httpRequest.onreadystatechange=function()
|
6
|
+
{if(this.readyState==4&&this.status==200){this.__user_callback__=callback;this.__user_callback__(this.responseText);}}
|
7
|
+
httpRequest.open('GET',url,true);httpRequest.send();};RG.SVG.AJAX.POST=function(url,data,callback)
|
8
|
+
{var crumbs=[];if(window.XMLHttpRequest){var httpRequest=new XMLHttpRequest();}else if(window.ActiveXObject){var httpRequest=new ActiveXObject("Microsoft.XMLHTTP");}
|
9
|
+
httpRequest.onreadystatechange=function()
|
10
|
+
{if(this.readyState==4&&this.status==200){this.__user_callback__=callback;this.__user_callback__(this.responseText);}}
|
11
|
+
httpRequest.open('POST',url,true);httpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");for(i in data){if(typeof i=='string'){crumbs.push(i+'='+encodeURIComponent(data[i]));}}
|
12
|
+
httpRequest.send(crumbs.join('&'));};RG.SVG.AJAX.getNumber=function(url,callback)
|
13
|
+
{RG.SVG.AJAX(url,function()
|
14
|
+
{var num=parseFloat(this.responseText);callback(num);});};RG.SVG.AJAX.getString=function(url,callback)
|
15
|
+
{RG.SVG.AJAX(url,function()
|
16
|
+
{var str=String(this.responseText);callback(str);});};RG.SVG.AJAX.getJSON=function(url,callback)
|
17
|
+
{RG.SVG.AJAX(url,function()
|
18
|
+
{var json=eval('('+this.responseText+')');callback(json);});};RG.SVG.AJAX.getCSV=function(url,callback)
|
19
|
+
{var seperator=(typeof arguments[2]==='string'?arguments[2]:','),lineSep=(typeof arguments[3]==='string'?arguments[3]:"\r?\n");RG.SVG.AJAX(url,function()
|
20
|
+
{var text=this.responseText,regexp=new RegExp(seperator),lines=this.responseText.split(lineSep),rows=[];for(var i=0;i<lines.length;++i){var row=lines[i].split(seperator);for(var j=0,len=row.length;j<len;++j){if(row[j].match(/^[0-9.]+$/)){row[j]=parseFloat(row[j]);}}
|
21
|
+
rows.push(row);}
|
22
|
+
callback(rows);});};})(window,document);
|
@@ -1,3938 +1,256 @@
|
|
1
|
-
// version: 2017-05-08
|
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
|
-
*/
|
12
1
|
|
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
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
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
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
x + 0.001,
|
269
|
-
startY,
|
270
|
-
x,
|
271
|
-
endY
|
272
|
-
),
|
273
|
-
stroke: prop.xaxisColor,
|
274
|
-
'stroke-width': typeof prop.xaxisLinewidth === 'number' ? prop.xaxisLinewidth : 1,
|
275
|
-
'shape-rendering': "crispEdges"
|
276
|
-
}
|
277
|
-
});
|
278
|
-
}
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
} else {
|
284
|
-
|
285
|
-
// This style is used by Bar and Scatter charts
|
286
|
-
if (prop.xaxisLabelsPosition === 'section') {
|
287
|
-
|
288
|
-
if (obj.type === 'bar' || obj.type === 'waterfall') {
|
289
|
-
var dataPoints = obj.data.length;
|
290
|
-
} else if (obj.type === 'line'){
|
291
|
-
var dataPoints = obj.data[0].length;
|
292
|
-
} else if (obj.type === 'scatter') {
|
293
|
-
var dataPoints = prop.xaxisLabels ? prop.xaxisLabels.length : 10;
|
294
|
-
}
|
295
|
-
|
296
|
-
for (var i=0; i<dataPoints; ++i) {
|
297
|
-
|
298
|
-
x = prop.gutterLeft + ((i+1) * (obj.graphWidth / dataPoints));
|
299
|
-
|
300
|
-
RG.SVG.create({
|
301
|
-
svg: obj.svg,
|
302
|
-
parent: obj.svg.all,
|
303
|
-
type: 'path',
|
304
|
-
attr: {
|
305
|
-
d: 'M{1} {2} L{3} {4}'.format(
|
306
|
-
x + 0.001,
|
307
|
-
startY,
|
308
|
-
x,
|
309
|
-
endY
|
310
|
-
),
|
311
|
-
stroke: prop.xaxisColor,
|
312
|
-
'stroke-width': typeof prop.xaxisLinewidth === 'number' ? prop.xaxisLinewidth : 1,
|
313
|
-
'shape-rendering': "crispEdges"
|
314
|
-
}
|
315
|
-
});
|
316
|
-
}
|
317
|
-
|
318
|
-
// This style is used by line charts
|
319
|
-
} else if (prop.xaxisLabelsPosition === 'edge') {
|
320
|
-
|
321
|
-
if (typeof prop.xaxisLabelsPositionEdgeTickmarksCount === 'number') {
|
322
|
-
var len = prop.xaxisLabelsPositionEdgeTickmarksCount;
|
323
|
-
} else {
|
324
|
-
var len = obj.data && obj.data[0] && obj.data[0].length ? obj.data[0].length : 0;
|
325
|
-
}
|
326
|
-
|
327
|
-
for (var i=0; i<len; ++i) {
|
328
|
-
|
329
|
-
var gap = ( (obj.graphWidth) / (len - 1)),
|
330
|
-
x = prop.gutterLeft + ((i+1) * gap);
|
331
|
-
|
332
|
-
RG.SVG.create({
|
333
|
-
svg: obj.svg,
|
334
|
-
parent: obj.svg.all,
|
335
|
-
type: 'path',
|
336
|
-
attr: {
|
337
|
-
d: 'M{1} {2} L{3} {4}'.format(
|
338
|
-
x + 0.001,
|
339
|
-
startY,
|
340
|
-
x,
|
341
|
-
endY
|
342
|
-
),
|
343
|
-
stroke: prop.xaxisColor,
|
344
|
-
'stroke-width': typeof prop.xaxisLinewidth === 'number' ? prop.xaxisLinewidth : 1,
|
345
|
-
'shape-rendering': "crispEdges"
|
346
|
-
}
|
347
|
-
});
|
348
|
-
}
|
349
|
-
}
|
350
|
-
}
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
// Draw an extra tick if the Y axis is not being shown
|
358
|
-
if (prop.yaxis === false) {
|
359
|
-
RG.SVG.create({
|
360
|
-
svg: obj.svg,
|
361
|
-
parent: obj.svg.all,
|
362
|
-
type: 'path',
|
363
|
-
attr: {
|
364
|
-
d: 'M{1} {2} L{3} {4}'.format(
|
365
|
-
prop.gutterLeft + 0.001,
|
366
|
-
startY,
|
367
|
-
prop.gutterLeft,
|
368
|
-
endY
|
369
|
-
),
|
370
|
-
stroke: obj.properties.xaxisColor,
|
371
|
-
'stroke-width': typeof prop.xaxisLinewidth === 'number' ? prop.xaxisLinewidth : 1,
|
372
|
-
'shape-rendering': "crispEdges",
|
373
|
-
parent: obj.svg.all,
|
374
|
-
}
|
375
|
-
});
|
376
|
-
}
|
377
|
-
}
|
378
|
-
}
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
//
|
392
|
-
// Draw an X axis scale
|
393
|
-
//
|
394
|
-
if (prop.xaxisScale) {
|
395
|
-
|
396
|
-
var segment = obj.graphWidth / prop.xaxisLabelsCount;
|
397
|
-
|
398
|
-
for (var i=0; i<obj.scale.labels.length; ++i) {
|
399
|
-
|
400
|
-
var x = prop.gutterLeft + (segment * i) + segment + prop.xaxisLabelsOffsetx;
|
401
|
-
|
402
|
-
RG.SVG.text({
|
403
|
-
object: obj,
|
404
|
-
parent: obj.svg.all,
|
405
|
-
text: obj.scale.labels[i],
|
406
|
-
x: x,
|
407
|
-
y: (obj.height - prop.gutterBottom) + (prop.xaxis ? prop.xaxisTickmarksLength + 6 : 10) + (prop.xaxisLinewidth || 1) + prop.xaxisLabelsOffsety,
|
408
|
-
halign: 'center',
|
409
|
-
valign: 'top',
|
410
|
-
font: prop.xaxisTextFont || prop.textFont,
|
411
|
-
size: prop.xaxisTextSize || (typeof prop.textSize === 'number' ? prop.textSize + 'pt' : prop.textSize),
|
412
|
-
bold: prop.xaxisTextBold || prop.textBold,
|
413
|
-
italic: prop.xaxisTextItalic || prop.textItalic,
|
414
|
-
color: prop.xaxisTextColor || prop.textColor
|
415
|
-
});
|
416
|
-
}
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
// Add the minimum label if labels are enabled
|
423
|
-
if (prop.xaxisLabelsCount > 0) {
|
424
|
-
var y = obj.height - prop.gutterBottom + prop.xaxisLabelsOffsety + (prop.xaxis ? prop.xaxisTickmarksLength + 6 : 10),
|
425
|
-
str = RG.SVG.numberFormat({
|
426
|
-
object: obj,
|
427
|
-
num: prop.xaxisMin.toFixed(prop.xaxisDecimals),
|
428
|
-
prepend: prop.xaxisUnitsPre,
|
429
|
-
append: prop.xaxisUnitsPost,
|
430
|
-
point: prop.xaxisPoint,
|
431
|
-
thousand: prop.xaxisThousand,
|
432
|
-
formatter: prop.xaxisFormatter
|
433
|
-
});
|
434
|
-
|
435
|
-
var text = RG.SVG.text({
|
436
|
-
object: obj,
|
437
|
-
parent: obj.svg.all,
|
438
|
-
text: typeof prop.xaxisFormatter === 'function' ? (prop.xaxisFormatter)(this, prop.xaxisMin) : str,
|
439
|
-
x: prop.gutterLeft + prop.xaxisLabelsOffsetx,
|
440
|
-
y: y,
|
441
|
-
halign: 'center',
|
442
|
-
valign: 'top',
|
443
|
-
font: prop.xaxisTextFont || prop.textFont,
|
444
|
-
size: prop.xaxisTextSize || (typeof prop.textSize === 'number' ? prop.textSize + 'pt' : prop.textSize),
|
445
|
-
bold: prop.xaxisTextBold || prop.textBold,
|
446
|
-
italic: prop.xaxisTextItalic || prop.textItalic,
|
447
|
-
color: prop.xaxisTextColor || prop.textColor
|
448
|
-
});
|
449
|
-
}
|
450
|
-
|
451
|
-
//
|
452
|
-
// Draw the X axis labels
|
453
|
-
//
|
454
|
-
} else {
|
455
|
-
if (typeof prop.xaxisLabels === 'object' && !RG.SVG.isNull(prop.xaxisLabels) ) {
|
456
|
-
|
457
|
-
// Loop through the X labels
|
458
|
-
if (prop.xaxisLabelsPosition === 'section') {
|
459
|
-
|
460
|
-
var segment = (obj.width - prop.gutterLeft - prop.gutterRight) / prop.xaxisLabels.length;
|
461
|
-
|
462
|
-
for (var i=0; i<prop.xaxisLabels.length; ++i) {
|
463
|
-
|
464
|
-
var x = prop.gutterLeft + (segment / 2) + (i * segment);
|
465
|
-
|
466
|
-
if (obj.scale.max <=0 && obj.scale.min < obj.scale.max) {
|
467
|
-
var y = prop.gutterTop - (RG.SVG.ISFF ? 5 : 10) - (prop.xaxisLinewidth || 1) + prop.xaxisLabelsOffsety;
|
468
|
-
var valign = 'bottom';
|
469
|
-
} else {
|
470
|
-
var y = obj.height - prop.gutterBottom + (RG.SVG.ISFF ? 5 : 10) + (prop.xaxisLinewidth || 1) + prop.xaxisLabelsOffsety;
|
471
|
-
var valign = 'top';
|
472
|
-
}
|
473
|
-
|
474
|
-
RG.SVG.text({
|
475
|
-
object: obj,
|
476
|
-
parent: obj.svg.all,
|
477
|
-
text: prop.xaxisLabels[i],
|
478
|
-
x: x + prop.xaxisLabelsOffsetx,
|
479
|
-
y: y,
|
480
|
-
valign: valign,
|
481
|
-
halign: 'center',
|
482
|
-
size: prop.xaxisTextSize || prop.textSize,
|
483
|
-
italic: prop.xaxisTextItalic || prop.textItalic,
|
484
|
-
font: prop.xaxisTextFont || prop.textFont,
|
485
|
-
bold: prop.xaxisTextBold || prop.textBold,
|
486
|
-
color: prop.xaxisTextColor || prop.textColor
|
487
|
-
});
|
488
|
-
}
|
489
|
-
} else if (prop.xaxisLabelsPosition === 'edge') {
|
490
|
-
|
491
|
-
if (obj.type === 'line') {
|
492
|
-
var hmargin = prop.hmargin;
|
493
|
-
} else {
|
494
|
-
var hmargin = 0;
|
495
|
-
}
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
var segment = (obj.graphWidth - hmargin - hmargin) / (prop.xaxisLabels.length - 1);
|
500
|
-
|
501
|
-
for (var i=0; i<prop.xaxisLabels.length; ++i) {
|
502
|
-
|
503
|
-
var x = prop.gutterLeft + (i * segment) + hmargin;
|
504
|
-
|
505
|
-
if (obj.scale.max <= 0 && obj.scale.min < 0) {
|
506
|
-
valign = 'bottom';
|
507
|
-
y = prop.gutterTop - (RG.SVG.ISFF ? 5 : 10) - (prop.xaxisTickmarksLength - 5) - (prop.xaxisLinewidth || 1) + prop.xaxisLabelsOffsety
|
508
|
-
} else {
|
509
|
-
valign = 'top';
|
510
|
-
y = obj.height - prop.gutterBottom + (RG.SVG.ISFF ? 5 : 10) + (prop.xaxisTickmarksLength - 5) + (prop.xaxisLinewidth || 1) + prop.xaxisLabelsOffsety;
|
511
|
-
}
|
512
|
-
|
513
|
-
RG.SVG.text({
|
514
|
-
object: obj,
|
515
|
-
parent: obj.svg.all,
|
516
|
-
text: prop.xaxisLabels[i],
|
517
|
-
x: x + prop.xaxisLabelsOffsetx,
|
518
|
-
y: y,
|
519
|
-
valign: valign,
|
520
|
-
halign: 'center',
|
521
|
-
size: prop.xaxisTextSize || prop.textSize,
|
522
|
-
italic: prop.xaxisTextItalic || prop.textItalic,
|
523
|
-
font: prop.xaxisTextFont || prop.textFont,
|
524
|
-
bold: prop.xaxisTextBold || prop.textBold,
|
525
|
-
color: prop.xaxisTextColor || prop.textColor
|
526
|
-
});
|
527
|
-
}
|
528
|
-
}
|
529
|
-
}
|
530
|
-
}
|
531
|
-
};
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
//
|
541
|
-
// Draws an Y axis
|
542
|
-
//
|
543
|
-
//@param The chart object
|
544
|
-
//
|
545
|
-
RG.SVG.drawYAxis = function (obj)
|
546
|
-
{
|
547
|
-
var prop = obj.properties;
|
548
|
-
|
549
|
-
if (prop.yaxis) {
|
550
|
-
|
551
|
-
// The X coordinate that the Y axis is positioned at
|
552
|
-
if (obj.type === 'hbar') {
|
553
|
-
|
554
|
-
var x = obj.getXCoord(prop.xaxisMin > 0 ? prop.xaxisMin : 0);
|
555
|
-
|
556
|
-
if (prop.xaxisMin < 0 && prop.xaxisMax <= 0) {
|
557
|
-
x = obj.getXCoord(prop.xaxisMax);
|
558
|
-
}
|
559
|
-
} else {
|
560
|
-
var x = prop.gutterLeft;
|
561
|
-
}
|
562
|
-
|
563
|
-
|
564
|
-
var axis = RG.SVG.create({
|
565
|
-
svg: obj.svg,
|
566
|
-
parent: obj.svg.all,
|
567
|
-
type: 'path',
|
568
|
-
attr: {
|
569
|
-
d: 'M{1} {2} L{3} {4}'.format(
|
570
|
-
x,
|
571
|
-
prop.gutterTop,
|
572
|
-
x + 0.001,
|
573
|
-
obj.height - prop.gutterBottom
|
574
|
-
),
|
575
|
-
stroke: prop.yaxisColor,
|
576
|
-
fill: prop.yaxisColor,
|
577
|
-
'stroke-width': typeof prop.yaxisLinewidth === 'number' ? prop.yaxisLinewidth : 1,
|
578
|
-
'shape-rendering': "crispEdges",
|
579
|
-
'stroke-linecap': 'square'
|
580
|
-
}
|
581
|
-
});
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
if (obj.type === 'hbar') {
|
590
|
-
|
591
|
-
var height = (obj.graphHeight - prop.vmarginTop - prop.vmarginBottom) / prop.yaxisLabels.length,
|
592
|
-
y = prop.gutterTop + prop.vmarginTop,
|
593
|
-
len = prop.yaxisLabels.length,
|
594
|
-
startX = obj.getXCoord(0) + (prop.xaxisMin < 0 ? prop.yaxisTickmarksLength : 0),
|
595
|
-
endX = obj.getXCoord(0) - prop.yaxisTickmarksLength;
|
596
|
-
|
597
|
-
if (obj.type === 'hbar' && prop.xaxisMin < 0 && prop.xaxisMax <=0) {
|
598
|
-
startX = obj.getXCoord(prop.xaxisMax);
|
599
|
-
endX = obj.getXCoord(prop.xaxisMax) + 5;
|
600
|
-
}
|
601
|
-
|
602
|
-
//
|
603
|
-
// Draw the tickmarks
|
604
|
-
//
|
605
|
-
if (prop.yaxisTickmarks) {
|
606
|
-
for (var i=0; i<len; ++i) {
|
607
|
-
|
608
|
-
// Draw the axis
|
609
|
-
var axis = RG.SVG.create({
|
610
|
-
svg: obj.svg,
|
611
|
-
parent: obj.svg.all,
|
612
|
-
type: 'path',
|
613
|
-
attr: {
|
614
|
-
d: 'M{1} {2} L{3} {4}'.format(
|
615
|
-
startX,
|
616
|
-
y,
|
617
|
-
endX,
|
618
|
-
y + 0.001
|
619
|
-
),
|
620
|
-
stroke: prop.yaxisColor,
|
621
|
-
'stroke-width': typeof prop.yaxisLinewidth === 'number' ? prop.yaxisLinewidth : 1,
|
622
|
-
'shape-rendering': "crispEdges"
|
623
|
-
}
|
624
|
-
});
|
625
|
-
|
626
|
-
y += height;
|
627
|
-
}
|
628
|
-
|
629
|
-
|
630
|
-
// Draw an extra tick if the X axis position is not zero or
|
631
|
-
// if the xaxis is not being shown
|
632
|
-
if (prop.xaxis === false) {
|
633
|
-
|
634
|
-
if (obj.type === 'hbar' && prop.xaxisMin <= 0 && prop.xaxisMax < 0) {
|
635
|
-
var startX = obj.getXCoord(prop.xaxisMax);
|
636
|
-
var endX = obj.getXCoord(prop.xaxisMax) + prop.yaxisTickmarksLength;
|
637
|
-
|
638
|
-
} else {
|
639
|
-
var startX = obj.getXCoord(0) - prop.yaxisTickmarksLength;
|
640
|
-
var endX = obj.getXCoord(0) + (prop.xaxisMin < 0 ? prop.yaxisTickmarksLength : 0);
|
641
|
-
}
|
642
|
-
|
643
|
-
var axis = RG.SVG.create({
|
644
|
-
svg: obj.svg,
|
645
|
-
parent: obj.svg.all,
|
646
|
-
type: 'path',
|
647
|
-
attr: {
|
648
|
-
d: 'M{1} {2} L{3} {4}'.format(
|
649
|
-
startX,
|
650
|
-
obj.height - prop.gutterBottom - parseFloat(prop.vmarginBottom),
|
651
|
-
|
652
|
-
endX,
|
653
|
-
obj.height - prop.gutterBottom - parseFloat(prop.vmarginBottom) - 0.001
|
654
|
-
),
|
655
|
-
stroke: obj.properties.yaxisColor,
|
656
|
-
'stroke-width': typeof prop.yaxisLinewidth === 'number' ? prop.yaxisLinewidth : 1,
|
657
|
-
'shape-rendering': "crispEdges"
|
658
|
-
}
|
659
|
-
});
|
660
|
-
}
|
661
|
-
}
|
662
|
-
|
663
|
-
//
|
664
|
-
// Bar, Line etc types of chart
|
665
|
-
//
|
666
|
-
} else {
|
667
|
-
|
668
|
-
var height = obj.graphHeight / prop.yaxisLabelsCount,
|
669
|
-
y = prop.gutterTop,
|
670
|
-
len = prop.yaxisLabelsCount,
|
671
|
-
startX = prop.gutterLeft,
|
672
|
-
endX = prop.gutterLeft - prop.yaxisTickmarksLength;
|
673
|
-
|
674
|
-
//
|
675
|
-
// Draw the tickmarks
|
676
|
-
//
|
677
|
-
if (prop.yaxisTickmarks) {
|
678
|
-
for (var i=0; i<len; ++i) {
|
679
|
-
|
680
|
-
// Draw the axis
|
681
|
-
var axis = RG.SVG.create({
|
682
|
-
svg: obj.svg,
|
683
|
-
parent: obj.svg.all,
|
684
|
-
type: 'path',
|
685
|
-
attr: {
|
686
|
-
d: 'M{1} {2} L{3} {4}'.format(
|
687
|
-
startX,
|
688
|
-
y,
|
689
|
-
endX,
|
690
|
-
y + 0.001
|
691
|
-
),
|
692
|
-
stroke: prop.yaxisColor,
|
693
|
-
'stroke-width': typeof prop.yaxisLinewidth === 'number' ? prop.yaxisLinewidth : 1,
|
694
|
-
'shape-rendering': "crispEdges"
|
695
|
-
}
|
696
|
-
});
|
697
|
-
|
698
|
-
y += height;
|
699
|
-
}
|
700
|
-
|
701
|
-
|
702
|
-
// Draw an extra tick if the X axis position is not zero or
|
703
|
-
//if the xaxis is not being shown
|
704
|
-
if ( (prop.yaxisMin !== 0 || prop.xaxis === false)
|
705
|
-
&& !(obj.scale.min > 0 && obj.scale.max > 0) ) {
|
706
|
-
|
707
|
-
|
708
|
-
var axis = RG.SVG.create({
|
709
|
-
svg: obj.svg,
|
710
|
-
parent: obj.svg.all,
|
711
|
-
type: 'path',
|
712
|
-
attr: {
|
713
|
-
d: 'M{1} {2} L{3} {4}'.format(
|
714
|
-
prop.gutterLeft - prop.yaxisTickmarksLength,
|
715
|
-
obj.height - prop.gutterBottom,
|
716
|
-
prop.gutterLeft,
|
717
|
-
obj.height - prop.gutterBottom - 0.001
|
718
|
-
),
|
719
|
-
stroke: prop.yaxisColor,
|
720
|
-
'stroke-width': typeof prop.yaxisLinewidth === 'number' ? prop.yaxisLinewidth : 1,
|
721
|
-
'shape-rendering': "crispEdges"
|
722
|
-
}
|
723
|
-
});
|
724
|
-
}
|
725
|
-
}
|
726
|
-
}
|
727
|
-
}
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
//
|
735
|
-
// Draw the Y axis labels
|
736
|
-
//
|
737
|
-
if (prop.yaxisScale) {
|
738
|
-
|
739
|
-
var segment = (obj.height - prop.gutterTop - prop.gutterBottom) / prop.yaxisLabelsCount;
|
740
|
-
|
741
|
-
for (var i=0; i<obj.scale.labels.length; ++i) {
|
742
|
-
|
743
|
-
var y = obj.height - prop.gutterBottom - (segment * i) - segment;
|
744
|
-
|
745
|
-
RG.SVG.text({
|
746
|
-
object: obj,
|
747
|
-
parent: obj.svg.all,
|
748
|
-
text: obj.scale.labels[i],
|
749
|
-
x: prop.gutterLeft - 7 - (prop.yaxis ? (prop.yaxisTickmarksLength - 3) : 0) + prop.yaxisLabelsOffsetx,
|
750
|
-
y: y + prop.yaxisLabelsOffsety,
|
751
|
-
halign: 'right',
|
752
|
-
valign: 'center',
|
753
|
-
font: prop.yaxisTextFont || prop.textFont,
|
754
|
-
size: prop.yaxisTextSize || (typeof prop.textSize === 'number' ? prop.textSize + 'pt' : prop.textSize),
|
755
|
-
bold: prop.yaxisTextBold || prop.textBold,
|
756
|
-
italic: prop.yaxisTextItalic || prop.textItalic,
|
757
|
-
color: prop.yaxisTextColor || prop.textColor
|
758
|
-
});
|
759
|
-
}
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
//
|
765
|
-
// Add the minimum label
|
766
|
-
//
|
767
|
-
var y = obj.height - prop.gutterBottom,
|
768
|
-
str = (prop.yaxisUnitsPre + prop.yaxisMin.toFixed(prop.yaxisDecimals).replace(/\./, prop.yaxisPoint) + prop.yaxisUnitsPost);
|
769
|
-
|
770
|
-
var text = RG.SVG.text({
|
771
|
-
object: obj,
|
772
|
-
parent: obj.svg.all,
|
773
|
-
text: typeof prop.yaxisFormatter === 'function' ? (prop.yaxisFormatter)(this, prop.yaxisMin) : str,
|
774
|
-
x: prop.gutterLeft - 7 - (prop.yaxis ? (prop.yaxisTickmarksLength - 3) : 0) + prop.yaxisLabelsOffsetx,
|
775
|
-
y: y + prop.yaxisLabelsOffsety,
|
776
|
-
halign: 'right',
|
777
|
-
valign: 'center',
|
778
|
-
font: prop.yaxisTextFont || prop.textFont,
|
779
|
-
size: prop.yaxisTextSize || (typeof prop.textSize === 'number' ? prop.textSize + 'pt' : prop.textSize),
|
780
|
-
bold: prop.yaxisTextBold || prop.textBold,
|
781
|
-
italic: prop.yaxisTextItalic || prop.textItalic,
|
782
|
-
color: prop.yaxisTextColor || prop.textColor
|
783
|
-
});
|
784
|
-
|
785
|
-
|
786
|
-
//
|
787
|
-
// Draw Y axis labels (eg when specific labels are defined or
|
788
|
-
//the chart is an HBar
|
789
|
-
//
|
790
|
-
} else if (prop.yaxisLabels && prop.yaxisLabels.length) {
|
791
|
-
|
792
|
-
for (var i=0; i<prop.yaxisLabels.length; ++i) {
|
793
|
-
|
794
|
-
var segment = (obj.graphHeight - (prop.vmarginTop || 0) - (prop.vmarginBottom || 0) ) / prop.yaxisLabels.length,
|
795
|
-
y = prop.gutterTop + (prop.vmarginTop || 0) + (segment * i) + (segment / 2) + prop.yaxisLabelsOffsety,
|
796
|
-
x = prop.gutterLeft - 7 /*- (prop.yaxis ? (prop.yaxisTickmarksLength) : 0)*/ - (prop.yaxisLinewidth || 1) + prop.yaxisLabelsOffsetx,
|
797
|
-
halign = 'right';
|
798
|
-
|
799
|
-
// HBar labels
|
800
|
-
if (obj.type === 'hbar' && obj.scale.min < obj.scale.max && obj.scale.max <= 0) {
|
801
|
-
halign = 'left';
|
802
|
-
x = obj.width - prop.gutterRight + 7 + prop.yaxisLabelsOffsetx;
|
803
|
-
|
804
|
-
// HBar labels
|
805
|
-
} else if (obj.type === 'hbar' && !prop.yaxisLabelsSpecific) {
|
806
|
-
var segment = (obj.graphHeight - (prop.vmarginTop || 0) - (prop.vmarginBottom || 0) ) / (prop.yaxisLabels.length);
|
807
|
-
y = prop.gutterTop + (prop.vmarginTop || 0) + (segment * i) + (segment / 2) + prop.yaxisLabelsOffsetx;
|
808
|
-
|
809
|
-
// Specific scale
|
810
|
-
} else {
|
811
|
-
var segment = (obj.graphHeight - (prop.vmarginTop || 0) - (prop.vmarginBottom || 0) ) / (prop.yaxisLabels.length - 1);
|
812
|
-
y = obj.height - prop.gutterBottom - (segment * i) + prop.yaxisLabelsOffsetx;
|
813
|
-
}
|
814
|
-
|
815
|
-
var text = RG.SVG.text({
|
816
|
-
object: obj,
|
817
|
-
parent: obj.svg.all,
|
818
|
-
text: prop.yaxisLabels[i] ? prop.yaxisLabels[i] : '',
|
819
|
-
x: x,
|
820
|
-
y: y,
|
821
|
-
halign: halign,
|
822
|
-
valign: 'center',
|
823
|
-
font: prop.yaxisTextFont || prop.textFont,
|
824
|
-
size: prop.yaxisTextSize || (typeof prop.textSize === 'number' ? prop.textSize + 'pt' : prop.textSize),
|
825
|
-
bold: prop.yaxisTextBold || prop.textBold,
|
826
|
-
italic: prop.yaxisTextItalic || prop.textItalic,
|
827
|
-
color: prop.yaxisTextColor || prop.textColor
|
828
|
-
});
|
829
|
-
}
|
830
|
-
}
|
831
|
-
};
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
//
|
841
|
-
// Draws the background
|
842
|
-
//
|
843
|
-
//@param The chart object
|
844
|
-
//
|
845
|
-
RG.SVG.drawBackground = function (obj)
|
846
|
-
{
|
847
|
-
var prop = obj.properties;
|
848
|
-
|
849
|
-
// Set these properties so that if it doesn't exist things don't fail
|
850
|
-
if (typeof prop.variant3dOffsetx !== 'number') prop.variant3dOffsetx = 0;
|
851
|
-
if (typeof prop.variant3dOffsety !== 'number') prop.variant3dOffsety = 0;
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
if (prop.backgroundColor) {
|
857
|
-
RG.SVG.create({
|
858
|
-
svg: obj.svg,
|
859
|
-
parent: obj.svg.all,
|
860
|
-
type: 'rect',
|
861
|
-
attr: {
|
862
|
-
x: -1 + prop.variant3dOffsetx,
|
863
|
-
y: -1 - prop.variant3dOffsety,
|
864
|
-
width: parseFloat(obj.svg.getAttribute('width')) + 2,
|
865
|
-
height: parseFloat(obj.svg.getAttribute('height')) + 2,
|
866
|
-
fill: prop.backgroundColor
|
867
|
-
}
|
868
|
-
});
|
869
|
-
}
|
870
|
-
|
871
|
-
// Render a background image
|
872
|
-
// <image xlink:href="firefox.jpg" x="0" y="0" height="50px" width="50px"/>
|
873
|
-
if (prop.backgroundImage) {
|
874
|
-
|
875
|
-
var attr = {
|
876
|
-
'xlink:href': prop.backgroundImage,
|
877
|
-
//preserveAspectRatio: 'xMidYMid slice',
|
878
|
-
preserveAspectRatio: prop.backgroundImageAspect || 'none',
|
879
|
-
x: prop.gutterLeft,
|
880
|
-
y: prop.gutterTop
|
881
|
-
};
|
882
|
-
|
883
|
-
if (prop.backgroundImageStretch) {
|
884
|
-
|
885
|
-
attr.x = prop.gutterLeft + prop.variant3dOffsetx;
|
886
|
-
attr.y = prop.gutterTop + prop.variant3dOffsety;
|
887
|
-
attr.width = obj.width - prop.gutterLeft - prop.gutterRight;
|
888
|
-
attr.height = obj.height - prop.gutterTop - prop.gutterBottom;
|
889
|
-
|
890
|
-
} else {
|
891
|
-
|
892
|
-
if (typeof prop.backgroundImageX === 'number') {
|
893
|
-
attr.x = prop.backgroundImageX + prop.variant3dOffsetx;
|
894
|
-
}
|
895
|
-
|
896
|
-
if (typeof prop.backgroundImageY === 'number') {
|
897
|
-
attr.y = prop.backgroundImageY + prop.variant3dOffsety;
|
898
|
-
}
|
899
|
-
|
900
|
-
if (typeof prop.backgroundImageW === 'number') {
|
901
|
-
attr.width = prop.backgroundImageW;
|
902
|
-
}
|
903
|
-
|
904
|
-
if (typeof prop.backgroundImageH === 'number') {
|
905
|
-
attr.height = prop.backgroundImageH;
|
906
|
-
}
|
907
|
-
}
|
908
|
-
|
909
|
-
//
|
910
|
-
// Account for the chart being 3d
|
911
|
-
//
|
912
|
-
if (prop.variant === '3d') {
|
913
|
-
attr.x += prop.variant3dOffsetx;
|
914
|
-
attr.y -= prop.variant3dOffsety;
|
915
|
-
}
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
var img = RG.SVG.create({
|
920
|
-
svg: obj.svg,
|
921
|
-
parent: obj.svg.all,
|
922
|
-
type: 'image',
|
923
|
-
attr: attr,
|
924
|
-
style: {
|
925
|
-
opacity: typeof prop.backgroundImageOpacity === 'number' ? prop.backgroundImageOpacity : 1
|
926
|
-
}
|
927
|
-
});
|
928
|
-
}
|
929
|
-
|
930
|
-
if (prop .backgroundGrid) {
|
931
|
-
|
932
|
-
var parts = [];
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
// Add the horizontal lines to the path
|
937
|
-
if (prop.backgroundGridHlines) {
|
938
|
-
|
939
|
-
var count = typeof prop.backgroundGridHlinesCount === 'number' ? prop.backgroundGridHlinesCount : (obj.type === 'hbar' ? (prop.yaxisLabels.length || obj.data.length || 5) : prop.yaxisLabelsCount);
|
940
|
-
|
941
|
-
for (var i=0; i<count; ++i) {
|
942
|
-
|
943
|
-
parts.push('M{1} {2} L{3} {4}'.format(
|
944
|
-
prop.gutterLeft + prop.variant3dOffsetx,
|
945
|
-
prop.gutterTop + (obj.graphHeight / count) * i - prop.variant3dOffsety,
|
946
|
-
obj.width - prop.gutterRight + prop.variant3dOffsetx,
|
947
|
-
prop.gutterTop + (obj.graphHeight / count) * i - prop.variant3dOffsety
|
948
|
-
));
|
949
|
-
}
|
950
|
-
|
951
|
-
// Add an extra background grid line to the path - this its
|
952
|
-
// underneath the X axis and shows up if its not there.
|
953
|
-
parts.push('M{1} {2} L{3} {4}'.format(
|
954
|
-
prop.gutterLeft + prop.variant3dOffsetx,
|
955
|
-
obj.height - prop.gutterBottom - prop.variant3dOffsety,
|
956
|
-
obj.width - prop.gutterRight + prop.variant3dOffsetx,
|
957
|
-
obj.height - prop.gutterBottom - prop.variant3dOffsety
|
958
|
-
));
|
959
|
-
}
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
// Add the vertical lines to the path
|
964
|
-
if (prop.backgroundGridVlines) {
|
965
|
-
|
966
|
-
if (obj.type === 'line' && RG.SVG.isArray(obj.data[0])) {
|
967
|
-
var len = obj.data[0].length;
|
968
|
-
} else if (obj.type === 'hbar') {
|
969
|
-
var len = prop.xaxisLabelsCount || 10;
|
970
|
-
} else if (obj.type === 'scatter') {
|
971
|
-
var len = (prop.xaxisLabels && prop.xaxisLabels.length) || 10;
|
972
|
-
} else {
|
973
|
-
var len = obj.data.length;
|
974
|
-
}
|
975
|
-
|
976
|
-
var count = typeof prop.backgroundGridVlinesCount === 'number' ? prop.backgroundGridVlinesCount : len;
|
977
|
-
|
978
|
-
if (prop.xaxisLabelsPosition === 'edge') {
|
979
|
-
count--;
|
980
|
-
}
|
981
|
-
|
982
|
-
for (var i=0; i<=count; ++i) {
|
983
|
-
parts.push('M{1} {2} L{3} {4}'.format(
|
984
|
-
prop.gutterLeft + ((obj.graphWidth / count) * i) + prop.variant3dOffsetx,
|
985
|
-
prop.gutterTop - prop.variant3dOffsety,
|
986
|
-
prop.gutterLeft + ((obj.graphWidth / count) * i) + prop.variant3dOffsetx,
|
987
|
-
obj.height - prop.gutterBottom - prop.variant3dOffsety
|
988
|
-
));
|
989
|
-
}
|
990
|
-
}
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
// Add the box around the grid
|
997
|
-
if (prop.backgroundGridBorder) {
|
998
|
-
parts.push('M{1} {2} L{3} {4} L{5} {6} L{7} {8} z'.format(
|
999
|
-
|
1000
|
-
prop.gutterLeft + prop.variant3dOffsetx,
|
1001
|
-
prop.gutterTop - prop.variant3dOffsety,
|
1002
|
-
|
1003
|
-
obj.width - prop.gutterRight + prop.variant3dOffsetx,
|
1004
|
-
prop.gutterTop - prop.variant3dOffsety,
|
1005
|
-
|
1006
|
-
obj.width - prop.gutterRight + prop.variant3dOffsetx,
|
1007
|
-
obj.height - prop.gutterBottom - prop.variant3dOffsety,
|
1008
|
-
|
1009
|
-
prop.gutterLeft + prop.variant3dOffsetx,
|
1010
|
-
obj.height - prop.gutterBottom - prop.variant3dOffsety
|
1011
|
-
));
|
1012
|
-
}
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
// Now draw the path
|
1017
|
-
var grid = RG.SVG.create({
|
1018
|
-
svg: obj.svg,
|
1019
|
-
parent: obj.svg.all,
|
1020
|
-
type: 'path',
|
1021
|
-
attr: {
|
1022
|
-
d: parts.join(' '),
|
1023
|
-
stroke: prop.backgroundGridColor,
|
1024
|
-
fill: 'rgba(0,0,0,0)',
|
1025
|
-
'stroke-width': prop.backgroundGridLinewidth,
|
1026
|
-
'shape-rendering': "crispEdges"
|
1027
|
-
}
|
1028
|
-
});
|
1029
|
-
|
1030
|
-
}
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
// Draw the title and subtitle
|
1035
|
-
RG.SVG.drawTitle(obj);
|
1036
|
-
};
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
/**
|
1046
|
-
* Returns true/false as to whether the given variable is null or not
|
1047
|
-
*
|
1048
|
-
* @param mixed arg The argument to check
|
1049
|
-
*/
|
1050
|
-
RG.SVG.isNull = function (arg)
|
1051
|
-
{
|
1052
|
-
// must BE DOUBLE EQUALS - NOT TRIPLE
|
1053
|
-
if (arg == null || typeof arg === 'object' && !arg) {
|
1054
|
-
return true;
|
1055
|
-
}
|
1056
|
-
|
1057
|
-
return false;
|
1058
|
-
};
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
/**
|
1068
|
-
* Returns an appropriate scale. The return value is actualy an object consisting of:
|
1069
|
-
* scale.max
|
1070
|
-
* scale.min
|
1071
|
-
* scale.scale
|
1072
|
-
*
|
1073
|
-
* @param obj object The graph object
|
1074
|
-
* @param prop object An object consisting of configuration properties
|
1075
|
-
* @return object An object containg scale information
|
1076
|
-
*/
|
1077
|
-
RG.SVG.getScale = function (opt)
|
1078
|
-
{
|
1079
|
-
var obj = opt.object,
|
1080
|
-
prop = obj.properties,
|
1081
|
-
numlabels = opt.numlabels,
|
1082
|
-
unitsPre = opt.unitsPre,
|
1083
|
-
unitsPost = opt.unitsPost,
|
1084
|
-
max = Number(opt.max),
|
1085
|
-
min = Number(opt.min),
|
1086
|
-
strict = opt.strict,
|
1087
|
-
decimals = Number(opt.decimals),
|
1088
|
-
point = opt.point,
|
1089
|
-
thousand = opt.thousand,
|
1090
|
-
originalMax = max,
|
1091
|
-
round = opt.round,
|
1092
|
-
scale = {max:1,labels:[],values:[]},
|
1093
|
-
formatter = opt.formatter;
|
1094
|
-
|
1095
|
-
|
1096
|
-
/**
|
1097
|
-
* Special case for 0
|
1098
|
-
*
|
1099
|
-
* ** Must be first **
|
1100
|
-
*/
|
1101
|
-
|
1102
|
-
if (max === 0 && min === 0) {
|
1103
|
-
|
1104
|
-
var max = 1;
|
1105
|
-
|
1106
|
-
for (var i=0; i<numlabels; ++i) {
|
1107
|
-
|
1108
|
-
var label = ((((max - min) / numlabels) * (i + 1)) + min).toFixed(decimals);
|
1109
|
-
|
1110
|
-
scale.labels.push(unitsPre + label + unitsPost);
|
1111
|
-
scale.values.push(parseFloat(label))
|
1112
|
-
}
|
1113
|
-
|
1114
|
-
/**
|
1115
|
-
* Manually do decimals
|
1116
|
-
*/
|
1117
|
-
} else if (max <= 1 && !strict) {
|
1118
|
-
|
1119
|
-
var arr = [
|
1120
|
-
1,0.5,
|
1121
|
-
0.10,0.05,
|
1122
|
-
0.010,0.005,
|
1123
|
-
0.0010,0.0005,
|
1124
|
-
0.00010,0.00005,
|
1125
|
-
0.000010,0.000005,
|
1126
|
-
0.0000010,0.0000005,
|
1127
|
-
0.00000010,0.00000005,
|
1128
|
-
0.000000010,0.000000005,
|
1129
|
-
0.0000000010,0.0000000005,
|
1130
|
-
0.00000000010,0.00000000005,
|
1131
|
-
0.000000000010,0.000000000005,
|
1132
|
-
0.0000000000010,0.0000000000005
|
1133
|
-
], vals = [];
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
for (var i=0; i<arr.length; ++i) {
|
1138
|
-
if (max > arr[i]) {
|
1139
|
-
i--;
|
1140
|
-
break;
|
1141
|
-
}
|
1142
|
-
}
|
1143
|
-
|
1144
|
-
|
1145
|
-
scale.max = arr[i]
|
1146
|
-
scale.labels = [];
|
1147
|
-
scale.values = [];
|
1148
|
-
|
1149
|
-
|
1150
|
-
for (var j=0; j<numlabels; ++j) {
|
1151
|
-
|
1152
|
-
var value = ((((arr[i] - min) / numlabels) * (j + 1)) + min).toFixed(decimals);
|
1153
|
-
|
1154
|
-
scale.values.push(value);
|
1155
|
-
scale.labels.push(RG.SVG.numberFormat({
|
1156
|
-
object: obj,
|
1157
|
-
num: value,
|
1158
|
-
prepend: unitsPre,
|
1159
|
-
append: unitsPost,
|
1160
|
-
point: prop.yaxisPoint,
|
1161
|
-
thousand: prop.yaxisThousand,
|
1162
|
-
formatter: formatter
|
1163
|
-
}));
|
1164
|
-
}
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
} else if (!strict) {
|
1170
|
-
|
1171
|
-
/**
|
1172
|
-
* Now comes the scale handling for integer values
|
1173
|
-
*/
|
1174
|
-
|
1175
|
-
// This accomodates decimals by rounding the max up to the next integer
|
1176
|
-
max = ma.ceil(max);
|
1177
|
-
|
1178
|
-
var interval = ma.pow(10, ma.max(1, Number(String(Number(max) - Number(min)).length - 1)) );
|
1179
|
-
var topValue = interval;
|
1180
|
-
|
1181
|
-
while (topValue < max) {
|
1182
|
-
topValue += (interval / 2);
|
1183
|
-
}
|
1184
|
-
|
1185
|
-
// Handles cases where the max is (for example) 50.5
|
1186
|
-
if (Number(originalMax) > Number(topValue)) {
|
1187
|
-
topValue += (interval / 2);
|
1188
|
-
}
|
1189
|
-
|
1190
|
-
// Custom if the max is greater than 5 and less than 10
|
1191
|
-
if (max <= 10) {
|
1192
|
-
topValue = (Number(originalMax) <= 5 ? 5 : 10);
|
1193
|
-
}
|
1194
|
-
|
1195
|
-
|
1196
|
-
// Added 02/11/2010 to create "nicer" scales
|
1197
|
-
if (obj && typeof(round) == 'boolean' && round) {
|
1198
|
-
topValue = 10 * interval;
|
1199
|
-
}
|
1200
|
-
|
1201
|
-
scale.max = topValue;
|
1202
|
-
|
1203
|
-
|
1204
|
-
for (var i=0; i<numlabels; ++i) {
|
1205
|
-
|
1206
|
-
var label = RG.SVG.numberFormat({
|
1207
|
-
object: obj,
|
1208
|
-
num: ((((i+1) / numlabels) * (topValue - min)) + min).toFixed(decimals),
|
1209
|
-
prepend: unitsPre,
|
1210
|
-
append: unitsPost,
|
1211
|
-
point: point,
|
1212
|
-
thousand: thousand,
|
1213
|
-
formatter: formatter
|
1214
|
-
});
|
1215
|
-
|
1216
|
-
scale.labels.push(label);
|
1217
|
-
scale.values.push(((((i+1) / numlabels) * (topValue - min)) + min).toFixed(decimals));
|
1218
|
-
}
|
1219
|
-
|
1220
|
-
} else if (typeof max === 'number' && strict) {
|
1221
|
-
|
1222
|
-
/**
|
1223
|
-
* ymax is set and also strict
|
1224
|
-
*/
|
1225
|
-
for (var i=0; i<numlabels; ++i) {
|
1226
|
-
|
1227
|
-
scale.labels.push(RG.SVG.numberFormat({
|
1228
|
-
object: obj,
|
1229
|
-
formatter: formatter,
|
1230
|
-
num: ((((i+1) / numlabels) * (max - min)) + min).toFixed(decimals),
|
1231
|
-
prepend: unitsPre,
|
1232
|
-
append: unitsPost,
|
1233
|
-
point: point,
|
1234
|
-
thousand: thousand
|
1235
|
-
}));
|
1236
|
-
|
1237
|
-
|
1238
|
-
scale.values.push(
|
1239
|
-
((((i+1) / numlabels) * (max - min)) + min).toFixed(decimals)
|
1240
|
-
);
|
1241
|
-
}
|
1242
|
-
|
1243
|
-
// ???
|
1244
|
-
scale.max = max;
|
1245
|
-
}
|
1246
|
-
|
1247
|
-
|
1248
|
-
scale.unitsPre = unitsPre;
|
1249
|
-
scale.unitsPost = unitsPost;
|
1250
|
-
scale.point = point;
|
1251
|
-
scale.decimals = decimals;
|
1252
|
-
scale.thousand = thousand;
|
1253
|
-
scale.numlabels = numlabels;
|
1254
|
-
scale.round = Boolean(round);
|
1255
|
-
scale.min = min;
|
1256
|
-
|
1257
|
-
//
|
1258
|
-
// Convert all of the scale values to numbers
|
1259
|
-
//
|
1260
|
-
for (var i=0; i<scale.values.length; ++i) {
|
1261
|
-
scale.values[i] = parseFloat(scale.values[i]);
|
1262
|
-
}
|
1263
|
-
|
1264
|
-
return scale;
|
1265
|
-
};
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
/**
|
1275
|
-
* Pads/fills the array
|
1276
|
-
*
|
1277
|
-
* @param array arr The array
|
1278
|
-
* @param int len The length to pad the array to
|
1279
|
-
* @param mixed The value to use to pad the array (optional)
|
1280
|
-
*/
|
1281
|
-
RG.SVG.arrayFill =
|
1282
|
-
RG.SVG.arrayPad = function (opt)
|
1283
|
-
{
|
1284
|
-
var arr = opt.array,
|
1285
|
-
len = opt.length,
|
1286
|
-
value = (opt.value ? opt.value : null);
|
1287
|
-
|
1288
|
-
if (arr.length < len) {
|
1289
|
-
for (var i=arr.length; i<len; i+=1) {
|
1290
|
-
arr[i] = value;
|
1291
|
-
}
|
1292
|
-
}
|
1293
|
-
|
1294
|
-
return arr;
|
1295
|
-
};
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
|
1304
|
-
/**
|
1305
|
-
* An array sum function
|
1306
|
-
*
|
1307
|
-
* @param array arr The array to calculate the total of
|
1308
|
-
* @return int The summed total of the arrays elements
|
1309
|
-
*/
|
1310
|
-
RG.SVG.arraySum = function (arr)
|
1311
|
-
{
|
1312
|
-
// Allow integers
|
1313
|
-
if (typeof arr === 'number') {
|
1314
|
-
return arr;
|
1315
|
-
}
|
1316
|
-
|
1317
|
-
// Account for null
|
1318
|
-
if (RG.SVG.isNull(arr)) {
|
1319
|
-
return 0;
|
1320
|
-
}
|
1321
|
-
|
1322
|
-
var i, sum, len = arr.length;
|
1323
|
-
|
1324
|
-
for(i=0,sum=0;i<len;sum+=arr[i++]);
|
1325
|
-
|
1326
|
-
return sum;
|
1327
|
-
};
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
/**
|
1337
|
-
* Returns the maximum numeric value which is in an array. This function IS NOT
|
1338
|
-
* recursive
|
1339
|
-
*
|
1340
|
-
* @param array arr The array (can also be a number, in which case it's returned as-is)
|
1341
|
-
* @param int Whether to ignore signs (ie negative/positive)
|
1342
|
-
* @return int The maximum value in the array
|
1343
|
-
*/
|
1344
|
-
RG.SVG.arrayMax = function (arr)
|
1345
|
-
{
|
1346
|
-
var max = null
|
1347
|
-
|
1348
|
-
if (typeof arr === 'number') {
|
1349
|
-
return arr;
|
1350
|
-
}
|
1351
|
-
|
1352
|
-
if (RG.SVG.isNull(arr)) {
|
1353
|
-
return 0;
|
1354
|
-
}
|
1355
|
-
|
1356
|
-
for (var i=0,len=arr.length; i<len; ++i) {
|
1357
|
-
if (typeof arr[i] === 'number') {
|
1358
|
-
|
1359
|
-
var val = arguments[1] ? ma.abs(arr[i]) : arr[i];
|
1360
|
-
|
1361
|
-
if (typeof max === 'number') {
|
1362
|
-
max = ma.max(max, val);
|
1363
|
-
} else {
|
1364
|
-
max = val;
|
1365
|
-
}
|
1366
|
-
}
|
1367
|
-
}
|
1368
|
-
|
1369
|
-
return max;
|
1370
|
-
};
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
/**
|
1380
|
-
* Returns the minimum numeric value which is in an array
|
1381
|
-
*
|
1382
|
-
* @param array arr The array (can also be a number, in which case it's returned as-is)
|
1383
|
-
* @param int Whether to ignore signs (ie negative/positive)
|
1384
|
-
* @return int The minimum value in the array
|
1385
|
-
*/
|
1386
|
-
RG.SVG.arrayMin = function (arr)
|
1387
|
-
{
|
1388
|
-
var max = null,
|
1389
|
-
min = null,
|
1390
|
-
ma = Math;
|
1391
|
-
|
1392
|
-
if (typeof arr === 'number') {
|
1393
|
-
return arr;
|
1394
|
-
}
|
1395
|
-
|
1396
|
-
if (RG.SVG.isNull(arr)) {
|
1397
|
-
return 0;
|
1398
|
-
}
|
1399
|
-
|
1400
|
-
for (var i=0,len=arr.length; i<len; ++i) {
|
1401
|
-
if (typeof arr[i] === 'number') {
|
1402
|
-
|
1403
|
-
var val = arguments[1] ? ma.abs(arr[i]) : arr[i];
|
1404
|
-
|
1405
|
-
if (typeof min === 'number') {
|
1406
|
-
min = ma.min(min, val);
|
1407
|
-
} else {
|
1408
|
-
min = val;
|
1409
|
-
}
|
1410
|
-
}
|
1411
|
-
}
|
1412
|
-
|
1413
|
-
return min;
|
1414
|
-
};
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
/**
|
1424
|
-
* Returns the maximum value which is in an array
|
1425
|
-
*
|
1426
|
-
* @param array arr The array
|
1427
|
-
* @param int len The length to pad the array to
|
1428
|
-
* @param mixed The value to use to pad the array (optional)
|
1429
|
-
*/
|
1430
|
-
RG.SVG.arrayPad = function (arr, len)
|
1431
|
-
{
|
1432
|
-
if (arr.length < len) {
|
1433
|
-
var val = arguments[2] ? arguments[2] : null;
|
1434
|
-
|
1435
|
-
for (var i=arr.length; i<len; i+=1) {
|
1436
|
-
arr[i] = val;
|
1437
|
-
}
|
1438
|
-
}
|
1439
|
-
|
1440
|
-
return arr;
|
1441
|
-
};
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
/**
|
1451
|
-
* An array sum function
|
1452
|
-
*
|
1453
|
-
* @param array arr The array to calculate the total of
|
1454
|
-
* @return int The summed total of the arrays elements
|
1455
|
-
*/
|
1456
|
-
RG.SVG.arraySum = function (arr)
|
1457
|
-
{
|
1458
|
-
// Allow integers
|
1459
|
-
if (typeof arr === 'number') {
|
1460
|
-
return arr;
|
1461
|
-
}
|
1462
|
-
|
1463
|
-
// Account for null
|
1464
|
-
if (RG.SVG.isNull(arr)) {
|
1465
|
-
return 0;
|
1466
|
-
}
|
1467
|
-
|
1468
|
-
var i, sum, len = arr.length;
|
1469
|
-
|
1470
|
-
for(i=0,sum=0;i<len;sum+=arr[i++]);
|
1471
|
-
|
1472
|
-
return sum;
|
1473
|
-
};
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
/**
|
1483
|
-
* Takes any number of arguments and adds them to one big linear array
|
1484
|
-
* which is then returned
|
1485
|
-
*
|
1486
|
-
* @param ... mixed The data to linearise. You can strings, booleans, numbers or arrays
|
1487
|
-
*/
|
1488
|
-
RG.SVG.arrayLinearize = function ()
|
1489
|
-
{
|
1490
|
-
var arr = [],
|
1491
|
-
args = arguments
|
1492
|
-
|
1493
|
-
for (var i=0,len=args.length; i<len; ++i) {
|
1494
|
-
|
1495
|
-
if (typeof args[i] === 'object' && args[i]) {
|
1496
|
-
for (var j=0,len2=args[i].length; j<len2; ++j) {
|
1497
|
-
var sub = RG.SVG.arrayLinearize(args[i][j]);
|
1498
|
-
|
1499
|
-
for (var k=0,len3=sub.length; k<len3; ++k) {
|
1500
|
-
arr.push(sub[k]);
|
1501
|
-
}
|
1502
|
-
}
|
1503
|
-
} else {
|
1504
|
-
arr.push(args[i]);
|
1505
|
-
}
|
1506
|
-
}
|
1507
|
-
|
1508
|
-
return arr;
|
1509
|
-
};
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
/**
|
1519
|
-
* Takes one off the front of the given array and returns the new array.
|
1520
|
-
*
|
1521
|
-
* @param array arr The array from which to take one off the front of array
|
1522
|
-
*
|
1523
|
-
* @return array The new array
|
1524
|
-
*/
|
1525
|
-
RG.SVG.arrayShift = function(arr)
|
1526
|
-
{
|
1527
|
-
var ret = [];
|
1528
|
-
|
1529
|
-
for(var i=1,len=arr.length; i<len; ++i) {
|
1530
|
-
ret.push(arr[i]);
|
1531
|
-
}
|
1532
|
-
|
1533
|
-
return ret;
|
1534
|
-
};
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
/**
|
1544
|
-
* Reverses the order of an array
|
1545
|
-
*
|
1546
|
-
* @param array arr The array to reverse
|
1547
|
-
*/
|
1548
|
-
RG.SVG.arrayReverse = function (arr)
|
1549
|
-
{
|
1550
|
-
if (!arr) {
|
1551
|
-
return;
|
1552
|
-
}
|
1553
|
-
|
1554
|
-
var newarr=[];
|
1555
|
-
|
1556
|
-
for(var i=arr.length - 1; i>=0; i-=1) {
|
1557
|
-
newarr.push(arr[i]);
|
1558
|
-
}
|
1559
|
-
|
1560
|
-
return newarr;
|
1561
|
-
};
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
/**
|
1571
|
-
* Makes a clone of an object
|
1572
|
-
*
|
1573
|
-
* @param obj val The object to clone
|
1574
|
-
*/
|
1575
|
-
RG.SVG.arrayClone = function (obj)
|
1576
|
-
{
|
1577
|
-
if(obj === null || typeof obj !== 'object') {
|
1578
|
-
return obj;
|
1579
|
-
}
|
1580
|
-
|
1581
|
-
if (RG.SVG.isArray(obj)) {
|
1582
|
-
|
1583
|
-
var temp = [];
|
1584
|
-
|
1585
|
-
for (var i=0,len=obj.length;i<len; ++i) {
|
1586
|
-
|
1587
|
-
if (typeof obj[i] === 'number') {
|
1588
|
-
temp[i] = (function (arg) {return Number(arg);})(obj[i]);
|
1589
|
-
|
1590
|
-
} else if (typeof obj[i] === 'string') {
|
1591
|
-
temp[i] = (function (arg) {return String(arg);})(obj[i]);
|
1592
|
-
|
1593
|
-
} else if (typeof obj[i] === 'function') {
|
1594
|
-
temp[i] = obj[i];
|
1595
|
-
|
1596
|
-
} else {
|
1597
|
-
temp[i] = RG.SVG.arrayClone(obj[i]);
|
1598
|
-
}
|
1599
|
-
}
|
1600
|
-
} else if (typeof obj === 'object') {
|
1601
|
-
|
1602
|
-
var temp = {};
|
1603
|
-
|
1604
|
-
for (var i in obj) {
|
1605
|
-
if (typeof i === 'string') {
|
1606
|
-
temp[i] = obj[i];
|
1607
|
-
}
|
1608
|
-
}
|
1609
|
-
}
|
1610
|
-
|
1611
|
-
return temp;
|
1612
|
-
};
|
1613
|
-
|
1614
|
-
|
1615
|
-
|
1616
|
-
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1620
|
-
|
1621
|
-
//
|
1622
|
-
// Converts an the truthy values to falsey values and vice-versa
|
1623
|
-
//
|
1624
|
-
RG.SVG.arrayInvert = function (arr)
|
1625
|
-
{
|
1626
|
-
for (var i=0,len=arr.length; i<len; ++i) {
|
1627
|
-
arr[i] = !arr[i];
|
1628
|
-
}
|
1629
|
-
|
1630
|
-
return arr;
|
1631
|
-
};
|
1632
|
-
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
//
|
1641
|
-
// An array_trim function that removes the empty elements off
|
1642
|
-
//both ends
|
1643
|
-
//
|
1644
|
-
RG.SVG.arrayTrim = function (arr)
|
1645
|
-
{
|
1646
|
-
var out = [], content = false;
|
1647
|
-
|
1648
|
-
// Trim the start
|
1649
|
-
for (var i=0; i<arr.length; i++) {
|
1650
|
-
|
1651
|
-
if (arr[i]) {
|
1652
|
-
content = true;
|
1653
|
-
}
|
1654
|
-
|
1655
|
-
if (content) {
|
1656
|
-
out.push(arr[i]);
|
1657
|
-
}
|
1658
|
-
}
|
1659
|
-
|
1660
|
-
// Reverse the array and trim the start again
|
1661
|
-
out = RG.SVG.arrayReverse(out);
|
1662
|
-
|
1663
|
-
var out2 = [], content = false ;
|
1664
|
-
for (var i=0; i<out.length; i++) {
|
1665
|
-
|
1666
|
-
if (out[i]) {
|
1667
|
-
content = true;
|
1668
|
-
}
|
1669
|
-
|
1670
|
-
if (content) {
|
1671
|
-
out2.push(out[i]);
|
1672
|
-
}
|
1673
|
-
}
|
1674
|
-
|
1675
|
-
// Now reverse the array and return it
|
1676
|
-
out2 = RG.SVG.arrayReverse(out2);
|
1677
|
-
|
1678
|
-
return out2;
|
1679
|
-
};
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
/**
|
1689
|
-
* Determines if the given object is an array or not
|
1690
|
-
*
|
1691
|
-
* @param mixed obj The variable to test
|
1692
|
-
*/
|
1693
|
-
RG.SVG.isArray = function (obj)
|
1694
|
-
{
|
1695
|
-
if (obj && obj.constructor) {
|
1696
|
-
var pos = obj.constructor.toString().indexOf('Array');
|
1697
|
-
} else {
|
1698
|
-
return false;
|
1699
|
-
}
|
1700
|
-
|
1701
|
-
return obj != null &&
|
1702
|
-
typeof pos === 'number' &&
|
1703
|
-
pos > 0 &&
|
1704
|
-
pos < 20;
|
1705
|
-
};
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
/**
|
1715
|
-
* Returns the absolute value of a number. You can also pass in an
|
1716
|
-
* array and it will run the abs() function on each element. It
|
1717
|
-
* operates recursively so sub-arrays are also traversed.
|
1718
|
-
*
|
1719
|
-
* @param array arr The number or array to work on
|
1720
|
-
*/
|
1721
|
-
RG.SVG.abs = function (value)
|
1722
|
-
{
|
1723
|
-
if (typeof value === 'string') {
|
1724
|
-
value = parseFloat(value) || 0;
|
1725
|
-
}
|
1726
|
-
|
1727
|
-
if (typeof value === 'number') {
|
1728
|
-
return ma.abs(value);
|
1729
|
-
}
|
1730
|
-
|
1731
|
-
if (typeof value === 'object') {
|
1732
|
-
for (i in value) {
|
1733
|
-
if ( typeof i === 'string'
|
1734
|
-
|| typeof i === 'number'
|
1735
|
-
|| typeof i === 'object') {
|
1736
|
-
|
1737
|
-
value[i] = RG.SVG.abs(value[i]);
|
1738
|
-
}
|
1739
|
-
}
|
1740
|
-
|
1741
|
-
return value;
|
1742
|
-
}
|
1743
|
-
|
1744
|
-
return 0;
|
1745
|
-
};
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
1749
|
-
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1754
|
-
//
|
1755
|
-
// Formats a number with thousand seperators so it's easier to read
|
1756
|
-
//
|
1757
|
-
// @param opt object The options to the function
|
1758
|
-
//
|
1759
|
-
RG.SVG.numberFormat = function (opt)
|
1760
|
-
{
|
1761
|
-
var obj = opt.object,
|
1762
|
-
prepend = opt.prepend ? String(opt.prepend) : '',
|
1763
|
-
append = opt.append ? String(opt.append) : '',
|
1764
|
-
output = '',
|
1765
|
-
decimal_seperator = typeof opt.point === 'string' ? opt.point : '.',
|
1766
|
-
thousand_seperator = typeof opt.thousand === 'string' ? opt.thousand : ',',
|
1767
|
-
num = opt.num;
|
1768
|
-
|
1769
|
-
RegExp.$1 = '';
|
1770
|
-
|
1771
|
-
if (typeof opt.formatter === 'function') {
|
1772
|
-
return opt.formatter(obj, num);
|
1773
|
-
}
|
1774
|
-
|
1775
|
-
// Ignore the preformatted version of "1e-2"
|
1776
|
-
if (String(num).indexOf('e') > 0) {
|
1777
|
-
return String(prepend + String(num) + append);
|
1778
|
-
}
|
1779
|
-
|
1780
|
-
// We need then number as a string
|
1781
|
-
num = String(num);
|
1782
|
-
|
1783
|
-
// Take off the decimal part - we re-append it later
|
1784
|
-
if (num.indexOf('.') > 0) {
|
1785
|
-
var tmp = num;
|
1786
|
-
num = num.replace(/\.(.*)/, ''); // The front part of the number
|
1787
|
-
decimal = tmp.replace(/(.*)\.(.*)/, '$2'); // The decimal part of the number
|
1788
|
-
} else {
|
1789
|
-
decimal = '';
|
1790
|
-
}
|
1791
|
-
|
1792
|
-
// Thousand seperator
|
1793
|
-
//var seperator = arguments[1] ? String(arguments[1]) : ',';
|
1794
|
-
var seperator = thousand_seperator;
|
1795
|
-
|
1796
|
-
/**
|
1797
|
-
* Work backwards adding the thousand seperators
|
1798
|
-
*/
|
1799
|
-
var foundPoint;
|
1800
|
-
for (i=(num.length - 1),j=0; i>=0; j++,i--) {
|
1801
|
-
var character = num.charAt(i);
|
1802
|
-
|
1803
|
-
if ( j % 3 == 0 && j != 0) {
|
1804
|
-
output += seperator;
|
1805
|
-
}
|
1806
|
-
|
1807
|
-
/**
|
1808
|
-
* Build the output
|
1809
|
-
*/
|
1810
|
-
output += character;
|
1811
|
-
}
|
1812
|
-
|
1813
|
-
/**
|
1814
|
-
* Now need to reverse the string
|
1815
|
-
*/
|
1816
|
-
var rev = output;
|
1817
|
-
output = '';
|
1818
|
-
for (i=(rev.length - 1); i>=0; i--) {
|
1819
|
-
output += rev.charAt(i);
|
1820
|
-
}
|
1821
|
-
|
1822
|
-
// Tidy up
|
1823
|
-
//output = output.replace(/^-,/, '-');
|
1824
|
-
if (output.indexOf('-' + thousand_seperator) == 0) {
|
1825
|
-
output = '-' + output.substr(('-' + thousand_seperator).length);
|
1826
|
-
}
|
1827
|
-
|
1828
|
-
// Reappend the decimal
|
1829
|
-
if (decimal.length) {
|
1830
|
-
output = output + decimal_seperator + decimal;
|
1831
|
-
decimal = '';
|
1832
|
-
RegExp.$1 = '';
|
1833
|
-
}
|
1834
|
-
|
1835
|
-
// Minor bugette
|
1836
|
-
if (output.charAt(0) == '-') {
|
1837
|
-
output = output.replace(/-/, '');
|
1838
|
-
prepend = '-' + prepend;
|
1839
|
-
}
|
1840
|
-
|
1841
|
-
return prepend + output + append;
|
1842
|
-
};
|
1843
|
-
|
1844
|
-
|
1845
|
-
|
1846
|
-
|
1847
|
-
|
1848
|
-
|
1849
|
-
|
1850
|
-
|
1851
|
-
//
|
1852
|
-
// A function that adds text to the chart
|
1853
|
-
//
|
1854
|
-
RG.SVG.text = function (opt)
|
1855
|
-
{
|
1856
|
-
var obj = opt.object,
|
1857
|
-
parent = opt.parent || opt.object.svg.all,
|
1858
|
-
size = opt.size,
|
1859
|
-
bold = opt.bold,
|
1860
|
-
font = opt.font,
|
1861
|
-
italic = opt.italic,
|
1862
|
-
halign = opt.halign,
|
1863
|
-
valign = opt.valign,
|
1864
|
-
str = opt.text,
|
1865
|
-
x = opt.x,
|
1866
|
-
y = opt.y,
|
1867
|
-
color = opt.color ? opt.color : 'black',
|
1868
|
-
background = opt.background || null,
|
1869
|
-
padding = opt.padding || 0;
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
1873
|
-
|
1874
|
-
|
1875
|
-
// Horizontal alignment
|
1876
|
-
if (halign === 'right') {
|
1877
|
-
halign = 'end';
|
1878
|
-
} else if (halign === 'center' || halign === 'middle') {
|
1879
|
-
halign = 'middle';
|
1880
|
-
} else {
|
1881
|
-
halign = 'start';
|
1882
|
-
}
|
1883
|
-
|
1884
|
-
// Vertical alignment
|
1885
|
-
if (valign === 'top') {
|
1886
|
-
valign = 'hanging';
|
1887
|
-
} else if (valign === 'center' || valign === 'middle') {
|
1888
|
-
valign = 'central';
|
1889
|
-
valign = 'middle';
|
1890
|
-
} else {
|
1891
|
-
valign = 'bottom';
|
1892
|
-
}
|
1893
|
-
|
1894
|
-
|
1895
|
-
var text = RG.SVG.create({
|
1896
|
-
svg: obj.svg,
|
1897
|
-
parent: opt.parent,
|
1898
|
-
type: 'text',
|
1899
|
-
attr: {
|
1900
|
-
fill: color,
|
1901
|
-
x: x,
|
1902
|
-
y: y,
|
1903
|
-
'font-size': typeof size === 'number' ? size + 'pt' : size,
|
1904
|
-
'font-weight': bold ? 900 : 100,
|
1905
|
-
'font-family': font ? font : 'sans-serif',
|
1906
|
-
'font-style': italic ? 'italic' : 'normal',
|
1907
|
-
'text-anchor': halign,
|
1908
|
-
'dominant-baseline': valign
|
1909
|
-
}
|
1910
|
-
});
|
1911
|
-
|
1912
|
-
var textNode = document.createTextNode(str);
|
1913
|
-
text.appendChild(textNode);
|
1914
|
-
|
1915
|
-
|
1916
|
-
|
1917
|
-
//
|
1918
|
-
// Add a background color if specified
|
1919
|
-
//
|
1920
|
-
if (typeof background === 'string') {
|
1921
|
-
|
1922
|
-
var bbox = text.getBBox(),
|
1923
|
-
rect = RG.SVG.create({
|
1924
|
-
svg: obj.svg,
|
1925
|
-
parent: opt.parent,
|
1926
|
-
type: 'rect',
|
1927
|
-
attr: {
|
1928
|
-
x: bbox.x - padding,
|
1929
|
-
y: bbox.y - padding,
|
1930
|
-
width: bbox.width + (padding * 2),
|
1931
|
-
height: bbox.height + (padding * 2),
|
1932
|
-
fill: background
|
1933
|
-
}
|
1934
|
-
});
|
1935
|
-
|
1936
|
-
parent.insertBefore(rect, text);
|
1937
|
-
}
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1941
|
-
if (RG.SVG.ISIE && (valign === 'hanging') ) {
|
1942
|
-
text.setAttribute('y', y + (text.scrollHeight / 2));
|
1943
|
-
|
1944
|
-
} else if (RG.SVG.ISIE && valign === 'middle') {
|
1945
|
-
text.setAttribute('y', y + (text.scrollHeight / 3));
|
1946
|
-
}
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
if (RG.SVG.ISFF) {
|
1952
|
-
Y = y + (text.scrollHeight / 3);
|
1953
|
-
}
|
1954
|
-
|
1955
|
-
return text;
|
1956
|
-
};
|
1957
|
-
|
1958
|
-
|
1959
|
-
|
1960
|
-
|
1961
|
-
|
1962
|
-
|
1963
|
-
|
1964
|
-
|
1965
|
-
//
|
1966
|
-
// Creates a UID that is applied to the object
|
1967
|
-
//
|
1968
|
-
RG.SVG.createUID = function ()
|
1969
|
-
{
|
1970
|
-
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c)
|
1971
|
-
{
|
1972
|
-
var r = ma.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
|
1973
|
-
return v.toString(16);
|
1974
|
-
});
|
1975
|
-
};
|
1976
|
-
|
1977
|
-
|
1978
|
-
|
1979
|
-
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
1983
|
-
|
1984
|
-
//
|
1985
|
-
// Determines if the SVG DIV container is fixed
|
1986
|
-
//
|
1987
|
-
RG.SVG.isFixed = function (svg)
|
1988
|
-
{
|
1989
|
-
var obj = svg.parentNode,
|
1990
|
-
i = 0;
|
1991
|
-
|
1992
|
-
while (obj && obj.tagName.toLowerCase() != 'body' && i < 99) {
|
1993
|
-
|
1994
|
-
if (obj.style.position === 'fixed') {
|
1995
|
-
return obj;
|
1996
|
-
}
|
1997
|
-
|
1998
|
-
obj = obj.offsetParent;
|
1999
|
-
}
|
2000
|
-
|
2001
|
-
return false;
|
2002
|
-
};
|
2003
|
-
|
2004
|
-
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2008
|
-
|
2009
|
-
|
2010
|
-
|
2011
|
-
/**
|
2012
|
-
* Sets an object in the RGraph registry
|
2013
|
-
*
|
2014
|
-
* @param string name The name of the value to set
|
2015
|
-
*/
|
2016
|
-
RG.SVG.REG.set = function (name, value)
|
2017
|
-
{
|
2018
|
-
RG.SVG.REG.store[name] = value;
|
2019
|
-
|
2020
|
-
return value;
|
2021
|
-
};
|
2022
|
-
|
2023
|
-
|
2024
|
-
|
2025
|
-
|
2026
|
-
|
2027
|
-
|
2028
|
-
|
2029
|
-
|
2030
|
-
/**
|
2031
|
-
* Gets an object from the RGraph registry
|
2032
|
-
*
|
2033
|
-
* @param string name The name of the value to fetch
|
2034
|
-
*/
|
2035
|
-
RG.SVG.REG.get = function (name)
|
2036
|
-
{
|
2037
|
-
return RG.SVG.REG.store[name];
|
2038
|
-
};
|
2039
|
-
|
2040
|
-
|
2041
|
-
|
2042
|
-
|
2043
|
-
|
2044
|
-
|
2045
|
-
|
2046
|
-
|
2047
|
-
/**
|
2048
|
-
* Removes white-space from the start aqnd end of a string
|
2049
|
-
*
|
2050
|
-
* @param string str The string to trim
|
2051
|
-
*/
|
2052
|
-
RG.SVG.trim = function (str)
|
2053
|
-
{
|
2054
|
-
return RG.SVG.ltrim(RG.SVG.rtrim(str));
|
2055
|
-
};
|
2056
|
-
|
2057
|
-
|
2058
|
-
|
2059
|
-
|
2060
|
-
|
2061
|
-
|
2062
|
-
|
2063
|
-
|
2064
|
-
/**
|
2065
|
-
* Trims the white-space from the start of a string
|
2066
|
-
*
|
2067
|
-
* @param string str The string to trim
|
2068
|
-
*/
|
2069
|
-
RG.SVG.ltrim = function (str)
|
2070
|
-
{
|
2071
|
-
return str.replace(/^(\s|\0)+/, '');
|
2072
|
-
};
|
2073
|
-
|
2074
|
-
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2078
|
-
|
2079
|
-
|
2080
|
-
|
2081
|
-
/**
|
2082
|
-
* Trims the white-space off of the end of a string
|
2083
|
-
*
|
2084
|
-
* @param string str The string to trim
|
2085
|
-
*/
|
2086
|
-
RG.SVG.rtrim = function (str)
|
2087
|
-
{
|
2088
|
-
return str.replace(/(\s|\0)+$/, '');
|
2089
|
-
};
|
2090
|
-
|
2091
|
-
|
2092
|
-
|
2093
|
-
|
2094
|
-
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
2098
|
-
//
|
2099
|
-
// Hides the currently shown tooltip
|
2100
|
-
//
|
2101
|
-
RG.SVG.hideTooltip = function ()
|
2102
|
-
{
|
2103
|
-
var tooltip = RG.SVG.REG.get('tooltip');
|
2104
|
-
|
2105
|
-
if (tooltip && tooltip.parentNode /*&& (!uid || uid == tooltip.__canvas__.uid)*/) {
|
2106
|
-
tooltip.parentNode.removeChild(tooltip);
|
2107
|
-
tooltip.style.display = 'none';
|
2108
|
-
tooltip.style.visibility = 'hidden';
|
2109
|
-
RG.SVG.REG.set('tooltip', null);
|
2110
|
-
}
|
2111
|
-
|
2112
|
-
if (tooltip && tooltip.__object__) {
|
2113
|
-
RG.SVG.removeHighlight(tooltip.__object__);
|
2114
|
-
}
|
2115
|
-
};
|
2116
|
-
|
2117
|
-
|
2118
|
-
|
2119
|
-
|
2120
|
-
|
2121
|
-
|
2122
|
-
|
2123
|
-
|
2124
|
-
//
|
2125
|
-
// Creates a shadow
|
2126
|
-
//
|
2127
|
-
RG.SVG.setShadow = function (options)
|
2128
|
-
{
|
2129
|
-
var obj = options.object,
|
2130
|
-
offsetx = options.offsetx || 0,
|
2131
|
-
offsety = options.offsety || 0,
|
2132
|
-
blur = options.blur || 0,
|
2133
|
-
opacity = options.opacity || 0,
|
2134
|
-
id = options.id;
|
2135
|
-
|
2136
|
-
var filter = RG.SVG.create({
|
2137
|
-
svg: obj.svg,
|
2138
|
-
parent: obj.svg.defs,
|
2139
|
-
type: 'filter',
|
2140
|
-
attr: {
|
2141
|
-
id: id,
|
2142
|
-
width: "130%",
|
2143
|
-
height: "130%"
|
2144
|
-
}
|
2145
|
-
});
|
2146
|
-
|
2147
|
-
RG.SVG.create({
|
2148
|
-
svg: obj.svg,
|
2149
|
-
parent: filter,
|
2150
|
-
type: 'feOffset',
|
2151
|
-
attr: {
|
2152
|
-
result: 'offOut',
|
2153
|
-
'in': 'SourceGraphic',
|
2154
|
-
dx: offsetx,
|
2155
|
-
dy: offsety
|
2156
|
-
}
|
2157
|
-
});
|
2158
|
-
|
2159
|
-
RG.SVG.create({
|
2160
|
-
svg: obj.svg,
|
2161
|
-
parent: filter,
|
2162
|
-
type: 'feColorMatrix',
|
2163
|
-
attr: {
|
2164
|
-
result: 'matrixOut',
|
2165
|
-
'in': 'offOut',
|
2166
|
-
type: 'matrix',
|
2167
|
-
values: '0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 {1} 0'.format(
|
2168
|
-
opacity
|
2169
|
-
)
|
2170
|
-
}
|
2171
|
-
});
|
2172
|
-
|
2173
|
-
RG.SVG.create({
|
2174
|
-
svg: obj.svg,
|
2175
|
-
parent: filter,
|
2176
|
-
type: 'feGaussianBlur',
|
2177
|
-
attr: {
|
2178
|
-
result: 'blurOut',
|
2179
|
-
'in': 'matrixOut',
|
2180
|
-
stdDeviation: blur
|
2181
|
-
}
|
2182
|
-
});
|
2183
|
-
|
2184
|
-
RG.SVG.create({
|
2185
|
-
svg: obj.svg,
|
2186
|
-
parent: filter,
|
2187
|
-
type: 'feBlend',
|
2188
|
-
attr: {
|
2189
|
-
'in': 'SourceGraphic',
|
2190
|
-
'in2': 'blurOut',
|
2191
|
-
mode: 'normal'
|
2192
|
-
}
|
2193
|
-
});
|
2194
|
-
};
|
2195
|
-
|
2196
|
-
|
2197
|
-
|
2198
|
-
|
2199
|
-
|
2200
|
-
|
2201
|
-
|
2202
|
-
|
2203
|
-
/**
|
2204
|
-
* Takes a sequential index and returns the group/index variation of it. Eg if you have a
|
2205
|
-
* sequential index from a grouped bar chart this function can be used to convert that into
|
2206
|
-
* an appropriate group/index combination
|
2207
|
-
*
|
2208
|
-
* @param nindex number The sequential index
|
2209
|
-
* @param data array The original data (which is grouped)
|
2210
|
-
* @return The group/index information
|
2211
|
-
*/
|
2212
|
-
RG.SVG.sequentialIndexToGrouped = function (index, data)
|
2213
|
-
{
|
2214
|
-
var group = 0,
|
2215
|
-
grouped_index = 0;
|
2216
|
-
|
2217
|
-
while (--index >= 0) {
|
2218
|
-
|
2219
|
-
if (RG.SVG.isNull(data[group])) {
|
2220
|
-
group++;
|
2221
|
-
grouped_index = 0;
|
2222
|
-
continue;
|
2223
|
-
}
|
2224
|
-
|
2225
|
-
// Allow for numbers as well as arrays in the dataset
|
2226
|
-
if (typeof data[group] == 'number') {
|
2227
|
-
group++
|
2228
|
-
grouped_index = 0;
|
2229
|
-
continue;
|
2230
|
-
}
|
2231
|
-
|
2232
|
-
|
2233
|
-
grouped_index++;
|
2234
|
-
|
2235
|
-
if (grouped_index >= data[group].length) {
|
2236
|
-
group++;
|
2237
|
-
grouped_index = 0;
|
2238
|
-
}
|
2239
|
-
}
|
2240
|
-
|
2241
|
-
return [group, grouped_index];
|
2242
|
-
};
|
2243
|
-
|
2244
|
-
|
2245
|
-
|
2246
|
-
|
2247
|
-
|
2248
|
-
|
2249
|
-
|
2250
|
-
|
2251
|
-
//
|
2252
|
-
// This function converts coordinates into the type understood by
|
2253
|
-
// SVG for drawing arcs
|
2254
|
-
//
|
2255
|
-
RG.SVG.TRIG.toCartesian = function (options)
|
2256
|
-
{
|
2257
|
-
return {
|
2258
|
-
x: options.cx + (options.r * ma.cos(options.angle)),
|
2259
|
-
y: options.cy + (options.r * ma.sin(options.angle))
|
2260
|
-
};
|
2261
|
-
};
|
2262
|
-
|
2263
|
-
|
2264
|
-
|
2265
|
-
|
2266
|
-
|
2267
|
-
|
2268
|
-
|
2269
|
-
|
2270
|
-
//
|
2271
|
-
// Gets a path that is usable by the SVG A path command
|
2272
|
-
//
|
2273
|
-
// @patam object options The options/arg to the function
|
2274
|
-
//
|
2275
|
-
// NB ** Still used by the Pie chart and the semi-circular Meter **
|
2276
|
-
//
|
2277
|
-
RG.SVG.TRIG.getArcPath = function (options)
|
2278
|
-
{
|
2279
|
-
//
|
2280
|
-
// Make circles start at the top instead of the right hand side
|
2281
|
-
//
|
2282
|
-
options.start -= 1.57;
|
2283
|
-
options.end -= 1.57;
|
2284
|
-
|
2285
|
-
var start = RG.SVG.TRIG.toCartesian({
|
2286
|
-
cx: options.cx,
|
2287
|
-
cy: options.cy,
|
2288
|
-
r: options.r,
|
2289
|
-
angle: options.start}
|
2290
|
-
);
|
2291
|
-
|
2292
|
-
var end = RG.SVG.TRIG.toCartesian({
|
2293
|
-
cx: options.cx,
|
2294
|
-
cy: options.cy,
|
2295
|
-
r: options.r,
|
2296
|
-
angle: options.end
|
2297
|
-
});
|
2298
|
-
|
2299
|
-
var diff = options.end - options.start;
|
2300
|
-
|
2301
|
-
// Initial values
|
2302
|
-
var largeArc = '0';
|
2303
|
-
var sweep = '0';
|
2304
|
-
|
2305
|
-
if (options.anticlockwise && diff > 3.14) {
|
2306
|
-
largeArc = '0';
|
2307
|
-
sweep = '0';
|
2308
|
-
} else if (options.anticlockwise && diff <= 3.14) {
|
2309
|
-
largeArc = '1';
|
2310
|
-
sweep = '0';
|
2311
|
-
} else if (!options.anticlockwise && diff > 3.14) {
|
2312
|
-
largeArc = '1';
|
2313
|
-
sweep = '1';
|
2314
|
-
} else if (!options.anticlockwise && diff <= 3.14) {
|
2315
|
-
largeArc = '0';
|
2316
|
-
sweep = '1';
|
2317
|
-
}
|
2318
|
-
|
2319
|
-
if (options.start > options.end && options.anticlockwise && diff <= 3.14) {
|
2320
|
-
largeArc = '0';
|
2321
|
-
sweep = '0';
|
2322
|
-
}
|
2323
|
-
|
2324
|
-
if (options.start > options.end && options.anticlockwise && diff > 3.14) {
|
2325
|
-
largeArc = '1';
|
2326
|
-
sweep = '1';
|
2327
|
-
}
|
2328
|
-
|
2329
|
-
|
2330
|
-
if (typeof options.moveto === 'boolean' && options.moveto === false) {
|
2331
|
-
var d = [
|
2332
|
-
"A", options.r, options.r, 0, largeArc, sweep, end.x, end.y
|
2333
|
-
];
|
2334
|
-
} else {
|
2335
|
-
var d = [
|
2336
|
-
"M", start.x, start.y,
|
2337
|
-
"A", options.r, options.r, 0, largeArc, sweep, end.x, end.y
|
2338
|
-
];
|
2339
|
-
}
|
2340
|
-
|
2341
|
-
if (options.array === true) {
|
2342
|
-
return d;
|
2343
|
-
} else {
|
2344
|
-
return d.join(" ");
|
2345
|
-
}
|
2346
|
-
};
|
2347
|
-
|
2348
|
-
|
2349
|
-
|
2350
|
-
|
2351
|
-
|
2352
|
-
|
2353
|
-
|
2354
|
-
|
2355
|
-
//
|
2356
|
-
// Gets a path that is usable by the SVG A path command
|
2357
|
-
//
|
2358
|
-
// @patam object options The options/arg to the function
|
2359
|
-
//
|
2360
|
-
RG.SVG.TRIG.getArcPath2 = function (options)
|
2361
|
-
{
|
2362
|
-
//
|
2363
|
-
// Make circles start at the top instead of the right hand side
|
2364
|
-
//
|
2365
|
-
options.start -= 1.57;
|
2366
|
-
options.end -= 1.57;
|
2367
|
-
|
2368
|
-
var start = RG.SVG.TRIG.toCartesian({
|
2369
|
-
cx: options.cx,
|
2370
|
-
cy: options.cy,
|
2371
|
-
r: options.r,
|
2372
|
-
angle: options.start
|
2373
|
-
});
|
2374
|
-
|
2375
|
-
var end = RG.SVG.TRIG.toCartesian({
|
2376
|
-
cx: options.cx,
|
2377
|
-
cy: options.cy,
|
2378
|
-
r: options.r,
|
2379
|
-
angle: options.end
|
2380
|
-
});
|
2381
|
-
|
2382
|
-
var diff = ma.abs(options.end - options.start);
|
2383
|
-
|
2384
|
-
// Initial values
|
2385
|
-
var largeArc = '0';
|
2386
|
-
var sweep = '0';
|
2387
|
-
|
2388
|
-
//TODO Put various options here for the correct combination of flags to use
|
2389
|
-
if (!options.anticlockwise) {
|
2390
|
-
if (diff > RG.SVG.TRIG.PI) {
|
2391
|
-
largeArc = '1';
|
2392
|
-
sweep = '1';
|
2393
|
-
} else {
|
2394
|
-
largeArc = '0';
|
2395
|
-
sweep = '1';
|
2396
|
-
}
|
2397
|
-
} else {
|
2398
|
-
if (diff > RG.SVG.TRIG.PI) {
|
2399
|
-
largeArc = '1';
|
2400
|
-
sweep = '0';
|
2401
|
-
} else {
|
2402
|
-
largeArc = '0';
|
2403
|
-
sweep = '0';
|
2404
|
-
}
|
2405
|
-
}
|
2406
|
-
|
2407
|
-
if (typeof options.lineto === 'boolean' && options.lineto === false) {
|
2408
|
-
var d = [
|
2409
|
-
"M", start.x, start.y,
|
2410
|
-
"A", options.r, options.r, 0, largeArc, sweep, end.x, end.y
|
2411
|
-
];
|
2412
|
-
} else {
|
2413
|
-
var d = [
|
2414
|
-
"M", options.cx, options.cy,
|
2415
|
-
"L", start.x, start.y,
|
2416
|
-
"A", options.r, options.r, 0, largeArc, sweep, end.x, end.y
|
2417
|
-
];
|
2418
|
-
}
|
2419
|
-
|
2420
|
-
if (options.array === true) {
|
2421
|
-
return d;
|
2422
|
-
} else {
|
2423
|
-
return d.join(" ");
|
2424
|
-
}
|
2425
|
-
};
|
2426
|
-
|
2427
|
-
|
2428
|
-
|
2429
|
-
|
2430
|
-
|
2431
|
-
|
2432
|
-
|
2433
|
-
|
2434
|
-
//
|
2435
|
-
// Gets a path that is usable by the SVG A path command
|
2436
|
-
//
|
2437
|
-
// @patam object options The options/arg to the function
|
2438
|
-
//
|
2439
|
-
RG.SVG.TRIG.getArcPath3 = function (options)
|
2440
|
-
{
|
2441
|
-
//
|
2442
|
-
// Make circles start at the top instead of the right hand side
|
2443
|
-
//
|
2444
|
-
options.start -= 1.57;
|
2445
|
-
options.end -= 1.57;
|
2446
|
-
|
2447
|
-
var start = RG.SVG.TRIG.toCartesian({
|
2448
|
-
cx: options.cx,
|
2449
|
-
cy: options.cy,
|
2450
|
-
r: options.r,
|
2451
|
-
angle: options.start
|
2452
|
-
});
|
2453
|
-
|
2454
|
-
var end = RG.SVG.TRIG.toCartesian({
|
2455
|
-
cx: options.cx,
|
2456
|
-
cy: options.cy,
|
2457
|
-
r: options.r,
|
2458
|
-
angle: options.end
|
2459
|
-
});
|
2460
|
-
|
2461
|
-
var diff = ma.abs(options.end - options.start);
|
2462
|
-
|
2463
|
-
// Initial values
|
2464
|
-
var largeArc = '0';
|
2465
|
-
var sweep = '0';
|
2466
|
-
|
2467
|
-
//TODO Put various options here for the correct combination of flags to use
|
2468
|
-
if (!options.anticlockwise) {
|
2469
|
-
if (diff > RG.SVG.TRIG.PI) {
|
2470
|
-
largeArc = '1';
|
2471
|
-
sweep = '1';
|
2472
|
-
} else {
|
2473
|
-
largeArc = '0';
|
2474
|
-
sweep = '1';
|
2475
|
-
}
|
2476
|
-
} else {
|
2477
|
-
if (diff > RG.SVG.TRIG.PI) {
|
2478
|
-
largeArc = '1';
|
2479
|
-
sweep = '0';
|
2480
|
-
} else {
|
2481
|
-
largeArc = '0';
|
2482
|
-
sweep = '0';
|
2483
|
-
}
|
2484
|
-
}
|
2485
|
-
|
2486
|
-
if (typeof options.lineto === 'boolean' && options.lineto === false) {
|
2487
|
-
var d = [
|
2488
|
-
"M", start.x, start.y,
|
2489
|
-
"A", options.r, options.r, 0, largeArc, sweep, end.x, end.y
|
2490
|
-
];
|
2491
|
-
} else {
|
2492
|
-
var d = [
|
2493
|
-
"L", start.x, start.y,
|
2494
|
-
"A", options.r, options.r, 0, largeArc, sweep, end.x, end.y
|
2495
|
-
];
|
2496
|
-
}
|
2497
|
-
|
2498
|
-
if (options.array === true) {
|
2499
|
-
return d;
|
2500
|
-
} else {
|
2501
|
-
return d.join(" ");
|
2502
|
-
}
|
2503
|
-
};
|
2504
|
-
|
2505
|
-
|
2506
|
-
|
2507
|
-
|
2508
|
-
|
2509
|
-
|
2510
|
-
|
2511
|
-
|
2512
|
-
/**
|
2513
|
-
* This function gets the end point (X/Y coordinates) of a given radius.
|
2514
|
-
* You pass it the center X/Y and the radius and this function will return
|
2515
|
-
* the endpoint X/Y coordinates.
|
2516
|
-
*
|
2517
|
-
* @param number cx The center X coord
|
2518
|
-
* @param number cy The center Y coord
|
2519
|
-
* @param number r The lrngth of the radius
|
2520
|
-
*/
|
2521
|
-
RG.SVG.TRIG.getRadiusEndPoint = function (opt)
|
2522
|
-
{
|
2523
|
-
// Allow for two arguments style
|
2524
|
-
if (arguments.length === 1) {
|
2525
|
-
|
2526
|
-
var angle = opt.angle,
|
2527
|
-
r = opt.r;
|
2528
|
-
|
2529
|
-
} else if (arguments.length === 4) {
|
2530
|
-
|
2531
|
-
var angle = arguments[0],
|
2532
|
-
r = arguments[1];
|
2533
|
-
}
|
2534
|
-
|
2535
|
-
var x = ma.cos(angle) * r,
|
2536
|
-
y = ma.sin(angle) * r;
|
2537
|
-
|
2538
|
-
return [x, y];
|
2539
|
-
};
|
2540
|
-
|
2541
|
-
|
2542
|
-
|
2543
|
-
|
2544
|
-
|
2545
|
-
|
2546
|
-
|
2547
|
-
|
2548
|
-
/**
|
2549
|
-
* This function draws the title. This function also draws the subtitle.
|
2550
|
-
*/
|
2551
|
-
RG.SVG.drawTitle = function (obj)
|
2552
|
-
{
|
2553
|
-
var prop = obj.properties;
|
2554
|
-
var valign = 'bottom';
|
2555
|
-
|
2556
|
-
//
|
2557
|
-
// The Pie chart title should default to being above the centerx
|
2558
|
-
//
|
2559
|
-
if (obj.type === 'pie') {
|
2560
|
-
if (RG.SVG.isNull(prop.titleX)) {
|
2561
|
-
prop.titleX = obj.centerx;
|
2562
|
-
prop.titleSubtitleX = obj.centerx;
|
2563
|
-
}
|
2564
|
-
|
2565
|
-
if (RG.SVG.isNull(prop.titleY)) {
|
2566
|
-
prop.titleY = obj.centery - obj.radius - 10;
|
2567
|
-
}
|
2568
|
-
}
|
2569
|
-
|
2570
|
-
|
2571
|
-
|
2572
|
-
|
2573
|
-
|
2574
|
-
|
2575
|
-
if (obj.scale && obj.scale.max <= 0 && obj.scale.min < 0 && typeof prop.titleY !== 'number' && obj.type !== 'hbar') {
|
2576
|
-
prop.titleY = obj.height - prop.gutterBottom + 10;
|
2577
|
-
var positionBottom = true;
|
2578
|
-
valign = 'top';
|
2579
|
-
} else if (typeof prop.titleY !== 'number') {
|
2580
|
-
var positionBottom = false;
|
2581
|
-
prop.titleY = prop.gutterTop - 10;
|
2582
|
-
valign = 'bottom';
|
2583
|
-
|
2584
|
-
// Account for the key
|
2585
|
-
if (!RG.SVG.isNull(prop.key)) {
|
2586
|
-
prop.titleY -= (2 * (prop.keyTextSize || prop.textSize));
|
2587
|
-
}
|
2588
|
-
}
|
2589
|
-
|
2590
|
-
// If a subtitle is specified move the title up a bit in
|
2591
|
-
// order to accommodate it
|
2592
|
-
if (prop.titleSubtitle && typeof prop.titleSubtitleY !== 'number' && !positionBottom) {
|
2593
|
-
prop.titleY = prop.titleY - (prop.titleSubtitleSize * 1.5);
|
2594
|
-
}
|
2595
|
-
|
2596
|
-
// Work out the subtitle size
|
2597
|
-
prop.titleSubTitleSize = prop.titleSubTitleSize || prop.textSize;
|
2598
|
-
|
2599
|
-
// Work out the subtitle Y position
|
2600
|
-
prop.titleSubtitleY = prop.titleSubtitleY || prop.titleY + 18;
|
2601
|
-
|
2602
|
-
if (positionBottom && typeof prop.titleSubtitleY !== 'number') {
|
2603
|
-
prop.titleSubtitleY = prop.titleY + 26;
|
2604
|
-
}
|
2605
|
-
|
2606
|
-
|
2607
|
-
|
2608
|
-
|
2609
|
-
|
2610
|
-
|
2611
|
-
// Draw the title
|
2612
|
-
if (prop.title) {
|
2613
|
-
|
2614
|
-
RG.SVG.text({
|
2615
|
-
object: obj,
|
2616
|
-
svg: obj.svg,
|
2617
|
-
parent: obj.svg.all,
|
2618
|
-
text: prop.title.toString(),
|
2619
|
-
size: prop.titleSize || (prop.textSize + 4) || 16,
|
2620
|
-
|
2621
|
-
x: typeof prop.titleX === 'number' ? prop.titleX + (prop.variant3dOffsetx || 0) : prop.gutterLeft + (obj.graphWidth / 2) + (prop.variant3dOffsetx || 0),
|
2622
|
-
y: prop.titleY + (prop.variant3dOffsety || 0),
|
2623
|
-
|
2624
|
-
halign: prop.titleHalign || 'center',
|
2625
|
-
valign: prop.titleValign || valign,
|
2626
|
-
color: prop.titleColor || prop.textColor || 'black',
|
2627
|
-
bold: prop.titleBold || false,
|
2628
|
-
italic: prop.titleItalic || false,
|
2629
|
-
font: prop.titleFont || prop.textFont || 'Arial'
|
2630
|
-
});
|
2631
|
-
}
|
2632
|
-
|
2633
|
-
|
2634
|
-
|
2635
|
-
// Draw the subtitle
|
2636
|
-
if (prop.titleSubtitle) {
|
2637
|
-
RG.SVG.text({
|
2638
|
-
object: obj,
|
2639
|
-
svg: obj.svg,
|
2640
|
-
parent: obj.svg.all,
|
2641
|
-
text: prop.titleSubtitle,
|
2642
|
-
size: prop.titleSubtitleSize,
|
2643
|
-
x: typeof prop.titleSubtitleX === 'number' ? prop.titleSubtitleX : prop.gutterLeft + (obj.graphWidth / 2) + (prop.variant3dOffsetx || 0),
|
2644
|
-
y: prop.titleSubtitleY + (prop.variant3dOffsety || 0),
|
2645
|
-
halign: prop.titleSubtitleHalign || 'center',
|
2646
|
-
valign: prop.titleSubtitleValign || valign,
|
2647
|
-
color: prop.titleSubtitleColor || prop.textColor || '#aaa',
|
2648
|
-
bold: prop.titleSubtitleBold || false,
|
2649
|
-
italic: prop.titleSubtitleItalic || false,
|
2650
|
-
font: prop.titleSubtitleFont || prop.textFont || 'Arial'
|
2651
|
-
});
|
2652
|
-
}
|
2653
|
-
};
|
2654
|
-
|
2655
|
-
|
2656
|
-
|
2657
|
-
|
2658
|
-
|
2659
|
-
|
2660
|
-
|
2661
|
-
|
2662
|
-
/**
|
2663
|
-
* Removes white-space from the start and end of a string
|
2664
|
-
*
|
2665
|
-
* @param string str The string to trim
|
2666
|
-
*/
|
2667
|
-
RG.SVG.trim = function (str)
|
2668
|
-
{
|
2669
|
-
return RG.SVG.ltrim(RG.SVG.rtrim(str));
|
2670
|
-
};
|
2671
|
-
|
2672
|
-
|
2673
|
-
|
2674
|
-
|
2675
|
-
|
2676
|
-
|
2677
|
-
|
2678
|
-
|
2679
|
-
/**
|
2680
|
-
* Trims the white-space from the start of a string
|
2681
|
-
*
|
2682
|
-
* @param string str The string to trim
|
2683
|
-
*/
|
2684
|
-
RG.SVG.ltrim = function (str)
|
2685
|
-
{
|
2686
|
-
return String(str).replace(/^(\s|\0)+/, '');
|
2687
|
-
};
|
2688
|
-
|
2689
|
-
|
2690
|
-
|
2691
|
-
|
2692
|
-
|
2693
|
-
|
2694
|
-
|
2695
|
-
|
2696
|
-
/**
|
2697
|
-
* Trims the white-space off of the end of a string
|
2698
|
-
*
|
2699
|
-
* @param string str The string to trim
|
2700
|
-
*/
|
2701
|
-
RG.SVG.rtrim = function (str)
|
2702
|
-
{
|
2703
|
-
return String(str).replace(/(\s|\0)+$/, '');
|
2704
|
-
};
|
2705
|
-
|
2706
|
-
|
2707
|
-
|
2708
|
-
|
2709
|
-
|
2710
|
-
|
2711
|
-
|
2712
|
-
|
2713
|
-
/**
|
2714
|
-
* This parses a single color value
|
2715
|
-
*/
|
2716
|
-
RG.SVG.parseColorLinear = function (opt)
|
2717
|
-
{
|
2718
|
-
var obj = opt.object,
|
2719
|
-
color = opt.color;
|
2720
|
-
|
2721
|
-
if (!color || typeof color !== 'string') {
|
2722
|
-
return color;
|
2723
|
-
}
|
2724
|
-
|
2725
|
-
if (color.match(/^gradient\((.*)\)$/i)) {
|
2726
|
-
|
2727
|
-
var parts = RegExp.$1.split(':'),
|
2728
|
-
diff = 1 / (parts.length - 1);
|
2729
|
-
|
2730
|
-
if (opt && opt.direction && opt.direction === 'horizontal') {
|
2731
|
-
var grad = RG.SVG.create({
|
2732
|
-
type: 'linearGradient',
|
2733
|
-
parent: obj.svg.defs,
|
2734
|
-
attr: {
|
2735
|
-
id: 'RGraph-linear-gradient' + obj.gradientCounter,
|
2736
|
-
x1: opt.start || 0,
|
2737
|
-
x2: opt.end || '100%',
|
2738
|
-
y1: 0,
|
2739
|
-
y2: 0,
|
2740
|
-
gradientUnits: "userSpaceOnUse"
|
2741
|
-
}
|
2742
|
-
});
|
2743
|
-
|
2744
|
-
} else {
|
2745
|
-
|
2746
|
-
var grad = RG.SVG.create({
|
2747
|
-
type: 'linearGradient',
|
2748
|
-
parent: obj.svg.defs,
|
2749
|
-
attr: {
|
2750
|
-
id: 'RGraph-linear-gradient' + obj.gradientCounter,
|
2751
|
-
x1: 0,
|
2752
|
-
x2: 0,
|
2753
|
-
y1: opt.start || 0,
|
2754
|
-
y2: opt.end || '100%',
|
2755
|
-
gradientUnits: "userSpaceOnUse"
|
2756
|
-
}
|
2757
|
-
});
|
2758
|
-
}
|
2759
|
-
|
2760
|
-
// Add the first color stop
|
2761
|
-
var stop = RG.SVG.create({
|
2762
|
-
type: 'stop',
|
2763
|
-
parent: grad,
|
2764
|
-
attr: {
|
2765
|
-
offset: '0%',
|
2766
|
-
'stop-color': RG.SVG.trim(parts[0])
|
2767
|
-
}
|
2768
|
-
});
|
2769
|
-
|
2770
|
-
// Add the rest of the color stops
|
2771
|
-
for (var j=1,len=parts.length; j<len; ++j) {
|
2772
|
-
|
2773
|
-
RG.SVG.create({
|
2774
|
-
type: 'stop',
|
2775
|
-
parent: grad,
|
2776
|
-
attr: {
|
2777
|
-
offset: (j * diff * 100) + '%',
|
2778
|
-
'stop-color': RG.SVG.trim(parts[j])
|
2779
|
-
}
|
2780
|
-
});
|
2781
|
-
}
|
2782
|
-
}
|
2783
|
-
|
2784
|
-
color = grad ? 'url(#RGraph-linear-gradient' + (obj.gradientCounter++) + ')' : color;
|
2785
|
-
|
2786
|
-
return color;
|
2787
|
-
};
|
2788
|
-
|
2789
|
-
|
2790
|
-
|
2791
|
-
|
2792
|
-
|
2793
|
-
|
2794
|
-
|
2795
|
-
|
2796
|
-
/**
|
2797
|
-
* This parses a single color value
|
2798
|
-
*/
|
2799
|
-
RG.SVG.parseColorRadial = function (opt)
|
2800
|
-
{
|
2801
|
-
var obj = opt.object,
|
2802
|
-
color = opt.color;
|
2803
|
-
|
2804
|
-
if (!color || typeof color !== 'string') {
|
2805
|
-
return color;
|
2806
|
-
}
|
2807
|
-
|
2808
|
-
if (color.match(/^gradient\((.*)\)$/i)) {
|
2809
|
-
|
2810
|
-
var parts = RegExp.$1.split(':'),
|
2811
|
-
diff = 1 / (parts.length - 1);
|
2812
|
-
|
2813
|
-
|
2814
|
-
var grad = RG.SVG.create({
|
2815
|
-
type: 'radialGradient',
|
2816
|
-
parent: obj.svg.defs,
|
2817
|
-
attr: {
|
2818
|
-
id: 'RGraph-radial-gradient' + obj.gradientCounter,
|
2819
|
-
gradientUnits: opt.gradientUnits || 'userSpaceOnUse',
|
2820
|
-
cx: opt.cx || obj.centerx,
|
2821
|
-
cy: opt.cy || obj.centery,
|
2822
|
-
fx: opt.fx || obj.centerx,
|
2823
|
-
fy: opt.fy || obj.centery,
|
2824
|
-
r: opt.r || obj.radius
|
2825
|
-
}
|
2826
|
-
});
|
2827
|
-
|
2828
|
-
// Add the first color stop
|
2829
|
-
var stop = RG.SVG.create({
|
2830
|
-
type: 'stop',
|
2831
|
-
parent: grad,
|
2832
|
-
attr: {
|
2833
|
-
offset: '0%',
|
2834
|
-
'stop-color': RG.SVG.trim(parts[0])
|
2835
|
-
}
|
2836
|
-
});
|
2837
|
-
|
2838
|
-
// Add the rest of the color stops
|
2839
|
-
for (var j=1,len=parts.length; j<len; ++j) {
|
2840
|
-
|
2841
|
-
RG.SVG.create({
|
2842
|
-
type: 'stop',
|
2843
|
-
parent: grad,
|
2844
|
-
attr: {
|
2845
|
-
offset: (j * diff * 100) + '%',
|
2846
|
-
'stop-color': RG.SVG.trim(parts[j])
|
2847
|
-
}
|
2848
|
-
});
|
2849
|
-
}
|
2850
|
-
}
|
2851
|
-
|
2852
|
-
color = grad ? 'url(#RGraph-radial-gradient' + (obj.gradientCounter++) + ')' : color;
|
2853
|
-
|
2854
|
-
return color;
|
2855
|
-
};
|
2856
|
-
|
2857
|
-
|
2858
|
-
|
2859
|
-
|
2860
|
-
|
2861
|
-
|
2862
|
-
|
2863
|
-
|
2864
|
-
/**
|
2865
|
-
* Reset all of the color values to their original values
|
2866
|
-
*
|
2867
|
-
* @param object
|
2868
|
-
*/
|
2869
|
-
RG.SVG.resetColorsToOriginalValues = function (opt)
|
2870
|
-
{
|
2871
|
-
var obj = opt.object;
|
2872
|
-
|
2873
|
-
if (obj.originalColors) {
|
2874
|
-
// Reset the colors to their original values
|
2875
|
-
for (var j in obj.originalColors) {
|
2876
|
-
if (typeof j === 'string') {
|
2877
|
-
obj.properties[j] = RG.SVG.arrayClone(obj.originalColors[j]);
|
2878
|
-
}
|
2879
|
-
}
|
2880
|
-
}
|
2881
|
-
|
2882
|
-
/**
|
2883
|
-
* If the function is present on the object to reset specific
|
2884
|
-
* colors - use that
|
2885
|
-
*/
|
2886
|
-
if (typeof obj.resetColorsToOriginalValues === 'function') {
|
2887
|
-
obj.resetColorsToOriginalValues();
|
2888
|
-
}
|
2889
|
-
|
2890
|
-
// Hmmm... Should this be necessary? I don't think it will
|
2891
|
-
// do any harm to leave it in.
|
2892
|
-
obj.originalColors = {};
|
2893
|
-
|
2894
|
-
|
2895
|
-
|
2896
|
-
// Reset the colorsParsed flag so that they're parsed for gradients again
|
2897
|
-
obj.colorsParsed = false;
|
2898
|
-
|
2899
|
-
// Reset the gradient counter
|
2900
|
-
obj.gradientCounter = 1;
|
2901
|
-
};
|
2902
|
-
|
2903
|
-
|
2904
|
-
|
2905
|
-
|
2906
|
-
|
2907
|
-
|
2908
|
-
|
2909
|
-
|
2910
|
-
//
|
2911
|
-
// Clear the SVG tag by deleting all of its
|
2912
|
-
// child nodes
|
2913
|
-
//
|
2914
|
-
// @param object svg The SVG tag (same as what is returned
|
2915
|
-
// by document.getElementById() )
|
2916
|
-
//
|
2917
|
-
RG.SVG.clear = function (svg)
|
2918
|
-
{
|
2919
|
-
while (svg.all.lastChild) {
|
2920
|
-
svg.all.removeChild(svg.all.lastChild);
|
2921
|
-
}
|
2922
|
-
|
2923
|
-
//while (svg.lastChild) {
|
2924
|
-
// svg.removeChild(svg.lastChild);
|
2925
|
-
//}
|
2926
|
-
};
|
2927
|
-
|
2928
|
-
|
2929
|
-
|
2930
|
-
|
2931
|
-
|
2932
|
-
|
2933
|
-
|
2934
|
-
|
2935
|
-
/**
|
2936
|
-
* Adds an event listener
|
2937
|
-
*
|
2938
|
-
* @param object obj The graph object
|
2939
|
-
* @param string event The name of the event, eg ontooltip
|
2940
|
-
* @param object func The callback function
|
2941
|
-
*/
|
2942
|
-
RG.SVG.addCustomEventListener = function (obj, name, func)
|
2943
|
-
{
|
2944
|
-
// Initialise the events array if necessary
|
2945
|
-
if (typeof RG.SVG.events[obj.uid] === 'undefined') {
|
2946
|
-
RG.SVG.events[obj.uid] = [];
|
2947
|
-
}
|
2948
|
-
|
2949
|
-
// Prepend "on" if necessary
|
2950
|
-
if (name.substr(0, 2) !== 'on') {
|
2951
|
-
name = 'on' + name;
|
2952
|
-
}
|
2953
|
-
|
2954
|
-
RG.SVG.events[obj.uid].push({
|
2955
|
-
object: obj,
|
2956
|
-
event: name,
|
2957
|
-
func: func
|
2958
|
-
});
|
2959
|
-
|
2960
|
-
return RG.SVG.events[obj.uid].length - 1;
|
2961
|
-
};
|
2962
|
-
|
2963
|
-
|
2964
|
-
|
2965
|
-
|
2966
|
-
|
2967
|
-
|
2968
|
-
|
2969
|
-
|
2970
|
-
/**
|
2971
|
-
* Used to fire one of the RGraph custom events
|
2972
|
-
*
|
2973
|
-
* @param object obj The graph object that fires the event
|
2974
|
-
* @param string event The name of the event to fire
|
2975
|
-
*/
|
2976
|
-
RG.SVG.fireCustomEvent = function (obj, name)
|
2977
|
-
{
|
2978
|
-
if (obj && obj.isRGraph) {
|
2979
|
-
|
2980
|
-
var uid = obj.uid;
|
2981
|
-
|
2982
|
-
if ( typeof uid === 'string'
|
2983
|
-
&& typeof RG.SVG.events === 'object'
|
2984
|
-
&& typeof RG.SVG.events[uid] === 'object'
|
2985
|
-
&& RG.SVG.events[uid].length > 0) {
|
2986
|
-
|
2987
|
-
for(var j=0,len=RG.SVG.events[uid].length; j<len; ++j) {
|
2988
|
-
if (RG.SVG.events[uid][j] && RG.SVG.events[uid][j].event === name) {
|
2989
|
-
RG.SVG.events[uid][j].func(obj);
|
2990
|
-
}
|
2991
|
-
}
|
2992
|
-
}
|
2993
|
-
}
|
2994
|
-
};
|
2995
|
-
|
2996
|
-
|
2997
|
-
|
2998
|
-
|
2999
|
-
|
3000
|
-
|
3001
|
-
|
3002
|
-
|
3003
|
-
/**
|
3004
|
-
* Clears all the custom event listeners that have been registered
|
3005
|
-
*
|
3006
|
-
* @param string optional Limits the clearing to this object UID
|
3007
|
-
*/
|
3008
|
-
RG.SVG.removeAllCustomEventListeners = function ()
|
3009
|
-
{
|
3010
|
-
var uid = arguments[0];
|
3011
|
-
|
3012
|
-
if (uid && RG.SVG.events[uid]) {
|
3013
|
-
RG.SVG.events[uid] = {};
|
3014
|
-
} else {
|
3015
|
-
RG.SVG.events = [];
|
3016
|
-
}
|
3017
|
-
};
|
3018
|
-
|
3019
|
-
|
3020
|
-
|
3021
|
-
|
3022
|
-
|
3023
|
-
|
3024
|
-
|
3025
|
-
|
3026
|
-
/**
|
3027
|
-
* Clears a particular custom event listener
|
3028
|
-
*
|
3029
|
-
* @param object obj The graph object
|
3030
|
-
* @param number i This is the index that is return by .addCustomEventListener()
|
3031
|
-
*/
|
3032
|
-
RG.SVG.removeCustomEventListener = function (obj, i)
|
3033
|
-
{
|
3034
|
-
if ( typeof RG.SVG.events === 'object'
|
3035
|
-
&& typeof RG.SVG.events[obj.uid] === 'object'
|
3036
|
-
&& typeof RG.SVG.events[obj.uid][i] === 'object') {
|
3037
|
-
|
3038
|
-
RG.SVG.events[obj.uid][i] = null;
|
3039
|
-
}
|
3040
|
-
};
|
3041
|
-
|
3042
|
-
|
3043
|
-
|
3044
|
-
|
3045
|
-
|
3046
|
-
|
3047
|
-
|
3048
|
-
|
3049
|
-
//
|
3050
|
-
// Removes the highlight from the chart added by tooltips (possibly others too)
|
3051
|
-
//
|
3052
|
-
RG.SVG.removeHighlight = function (obj)
|
3053
|
-
{
|
3054
|
-
var highlight = RG.SVG.REG.get('highlight');
|
3055
|
-
|
3056
|
-
if (highlight && RG.SVG.isArray(highlight) && highlight.length) {
|
3057
|
-
for (var i=0,len=highlight.length; i<len; ++i) {
|
3058
|
-
if (highlight[i].parentNode) {
|
3059
|
-
//obj.svg.removeChild(highlight[i]);
|
3060
|
-
highlight[i].parentNode.removeChild(highlight[i]);
|
3061
|
-
}
|
3062
|
-
}
|
3063
|
-
} else if (highlight && highlight.parentNode) {
|
3064
|
-
if (obj.type === 'scatter') {
|
3065
|
-
highlight.setAttribute('fill', 'transparent');
|
3066
|
-
} else {
|
3067
|
-
highlight.parentNode.removeChild(highlight);
|
3068
|
-
}
|
3069
|
-
}
|
3070
|
-
};
|
3071
|
-
|
3072
|
-
|
3073
|
-
|
3074
|
-
|
3075
|
-
|
3076
|
-
|
3077
|
-
|
3078
|
-
|
3079
|
-
//
|
3080
|
-
// Removes the highlight from the chart added by tooltips (possibly others too)
|
3081
|
-
//
|
3082
|
-
RG.SVG.redraw = function ()
|
3083
|
-
{
|
3084
|
-
if (arguments.length === 1) {
|
3085
|
-
|
3086
|
-
var svg = arguments[0];
|
3087
|
-
|
3088
|
-
RG.SVG.clear(svg);
|
3089
|
-
|
3090
|
-
var objects = RG.SVG.OR.get('id:' + svg.parentNode.id);
|
3091
|
-
|
3092
|
-
for (var i=0,len=objects.length; i<len; ++i) {
|
3093
|
-
|
3094
|
-
// Reset the colors to the original values
|
3095
|
-
RG.SVG.resetColorsToOriginalValues({object: objects[i]});
|
3096
|
-
|
3097
|
-
objects[i].draw();
|
3098
|
-
}
|
3099
|
-
} else {
|
3100
|
-
|
3101
|
-
var tags = RG.SVG.OR.tags();
|
3102
|
-
|
3103
|
-
for (var i in tags) {
|
3104
|
-
RG.SVG.redraw(tags[i]);
|
3105
|
-
}
|
3106
|
-
}
|
3107
|
-
};
|
3108
|
-
|
3109
|
-
|
3110
|
-
|
3111
|
-
|
3112
|
-
|
3113
|
-
|
3114
|
-
|
3115
|
-
|
3116
|
-
//
|
3117
|
-
// A better, more flexible, date parsing function
|
3118
|
-
//
|
3119
|
-
//@param string str The string to parse
|
3120
|
-
//@retutn number A number, as returned by Date.parse()
|
3121
|
-
//
|
3122
|
-
RG.SVG.parseDate = function (str)
|
3123
|
-
{
|
3124
|
-
var d = new Date();
|
3125
|
-
|
3126
|
-
// Initialise the default values
|
3127
|
-
var defaults = {
|
3128
|
-
seconds: '00',
|
3129
|
-
minutes: '00',
|
3130
|
-
hours: '00',
|
3131
|
-
date: d.getDate(),
|
3132
|
-
month: d.getMonth() + 1,
|
3133
|
-
year: d.getFullYear()
|
3134
|
-
};
|
3135
|
-
|
3136
|
-
// Create the months array for turning textual months back to numbers
|
3137
|
-
var months = ['january','february','march','april','may','june','july','august','september','october','november','december'],
|
3138
|
-
months_regex = months.join('|');
|
3139
|
-
|
3140
|
-
for (var i=0; i<months.length; ++i) {
|
3141
|
-
months[months[i]] = i;
|
3142
|
-
months[months[i].substring(0,3)] = i;
|
3143
|
-
months_regex = months_regex + '|' + months[i].substring(0,3);
|
3144
|
-
}
|
3145
|
-
|
3146
|
-
// These are the seperators allowable for d/m/y and y/m/d dates
|
3147
|
-
// (Its part of a regexp so the position of the square brackets
|
3148
|
-
// is crucial)
|
3149
|
-
var sep = '[-./_=+~#:;,]+';
|
3150
|
-
|
3151
|
-
|
3152
|
-
// Tokenise the string
|
3153
|
-
var tokens = str.split(/ +/);
|
3154
|
-
|
3155
|
-
// Loop through each token checking what is is
|
3156
|
-
for (var i=0,len=tokens.length; i<len; ++i) {
|
3157
|
-
if (tokens[i]) {
|
3158
|
-
|
3159
|
-
// Year
|
3160
|
-
if (tokens[i].match(/^\d\d\d\d$/)) {
|
3161
|
-
defaults.year = tokens[i];
|
3162
|
-
}
|
3163
|
-
|
3164
|
-
// Month
|
3165
|
-
var res = isMonth(tokens[i]);
|
3166
|
-
if (typeof res === 'number') {
|
3167
|
-
defaults.month = res + 1; // Months are zero indexed
|
3168
|
-
}
|
3169
|
-
|
3170
|
-
// Date
|
3171
|
-
if (tokens[i].match(/^\d?\d(?:st|nd|rd|th)?$/)) {
|
3172
|
-
defaults.date = parseInt(tokens[i]);
|
3173
|
-
}
|
3174
|
-
|
3175
|
-
// Time
|
3176
|
-
if (tokens[i].match(/^(\d\d):(\d\d)(?:(\d\d))?$/)) {
|
3177
|
-
defaults.hours = parseInt(RegExp.$1);
|
3178
|
-
defaults.minutes = parseInt(RegExp.$2);
|
3179
|
-
|
3180
|
-
if (RegExp.$3) {
|
3181
|
-
defaults.seconds = parseInt(RegExp.$3);
|
3182
|
-
}
|
3183
|
-
}
|
3184
|
-
|
3185
|
-
// Dateformat: XXXX-XX-XX
|
3186
|
-
if (tokens[i].match(new RegExp('^(\\d\\d\\d\\d)' + sep + '(\\d\\d)' + sep + '(\\d\\d)$', 'i'))) {
|
3187
|
-
defaults.date = parseInt(RegExp.$3);
|
3188
|
-
defaults.month = parseInt(RegExp.$2);
|
3189
|
-
defaults.year = parseInt(RegExp.$1);
|
3190
|
-
}
|
3191
|
-
|
3192
|
-
// Dateformat: XX-XX-XXXX
|
3193
|
-
if (tokens[i].match(new RegExp('^(\\d\\d)' + sep + '(\\d\\d)' + sep + '(\\d\\d\\d\\d)$','i') )) {
|
3194
|
-
defaults.date = parseInt(RegExp.$1);
|
3195
|
-
defaults.month = parseInt(RegExp.$2);
|
3196
|
-
defaults.year = parseInt(RegExp.$3);
|
3197
|
-
}
|
3198
|
-
}
|
3199
|
-
}
|
3200
|
-
|
3201
|
-
// Now put the defaults into a format thats recognised by Date.parse()
|
3202
|
-
str = '{1}/{2}/{3} {4}:{5}:{6}'.format(
|
3203
|
-
defaults.year,
|
3204
|
-
String(defaults.month).length === 1 ? '0' + (defaults.month) : defaults.month,
|
3205
|
-
String(defaults.date).length === 1 ? '0' + (defaults.date) : defaults.date,
|
3206
|
-
String(defaults.hours).length === 1 ? '0' + (defaults.hours) : defaults.hours,
|
3207
|
-
String(defaults.minutes).length === 1 ? '0' + (defaults.minutes) : defaults.minutes,
|
3208
|
-
String(defaults.seconds).length === 1 ? '0' + (defaults.seconds) : defaults.seconds
|
3209
|
-
);
|
3210
|
-
|
3211
|
-
return Date.parse(str);
|
3212
|
-
|
3213
|
-
//
|
3214
|
-
// Support functions
|
3215
|
-
//
|
3216
|
-
function isMonth(str)
|
3217
|
-
{
|
3218
|
-
var res = str.toLowerCase().match(months_regex);
|
3219
|
-
|
3220
|
-
return res ? months[res[0]] : false;
|
3221
|
-
}
|
3222
|
-
};
|
3223
|
-
|
3224
|
-
|
3225
|
-
|
3226
|
-
|
3227
|
-
|
3228
|
-
|
3229
|
-
|
3230
|
-
|
3231
|
-
// The ObjectRegistry add function
|
3232
|
-
RG.SVG.OR.add = function (obj)
|
3233
|
-
{
|
3234
|
-
RG.SVG.OR.objects.push(obj);
|
3235
|
-
|
3236
|
-
return obj;
|
3237
|
-
};
|
3238
|
-
|
3239
|
-
|
3240
|
-
|
3241
|
-
|
3242
|
-
|
3243
|
-
|
3244
|
-
|
3245
|
-
|
3246
|
-
// The ObjectRegistry function that returns all of the objects. Th argument
|
3247
|
-
// can aither be:
|
3248
|
-
//
|
3249
|
-
// o omitted All of the registered objects are returned
|
3250
|
-
// o id:XXX All of the objects on that SVG tag are returned
|
3251
|
-
// o type:XXX All the objects of that type are returned
|
3252
|
-
//
|
3253
|
-
RG.SVG.OR.get = function ()
|
3254
|
-
{
|
3255
|
-
// Fetch objects that are on a particular SVG tag
|
3256
|
-
if (typeof arguments[0] === 'string' && arguments[0].substr(0, 3).toLowerCase() === 'id:') {
|
3257
|
-
|
3258
|
-
var ret = [];
|
3259
|
-
|
3260
|
-
for (var i=0; i<RG.SVG.OR.objects.length; ++i) {
|
3261
|
-
if (RG.SVG.OR.objects[i].id === arguments[0].substr(3)) {
|
3262
|
-
ret.push(RG.SVG.OR.objects[i]);
|
3263
|
-
}
|
3264
|
-
}
|
3265
|
-
|
3266
|
-
return ret;
|
3267
|
-
}
|
3268
|
-
|
3269
|
-
|
3270
|
-
// Fetch objects that are of a particular type
|
3271
|
-
//
|
3272
|
-
// TODO Allow multiple types to be specified
|
3273
|
-
if (typeof arguments[0] === 'string' && arguments[0].substr(0, 4).toLowerCase() === 'type') {
|
3274
|
-
|
3275
|
-
var ret = [];
|
3276
|
-
|
3277
|
-
for (var i=0; i<RG.SVG.OR.objects.length; ++i) {
|
3278
|
-
if (RG.SVG.OR.objects[i].type === arguments[0].substr(5)) {
|
3279
|
-
ret.push(RG.SVG.OR.objects[i]);
|
3280
|
-
}
|
3281
|
-
}
|
3282
|
-
|
3283
|
-
return ret;
|
3284
|
-
}
|
3285
|
-
|
3286
|
-
|
3287
|
-
// Fetch an object that has a specific UID
|
3288
|
-
if (typeof arguments[0] === 'string' && arguments[0].substr(0, 3).toLowerCase() === 'uid') {
|
3289
|
-
|
3290
|
-
var ret = [];
|
3291
|
-
|
3292
|
-
for (var i=0; i<RG.SVG.OR.objects.length; ++i) {
|
3293
|
-
if (RG.SVG.OR.objects[i].uid === arguments[0].substr(4)) {
|
3294
|
-
ret.push(RG.SVG.OR.objects[i]);
|
3295
|
-
}
|
3296
|
-
}
|
3297
|
-
|
3298
|
-
return ret;
|
3299
|
-
}
|
3300
|
-
|
3301
|
-
return RG.SVG.OR.objects;
|
3302
|
-
};
|
3303
|
-
|
3304
|
-
|
3305
|
-
|
3306
|
-
|
3307
|
-
|
3308
|
-
|
3309
|
-
|
3310
|
-
|
3311
|
-
// The ObjectRegistry function that returns all of the registeredt SVG tags
|
3312
|
-
//
|
3313
|
-
RG.SVG.OR.tags = function ()
|
3314
|
-
{
|
3315
|
-
var tags = [];
|
3316
|
-
|
3317
|
-
for (var i=0; i<RG.SVG.OR.objects.length; ++i) {
|
3318
|
-
if (!tags[RG.SVG.OR.objects[i].svg.parentNode.id]) {
|
3319
|
-
tags[RG.SVG.OR.objects[i].svg.parentNode.id] = RG.SVG.OR.objects[i].svg;
|
3320
|
-
}
|
3321
|
-
}
|
3322
|
-
|
3323
|
-
return tags;
|
3324
|
-
};
|
3325
|
-
|
3326
|
-
|
3327
|
-
|
3328
|
-
|
3329
|
-
|
3330
|
-
|
3331
|
-
|
3332
|
-
|
3333
|
-
//
|
3334
|
-
// This function returns a two element array of the SVG x/y position in
|
3335
|
-
// relation to the page
|
3336
|
-
//
|
3337
|
-
// @param object svg
|
3338
|
-
//
|
3339
|
-
RG.SVG.getSVGXY = function (svg)
|
3340
|
-
{
|
3341
|
-
var x = 0,
|
3342
|
-
y = 0,
|
3343
|
-
el = svg.parentNode; // !!!
|
3344
|
-
|
3345
|
-
do {
|
3346
|
-
|
3347
|
-
x += el.offsetLeft;
|
3348
|
-
y += el.offsetTop;
|
3349
|
-
|
3350
|
-
// Account for tables in webkit
|
3351
|
-
if (el.tagName.toLowerCase() == 'table' && (RG.SVG.ISCHROME || RG.SVG.ISSAFARI)) {
|
3352
|
-
x += parseInt(el.border) || 0;
|
3353
|
-
y += parseInt(el.border) || 0;
|
3354
|
-
}
|
3355
|
-
|
3356
|
-
el = el.offsetParent;
|
3357
|
-
|
3358
|
-
} while (el && el.tagName && el.tagName.toLowerCase() != 'body');
|
3359
|
-
|
3360
|
-
|
3361
|
-
var paddingLeft = svg.style.paddingLeft ? parseInt(svg.style.paddingLeft) : 0,
|
3362
|
-
paddingTop = svg.style.paddingTop ? parseInt(svg.style.paddingTop) : 0,
|
3363
|
-
borderLeft = svg.style.borderLeftWidth ? parseInt(svg.style.borderLeftWidth) : 0,
|
3364
|
-
borderTop = svg.style.borderTopWidth ? parseInt(svg.style.borderTopWidth) : 0;
|
3365
|
-
|
3366
|
-
if (navigator.userAgent.indexOf('Firefox') > 0) {
|
3367
|
-
x += parseInt(document.body.style.borderLeftWidth) || 0;
|
3368
|
-
y += parseInt(document.body.style.borderTopWidth) || 0;
|
3369
|
-
}
|
3370
|
-
|
3371
|
-
return [x + paddingLeft + borderLeft, y + paddingTop + borderTop];
|
3372
|
-
};
|
3373
|
-
|
3374
|
-
|
3375
|
-
|
3376
|
-
|
3377
|
-
|
3378
|
-
|
3379
|
-
|
3380
|
-
|
3381
|
-
//
|
3382
|
-
// This function is a compatibility wrapper around
|
3383
|
-
// the requestAnimationFrame function.
|
3384
|
-
//
|
3385
|
-
// @param function func The function to give to the
|
3386
|
-
// requestAnimationFrame function
|
3387
|
-
//
|
3388
|
-
RG.SVG.FX.update = function (func)
|
3389
|
-
{
|
3390
|
-
win.requestAnimationFrame =
|
3391
|
-
win.requestAnimationFrame ||
|
3392
|
-
win.webkitRequestAnimationFrame ||
|
3393
|
-
win.msRequestAnimationFrame ||
|
3394
|
-
win.mozRequestAnimationFrame ||
|
3395
|
-
(function (func){setTimeout(func, 16.666);});
|
3396
|
-
|
3397
|
-
win.requestAnimationFrame(func);
|
3398
|
-
};
|
3399
|
-
|
3400
|
-
|
3401
|
-
|
3402
|
-
|
3403
|
-
|
3404
|
-
|
3405
|
-
|
3406
|
-
|
3407
|
-
/**
|
3408
|
-
* This function returns an easing multiplier for effects so they eas out towards the
|
3409
|
-
* end of the effect.
|
3410
|
-
*
|
3411
|
-
* @param number frames The total number of frames
|
3412
|
-
* @param number frame The frame number
|
3413
|
-
*/
|
3414
|
-
RG.SVG.FX.getEasingMultiplier = function (frames, frame)
|
3415
|
-
{
|
3416
|
-
var multiplier = ma.pow(ma.sin((frame / frames) * RG.SVG.TRIG.HALFPI), 3);
|
3417
|
-
|
3418
|
-
return multiplier;
|
3419
|
-
};
|
3420
|
-
|
3421
|
-
|
3422
|
-
|
3423
|
-
|
3424
|
-
|
3425
|
-
|
3426
|
-
|
3427
|
-
|
3428
|
-
/**
|
3429
|
-
* Measures text by creating a DIV in the document and adding the relevant
|
3430
|
-
* text to it, then checking the .offsetWidth and .offsetHeight.
|
3431
|
-
*
|
3432
|
-
* @param object opt An object containing the following:
|
3433
|
-
* o text( string) The text to measure
|
3434
|
-
* o bold (bool) Whether the text is bold or not
|
3435
|
-
* o font (string) The font to use
|
3436
|
-
* o size (number) The size of the text (in pts)
|
3437
|
-
*
|
3438
|
-
* @return array A two element array of the width and height of the text
|
3439
|
-
*/
|
3440
|
-
RG.SVG.measureText = function (opt)
|
3441
|
-
{
|
3442
|
-
//text, bold, font, size
|
3443
|
-
var text = opt.text || '',
|
3444
|
-
bold = opt.bold || false,
|
3445
|
-
font = opt.font || 'Arial',
|
3446
|
-
size = opt.size || 10,
|
3447
|
-
str = text + ':' + bold + ':' + font + ':' + size;
|
3448
|
-
|
3449
|
-
// Add the sizes to the cache as adding DOM elements is costly and causes slow downs
|
3450
|
-
if (typeof RG.SVG.measuretext_cache === 'undefined') {
|
3451
|
-
RG.SVG.measuretext_cache = [];
|
3452
|
-
}
|
3453
|
-
|
3454
|
-
if (typeof RG.SVG.measuretext_cache == 'object' && RG.SVG.measuretext_cache[str]) {
|
3455
|
-
|
3456
|
-
return RG.SVG.measuretext_cache[str];
|
3457
|
-
}
|
3458
|
-
|
3459
|
-
if (!RG.SVG.measuretext_cache['text-span']) {
|
3460
|
-
var span = document.createElement('SPAN');
|
3461
|
-
span.style.position = 'absolute';
|
3462
|
-
//span.style.backgroundColor = 'red';
|
3463
|
-
span.style.padding = 0;
|
3464
|
-
span.style.display = 'inline';
|
3465
|
-
span.style.top = '-200px';
|
3466
|
-
span.style.left = '-200px';
|
3467
|
-
span.style.lineHeight = '1em';
|
3468
|
-
document.body.appendChild(span);
|
3469
|
-
|
3470
|
-
// Now store the newly created DIV
|
3471
|
-
RG.SVG.measuretext_cache['text-span'] = span;
|
3472
|
-
|
3473
|
-
} else if (RG.SVG.measuretext_cache['text-span']) {
|
3474
|
-
var span = RG.SVG.measuretext_cache['text-span'];
|
3475
|
-
}
|
3476
|
-
|
3477
|
-
span.innerHTML = text.replace(/\r\n/g, '<br />');
|
3478
|
-
span.style.fontFamily = font;
|
3479
|
-
span.style.fontWeight = bold ? 'bold' : 'normal';
|
3480
|
-
span.style.fontSize = size + 'pt';
|
3481
|
-
|
3482
|
-
var sizes = [span.offsetWidth, span.offsetHeight];
|
3483
|
-
|
3484
|
-
//document.body.removeChild(span);
|
3485
|
-
RG.SVG.measuretext_cache[str] = sizes;
|
3486
|
-
|
3487
|
-
return sizes;
|
3488
|
-
};
|
3489
|
-
|
3490
|
-
|
3491
|
-
|
3492
|
-
|
3493
|
-
|
3494
|
-
|
3495
|
-
|
3496
|
-
|
3497
|
-
/**
|
3498
|
-
* This function converts an array of strings to an array of numbers. Its used by the meter/gauge
|
3499
|
-
* style charts so that if you want you can pass in a string. It supports various formats:
|
3500
|
-
*
|
3501
|
-
* '45.2'
|
3502
|
-
* '-45.2'
|
3503
|
-
* ['45.2']
|
3504
|
-
* ['-45.2']
|
3505
|
-
* '45.2,45.2,45.2' // A CSV style string
|
3506
|
-
*
|
3507
|
-
* @param number frames The string or array to parse
|
3508
|
-
*/
|
3509
|
-
RG.SVG.stringsToNumbers = function (str)
|
3510
|
-
{
|
3511
|
-
// An optional seperator to use intead of a comma
|
3512
|
-
var sep = arguments[1] || ',';
|
3513
|
-
|
3514
|
-
|
3515
|
-
// If it's already a number just return it
|
3516
|
-
if (typeof str === 'number') {
|
3517
|
-
return str;
|
3518
|
-
}
|
3519
|
-
|
3520
|
-
|
3521
|
-
|
3522
|
-
|
3523
|
-
|
3524
|
-
if (typeof str === 'string') {
|
3525
|
-
if (str.indexOf(sep) != -1) {
|
3526
|
-
str = str.split(sep);
|
3527
|
-
} else {
|
3528
|
-
str = parseFloat(str);
|
3529
|
-
}
|
3530
|
-
}
|
3531
|
-
|
3532
|
-
|
3533
|
-
|
3534
|
-
|
3535
|
-
|
3536
|
-
if (typeof str === 'object') {
|
3537
|
-
for (var i=0,len=str.length; i<len; i+=1) {
|
3538
|
-
str[i] = parseFloat(str[i]);
|
3539
|
-
}
|
3540
|
-
}
|
3541
|
-
|
3542
|
-
return str;
|
3543
|
-
};
|
3544
|
-
|
3545
|
-
|
3546
|
-
|
3547
|
-
|
3548
|
-
|
3549
|
-
|
3550
|
-
|
3551
|
-
|
3552
|
-
// This function allows for numbers that are given as a +/- adjustment
|
3553
|
-
RG.SVG.getAdjustedNumber = function (opt)
|
3554
|
-
{
|
3555
|
-
var value = opt.value,
|
3556
|
-
prop = opt.prop;
|
3557
|
-
|
3558
|
-
if (typeof prop === 'string' && match(/^(\+|-)([0-9.]+)/)) {
|
3559
|
-
if (RegExp.$1 === '+') {
|
3560
|
-
value += parseFloat(RegExp.$2);
|
3561
|
-
} else if (RegExp.$1 === '-') {
|
3562
|
-
value -= parseFloat(RegExp.$2);
|
3563
|
-
}
|
3564
|
-
}
|
3565
|
-
|
3566
|
-
return value;
|
3567
|
-
};
|
3568
|
-
|
3569
|
-
|
3570
|
-
|
3571
|
-
|
3572
|
-
|
3573
|
-
|
3574
|
-
|
3575
|
-
|
3576
|
-
//
|
3577
|
-
// Adds the attribution link to the chart in the
|
3578
|
-
// (by default) bottom right corner
|
3579
|
-
//
|
3580
|
-
//@param ibject obj The chart object
|
3581
|
-
//
|
3582
|
-
RG.SVG.attribution = function (obj)
|
3583
|
-
{
|
3584
|
-
return;
|
3585
|
-
/*
|
3586
|
-
var prop = obj.properties;
|
3587
|
-
|
3588
|
-
if (!prop.attribution && typeof prop.attribution !== 'undefined') {
|
3589
|
-
return false;
|
3590
|
-
}
|
3591
|
-
|
3592
|
-
|
3593
|
-
// Create the A tag
|
3594
|
-
var a = RG.SVG.create({
|
3595
|
-
svg: obj.svg,
|
3596
|
-
parent: obj.svg.all,
|
3597
|
-
type: 'a',
|
3598
|
-
attr: {
|
3599
|
-
rel: 'nofollow',
|
3600
|
-
target: '_blank',
|
3601
|
-
'xlink:href': prop.attributionHref || 'http://www.rgraph.net/'
|
3602
|
-
}
|
3603
|
-
});
|
3604
|
-
|
3605
|
-
|
3606
|
-
|
3607
|
-
// Work out the X/Y coords
|
3608
|
-
var x = parseFloat(obj.svg.getAttribute('width')) - 2,
|
3609
|
-
y = parseFloat(obj.svg.getAttribute('height')) - 2;
|
3610
|
-
|
3611
|
-
// Allow the X coord to be a +/- string
|
3612
|
-
if (typeof prop.attributionX === 'string') {
|
3613
|
-
x += parseFloat(prop.attributionX);
|
3614
|
-
} else if (typeof prop.attributionX === 'number') {
|
3615
|
-
x = parseFloat(prop.attributionX);
|
3616
|
-
}
|
3617
|
-
|
3618
|
-
// Allow the Y coord to be a +/- string|
|
3619
|
-
if (typeof prop.attributionY === 'string') {
|
3620
|
-
y += parseFloat(prop.attributionY);
|
3621
|
-
} else if (typeof prop.attributionY === 'number') {
|
3622
|
-
y = parseFloat(prop.attributionY);
|
3623
|
-
}
|
3624
|
-
|
3625
|
-
// Add a text tag to the attribution A tag
|
3626
|
-
var text = RG.SVG.text({
|
3627
|
-
object: obj,
|
3628
|
-
parent: a,
|
3629
|
-
text: typeof prop.attributionText === 'string' ? prop.attributionText : 'JavaScript charts with RGraph',
|
3630
|
-
x: x,
|
3631
|
-
y: y,
|
3632
|
-
halign: prop.attributionHalign || 'right',
|
3633
|
-
valign: prop.attributionValign || 'bottom',
|
3634
|
-
font: prop.attributionFont || 'sans-serif',
|
3635
|
-
size: prop.attributionSize || 7,
|
3636
|
-
color: prop.attributionColor || 'gray',
|
3637
|
-
italic: prop.attributionItalic,
|
3638
|
-
bold: prop.attributionBold
|
3639
|
-
});
|
3640
|
-
*/
|
3641
|
-
};
|
3642
|
-
|
3643
|
-
|
3644
|
-
|
3645
|
-
|
3646
|
-
|
3647
|
-
|
3648
|
-
|
3649
|
-
|
3650
|
-
/**
|
3651
|
-
* Parse a gradient and returns the various parts
|
3652
|
-
*
|
3653
|
-
* @param string str The gradient string
|
3654
|
-
*/
|
3655
|
-
RG.SVG.parseGradient = function (str)
|
3656
|
-
{
|
3657
|
-
};
|
3658
|
-
|
3659
|
-
|
3660
|
-
|
3661
|
-
|
3662
|
-
|
3663
|
-
|
3664
|
-
|
3665
|
-
|
3666
|
-
/**
|
3667
|
-
* Generates a random number between the minimum and maximum
|
3668
|
-
*
|
3669
|
-
* @param number min The minimum value
|
3670
|
-
* @param number max The maximum value
|
3671
|
-
* @param number OPTIONAL Number of decimal places
|
3672
|
-
*/
|
3673
|
-
RG.SVG.random = function (opt)
|
3674
|
-
{
|
3675
|
-
var min = opt.min,
|
3676
|
-
max = opt.max,
|
3677
|
-
dp = opt.dp || opt.decimals || 0,
|
3678
|
-
r = ma.random();
|
3679
|
-
|
3680
|
-
return Number((((max - min) * r) + min).toFixed(dp));
|
3681
|
-
};
|
3682
|
-
|
3683
|
-
|
3684
|
-
|
3685
|
-
|
3686
|
-
|
3687
|
-
|
3688
|
-
|
3689
|
-
|
3690
|
-
/**
|
3691
|
-
* Fill an array full of random numbers
|
3692
|
-
*/
|
3693
|
-
RG.SVG.arrayRand =
|
3694
|
-
RG.SVG.arrayRandom =
|
3695
|
-
RG.SVG.random.array = function (opt)
|
3696
|
-
{
|
3697
|
-
var num = opt.num,
|
3698
|
-
min = opt.min,
|
3699
|
-
max = opt.max,
|
3700
|
-
dp = opt.dp || opt.decimals || 0;
|
3701
|
-
|
3702
|
-
for(var i=0,arr=[]; i<num; i+=1) {
|
3703
|
-
arr.push(RG.SVG.random({min: min, max: max, dp: dp}));
|
3704
|
-
}
|
3705
|
-
|
3706
|
-
return arr;
|
3707
|
-
};
|
3708
|
-
|
3709
|
-
|
3710
|
-
|
3711
|
-
|
3712
|
-
|
3713
|
-
|
3714
|
-
|
3715
|
-
|
3716
|
-
//
|
3717
|
-
// This function is called by each objects setter so that common BC
|
3718
|
-
// and adjustments are centralised. And there's less typing for me too.
|
3719
|
-
//
|
3720
|
-
// @param object opt An object of options to the function, which are:
|
3721
|
-
// object: The chart object
|
3722
|
-
// name: The name of the config parameter
|
3723
|
-
// value: The value thats being set
|
3724
|
-
//
|
3725
|
-
RG.SVG.commonSetter = function (opt)
|
3726
|
-
{
|
3727
|
-
var obj = opt.object,
|
3728
|
-
name = opt.name,
|
3729
|
-
value = opt.value;
|
3730
|
-
|
3731
|
-
// The default event for tooltips is click
|
3732
|
-
if (name === 'tooltipsEvent'&& value !== 'click' && value !== 'mousemove') {
|
3733
|
-
value = 'click';
|
3734
|
-
}
|
3735
|
-
|
3736
|
-
return {
|
3737
|
-
name: name,
|
3738
|
-
value: value
|
3739
|
-
};
|
3740
|
-
};
|
3741
|
-
|
3742
|
-
|
3743
|
-
|
3744
|
-
|
3745
|
-
|
3746
|
-
|
3747
|
-
|
3748
|
-
|
3749
|
-
//
|
3750
|
-
// Generates logs for... log charts
|
3751
|
-
//
|
3752
|
-
// @param object opt The options:
|
3753
|
-
// o num The number
|
3754
|
-
// o base The base
|
3755
|
-
//
|
3756
|
-
RG.SVG.log = function (opt)
|
3757
|
-
{
|
3758
|
-
var num = opt.num,
|
3759
|
-
base = opt.base;
|
3760
|
-
|
3761
|
-
return ma.log(num) / (base ? ma.log(base) : 1);
|
3762
|
-
};
|
3763
|
-
|
3764
|
-
|
3765
|
-
|
3766
|
-
|
3767
|
-
|
3768
|
-
|
3769
|
-
|
3770
|
-
|
3771
|
-
RG.SVG.donut = function (opt)
|
3772
|
-
{
|
3773
|
-
var arcPath1 = RG.SVG.TRIG.getArcPath3({
|
3774
|
-
cx: opt.cx,
|
3775
|
-
cy: opt.cy,
|
3776
|
-
r: opt.outerRadius,
|
3777
|
-
start: 0,
|
3778
|
-
end: RG.SVG.TRIG.TWOPI,
|
3779
|
-
anticlockwise: false,
|
3780
|
-
lineto: false
|
3781
|
-
});
|
3782
|
-
|
3783
|
-
var arcPath2 = RG.SVG.TRIG.getArcPath3({
|
3784
|
-
cx: opt.cx,
|
3785
|
-
cy: opt.cy,
|
3786
|
-
r: opt.innerRadius,
|
3787
|
-
start: RG.SVG.TRIG.TWOPI,
|
3788
|
-
end: 0,
|
3789
|
-
anticlockwise: true,
|
3790
|
-
lineto: false
|
3791
|
-
});
|
3792
|
-
|
3793
|
-
//
|
3794
|
-
// Create the red circle
|
3795
|
-
//
|
3796
|
-
var path = RG.SVG.create({
|
3797
|
-
svg: opt.svg,
|
3798
|
-
type: 'path',
|
3799
|
-
attr: {
|
3800
|
-
d: arcPath1 + arcPath2,
|
3801
|
-
stroke: opt.stroke,
|
3802
|
-
fill: opt.fill
|
3803
|
-
}
|
3804
|
-
});
|
3805
|
-
|
3806
|
-
return path;
|
3807
|
-
};
|
3808
|
-
|
3809
|
-
|
3810
|
-
|
3811
|
-
|
3812
|
-
|
3813
|
-
|
3814
|
-
|
3815
|
-
|
3816
|
-
//
|
3817
|
-
// This is here so that if the tooltip library has not
|
3818
|
-
// been included, this function will show an alert
|
3819
|
-
//informing the user
|
3820
|
-
//
|
3821
|
-
if (typeof RG.SVG.tooltip !== 'function') {
|
3822
|
-
RG.SVG.tooltip = function ()
|
3823
|
-
{
|
3824
|
-
$a('The tooltip library has not been included!');
|
3825
|
-
};
|
3826
|
-
}
|
3827
|
-
|
3828
|
-
|
3829
|
-
|
3830
|
-
|
3831
|
-
|
3832
|
-
|
3833
|
-
|
3834
|
-
|
3835
|
-
// End module pattern
|
3836
|
-
})(window, document);
|
3837
|
-
|
3838
|
-
|
3839
|
-
|
3840
|
-
|
3841
|
-
/**
|
3842
|
-
* Loosly mimicks the PHP function print_r();
|
3843
|
-
*/
|
3844
|
-
window.$p = function (obj)
|
3845
|
-
{
|
3846
|
-
var indent = (arguments[2] ? arguments[2] : ' ');
|
3847
|
-
var str = '';
|
3848
|
-
|
3849
|
-
var counter = typeof arguments[3] == 'number' ? arguments[3] : 0;
|
3850
|
-
|
3851
|
-
if (counter >= 5) {
|
3852
|
-
return '';
|
3853
|
-
}
|
3854
|
-
|
3855
|
-
switch (typeof obj) {
|
3856
|
-
|
3857
|
-
case 'string': str += obj + ' (' + (typeof obj) + ', ' + obj.length + ')'; break;
|
3858
|
-
case 'number': str += obj + ' (' + (typeof obj) + ')'; break;
|
3859
|
-
case 'boolean': str += obj + ' (' + (typeof obj) + ')'; break;
|
3860
|
-
case 'function': str += 'function () {}'; break;
|
3861
|
-
case 'undefined': str += 'undefined'; break;
|
3862
|
-
case 'null': str += 'null'; break;
|
3863
|
-
|
3864
|
-
case 'object':
|
3865
|
-
// In case of null
|
3866
|
-
if (RGraph.SVG.isNull(obj)) {
|
3867
|
-
str += indent + 'null\n';
|
3868
|
-
} else {
|
3869
|
-
str += indent + 'Object {' + '\n'
|
3870
|
-
for (j in obj) {
|
3871
|
-
str += indent + ' ' + j + ' => ' + window.$p(obj[j], true, indent + ' ', counter + 1) + '\n';
|
3872
|
-
}
|
3873
|
-
str += indent + '}';
|
3874
|
-
}
|
3875
|
-
break;
|
3876
|
-
|
3877
|
-
|
3878
|
-
default:
|
3879
|
-
str += 'Unknown type: ' + typeof obj + '';
|
3880
|
-
break;
|
3881
|
-
}
|
3882
|
-
|
3883
|
-
|
3884
|
-
/**
|
3885
|
-
* Finished, now either return if we're in a recursed call, or alert()
|
3886
|
-
* if we're not.
|
3887
|
-
*/
|
3888
|
-
if (!arguments[1]) {
|
3889
|
-
alert(str);
|
3890
|
-
}
|
3891
|
-
|
3892
|
-
return str;
|
3893
|
-
};
|
3894
|
-
|
3895
|
-
|
3896
|
-
|
3897
|
-
/**
|
3898
|
-
* A shorthand for the default alert() function
|
3899
|
-
*/
|
3900
|
-
window.$a = function (v)
|
3901
|
-
{
|
3902
|
-
alert(v);
|
3903
|
-
};
|
3904
|
-
|
3905
|
-
|
3906
|
-
|
3907
|
-
|
3908
|
-
/**
|
3909
|
-
* Short-hand for console.log
|
3910
|
-
*
|
3911
|
-
* @param mixed v The variable to log to the console
|
3912
|
-
*/
|
3913
|
-
window.$cl = function (v)
|
3914
|
-
{
|
3915
|
-
return console.log(v);
|
3916
|
-
};
|
3917
|
-
|
3918
|
-
|
3919
|
-
|
3920
|
-
|
3921
|
-
/**
|
3922
|
-
* A basic string formatting function. Use it like this:
|
3923
|
-
*
|
3924
|
-
* var str = '{0} {1} {2}'.format('a', 'b', 'c');
|
3925
|
-
*
|
3926
|
-
* Outputs: a b c
|
3927
|
-
*/
|
3928
|
-
if (!String.prototype.format) {
|
3929
|
-
String.prototype.format = function()
|
3930
|
-
{
|
3931
|
-
var args = arguments;
|
3932
|
-
|
3933
|
-
return this.replace(/{(\d+)}/g, function(str, idx)
|
3934
|
-
{
|
3935
|
-
return typeof args[idx - 1] !== 'undefined' ? args[idx - 1] : str;
|
3936
|
-
});
|
3937
|
-
};
|
3938
|
-
}
|
2
|
+
RGraph=window.RGraph||{isRGraph:true,isRGraphSVG:true};RGraph.SVG=RGraph.SVG||{};RGraph.SVG.FX=RGraph.SVG.FX||{};(function(win,doc,undefined)
|
3
|
+
{var RG=RGraph,ua=navigator.userAgent,ma=Math;RG.SVG.REG={store:[]};RG.SVG.OR={objects:[]};RG.SVG.TRIG={};RG.SVG.TRIG.HALFPI=ma.PI*.4999;RG.SVG.TRIG.PI=RG.SVG.TRIG.HALFPI*2;RG.SVG.TRIG.TWOPI=RG.SVG.TRIG.PI*2;RG.SVG.ISIE=ua.indexOf('rident')>0;RG.SVG.ISFF=ua.indexOf('irefox')>0;RG.SVG.events=[];RG.SVG.GLOBALS={};RG.SVG.ISFF=ua.indexOf('Firefox')!=-1;RG.SVG.ISOPERA=ua.indexOf('Opera')!=-1;RG.SVG.ISCHROME=ua.indexOf('Chrome')!=-1;RG.SVG.ISSAFARI=ua.indexOf('Safari')!=-1&&!RG.ISCHROME;RG.SVG.ISWEBKIT=ua.indexOf('WebKit')!=-1;RG.SVG.ISIE=ua.indexOf('Trident')>0||navigator.userAgent.indexOf('MSIE')>0;RG.SVG.ISIE6=ua.indexOf('MSIE 6')>0;RG.SVG.ISIE7=ua.indexOf('MSIE 7')>0;RG.SVG.ISIE8=ua.indexOf('MSIE 8')>0;RG.SVG.ISIE9=ua.indexOf('MSIE 9')>0;RG.SVG.ISIE10=ua.indexOf('MSIE 10')>0;RG.SVG.ISIE11UP=ua.indexOf('MSIE')==-1&&ua.indexOf('Trident')>0;RG.SVG.ISIE10UP=RG.SVG.ISIE10||RG.SVG.ISIE11UP;RG.SVG.ISIE9UP=RG.SVG.ISIE9||RG.SVG.ISIE10UP;RG.SVG.createSVG=function(opt)
|
4
|
+
{var container=opt.container,obj=opt.object;if(container.__svg__){return container.__svg__;}
|
5
|
+
var svg=doc.createElementNS("http://www.w3.org/2000/svg","svg");svg.setAttribute('style','top: 0; left: 0; position: absolute');svg.setAttribute('width',container.offsetWidth);svg.setAttribute('height',container.offsetHeight);svg.setAttribute('version','1.1');svg.setAttributeNS("http://www.w3.org/2000/xmlns/",'xmlns','http://www.w3.org/2000/svg');svg.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink");container.appendChild(svg);container.__svg__=svg;container.style.position='relative';var numLayers=10;for(var i=1;i<=numLayers;++i){var group=RG.SVG.create({svg:svg,type:'g',attr:{className:'background'+i}});obj.layers['background'+i]=group;svg['background'+i]=group;}
|
6
|
+
var group=RG.SVG.create({svg:svg,type:'g',attr:{className:'all-elements'}});container.__svg__.all=group;return svg;};RG.SVG.createDefs=function(obj)
|
7
|
+
{if(!obj.svg.defs){var defs=RG.SVG.create({svg:obj.svg,type:'defs'});obj.svg.defs=defs;}
|
8
|
+
return defs;};RG.SVG.create=function(opt)
|
9
|
+
{var ns="http://www.w3.org/2000/svg",tag=doc.createElementNS(ns,opt.type);for(var o in opt.attr){if(typeof o==='string'){var name=o;if(o==='className'){name='class';}
|
10
|
+
if((opt.type==='a'||opt.type==='image')&&o==='xlink:href'){tag.setAttributeNS('http://www.w3.org/1999/xlink',o,String(opt.attr[o]));}else{tag.setAttribute(name,String(opt.attr[o]));}}}
|
11
|
+
for(var o in opt.style){if(typeof o==='string'){tag.style[o]=String(opt.style[o]);}}
|
12
|
+
if(opt.parent){opt.parent.appendChild(tag);}else{opt.svg.appendChild(tag);}
|
13
|
+
return tag;};RG.SVG.getMouseXY=function(e)
|
14
|
+
{if(!e.target){return;}
|
15
|
+
var el=e.target,offsetX=0,offsetY=0,x,y;if(typeof el.offsetParent!=='undefined'){do{offsetX+=el.offsetLeft;offsetY+=el.offsetTop;}while((el=el.offsetParent));}
|
16
|
+
x=e.pageX;y=e.pageY;x-=(2*(parseInt(document.body.style.borderLeftWidth)||0));y-=(2*(parseInt(document.body.style.borderTopWidth)||0));return[x,y];};RG.SVG.drawXAxis=function(obj)
|
17
|
+
{var prop=obj.properties;if(prop.xaxis){var y=obj.type==='hbar'?obj.height-prop.gutterBottom:obj.getYCoord(obj.scale.min<0&&obj.scale.max<0?obj.scale.max:(obj.scale.min>0&&obj.scale.max>0?obj.scale.min:0));var axis=RG.SVG.create({svg:obj.svg,parent:obj.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(prop.gutterLeft,y,obj.width-prop.gutterRight,y),fill:prop.xaxisColor,stroke:prop.xaxisColor,'stroke-width':typeof prop.xaxisLinewidth==='number'?prop.xaxisLinewidth:1,'shape-rendering':'crispEdges','stroke-linecap':'square'}});if(obj.type==='hbar'){var width=obj.graphWidth/obj.data.length,x=prop.gutterLeft,startY=(obj.height-prop.gutterBottom),endY=(obj.height-prop.gutterBottom)+prop.xaxisTickmarksLength;}else{var width=obj.graphWidth/obj.data.length,x=prop.gutterLeft,startY=obj.getYCoord(0)-(prop.yaxisMin<0?prop.xaxisTickmarksLength:0),endY=obj.getYCoord(0)+prop.xaxisTickmarksLength;if(obj.scale.min<0&&obj.scale.max<=0){startY=prop.gutterTop;endY=prop.gutterTop-prop.xaxisTickmarksLength;}
|
18
|
+
if(obj.scale.min>0&&obj.scale.max>0){startY=obj.getYCoord(obj.scale.min);endY=obj.getYCoord(obj.scale.min)+prop.xaxisTickmarksLength;}}
|
19
|
+
if(prop.xaxisTickmarks){if(prop.xaxisScale){for(var i=0;i<(typeof prop.xaxisLabelsPositionEdgeTickmarksCount==='number'?prop.xaxisLabelsPositionEdgeTickmarksCount:(obj.scale.numlabels+(prop.yaxis&&prop.xaxisMin===0?0:1)));++i){if(obj.type==='hbar'){var dataPoints=obj.data.length;}
|
20
|
+
x=prop.gutterLeft+((i+(prop.yaxis&&prop.xaxisMin===0?1:0))*(obj.graphWidth/obj.scale.numlabels));if(typeof prop.xaxisLabelsPositionEdgeTickmarksCount==='number'){dataPoints=prop.xaxisLabelsPositionEdgeTickmarksCount;var gap=(obj.graphWidth/prop.xaxisLabelsPositionEdgeTickmarksCount);x=(gap*i)+prop.gutterLeft+gap;}
|
21
|
+
RG.SVG.create({svg:obj.svg,parent:obj.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(x,startY,x,endY),stroke:prop.xaxisColor,'stroke-width':typeof prop.xaxisLinewidth==='number'?prop.xaxisLinewidth:1,'shape-rendering':"crispEdges"}});}}else{if(prop.xaxisLabelsPosition==='section'){if(obj.type==='bar'||obj.type==='waterfall'){var dataPoints=obj.data.length;}else if(obj.type==='line'){var dataPoints=obj.data[0].length;}else if(obj.type==='scatter'){var dataPoints=prop.xaxisLabels?prop.xaxisLabels.length:10;}
|
22
|
+
if(typeof prop.xaxisLabelsPositionSectionTickmarksCount==='number'){dataPoints=prop.xaxisLabelsPositionSectionTickmarksCount;}
|
23
|
+
for(var i=0;i<dataPoints;++i){x=prop.gutterLeft+((i+1)*(obj.graphWidth/dataPoints));RG.SVG.create({svg:obj.svg,parent:obj.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(x+0.001,startY,x,endY),stroke:prop.xaxisColor,'stroke-width':typeof prop.xaxisLinewidth==='number'?prop.xaxisLinewidth:1,'shape-rendering':"crispEdges"}});}}else if(prop.xaxisLabelsPosition==='edge'){if(typeof prop.xaxisLabelsPositionEdgeTickmarksCount==='number'){var len=prop.xaxisLabelsPositionEdgeTickmarksCount;}else{var len=obj.data&&obj.data[0]&&obj.data[0].length?obj.data[0].length:0;}
|
24
|
+
for(var i=0;i<len;++i){var gap=((obj.graphWidth)/(len-1)),x=prop.gutterLeft+((i+1)*gap);RG.SVG.create({svg:obj.svg,parent:obj.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(x+0.001,startY,x,endY),stroke:prop.xaxisColor,'stroke-width':typeof prop.xaxisLinewidth==='number'?prop.xaxisLinewidth:1,'shape-rendering':"crispEdges"}});}}}
|
25
|
+
if(prop.yaxis===false){RG.SVG.create({svg:obj.svg,parent:obj.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(prop.gutterLeft+0.001,startY,prop.gutterLeft,endY),stroke:obj.properties.xaxisColor,'stroke-width':typeof prop.xaxisLinewidth==='number'?prop.xaxisLinewidth:1,'shape-rendering':"crispEdges",parent:obj.svg.all,}});}}}
|
26
|
+
if(prop.xaxisScale){var segment=obj.graphWidth/prop.xaxisLabelsCount;for(var i=0;i<obj.scale.labels.length;++i){var x=prop.gutterLeft+(segment*i)+segment+prop.xaxisLabelsOffsetx;RG.SVG.text({object:obj,parent:obj.svg.all,text:obj.scale.labels[i],x:x,y:(obj.height-prop.gutterBottom)+(prop.xaxis?prop.xaxisTickmarksLength+6:10)+(prop.xaxisLinewidth||1)+prop.xaxisLabelsOffsety,halign:'center',valign:'top',font:prop.xaxisTextFont||prop.textFont,size:prop.xaxisTextSize||(typeof prop.textSize==='number'?prop.textSize+'pt':prop.textSize),bold:prop.xaxisTextBold||prop.textBold,italic:prop.xaxisTextItalic||prop.textItalic,color:prop.xaxisTextColor||prop.textColor});}
|
27
|
+
if(prop.xaxisLabelsCount>0){var y=obj.height-prop.gutterBottom+prop.xaxisLabelsOffsety+(prop.xaxis?prop.xaxisTickmarksLength+6:10),str=RG.SVG.numberFormat({object:obj,num:prop.xaxisMin.toFixed(prop.xaxisDecimals),prepend:prop.xaxisUnitsPre,append:prop.xaxisUnitsPost,point:prop.xaxisPoint,thousand:prop.xaxisThousand,formatter:prop.xaxisFormatter});var text=RG.SVG.text({object:obj,parent:obj.svg.all,text:typeof prop.xaxisFormatter==='function'?(prop.xaxisFormatter)(this,prop.xaxisMin):str,x:prop.gutterLeft+prop.xaxisLabelsOffsetx,y:y,halign:'center',valign:'top',font:prop.xaxisTextFont||prop.textFont,size:prop.xaxisTextSize||(typeof prop.textSize==='number'?prop.textSize+'pt':prop.textSize),bold:prop.xaxisTextBold||prop.textBold,italic:prop.xaxisTextItalic||prop.textItalic,color:prop.xaxisTextColor||prop.textColor});}}else{if(typeof prop.xaxisLabels==='object'&&!RG.SVG.isNull(prop.xaxisLabels)){if(prop.xaxisLabelsPosition==='section'){var segment=(obj.width-prop.gutterLeft-prop.gutterRight)/prop.xaxisLabels.length;for(var i=0;i<prop.xaxisLabels.length;++i){var x=prop.gutterLeft+(segment/2)+(i*segment);if(obj.scale.max<=0&&obj.scale.min<obj.scale.max){var y=prop.gutterTop-(RG.SVG.ISFF?5:10)-(prop.xaxisLinewidth||1)+prop.xaxisLabelsOffsety;var valign='bottom';}else{var y=obj.height-prop.gutterBottom+(RG.SVG.ISFF?5:10)+(prop.xaxisLinewidth||1)+prop.xaxisLabelsOffsety;var valign='top';}
|
28
|
+
RG.SVG.text({object:obj,parent:obj.svg.all,text:prop.xaxisLabels[i],x:x+prop.xaxisLabelsOffsetx,y:y,valign:valign,halign:'center',size:prop.xaxisTextSize||prop.textSize,italic:prop.xaxisTextItalic||prop.textItalic,font:prop.xaxisTextFont||prop.textFont,bold:prop.xaxisTextBold||prop.textBold,color:prop.xaxisTextColor||prop.textColor});}}else if(prop.xaxisLabelsPosition==='edge'){if(obj.type==='line'){var hmargin=prop.hmargin;}else{var hmargin=0;}
|
29
|
+
var segment=(obj.graphWidth-hmargin-hmargin)/(prop.xaxisLabels.length-1);for(var i=0;i<prop.xaxisLabels.length;++i){var x=prop.gutterLeft+(i*segment)+hmargin;if(obj.scale.max<=0&&obj.scale.min<0){valign='bottom';y=prop.gutterTop-(RG.SVG.ISFF?5:10)-(prop.xaxisTickmarksLength-5)-(prop.xaxisLinewidth||1)+prop.xaxisLabelsOffsety}else{valign='top';y=obj.height-prop.gutterBottom+(RG.SVG.ISFF?5:10)+(prop.xaxisTickmarksLength-5)+(prop.xaxisLinewidth||1)+prop.xaxisLabelsOffsety;}
|
30
|
+
RG.SVG.text({object:obj,parent:obj.svg.all,text:prop.xaxisLabels[i],x:x+prop.xaxisLabelsOffsetx,y:y,valign:valign,halign:'center',size:prop.xaxisTextSize||prop.textSize,italic:prop.xaxisTextItalic||prop.textItalic,font:prop.xaxisTextFont||prop.textFont,bold:prop.xaxisTextBold||prop.textBold,color:prop.xaxisTextColor||prop.textColor});}}}}};RG.SVG.drawYAxis=function(obj)
|
31
|
+
{var prop=obj.properties;if(prop.yaxis){if(obj.type==='hbar'){var x=obj.getXCoord(prop.xaxisMin>0?prop.xaxisMin:0);if(prop.xaxisMin<0&&prop.xaxisMax<=0){x=obj.getXCoord(prop.xaxisMax);}}else{var x=prop.gutterLeft;}
|
32
|
+
var axis=RG.SVG.create({svg:obj.svg,parent:obj.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(x,prop.gutterTop,x,obj.height-prop.gutterBottom),stroke:prop.yaxisColor,fill:prop.yaxisColor,'stroke-width':typeof prop.yaxisLinewidth==='number'?prop.yaxisLinewidth:1,'shape-rendering':"crispEdges",'stroke-linecap':'square'}});if(obj.type==='hbar'){var height=(obj.graphHeight-prop.vmarginTop-prop.vmarginBottom)/prop.yaxisLabels.length,y=prop.gutterTop+prop.vmarginTop,len=prop.yaxisLabels.length,startX=obj.getXCoord(0)+(prop.xaxisMin<0?prop.yaxisTickmarksLength:0),endX=obj.getXCoord(0)-prop.yaxisTickmarksLength;if(prop.xaxisMin<0&&prop.xaxisMax<=0){startX=obj.getXCoord(prop.xaxisMax);endX=obj.getXCoord(prop.xaxisMax)+5;}
|
33
|
+
if(typeof prop.yaxisLabelsPositionSectionTickmarksCount==='number'){len=prop.yaxisLabelsPositionSectionTickmarksCount;height=(obj.graphHeight-prop.vmarginTop-prop.vmarginBottom)/len;}
|
34
|
+
if(prop.yaxisTickmarks){for(var i=0;i<len;++i){var axis=RG.SVG.create({svg:obj.svg,parent:obj.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(startX,y,endX,y+0.001),stroke:prop.yaxisColor,'stroke-width':typeof prop.yaxisLinewidth==='number'?prop.yaxisLinewidth:1,'shape-rendering':"crispEdges"}});y+=height;}
|
35
|
+
if(prop.xaxis===false){if(obj.type==='hbar'&&prop.xaxisMin<=0&&prop.xaxisMax<0){var startX=obj.getXCoord(prop.xaxisMax);var endX=obj.getXCoord(prop.xaxisMax)+prop.yaxisTickmarksLength;}else{var startX=obj.getXCoord(0)-prop.yaxisTickmarksLength;var endX=obj.getXCoord(0)+(prop.xaxisMin<0?prop.yaxisTickmarksLength:0);}
|
36
|
+
var axis=RG.SVG.create({svg:obj.svg,parent:obj.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(startX,ma.round(obj.height-prop.gutterBottom-parseFloat(prop.vmarginBottom)),endX,ma.round(obj.height-prop.gutterBottom-parseFloat(prop.vmarginBottom))),stroke:obj.properties.yaxisColor,'stroke-width':typeof prop.yaxisLinewidth==='number'?prop.yaxisLinewidth:1,'shape-rendering':"crispEdges"}});}}}else{var height=obj.graphHeight/prop.yaxisLabelsCount,y=prop.gutterTop,len=prop.yaxisLabelsCount,startX=prop.gutterLeft,endX=prop.gutterLeft-prop.yaxisTickmarksLength;if(typeof prop.yaxisLabelsPositionEdgeTickmarksCount==='number'){len=prop.yaxisLabelsPositionEdgeTickmarksCount;height=obj.graphHeight/len;}
|
37
|
+
if(prop.yaxisTickmarks){for(var i=0;i<len;++i){var axis=RG.SVG.create({svg:obj.svg,parent:obj.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(startX,y,endX,y),stroke:prop.yaxisColor,'stroke-width':typeof prop.yaxisLinewidth==='number'?prop.yaxisLinewidth:1,'shape-rendering':"crispEdges"}});y+=height;}
|
38
|
+
if((prop.yaxisMin!==0||prop.xaxis===false)&&!(obj.scale.min>0&&obj.scale.max>0)){var axis=RG.SVG.create({svg:obj.svg,parent:obj.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(prop.gutterLeft-prop.yaxisTickmarksLength,obj.height-prop.gutterBottom,prop.gutterLeft,obj.height-prop.gutterBottom-0.001),stroke:prop.yaxisColor,'stroke-width':typeof prop.yaxisLinewidth==='number'?prop.yaxisLinewidth:1,'shape-rendering':"crispEdges"}});}}}}
|
39
|
+
if(prop.yaxisScale){var segment=(obj.height-prop.gutterTop-prop.gutterBottom)/prop.yaxisLabelsCount;for(var i=0;i<obj.scale.labels.length;++i){var y=obj.height-prop.gutterBottom-(segment*i)-segment;RG.SVG.text({object:obj,parent:obj.svg.all,text:obj.scale.labels[i],x:prop.gutterLeft-7-(prop.yaxis?(prop.yaxisTickmarksLength-3):0)+prop.yaxisLabelsOffsetx,y:y+prop.yaxisLabelsOffsety,halign:'right',valign:'center',font:prop.yaxisTextFont||prop.textFont,size:prop.yaxisTextSize||(typeof prop.textSize==='number'?prop.textSize+'pt':prop.textSize),bold:prop.yaxisTextBold||prop.textBold,italic:prop.yaxisTextItalic||prop.textItalic,color:prop.yaxisTextColor||prop.textColor});}
|
40
|
+
var y=obj.height-prop.gutterBottom,str=(prop.yaxisUnitsPre+prop.yaxisMin.toFixed(prop.yaxisDecimals).replace(/\./,prop.yaxisPoint)+prop.yaxisUnitsPost);var text=RG.SVG.text({object:obj,parent:obj.svg.all,text:typeof prop.yaxisFormatter==='function'?(prop.yaxisFormatter)(this,prop.yaxisMin):str,x:prop.gutterLeft-7-(prop.yaxis?(prop.yaxisTickmarksLength-3):0)+prop.yaxisLabelsOffsetx,y:y+prop.yaxisLabelsOffsety,halign:'right',valign:'center',font:prop.yaxisTextFont||prop.textFont,size:prop.yaxisTextSize||(typeof prop.textSize==='number'?prop.textSize+'pt':prop.textSize),bold:prop.yaxisTextBold||prop.textBold,italic:prop.yaxisTextItalic||prop.textItalic,color:prop.yaxisTextColor||prop.textColor});}else if(prop.yaxisLabels&&prop.yaxisLabels.length){for(var i=0;i<prop.yaxisLabels.length;++i){var segment=(obj.graphHeight-(prop.vmarginTop||0)-(prop.vmarginBottom||0))/prop.yaxisLabels.length,y=prop.gutterTop+(prop.vmarginTop||0)+(segment*i)+(segment/2)+prop.yaxisLabelsOffsety,x=prop.gutterLeft-7-(prop.yaxisLinewidth||1)+prop.yaxisLabelsOffsetx,halign='right';if(obj.type==='hbar'&&obj.scale.min<obj.scale.max&&obj.scale.max<=0){halign='left';x=obj.width-prop.gutterRight+7+prop.yaxisLabelsOffsetx;}else if(obj.type==='hbar'&&!prop.yaxisLabelsSpecific){var segment=(obj.graphHeight-(prop.vmarginTop||0)-(prop.vmarginBottom||0))/(prop.yaxisLabels.length);y=prop.gutterTop+(prop.vmarginTop||0)+(segment*i)+(segment/2)+prop.yaxisLabelsOffsetx;}else{var segment=(obj.graphHeight-(prop.vmarginTop||0)-(prop.vmarginBottom||0))/(prop.yaxisLabels.length-1);y=obj.height-prop.gutterBottom-(segment*i)+prop.yaxisLabelsOffsetx;}
|
41
|
+
var text=RG.SVG.text({object:obj,parent:obj.svg.all,text:prop.yaxisLabels[i]?prop.yaxisLabels[i]:'',x:x,y:y,halign:halign,valign:'center',font:prop.yaxisTextFont||prop.textFont,size:prop.yaxisTextSize||(typeof prop.textSize==='number'?prop.textSize+'pt':prop.textSize),bold:prop.yaxisTextBold||prop.textBold,italic:prop.yaxisTextItalic||prop.textItalic,color:prop.yaxisTextColor||prop.textColor});}}};RG.SVG.drawBackground=function(obj)
|
42
|
+
{var prop=obj.properties;if(typeof prop.variant3dOffsetx!=='number')prop.variant3dOffsetx=0;if(typeof prop.variant3dOffsety!=='number')prop.variant3dOffsety=0;if(prop.backgroundColor){RG.SVG.create({svg:obj.svg,parent:obj.svg.all,type:'rect',attr:{x:-1+prop.variant3dOffsetx+prop.gutterLeft,y:-1-prop.variant3dOffsety+prop.gutterTop,width:parseFloat(obj.svg.getAttribute('width'))+2-prop.gutterLeft-prop.gutterRight,height:parseFloat(obj.svg.getAttribute('height'))+2-prop.gutterTop-prop.gutterBottom,fill:prop.backgroundColor}});}
|
43
|
+
if(prop.backgroundImage){var attr={'xlink:href':prop.backgroundImage,preserveAspectRatio:prop.backgroundImageAspect||'none',x:prop.gutterLeft,y:prop.gutterTop};if(prop.backgroundImageStretch){attr.x=prop.gutterLeft+prop.variant3dOffsetx;attr.y=prop.gutterTop+prop.variant3dOffsety;attr.width=obj.width-prop.gutterLeft-prop.gutterRight;attr.height=obj.height-prop.gutterTop-prop.gutterBottom;}else{if(typeof prop.backgroundImageX==='number'){attr.x=prop.backgroundImageX+prop.variant3dOffsetx;}
|
44
|
+
if(typeof prop.backgroundImageY==='number'){attr.y=prop.backgroundImageY+prop.variant3dOffsety;}
|
45
|
+
if(typeof prop.backgroundImageW==='number'){attr.width=prop.backgroundImageW;}
|
46
|
+
if(typeof prop.backgroundImageH==='number'){attr.height=prop.backgroundImageH;}}
|
47
|
+
if(prop.variant==='3d'){attr.x+=prop.variant3dOffsetx;attr.y-=prop.variant3dOffsety;}
|
48
|
+
var img=RG.SVG.create({svg:obj.svg,parent:obj.svg.all,type:'image',attr:attr,style:{opacity:typeof prop.backgroundImageOpacity==='number'?prop.backgroundImageOpacity:1}});}
|
49
|
+
if(prop.backgroundGrid){var parts=[];if(prop.backgroundGridHlines){var count=typeof prop.backgroundGridHlinesCount==='number'?prop.backgroundGridHlinesCount:(obj.type==='hbar'?(prop.yaxisLabels.length||obj.data.length||5):prop.yaxisLabelsCount);for(var i=0;i<=count;++i){parts.push('M{1} {2} L{3} {4}'.format(prop.gutterLeft+prop.variant3dOffsetx,prop.gutterTop+(obj.graphHeight/count)*i-prop.variant3dOffsety,obj.width-prop.gutterRight+prop.variant3dOffsetx,prop.gutterTop+(obj.graphHeight/count)*i-prop.variant3dOffsety));}
|
50
|
+
parts.push('M{1} {2} L{3} {4}'.format(prop.gutterLeft+prop.variant3dOffsetx,obj.height-prop.gutterBottom-prop.variant3dOffsety,obj.width-prop.gutterRight+prop.variant3dOffsetx,obj.height-prop.gutterBottom-prop.variant3dOffsety));}
|
51
|
+
if(prop.backgroundGridVlines){if(obj.type==='line'&&RG.SVG.isArray(obj.data[0])){var len=obj.data[0].length;}else if(obj.type==='hbar'){var len=prop.xaxisLabelsCount||10;}else if(obj.type==='scatter'){var len=(prop.xaxisLabels&&prop.xaxisLabels.length)||10;}else{var len=obj.data.length;}
|
52
|
+
var count=typeof prop.backgroundGridVlinesCount==='number'?prop.backgroundGridVlinesCount:len;if(prop.xaxisLabelsPosition==='edge'){count--;}
|
53
|
+
for(var i=0;i<=count;++i){parts.push('M{1} {2} L{3} {4}'.format(prop.gutterLeft+((obj.graphWidth/count)*i)+prop.variant3dOffsetx,prop.gutterTop-prop.variant3dOffsety,prop.gutterLeft+((obj.graphWidth/count)*i)+prop.variant3dOffsetx,obj.height-prop.gutterBottom-prop.variant3dOffsety));}}
|
54
|
+
if(prop.backgroundGridBorder){parts.push('M{1} {2} L{3} {4} L{5} {6} L{7} {8} z'.format(prop.gutterLeft+prop.variant3dOffsetx,prop.gutterTop-prop.variant3dOffsety,obj.width-prop.gutterRight+prop.variant3dOffsetx,prop.gutterTop-prop.variant3dOffsety,obj.width-prop.gutterRight+prop.variant3dOffsetx,obj.height-prop.gutterBottom-prop.variant3dOffsety,prop.gutterLeft+prop.variant3dOffsetx,obj.height-prop.gutterBottom-prop.variant3dOffsety));}
|
55
|
+
var dasharray;if(prop.backgroundGridDashed){dasharray=[3,5];}else if(prop.backgroundGridDotted){dasharray=[1,3];}else if(prop.backgroundGridDashArray){dasharray=prop.backgroundGridDashArray;}else{dasharray='';}
|
56
|
+
var grid=RG.SVG.create({svg:obj.svg,parent:obj.svg.all,type:'path',attr:{d:parts.join(' '),stroke:prop.backgroundGridColor,fill:'rgba(0,0,0,0)','stroke-width':prop.backgroundGridLinewidth,'shape-rendering':"crispEdges",'stroke-dasharray':dasharray}});}
|
57
|
+
RG.SVG.drawTitle(obj);};RG.SVG.isNull=function(arg)
|
58
|
+
{if(arg==null||typeof arg==='object'&&!arg){return true;}
|
59
|
+
return false;};RG.SVG.getScale=function(opt)
|
60
|
+
{var obj=opt.object,prop=obj.properties,numlabels=opt.numlabels,unitsPre=opt.unitsPre,unitsPost=opt.unitsPost,max=Number(opt.max),min=Number(opt.min),strict=opt.strict,decimals=Number(opt.decimals),point=opt.point,thousand=opt.thousand,originalMax=max,round=opt.round,scale={max:1,labels:[],values:[]},formatter=opt.formatter;if(max===0&&min===0){var max=1;for(var i=0;i<numlabels;++i){var label=((((max-min)/numlabels)*(i+1))+min).toFixed(decimals);scale.labels.push(unitsPre+label+unitsPost);scale.values.push(parseFloat(label))}}else if(max<=1&&!strict){var arr=[1,0.5,0.10,0.05,0.010,0.005,0.0010,0.0005,0.00010,0.00005,0.000010,0.000005,0.0000010,0.0000005,0.00000010,0.00000005,0.000000010,0.000000005,0.0000000010,0.0000000005,0.00000000010,0.00000000005,0.000000000010,0.000000000005,0.0000000000010,0.0000000000005],vals=[];for(var i=0;i<arr.length;++i){if(max>arr[i]){i--;break;}}
|
61
|
+
scale.max=arr[i]
|
62
|
+
scale.labels=[];scale.values=[];for(var j=0;j<numlabels;++j){var value=((((arr[i]-min)/numlabels)*(j+1))+min).toFixed(decimals);scale.values.push(value);scale.labels.push(RG.SVG.numberFormat({object:obj,num:value,prepend:unitsPre,append:unitsPost,point:prop.yaxisPoint,thousand:prop.yaxisThousand,formatter:formatter}));}}else if(!strict){max=ma.ceil(max);var interval=ma.pow(10,ma.max(1,Number(String(Number(max)-Number(min)).length-1)));var topValue=interval;while(topValue<max){topValue+=(interval/2);}
|
63
|
+
if(Number(originalMax)>Number(topValue)){topValue+=(interval/2);}
|
64
|
+
if(max<=10){topValue=(Number(originalMax)<=5?5:10);}
|
65
|
+
if(obj&&typeof(round)=='boolean'&&round){topValue=10*interval;}
|
66
|
+
scale.max=topValue;for(var i=0;i<numlabels;++i){var label=RG.SVG.numberFormat({object:obj,num:((((i+1)/numlabels)*(topValue-min))+min).toFixed(decimals),prepend:unitsPre,append:unitsPost,point:point,thousand:thousand,formatter:formatter});scale.labels.push(label);scale.values.push(((((i+1)/numlabels)*(topValue-min))+min).toFixed(decimals));}}else if(typeof max==='number'&&strict){for(var i=0;i<numlabels;++i){scale.labels.push(RG.SVG.numberFormat({object:obj,formatter:formatter,num:((((i+1)/numlabels)*(max-min))+min).toFixed(decimals),prepend:unitsPre,append:unitsPost,point:point,thousand:thousand}));scale.values.push(((((i+1)/numlabels)*(max-min))+min).toFixed(decimals));}
|
67
|
+
scale.max=max;}
|
68
|
+
scale.unitsPre=unitsPre;scale.unitsPost=unitsPost;scale.point=point;scale.decimals=decimals;scale.thousand=thousand;scale.numlabels=numlabels;scale.round=Boolean(round);scale.min=min;for(var i=0;i<scale.values.length;++i){scale.values[i]=parseFloat(scale.values[i]);}
|
69
|
+
return scale;};RG.SVG.arrayFill=RG.SVG.arrayPad=function(opt)
|
70
|
+
{var arr=opt.array,len=opt.length,value=(opt.value?opt.value:null);if(arr.length<len){for(var i=arr.length;i<len;i+=1){arr[i]=value;}}
|
71
|
+
return arr;};RG.SVG.arraySum=function(arr)
|
72
|
+
{if(typeof arr==='number'){return arr;}
|
73
|
+
if(RG.SVG.isNull(arr)){return 0;}
|
74
|
+
var i,sum,len=arr.length;for(i=0,sum=0;i<len;sum+=arr[i++]);return sum;};RG.SVG.arrayMax=function(arr)
|
75
|
+
{var max=null
|
76
|
+
if(typeof arr==='number'){return arr;}
|
77
|
+
if(RG.SVG.isNull(arr)){return 0;}
|
78
|
+
for(var i=0,len=arr.length;i<len;++i){if(typeof arr[i]==='number'){var val=arguments[1]?ma.abs(arr[i]):arr[i];if(typeof max==='number'){max=ma.max(max,val);}else{max=val;}}}
|
79
|
+
return max;};RG.SVG.arrayMin=function(arr)
|
80
|
+
{var max=null,min=null,ma=Math;if(typeof arr==='number'){return arr;}
|
81
|
+
if(RG.SVG.isNull(arr)){return 0;}
|
82
|
+
for(var i=0,len=arr.length;i<len;++i){if(typeof arr[i]==='number'){var val=arguments[1]?ma.abs(arr[i]):arr[i];if(typeof min==='number'){min=ma.min(min,val);}else{min=val;}}}
|
83
|
+
return min;};RG.SVG.arrayPad=function(arr,len)
|
84
|
+
{if(arr.length<len){var val=arguments[2]?arguments[2]:null;for(var i=arr.length;i<len;i+=1){arr[i]=val;}}
|
85
|
+
return arr;};RG.SVG.arraySum=function(arr)
|
86
|
+
{if(typeof arr==='number'){return arr;}
|
87
|
+
if(RG.SVG.isNull(arr)){return 0;}
|
88
|
+
var i,sum,len=arr.length;for(i=0,sum=0;i<len;sum+=arr[i++]);return sum;};RG.SVG.arrayLinearize=function()
|
89
|
+
{var arr=[],args=arguments
|
90
|
+
for(var i=0,len=args.length;i<len;++i){if(typeof args[i]==='object'&&args[i]){for(var j=0,len2=args[i].length;j<len2;++j){var sub=RG.SVG.arrayLinearize(args[i][j]);for(var k=0,len3=sub.length;k<len3;++k){arr.push(sub[k]);}}}else{arr.push(args[i]);}}
|
91
|
+
return arr;};RG.SVG.arrayShift=function(arr)
|
92
|
+
{var ret=[];for(var i=1,len=arr.length;i<len;++i){ret.push(arr[i]);}
|
93
|
+
return ret;};RG.SVG.arrayReverse=function(arr)
|
94
|
+
{if(!arr){return;}
|
95
|
+
var newarr=[];for(var i=arr.length-1;i>=0;i-=1){newarr.push(arr[i]);}
|
96
|
+
return newarr;};RG.SVG.arrayClone=function(obj)
|
97
|
+
{if(obj===null||typeof obj!=='object'){return obj;}
|
98
|
+
if(RG.SVG.isArray(obj)){var temp=[];for(var i=0,len=obj.length;i<len;++i){if(typeof obj[i]==='number'){temp[i]=(function(arg){return Number(arg);})(obj[i]);}else if(typeof obj[i]==='string'){temp[i]=(function(arg){return String(arg);})(obj[i]);}else if(typeof obj[i]==='function'){temp[i]=obj[i];}else{temp[i]=RG.SVG.arrayClone(obj[i]);}}}else if(typeof obj==='object'){var temp={};for(var i in obj){if(typeof i==='string'){temp[i]=obj[i];}}}
|
99
|
+
return temp;};RG.SVG.arrayInvert=function(arr)
|
100
|
+
{for(var i=0,len=arr.length;i<len;++i){arr[i]=!arr[i];}
|
101
|
+
return arr;};RG.SVG.arrayTrim=function(arr)
|
102
|
+
{var out=[],content=false;for(var i=0;i<arr.length;i++){if(arr[i]){content=true;}
|
103
|
+
if(content){out.push(arr[i]);}}
|
104
|
+
out=RG.SVG.arrayReverse(out);var out2=[],content=false;for(var i=0;i<out.length;i++){if(out[i]){content=true;}
|
105
|
+
if(content){out2.push(out[i]);}}
|
106
|
+
out2=RG.SVG.arrayReverse(out2);return out2;};RG.SVG.isArray=function(obj)
|
107
|
+
{if(obj&&obj.constructor){var pos=obj.constructor.toString().indexOf('Array');}else{return false;}
|
108
|
+
return obj!=null&&typeof pos==='number'&&pos>0&&pos<20;};RG.SVG.abs=function(value)
|
109
|
+
{if(typeof value==='string'){value=parseFloat(value)||0;}
|
110
|
+
if(typeof value==='number'){return ma.abs(value);}
|
111
|
+
if(typeof value==='object'){for(i in value){if(typeof i==='string'||typeof i==='number'||typeof i==='object'){value[i]=RG.SVG.abs(value[i]);}}
|
112
|
+
return value;}
|
113
|
+
return 0;};RG.SVG.numberFormat=function(opt)
|
114
|
+
{var obj=opt.object,prepend=opt.prepend?String(opt.prepend):'',append=opt.append?String(opt.append):'',output='',decimal_seperator=typeof opt.point==='string'?opt.point:'.',thousand_seperator=typeof opt.thousand==='string'?opt.thousand:',',num=opt.num
|
115
|
+
decimals_trim=opt.decimals_trim;RegExp.$1='';if(typeof opt.formatter==='function'){return opt.formatter(obj,num);}
|
116
|
+
if(String(num).indexOf('e')>0){return String(prepend+String(num)+append);}
|
117
|
+
num=String(num);if(num.indexOf('.')>0){var tmp=num;num=num.replace(/\.(.*)/,'');decimal=tmp.replace(/(.*)\.(.*)/,'$2');}else{decimal='';}
|
118
|
+
var seperator=thousand_seperator;var foundPoint;for(i=(num.length-1),j=0;i>=0;j++,i--){var character=num.charAt(i);if(j%3==0&&j!=0){output+=seperator;}
|
119
|
+
output+=character;}
|
120
|
+
var rev=output;output='';for(i=(rev.length-1);i>=0;i--){output+=rev.charAt(i);}
|
121
|
+
if(output.indexOf('-'+thousand_seperator)==0){output='-'+output.substr(('-'+thousand_seperator).length);}
|
122
|
+
if(decimal.length){output=output+decimal_seperator+decimal;decimal='';RegExp.$1='';}
|
123
|
+
if(decimals_trim){output=output.replace(/0+$/,'');output=output.replace(/\.$/,'');}
|
124
|
+
if(output.charAt(0)=='-'){output=output.replace(/-/,'');prepend='-'+prepend;}
|
125
|
+
return prepend+output+append;};RG.SVG.text=function(opt)
|
126
|
+
{var obj=opt.object,parent=opt.parent||opt.object.svg.all,size=opt.size,bold=opt.bold,font=opt.font,italic=opt.italic,halign=opt.halign,valign=opt.valign,str=opt.text,x=opt.x,y=opt.y,color=opt.color?opt.color:'black',background=opt.background||null,padding=opt.padding||0,link=opt.link||'',linkTarget=opt.linkTarget||'_blank';if(halign==='right'){halign='end';}else if(halign==='center'||halign==='middle'){halign='middle';}else{halign='start';}
|
127
|
+
if(valign==='top'){valign='hanging';}else if(valign==='center'||valign==='middle'){valign='central';valign='middle';}else{valign='bottom';}
|
128
|
+
if(link){var a=RGraph.SVG.create({svg:bar.svg,type:'a',parent:opt.parent,attr:{'xlink:href':link,target:linkTarget}});}
|
129
|
+
var text=RG.SVG.create({svg:obj.svg,parent:link?a:opt.parent,type:'text',attr:{fill:color,x:x,y:y,'font-size':typeof size==='number'?size+'pt':size,'font-weight':bold?900:100,'font-family':font?font:'sans-serif','font-style':italic?'italic':'normal','text-anchor':halign,'dominant-baseline':valign}});var textNode=document.createTextNode(str);text.appendChild(textNode);if(typeof background==='string'){var bbox=text.getBBox(),rect=RG.SVG.create({svg:obj.svg,parent:opt.parent,type:'rect',attr:{x:bbox.x-padding,y:bbox.y-padding,width:bbox.width+(padding*2),height:bbox.height+(padding*2),fill:background}});parent.insertBefore(rect,text);}
|
130
|
+
if(RG.SVG.ISIE&&(valign==='hanging')){text.setAttribute('y',y+(text.scrollHeight/2));}else if(RG.SVG.ISIE&&valign==='middle'){text.setAttribute('y',y+(text.scrollHeight/3));}
|
131
|
+
if(RG.SVG.ISFF){Y=y+(text.scrollHeight/3);}
|
132
|
+
return text;};RG.SVG.createUID=function()
|
133
|
+
{return'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,function(c)
|
134
|
+
{var r=ma.random()*16|0,v=c=='x'?r:(r&0x3|0x8);return v.toString(16);});};RG.SVG.isFixed=function(svg)
|
135
|
+
{var obj=svg.parentNode,i=0;while(obj&&obj.tagName.toLowerCase()!='body'&&i<99){if(obj.style.position==='fixed'){return obj;}
|
136
|
+
obj=obj.offsetParent;}
|
137
|
+
return false;};RG.SVG.REG.set=function(name,value)
|
138
|
+
{RG.SVG.REG.store[name]=value;return value;};RG.SVG.REG.get=function(name)
|
139
|
+
{return RG.SVG.REG.store[name];};RG.SVG.trim=function(str)
|
140
|
+
{return RG.SVG.ltrim(RG.SVG.rtrim(str));};RG.SVG.ltrim=function(str)
|
141
|
+
{return str.replace(/^(\s|\0)+/,'');};RG.SVG.rtrim=function(str)
|
142
|
+
{return str.replace(/(\s|\0)+$/,'');};RG.SVG.hideTooltip=function()
|
143
|
+
{var tooltip=RG.SVG.REG.get('tooltip');if(tooltip&&tooltip.parentNode){tooltip.parentNode.removeChild(tooltip);tooltip.style.display='none';tooltip.style.visibility='hidden';RG.SVG.REG.set('tooltip',null);}
|
144
|
+
if(tooltip&&tooltip.__object__){RG.SVG.removeHighlight(tooltip.__object__);}};RG.SVG.setShadow=function(options)
|
145
|
+
{var obj=options.object,offsetx=options.offsetx||0,offsety=options.offsety||0,blur=options.blur||0,opacity=options.opacity||0,id=options.id;var filter=RG.SVG.create({svg:obj.svg,parent:obj.svg.defs,type:'filter',attr:{id:id,width:"130%",height:"130%"}});RG.SVG.create({svg:obj.svg,parent:filter,type:'feOffset',attr:{result:'offOut','in':'SourceGraphic',dx:offsetx,dy:offsety}});RG.SVG.create({svg:obj.svg,parent:filter,type:'feColorMatrix',attr:{result:'matrixOut','in':'offOut',type:'matrix',values:'0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 {1} 0'.format(opacity)}});RG.SVG.create({svg:obj.svg,parent:filter,type:'feGaussianBlur',attr:{result:'blurOut','in':'matrixOut',stdDeviation:blur}});RG.SVG.create({svg:obj.svg,parent:filter,type:'feBlend',attr:{'in':'SourceGraphic','in2':'blurOut',mode:'normal'}});};RG.SVG.sequentialIndexToGrouped=function(index,data)
|
146
|
+
{var group=0,grouped_index=0;while(--index>=0){if(RG.SVG.isNull(data[group])){group++;grouped_index=0;continue;}
|
147
|
+
if(typeof data[group]=='number'){group++
|
148
|
+
grouped_index=0;continue;}
|
149
|
+
grouped_index++;if(grouped_index>=data[group].length){group++;grouped_index=0;}}
|
150
|
+
return[group,grouped_index];};RG.SVG.TRIG.toCartesian=function(options)
|
151
|
+
{return{x:options.cx+(options.r*ma.cos(options.angle)),y:options.cy+(options.r*ma.sin(options.angle))};};RG.SVG.TRIG.getArcPath=function(options)
|
152
|
+
{options.start-=1.57;options.end-=1.57;var start=RG.SVG.TRIG.toCartesian({cx:options.cx,cy:options.cy,r:options.r,angle:options.start});var end=RG.SVG.TRIG.toCartesian({cx:options.cx,cy:options.cy,r:options.r,angle:options.end});var diff=options.end-options.start;var largeArc='0';var sweep='0';if(options.anticlockwise&&diff>3.14){largeArc='0';sweep='0';}else if(options.anticlockwise&&diff<=3.14){largeArc='1';sweep='0';}else if(!options.anticlockwise&&diff>3.14){largeArc='1';sweep='1';}else if(!options.anticlockwise&&diff<=3.14){largeArc='0';sweep='1';}
|
153
|
+
if(options.start>options.end&&options.anticlockwise&&diff<=3.14){largeArc='0';sweep='0';}
|
154
|
+
if(options.start>options.end&&options.anticlockwise&&diff>3.14){largeArc='1';sweep='1';}
|
155
|
+
if(typeof options.moveto==='boolean'&&options.moveto===false){var d=["A",options.r,options.r,0,largeArc,sweep,end.x,end.y];}else{var d=["M",start.x,start.y,"A",options.r,options.r,0,largeArc,sweep,end.x,end.y];}
|
156
|
+
if(options.array===true){return d;}else{return d.join(" ");}};RG.SVG.TRIG.getArcPath2=function(options)
|
157
|
+
{options.start-=1.57;options.end-=1.57;var start=RG.SVG.TRIG.toCartesian({cx:options.cx,cy:options.cy,r:options.r,angle:options.start});var end=RG.SVG.TRIG.toCartesian({cx:options.cx,cy:options.cy,r:options.r,angle:options.end});var diff=ma.abs(options.end-options.start);var largeArc='0';var sweep='0';if(!options.anticlockwise){if(diff>RG.SVG.TRIG.PI){largeArc='1';sweep='1';}else{largeArc='0';sweep='1';}}else{if(diff>RG.SVG.TRIG.PI){largeArc='1';sweep='0';}else{largeArc='0';sweep='0';}}
|
158
|
+
if(typeof options.lineto==='boolean'&&options.lineto===false){var d=["M",start.x,start.y,"A",options.r,options.r,0,largeArc,sweep,end.x,end.y];}else{var d=["M",options.cx,options.cy,"L",start.x,start.y,"A",options.r,options.r,0,largeArc,sweep,end.x,end.y];}
|
159
|
+
if(options.array===true){return d;}else{return d.join(" ");}};RG.SVG.TRIG.getArcPath3=function(options)
|
160
|
+
{options.start-=1.57;options.end-=1.57;var start=RG.SVG.TRIG.toCartesian({cx:options.cx,cy:options.cy,r:options.r,angle:options.start});var end=RG.SVG.TRIG.toCartesian({cx:options.cx,cy:options.cy,r:options.r,angle:options.end});var diff=ma.abs(options.end-options.start);var largeArc='0';var sweep='0';if(!options.anticlockwise){if(diff>RG.SVG.TRIG.PI){largeArc='1';sweep='1';}else{largeArc='0';sweep='1';}}else{if(diff>RG.SVG.TRIG.PI){largeArc='1';sweep='0';}else{largeArc='0';sweep='0';}}
|
161
|
+
if(typeof options.lineto==='boolean'&&options.lineto===false){var d=["M",start.x,start.y,"A",options.r,options.r,0,largeArc,sweep,end.x,end.y];}else{var d=["L",start.x,start.y,"A",options.r,options.r,0,largeArc,sweep,end.x,end.y];}
|
162
|
+
if(options.array===true){return d;}else{return d.join(" ");}};RG.SVG.TRIG.getRadiusEndPoint=function(opt)
|
163
|
+
{if(arguments.length===1){var angle=opt.angle,r=opt.r;}else if(arguments.length===4){var angle=arguments[0],r=arguments[1];}
|
164
|
+
var x=ma.cos(angle)*r,y=ma.sin(angle)*r;return[x,y];};RG.SVG.drawTitle=function(obj)
|
165
|
+
{var prop=obj.properties,valign='bottom',originalTitleX=prop.titleX,originalTitleY=prop.titleY,originalTitleSubtitleX=prop.titleSubtitleX,originalTitleSubtitleY=prop.titleSubtitleY;if(typeof originalTitleX==='string')originalTitleX.replace(/^\+/,'');if(typeof originalTitleY==='string')originalTitleY.replace(/^\+/,'');if(typeof originalTitleSubtitleX==='string')originalTitleSubtitleX.replace(/^\+/,'');if(typeof originalTitleSubtitleY==='string')originalTitleSubtitleY.replace(/^\+/,'');if(obj.type==='pie'){if(RG.SVG.isNull(prop.titleX)){prop.titleX=obj.centerx;prop.titleSubtitleX=obj.centerx;}
|
166
|
+
if(RG.SVG.isNull(prop.titleY)){prop.titleY=obj.centery-obj.radius-10;}}
|
167
|
+
if(obj.scale&&obj.scale.max<=0&&obj.scale.min<0&&typeof prop.titleY!=='number'&&obj.type!=='hbar'){prop.titleY=obj.height-prop.gutterBottom+10;var positionBottom=true;valign='top';}else if(typeof prop.titleY!=='number'){var positionBottom=false;prop.titleY=prop.gutterTop-10;valign='bottom';if(!RG.SVG.isNull(prop.key)){prop.titleY-=(2*(prop.keyTextSize||prop.textSize));}}
|
168
|
+
if(prop.titleSubtitle&&typeof prop.titleSubtitleY!=='number'&&!positionBottom){prop.titleY=prop.titleY-(prop.titleSubtitleSize*1.5);}
|
169
|
+
prop.titleSubTitleSize=prop.titleSubTitleSize||prop.textSize;prop.titleSubtitleY=prop.titleSubtitleY||prop.titleY+18;if(positionBottom&&typeof prop.titleSubtitleY!=='number'){prop.titleSubtitleY=prop.titleY+26;}
|
170
|
+
if(prop.title){var x=typeof prop.titleX==='number'?prop.titleX+(prop.variant3dOffsetx||0):prop.gutterLeft+(obj.graphWidth/2)+(prop.variant3dOffsetx||0);var y=prop.titleY+(prop.variant3dOffsety||0);if(typeof originalTitleX==='string'){x+=parseFloat(originalTitleX);}
|
171
|
+
if(typeof originalTitleY==='string'){y+=parseFloat(originalTitleY);}
|
172
|
+
RG.SVG.text({object:obj,svg:obj.svg,parent:obj.svg.all,text:prop.title.toString(),size:prop.titleSize||(prop.textSize+4)||16,x:x,y:y,halign:prop.titleHalign||'center',valign:prop.titleValign||valign,color:prop.titleColor||prop.textColor||'black',bold:prop.titleBold||false,italic:prop.titleItalic||false,font:prop.titleFont||prop.textFont||'Arial'});}
|
173
|
+
if(typeof prop.title==='string'&&typeof prop.titleSubtitle==='string'){y+=(prop.titleSubtitleSize*1.5);if(typeof originalTitleSubtitleX==='number'){x=originalTitleSubtitleX;}
|
174
|
+
if(typeof originalTitleSubtitleY==='number'){y=originalTitleSubtitleY;}
|
175
|
+
if(typeof originalTitleSubtitleX==='string'){x+=parseFloat(originalTitleSubtitleX);}
|
176
|
+
if(typeof originalTitleSubtitleY==='string'){y+=parseFloat(originalTitleSubtitleY);}
|
177
|
+
RG.SVG.text({object:obj,svg:obj.svg,parent:obj.svg.all,text:prop.titleSubtitle,size:prop.titleSubtitleSize,x:x,y:y,halign:prop.titleSubtitleHalign||'center',valign:prop.titleSubtitleValign||valign,color:prop.titleSubtitleColor||prop.textColor||'#aaa',bold:prop.titleSubtitleBold||false,italic:prop.titleSubtitleItalic||false,font:prop.titleSubtitleFont||prop.textFont||'Arial'});}};RG.SVG.trim=function(str)
|
178
|
+
{return RG.SVG.ltrim(RG.SVG.rtrim(str));};RG.SVG.ltrim=function(str)
|
179
|
+
{return String(str).replace(/^(\s|\0)+/,'');};RG.SVG.rtrim=function(str)
|
180
|
+
{return String(str).replace(/(\s|\0)+$/,'');};RG.SVG.parseColorLinear=function(opt)
|
181
|
+
{var obj=opt.object,color=opt.color;if(!color||typeof color!=='string'){return color;}
|
182
|
+
if(color.match(/^gradient\((.*)\)$/i)){var parts=RegExp.$1.split(':'),diff=1/(parts.length-1);if(opt&&opt.direction&&opt.direction==='horizontal'){var grad=RG.SVG.create({type:'linearGradient',parent:obj.svg.defs,attr:{id:'RGraph-linear-gradient-'+obj.uid+'-'+obj.gradientCounter,x1:opt.start||0,x2:opt.end||'100%',y1:0,y2:0,gradientUnits:"userSpaceOnUse"}});}else{var grad=RG.SVG.create({type:'linearGradient',parent:obj.svg.defs,attr:{id:'RGraph-linear-gradient-'+obj.uid+'-'+obj.gradientCounter,x1:0,x2:0,y1:opt.start||0,y2:opt.end||'100%',gradientUnits:"userSpaceOnUse"}});}
|
183
|
+
var stop=RG.SVG.create({type:'stop',parent:grad,attr:{offset:'0%','stop-color':RG.SVG.trim(parts[0])}});for(var j=1,len=parts.length;j<len;++j){RG.SVG.create({type:'stop',parent:grad,attr:{offset:(j*diff*100)+'%','stop-color':RG.SVG.trim(parts[j])}});}}
|
184
|
+
color=grad?'url(#RGraph-linear-gradient-'+obj.uid+'-'+(obj.gradientCounter++)+')':color;return color;};RG.SVG.parseColorRadial=function(opt)
|
185
|
+
{var obj=opt.object,color=opt.color;if(!color||typeof color!=='string'){return color;}
|
186
|
+
if(color.match(/^gradient\((.*)\)$/i)){var parts=RegExp.$1.split(':'),diff=1/(parts.length-1);var grad=RG.SVG.create({type:'radialGradient',parent:obj.svg.defs,attr:{id:'RGraph-radial-gradient-'+obj.uid+'-'+obj.gradientCounter,gradientUnits:opt.gradientUnits||'userSpaceOnUse',cx:opt.cx||obj.centerx,cy:opt.cy||obj.centery,fx:opt.fx||obj.centerx,fy:opt.fy||obj.centery,r:opt.r||obj.radius}});var stop=RG.SVG.create({type:'stop',parent:grad,attr:{offset:'0%','stop-color':RG.SVG.trim(parts[0])}});for(var j=1,len=parts.length;j<len;++j){RG.SVG.create({type:'stop',parent:grad,attr:{offset:(j*diff*100)+'%','stop-color':RG.SVG.trim(parts[j])}});}}
|
187
|
+
color=grad?'url(#RGraph-radial-gradient-'+obj.uid+'-'+(obj.gradientCounter++)+')':color;return color;};RG.SVG.resetColorsToOriginalValues=function(opt)
|
188
|
+
{var obj=opt.object;if(obj.originalColors){for(var j in obj.originalColors){if(typeof j==='string'){obj.properties[j]=RG.SVG.arrayClone(obj.originalColors[j]);}}}
|
189
|
+
if(typeof obj.resetColorsToOriginalValues==='function'){obj.resetColorsToOriginalValues();}
|
190
|
+
obj.originalColors={};obj.colorsParsed=false;obj.gradientCounter=1;};RG.SVG.clear=function(svg)
|
191
|
+
{for(var i=1;i<=100;++i){if(svg['background'+i]){while(svg['background'+i].lastChild){svg['background'+i].removeChild(svg['background'+i].lastChild);}}else{break;}}
|
192
|
+
while(svg.all.lastChild){svg.all.removeChild(svg.all.lastChild);}};RG.SVG.addCustomEventListener=function(obj,name,func)
|
193
|
+
{if(typeof RG.SVG.events[obj.uid]==='undefined'){RG.SVG.events[obj.uid]=[];}
|
194
|
+
if(name.substr(0,2)!=='on'){name='on'+name;}
|
195
|
+
RG.SVG.events[obj.uid].push({object:obj,event:name,func:func});return RG.SVG.events[obj.uid].length-1;};RG.SVG.fireCustomEvent=function(obj,name)
|
196
|
+
{if(obj&&obj.isRGraph){var uid=obj.uid;if(typeof uid==='string'&&typeof RG.SVG.events==='object'&&typeof RG.SVG.events[uid]==='object'&&RG.SVG.events[uid].length>0){for(var j=0,len=RG.SVG.events[uid].length;j<len;++j){if(RG.SVG.events[uid][j]&&RG.SVG.events[uid][j].event===name){RG.SVG.events[uid][j].func(obj);}}}}};RG.SVG.removeAllCustomEventListeners=function()
|
197
|
+
{var uid=arguments[0];if(uid&&RG.SVG.events[uid]){RG.SVG.events[uid]={};}else{RG.SVG.events=[];}};RG.SVG.removeCustomEventListener=function(obj,i)
|
198
|
+
{if(typeof RG.SVG.events==='object'&&typeof RG.SVG.events[obj.uid]==='object'&&typeof RG.SVG.events[obj.uid][i]==='object'){RG.SVG.events[obj.uid][i]=null;}};RG.SVG.removeHighlight=function(obj)
|
199
|
+
{var highlight=RG.SVG.REG.get('highlight');if(highlight&&RG.SVG.isArray(highlight)&&highlight.length){for(var i=0,len=highlight.length;i<len;++i){if(highlight[i].parentNode){highlight[i].parentNode.removeChild(highlight[i]);}}}else if(highlight&&highlight.parentNode){if(obj.type==='scatter'){highlight.setAttribute('fill','transparent');}else{highlight.parentNode.removeChild(highlight);}}};RG.SVG.redraw=function()
|
200
|
+
{if(arguments.length===1){var svg=arguments[0];RG.SVG.clear(svg);var objects=RG.SVG.OR.get('id:'+svg.parentNode.id);for(var i=0,len=objects.length;i<len;++i){RG.SVG.resetColorsToOriginalValues({object:objects[i]});objects[i].draw();}}else{var tags=RG.SVG.OR.tags();for(var i in tags){RG.SVG.redraw(tags[i]);}}};RG.SVG.parseDate=function(str)
|
201
|
+
{var d=new Date();var defaults={seconds:'00',minutes:'00',hours:'00',date:d.getDate(),month:d.getMonth()+1,year:d.getFullYear()};var months=['january','february','march','april','may','june','july','august','september','october','november','december'],months_regex=months.join('|');for(var i=0;i<months.length;++i){months[months[i]]=i;months[months[i].substring(0,3)]=i;months_regex=months_regex+'|'+months[i].substring(0,3);}
|
202
|
+
var sep='[-./_=+~#:;,]+';var tokens=str.split(/ +/);for(var i=0,len=tokens.length;i<len;++i){if(tokens[i]){if(tokens[i].match(/^\d\d\d\d$/)){defaults.year=tokens[i];}
|
203
|
+
var res=isMonth(tokens[i]);if(typeof res==='number'){defaults.month=res+1;}
|
204
|
+
if(tokens[i].match(/^\d?\d(?:st|nd|rd|th)?$/)){defaults.date=parseInt(tokens[i]);}
|
205
|
+
if(tokens[i].match(/^(\d\d):(\d\d)(?:(\d\d))?$/)){defaults.hours=parseInt(RegExp.$1);defaults.minutes=parseInt(RegExp.$2);if(RegExp.$3){defaults.seconds=parseInt(RegExp.$3);}}
|
206
|
+
if(tokens[i].match(new RegExp('^(\\d\\d\\d\\d)'+sep+'(\\d\\d)'+sep+'(\\d\\d)$','i'))){defaults.date=parseInt(RegExp.$3);defaults.month=parseInt(RegExp.$2);defaults.year=parseInt(RegExp.$1);}
|
207
|
+
if(tokens[i].match(new RegExp('^(\\d\\d)'+sep+'(\\d\\d)'+sep+'(\\d\\d\\d\\d)$','i'))){defaults.date=parseInt(RegExp.$1);defaults.month=parseInt(RegExp.$2);defaults.year=parseInt(RegExp.$3);}}}
|
208
|
+
str='{1}/{2}/{3} {4}:{5}:{6}'.format(defaults.year,String(defaults.month).length===1?'0'+(defaults.month):defaults.month,String(defaults.date).length===1?'0'+(defaults.date):defaults.date,String(defaults.hours).length===1?'0'+(defaults.hours):defaults.hours,String(defaults.minutes).length===1?'0'+(defaults.minutes):defaults.minutes,String(defaults.seconds).length===1?'0'+(defaults.seconds):defaults.seconds);return Date.parse(str);function isMonth(str)
|
209
|
+
{var res=str.toLowerCase().match(months_regex);return res?months[res[0]]:false;}};RG.SVG.OR.add=function(obj)
|
210
|
+
{RG.SVG.OR.objects.push(obj);return obj;};RG.SVG.OR.get=function()
|
211
|
+
{if(typeof arguments[0]==='string'&&arguments[0].substr(0,3).toLowerCase()==='id:'){var ret=[];for(var i=0;i<RG.SVG.OR.objects.length;++i){if(RG.SVG.OR.objects[i].id===arguments[0].substr(3)){ret.push(RG.SVG.OR.objects[i]);}}
|
212
|
+
return ret;}
|
213
|
+
if(typeof arguments[0]==='string'&&arguments[0].substr(0,4).toLowerCase()==='type'){var ret=[];for(var i=0;i<RG.SVG.OR.objects.length;++i){if(RG.SVG.OR.objects[i].type===arguments[0].substr(5)){ret.push(RG.SVG.OR.objects[i]);}}
|
214
|
+
return ret;}
|
215
|
+
if(typeof arguments[0]==='string'&&arguments[0].substr(0,3).toLowerCase()==='uid'){var ret=[];for(var i=0;i<RG.SVG.OR.objects.length;++i){if(RG.SVG.OR.objects[i].uid===arguments[0].substr(4)){ret.push(RG.SVG.OR.objects[i]);}}
|
216
|
+
return ret;}
|
217
|
+
return RG.SVG.OR.objects;};RG.SVG.OR.tags=function()
|
218
|
+
{var tags=[];for(var i=0;i<RG.SVG.OR.objects.length;++i){if(!tags[RG.SVG.OR.objects[i].svg.parentNode.id]){tags[RG.SVG.OR.objects[i].svg.parentNode.id]=RG.SVG.OR.objects[i].svg;}}
|
219
|
+
return tags;};RG.SVG.getSVGXY=function(svg)
|
220
|
+
{var x=0,y=0,el=svg.parentNode;do{x+=el.offsetLeft;y+=el.offsetTop;if(el.tagName.toLowerCase()=='table'&&(RG.SVG.ISCHROME||RG.SVG.ISSAFARI)){x+=parseInt(el.border)||0;y+=parseInt(el.border)||0;}
|
221
|
+
el=el.offsetParent;}while(el&&el.tagName&&el.tagName.toLowerCase()!='body');var paddingLeft=svg.style.paddingLeft?parseInt(svg.style.paddingLeft):0,paddingTop=svg.style.paddingTop?parseInt(svg.style.paddingTop):0,borderLeft=svg.style.borderLeftWidth?parseInt(svg.style.borderLeftWidth):0,borderTop=svg.style.borderTopWidth?parseInt(svg.style.borderTopWidth):0;if(navigator.userAgent.indexOf('Firefox')>0){x+=parseInt(document.body.style.borderLeftWidth)||0;y+=parseInt(document.body.style.borderTopWidth)||0;}
|
222
|
+
return[x+paddingLeft+borderLeft,y+paddingTop+borderTop];};RG.SVG.FX.update=function(func)
|
223
|
+
{win.requestAnimationFrame=win.requestAnimationFrame||win.webkitRequestAnimationFrame||win.msRequestAnimationFrame||win.mozRequestAnimationFrame||(function(func){setTimeout(func,16.666);});win.requestAnimationFrame(func);};RG.SVG.FX.getEasingMultiplier=function(frames,frame)
|
224
|
+
{var multiplier=ma.pow(ma.sin((frame/frames)*RG.SVG.TRIG.HALFPI),3);return multiplier;};RG.SVG.measureText=function(opt)
|
225
|
+
{var text=opt.text||'',bold=opt.bold||false,font=opt.font||'Arial',size=opt.size||10,str=text+':'+bold+':'+font+':'+size;if(typeof RG.SVG.measuretext_cache==='undefined'){RG.SVG.measuretext_cache=[];}
|
226
|
+
if(typeof RG.SVG.measuretext_cache=='object'&&RG.SVG.measuretext_cache[str]){return RG.SVG.measuretext_cache[str];}
|
227
|
+
if(!RG.SVG.measuretext_cache['text-span']){var span=document.createElement('SPAN');span.style.position='absolute';span.style.padding=0;span.style.display='inline';span.style.top='-200px';span.style.left='-200px';span.style.lineHeight='1em';document.body.appendChild(span);RG.SVG.measuretext_cache['text-span']=span;}else if(RG.SVG.measuretext_cache['text-span']){var span=RG.SVG.measuretext_cache['text-span'];}
|
228
|
+
span.innerHTML=text.replace(/\r\n/g,'<br />');span.style.fontFamily=font;span.style.fontWeight=bold?'bold':'normal';span.style.fontSize=size+'pt';var sizes=[span.offsetWidth,span.offsetHeight];RG.SVG.measuretext_cache[str]=sizes;return sizes;};RG.SVG.stringsToNumbers=function(str)
|
229
|
+
{var sep=arguments[1]||',';if(typeof str==='number'){return str;}
|
230
|
+
if(typeof str==='string'){if(str.indexOf(sep)!=-1){str=str.split(sep);}else{str=parseFloat(str);}}
|
231
|
+
if(typeof str==='object'){for(var i=0,len=str.length;i<len;i+=1){str[i]=parseFloat(str[i]);}}
|
232
|
+
return str;};RG.SVG.getAdjustedNumber=function(opt)
|
233
|
+
{var value=opt.value,prop=opt.prop;if(typeof prop==='string'&&match(/^(\+|-)([0-9.]+)/)){if(RegExp.$1==='+'){value+=parseFloat(RegExp.$2);}else if(RegExp.$1==='-'){value-=parseFloat(RegExp.$2);}}
|
234
|
+
return value;};RG.SVG.attribution=function(){return;};RG.SVG.parseGradient=function(str)
|
235
|
+
{};RG.SVG.random=function(opt)
|
236
|
+
{var min=opt.min,max=opt.max,dp=opt.dp||opt.decimals||0,r=ma.random();return Number((((max-min)*r)+min).toFixed(dp));};RG.SVG.arrayRand=RG.SVG.arrayRandom=RG.SVG.random.array=function(opt)
|
237
|
+
{var num=opt.num,min=opt.min,max=opt.max,dp=opt.dp||opt.decimals||0;for(var i=0,arr=[];i<num;i+=1){arr.push(RG.SVG.random({min:min,max:max,dp:dp}));}
|
238
|
+
return arr;};RG.SVG.commonSetter=function(opt)
|
239
|
+
{var obj=opt.object,name=opt.name,value=opt.value;if(name==='tooltipsEvent'&&value!=='click'&&value!=='mousemove'){value='click';}
|
240
|
+
return{name:name,value:value};};RG.SVG.log=function(opt)
|
241
|
+
{var num=opt.num,base=opt.base;return ma.log(num)/(base?ma.log(base):1);};RG.SVG.donut=function(opt)
|
242
|
+
{var arcPath1=RG.SVG.TRIG.getArcPath3({cx:opt.cx,cy:opt.cy,r:opt.outerRadius,start:0,end:RG.SVG.TRIG.TWOPI,anticlockwise:false,lineto:false});var arcPath2=RG.SVG.TRIG.getArcPath3({cx:opt.cx,cy:opt.cy,r:opt.innerRadius,start:RG.SVG.TRIG.TWOPI,end:0,anticlockwise:true,lineto:false});var path=RG.SVG.create({svg:opt.svg,type:'path',attr:{d:arcPath1+arcPath2,stroke:opt.stroke,fill:opt.fill}});return path;};RG.SVG.getGlobals=function(obj)
|
243
|
+
{var prop=obj.properties;for(i in RG.SVG.GLOBALS){if(typeof i==='string'){prop[i]=RG.SVG.arrayClone(RG.SVG.GLOBALS[i]);}}};RG.SVG.link=function(opt)
|
244
|
+
{var a=RGraph.SVG.create({svg:bar.svg,type:'a',parent:bar.svg.all,attr:{'xlink:href':href,target:target}});var text=RGraph.SVG.create({svg:bar.svg,type:'text',parent:a,attr:{x:x,y:y,fill:fill}});text.innerHTML=text;};if(typeof RG.SVG.tooltip!=='function'){RG.SVG.tooltip=function()
|
245
|
+
{$a('The tooltip library has not been included!');};}})(window,document);window.$p=function(obj)
|
246
|
+
{var indent=(arguments[2]?arguments[2]:' ');var str='';var counter=typeof arguments[3]=='number'?arguments[3]:0;if(counter>=5){return'';}
|
247
|
+
switch(typeof obj){case'string':str+=obj+' ('+(typeof obj)+', '+obj.length+')';break;case'number':str+=obj+' ('+(typeof obj)+')';break;case'boolean':str+=obj+' ('+(typeof obj)+')';break;case'function':str+='function () {}';break;case'undefined':str+='undefined';break;case'null':str+='null';break;case'object':if(RGraph.SVG.isNull(obj)){str+=indent+'null\n';}else{str+=indent+'Object {'+'\n'
|
248
|
+
for(j in obj){str+=indent+' '+j+' => '+window.$p(obj[j],true,indent+' ',counter+1)+'\n';}
|
249
|
+
str+=indent+'}';}
|
250
|
+
break;default:str+='Unknown type: '+typeof obj+'';break;}
|
251
|
+
if(!arguments[1]){alert(str);}
|
252
|
+
return str;};window.$a=function(v)
|
253
|
+
{alert(v);};window.$cl=function(v)
|
254
|
+
{return console.log(v);};if(!String.prototype.format){String.prototype.format=function()
|
255
|
+
{var args=arguments;return this.replace(/{(\d+)}/g,function(str,idx)
|
256
|
+
{return typeof args[idx-1]!=='undefined'?args[idx-1]:str;});};}
|