rgraph-rails 1.0.4 → 1.0.5

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.
Files changed (55) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +1 -0
  3. data/README.md +2 -2
  4. data/lib/rgraph-rails/version.rb +1 -1
  5. data/vendor/assets/images/bullet.png +0 -0
  6. data/vendor/assets/images/facebook-large.png +0 -0
  7. data/vendor/assets/images/google-plus-large.png +0 -0
  8. data/vendor/assets/images/logo.png +0 -0
  9. data/vendor/assets/images/rgraph.jpg +0 -0
  10. data/vendor/assets/javascripts/RGraph.bar.js +533 -242
  11. data/vendor/assets/javascripts/RGraph.bipolar.js +152 -169
  12. data/vendor/assets/javascripts/RGraph.common.annotate.js +2 -2
  13. data/vendor/assets/javascripts/RGraph.common.context.js +2 -2
  14. data/vendor/assets/javascripts/RGraph.common.core.js +688 -373
  15. data/vendor/assets/javascripts/RGraph.common.csv.js +2 -2
  16. data/vendor/assets/javascripts/RGraph.common.deprecated.js +2 -2
  17. data/vendor/assets/javascripts/RGraph.common.dynamic.js +188 -193
  18. data/vendor/assets/javascripts/RGraph.common.effects.js +62 -38
  19. data/vendor/assets/javascripts/RGraph.common.key.js +35 -15
  20. data/vendor/assets/javascripts/RGraph.common.resizing.js +38 -21
  21. data/vendor/assets/javascripts/RGraph.common.sheets.js +2 -2
  22. data/vendor/assets/javascripts/RGraph.common.tooltips.js +48 -40
  23. data/vendor/assets/javascripts/RGraph.common.zoom.js +2 -2
  24. data/vendor/assets/javascripts/RGraph.drawing.background.js +33 -49
  25. data/vendor/assets/javascripts/RGraph.drawing.circle.js +27 -30
  26. data/vendor/assets/javascripts/RGraph.drawing.image.js +23 -26
  27. data/vendor/assets/javascripts/RGraph.drawing.marker1.js +47 -40
  28. data/vendor/assets/javascripts/RGraph.drawing.marker2.js +38 -42
  29. data/vendor/assets/javascripts/RGraph.drawing.marker3.js +24 -28
  30. data/vendor/assets/javascripts/RGraph.drawing.poly.js +25 -39
  31. data/vendor/assets/javascripts/RGraph.drawing.rect.js +27 -32
  32. data/vendor/assets/javascripts/RGraph.drawing.text.js +53 -58
  33. data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +24 -29
  34. data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +45 -51
  35. data/vendor/assets/javascripts/RGraph.fuel.js +11 -9
  36. data/vendor/assets/javascripts/RGraph.funnel.js +40 -43
  37. data/vendor/assets/javascripts/RGraph.gantt.js +34 -34
  38. data/vendor/assets/javascripts/RGraph.gauge.js +64 -55
  39. data/vendor/assets/javascripts/RGraph.hbar.js +194 -137
  40. data/vendor/assets/javascripts/RGraph.hprogress.js +261 -167
  41. data/vendor/assets/javascripts/RGraph.line.js +520 -512
  42. data/vendor/assets/javascripts/RGraph.meter.js +11 -10
  43. data/vendor/assets/javascripts/RGraph.modaldialog.js +11 -2
  44. data/vendor/assets/javascripts/RGraph.odo.js +11 -9
  45. data/vendor/assets/javascripts/RGraph.pie.js +385 -100
  46. data/vendor/assets/javascripts/RGraph.radar.js +36 -29
  47. data/vendor/assets/javascripts/RGraph.rose.js +58 -41
  48. data/vendor/assets/javascripts/RGraph.rscatter.js +40 -36
  49. data/vendor/assets/javascripts/RGraph.scatter.js +441 -499
  50. data/vendor/assets/javascripts/RGraph.semicircularprogress.js +1015 -0
  51. data/vendor/assets/javascripts/RGraph.thermometer.js +37 -37
  52. data/vendor/assets/javascripts/RGraph.vprogress.js +285 -157
  53. data/vendor/assets/javascripts/RGraph.waterfall.js +62 -62
  54. data/vendor/assets/stylesheets/website.css +30 -16
  55. metadata +3 -2
@@ -1,4 +1,4 @@
1
- // version: 2016-02-06
1
+ // version: 2016-06-04
2
2
  /**
3
3
  * o--------------------------------------------------------------------------------o
4
4
  * | This file is part of the RGraph package - you can learn more at: |
@@ -7,7 +7,7 @@
7
7
  * | |
8
8
  * | RGraph is dual licensed under the Open Source GPL (General Public License) |
9
9
  * | v2.0 license and a commercial license which means that you're not bound by |
10
- * | the terms of the GPL. The commercial license starts at just 99 (GBP) and |
10
+ * | the terms of the GPL. The commercial license starts at just 99 GBP and |
11
11
  * | you can read about it here: |
12
12
  * | |
13
13
  * | http://www.rgraph.net/license |
@@ -1,4 +1,4 @@
1
- // version: 2016-02-06
1
+ // version: 2016-06-04
2
2
  /**
3
3
  * o--------------------------------------------------------------------------------o
4
4
  * | This file is part of the RGraph package - you can learn more at: |
@@ -7,7 +7,7 @@
7
7
  * | |
8
8
  * | RGraph is dual licensed under the Open Source GPL (General Public License) |
9
9
  * | v2.0 license and a commercial license which means that you're not bound by |
10
- * | the terms of the GPL. The commercial license starts at just 99 (GBP) and |
10
+ * | the terms of the GPL. The commercial license starts at just 99 GBP and |
11
11
  * | you can read about it here: |
12
12
  * | |
13
13
  * | http://www.rgraph.net/license |
@@ -1,13 +1,14 @@
1
- // version: 2016-02-06
1
+ // version: 2016-06-04
2
2
  /**
3
3
  * o--------------------------------------------------------------------------------o
4
4
  * | This file is part of the RGraph package - you can learn more at: |
5
5
  * | |
6
6
  * | http://www.rgraph.net |
7
- * | |
7
+ * | F |
8
+ * | F |
8
9
  * | RGraph is dual licensed under the Open Source GPL (General Public License) |
9
10
  * | v2.0 license and a commercial license which means that you're not bound by |
10
- * | the terms of the GPL. The commercial license starts at just 99 (GBP) and |
11
+ * | the terms of the GPL. The commercial license starts at just 99 GBP and |
11
12
  * | you can read about it here: |
12
13
  * | |
13
14
  * | http://www.rgraph.net/license |
@@ -428,7 +429,7 @@
428
429
  temp[i] = obj[i];
429
430
 
430
431
  } else {
431
- temp[i] = RG.array_clone(obj[i]);
432
+ temp[i] = RG.arrayClone(obj[i]);
432
433
  }
433
434
  }
434
435
 
@@ -489,6 +490,7 @@
489
490
  RG.arrayMin = function (arr)
490
491
  {
491
492
  var max = null,
493
+ min = null,
492
494
  ma = Math;
493
495
 
494
496
  if (typeof arr === 'number') {
@@ -704,34 +706,47 @@
704
706
  return;
705
707
  }
706
708
 
707
- RG.FireCustomEvent(obj, 'onbeforeclear');
709
+ RG.fireCustomEvent(obj, 'onbeforeclear');
708
710
 
709
- if (RG.ISIE8 && !color) {
710
- color = 'white';
711
+ /**
712
+ * Set the CSS display: to none for DOM text
713
+ */
714
+ if (RG.text2.domNodeCache && RG.text2.domNodeCache[ca.id]) {
715
+ for (var i in RG.text2.domNodeCache[ca.id]) {
716
+
717
+ var el = RG.text2.domNodeCache[ca.id][i];
718
+
719
+ if (el && el.style) {
720
+ el.style.display = 'none';
721
+ }
722
+ }
711
723
  }
712
724
 
713
725
  /**
714
726
  * Can now clear the canvas back to fully transparent
715
727
  */
