chart-js-rails 0.0.7 → 0.0.8
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.
- data/README.md +1 -1
- data/lib/chart-js-rails/version.rb +1 -1
- data/vendor/assets/javascripts/Chart.js +350 -197
- metadata +11 -7
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
/*!
|
2
2
|
* Chart.js
|
3
3
|
* http://chartjs.org/
|
4
|
+
* Version: 1.0.1
|
4
5
|
*
|
5
|
-
* Copyright
|
6
|
+
* Copyright 2015 Nick Downie
|
6
7
|
* Released under the MIT license
|
7
8
|
* https://github.com/nnnick/Chart.js/blob/master/LICENSE.md
|
8
9
|
*/
|
@@ -91,9 +92,15 @@
|
|
91
92
|
// Boolean - whether or not the chart should be responsive and resize when the browser does.
|
92
93
|
responsive: false,
|
93
94
|
|
95
|
+
// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container
|
96
|
+
maintainAspectRatio: true,
|
97
|
+
|
94
98
|
// Boolean - Determines whether to draw tooltips on the canvas or not - attaches events to touchmove & mousemove
|
95
99
|
showTooltips: true,
|
96
100
|
|
101
|
+
// Boolean - Determines whether to draw built-in tooltip or call custom tooltip function
|
102
|
+
customTooltips: false,
|
103
|
+
|
97
104
|
// Array - Array of string names to attach tooltip events
|
98
105
|
tooltipEvents: ["mousemove", "touchstart", "touchmove", "mouseout"],
|
99
106
|
|
@@ -213,6 +220,41 @@
|
|
213
220
|
return -1;
|
214
221
|
}
|
215
222
|
},
|
223
|
+
where = helpers.where = function(collection, filterCallback){
|
224
|
+
var filtered = [];
|
225
|
+
|
226
|
+
helpers.each(collection, function(item){
|
227
|
+
if (filterCallback(item)){
|
228
|
+
filtered.push(item);
|
229
|
+
}
|
230
|
+
});
|
231
|
+
|
232
|
+
return filtered;
|
233
|
+
},
|
234
|
+
findNextWhere = helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex){
|
235
|
+
// Default to start of the array
|
236
|
+
if (!startIndex){
|
237
|
+
startIndex = -1;
|
238
|
+
}
|
239
|
+
for (var i = startIndex + 1; i < arrayToSearch.length; i++) {
|
240
|
+
var currentItem = arrayToSearch[i];
|
241
|
+
if (filterCallback(currentItem)){
|
242
|
+
return currentItem;
|
243
|
+
}
|
244
|
+
}
|
245
|
+
},
|
246
|
+
findPreviousWhere = helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex){
|
247
|
+
// Default to end of the array
|
248
|
+
if (!startIndex){
|
249
|
+
startIndex = arrayToSearch.length;
|
250
|
+
}
|
251
|
+
for (var i = startIndex - 1; i >= 0; i--) {
|
252
|
+
var currentItem = arrayToSearch[i];
|
253
|
+
if (filterCallback(currentItem)){
|
254
|
+
return currentItem;
|
255
|
+
}
|
256
|
+
}
|
257
|
+
},
|
216
258
|
inherits = helpers.inherits = function(extensions){
|
217
259
|
//Basic javascript inheritance based on the model created in Backbone.js
|
218
260
|
var parent = this;
|
@@ -241,7 +283,7 @@
|
|
241
283
|
//Method for warning of errors
|
242
284
|
if (window.console && typeof window.console.warn == "function") console.warn(str);
|
243
285
|
},
|
244
|
-
amd = helpers.amd = (typeof
|
286
|
+
amd = helpers.amd = (typeof define == 'function' && define.amd),
|
245
287
|
//-- Math methods
|
246
288
|
isNumber = helpers.isNumber = function(n){
|
247
289
|
return !isNaN(parseFloat(n)) && isFinite(n);
|
@@ -402,6 +444,13 @@
|
|
402
444
|
//Templating methods
|
403
445
|
//Javascript micro templating by John Resig - source at http://ejohn.org/blog/javascript-micro-templating/
|
404
446
|
template = helpers.template = function(templateString, valuesObject){
|
447
|
+
|
448
|
+
// If templateString is function rather than string-template - call the function for valuesObject
|
449
|
+
|
450
|
+
if(templateString instanceof Function){
|
451
|
+
return templateString(valuesObject);
|
452
|
+
}
|
453
|
+
|
405
454
|
var cache = {};
|
406
455
|
function tmpl(str, data){
|
407
456
|
// Figure out if we're getting a template, or if we need to
|
@@ -693,16 +742,22 @@
|
|
693
742
|
removeEvent(chartInstance.chart.canvas, eventName, handler);
|
694
743
|
});
|
695
744
|
},
|
696
|
-
|
745
|
+
getMaximumWidth = helpers.getMaximumWidth = function(domNode){
|
697
746
|
var container = domNode.parentNode;
|
698
747
|
// TODO = check cross browser stuff with this.
|
699
748
|
return container.clientWidth;
|
700
749
|
},
|
750
|
+
getMaximumHeight = helpers.getMaximumHeight = function(domNode){
|
751
|
+
var container = domNode.parentNode;
|
752
|
+
// TODO = check cross browser stuff with this.
|
753
|
+
return container.clientHeight;
|
754
|
+
},
|
755
|
+
getMaximumSize = helpers.getMaximumSize = helpers.getMaximumWidth, // legacy support
|
701
756
|
retinaScale = helpers.retinaScale = function(chart){
|
702
757
|
var ctx = chart.ctx,
|
703
758
|
width = chart.canvas.width,
|
704
759
|
height = chart.canvas.height;
|
705
|
-
|
760
|
+
|
706
761
|
if (window.devicePixelRatio) {
|
707
762
|
ctx.canvas.style.width = width + "px";
|
708
763
|
ctx.canvas.style.height = height + "px";
|
@@ -776,11 +831,11 @@
|
|
776
831
|
resize : function(callback){
|
777
832
|
this.stop();
|
778
833
|
var canvas = this.chart.canvas,
|
779
|
-
newWidth =
|
780
|
-
newHeight = newWidth / this.chart.aspectRatio;
|
834
|
+
newWidth = getMaximumWidth(this.chart.canvas),
|
835
|
+
newHeight = this.options.maintainAspectRatio ? newWidth / this.chart.aspectRatio : getMaximumHeight(this.chart.canvas);
|
781
836
|
|
782
837
|
canvas.width = this.chart.width = newWidth;
|
783
|
-
canvas.height =
|
838
|
+
canvas.height = this.chart.height = newHeight;
|
784
839
|
|
785
840
|
retinaScale(this.chart);
|
786
841
|
|
@@ -816,6 +871,21 @@
|
|
816
871
|
destroy : function(){
|
817
872
|
this.clear();
|
818
873
|
unbindEvents(this, this.events);
|
874
|
+
var canvas = this.chart.canvas;
|
875
|
+
|
876
|
+
// Reset canvas height/width attributes starts a fresh with the canvas context
|
877
|
+
canvas.width = this.chart.width;
|
878
|
+
canvas.height = this.chart.height;
|
879
|
+
|
880
|
+
// < IE9 doesn't support removeProperty
|
881
|
+
if (canvas.style.removeProperty) {
|
882
|
+
canvas.style.removeProperty('width');
|
883
|
+
canvas.style.removeProperty('height');
|
884
|
+
} else {
|
885
|
+
canvas.style.removeAttribute('width');
|
886
|
+
canvas.style.removeAttribute('height');
|
887
|
+
}
|
888
|
+
|
819
889
|
delete Chart.instances[this.id];
|
820
890
|
},
|
821
891
|
showTooltip : function(ChartElements, forceRedraw){
|
@@ -845,6 +915,9 @@
|
|
845
915
|
this.activeElements = ChartElements;
|
846
916
|
}
|
847
917
|
this.draw();
|
918
|
+
if(this.options.customTooltips){
|
919
|
+
this.options.customTooltips(false);
|
920
|
+
}
|
848
921
|
if (ChartElements.length > 0){
|
849
922
|
// If we have multiple datasets, show a MultiTooltip for all of the data points at that index
|
850
923
|
if (this.datasets && this.datasets.length > 1) {
|
@@ -873,7 +946,7 @@
|
|
873
946
|
yMin;
|
874
947
|
helpers.each(this.datasets, function(dataset){
|
875
948
|
dataCollection = dataset.points || dataset.bars || dataset.segments;
|
876
|
-
if (dataCollection[dataIndex]){
|
949
|
+
if (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue()){
|
877
950
|
Elements.push(dataCollection[dataIndex]);
|
878
951
|
}
|
879
952
|
});
|
@@ -925,7 +998,8 @@
|
|
925
998
|
legendColorBackground : this.options.multiTooltipKeyBackground,
|
926
999
|
title: ChartElements[0].label,
|
927
1000
|
chart: this.chart,
|
928
|
-
ctx: this.chart.ctx
|
1001
|
+
ctx: this.chart.ctx,
|
1002
|
+
custom: this.options.customTooltips
|
929
1003
|
}).draw();
|
930
1004
|
|
931
1005
|
} else {
|
@@ -944,7 +1018,8 @@
|
|
944
1018
|
caretHeight: this.options.tooltipCaretSize,
|
945
1019
|
cornerRadius: this.options.tooltipCornerRadius,
|
946
1020
|
text: template(this.options.tooltipTemplate, Element),
|
947
|
-
chart: this.chart
|
1021
|
+
chart: this.chart,
|
1022
|
+
custom: this.options.customTooltips
|
948
1023
|
}).draw();
|
949
1024
|
}, this);
|
950
1025
|
}
|
@@ -1037,6 +1112,9 @@
|
|
1037
1112
|
x : this.x,
|
1038
1113
|
y : this.y
|
1039
1114
|
};
|
1115
|
+
},
|
1116
|
+
hasValue: function(){
|
1117
|
+
return isNumber(this.value);
|
1040
1118
|
}
|
1041
1119
|
});
|
1042
1120
|
|
@@ -1083,6 +1161,7 @@
|
|
1083
1161
|
// ctx.fill();
|
1084
1162
|
|
1085
1163
|
// ctx.moveTo(this.controlPoints.inner.x,this.controlPoints.inner.y);
|
1164
|
+
// ctx.lineTo(this.x, this.y);
|
1086
1165
|
// ctx.lineTo(this.controlPoints.outer.x,this.controlPoints.outer.y);
|
1087
1166
|
// ctx.stroke();
|
1088
1167
|
|
@@ -1196,7 +1275,7 @@
|
|
1196
1275
|
this.yAlign = "above";
|
1197
1276
|
|
1198
1277
|
//Distance between the actual element.y position and the start of the tooltip caret
|
1199
|
-
var caretPadding = 2;
|
1278
|
+
var caretPadding = this.caretPadding = 2;
|
1200
1279
|
|
1201
1280
|
var tooltipWidth = ctx.measureText(this.text).width + 2*this.xPadding,
|
1202
1281
|
tooltipRectHeight = this.fontSize + 2*this.yPadding,
|
@@ -1218,47 +1297,53 @@
|
|
1218
1297
|
|
1219
1298
|
ctx.fillStyle = this.fillColor;
|
1220
1299
|
|
1221
|
-
|
1222
|
-
{
|
1223
|
-
|
1224
|
-
//Draw a caret above the x/y
|
1225
|
-
ctx.beginPath();
|
1226
|
-
ctx.moveTo(this.x,this.y - caretPadding);
|
1227
|
-
ctx.lineTo(this.x + this.caretHeight, this.y - (caretPadding + this.caretHeight));
|
1228
|
-
ctx.lineTo(this.x - this.caretHeight, this.y - (caretPadding + this.caretHeight));
|
1229
|
-
ctx.closePath();
|
1230
|
-
ctx.fill();
|
1231
|
-
break;
|
1232
|
-
case "below":
|
1233
|
-
tooltipY = this.y + caretPadding + this.caretHeight;
|
1234
|
-
//Draw a caret below the x/y
|
1235
|
-
ctx.beginPath();
|
1236
|
-
ctx.moveTo(this.x, this.y + caretPadding);
|
1237
|
-
ctx.lineTo(this.x + this.caretHeight, this.y + caretPadding + this.caretHeight);
|
1238
|
-
ctx.lineTo(this.x - this.caretHeight, this.y + caretPadding + this.caretHeight);
|
1239
|
-
ctx.closePath();
|
1240
|
-
ctx.fill();
|
1241
|
-
break;
|
1300
|
+
// Custom Tooltips
|
1301
|
+
if(this.custom){
|
1302
|
+
this.custom(this);
|
1242
1303
|
}
|
1304
|
+
else{
|
1305
|
+
switch(this.yAlign)
|
1306
|
+
{
|
1307
|
+
case "above":
|
1308
|
+
//Draw a caret above the x/y
|
1309
|
+
ctx.beginPath();
|
1310
|
+
ctx.moveTo(this.x,this.y - caretPadding);
|
1311
|
+
ctx.lineTo(this.x + this.caretHeight, this.y - (caretPadding + this.caretHeight));
|
1312
|
+
ctx.lineTo(this.x - this.caretHeight, this.y - (caretPadding + this.caretHeight));
|
1313
|
+
ctx.closePath();
|
1314
|
+
ctx.fill();
|
1315
|
+
break;
|
1316
|
+
case "below":
|
1317
|
+
tooltipY = this.y + caretPadding + this.caretHeight;
|
1318
|
+
//Draw a caret below the x/y
|
1319
|
+
ctx.beginPath();
|
1320
|
+
ctx.moveTo(this.x, this.y + caretPadding);
|
1321
|
+
ctx.lineTo(this.x + this.caretHeight, this.y + caretPadding + this.caretHeight);
|
1322
|
+
ctx.lineTo(this.x - this.caretHeight, this.y + caretPadding + this.caretHeight);
|
1323
|
+
ctx.closePath();
|
1324
|
+
ctx.fill();
|
1325
|
+
break;
|
1326
|
+
}
|
1243
1327
|
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1328
|
+
switch(this.xAlign)
|
1329
|
+
{
|
1330
|
+
case "left":
|
1331
|
+
tooltipX = this.x - tooltipWidth + (this.cornerRadius + this.caretHeight);
|
1332
|
+
break;
|
1333
|
+
case "right":
|
1334
|
+
tooltipX = this.x - (this.cornerRadius + this.caretHeight);
|
1335
|
+
break;
|
1336
|
+
}
|
1253
1337
|
|
1254
|
-
|
1338
|
+
drawRoundedRectangle(ctx,tooltipX,tooltipY,tooltipWidth,tooltipRectHeight,this.cornerRadius);
|
1255
1339
|
|
1256
|
-
|
1340
|
+
ctx.fill();
|
1257
1341
|
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1342
|
+
ctx.fillStyle = this.textColor;
|
1343
|
+
ctx.textAlign = "center";
|
1344
|
+
ctx.textBaseline = "middle";
|
1345
|
+
ctx.fillText(this.text, tooltipX + tooltipWidth/2, tooltipY + tooltipRectHeight/2);
|
1346
|
+
}
|
1262
1347
|
}
|
1263
1348
|
});
|
1264
1349
|
|
@@ -1312,36 +1397,42 @@
|
|
1312
1397
|
|
1313
1398
|
},
|
1314
1399
|
draw : function(){
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1400
|
+
// Custom Tooltips
|
1401
|
+
if(this.custom){
|
1402
|
+
this.custom(this);
|
1403
|
+
}
|
1404
|
+
else{
|
1405
|
+
drawRoundedRectangle(this.ctx,this.x,this.y - this.height/2,this.width,this.height,this.cornerRadius);
|
1406
|
+
var ctx = this.ctx;
|
1407
|
+
ctx.fillStyle = this.fillColor;
|
1408
|
+
ctx.fill();
|
1409
|
+
ctx.closePath();
|
1320
1410
|
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1411
|
+
ctx.textAlign = "left";
|
1412
|
+
ctx.textBaseline = "middle";
|
1413
|
+
ctx.fillStyle = this.titleTextColor;
|
1414
|
+
ctx.font = this.titleFont;
|
1325
1415
|
|
1326
|
-
|
1416
|
+
ctx.fillText(this.title,this.x + this.xPadding, this.getLineHeight(0));
|
1327
1417
|
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1418
|
+
ctx.font = this.font;
|
1419
|
+
helpers.each(this.labels,function(label,index){
|
1420
|
+
ctx.fillStyle = this.textColor;
|
1421
|
+
ctx.fillText(label,this.x + this.xPadding + this.fontSize + 3, this.getLineHeight(index + 1));
|
1332
1422
|
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1423
|
+
//A bit gnarly, but clearing this rectangle breaks when using explorercanvas (clears whole canvas)
|
1424
|
+
//ctx.clearRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
|
1425
|
+
//Instead we'll make a white filled block to put the legendColour palette over.
|
1336
1426
|
|
1337
|
-
|
1338
|
-
|
1427
|
+
ctx.fillStyle = this.legendColorBackground;
|
1428
|
+
ctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
|
1339
1429
|
|
1340
|
-
|
1341
|
-
|
1430
|
+
ctx.fillStyle = this.legendColors[index].fill;
|
1431
|
+
ctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
|
1342
1432
|
|
1343
1433
|
|
1344
|
-
|
1434
|
+
},this);
|
1435
|
+
}
|
1345
1436
|
}
|
1346
1437
|
});
|
1347
1438
|
|
@@ -1506,14 +1597,24 @@
|
|
1506
1597
|
ctx.font = this.font;
|
1507
1598
|
each(this.yLabels,function(labelString,index){
|
1508
1599
|
var yLabelCenter = this.endPoint - (yLabelGap * index),
|
1509
|
-
linePositionY = Math.round(yLabelCenter)
|
1600
|
+
linePositionY = Math.round(yLabelCenter),
|
1601
|
+
drawHorizontalLine = this.showHorizontalLines;
|
1510
1602
|
|
1511
1603
|
ctx.textAlign = "right";
|
1512
1604
|
ctx.textBaseline = "middle";
|
1513
1605
|
if (this.showLabels){
|
1514
1606
|
ctx.fillText(labelString,xStart - 10,yLabelCenter);
|
1515
1607
|
}
|
1516
|
-
|
1608
|
+
|
1609
|
+
// This is X axis, so draw it
|
1610
|
+
if (index === 0 && !drawHorizontalLine){
|
1611
|
+
drawHorizontalLine = true;
|
1612
|
+
}
|
1613
|
+
|
1614
|
+
if (drawHorizontalLine){
|
1615
|
+
ctx.beginPath();
|
1616
|
+
}
|
1617
|
+
|
1517
1618
|
if (index > 0){
|
1518
1619
|
// This is a grid line in the centre, so drop that
|
1519
1620
|
ctx.lineWidth = this.gridLineWidth;
|
@@ -1526,10 +1627,12 @@
|
|
1526
1627
|
|
1527
1628
|
linePositionY += helpers.aliasPixel(ctx.lineWidth);
|
1528
1629
|
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1630
|
+
if(drawHorizontalLine){
|
1631
|
+
ctx.moveTo(xStart, linePositionY);
|
1632
|
+
ctx.lineTo(this.width, linePositionY);
|
1633
|
+
ctx.stroke();
|
1634
|
+
ctx.closePath();
|
1635
|
+
}
|
1533
1636
|
|
1534
1637
|
ctx.lineWidth = this.lineWidth;
|
1535
1638
|
ctx.strokeStyle = this.lineColor;
|
@@ -1545,9 +1648,17 @@
|
|
1545
1648
|
var xPos = this.calculateX(index) + aliasPixel(this.lineWidth),
|
1546
1649
|
// Check to see if line/bar here and decide where to place the line
|
1547
1650
|
linePos = this.calculateX(index - (this.offsetGridLines ? 0.5 : 0)) + aliasPixel(this.lineWidth),
|
1548
|
-
isRotated = (this.xLabelRotation > 0)
|
1651
|
+
isRotated = (this.xLabelRotation > 0),
|
1652
|
+
drawVerticalLine = this.showVerticalLines;
|
1549
1653
|
|
1550
|
-
|
1654
|
+
// This is Y axis, so draw it
|
1655
|
+
if (index === 0 && !drawVerticalLine){
|
1656
|
+
drawVerticalLine = true;
|
1657
|
+
}
|
1658
|
+
|
1659
|
+
if (drawVerticalLine){
|
1660
|
+
ctx.beginPath();
|
1661
|
+
}
|
1551
1662
|
|
1552
1663
|
if (index > 0){
|
1553
1664
|
// This is a grid line in the centre, so drop that
|
@@ -1558,10 +1669,13 @@
|
|
1558
1669
|
ctx.lineWidth = this.lineWidth;
|
1559
1670
|
ctx.strokeStyle = this.lineColor;
|
1560
1671
|
}
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1672
|
+
|
1673
|
+
if (drawVerticalLine){
|
1674
|
+
ctx.moveTo(linePos,this.endPoint);
|
1675
|
+
ctx.lineTo(linePos,this.startPoint - 3);
|
1676
|
+
ctx.stroke();
|
1677
|
+
ctx.closePath();
|
1678
|
+
}
|
1565
1679
|
|
1566
1680
|
|
1567
1681
|
ctx.lineWidth = this.lineWidth;
|
@@ -1887,6 +2001,7 @@
|
|
1887
2001
|
};
|
1888
2002
|
|
1889
2003
|
}).call(this);
|
2004
|
+
|
1890
2005
|
(function(){
|
1891
2006
|
"use strict";
|
1892
2007
|
|
@@ -1908,6 +2023,12 @@
|
|
1908
2023
|
//Number - Width of the grid lines
|
1909
2024
|
scaleGridLineWidth : 1,
|
1910
2025
|
|
2026
|
+
//Boolean - Whether to show horizontal lines (except X axis)
|
2027
|
+
scaleShowHorizontalLines: true,
|
2028
|
+
|
2029
|
+
//Boolean - Whether to show vertical lines (except Y axis)
|
2030
|
+
scaleShowVerticalLines: true,
|
2031
|
+
|
1911
2032
|
//Boolean - If there is a stroke on each bar
|
1912
2033
|
barShowStroke : true,
|
1913
2034
|
|
@@ -1993,18 +2114,16 @@
|
|
1993
2114
|
this.datasets.push(datasetObject);
|
1994
2115
|
|
1995
2116
|
helpers.each(dataset.data,function(dataPoint,index){
|
1996
|
-
|
1997
|
-
|
1998
|
-
|
1999
|
-
|
2000
|
-
|
2001
|
-
|
2002
|
-
|
2003
|
-
|
2004
|
-
|
2005
|
-
|
2006
|
-
}));
|
2007
|
-
}
|
2117
|
+
//Add a new point for each piece of data, passing any required data to draw.
|
2118
|
+
datasetObject.bars.push(new this.BarClass({
|
2119
|
+
value : dataPoint,
|
2120
|
+
label : data.labels[index],
|
2121
|
+
datasetLabel: dataset.label,
|
2122
|
+
strokeColor : dataset.strokeColor,
|
2123
|
+
fillColor : dataset.fillColor,
|
2124
|
+
highlightFill : dataset.highlightFill || dataset.fillColor,
|
2125
|
+
highlightStroke : dataset.highlightStroke || dataset.strokeColor
|
2126
|
+
}));
|
2008
2127
|
},this);
|
2009
2128
|
|
2010
2129
|
},this);
|
@@ -2097,6 +2216,8 @@
|
|
2097
2216
|
font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
|
2098
2217
|
lineWidth : this.options.scaleLineWidth,
|
2099
2218
|
lineColor : this.options.scaleLineColor,
|
2219
|
+
showHorizontalLines : this.options.scaleShowHorizontalLines,
|
2220
|
+
showVerticalLines : this.options.scaleShowVerticalLines,
|
2100
2221
|
gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
|
2101
2222
|
gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
|
2102
2223
|
padding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0,
|
@@ -2119,19 +2240,17 @@
|
|
2119
2240
|
addData : function(valuesArray,label){
|
2120
2241
|
//Map the values array for each of the datasets
|
2121
2242
|
helpers.each(valuesArray,function(value,datasetIndex){
|
2122
|
-
|
2123
|
-
|
2124
|
-
|
2125
|
-
|
2126
|
-
|
2127
|
-
|
2128
|
-
|
2129
|
-
|
2130
|
-
|
2131
|
-
|
2132
|
-
|
2133
|
-
}));
|
2134
|
-
}
|
2243
|
+
//Add a new point for each piece of data, passing any required data to draw.
|
2244
|
+
this.datasets[datasetIndex].bars.push(new this.BarClass({
|
2245
|
+
value : value,
|
2246
|
+
label : label,
|
2247
|
+
x: this.scale.calculateBarX(this.datasets.length, datasetIndex, this.scale.valuesCount+1),
|
2248
|
+
y: this.scale.endPoint,
|
2249
|
+
width : this.scale.calculateBarWidth(this.datasets.length),
|
2250
|
+
base : this.scale.endPoint,
|
2251
|
+
strokeColor : this.datasets[datasetIndex].strokeColor,
|
2252
|
+
fillColor : this.datasets[datasetIndex].fillColor
|
2253
|
+
}));
|
2135
2254
|
},this);
|
2136
2255
|
|
2137
2256
|
this.scale.addXLabel(label);
|
@@ -2168,13 +2287,15 @@
|
|
2168
2287
|
//Draw all the bars for each dataset
|
2169
2288
|
helpers.each(this.datasets,function(dataset,datasetIndex){
|
2170
2289
|
helpers.each(dataset.bars,function(bar,index){
|
2171
|
-
bar.
|
2172
|
-
|
2173
|
-
|
2174
|
-
|
2175
|
-
|
2176
|
-
|
2177
|
-
|
2290
|
+
if (bar.hasValue()){
|
2291
|
+
bar.base = this.scale.endPoint;
|
2292
|
+
//Transition then draw
|
2293
|
+
bar.transition({
|
2294
|
+
x : this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
|
2295
|
+
y : this.scale.calculateY(bar.value),
|
2296
|
+
width : this.scale.calculateBarWidth(this.datasets.length)
|
2297
|
+
}, easingDecimal).draw();
|
2298
|
+
}
|
2178
2299
|
},this);
|
2179
2300
|
|
2180
2301
|
},this);
|
@@ -2183,6 +2304,7 @@
|
|
2183
2304
|
|
2184
2305
|
|
2185
2306
|
}).call(this);
|
2307
|
+
|
2186
2308
|
(function(){
|
2187
2309
|
"use strict";
|
2188
2310
|
|
@@ -2385,6 +2507,12 @@
|
|
2385
2507
|
//Number - Width of the grid lines
|
2386
2508
|
scaleGridLineWidth : 1,
|
2387
2509
|
|
2510
|
+
//Boolean - Whether to show horizontal lines (except X axis)
|
2511
|
+
scaleShowHorizontalLines: true,
|
2512
|
+
|
2513
|
+
//Boolean - Whether to show vertical lines (except Y axis)
|
2514
|
+
scaleShowVerticalLines: true,
|
2515
|
+
|
2388
2516
|
//Boolean - Whether the line is curved between points
|
2389
2517
|
bezierCurve : true,
|
2390
2518
|
|
@@ -2467,19 +2595,16 @@
|
|
2467
2595
|
|
2468
2596
|
|
2469
2597
|
helpers.each(dataset.data,function(dataPoint,index){
|
2470
|
-
//Best way to do this? or in draw sequence...?
|
2471
|
-
if (helpers.isNumber(dataPoint)){
|
2472
2598
|
//Add a new point for each piece of data, passing any required data to draw.
|
2473
|
-
|
2474
|
-
|
2475
|
-
|
2476
|
-
|
2477
|
-
|
2478
|
-
|
2479
|
-
|
2480
|
-
|
2481
|
-
|
2482
|
-
}
|
2599
|
+
datasetObject.points.push(new this.PointClass({
|
2600
|
+
value : dataPoint,
|
2601
|
+
label : data.labels[index],
|
2602
|
+
datasetLabel: dataset.label,
|
2603
|
+
strokeColor : dataset.pointStrokeColor,
|
2604
|
+
fillColor : dataset.pointColor,
|
2605
|
+
highlightFill : dataset.pointHighlightFill || dataset.pointColor,
|
2606
|
+
highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
|
2607
|
+
}));
|
2483
2608
|
},this);
|
2484
2609
|
|
2485
2610
|
this.buildScale(data.labels);
|
@@ -2562,6 +2687,8 @@
|
|
2562
2687
|
font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
|
2563
2688
|
lineWidth : this.options.scaleLineWidth,
|
2564
2689
|
lineColor : this.options.scaleLineColor,
|
2690
|
+
showHorizontalLines : this.options.scaleShowHorizontalLines,
|
2691
|
+
showVerticalLines : this.options.scaleShowVerticalLines,
|
2565
2692
|
gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
|
2566
2693
|
gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
|
2567
2694
|
padding: (this.options.showScale) ? 0 : this.options.pointDotRadius + this.options.pointDotStrokeWidth,
|
@@ -2586,17 +2713,15 @@
|
|
2586
2713
|
//Map the values array for each of the datasets
|
2587
2714
|
|
2588
2715
|
helpers.each(valuesArray,function(value,datasetIndex){
|
2589
|
-
|
2590
|
-
|
2591
|
-
|
2592
|
-
|
2593
|
-
|
2594
|
-
|
2595
|
-
|
2596
|
-
|
2597
|
-
|
2598
|
-
}));
|
2599
|
-
}
|
2716
|
+
//Add a new point for each piece of data, passing any required data to draw.
|
2717
|
+
this.datasets[datasetIndex].points.push(new this.PointClass({
|
2718
|
+
value : value,
|
2719
|
+
label : label,
|
2720
|
+
x: this.scale.calculateX(this.scale.valuesCount+1),
|
2721
|
+
y: this.scale.endPoint,
|
2722
|
+
strokeColor : this.datasets[datasetIndex].pointStrokeColor,
|
2723
|
+
fillColor : this.datasets[datasetIndex].pointColor
|
2724
|
+
}));
|
2600
2725
|
},this);
|
2601
2726
|
|
2602
2727
|
this.scale.addXLabel(label);
|
@@ -2624,37 +2749,64 @@
|
|
2624
2749
|
|
2625
2750
|
var ctx = this.chart.ctx;
|
2626
2751
|
|
2752
|
+
// Some helper methods for getting the next/prev points
|
2753
|
+
var hasValue = function(item){
|
2754
|
+
return item.value !== null;
|
2755
|
+
},
|
2756
|
+
nextPoint = function(point, collection, index){
|
2757
|
+
return helpers.findNextWhere(collection, hasValue, index) || point;
|
2758
|
+
},
|
2759
|
+
previousPoint = function(point, collection, index){
|
2760
|
+
return helpers.findPreviousWhere(collection, hasValue, index) || point;
|
2761
|
+
};
|
2762
|
+
|
2627
2763
|
this.scale.draw(easingDecimal);
|
2628
2764
|
|
2629
2765
|
|
2630
2766
|
helpers.each(this.datasets,function(dataset){
|
2767
|
+
var pointsWithValues = helpers.where(dataset.points, hasValue);
|
2631
2768
|
|
2632
2769
|
//Transition each point first so that the line and point drawing isn't out of sync
|
2633
2770
|
//We can use this extra loop to calculate the control points of this dataset also in this loop
|
2634
2771
|
|
2635
|
-
helpers.each(dataset.points,function(point,index){
|
2636
|
-
point.
|
2637
|
-
|
2638
|
-
|
2639
|
-
|
2640
|
-
|
2772
|
+
helpers.each(dataset.points, function(point, index){
|
2773
|
+
if (point.hasValue()){
|
2774
|
+
point.transition({
|
2775
|
+
y : this.scale.calculateY(point.value),
|
2776
|
+
x : this.scale.calculateX(index)
|
2777
|
+
}, easingDecimal);
|
2778
|
+
}
|
2641
2779
|
},this);
|
2642
2780
|
|
2643
2781
|
|
2644
2782
|
// Control points need to be calculated in a seperate loop, because we need to know the current x/y of the point
|
2645
2783
|
// This would cause issues when there is no animation, because the y of the next point would be 0, so beziers would be skewed
|
2646
2784
|
if (this.options.bezierCurve){
|
2647
|
-
helpers.each(
|
2648
|
-
|
2649
|
-
|
2650
|
-
|
2651
|
-
point
|
2785
|
+
helpers.each(pointsWithValues, function(point, index){
|
2786
|
+
var tension = (index > 0 && index < pointsWithValues.length - 1) ? this.options.bezierCurveTension : 0;
|
2787
|
+
point.controlPoints = helpers.splineCurve(
|
2788
|
+
previousPoint(point, pointsWithValues, index),
|
2789
|
+
point,
|
2790
|
+
nextPoint(point, pointsWithValues, index),
|
2791
|
+
tension
|
2792
|
+
);
|
2793
|
+
|
2794
|
+
// Prevent the bezier going outside of the bounds of the graph
|
2795
|
+
|
2796
|
+
// Cap puter bezier handles to the upper/lower scale bounds
|
2797
|
+
if (point.controlPoints.outer.y > this.scale.endPoint){
|
2798
|
+
point.controlPoints.outer.y = this.scale.endPoint;
|
2652
2799
|
}
|
2653
|
-
else if (
|
2654
|
-
point.controlPoints =
|
2800
|
+
else if (point.controlPoints.outer.y < this.scale.startPoint){
|
2801
|
+
point.controlPoints.outer.y = this.scale.startPoint;
|
2655
2802
|
}
|
2656
|
-
|
2657
|
-
|
2803
|
+
|
2804
|
+
// Cap inner bezier handles to the upper/lower scale bounds
|
2805
|
+
if (point.controlPoints.inner.y > this.scale.endPoint){
|
2806
|
+
point.controlPoints.inner.y = this.scale.endPoint;
|
2807
|
+
}
|
2808
|
+
else if (point.controlPoints.inner.y < this.scale.startPoint){
|
2809
|
+
point.controlPoints.inner.y = this.scale.startPoint;
|
2658
2810
|
}
|
2659
2811
|
},this);
|
2660
2812
|
}
|
@@ -2664,12 +2816,18 @@
|
|
2664
2816
|
ctx.lineWidth = this.options.datasetStrokeWidth;
|
2665
2817
|
ctx.strokeStyle = dataset.strokeColor;
|
2666
2818
|
ctx.beginPath();
|
2667
|
-
|
2668
|
-
|
2819
|
+
|
2820
|
+
helpers.each(pointsWithValues, function(point, index){
|
2821
|
+
if (index === 0){
|
2822
|
+
ctx.moveTo(point.x, point.y);
|
2823
|
+
}
|
2824
|
+
else{
|
2669
2825
|
if(this.options.bezierCurve){
|
2826
|
+
var previous = previousPoint(point, pointsWithValues, index);
|
2827
|
+
|
2670
2828
|
ctx.bezierCurveTo(
|
2671
|
-
|
2672
|
-
|
2829
|
+
previous.controlPoints.outer.x,
|
2830
|
+
previous.controlPoints.outer.y,
|
2673
2831
|
point.controlPoints.inner.x,
|
2674
2832
|
point.controlPoints.inner.y,
|
2675
2833
|
point.x,
|
@@ -2679,19 +2837,15 @@
|
|
2679
2837
|
else{
|
2680
2838
|
ctx.lineTo(point.x,point.y);
|
2681
2839
|
}
|
2682
|
-
|
2683
2840
|
}
|
2684
|
-
|
2685
|
-
ctx.moveTo(point.x,point.y);
|
2686
|
-
}
|
2687
|
-
},this);
|
2688
|
-
ctx.stroke();
|
2841
|
+
}, this);
|
2689
2842
|
|
2843
|
+
ctx.stroke();
|
2690
2844
|
|
2691
|
-
if (this.options.datasetFill){
|
2845
|
+
if (this.options.datasetFill && pointsWithValues.length > 0){
|
2692
2846
|
//Round off the line by going to the base of the chart, back to the start, then fill.
|
2693
|
-
ctx.lineTo(
|
2694
|
-
ctx.lineTo(
|
2847
|
+
ctx.lineTo(pointsWithValues[pointsWithValues.length - 1].x, this.scale.endPoint);
|
2848
|
+
ctx.lineTo(pointsWithValues[0].x, this.scale.endPoint);
|
2695
2849
|
ctx.fillStyle = dataset.fillColor;
|
2696
2850
|
ctx.closePath();
|
2697
2851
|
ctx.fill();
|
@@ -2700,16 +2854,16 @@
|
|
2700
2854
|
//Now draw the points over the line
|
2701
2855
|
//A little inefficient double looping, but better than the line
|
2702
2856
|
//lagging behind the point positions
|
2703
|
-
helpers.each(
|
2857
|
+
helpers.each(pointsWithValues,function(point){
|
2704
2858
|
point.draw();
|
2705
2859
|
});
|
2706
|
-
|
2707
2860
|
},this);
|
2708
2861
|
}
|
2709
2862
|
});
|
2710
2863
|
|
2711
2864
|
|
2712
2865
|
}).call(this);
|
2866
|
+
|
2713
2867
|
(function(){
|
2714
2868
|
"use strict";
|
2715
2869
|
|
@@ -3071,25 +3225,22 @@
|
|
3071
3225
|
this.datasets.push(datasetObject);
|
3072
3226
|
|
3073
3227
|
helpers.each(dataset.data,function(dataPoint,index){
|
3074
|
-
//Best way to do this? or in draw sequence...?
|
3075
|
-
if (helpers.isNumber(dataPoint)){
|
3076
3228
|
//Add a new point for each piece of data, passing any required data to draw.
|
3077
|
-
|
3078
|
-
|
3079
|
-
|
3080
|
-
}
|
3081
|
-
datasetObject.points.push(new this.PointClass({
|
3082
|
-
value : dataPoint,
|
3083
|
-
label : data.labels[index],
|
3084
|
-
datasetLabel: dataset.label,
|
3085
|
-
x: (this.options.animation) ? this.scale.xCenter : pointPosition.x,
|
3086
|
-
y: (this.options.animation) ? this.scale.yCenter : pointPosition.y,
|
3087
|
-
strokeColor : dataset.pointStrokeColor,
|
3088
|
-
fillColor : dataset.pointColor,
|
3089
|
-
highlightFill : dataset.pointHighlightFill || dataset.pointColor,
|
3090
|
-
highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
|
3091
|
-
}));
|
3229
|
+
var pointPosition;
|
3230
|
+
if (!this.scale.animation){
|
3231
|
+
pointPosition = this.scale.getPointPosition(index, this.scale.calculateCenterOffset(dataPoint));
|
3092
3232
|
}
|
3233
|
+
datasetObject.points.push(new this.PointClass({
|
3234
|
+
value : dataPoint,
|
3235
|
+
label : data.labels[index],
|
3236
|
+
datasetLabel: dataset.label,
|
3237
|
+
x: (this.options.animation) ? this.scale.xCenter : pointPosition.x,
|
3238
|
+
y: (this.options.animation) ? this.scale.yCenter : pointPosition.y,
|
3239
|
+
strokeColor : dataset.pointStrokeColor,
|
3240
|
+
fillColor : dataset.pointColor,
|
3241
|
+
highlightFill : dataset.pointHighlightFill || dataset.pointColor,
|
3242
|
+
highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
|
3243
|
+
}));
|
3093
3244
|
},this);
|
3094
3245
|
|
3095
3246
|
},this);
|
@@ -3204,17 +3355,15 @@
|
|
3204
3355
|
//Map the values array for each of the datasets
|
3205
3356
|
this.scale.valuesCount++;
|
3206
3357
|
helpers.each(valuesArray,function(value,datasetIndex){
|
3207
|
-
|
3208
|
-
|
3209
|
-
|
3210
|
-
|
3211
|
-
|
3212
|
-
|
3213
|
-
|
3214
|
-
|
3215
|
-
|
3216
|
-
}));
|
3217
|
-
}
|
3358
|
+
var pointPosition = this.scale.getPointPosition(this.scale.valuesCount, this.scale.calculateCenterOffset(value));
|
3359
|
+
this.datasets[datasetIndex].points.push(new this.PointClass({
|
3360
|
+
value : value,
|
3361
|
+
label : label,
|
3362
|
+
x: pointPosition.x,
|
3363
|
+
y: pointPosition.y,
|
3364
|
+
strokeColor : this.datasets[datasetIndex].pointStrokeColor,
|
3365
|
+
fillColor : this.datasets[datasetIndex].pointColor
|
3366
|
+
}));
|
3218
3367
|
},this);
|
3219
3368
|
|
3220
3369
|
this.scale.labels.push(label);
|
@@ -3261,7 +3410,9 @@
|
|
3261
3410
|
|
3262
3411
|
//Transition each point first so that the line and point drawing isn't out of sync
|
3263
3412
|
helpers.each(dataset.points,function(point,index){
|
3264
|
-
|
3413
|
+
if (point.hasValue()){
|
3414
|
+
point.transition(this.scale.getPointPosition(index, this.scale.calculateCenterOffset(point.value)), easeDecimal);
|
3415
|
+
}
|
3265
3416
|
},this);
|
3266
3417
|
|
3267
3418
|
|
@@ -3288,7 +3439,9 @@
|
|
3288
3439
|
//A little inefficient double looping, but better than the line
|
3289
3440
|
//lagging behind the point positions
|
3290
3441
|
helpers.each(dataset.points,function(point){
|
3291
|
-
point.
|
3442
|
+
if (point.hasValue()){
|
3443
|
+
point.draw();
|
3444
|
+
}
|
3292
3445
|
});
|
3293
3446
|
|
3294
3447
|
},this);
|
@@ -3301,4 +3454,4 @@
|
|
3301
3454
|
|
3302
3455
|
|
3303
3456
|
|
3304
|
-
}).call(this);
|
3457
|
+
}).call(this);
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chart-js-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,12 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
default_executable:
|
12
|
+
date: 2015-01-19 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: railties
|
17
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
18
17
|
none: false
|
19
18
|
requirements:
|
20
19
|
- - ! '>'
|
@@ -22,7 +21,12 @@ dependencies:
|
|
22
21
|
version: '3.1'
|
23
22
|
type: :runtime
|
24
23
|
prerelease: false
|
25
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>'
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.1'
|
26
30
|
description: Chart.js for use in Rails asset pipeline
|
27
31
|
email:
|
28
32
|
- walsh1kt@gmail.com
|
@@ -39,7 +43,6 @@ files:
|
|
39
43
|
- lib/chart-js-rails.rb
|
40
44
|
- lib/chart-js-rails/version.rb
|
41
45
|
- vendor/assets/javascripts/Chart.js
|
42
|
-
has_rdoc: true
|
43
46
|
homepage: ''
|
44
47
|
licenses: []
|
45
48
|
post_install_message:
|
@@ -60,8 +63,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
63
|
version: '0'
|
61
64
|
requirements: []
|
62
65
|
rubyforge_project:
|
63
|
-
rubygems_version: 1.
|
66
|
+
rubygems_version: 1.8.25
|
64
67
|
signing_key:
|
65
68
|
specification_version: 3
|
66
69
|
summary: Create HTML5 charts
|
67
70
|
test_files: []
|
71
|
+
has_rdoc:
|