rgraph-rails 1.0.8 → 4.62
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 +4 -4
- data/README.md +3 -3
- data/lib/rgraph-rails/version.rb +1 -1
- data/vendor/assets/javascripts/RGraph.bar.js +16 -8
- data/vendor/assets/javascripts/RGraph.bipolar.js +1 -1
- data/vendor/assets/javascripts/RGraph.common.annotate.js +1 -1
- data/vendor/assets/javascripts/RGraph.common.context.js +1 -1
- data/vendor/assets/javascripts/RGraph.common.core.js +84 -7
- data/vendor/assets/javascripts/RGraph.common.csv.js +1 -1
- data/vendor/assets/javascripts/RGraph.common.deprecated.js +1 -1
- data/vendor/assets/javascripts/RGraph.common.dynamic.js +1 -1
- data/vendor/assets/javascripts/RGraph.common.effects.js +1 -1
- data/vendor/assets/javascripts/RGraph.common.key.js +3 -3
- data/vendor/assets/javascripts/RGraph.common.resizing.js +1 -1
- data/vendor/assets/javascripts/RGraph.common.sheets.js +1 -1
- data/vendor/assets/javascripts/RGraph.common.tooltips.js +1 -1
- data/vendor/assets/javascripts/RGraph.common.zoom.js +1 -1
- data/vendor/assets/javascripts/RGraph.drawing.background.js +1 -1
- data/vendor/assets/javascripts/RGraph.drawing.circle.js +1 -1
- data/vendor/assets/javascripts/RGraph.drawing.image.js +1 -1
- data/vendor/assets/javascripts/RGraph.drawing.marker1.js +1 -1
- data/vendor/assets/javascripts/RGraph.drawing.marker2.js +1 -1
- data/vendor/assets/javascripts/RGraph.drawing.marker3.js +1 -1
- data/vendor/assets/javascripts/RGraph.drawing.poly.js +1 -1
- data/vendor/assets/javascripts/RGraph.drawing.rect.js +1 -1
- data/vendor/assets/javascripts/RGraph.drawing.text.js +1 -1
- data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +1 -1
- data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +1 -1
- data/vendor/assets/javascripts/RGraph.fuel.js +1 -1
- data/vendor/assets/javascripts/RGraph.funnel.js +1 -1
- data/vendor/assets/javascripts/RGraph.gantt.js +1 -1
- data/vendor/assets/javascripts/RGraph.gauge.js +1 -1
- data/vendor/assets/javascripts/RGraph.hbar.js +228 -2
- data/vendor/assets/javascripts/RGraph.hprogress.js +1 -1
- data/vendor/assets/javascripts/RGraph.line.js +27 -5
- data/vendor/assets/javascripts/RGraph.meter.js +1 -1
- data/vendor/assets/javascripts/RGraph.modaldialog.js +1 -1
- data/vendor/assets/javascripts/RGraph.odo.js +1 -1
- data/vendor/assets/javascripts/RGraph.pie.js +1 -1
- data/vendor/assets/javascripts/RGraph.radar.js +1 -1
- data/vendor/assets/javascripts/RGraph.rose.js +1 -1
- data/vendor/assets/javascripts/RGraph.rscatter.js +1 -1
- data/vendor/assets/javascripts/RGraph.scatter.js +161 -34
- data/vendor/assets/javascripts/RGraph.semicircularprogress.js +1 -1
- data/vendor/assets/javascripts/RGraph.svg.bar.js +772 -103
- data/vendor/assets/javascripts/RGraph.svg.common.ajax.js +1 -1
- data/vendor/assets/javascripts/RGraph.svg.common.core.js +806 -231
- data/vendor/assets/javascripts/RGraph.svg.common.csv.js +1 -1
- data/vendor/assets/javascripts/RGraph.svg.common.fx.js +24 -24
- data/vendor/assets/javascripts/RGraph.svg.common.key.js +206 -0
- data/vendor/assets/javascripts/RGraph.svg.common.sheets.js +1 -1
- data/vendor/assets/javascripts/RGraph.svg.common.tooltips.js +63 -22
- data/vendor/assets/javascripts/RGraph.svg.hbar.js +351 -91
- data/vendor/assets/javascripts/RGraph.svg.line.js +159 -64
- data/vendor/assets/javascripts/RGraph.svg.pie.js +402 -51
- data/vendor/assets/javascripts/RGraph.svg.radar.js +320 -143
- data/vendor/assets/javascripts/RGraph.svg.rose.js +1818 -0
- data/vendor/assets/javascripts/RGraph.svg.scatter.js +1262 -0
- data/vendor/assets/javascripts/RGraph.svg.semicircularprogress.js +106 -57
- data/vendor/assets/javascripts/RGraph.svg.waterfall.js +1253 -0
- data/vendor/assets/javascripts/RGraph.thermometer.js +7 -6
- data/vendor/assets/javascripts/RGraph.vprogress.js +1 -1
- data/vendor/assets/javascripts/RGraph.waterfall.js +1 -1
- data/vendor/assets/javascripts/financial-data.js +1067 -0
- metadata +8 -5
- data/vendor/assets/javascripts/RGraph.cornergauge.js +0 -71
- data/vendor/assets/javascripts/RGraph.thermometer.old.js +0 -68
@@ -1,4 +1,4 @@
|
|
1
|
-
// version: 2017-
|
1
|
+
// version: 2017-05-08
|
2
2
|
/**
|
3
3
|
* o--------------------------------------------------------------------------------o
|
4
4
|
* | This file is part of the RGraph package - you can learn more at: |
|
@@ -65,7 +65,7 @@
|
|
65
65
|
//
|
66
66
|
RG.SVG.createSVG = function (opt)
|
67
67
|
{
|
68
|
-
var container
|
68
|
+
var container = opt.container;
|
69
69
|
|
70
70
|
if (container.__svg__) {
|
71
71
|
return container.__svg__;
|
@@ -75,6 +75,7 @@
|
|
75
75
|
svg.setAttribute('style', 'top: 0; left: 0; position: absolute');
|
76
76
|
svg.setAttribute('width', container.offsetWidth);
|
77
77
|
svg.setAttribute('height', container.offsetHeight);
|
78
|
+
svg.setAttribute('version', '1.1');
|
78
79
|
svg.setAttributeNS("http://www.w3.org/2000/xmlns/", 'xmlns', 'http://www.w3.org/2000/svg');
|
79
80
|
svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
|
80
81
|
container.appendChild(svg);
|
@@ -82,6 +83,17 @@
|
|
82
83
|
container.__svg__ = svg;
|
83
84
|
container.style.position = 'relative';
|
84
85
|
|
86
|
+
// Add the group tag to the SVG that contains all of the elements
|
87
|
+
var group = RG.SVG.create({
|
88
|
+
svg: svg,
|
89
|
+
type: 'g',
|
90
|
+
attr: {
|
91
|
+
className: 'all-elements'
|
92
|
+
}
|
93
|
+
});
|
94
|
+
|
95
|
+
container.__svg__.all = group;
|
96
|
+
|
85
97
|
return svg;
|
86
98
|
};
|
87
99
|
|
@@ -97,13 +109,16 @@
|
|
97
109
|
//
|
98
110
|
RG.SVG.createDefs = function (obj)
|
99
111
|
{
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
112
|
+
if (!obj.svg.defs) {
|
113
|
+
|
114
|
+
var defs = RG.SVG.create({
|
115
|
+
svg: obj.svg,
|
116
|
+
type: 'defs'
|
117
|
+
});
|
118
|
+
|
119
|
+
obj.svg.defs = defs;
|
120
|
+
}
|
104
121
|
|
105
|
-
obj.defs = defs;
|
106
|
-
|
107
122
|
return defs;
|
108
123
|
};
|
109
124
|
|
@@ -133,7 +148,7 @@
|
|
133
148
|
if (o === 'className') {
|
134
149
|
name = 'class';
|
135
150
|
}
|
136
|
-
if (opt.type === 'a' && o === 'xlink:href') {
|
151
|
+
if ( (opt.type === 'a' || opt.type === 'image') && o === 'xlink:href') {
|
137
152
|
tag.setAttributeNS('http://www.w3.org/1999/xlink', o, String(opt.attr[o]));
|
138
153
|
} else {
|
139
154
|
tag.setAttribute(name, String(opt.attr[o]));
|
@@ -176,10 +191,11 @@
|
|
176
191
|
// Draw the axis
|
177
192
|
if (prop.xaxis) {
|
178
193
|
|
179
|
-
var y = obj.type === 'hbar' ? obj.height - prop.gutterBottom : obj.getYCoord(0);
|
194
|
+
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));
|
180
195
|
|
181
196
|
var axis = RG.SVG.create({
|
182
197
|
svg: obj.svg,
|
198
|
+
parent: obj.svg.all,
|
183
199
|
type: 'path',
|
184
200
|
attr: {
|
185
201
|
d: 'M{1} {2} L{3} {4}'.format(
|
@@ -190,7 +206,9 @@
|
|
190
206
|
),
|
191
207
|
fill: prop.xaxisColor,
|
192
208
|
stroke: prop.xaxisColor,
|
193
|
-
'
|
209
|
+
'stroke-width': typeof prop.xaxisLinewidth === 'number' ? prop.xaxisLinewidth : 1,
|
210
|
+
'shape-rendering': 'crispEdges',
|
211
|
+
'stroke-linecap': 'square'
|
194
212
|
}
|
195
213
|
});
|
196
214
|
|
@@ -202,14 +220,23 @@
|
|
202
220
|
startY = (obj.height - prop.gutterBottom),
|
203
221
|
endY = (obj.height - prop.gutterBottom) + prop.xaxisTickmarksLength;
|
204
222
|
|
205
|
-
// Line/Bar X axis
|
223
|
+
// Line/Bar/Waterfall/Scatter X axis
|
206
224
|
} else {
|
207
225
|
var width = obj.graphWidth / obj.data.length,
|
208
226
|
x = prop.gutterLeft,
|
209
227
|
startY = obj.getYCoord(0) - (prop.yaxisMin < 0 ? prop.xaxisTickmarksLength : 0),
|
210
228
|
endY = obj.getYCoord(0) + prop.xaxisTickmarksLength;
|
211
|
-
|
229
|
+
|
230
|
+
if (obj.scale.min < 0 && obj.scale.max <= 0) {
|
231
|
+
startY = prop.gutterTop;
|
232
|
+
endY = prop.gutterTop - prop.xaxisTickmarksLength;
|
233
|
+
}
|
212
234
|
|
235
|
+
if (obj.scale.min > 0 && obj.scale.max > 0) {
|
236
|
+
startY = obj.getYCoord(obj.scale.min);
|
237
|
+
endY = obj.getYCoord(obj.scale.min) + prop.xaxisTickmarksLength;
|
238
|
+
}
|
239
|
+
}
|
213
240
|
|
214
241
|
|
215
242
|
|
@@ -221,7 +248,7 @@
|
|
221
248
|
// Draw the tickmarks
|
222
249
|
if (prop.xaxisTickmarks) {
|
223
250
|
|
224
|
-
//
|
251
|
+
// The HBar uses a scale
|
225
252
|
if (prop.xaxisScale) {
|
226
253
|
|
227
254
|
for (var i=0; i<(obj.scale.numlabels + (prop.yaxis && prop.xaxisMin === 0 ? 0 : 1)); ++i) {
|
@@ -234,6 +261,7 @@
|
|
234
261
|
|
235
262
|
RG.SVG.create({
|
236
263
|
svg: obj.svg,
|
264
|
+
parent: obj.svg.all,
|
237
265
|
type: 'path',
|
238
266
|
attr: {
|
239
267
|
d: 'M{1} {2} L{3} {4}'.format(
|
@@ -243,6 +271,7 @@
|
|
243
271
|
endY
|
244
272
|
),
|
245
273
|
stroke: prop.xaxisColor,
|
274
|
+
'stroke-width': typeof prop.xaxisLinewidth === 'number' ? prop.xaxisLinewidth : 1,
|
246
275
|
'shape-rendering': "crispEdges"
|
247
276
|
}
|
248
277
|
});
|
@@ -252,23 +281,25 @@
|
|
252
281
|
|
253
282
|
|
254
283
|
} else {
|
255
|
-
|
284
|
+
|
256
285
|
// This style is used by Bar and Scatter charts
|
257
286
|
if (prop.xaxisLabelsPosition === 'section') {
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
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) {
|
267
297
|
|
268
298
|
x = prop.gutterLeft + ((i+1) * (obj.graphWidth / dataPoints));
|
269
|
-
|
299
|
+
|
270
300
|
RG.SVG.create({
|
271
301
|
svg: obj.svg,
|
302
|
+
parent: obj.svg.all,
|
272
303
|
type: 'path',
|
273
304
|
attr: {
|
274
305
|
d: 'M{1} {2} L{3} {4}'.format(
|
@@ -278,11 +309,12 @@
|
|
278
309
|
endY
|
279
310
|
),
|
280
311
|
stroke: prop.xaxisColor,
|
312
|
+
'stroke-width': typeof prop.xaxisLinewidth === 'number' ? prop.xaxisLinewidth : 1,
|
281
313
|
'shape-rendering': "crispEdges"
|
282
314
|
}
|
283
315
|
});
|
284
316
|
}
|
285
|
-
|
317
|
+
|
286
318
|
// This style is used by line charts
|
287
319
|
} else if (prop.xaxisLabelsPosition === 'edge') {
|
288
320
|
|
@@ -296,9 +328,10 @@
|
|
296
328
|
|
297
329
|
var gap = ( (obj.graphWidth) / (len - 1)),
|
298
330
|
x = prop.gutterLeft + ((i+1) * gap);
|
299
|
-
|
331
|
+
|
300
332
|
RG.SVG.create({
|
301
333
|
svg: obj.svg,
|
334
|
+
parent: obj.svg.all,
|
302
335
|
type: 'path',
|
303
336
|
attr: {
|
304
337
|
d: 'M{1} {2} L{3} {4}'.format(
|
@@ -308,6 +341,7 @@
|
|
308
341
|
endY
|
309
342
|
),
|
310
343
|
stroke: prop.xaxisColor,
|
344
|
+
'stroke-width': typeof prop.xaxisLinewidth === 'number' ? prop.xaxisLinewidth : 1,
|
311
345
|
'shape-rendering': "crispEdges"
|
312
346
|
}
|
313
347
|
});
|
@@ -324,6 +358,7 @@
|
|
324
358
|
if (prop.yaxis === false) {
|
325
359
|
RG.SVG.create({
|
326
360
|
svg: obj.svg,
|
361
|
+
parent: obj.svg.all,
|
327
362
|
type: 'path',
|
328
363
|
attr: {
|
329
364
|
d: 'M{1} {2} L{3} {4}'.format(
|
@@ -333,7 +368,9 @@
|
|
333
368
|
endY
|
334
369
|
),
|
335
370
|
stroke: obj.properties.xaxisColor,
|
336
|
-
'
|
371
|
+
'stroke-width': typeof prop.xaxisLinewidth === 'number' ? prop.xaxisLinewidth : 1,
|
372
|
+
'shape-rendering': "crispEdges",
|
373
|
+
parent: obj.svg.all,
|
337
374
|
}
|
338
375
|
});
|
339
376
|
}
|
@@ -364,9 +401,10 @@
|
|
364
401
|
|
365
402
|
RG.SVG.text({
|
366
403
|
object: obj,
|
404
|
+
parent: obj.svg.all,
|
367
405
|
text: obj.scale.labels[i],
|
368
406
|
x: x,
|
369
|
-
y: (obj.height - prop.gutterBottom) + (prop.xaxis ? prop.xaxisTickmarksLength + 6 : 10) + prop.xaxisLabelsOffsety,
|
407
|
+
y: (obj.height - prop.gutterBottom) + (prop.xaxis ? prop.xaxisTickmarksLength + 6 : 10) + (prop.xaxisLinewidth || 1) + prop.xaxisLabelsOffsety,
|
370
408
|
halign: 'center',
|
371
409
|
valign: 'top',
|
372
410
|
font: prop.xaxisTextFont || prop.textFont,
|
@@ -381,31 +419,34 @@
|
|
381
419
|
|
382
420
|
|
383
421
|
|
384
|
-
// Add the minimum label
|
385
|
-
|
386
|
-
|
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({
|
387
436
|
object: obj,
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
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
|
394
448
|
});
|
395
|
-
|
396
|
-
var text = RG.SVG.text({
|
397
|
-
object: obj,
|
398
|
-
text: typeof prop.xaxisFormatter === 'function' ? (prop.xaxisFormatter)(this, prop.xaxisMin) : str,
|
399
|
-
x: prop.gutterLeft + prop.xaxisLabelsOffsetx,
|
400
|
-
y: y,
|
401
|
-
halign: 'center',
|
402
|
-
valign: 'top',
|
403
|
-
font: prop.xaxisTextFont || prop.textFont,
|
404
|
-
size: prop.xaxisTextSize || (typeof prop.textSize === 'number' ? prop.textSize + 'pt' : prop.textSize),
|
405
|
-
bold: prop.xaxisTextBold || prop.textBold,
|
406
|
-
italic: prop.xaxisTextItalic || prop.textItalic,
|
407
|
-
color: prop.xaxisTextColor || prop.textColor
|
408
|
-
});
|
449
|
+
}
|
409
450
|
|
410
451
|
//
|
411
452
|
// Draw the X axis labels
|
@@ -421,13 +462,22 @@
|
|
421
462
|
for (var i=0; i<prop.xaxisLabels.length; ++i) {
|
422
463
|
|
423
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
|
+
}
|
424
473
|
|
425
474
|
RG.SVG.text({
|
426
475
|
object: obj,
|
476
|
+
parent: obj.svg.all,
|
427
477
|
text: prop.xaxisLabels[i],
|
428
478
|
x: x + prop.xaxisLabelsOffsetx,
|
429
|
-
y:
|
430
|
-
valign:
|
479
|
+
y: y,
|
480
|
+
valign: valign,
|
431
481
|
halign: 'center',
|
432
482
|
size: prop.xaxisTextSize || prop.textSize,
|
433
483
|
italic: prop.xaxisTextItalic || prop.textItalic,
|
@@ -451,13 +501,22 @@
|
|
451
501
|
for (var i=0; i<prop.xaxisLabels.length; ++i) {
|
452
502
|
|
453
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
|
+
}
|
454
512
|
|
455
513
|
RG.SVG.text({
|
456
514
|
object: obj,
|
515
|
+
parent: obj.svg.all,
|
457
516
|
text: prop.xaxisLabels[i],
|
458
517
|
x: x + prop.xaxisLabelsOffsetx,
|
459
|
-
y:
|
460
|
-
valign:
|
518
|
+
y: y,
|
519
|
+
valign: valign,
|
461
520
|
halign: 'center',
|
462
521
|
size: prop.xaxisTextSize || prop.textSize,
|
463
522
|
italic: prop.xaxisTextItalic || prop.textItalic,
|
@@ -490,10 +549,21 @@
|
|
490
549
|
if (prop.yaxis) {
|
491
550
|
|
492
551
|
// The X coordinate that the Y axis is positioned at
|
493
|
-
|
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
|
+
|
494
563
|
|
495
564
|
var axis = RG.SVG.create({
|
496
565
|
svg: obj.svg,
|
566
|
+
parent: obj.svg.all,
|
497
567
|
type: 'path',
|
498
568
|
attr: {
|
499
569
|
d: 'M{1} {2} L{3} {4}'.format(
|
@@ -504,7 +574,9 @@
|
|
504
574
|
),
|
505
575
|
stroke: prop.yaxisColor,
|
506
576
|
fill: prop.yaxisColor,
|
507
|
-
'
|
577
|
+
'stroke-width': typeof prop.yaxisLinewidth === 'number' ? prop.yaxisLinewidth : 1,
|
578
|
+
'shape-rendering': "crispEdges",
|
579
|
+
'stroke-linecap': 'square'
|
508
580
|
}
|
509
581
|
});
|
510
582
|
|
@@ -516,21 +588,27 @@
|
|
516
588
|
|
517
589
|
if (obj.type === 'hbar') {
|
518
590
|
|
519
|
-
var height = obj.graphHeight / prop.yaxisLabels.length,
|
520
|
-
y = prop.gutterTop,
|
591
|
+
var height = (obj.graphHeight - prop.vmarginTop - prop.vmarginBottom) / prop.yaxisLabels.length,
|
592
|
+
y = prop.gutterTop + prop.vmarginTop,
|
521
593
|
len = prop.yaxisLabels.length,
|
522
594
|
startX = obj.getXCoord(0) + (prop.xaxisMin < 0 ? prop.yaxisTickmarksLength : 0),
|
523
595
|
endX = obj.getXCoord(0) - prop.yaxisTickmarksLength;
|
524
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
|
+
|
525
602
|
//
|
526
603
|
// Draw the tickmarks
|
527
604
|
//
|
528
605
|
if (prop.yaxisTickmarks) {
|
529
606
|
for (var i=0; i<len; ++i) {
|
530
|
-
|
607
|
+
|
531
608
|
// Draw the axis
|
532
609
|
var axis = RG.SVG.create({
|
533
610
|
svg: obj.svg,
|
611
|
+
parent: obj.svg.all,
|
534
612
|
type: 'path',
|
535
613
|
attr: {
|
536
614
|
d: 'M{1} {2} L{3} {4}'.format(
|
@@ -540,6 +618,7 @@
|
|
540
618
|
y + 0.001
|
541
619
|
),
|
542
620
|
stroke: prop.yaxisColor,
|
621
|
+
'stroke-width': typeof prop.yaxisLinewidth === 'number' ? prop.yaxisLinewidth : 1,
|
543
622
|
'shape-rendering': "crispEdges"
|
544
623
|
}
|
545
624
|
});
|
@@ -549,19 +628,32 @@
|
|
549
628
|
|
550
629
|
|
551
630
|
// Draw an extra tick if the X axis position is not zero or
|
552
|
-
//if the xaxis is not being shown
|
631
|
+
// if the xaxis is not being shown
|
553
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
|
+
|
554
643
|
var axis = RG.SVG.create({
|
555
644
|
svg: obj.svg,
|
645
|
+
parent: obj.svg.all,
|
556
646
|
type: 'path',
|
557
647
|
attr: {
|
558
648
|
d: 'M{1} {2} L{3} {4}'.format(
|
559
|
-
|
560
|
-
obj.height - prop.gutterBottom,
|
561
|
-
|
562
|
-
|
649
|
+
startX,
|
650
|
+
obj.height - prop.gutterBottom - parseFloat(prop.vmarginBottom),
|
651
|
+
|
652
|
+
endX,
|
653
|
+
obj.height - prop.gutterBottom - parseFloat(prop.vmarginBottom) - 0.001
|
563
654
|
),
|
564
655
|
stroke: obj.properties.yaxisColor,
|
656
|
+
'stroke-width': typeof prop.yaxisLinewidth === 'number' ? prop.yaxisLinewidth : 1,
|
565
657
|
'shape-rendering': "crispEdges"
|
566
658
|
}
|
567
659
|
});
|
@@ -588,6 +680,7 @@
|
|
588
680
|
// Draw the axis
|
589
681
|
var axis = RG.SVG.create({
|
590
682
|
svg: obj.svg,
|
683
|
+
parent: obj.svg.all,
|
591
684
|
type: 'path',
|
592
685
|
attr: {
|
593
686
|
d: 'M{1} {2} L{3} {4}'.format(
|
@@ -597,6 +690,7 @@
|
|
597
690
|
y + 0.001
|
598
691
|
),
|
599
692
|
stroke: prop.yaxisColor,
|
693
|
+
'stroke-width': typeof prop.yaxisLinewidth === 'number' ? prop.yaxisLinewidth : 1,
|
600
694
|
'shape-rendering': "crispEdges"
|
601
695
|
}
|
602
696
|
});
|
@@ -607,9 +701,13 @@
|
|
607
701
|
|
608
702
|
// Draw an extra tick if the X axis position is not zero or
|
609
703
|
//if the xaxis is not being shown
|
610
|
-
if (
|
704
|
+
if ( (prop.yaxisMin !== 0 || prop.xaxis === false)
|
705
|
+
&& !(obj.scale.min > 0 && obj.scale.max > 0) ) {
|
706
|
+
|
707
|
+
|
611
708
|
var axis = RG.SVG.create({
|
612
709
|
svg: obj.svg,
|
710
|
+
parent: obj.svg.all,
|
613
711
|
type: 'path',
|
614
712
|
attr: {
|
615
713
|
d: 'M{1} {2} L{3} {4}'.format(
|
@@ -619,6 +717,7 @@
|
|
619
717
|
obj.height - prop.gutterBottom - 0.001
|
620
718
|
),
|
621
719
|
stroke: prop.yaxisColor,
|
720
|
+
'stroke-width': typeof prop.yaxisLinewidth === 'number' ? prop.yaxisLinewidth : 1,
|
622
721
|
'shape-rendering': "crispEdges"
|
623
722
|
}
|
624
723
|
});
|
@@ -645,6 +744,7 @@
|
|
645
744
|
|
646
745
|
RG.SVG.text({
|
647
746
|
object: obj,
|
747
|
+
parent: obj.svg.all,
|
648
748
|
text: obj.scale.labels[i],
|
649
749
|
x: prop.gutterLeft - 7 - (prop.yaxis ? (prop.yaxisTickmarksLength - 3) : 0) + prop.yaxisLabelsOffsetx,
|
650
750
|
y: y + prop.yaxisLabelsOffsety,
|
@@ -669,6 +769,7 @@
|
|
669
769
|
|
670
770
|
var text = RG.SVG.text({
|
671
771
|
object: obj,
|
772
|
+
parent: obj.svg.all,
|
672
773
|
text: typeof prop.yaxisFormatter === 'function' ? (prop.yaxisFormatter)(this, prop.yaxisMin) : str,
|
673
774
|
x: prop.gutterLeft - 7 - (prop.yaxis ? (prop.yaxisTickmarksLength - 3) : 0) + prop.yaxisLabelsOffsetx,
|
674
775
|
y: y + prop.yaxisLabelsOffsety,
|
@@ -690,15 +791,34 @@
|
|
690
791
|
|
691
792
|
for (var i=0; i<prop.yaxisLabels.length; ++i) {
|
692
793
|
|
693
|
-
var segment = obj.graphHeight / prop.yaxisLabels.length,
|
694
|
-
y = prop.gutterTop + (segment * i) + (segment / 2) + prop.yaxisLabelsOffsety
|
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
|
+
}
|
695
814
|
|
696
815
|
var text = RG.SVG.text({
|
697
816
|
object: obj,
|
817
|
+
parent: obj.svg.all,
|
698
818
|
text: prop.yaxisLabels[i] ? prop.yaxisLabels[i] : '',
|
699
|
-
x:
|
819
|
+
x: x,
|
700
820
|
y: y,
|
701
|
-
halign:
|
821
|
+
halign: halign,
|
702
822
|
valign: 'center',
|
703
823
|
font: prop.yaxisTextFont || prop.textFont,
|
704
824
|
size: prop.yaxisTextSize || (typeof prop.textSize === 'number' ? prop.textSize + 'pt' : prop.textSize),
|
@@ -724,33 +844,117 @@
|
|
724
844
|
//
|
725
845
|
RG.SVG.drawBackground = function (obj)
|
726
846
|
{
|
727
|
-
var prop
|
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
|
+
}
|
728
929
|
|
729
930
|
if (prop .backgroundGrid) {
|
730
931
|
|
731
932
|
var parts = [];
|
732
|
-
|
933
|
+
|
934
|
+
|
935
|
+
|
733
936
|
// Add the horizontal lines to the path
|
734
937
|
if (prop.backgroundGridHlines) {
|
735
938
|
|
736
939
|
var count = typeof prop.backgroundGridHlinesCount === 'number' ? prop.backgroundGridHlinesCount : (obj.type === 'hbar' ? (prop.yaxisLabels.length || obj.data.length || 5) : prop.yaxisLabelsCount);
|
737
940
|
|
738
941
|
for (var i=0; i<count; ++i) {
|
942
|
+
|
739
943
|
parts.push('M{1} {2} L{3} {4}'.format(
|
740
|
-
prop.gutterLeft,
|
741
|
-
prop.gutterTop + (obj.graphHeight / count) * i,
|
742
|
-
obj.width - prop.gutterRight,
|
743
|
-
prop.gutterTop + (obj.graphHeight / count) * i
|
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
|
744
948
|
));
|
745
949
|
}
|
746
950
|
|
747
951
|
// Add an extra background grid line to the path - this its
|
748
952
|
// underneath the X axis and shows up if its not there.
|
749
953
|
parts.push('M{1} {2} L{3} {4}'.format(
|
750
|
-
prop.gutterLeft,
|
751
|
-
obj.height - prop.gutterBottom,
|
752
|
-
obj.width - prop.gutterRight,
|
753
|
-
obj.height - prop.gutterBottom
|
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
|
754
958
|
));
|
755
959
|
}
|
756
960
|
|
@@ -762,7 +966,9 @@
|
|
762
966
|
if (obj.type === 'line' && RG.SVG.isArray(obj.data[0])) {
|
763
967
|
var len = obj.data[0].length;
|
764
968
|
} else if (obj.type === 'hbar') {
|
765
|
-
var len = prop.xaxisLabelsCount;
|
969
|
+
var len = prop.xaxisLabelsCount || 10;
|
970
|
+
} else if (obj.type === 'scatter') {
|
971
|
+
var len = (prop.xaxisLabels && prop.xaxisLabels.length) || 10;
|
766
972
|
} else {
|
767
973
|
var len = obj.data.length;
|
768
974
|
}
|
@@ -775,10 +981,10 @@
|
|
775
981
|
|
776
982
|
for (var i=0; i<=count; ++i) {
|
777
983
|
parts.push('M{1} {2} L{3} {4}'.format(
|
778
|
-
prop.gutterLeft + ((obj.graphWidth / count) * i),
|
779
|
-
prop.gutterTop,
|
780
|
-
prop.gutterLeft + ((obj.graphWidth / count) * i),
|
781
|
-
obj.height - prop.gutterBottom
|
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
|
782
988
|
));
|
783
989
|
}
|
784
990
|
}
|
@@ -791,17 +997,17 @@
|
|
791
997
|
if (prop.backgroundGridBorder) {
|
792
998
|
parts.push('M{1} {2} L{3} {4} L{5} {6} L{7} {8} z'.format(
|
793
999
|
|
794
|
-
prop.gutterLeft,
|
795
|
-
prop.gutterTop,
|
1000
|
+
prop.gutterLeft + prop.variant3dOffsetx,
|
1001
|
+
prop.gutterTop - prop.variant3dOffsety,
|
796
1002
|
|
797
|
-
obj.width - prop.gutterRight,
|
798
|
-
prop.gutterTop,
|
1003
|
+
obj.width - prop.gutterRight + prop.variant3dOffsetx,
|
1004
|
+
prop.gutterTop - prop.variant3dOffsety,
|
799
1005
|
|
800
|
-
obj.width - prop.gutterRight,
|
801
|
-
obj.height - prop.gutterBottom,
|
1006
|
+
obj.width - prop.gutterRight + prop.variant3dOffsetx,
|
1007
|
+
obj.height - prop.gutterBottom - prop.variant3dOffsety,
|
802
1008
|
|
803
|
-
prop.gutterLeft,
|
804
|
-
obj.height - prop.gutterBottom
|
1009
|
+
prop.gutterLeft + prop.variant3dOffsetx,
|
1010
|
+
obj.height - prop.gutterBottom - prop.variant3dOffsety
|
805
1011
|
));
|
806
1012
|
}
|
807
1013
|
|
@@ -810,6 +1016,7 @@
|
|
810
1016
|
// Now draw the path
|
811
1017
|
var grid = RG.SVG.create({
|
812
1018
|
svg: obj.svg,
|
1019
|
+
parent: obj.svg.all,
|
813
1020
|
type: 'path',
|
814
1021
|
attr: {
|
815
1022
|
d: parts.join(' '),
|
@@ -892,13 +1099,13 @@
|
|
892
1099
|
* ** Must be first **
|
893
1100
|
*/
|
894
1101
|
|
895
|
-
if (
|
1102
|
+
if (max === 0 && min === 0) {
|
896
1103
|
|
897
|
-
var max
|
1104
|
+
var max = 1;
|
898
1105
|
|
899
1106
|
for (var i=0; i<numlabels; ++i) {
|
900
1107
|
|
901
|
-
var label = ((((max - min) / numlabels)
|
1108
|
+
var label = ((((max - min) / numlabels) * (i + 1)) + min).toFixed(decimals);
|
902
1109
|
|
903
1110
|
scale.labels.push(unitsPre + label + unitsPost);
|
904
1111
|
scale.values.push(parseFloat(label))
|
@@ -1647,7 +1854,7 @@
|
|
1647
1854
|
RG.SVG.text = function (opt)
|
1648
1855
|
{
|
1649
1856
|
var obj = opt.object,
|
1650
|
-
parent = opt.parent,
|
1857
|
+
parent = opt.parent || opt.object.svg.all,
|
1651
1858
|
size = opt.size,
|
1652
1859
|
bold = opt.bold,
|
1653
1860
|
font = opt.font,
|
@@ -1687,7 +1894,7 @@
|
|
1687
1894
|
|
1688
1895
|
var text = RG.SVG.create({
|
1689
1896
|
svg: obj.svg,
|
1690
|
-
parent: opt.parent
|
1897
|
+
parent: opt.parent,
|
1691
1898
|
type: 'text',
|
1692
1899
|
attr: {
|
1693
1900
|
fill: color,
|
@@ -1714,17 +1921,19 @@
|
|
1714
1921
|
|
1715
1922
|
var bbox = text.getBBox(),
|
1716
1923
|
rect = RG.SVG.create({
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
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);
|
1728
1937
|
}
|
1729
1938
|
|
1730
1939
|
|
@@ -1892,7 +2101,6 @@
|
|
1892
2101
|
RG.SVG.hideTooltip = function ()
|
1893
2102
|
{
|
1894
2103
|
var tooltip = RG.SVG.REG.get('tooltip');
|
1895
|
-
//uid = arguments[0] && arguments[0].uid ? arguments[0].uid : null;
|
1896
2104
|
|
1897
2105
|
if (tooltip && tooltip.parentNode /*&& (!uid || uid == tooltip.__canvas__.uid)*/) {
|
1898
2106
|
tooltip.parentNode.removeChild(tooltip);
|
@@ -1900,7 +2108,7 @@
|
|
1900
2108
|
tooltip.style.visibility = 'hidden';
|
1901
2109
|
RG.SVG.REG.set('tooltip', null);
|
1902
2110
|
}
|
1903
|
-
|
2111
|
+
|
1904
2112
|
if (tooltip && tooltip.__object__) {
|
1905
2113
|
RG.SVG.removeHighlight(tooltip.__object__);
|
1906
2114
|
}
|
@@ -1927,7 +2135,7 @@
|
|
1927
2135
|
|
1928
2136
|
var filter = RG.SVG.create({
|
1929
2137
|
svg: obj.svg,
|
1930
|
-
parent: obj.defs,
|
2138
|
+
parent: obj.svg.defs,
|
1931
2139
|
type: 'filter',
|
1932
2140
|
attr: {
|
1933
2141
|
id: id,
|
@@ -1993,7 +2201,7 @@
|
|
1993
2201
|
|
1994
2202
|
|
1995
2203
|
/**
|
1996
|
-
* Takes a sequential index
|
2204
|
+
* Takes a sequential index and returns the group/index variation of it. Eg if you have a
|
1997
2205
|
* sequential index from a grouped bar chart this function can be used to convert that into
|
1998
2206
|
* an appropriate group/index combination
|
1999
2207
|
*
|
@@ -2064,6 +2272,8 @@
|
|
2064
2272
|
//
|
2065
2273
|
// @patam object options The options/arg to the function
|
2066
2274
|
//
|
2275
|
+
// NB ** Still used by the Pie chart and the semi-circular Meter **
|
2276
|
+
//
|
2067
2277
|
RG.SVG.TRIG.getArcPath = function (options)
|
2068
2278
|
{
|
2069
2279
|
//
|
@@ -2142,6 +2352,163 @@
|
|
2142
2352
|
|
2143
2353
|
|
2144
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
|
+
|
2145
2512
|
/**
|
2146
2513
|
* This function gets the end point (X/Y coordinates) of a given radius.
|
2147
2514
|
* You pass it the center X/Y and the radius and this function will return
|
@@ -2183,7 +2550,8 @@
|
|
2183
2550
|
*/
|
2184
2551
|
RG.SVG.drawTitle = function (obj)
|
2185
2552
|
{
|
2186
|
-
var prop
|
2553
|
+
var prop = obj.properties;
|
2554
|
+
var valign = 'bottom';
|
2187
2555
|
|
2188
2556
|
//
|
2189
2557
|
// The Pie chart title should default to being above the centerx
|
@@ -2203,19 +2571,37 @@
|
|
2203
2571
|
|
2204
2572
|
|
2205
2573
|
|
2206
|
-
|
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
|
+
}
|
2207
2589
|
|
2208
2590
|
// If a subtitle is specified move the title up a bit in
|
2209
2591
|
// order to accommodate it
|
2210
|
-
if (prop.titleSubtitle && typeof prop.titleSubtitleY !== 'number') {
|
2592
|
+
if (prop.titleSubtitle && typeof prop.titleSubtitleY !== 'number' && !positionBottom) {
|
2211
2593
|
prop.titleY = prop.titleY - (prop.titleSubtitleSize * 1.5);
|
2212
2594
|
}
|
2213
2595
|
|
2214
2596
|
// Work out the subtitle size
|
2215
2597
|
prop.titleSubTitleSize = prop.titleSubTitleSize || prop.textSize;
|
2216
|
-
|
2598
|
+
|
2217
2599
|
// Work out the subtitle Y position
|
2218
|
-
prop.titleSubtitleY = prop.titleSubtitleY || prop.titleY +
|
2600
|
+
prop.titleSubtitleY = prop.titleSubtitleY || prop.titleY + 18;
|
2601
|
+
|
2602
|
+
if (positionBottom && typeof prop.titleSubtitleY !== 'number') {
|
2603
|
+
prop.titleSubtitleY = prop.titleY + 26;
|
2604
|
+
}
|
2219
2605
|
|
2220
2606
|
|
2221
2607
|
|
@@ -2228,14 +2614,15 @@
|
|
2228
2614
|
RG.SVG.text({
|
2229
2615
|
object: obj,
|
2230
2616
|
svg: obj.svg,
|
2617
|
+
parent: obj.svg.all,
|
2231
2618
|
text: prop.title.toString(),
|
2232
2619
|
size: prop.titleSize || (prop.textSize + 4) || 16,
|
2233
2620
|
|
2234
|
-
x: typeof prop.titleX === 'number' ? prop.titleX : prop.gutterLeft + obj.graphWidth / 2,
|
2235
|
-
y: prop.titleY,
|
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),
|
2236
2623
|
|
2237
2624
|
halign: prop.titleHalign || 'center',
|
2238
|
-
valign: prop.titleValign ||
|
2625
|
+
valign: prop.titleValign || valign,
|
2239
2626
|
color: prop.titleColor || prop.textColor || 'black',
|
2240
2627
|
bold: prop.titleBold || false,
|
2241
2628
|
italic: prop.titleItalic || false,
|
@@ -2250,12 +2637,13 @@
|
|
2250
2637
|
RG.SVG.text({
|
2251
2638
|
object: obj,
|
2252
2639
|
svg: obj.svg,
|
2640
|
+
parent: obj.svg.all,
|
2253
2641
|
text: prop.titleSubtitle,
|
2254
2642
|
size: prop.titleSubtitleSize,
|
2255
|
-
x: typeof prop.titleSubtitleX === 'number' ? prop.titleSubtitleX : prop.gutterLeft + obj.graphWidth / 2,
|
2256
|
-
y: prop.titleSubtitleY,
|
2643
|
+
x: typeof prop.titleSubtitleX === 'number' ? prop.titleSubtitleX : prop.gutterLeft + (obj.graphWidth / 2) + (prop.variant3dOffsetx || 0),
|
2644
|
+
y: prop.titleSubtitleY + (prop.variant3dOffsety || 0),
|
2257
2645
|
halign: prop.titleSubtitleHalign || 'center',
|
2258
|
-
valign: prop.titleSubtitleValign ||
|
2646
|
+
valign: prop.titleSubtitleValign || valign,
|
2259
2647
|
color: prop.titleSubtitleColor || prop.textColor || '#aaa',
|
2260
2648
|
bold: prop.titleSubtitleBold || false,
|
2261
2649
|
italic: prop.titleSubtitleItalic || false,
|
@@ -2342,7 +2730,7 @@
|
|
2342
2730
|
if (opt && opt.direction && opt.direction === 'horizontal') {
|
2343
2731
|
var grad = RG.SVG.create({
|
2344
2732
|
type: 'linearGradient',
|
2345
|
-
parent: obj.defs,
|
2733
|
+
parent: obj.svg.defs,
|
2346
2734
|
attr: {
|
2347
2735
|
id: 'RGraph-linear-gradient' + obj.gradientCounter,
|
2348
2736
|
x1: opt.start || 0,
|
@@ -2357,7 +2745,7 @@
|
|
2357
2745
|
|
2358
2746
|
var grad = RG.SVG.create({
|
2359
2747
|
type: 'linearGradient',
|
2360
|
-
parent: obj.defs,
|
2748
|
+
parent: obj.svg.defs,
|
2361
2749
|
attr: {
|
2362
2750
|
id: 'RGraph-linear-gradient' + obj.gradientCounter,
|
2363
2751
|
x1: 0,
|
@@ -2425,15 +2813,15 @@
|
|
2425
2813
|
|
2426
2814
|
var grad = RG.SVG.create({
|
2427
2815
|
type: 'radialGradient',
|
2428
|
-
parent: obj.defs,
|
2816
|
+
parent: obj.svg.defs,
|
2429
2817
|
attr: {
|
2430
2818
|
id: 'RGraph-radial-gradient' + obj.gradientCounter,
|
2431
|
-
gradientUnits: 'userSpaceOnUse',
|
2432
|
-
cx: obj.centerx,
|
2433
|
-
cy: obj.centery,
|
2434
|
-
fx: obj.centerx,
|
2435
|
-
fy: obj.centery,
|
2436
|
-
r: obj.radius
|
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
|
2437
2825
|
}
|
2438
2826
|
});
|
2439
2827
|
|
@@ -2499,7 +2887,8 @@
|
|
2499
2887
|
obj.resetColorsToOriginalValues();
|
2500
2888
|
}
|
2501
2889
|
|
2502
|
-
// Hmmm... Should this be necessary?
|
2890
|
+
// Hmmm... Should this be necessary? I don't think it will
|
2891
|
+
// do any harm to leave it in.
|
2503
2892
|
obj.originalColors = {};
|
2504
2893
|
|
2505
2894
|
|
@@ -2527,9 +2916,13 @@
|
|
2527
2916
|
//
|
2528
2917
|
RG.SVG.clear = function (svg)
|
2529
2918
|
{
|
2530
|
-
while (svg.lastChild) {
|
2531
|
-
svg.removeChild(svg.lastChild);
|
2919
|
+
while (svg.all.lastChild) {
|
2920
|
+
svg.all.removeChild(svg.all.lastChild);
|
2532
2921
|
}
|
2922
|
+
|
2923
|
+
//while (svg.lastChild) {
|
2924
|
+
// svg.removeChild(svg.lastChild);
|
2925
|
+
//}
|
2533
2926
|
};
|
2534
2927
|
|
2535
2928
|
|
@@ -2663,11 +3056,16 @@
|
|
2663
3056
|
if (highlight && RG.SVG.isArray(highlight) && highlight.length) {
|
2664
3057
|
for (var i=0,len=highlight.length; i<len; ++i) {
|
2665
3058
|
if (highlight[i].parentNode) {
|
2666
|
-
obj.svg.removeChild(highlight[i]);
|
3059
|
+
//obj.svg.removeChild(highlight[i]);
|
3060
|
+
highlight[i].parentNode.removeChild(highlight[i]);
|
2667
3061
|
}
|
2668
3062
|
}
|
2669
3063
|
} else if (highlight && highlight.parentNode) {
|
2670
|
-
|
3064
|
+
if (obj.type === 'scatter') {
|
3065
|
+
highlight.setAttribute('fill', 'transparent');
|
3066
|
+
} else {
|
3067
|
+
highlight.parentNode.removeChild(highlight);
|
3068
|
+
}
|
2671
3069
|
}
|
2672
3070
|
};
|
2673
3071
|
|
@@ -2688,7 +3086,7 @@
|
|
2688
3086
|
var svg = arguments[0];
|
2689
3087
|
|
2690
3088
|
RG.SVG.clear(svg);
|
2691
|
-
|
3089
|
+
|
2692
3090
|
var objects = RG.SVG.OR.get('id:' + svg.parentNode.id);
|
2693
3091
|
|
2694
3092
|
for (var i=0,len=objects.length; i<len; ++i) {
|
@@ -2696,7 +3094,6 @@
|
|
2696
3094
|
// Reset the colors to the original values
|
2697
3095
|
RG.SVG.resetColorsToOriginalValues({object: objects[i]});
|
2698
3096
|
|
2699
|
-
|
2700
3097
|
objects[i].draw();
|
2701
3098
|
}
|
2702
3099
|
} else {
|
@@ -2716,63 +3113,112 @@
|
|
2716
3113
|
|
2717
3114
|
|
2718
3115
|
|
2719
|
-
|
2720
|
-
|
2721
|
-
|
2722
|
-
|
2723
|
-
|
2724
|
-
|
2725
|
-
*/
|
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
|
+
//
|
2726
3122
|
RG.SVG.parseDate = function (str)
|
2727
3123
|
{
|
2728
|
-
|
3124
|
+
var d = new Date();
|
2729
3125
|
|
2730
|
-
//
|
2731
|
-
|
2732
|
-
|
2733
|
-
|
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
|
+
};
|
2734
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('|');
|
2735
3139
|
|
2736
|
-
|
2737
|
-
|
2738
|
-
|
2739
|
-
|
2740
|
-
if (str.match(/^(\d\d)(?:-|\/)(\d\d)(?:-|\/)(\d\d\d\d)(.*)$/)) {
|
2741
|
-
str = '{1}/{2}/{3}{4}'.format(
|
2742
|
-
RegExp.$3,
|
2743
|
-
RegExp.$2,
|
2744
|
-
RegExp.$1,
|
2745
|
-
RegExp.$4
|
2746
|
-
);
|
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);
|
2747
3144
|
}
|
2748
3145
|
|
2749
|
-
//
|
2750
|
-
|
2751
|
-
|
2752
|
-
|
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 = '[-./_=+~#:;,]+';
|
2753
3150
|
|
2754
|
-
// Allow for: 2013-11-22
|
2755
|
-
if (str.match(/^\d\d\d\d-\d\d-\d\d$/)) {
|
2756
|
-
str = str.replace(/-/g, '/');
|
2757
|
-
}
|
2758
3151
|
|
3152
|
+
// Tokenise the string
|
3153
|
+
var tokens = str.split(/ +/);
|
2759
3154
|
|
2760
|
-
//
|
2761
|
-
|
2762
|
-
|
2763
|
-
|
2764
|
-
|
2765
|
-
|
2766
|
-
|
2767
|
-
|
2768
|
-
|
2769
|
-
|
2770
|
-
|
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
|
+
}
|
2771
3191
|
|
2772
|
-
|
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
|
+
}
|
2773
3199
|
}
|
2774
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
|
+
|
2775
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
|
+
}
|
2776
3222
|
};
|
2777
3223
|
|
2778
3224
|
|
@@ -2928,32 +3374,6 @@
|
|
2928
3374
|
|
2929
3375
|
|
2930
3376
|
|
2931
|
-
/**
|
2932
|
-
* This function determines whther a canvas is fixed (CSS positioning) or not. If not it returns
|
2933
|
-
* false. If it is then the element that is fixed is returned (it may be a parent of the canvas).
|
2934
|
-
*
|
2935
|
-
* @return Either false or the fixed positioned element
|
2936
|
-
*/
|
2937
|
-
RG.isFixed = function (canvas)
|
2938
|
-
{
|
2939
|
-
var obj = canvas;
|
2940
|
-
var i = 0;
|
2941
|
-
|
2942
|
-
while (obj && obj.tagName.toLowerCase() != 'body' && i < 99) {
|
2943
|
-
|
2944
|
-
if (obj.style.position == 'fixed') {
|
2945
|
-
return obj;
|
2946
|
-
}
|
2947
|
-
|
2948
|
-
obj = obj.offsetParent;
|
2949
|
-
}
|
2950
|
-
|
2951
|
-
return false;
|
2952
|
-
};
|
2953
|
-
|
2954
|
-
|
2955
|
-
|
2956
|
-
|
2957
3377
|
|
2958
3378
|
|
2959
3379
|
|
@@ -3032,31 +3452,36 @@
|
|
3032
3452
|
}
|
3033
3453
|
|
3034
3454
|
if (typeof RG.SVG.measuretext_cache == 'object' && RG.SVG.measuretext_cache[str]) {
|
3455
|
+
|
3035
3456
|
return RG.SVG.measuretext_cache[str];
|
3036
3457
|
}
|
3037
3458
|
|
3038
|
-
if (!RG.SVG.measuretext_cache['text-
|
3039
|
-
var
|
3040
|
-
|
3041
|
-
|
3042
|
-
|
3043
|
-
|
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);
|
3044
3469
|
|
3045
3470
|
// Now store the newly created DIV
|
3046
|
-
RG.SVG.measuretext_cache['text-
|
3471
|
+
RG.SVG.measuretext_cache['text-span'] = span;
|
3047
3472
|
|
3048
|
-
} else if (RG.SVG.measuretext_cache['text-
|
3049
|
-
var
|
3473
|
+
} else if (RG.SVG.measuretext_cache['text-span']) {
|
3474
|
+
var span = RG.SVG.measuretext_cache['text-span'];
|
3050
3475
|
}
|
3051
3476
|
|
3052
|
-
|
3053
|
-
|
3054
|
-
|
3055
|
-
|
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';
|
3056
3481
|
|
3057
|
-
var sizes = [
|
3482
|
+
var sizes = [span.offsetWidth, span.offsetHeight];
|
3058
3483
|
|
3059
|
-
//document.body.removeChild(
|
3484
|
+
//document.body.removeChild(span);
|
3060
3485
|
RG.SVG.measuretext_cache[str] = sizes;
|
3061
3486
|
|
3062
3487
|
return sizes;
|
@@ -3156,6 +3581,8 @@
|
|
3156
3581
|
//
|
3157
3582
|
RG.SVG.attribution = function (obj)
|
3158
3583
|
{
|
3584
|
+
return;
|
3585
|
+
/*
|
3159
3586
|
var prop = obj.properties;
|
3160
3587
|
|
3161
3588
|
if (!prop.attribution && typeof prop.attribution !== 'undefined') {
|
@@ -3166,9 +3593,12 @@
|
|
3166
3593
|
// Create the A tag
|
3167
3594
|
var a = RG.SVG.create({
|
3168
3595
|
svg: obj.svg,
|
3596
|
+
parent: obj.svg.all,
|
3169
3597
|
type: 'a',
|
3170
3598
|
attr: {
|
3171
|
-
|
3599
|
+
rel: 'nofollow',
|
3600
|
+
target: '_blank',
|
3601
|
+
'xlink:href': prop.attributionHref || 'http://www.rgraph.net/'
|
3172
3602
|
}
|
3173
3603
|
});
|
3174
3604
|
|
@@ -3196,7 +3626,7 @@
|
|
3196
3626
|
var text = RG.SVG.text({
|
3197
3627
|
object: obj,
|
3198
3628
|
parent: a,
|
3199
|
-
text: typeof prop.attributionText === 'string' ? prop.attributionText : 'RGraph
|
3629
|
+
text: typeof prop.attributionText === 'string' ? prop.attributionText : 'JavaScript charts with RGraph',
|
3200
3630
|
x: x,
|
3201
3631
|
y: y,
|
3202
3632
|
halign: prop.attributionHalign || 'right',
|
@@ -3207,6 +3637,23 @@
|
|
3207
3637
|
italic: prop.attributionItalic,
|
3208
3638
|
bold: prop.attributionBold
|
3209
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
|
+
{
|
3210
3657
|
};
|
3211
3658
|
|
3212
3659
|
|
@@ -3223,11 +3670,13 @@
|
|
3223
3670
|
* @param number max The maximum value
|
3224
3671
|
* @param number OPTIONAL Number of decimal places
|
3225
3672
|
*/
|
3226
|
-
RG.SVG.random = function (
|
3673
|
+
RG.SVG.random = function (opt)
|
3227
3674
|
{
|
3228
|
-
var
|
3229
|
-
|
3230
|
-
|
3675
|
+
var min = opt.min,
|
3676
|
+
max = opt.max,
|
3677
|
+
dp = opt.dp || opt.decimals || 0,
|
3678
|
+
r = ma.random();
|
3679
|
+
|
3231
3680
|
return Number((((max - min) * r) + min).toFixed(dp));
|
3232
3681
|
};
|
3233
3682
|
|
@@ -3238,6 +3687,132 @@
|
|
3238
3687
|
|
3239
3688
|
|
3240
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
|
+
|
3241
3816
|
//
|
3242
3817
|
// This is here so that if the tooltip library has not
|
3243
3818
|
// been included, this function will show an alert
|