716
- if (!color || (color && color === 'rgba(0,0,0,0)' || color === 'transparent')) {
728
+ if ( !color
729
+ || (color && color === 'rgba(0,0,0,0)' || color === 'transparent')
730
+ ) {
717
731
 
718
- co.clearRect(0,0,ca.width, ca.height);
732
+ co.clearRect(-100,-100,ca.width + 200, ca.height + 200);
719
733
 
720
734
  // Reset the globalCompositeOperation
721
735
  co.globalCompositeOperation = 'source-over';
722
736
 
737
+ } else if (color) {
738
+ RG.path2(co, 'fs % fr -100 -100 % %',
739
+ color,
740
+ ca.width + 200,
741
+ ca.height + 200
742
+ );
743
+
723
744
  } else {
724
-
725
- co.fillStyle = color;
726
- co.beginPath();
727
-
728
- if (RG.ISIE8) {
729
- co.fillRect(0,0,ca.width,ca.height);
730
- } else {
731
- co.fillRect(-10,-10,ca.width + 20,ca.height + 20);
732
- }
733
-
734
- co.fill();
745
+ RG.path2(co, 'fs % fr -100 -100 % %',
746
+ obj.get('clearto'),
747
+ ca.width + 200,
748
+ ca.height + 200
749
+ );
735
750
  }
736
751
 
737
752
  //if (RG.ClearAnnotations) {
@@ -752,7 +767,7 @@
752
767
  * This hides the tooltip that is showing IF it has the same canvas ID as
753
768
  * that which is being cleared
754
769
  */
755
- if (RG.Registry.Get('chart.tooltip') && obj.get('chart.tooltips.nohideonclear') !== true) {
770
+ if (RG.Registry.Get('chart.tooltip') && obj && !obj.get('chart.tooltips.nohideonclear')) {
756
771
  RG.HideTooltip(ca);
757
772
  //RG.Redraw();
758
773
  }
@@ -796,13 +811,14 @@
796
811
  {
797
812
  var ca = canvas = obj.canvas,
798
813
  co = context = obj.context,
799
- prop = obj.properties,
814
+ prop = obj.properties
800
815
  gutterLeft = prop['chart.gutter.left'],
801
816
  gutterRight = prop['chart.gutter.right'],
802
817
  gutterTop = gutterTop,
803
818
  gutterBottom = prop['chart.gutter.bottom'],
804
819
  size = arguments[4] ? arguments[4] : 12,
805
820
  bold = prop['chart.title.bold'],
821
+ italic = prop['chart.title.italic'],
806
822
  centerx = (arguments[3] ? arguments[3] : ((ca.width - gutterLeft - gutterRight) / 2) + gutterLeft),
807
823
  keypos = prop['chart.key.position'],
808
824
  vpos = prop['chart.title.vpos'],
@@ -924,7 +940,8 @@
924
940
  /**
925
941
  * Draw the title
926
942
  */
927
- RG.Text2(co, {
943
+
944
+ RG.text2(co, {
928
945
  'font':font,
929
946
  'size':size,
930
947
  'x':centerx,
@@ -935,7 +952,9 @@
935
952
  'bounding':bgcolor != null,
936
953
  'bounding.fill':bgcolor,
937
954
  'bold':bold,
938
- 'tag':'title'
955
+ italic: italic,
956
+ 'tag':'title',
957
+ marker: false
939
958
  });
940
959
 
941
960
  // Reset the fill colour
@@ -952,6 +971,11 @@
952
971
  */
953
972
  RG.getMouseXY = function(e)
954
973
  {
974
+ // This is necessary foe IE9
975
+ if (!e.target) {
976
+ return;
977
+ }
978
+
955
979
  var el = e.target;
956
980
  var ca = el;
957
981
  var caStyle = ca.style;
@@ -1203,19 +1227,17 @@
1203
1227
  RG.background.draw =
1204
1228
  RG.background.Draw = function (obj)
1205
1229
  {
1206
- var func = function (obj, canvas, context)
1207
- {
1208
- var ca = canvas,
1209
- co = context,
1210
- prop = obj.properties,
1211
-
1212
- height = 0,
1213
- gutterLeft = obj.gutterLeft,
1214
- gutterRight = obj.gutterRight,
1215
- gutterTop = obj.gutterTop,
1216
- gutterBottom = obj.gutterBottom,
1217
- variant = prop['chart.variant']
1218
-
1230
+ var ca = obj.canvas,
1231
+ co = obj.context,
1232
+ prop = obj.properties,
1233
+ height = 0,
1234
+ gutterLeft = obj.gutterLeft,
1235
+ gutterRight = obj.gutterRight,
1236
+ gutterTop = obj.gutterTop,
1237
+ gutterBottom = obj.gutterBottom,
1238
+ variant = prop['chart.variant']
1239
+
1240
+
1219
1241
  co.fillStyle = prop['chart.text.color'];
1220
1242
 
1221
1243
  // If it's a bar and 3D variant, translate
@@ -1260,8 +1282,7 @@
1260
1282
 
1261
1283
 
1262
1284
 
1263
-
1264
- RG.Text2(co, {
1285
+ RG.text2(prop['chart.text.accessible'] ? obj.context : co, {
1265
1286
  'font':font,
1266
1287
  'size':size,
1267
1288
  'x':hpos,
@@ -1319,9 +1340,9 @@
1319
1340
  if (typeof prop['chart.title.yaxis.y'] === 'number') {
1320
1341
  y = prop['chart.title.yaxis.y'];
1321
1342
  }
1322
-
1343
+
1323
1344
  co.fillStyle = color;
1324
- RG.text2(co, {
1345
+ RG.text2(prop['chart.text.accessible'] ? obj.context : co, {
1325
1346
  'font':font,
1326
1347
  'size':size,
1327
1348
  'x':yaxis_title_pos,
@@ -1331,7 +1352,8 @@
1331
1352
  'angle':angle,
1332
1353
  'bold':bold,
1333
1354
  'text':prop['chart.title.yaxis'],
1334
- 'tag':'title yaxis'
1355
+ 'tag':'title yaxis',
1356
+ accessible: false
1335
1357
  });
1336
1358
  }
1337
1359
 
@@ -1376,10 +1398,10 @@
1376
1398
 
1377
1399
  for (var i=0; i<numbars; i+=2) {
1378
1400
  co.rect(gutterLeft,
1379
- (i * barHeight) + gutterTop,
1380
- ca.width - gutterLeft - gutterRight,
1381
- barHeight
1382
- );
1401
+ (i * barHeight) + gutterTop,
1402
+ ca.width - gutterLeft - gutterRight,
1403
+ barHeight
1404
+ );
1383
1405
  }
1384
1406
  co.fill();
1385
1407
 
@@ -1399,158 +1421,153 @@
1399
1421
  }
1400
1422
 
1401
1423
  co.fill();
1402
-
1403
-
1404
-
1405
-
1406
-
1407
-
1408
-
1409
-
1410
-
1411
-
1412
-
1413
-
1414
-
1415
-
1416
-
1417
1424
 
1425
+ // Close any errantly open path
1426
+ co.beginPath();
1418
1427
 
1419
1428
 
1420
1429
 
1421
1430
 
1422
-
1423
-
1424
-
1425
-
1426
- // Draw the background grid
1427
- if (prop['chart.background.grid']) {
1428
-
1429
- // If autofit is specified, use the .numhlines and .numvlines along with the width to work
1430
- // out the hsize and vsize
1431
- if (prop['chart.background.grid.autofit']) {
1432
-
1433
- /**
1434
- * Align the grid to the tickmarks
1435
- */
1436
- if (prop['chart.background.grid.autofit.align']) {
1437
-
1438
- // Align the horizontal lines
1439
- if (obj.type === 'hbar') {
1440
- obj.set('chart.background.grid.autofit.numhlines', obj.data.length);
1441
- }
1442
-
1443
- // Align the vertical lines for the line
1444
- if (obj.type === 'line') {
1445
- if (typeof prop['chart.background.grid.autofit.numvlines'] === 'number') {
1446
- // Nada
1447
- } else if (prop['chart.labels'] && prop['chart.labels'].length) {
1448
- obj.Set('chart.background.grid.autofit.numvlines', prop['chart.labels'].length - 1);
1449
- } else {
1450
- obj.Set('chart.background.grid.autofit.numvlines', obj.data[0].length - 1);
1431
+ //
1432
+ // The background grid is cached
1433
+ //
1434
+ var func = function (obj, cacheCanvas, cacheContext)
1435
+ {
1436
+ // Draw the background grid
1437
+ if (prop['chart.background.grid']) {
1438
+
1439
+ // If autofit is specified, use the .numhlines and .numvlines along with the width to work
1440
+ // out the hsize and vsize
1441
+ if (prop['chart.background.grid.autofit']) {
1442
+
1443
+ /**
1444
+ * Align the grid to the tickmarks
1445
+ */
1446
+ if (prop['chart.background.grid.autofit.align']) {
1447
+
1448
+ // Align the horizontal lines
1449
+ if (obj.type === 'hbar') {
1450
+ obj.set('chart.background.grid.autofit.numhlines', obj.data.length);
1451
1451
  }
1452
- } else if (obj.type === 'waterfall') {
1452
+
1453
+ // Align the vertical lines for the line
1454
+ if (obj.type === 'line') {
1455
+ if (typeof prop['chart.background.grid.autofit.numvlines'] === 'number') {
1456
+ // Nada
1457
+ } else if (prop['chart.labels'] && prop['chart.labels'].length) {
1458
+ obj.Set('chart.background.grid.autofit.numvlines', prop['chart.labels'].length - 1);
1459
+ } else {
1460
+ obj.Set('chart.background.grid.autofit.numvlines', obj.data[0].length - 1);
1461
+ }
1462
+ } else if (obj.type === 'waterfall') {
1453
1463
  obj.set(
1454
1464
  'backgroundGridAutofitNumvlines',
1455
1465
  obj.data.length + (prop['chart.total'] ? 1 : 0)
1456
1466
  );
1457
-
1458
-
1459
- // Align the vertical lines for the bar, Scatter
1460
- } else if ( (
1461
- obj.type === 'bar' ||
1462
- obj.type === 'scatter'
1463
- )
1467
+
1468
+ // Align the vertical lines for the bar, Scatter
1469
+ } else if ( (
1470
+ obj.type === 'bar' ||
1471
+ obj.type === 'scatter'
1472
+ )
1473
+
1474
+ && (
1475
+ (prop['chart.labels'] && prop['chart.labels'].length)
1476
+ || obj.type === 'bar'
1477
+ )
1478
+ ) {
1479
+
1480
+ var len = (prop['chart.labels'] && prop['chart.labels'].length) || obj.data.length;
1481
+
1482
+
1483
+ obj.set({
1484
+ backgroundGridAutofitNumvlines: len
1485
+ });
1486
+
1487
+ // Gantt
1488
+ } else if (obj.type === 'gantt') {
1489
+
1490
+ if (typeof obj.get('chart.background.grid.autofit.numvlines') === 'number') {
1491
+ // Nothing to do here
1492
+ } else {
1493
+ obj.set('chart.background.grid.autofit.numvlines', prop['chart.xmax']);
1494
+ }
1495
+
1496
+ obj.set('chart.background.grid.autofit.numhlines', obj.data.length);
1464
1497
 
1465
- && (
1466
- (prop['chart.labels'] && prop['chart.labels'].length)
1467
- || obj.type === 'bar'
1468
- )
1469
- ) {
1470
-
1471
- var len = (prop['chart.labels'] && prop['chart.labels'].length) || obj.data.length;
1472
-
1473
-
1474
- obj.set({
1475
- backgroundGridAutofitNumvlines: len
1476
- });
1477
-
1478
- // Gantt
1479
- } else if (obj.type === 'gantt') {
1480
-
1481
- if (typeof obj.get('chart.background.grid.autofit.numvlines') === 'number') {
1482
- // Nothing to do here
1483
- } else {
1484
- obj.set('chart.background.grid.autofit.numvlines', prop['chart.xmax']);
1498
+ // HBar
1499
+ } else if (obj.type === 'hbar' && RG.isNull(prop['chart.background.grid.autofit.numhlines']) ) {
1500
+ obj.set('chart.background.grid.autofit.numhlines', obj.data.length);
1485
1501
  }
1486
-
1487
- obj.set('chart.background.grid.autofit.numhlines', obj.data.length);
1488
-
1489
- // HBar
1490
- } else if (obj.type === 'hbar' && RG.isNull(prop['chart.background.grid.autofit.numhlines']) ) {
1491
- obj.set('chart.background.grid.autofit.numhlines', obj.data.length);
1492
1502
  }
1493
- }
1494
-
1495
- var vsize = ((ca.width - gutterLeft - gutterRight)) / prop['chart.background.grid.autofit.numvlines'];
1496
- var hsize = (ca.height - gutterTop - gutterBottom) / prop['chart.background.grid.autofit.numhlines'];
1497
-
1498
- obj.Set('chart.background.grid.vsize', vsize);
1499
- obj.Set('chart.background.grid.hsize', hsize);
1500
- }
1501
-
1502
- co.beginPath();
1503
- co.lineWidth = prop['chart.background.grid.width'] ? prop['chart.background.grid.width'] : 1;
1504
- co.strokeStyle = prop['chart.background.grid.color'];
1505
1503
 
1506
- // Dashed background grid
1507
- if (prop['chart.background.grid.dashed'] && typeof co.setLineDash == 'function') {
1508
- co.setLineDash([3,5]);
1509
- }
1510
-
1511
- // Dotted background grid
1512
- if (prop['chart.background.grid.dotted'] && typeof co.setLineDash == 'function') {
1513
- co.setLineDash([1,3]);
1514
- }
1515
-
1516
- co.beginPath();
1504
+ var vsize = ((cacheCanvas.width - gutterLeft - gutterRight)) / prop['chart.background.grid.autofit.numvlines'];
1505
+ var hsize = (cacheCanvas.height - gutterTop - gutterBottom) / prop['chart.background.grid.autofit.numhlines'];
1517
1506
 
1507
+ obj.Set('chart.background.grid.vsize', vsize);
1508
+ obj.Set('chart.background.grid.hsize', hsize);
1509
+ }
1518
1510
 
1519
- // Draw the horizontal lines
1520
- if (prop['chart.background.grid.hlines']) {
1521
- height = (ca.height - gutterBottom)
1522
- var hsize = prop['chart.background.grid.hsize'];
1523
- for (y=gutterTop; y<=height; y+=hsize) {
1524
- context.moveTo(gutterLeft, ma.round(y));
1525
- context.lineTo(ca.width - gutterRight, ma.round(y));
1511
+ co.beginPath();
1512
+ cacheContext.lineWidth = prop['chart.background.grid.width'] ? prop['chart.background.grid.width'] : 1;
1513
+ cacheContext.strokeStyle = prop['chart.background.grid.color'];
1514
+
1515
+ // Dashed background grid
1516
+ if (prop['chart.background.grid.dashed'] && typeof cacheContext.setLineDash == 'function') {
1517
+ cacheContext.setLineDash([3,5]);
1526
1518
  }
1527
- }
1519
+
1520
+ // Dotted background grid
1521
+ if (prop['chart.background.grid.dotted'] && typeof cacheContext.setLineDash == 'function') {
1522
+ cacheContext.setLineDash([1,3]);
1523
+ }
1524
+
1525
+ co.beginPath();
1526
+
1527
+
1528
+ // Draw the horizontal lines
1529
+ if (prop['chart.background.grid.hlines']) {
1530
+ height = (cacheCanvas.height - gutterBottom)
1531
+ var hsize = prop['chart.background.grid.hsize'];
1532
+ for (y=gutterTop; y<=height; y+=hsize) {
1533
+ cacheContext.moveTo(gutterLeft, ma.round(y));
1534
+ cacheContext.lineTo(ca.width - gutterRight, ma.round(y));
1535
+ }
1536
+ }
1537
+
1538
+ if (prop['chart.background.grid.vlines']) {
1539
+ // Draw the vertical lines
1540
+ var width = (cacheCanvas.width - gutterRight)
1541
+ var vsize = prop['chart.background.grid.vsize'];
1528
1542
 
1529
- if (prop['chart.background.grid.vlines']) {
1530
- // Draw the vertical lines
1531
- var width = (ca.width - gutterRight)
1532
- var vsize = prop['chart.background.grid.vsize'];
1533
-
1534
- for (x=gutterLeft; x<=width; x+=vsize) {
1535
- co.moveTo(ma.round(x), gutterTop);
1536
- co.lineTo(ma.round(x), ca.height - gutterBottom);
1543
+ for (x=gutterLeft; x<=width; x+=vsize) {
1544
+ cacheContext.moveTo(ma.round(x), gutterTop);
1545
+ cacheContext.lineTo(ma.round(x), ca.height - gutterBottom);
1546
+ }
1547
+ }
1548
+
1549
+ if (prop['chart.background.grid.border']) {
1550
+ // Make sure a rectangle, the same colour as the grid goes around the graph
1551
+ cacheContext.strokeStyle = prop['chart.background.grid.color'];
1552
+ cacheContext.strokeRect(ma.round(gutterLeft), ma.round(gutterTop), ca.width - gutterLeft - gutterRight, ca.height - gutterTop - gutterBottom);
1537
1553
  }
1538
1554
  }
1539
1555
 
1540
- if (prop['chart.background.grid.border']) {
1541
- // Make sure a rectangle, the same colour as the grid goes around the graph
1542
- co.strokeStyle = prop['chart.background.grid.color'];
1543
- co.strokeRect(ma.round(gutterLeft), ma.round(gutterTop), ca.width - gutterLeft - gutterRight, ca.height - gutterTop - gutterBottom);
1544
- }
1556
+ cacheContext.stroke();
1557
+
1558
+
1559
+
1560
+ // Necessary to ensure the grids drawn before continuing
1561
+ cacheContext.beginPath();
1562
+ cacheContext.closePath();
1545
1563
  }
1564
+
1565
+ // Now a cached draw in newer browsers
1566
+ RG.cachedDraw(obj, obj.uid + '_background', func);
1546
1567
 
1547
- co.stroke();
1548
1568
 
1549
1569
 
1550
1570
 
1551
- // Necessary to ensure the gris drawn before continuing
1552
- co.beginPath();
1553
- co.closePath();
1554
1571
 
1555
1572
 
1556
1573
 
@@ -1564,29 +1581,24 @@
1564
1581
  co.setLineDash([1,0]);
1565
1582
  }
1566
1583
 
1567
- // Draw the title if one is set
1568
- if ( typeof(prop['chart.title']) == 'string') {
1569
-
1570
- if (obj.type == 'gantt') {
1571
- gutterTop -= 10;
1572
- }
1573
-
1574
- RG.drawTitle(
1575
- // Because of caching the obj variablee cannot be used here
1576
- {context: co, canvas: ca, properties: prop},
1577
- prop['chart.title'],
1578
- gutterTop,
1579
- null,
1580
- prop['chart.title.size'] ? prop['chart.title.size'] : prop['chart.text.size'] + 2,
1581
- {canvas: ca, context: co}
1582
- );
1583
- }
1584
-
1585
1584
  co.stroke();
1586
- }
1587
1585
 
1588
- // Now a cached draw in newer browsers
1589
- RG.ISOLD ? func(obj, obj.canvas, obj.context) : RG.cachedDraw(obj, obj.uid + '_background', func);
1586
+
1587
+
1588
+ // Draw the title if one is set
1589
+ if ( typeof(obj.properties['chart.title']) == 'string') {
1590
+
1591
+ var prop = obj.properties;
1592
+
1593
+ RG.drawTitle(
1594
+ obj,
1595
+ prop['chart.title'],
1596
+ obj.gutterTop,
1597
+ null,
1598
+ prop['chart.title.size'] ? prop['chart.title.size'] : prop['chart.text.size'] + 2,
1599
+ obj
1600
+ );
1601
+ }
1590
1602
  };
1591
1603
 
1592
1604
 
@@ -1848,7 +1860,7 @@
1848
1860
  /**
1849
1861
  * Turn off any shadow
1850
1862
  */
1851
- RG.NoShadow(obj);
1863
+ RG.noShadow(obj);
1852
1864
 
1853
1865
  if (labels_processed && labels_processed.length > 0) {
1854
1866
 
@@ -1903,8 +1915,8 @@
1903
1915
  co.fill();
1904
1916
 
1905
1917
 
1906
- } else if (obj.type == 'line') {
1907
-
1918
+ } else {
1919
+
1908
1920
  if (
1909
1921
  typeof labels_processed[i] == 'object' &&
1910
1922
  typeof labels_processed[i][3] == 'number' &&
@@ -1955,17 +1967,18 @@
1955
1967
  // Fore ground color
1956
1968
  co.fillStyle = (typeof labels_processed[i] === 'object' && typeof labels_processed[i][1] === 'string') ? labels_processed[i][1] : 'black';
1957
1969
 
1958
- RG.Text2(obj,{'font':prop['chart.text.font'],
1959
- 'size':prop['chart.text.size'],
1960
- 'x':text_x,
1961
- 'y':text_y,
1962
- 'text': (typeof labels_processed[i] === 'object' && typeof labels_processed[i][0] === 'string') ? labels_processed[i][0] : labels_processed[i],
1963
- 'valign': 'bottom',
1964
- 'halign':'center',
1965
- 'bounding':true,
1966
- 'bounding.fill': (typeof labels_processed[i] === 'object' && typeof labels_processed[i][2] === 'string') ? labels_processed[i][2] : 'white',
1967
- 'tag':'labels ingraph'
1968
- });
1970
+ RG.text2(obj,{
1971
+ 'font':prop['chart.text.font'],
1972
+ 'size':prop['chart.text.size'],
1973
+ 'x':text_x,
1974
+ 'y':text_y + (obj.properties['chart.text.accessible'] ? 2 : 0),
1975
+ 'text': (typeof labels_processed[i] === 'object' && typeof labels_processed[i][0] === 'string') ? labels_processed[i][0] : labels_processed[i],
1976
+ 'valign': 'bottom',
1977
+ 'halign':'center',
1978
+ 'bounding':true,
1979
+ 'bounding.fill': (typeof labels_processed[i] === 'object' && typeof labels_processed[i][2] === 'string') ? labels_processed[i][2] : 'white',
1980
+ 'tag':'labels ingraph'
1981
+ });
1969
1982
  co.fill();
1970
1983
  }
1971
1984
  }
@@ -2078,26 +2091,31 @@
2078
2091
  // X axis
2079
2092
  if (xaxis) {
2080
2093
  if (xaxispos === 'center') {
2081
- RG.path(co, [
2082
- 'b',
2083
- 'm',gutterLeft,gutterTop + halfGraphArea,
2084
- 'l',gutterLeft + offsetx,gutterTop + halfGraphArea - offsety,
2085
-
2086
- 'l',ca.width - gutterRight + offsetx,gutterTop + halfGraphArea - offsety,
2087
- 'l',ca.width - gutterRight,gutterTop + halfGraphArea,
2088
- 'c',
2089
- 's','#aaa',
2090
- 'f','#ddd'
2091
- ]);
2094
+ RG.path2(
2095
+ co,
2096
+ 'b m % % l % % l % % l % % c s #aaa f #ddd',
2097
+ gutterLeft,gutterTop + halfGraphArea,
2098
+ gutterLeft + offsetx,gutterTop + halfGraphArea - offsety,
2099
+ ca.width - gutterRight + offsetx,gutterTop + halfGraphArea - offsety,
2100
+ ca.width - gutterRight,gutterTop + halfGraphArea
2101
+ );
2102
+
2092
2103
  } else {
2093
- RG.path(co, [
2094
- 'b',
2095
- 'm',gutterLeft,ca.height - gutterBottom,
2096
- 'l',gutterLeft + offsetx,ca.height - gutterBottom - offsety,
2097
- 'l',ca.width - gutterRight + offsetx,ca.height - gutterBottom - offsety,
2098
- 'l',ca.width - gutterRight,ca.height - gutterBottom,
2099
- 'c','s','#aaa','f','#ddd'
2100
- ]);
2104
+
2105
+ if (obj.type === 'hbar') {
2106
+ var xaxisYCoord = obj.canvas.height - obj.properties['chart.gutter.bottom'];
2107
+ } else {
2108
+ var xaxisYCoord = obj.getYCoord(0);
2109
+ }
2110
+
2111
+ RG.path2(
2112
+ co,
2113
+ 'm % % l % % l % % l % % c s #aaa f #ddd',
2114
+ gutterLeft,xaxisYCoord,
2115
+ gutterLeft + offsetx,xaxisYCoord - offsety,
2116
+ ca.width - gutterRight + offsetx,xaxisYCoord - offsety,
2117
+ ca.width - gutterRight,xaxisYCoord
2118
+ );
2101
2119
  }
2102
2120
  }
2103
2121
  };
@@ -2131,23 +2149,23 @@
2131
2149
  // Y axis
2132
2150
  // Commented out the if condition because of drawing oddities
2133
2151
  //if (!prop['chart.noaxes'] && !prop['chart.noyaxis']) {
2134
-
2135
- if (obj.type === 'hbar' && prop['chart.yaxispos'] === 'center') {
2152
+
2153
+ if ( (obj.type === 'hbar' || obj.type === 'bar') && prop['chart.yaxispos'] === 'center') {
2136
2154
  var x = ((ca.width - gutterLeft - gutterRight) / 2) + gutterLeft;
2137
- } else if (obj.type === 'hbar' && prop['chart.yaxispos'] === 'right') {
2155
+ } else if ((obj.type === 'hbar' || obj.type === 'bar') && prop['chart.yaxispos'] === 'right') {
2138
2156
  var x = ca.width - gutterRight;
2139
2157
  } else {
2140
2158
  var x = gutterLeft;
2141
2159
  }
2142
2160
 
2143
- RG.path(co, [
2144
- 'b',
2145
- 'm', x,gutterTop,
2146
- 'l',x + offsetx,gutterTop - offsety,
2147
- 'l',x + offsetx,ca.height - gutterBottom - offsety,
2148
- 'l',x,ca.height - gutterBottom,
2149
- 's','#aaa','f','#ddd'
2150
- ]);
2161
+ RG.path2(
2162
+ co,
2163
+ 'b m % % l % % l % % l % % s #aaa f #ddd',
2164
+ x,gutterTop,
2165
+ x + offsetx,gutterTop - offsety,
2166
+ x + offsetx,ca.height - gutterBottom - offsety,
2167
+ x,ca.height - gutterBottom
2168
+ );
2151
2169
  //}
2152
2170
  };
2153
2171
 
@@ -3388,10 +3406,335 @@
3388
3406
  * bounding Whether to draw a bounding box for the text
3389
3407
  * boundingStroke The strokeStyle of the bounding box
3390
3408
  * boundingFill The fillStyle of the bounding box
3409
+ * accessible If false this will cause the text to be
3410
+ * rendered as native canvas text. DOM text otherwise
3391
3411
  */
3392
3412
  RG.text2 =
3393
3413
  RG.Text2 = function (obj, opt)
3394
3414
  {
3415
+ /**
3416
+ * Use DOM nodes to get better quality text. This option is BETA quality
3417
+ * code and most likely and will not work if you use 3D or if you use
3418
+ * your own transformations.
3419
+ */
3420
+ function domtext ()
3421
+ {
3422
+ /**
3423
+ * Check the font property to see if it contains the italic keyword,
3424
+ * and if it does then take it out and set the italic property
3425
+ */
3426
+ if (String(opt.size).toLowerCase().indexOf('italic') !== -1) {
3427
+ opt.size = opt.size.replace(/ *italic +/, '');
3428
+ opt.italic = true;
3429
+ }
3430
+
3431
+
3432
+
3433
+ // Used for caching the DOM node
3434
+ var cacheKey = ma.abs(parseInt(opt.x)) + '_' + ma.abs(parseInt(opt.y)) + '_' + String(opt.text).replace(/[^a-zA-Z0-9]+/g, '_') + '_' + obj.canvas.id;
3435
+
3436
+
3437
+
3438
+ // Wrap the canvas in a DIV
3439
+ if (!ca.rgraph_domtext_wrapper) {
3440
+
3441
+ var wrapper = document.createElement('div');
3442
+ wrapper.id = ca.id + '_rgraph_domtext_wrapper';
3443
+ wrapper.className = 'rgraph_domtext_wrapper';
3444
+
3445
+ // The wrapper can be configured to hide or show the
3446
+ // overflow with the textAccessibleOverflow option
3447
+ wrapper.style.overflow = obj.properties['chart.text.accessible.overflow'] != false && obj.properties['chart.text.accessible.overflow'] != 'hidden' ? 'visible' : 'hidden';
3448
+
3449
+ wrapper.style.width = ca.offsetWidth + 'px';
3450
+ wrapper.style.height = ca.offsetHeight + 'px';
3451
+
3452
+ wrapper.style.cssFloat = ca.style.cssFloat;
3453
+ wrapper.style.display = ca.style.display || 'inline-block';
3454
+ wrapper.style.position = ca.style.position || 'relative';
3455
+ wrapper.style.left = ca.style.left;
3456
+ wrapper.style.top = ca.style.top;
3457
+ wrapper.style.width = ca.width + 'px';
3458
+ wrapper.style.height = ca.height + 'px';
3459
+
3460
+ ca.style.position = 'absolute';
3461
+ ca.style.left = 0;
3462
+ ca.style.top = 0;
3463
+ ca.style.display = 'inline';
3464
+ ca.style.cssFloat = 'none';
3465
+
3466
+
3467
+ if ((obj.type === 'bar' || obj.type === 'bipolar' || obj.type === 'hbar') && obj.properties['chart.variant'] === '3d') {
3468
+ wrapper.style.transform = 'skewY(5.7deg)';
3469
+ }
3470
+
3471
+ ca.parentNode.insertBefore(wrapper, ca);
3472
+
3473
+ // Remove the canvas from the DOM and put it in the wrapper
3474
+ ca.parentNode.removeChild(ca);
3475
+ wrapper.appendChild(ca);
3476
+
3477
+ ca.rgraph_domtext_wrapper = wrapper;
3478
+
3479
+ // TODO Add a subwrapper here
3480
+
3481
+ } else {
3482
+ wrapper = ca.rgraph_domtext_wrapper;
3483
+ }
3484
+
3485
+
3486
+
3487
+ var defaults = {
3488
+ size: 12,
3489
+ font: 'Arial',
3490
+ italic: 'normal',
3491
+ bold: 'normal',
3492
+ valign: 'bottom',
3493
+ halign: 'left',
3494
+ marker: true,
3495
+ color: co.fillStyle,
3496
+ bounding: {
3497
+ enabled: false,
3498
+ fill: 'rgba(255,255,255,0.7)',
3499
+ stroke: '#666'
3500
+ }
3501
+ }
3502
+
3503
+
3504
+ // Transform \n to the string [[RETURN]] which is then replaced
3505
+ // further down
3506
+ opt.text = String(opt.text).replace(/\r?\n/g, '[[RETURN]]');
3507
+
3508
+
3509
+ // Create the node cache array that nodes
3510
+ // already created are stored in
3511
+ if (typeof RG.text2.domNodeCache === 'undefined') {
3512
+ RG.text2.domNodeCache = new Array();
3513
+ }
3514
+
3515
+ if (typeof RG.text2.domNodeCache[obj.id] === 'undefined') {
3516
+ RG.text2.domNodeCache[obj.id] = new Array();
3517
+ }
3518
+
3519
+ // Create the dimension cache array that node
3520
+ // dimensions are stored in
3521
+ if (typeof RG.text2.domNodeDimensionCache === 'undefined') {
3522
+ RG.text2.domNodeDimensionCache = new Array();
3523
+ }
3524
+
3525
+ if (typeof RG.text2.domNodeDimensionCache[obj.id] === 'undefined') {
3526
+ RG.text2.domNodeDimensionCache[obj.id] = new Array();
3527
+ }
3528
+
3529
+
3530
+
3531
+ // Create the DOM node
3532
+ if (!RG.text2.domNodeCache[obj.id] || !RG.text2.domNodeCache[obj.id][cacheKey]) {
3533
+
3534
+ var span = document.createElement('span');
3535
+ span.style.position = 'absolute';
3536
+ span.style.display = 'inline';
3537
+
3538
+ span.style.left = (opt.x * (parseInt(ca.offsetWidth) / parseInt(ca.width))) + 'px';
3539
+ span.style.top = (opt.y * (parseInt(ca.offsetHeight) / parseInt(ca.height))) + 'px';
3540
+ span.style.color = opt.color || defaults.color;
3541
+ span.style.fontFamily = opt.font || defaults.font;
3542
+ span.style.fontWeight = opt.bold ? 'bold' : defaults.bold;
3543
+ span.style.fontStyle = opt.italic ? 'italic' : defaults.italic;
3544
+ span.style.fontSize = (opt.size || defaults.size) + 'pt';
3545
+ span.style.whiteSpace = 'nowrap';
3546
+ span.tag = opt.tag;
3547
+
3548
+ if (opt.bounding) {
3549
+ span.style.border = '1px solid ' + (opt['bounding.stroke'] || defaults.bounding.stroke);
3550
+ span.style.backgroundColor = opt['bounding.fill'] || defaults.bounding.fill;
3551
+ }
3552
+ // Pointer events
3553
+ if ((typeof obj.properties['chart.text.accessible.pointerevents'] === 'undefined' ||
3554
+ obj.properties['chart.text.accessible.pointerevents']) &&
3555
+ obj.properties['chart.text.accessible.pointerevents'] !== 'none') {
3556
+
3557
+ span.style.pointerEvents = 'auto';
3558
+ } else {
3559
+ span.style.pointerEvents = 'none';
3560
+ }
3561
+
3562
+ span.style.padding = opt.bounding ? '2px' : null;
3563
+ span.innerHTML = opt.text.replace('&', '&amp;')
3564
+ .replace('<', '&lt;')
3565
+ .replace('>', '&gt;');
3566
+
3567
+ // Now replace the string [[RETURN]] with a <br />
3568
+ span.innerHTML = span.innerHTML.replace(/\[\[RETURN\]\]/g, '<br />');
3569
+
3570
+ wrapper.appendChild(span);
3571
+
3572
+ // Alignment defaults
3573
+ opt.halign = opt.halign || 'left';
3574
+ opt.valign = opt.valign || 'bottom';
3575
+
3576
+ // Horizontal alignment
3577
+ if (opt.halign === 'right') {
3578
+ span.style.left = parseFloat(span.style.left) - span.offsetWidth + 'px';
3579
+ span.style.textAlign = 'right';
3580
+ } else if (opt.halign === 'center') {
3581
+ span.style.left = parseFloat(span.style.left) - (span.offsetWidth / 2) + 'px';
3582
+ span.style.textAlign = 'center';
3583
+ }
3584
+
3585
+ // Vertical alignment
3586
+ if (opt.valign === 'top') {
3587
+ // Nothing to do here
3588
+ } else if (opt.valign === 'center') {
3589
+ span.style.top = parseFloat(span.style.top) - (span.offsetHeight / 2) + 'px';
3590
+ } else {
3591
+ span.style.top = parseFloat(span.style.top) - span.offsetHeight + 'px';
3592
+ }
3593
+
3594
+
3595
+ var offsetWidth = parseFloat(span.offsetWidth),
3596
+ offsetHeight = parseFloat(span.offsetHeight),
3597
+ top = parseFloat(span.style.top),
3598
+ left = parseFloat(span.style.left);
3599
+
3600
+ RG.text2.domNodeCache[obj.id][cacheKey] = span;
3601
+ RG.text2.domNodeDimensionCache[obj.id][cacheKey] = {
3602
+ left: left,
3603
+ top: top,
3604
+ width: offsetWidth,
3605
+ height: offsetHeight
3606
+ };
3607
+ span.id = cacheKey;
3608
+
3609
+
3610
+
3611
+ } else {
3612
+ span = RG.text2.domNodeCache[obj.id][cacheKey];
3613
+ span.style.display = 'inline';
3614
+
3615
+ var offsetWidth = RG.text2.domNodeDimensionCache[obj.id][cacheKey].width,
3616
+ offsetHeight = RG.text2.domNodeDimensionCache[obj.id][cacheKey].height,
3617
+ top = RG.text2.domNodeDimensionCache[obj.id][cacheKey].top,
3618
+ left = RG.text2.domNodeDimensionCache[obj.id][cacheKey].left;
3619
+ }
3620
+
3621
+
3622
+
3623
+
3624
+
3625
+
3626
+ // If requested, draw a marker to indicate the coords
3627
+ if (opt.marker) {
3628
+ RG.path2(context, 'b m % % l % % m % % l % % s',
3629
+ opt.x - 5, opt.y,
3630
+ opt.x + 5, opt.y,
3631
+ opt.x, opt.y - 5,
3632
+ opt.x, opt.y + 5
3633
+ );
3634
+ }
3635
+
3636
+ /**
3637
+ * If its a drawing API text object then allow
3638
+ * for events and tooltips
3639
+ */
3640
+ if (obj.type === 'drawing.text') {
3641
+
3642
+ // Mousemove
3643
+ if (obj.properties['chart.events.mousemove']) {
3644
+ span.addEventListener('mousemove', function (e) {(obj.properties['chart.events.mousemove'])(e, obj);}, false);
3645
+ }
3646
+
3647
+ // Click
3648
+ if (obj.properties['chart.events.click']) {
3649
+ span.addEventListener('click', function (e) {(obj.properties['chart.events.click'])(e, obj);}, false);
3650
+ }
3651
+
3652
+ // Tooltips
3653
+ if (obj.properties['chart.tooltips']) {
3654
+ span.addEventListener(
3655
+ obj.properties['chart.tooltips.event'].indexOf('mousemove') !== -1 ? 'mousemove' : 'click',
3656
+ function (e)
3657
+ {
3658
+ if ( !RG.Registry.get('chart.tooltip')
3659
+ || RG.Registry.get('chart.tooltip').__index__ !== 0
3660
+ || RG.Registry.get('chart.tooltip').__object__.uid != obj.uid
3661
+ ) {
3662
+
3663
+ RG.hideTooltip();
3664
+ RG.redraw();
3665
+ RG.tooltip(obj, obj.properties['chart.tooltips'][0], opt.x, opt.y, 0, e);
3666
+ }
3667
+ },
3668
+ false
3669
+ );
3670
+ }
3671
+ }
3672
+
3673
+ // Build the return value
3674
+ var ret = {};
3675
+ ret.x = left;
3676
+ ret.y = top;
3677
+ ret.width = offsetWidth;
3678
+ ret.height = offsetHeight;
3679
+ ret.object = obj;
3680
+ ret.text = opt.text;
3681
+ ret.tag = opt.tag;
3682
+
3683
+
3684
+ // The reset() function clears the domNodeCache
3685
+ ////
3686
+ // @param object OPTIONAL You can pass in the canvas to limit the
3687
+ // clearing to that canvas.
3688
+ RG.text2.domNodeCache.reset = function ()
3689
+ {
3690
+ // Limit the clearing to a single canvas tag
3691
+ if (arguments[0]) {
3692
+
3693
+ var nodes = RG.text2.domNodeCache[arguments[0].id];
3694
+
3695
+ for (j in nodes) {
3696
+
3697
+ var node = RG.text2.domNodeCache[arguments[0].id][j];
3698
+
3699
+ if (node && node.parentNode) {
3700
+ node.parentNode.removeChild(node);
3701
+ }
3702
+ }
3703
+
3704
+ // Clear all DOM text from all tags
3705
+ } else {
3706
+ for (i in RG.text2.domNodeCache) {
3707
+ for (j in RG.text2.domNodeCache[i]) {
3708
+ if (RG.text2.domNodeCache[i][j] && RG.text2.domNodeCache[i][j].parentNode) {
3709
+ RG.text2.domNodeCache[i][j].parentNode.removeChild(RG.text2.domNodeCache[i][j]);
3710
+ }
3711
+ }
3712
+ }
3713
+ }
3714
+ };
3715
+
3716
+ //
3717
+ // Add the SPAN tag to the return value
3718
+ //
3719
+ ret.node = span;
3720
+
3721
+
3722
+ /**
3723
+ * Save and then return the details of the text (but oly
3724
+ * if it's an RGraph object that was given)
3725
+ */
3726
+ if (obj && obj.isRGraph && obj.coordsText) {
3727
+ obj.coordsText.push(ret);
3728
+ }
3729
+
3730
+
3731
+ return ret;
3732
+ }
3733
+
3734
+
3735
+
3736
+
3737
+
3395
3738
  /**
3396
3739
  * An RGraph object can be given, or a string or the 2D rendering context
3397
3740
  * The coords are placed on the obj.coordsText variable ONLY if it's an RGraph object. The function
@@ -3421,23 +3764,39 @@
3421
3764
  var obj = ca.__object__;
3422
3765
  }
3423
3766
 
3424
- var x = opt.x;
3425
- var y = opt.y;
3426
- var originalX = x;
3427
- var originalY = y;
3428
- var text = opt.text;
3429
- var text_multiline = typeof text === 'string' ? text.split(/\r?\n/g) : '';
3430
- var numlines = text_multiline.length;
3431
- var font = opt.font ? opt.font : 'Arial';
3432
- var size = opt.size ? opt.size : 10;
3433
- var size_pixels = size * 1.5;
3434
- var bold = opt.bold;
3435
- var italic = opt.italic;
3436
- var halign = opt.halign ? opt.halign : 'left';
3437
- var valign = opt.valign ? opt.valign : 'bottom';
3438
- var tag = typeof opt.tag == 'string' && opt.tag.length > 0 ? opt.tag : '';
3439
- var marker = opt.marker;
3440
- var angle = opt.angle || 0;
3767
+
3768
+ /**
3769
+ * Changed the name of boundingFill/boundingStroke - this allows you to still use those names
3770
+ */
3771
+ if (typeof opt.boundingFill === 'string') opt['bounding.fill'] = opt.boundingFill;
3772
+ if (typeof opt.boundingStroke === 'string') opt['bounding.stroke'] = opt.boundingStroke;
3773
+
3774
+
3775
+
3776
+ if (obj && obj.properties['chart.text.accessible'] && opt.accessible !== false) {
3777
+ return domtext();
3778
+ }
3779
+
3780
+
3781
+
3782
+
3783
+ var x = opt.x,
3784
+ y = opt.y,
3785
+ originalX = x,
3786
+ originalY = y,
3787
+ text = opt.text,
3788
+ text_multiline = typeof text === 'string' ? text.split(/\r?\n/g) : '',
3789
+ numlines = text_multiline.length,
3790
+ font = opt.font ? opt.font : 'Arial',
3791
+ size = opt.size ? opt.size : 10,
3792
+ size_pixels = size * 1.5,
3793
+ bold = opt.bold,
3794
+ italic = opt.italic,
3795
+ halign = opt.halign ? opt.halign : 'left',
3796
+ valign = opt.valign ? opt.valign : 'bottom',
3797
+ tag = typeof opt.tag == 'string' && opt.tag.length > 0 ? opt.tag : '',
3798
+ marker = opt.marker,
3799
+ angle = opt.angle || 0
3441
3800
 
3442
3801
 
3443
3802
 
@@ -3462,21 +3821,17 @@
3462
3821
 
3463
3822
 
3464
3823
 
3465
- /**
3466
- * Changed the name of boundingFill/boundingStroke - this allows you to still use those names
3467
- */
3468
- if (typeof opt.boundingFill === 'string') opt['bounding.fill'] = opt.boundingFill;
3469
- if (typeof opt.boundingStroke === 'string') opt['bounding.stroke'] = opt.boundingStroke;
3470
3824
 
3471
- var bounding = opt.bounding;
3472
- var bounding_stroke = opt['bounding.stroke'] ? opt['bounding.stroke'] : 'black';
3473
- var bounding_fill = opt['bounding.fill'] ? opt['bounding.fill'] : 'rgba(255,255,255,0.7)';
3474
- var bounding_shadow = opt['bounding.shadow'];
3475
- var bounding_shadow_color = opt['bounding.shadow.color'] || '#ccc';
3476
- var bounding_shadow_blur = opt['bounding.shadow.blur'] || 3;
3477
- var bounding_shadow_offsetx = opt['bounding.shadow.offsetx'] || 3;
3478
- var bounding_shadow_offsety = opt['bounding.shadow.offsety'] || 3;
3479
- var bounding_linewidth = opt['bounding.linewidth'] || 1;
3825
+
3826
+ var bounding = opt.bounding,
3827
+ bounding_stroke = opt['bounding.stroke'] ? opt['bounding.stroke'] : 'black',
3828
+ bounding_fill = opt['bounding.fill'] ? opt['bounding.fill'] : 'rgba(255,255,255,0.7)',
3829
+ bounding_shadow = opt['bounding.shadow'],
3830
+ bounding_shadow_color = opt['bounding.shadow.color'] || '#ccc',
3831
+ bounding_shadow_blur = opt['bounding.shadow.blur'] || 3,
3832
+ bounding_shadow_offsetx = opt['bounding.shadow.offsetx'] || 3,
3833
+ bounding_shadow_offsety = opt['bounding.shadow.offsety'] || 3,
3834
+ bounding_linewidth = opt['bounding.linewidth'] || 1;
3480
3835
 
3481
3836
 
3482
3837
 
@@ -3899,6 +4254,7 @@
3899
4254
  */
3900
4255
  RG.parseDate = function (str)
3901
4256
  {
4257
+
3902
4258
  str = RG.trim(str);
3903
4259
 
3904
4260
  // Allow for: now (just the word "now")
@@ -3906,6 +4262,20 @@
3906
4262
  str = (new Date()).toString();
3907
4263
  }
3908
4264
 
4265
+
4266
+ // Allow for: 22-11-2013
4267
+ // Allow for: 22/11/2013
4268
+ // Allow for: 22-11-2013 12:09:09
4269
+ // Allow for: 22/11/2013 12:09:09
4270
+ if (str.match(/^(\d\d)(?:-|\/)(\d\d)(?:-|\/)(\d\d\d\d)(.*)$/)) {
4271
+ str = '{1}/{2}/{3}{4}'.format(
4272
+ RegExp.$3,
4273
+ RegExp.$2,
4274
+ RegExp.$1,
4275
+ RegExp.$4
4276
+ );
4277
+ }
4278
+
3909
4279
  // Allow for: 2013-11-22 12:12:12 or 2013/11/22 12:12:12
3910
4280
  if (str.match(/^(\d\d\d\d)(-|\/)(\d\d)(-|\/)(\d\d)( |T)(\d\d):(\d\d):(\d\d)$/)) {
3911
4281
  str = RegExp.$1 + '-' + RegExp.$3 + '-' + RegExp.$5 + 'T' + RegExp.$7 + ':' + RegExp.$8 + ':' + RegExp.$9;
@@ -3916,6 +4286,7 @@
3916
4286
  str = str.replace(/-/g, '/');
3917
4287
  }
3918
4288
 
4289
+
3919
4290
  // Allow for: 12:09:44 (time only using todays date)
3920
4291
  if (str.match(/^\d\d:\d\d:\d\d$/)) {
3921
4292
 
@@ -3971,74 +4342,6 @@
3971
4342
 
3972
4343
 
3973
4344
 
3974
- /**
3975
- * This function is a short-cut for the canvas path syntax (which can be rather verbose)
3976
- *
3977
- * @param mixed obj This can either be the 2D context or an RGraph object
3978
- * @param array path The path details
3979
- */
3980
- RG.path =
3981
- RG.Path = function (obj, path)
3982
- {
3983
- /**
3984
- * Allow either the RGraph object or the context to be used as the first argument
3985
- */
3986
- if (obj.isRGraph && typeof obj.type === 'string') {
3987
- var co = obj.context;
3988
- } else {
3989
- var co = obj,
3990
- obj = obj.canvas.__object__;
3991
- }
3992
-
3993
- /**
3994
- * If the Path information has been passed as a string - split it up
3995
- */
3996
- if (typeof path == 'string') {
3997
- path = path.split(/ +/);
3998
- }
3999
-
4000
- /**
4001
- * Go through the path information
4002
- */
4003
- for (var i=0,len=path.length; i<len; i+=1) {
4004
-
4005
- var op = path[i];
4006
-
4007
- // 100,100,50,0,Math.PI * 1.5, false
4008
- switch (op) {
4009
- case 'b':co.beginPath();break;
4010
- case 'c':co.closePath();break;
4011
- case 'm':co.moveTo(parseFloat(path[i+1]),parseFloat(path[i+2]));i+=2;break;
4012
- case 'l':co.lineTo(parseFloat(path[i+1]),parseFloat(path[i+2]));i+=2;break;
4013
- case 's':if(path[i+1])co.strokeStyle=obj.parseSingleColorForGradient(path[i+1]);co.stroke();i++;break;
4014
- case 'f':if(path[i+1]){co.fillStyle = obj.parseSingleColorForGradient(path[i+1]);}co.fill();i++;break;
4015
- case 'qc':co.quadraticCurveTo(parseFloat(path[i+1]),parseFloat(path[i+2]),parseFloat(path[i+3]),parseFloat(path[i+4]));i+=4;break;
4016
- case 'bc':co.bezierCurveTo(parseFloat(path[i+1]),parseFloat(path[i+2]),parseFloat(path[i+3]),parseFloat(path[i+4]),parseFloat(path[i+5]),parseFloat(path[i+6]));i+=6;break;
4017
- case 'r':co.rect(parseFloat(path[i+1]),parseFloat(path[i+2]),parseFloat(path[i+3]),parseFloat(path[i+4]));i+=4;break;
4018
- case 'a':co.arc(parseFloat(path[i+1]),parseFloat(path[i+2]),parseFloat(path[i+3]),parseFloat(path[i+4]),parseFloat(path[i+5]),path[i+6]==='true'||path[i+6]===true?true:false);i+=6;break;
4019
- case 'at':co.arcTo(parseFloat(path[i+1]),parseFloat(path[i+2]),parseFloat(path[i+3]),parseFloat(path[i+4]),parseFloat(path[i+5]));i+=5;break;
4020
- case 'lw':co.lineWidth=parseFloat(path[i+1]);i++;break;
4021
- case 'lj':co.lineJoin=path[i+1];i++;break;
4022
- case 'lc':co.lineCap=path[i+1];i++;break;
4023
- case 'sc':co.shadowColor=path[i+1];i++;break;
4024
- case 'sb':co.shadowBlur=parseFloat(path[i+1]);i++;break;
4025
- case 'sx':co.shadowOffsetX=parseFloat(path[i+1]);i++;break;
4026
- case 'sy':co.shadowOffsetY=parseFloat(path[i+1]);i++;break;
4027
- case 'fu':(path[i+1])(obj);i++;break;
4028
- case 'fs':co.fillStyle=obj.parseSingleColorForGradient(path[i+1]);i++;break;
4029
- case 'ss':co.strokeStyle=obj.parseSingleColorForGradient(path[i+1]);i++;break;
4030
- case 'fr':co.fillRect(parseFloat(path[i+1]),parseFloat(path[i+2]),parseFloat(path[i+3]),parseFloat(path[i+4]));i+=4;break;
4031
- case 'sr':co.strokeRect(parseFloat(path[i+1]),parseFloat(path[i+2]),parseFloat(path[i+3]),parseFloat(path[i+4]));i+=4;break;
4032
- case 'cl':co.clip();break;
4033
- case 'ct':co.save();co.beginPath();RG.path(co, path[i+1]);co.clip();i++;break;
4034
- case 'sa':co.save();break;
4035
- case 'rs':co.restore();break;
4036
- }
4037
- }
4038
- };
4039
-
4040
-
4041
-
4042
4345
  /**
4043
4346
  * Creates a Linear gradient
4044
4347
  *
@@ -4188,12 +4491,12 @@
4188
4491
  /**
4189
4492
  *
4190
4493
  */
4494
+ RG.arrayRand =
4495
+ RG.arrayRandom =
4191
4496
  RG.random.array = function (num, min, max)
4192
4497
  {
4193
- var arr = [];
4194
-
4195
- for(var i=0; i<num; i+=1) {
4196
- arr.push(RG.random(min,max));
4498
+ for(var i=0,arr=[]; i<num; i+=1) {
4499
+ arr.push(RG.random(min,max, arguments[3]));
4197
4500
  }
4198
4501
 
4199
4502
  return arr;
@@ -4435,24 +4738,17 @@
4435
4738
 
4436
4739
  ca.__rgraph_aa_translated__ = false;
4437
4740
 
4741
+ if (RG.text2.domNodeCache && RG.text2.domNodeCache.reset) {
4742
+ RG.text2.domNodeCache.reset(ca);
4743
+ }
4438
4744
 
4745
+ // Create the node and dimension caches if they don't already exist
4746
+ if (!RG.text2.domNodeCache) { RG.text2.domNodeCache = []; }
4747
+ if (!RG.text2.domNodeDimensionCache) { RG.text2.domNodeDimensionCache = []; }
4439
4748
 
4440
-
4441
-
4442
- //
4443
- // Clear any text objects that are in the cache
4444
- //
4445
- //var len = (ca.id + '-text-').length;
4446
-
4447
- //for (i in RG.cache) {
4448
- //
4449
- // var value = RG.cache[i];
4450
-
4451
- // if (i.substr(0, len) === (ca.id + '-text-') && typeof value === 'object' && value) {
4452
- // RG.cache[i].parentNode.removeChild(RG.cache[i]);
4453
- // RG.cache[i] = null;
4454
- // }
4455
- //}
4749
+ // Create/reset the specific canvas arrays in the caches
4750
+ RG.text2.domNodeCache[ca.id] = [];
4751
+ RG.text2.domNodeDimensionCache[ca.id] = [];
4456
4752
  };
4457
4753
 
4458
4754
 
@@ -4461,9 +4757,7 @@
4461
4757
  /**
4462
4758
  * NOT USED ANY MORE
4463
4759
  */
4464
- RG.att = function (ca)
4465
- {
4466
- }
4760
+ RG.att = function (ca){}
4467
4761
 
4468
4762
 
4469
4763
 
@@ -4579,30 +4873,28 @@
4579
4873
  */
4580
4874
  RG.cachedDraw = function (obj, id, func)
4581
4875
  {
4582
- //If the cache entry xists - just copy it across to the main canvas
4876
+ //If the cache entry exists - just copy it across to the main canvas
4583
4877
  if (!RG.cache[id]) {
4584
4878
 
4585
4879
  RG.cache[id] = {};
4880
+
4586
4881
  RG.cache[id].object = obj;
4587
- RG.cache[id].canvas = document.createElement('canvas');
4588
- RG.cache[id].canvas.setAttribute('width', obj.canvas.width);
4589
- RG.cache[id].canvas.setAttribute('height', obj.canvas.height);
4590
- RG.cache[id].canvas.setAttribute('id', 'background_cached_canvas' + obj.canvas.id);
4591
-
4592
- //Add MSIE support
4593
- if (typeof G_vmlCanvasManager === 'object' && G_vmlCanvasManager.initElement) {
4594
- G_vmlCanvasManager.initElement(RG.cache[id].canvas);
4595
- }
4882
+ RG.cache[id].canvas = document.createElement('canvas');
4883
+
4884
+ RG.cache[id].canvas.setAttribute('width', obj.canvas.width);
4885
+ RG.cache[id].canvas.setAttribute('height', obj.canvas.height);
4886
+ RG.cache[id].canvas.setAttribute('id', 'background_cached_canvas' + obj.canvas.id);
4596
4887
 
4888
+ RG.cache[id].canvas.__object__ = obj;
4597
4889
  RG.cache[id].context = RG.cache[id].canvas.getContext('2d');
4598
4890
 
4599
4891
  // Antialiasing on the cache canvas
4600
4892
  RG.cache[id].context.translate(0.5,0.5);
4601
-
4893
+
4602
4894
  // Call the function
4603
4895
  func(obj, RG.cache[id].canvas, RG.cache[id].context);
4604
4896
  }
4605
-
4897
+
4606
4898
  // Now copy the contents of the cached canvas over to the main one.
4607
4899
  // The coordinates are -0.5 because of the anti-aliasing effect in
4608
4900
  // use on the main canvas
@@ -4707,7 +4999,7 @@
4707
4999
  {
4708
5000
  // Save this functions arguments
4709
5001
  var args = arguments;
4710
-
5002
+
4711
5003
 
4712
5004
  // If the path was a string - split it then collapse quoted bits together
4713
5005
  if (typeof p === 'string') {
@@ -4762,6 +5054,7 @@
4762
5054
  case 'tbl':co.textBaseline=p[i+1];i++;break;
4763
5055
  case 'ga':co.globalAlpha=parseFloat(p[i+1]);i++;break;
4764
5056
  case 'gco':co.globalCompositeOperation=p[i+1];i++;break;
5057
+ case 'fu':(p[i+1])(co.canvas.__object__);i++;break;
4765
5058
 
4766
5059
  // Empty option - ignore it
4767
5060
  case '':break;
@@ -4870,4 +5163,26 @@
4870
5163
  window.$cl = function (v)
4871
5164
  {
4872
5165
  return console.log(v);
4873
- };
5166
+ };
5167
+
5168
+
5169
+
5170
+
5171
+ /**
5172
+ * A basic string formatting function. Use it like this:
5173
+ *
5174
+ * var str = '{0} {1} {2}'.format('a', 'b', 'c');
5175
+ *
5176
+ * Outputs: a b c
5177
+ */
5178
+ if (!String.prototype.format) {
5179
+ String.prototype.format = function()
5180
+ {
5181
+ var args = arguments;
5182
+
5183
+ return this.replace(/{(\d+)}/g, function(str, idx)
5184
+ {
5185
+ return typeof args[idx - 1] !== 'undefined' ? args[idx - 1] : str;
5186
+ });
5187
+ };
5188
+ }