app/assets/javascripts/pghero/Chart.bundle.js in pghero-1.4.2 vs app/assets/javascripts/pghero/Chart.bundle.js in pghero-1.5.0
- old
+ new
@@ -1,9 +1,9 @@
/*!
* Chart.js
* http://chartjs.org/
- * Version: 2.2.1
+ * Version: 2.2.2
*
* Copyright 2016 Nick Downie
* Released under the MIT license
* https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
*/
@@ -6528,11 +6528,11 @@
tickHeight: tickHeight,
categoryHeight: categoryHeight,
categorySpacing: categorySpacing,
fullBarHeight: fullBarHeight,
barHeight: barHeight,
- barSpacing: barSpacing,
+ barSpacing: barSpacing
};
},
calculateBarHeight: function (index) {
var me = this;
@@ -7109,10 +7109,11 @@
borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),
borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),
borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),
fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),
steppedLine: custom.steppedLine ? custom.steppedLine : helpers.getValueOrDefault(dataset.steppedLine, lineElementOptions.stepped),
+ cubicInterpolationMode: custom.cubicInterpolationMode ? custom.cubicInterpolationMode : helpers.getValueOrDefault(dataset.cubicInterpolationMode, lineElementOptions.cubicInterpolationMode),
// Scale
scaleTop: scale.top,
scaleBottom: scale.bottom,
scaleZero: scale.getBasePixel()
};
@@ -7192,20 +7193,22 @@
var value = dataset.data[index];
var yScale = me.getScaleForId(meta.yAxisID);
var xScale = me.getScaleForId(meta.xAxisID);
var pointOptions = me.chart.options.elements.point;
var x, y;
+ var labels = me.chart.data.labels || [];
+ var includeOffset = (labels.length === 1 || dataset.data.length === 1) || me.chart.isCombo;
// Compatibility: If the properties are defined with only the old name, use those values
if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
dataset.pointRadius = dataset.radius;
}
if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {
dataset.pointHitRadius = dataset.hitRadius;
}
- x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex, me.chart.isCombo);
+ x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex, includeOffset);
y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);
// Utility
point._xScale = xScale;
point._yScale = yScale;
@@ -7267,34 +7270,49 @@
updateBezierControlPoints: function() {
var me = this;
var meta = me.getMeta();
var area = me.chart.chartArea;
- // only consider points that are drawn in case the spanGaps option is ued
- var points = (meta.data || []).filter(function(pt) { return !pt._model.skip; });
+ // Only consider points that are drawn in case the spanGaps option is used
+ var points = (meta.data || []);
+ if (meta.dataset._model.spanGaps) points = points.filter(function(pt) { return !pt._model.skip; });
var i, ilen, point, model, controlPoints;
- var needToCap = me.chart.options.elements.line.capBezierPoints;
- function capIfNecessary(pt, min, max) {
- return needToCap ? Math.max(Math.min(pt, max), min) : pt;
+ function capControlPoint(pt, min, max) {
+ return Math.max(Math.min(pt, max), min);
}
- for (i=0, ilen=points.length; i<ilen; ++i) {
- point = points[i];
- model = point._model;
- controlPoints = helpers.splineCurve(
- helpers.previousItem(points, i)._model,
- model,
- helpers.nextItem(points, i)._model,
- meta.dataset._model.tension
- );
+ if (meta.dataset._model.cubicInterpolationMode == 'monotone') {
+ helpers.splineCurveMonotone(points);
+ }
+ else {
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ point = points[i];
+ model = point._model;
+ controlPoints = helpers.splineCurve(
+ helpers.previousItem(points, i)._model,
+ model,
+ helpers.nextItem(points, i)._model,
+ meta.dataset._model.tension
+ );
+ model.controlPointPreviousX = controlPoints.previous.x;
+ model.controlPointPreviousY = controlPoints.previous.y;
+ model.controlPointNextX = controlPoints.next.x;
+ model.controlPointNextY = controlPoints.next.y;
+ }
+ }
- model.controlPointPreviousX = capIfNecessary(controlPoints.previous.x, area.left, area.right);
- model.controlPointPreviousY = capIfNecessary(controlPoints.previous.y, area.top, area.bottom);
- model.controlPointNextX = capIfNecessary(controlPoints.next.x, area.left, area.right);
- model.controlPointNextY = capIfNecessary(controlPoints.next.y, area.top, area.bottom);
+ if (me.chart.options.elements.line.capBezierPoints) {
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ model = points[i]._model;
+ model.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right);
+ model.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom);
+ model.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right);
+ model.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom);
+ }
}
+
},
draw: function(ease) {
var me = this;
var meta = me.getMeta();
@@ -9296,10 +9314,81 @@
x: current.x + fb * (next.x - previous.x),
y: current.y + fb * (next.y - previous.y)
}
};
};
+ helpers.EPSILON = Number.EPSILON || 1e-14;
+ helpers.splineCurveMonotone = function(points) {
+ // This function calculates Bézier control points in a similar way than |splineCurve|,
+ // but preserves monotonicity of the provided data and ensures no local extremums are added
+ // between the dataset discrete points due to the interpolation.
+ // See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation
+
+ var pointsWithTangents = (points || []).map(function(point) {
+ return {
+ model: point._model,
+ deltaK: 0,
+ mK: 0
+ };
+ });
+
+ // Calculate slopes (deltaK) and initialize tangents (mK)
+ var pointsLen = pointsWithTangents.length;
+ var i, pointBefore, pointCurrent, pointAfter;
+ for (i = 0; i < pointsLen; ++i) {
+ pointCurrent = pointsWithTangents[i];
+ if (pointCurrent.model.skip) continue;
+ pointBefore = i > 0 ? pointsWithTangents[i - 1] : null;
+ pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;
+ if (pointAfter && !pointAfter.model.skip) {
+ pointCurrent.deltaK = (pointAfter.model.y - pointCurrent.model.y) / (pointAfter.model.x - pointCurrent.model.x);
+ }
+ if (!pointBefore || pointBefore.model.skip) pointCurrent.mK = pointCurrent.deltaK;
+ else if (!pointAfter || pointAfter.model.skip) pointCurrent.mK = pointBefore.deltaK;
+ else if (this.sign(pointBefore.deltaK) != this.sign(pointCurrent.deltaK)) pointCurrent.mK = 0;
+ else pointCurrent.mK = (pointBefore.deltaK + pointCurrent.deltaK) / 2;
+ }
+
+ // Adjust tangents to ensure monotonic properties
+ var alphaK, betaK, tauK, squaredMagnitude;
+ for (i = 0; i < pointsLen - 1; ++i) {
+ pointCurrent = pointsWithTangents[i];
+ pointAfter = pointsWithTangents[i + 1];
+ if (pointCurrent.model.skip || pointAfter.model.skip) continue;
+ if (helpers.almostEquals(pointCurrent.deltaK, 0, this.EPSILON))
+ {
+ pointCurrent.mK = pointAfter.mK = 0;
+ continue;
+ }
+ alphaK = pointCurrent.mK / pointCurrent.deltaK;
+ betaK = pointAfter.mK / pointCurrent.deltaK;
+ squaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2);
+ if (squaredMagnitude <= 9) continue;
+ tauK = 3 / Math.sqrt(squaredMagnitude);
+ pointCurrent.mK = alphaK * tauK * pointCurrent.deltaK;
+ pointAfter.mK = betaK * tauK * pointCurrent.deltaK;
+ }
+
+ // Compute control points
+ var deltaX;
+ for (i = 0; i < pointsLen; ++i) {
+ pointCurrent = pointsWithTangents[i];
+ if (pointCurrent.model.skip) continue;
+ pointBefore = i > 0 ? pointsWithTangents[i - 1] : null;
+ pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;
+ if (pointBefore && !pointBefore.model.skip) {
+ deltaX = (pointCurrent.model.x - pointBefore.model.x) / 3;
+ pointCurrent.model.controlPointPreviousX = pointCurrent.model.x - deltaX;
+ pointCurrent.model.controlPointPreviousY = pointCurrent.model.y - deltaX * pointCurrent.mK;
+ }
+ if (pointAfter && !pointAfter.model.skip) {
+ deltaX = (pointAfter.model.x - pointCurrent.model.x) / 3;
+ pointCurrent.model.controlPointNextX = pointCurrent.model.x + deltaX;
+ pointCurrent.model.controlPointNextY = pointCurrent.model.y + deltaX * pointCurrent.mK;
+ }
+ }
+ };
helpers.nextItem = function(collection, index, loop) {
if (loop) {
return index >= collection.length - 1 ? collection[0] : collection[index + 1];
}
@@ -9833,10 +9922,11 @@
} else {
hiddenIframe.setAttribute('class', hiddenIframeClass);
}
// Set the style
+ hiddenIframe.tabIndex = -1;
var style = hiddenIframe.style;
style.width = '100%';
style.display = 'block';
style.border = 0;
style.height = 0;
@@ -10959,11 +11049,13 @@
drawOnChartArea: true,
drawTicks: true,
tickMarkLength: 10,
zeroLineWidth: 1,
zeroLineColor: "rgba(0,0,0,0.25)",
- offsetGridLines: false
+ offsetGridLines: false,
+ borderDash: [],
+ borderDashOffset: 0.0
},
// scale label
scaleLabel: {
// actual label
@@ -11215,10 +11307,11 @@
var opts = me.options;
var globalDefaults = Chart.defaults.global;
var tickOpts = opts.ticks;
var scaleLabelOpts = opts.scaleLabel;
+ var gridLineOpts = opts.gridLines;
var display = opts.display;
var isHorizontal = me.isHorizontal();
var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
var tickFontStyle = helpers.getValueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);
@@ -11232,16 +11325,16 @@
// Width
if (isHorizontal) {
// subtract the margins to line up with the chartArea if we are a full width scale
minSize.width = me.isFullWidth() ? me.maxWidth - me.margins.left - me.margins.right : me.maxWidth;
} else {
- minSize.width = display ? tickMarkLength : 0;
+ minSize.width = display && gridLineOpts.drawTicks ? tickMarkLength : 0;
}
// height
if (isHorizontal) {
- minSize.height = display ? tickMarkLength : 0;
+ minSize.height = display && gridLineOpts.drawTicks ? tickMarkLength : 0;
} else {
minSize.height = me.maxHeight; // fill all the height
}
// Are we showing a title for the scale?
@@ -11442,10 +11535,12 @@
var tickFontSize = helpers.getValueOrDefault(optionTicks.fontSize, globalDefaults.defaultFontSize);
var tickFontStyle = helpers.getValueOrDefault(optionTicks.fontStyle, globalDefaults.defaultFontStyle);
var tickFontFamily = helpers.getValueOrDefault(optionTicks.fontFamily, globalDefaults.defaultFontFamily);
var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
var tl = gridLines.tickMarkLength;
+ var borderDash = helpers.getValueOrDefault(gridLines.borderDash, globalDefaults.borderDash);
+ var borderDashOffset = helpers.getValueOrDefault(gridLines.borderDashOffset, globalDefaults.borderDashOffset);
var scaleLabelFontColor = helpers.getValueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);
var scaleLabelFontSize = helpers.getValueOrDefault(scaleLabel.fontSize, globalDefaults.defaultFontSize);
var scaleLabelFontStyle = helpers.getValueOrDefault(scaleLabel.fontStyle, globalDefaults.defaultFontStyle);
var scaleLabelFontFamily = helpers.getValueOrDefault(scaleLabel.fontFamily, globalDefaults.defaultFontFamily);
@@ -11581,22 +11676,29 @@
y2: y2,
labelX: labelX,
labelY: labelY,
glWidth: lineWidth,
glColor: lineColor,
+ glBorderDash: borderDash,
+ glBorderDashOffset: borderDashOffset,
rotation: -1 * labelRotationRadians,
label: label,
textBaseline: textBaseline,
textAlign: textAlign
});
});
// Draw all of the tick labels, tick marks, and grid lines at the correct places
helpers.each(itemsToDraw, function(itemToDraw) {
if (gridLines.display) {
+ context.save();
context.lineWidth = itemToDraw.glWidth;
context.strokeStyle = itemToDraw.glColor;
+ if (context.setLineDash) {
+ context.setLineDash(itemToDraw.glBorderDash);
+ context.lineDashOffset = itemToDraw.glBorderDashOffset;
+ }
context.beginPath();
if (gridLines.drawTicks) {
context.moveTo(itemToDraw.tx1, itemToDraw.ty1);
@@ -11607,10 +11709,11 @@
context.moveTo(itemToDraw.x1, itemToDraw.y1);
context.lineTo(itemToDraw.x2, itemToDraw.y2);
}
context.stroke();
+ context.restore();
}
if (optionTicks.display) {
context.save();
context.translate(itemToDraw.labelX, itemToDraw.labelY);
@@ -12230,11 +12333,13 @@
tooltipItems.push(createTooltipItem(active[i]));
}
// If the user provided a sorting function, use it to modify the tooltip items
if (opts.itemSort) {
- tooltipItems = tooltipItems.sort(opts.itemSort);
+ tooltipItems = tooltipItems.sort(function(a,b) {
+ return opts.itemSort(a,b, data);
+ });
}
// If there is more than one item, show color items
if (active.length > 1) {
helpers.each(tooltipItems, function(tooltipItem) {
@@ -12865,11 +12970,11 @@
lastDrawnIndex = index;
}
}
}
- if (!loop) {
+ if (!loop && lastDrawnIndex !== -1) {
ctx.lineTo(points[lastDrawnIndex]._view.x, scaleZero);
}
ctx.fillStyle = vm.backgroundColor || globalDefaults.defaultColor;
ctx.closePath();
@@ -12899,13 +13004,11 @@
previous = helpers.previousItem(points, index);
currentVM = current._view;
// First point moves to it's starting position no matter what
if (index === 0) {
- if (currentVM.skip) {
-
- } else {
+ if (!currentVM.skip) {
ctx.moveTo(currentVM.x, currentVM.y);
lastDrawnIndex = index;
}
} else {
previous = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex];
@@ -13103,11 +13206,11 @@
return (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels;
},
// Implement this so that
determineDataLimits: function() {
var me = this;
- var labels = me.getLabels();
+ var labels = me.getLabels();
me.minIndex = 0;
me.maxIndex = labels.length - 1;
var findIndex;
if (me.options.ticks.min !== undefined) {
@@ -13141,24 +13244,24 @@
getPixelForValue: function(value, index, datasetIndex, includeOffset) {
var me = this;
// 1 is added because we need the length but we have the indexes
var offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
- if (value !== undefined) {
+ if (value !== undefined && isNaN(index)) {
var labels = me.getLabels();
var idx = labels.indexOf(value);
index = idx !== -1 ? idx : index;
}
if (me.isHorizontal()) {
var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
var valueWidth = innerWidth / offsetAmt;
var widthOffset = (valueWidth * (index - me.minIndex)) + me.paddingLeft;
- if (me.options.gridLines.offsetGridLines && includeOffset) {
+ if (me.options.gridLines.offsetGridLines && includeOffset || me.maxIndex === me.minIndex && includeOffset) {
widthOffset += (valueWidth / 2);
- }
+ }
return me.left + Math.round(widthOffset);
} else {
var innerHeight = me.height - (me.paddingTop + me.paddingBottom);
var valueHeight = innerHeight / offsetAmt;
@@ -13526,11 +13629,11 @@
var me = this;
me.ticksAsNumbers = me.ticks.slice();
me.zeroLineIndex = me.ticks.indexOf(0);
Chart.Scale.prototype.convertTicksToLabels.call(me);
- },
+ }
});
};
},{}],42:[function(require,module,exports){
"use strict";
@@ -13544,11 +13647,13 @@
// label settings
ticks: {
callback: function(value, index, arr) {
var remain = value / (Math.pow(10, Math.floor(helpers.log10(value))));
- if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === arr.length - 1) {
+ if (value === 0){
+ return '0';
+ } else if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === arr.length - 1) {
return value.toExponential();
} else {
return '';
}
}
@@ -13570,10 +13675,11 @@
}
// Calculate Range
me.min = null;
me.max = null;
+ me.minNotZero = null;
if (opts.stacked) {
var valuesPerType = {};
helpers.each(datasets, function(dataset, datasetIndex) {
@@ -13628,10 +13734,14 @@
if (me.max === null) {
me.max = value;
} else if (value > me.max) {
me.max = value;
}
+
+ if(value !== 0 && (me.minNotZero === null || value < me.minNotZero)) {
+ me.minNotZero = value;
+ }
});
}
});
}
@@ -13666,13 +13776,21 @@
var tickVal = getValueOrDefault(tickOpts.min, Math.pow(10, Math.floor(helpers.log10(me.min))));
while (tickVal < me.max) {
ticks.push(tickVal);
- var exp = Math.floor(helpers.log10(tickVal));
- var significand = Math.floor(tickVal / Math.pow(10, exp)) + 1;
+ var exp;
+ var significand;
+ if(tickVal === 0){
+ exp = Math.floor(helpers.log10(me.minNotZero));
+ significand = Math.round(me.minNotZero / Math.pow(10, exp));
+ } else {
+ exp = Math.floor(helpers.log10(tickVal));
+ significand = Math.floor(tickVal / Math.pow(10, exp)) + 1;
+ }
+
if (significand === 10) {
significand = 1;
++exp;
}
@@ -13719,49 +13837,67 @@
var innerDimension;
var pixel;
var start = me.start;
var newVal = +me.getRightValue(value);
- var range = helpers.log10(me.end) - helpers.log10(start);
+ var range;
var paddingTop = me.paddingTop;
var paddingBottom = me.paddingBottom;
var paddingLeft = me.paddingLeft;
+ var opts = me.options;
+ var tickOpts = opts.ticks;
if (me.isHorizontal()) {
-
+ range = helpers.log10(me.end) - helpers.log10(start); // todo: if start === 0
if (newVal === 0) {
pixel = me.left + paddingLeft;
} else {
innerDimension = me.width - (paddingLeft + me.paddingRight);
pixel = me.left + (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));
pixel += paddingLeft;
}
} else {
// Bottom - top since pixels increase downard on a screen
- if (newVal === 0) {
- pixel = me.top + paddingTop;
+ innerDimension = me.height - (paddingTop + paddingBottom);
+ if(start === 0 && !tickOpts.reverse){
+ range = helpers.log10(me.end) - helpers.log10(me.minNotZero);
+ if (newVal === start) {
+ pixel = me.bottom - paddingBottom;
+ } else if(newVal === me.minNotZero){
+ pixel = me.bottom - paddingBottom - innerDimension * 0.02;
+ } else {
+ pixel = me.bottom - paddingBottom - innerDimension * 0.02 - (innerDimension * 0.98/ range * (helpers.log10(newVal)-helpers.log10(me.minNotZero)));
+ }
+ } else if (me.end === 0 && tickOpts.reverse){
+ range = helpers.log10(me.start) - helpers.log10(me.minNotZero);
+ if (newVal === me.end) {
+ pixel = me.top + paddingTop;
+ } else if(newVal === me.minNotZero){
+ pixel = me.top + paddingTop + innerDimension * 0.02;
+ } else {
+ pixel = me.top + paddingTop + innerDimension * 0.02 + (innerDimension * 0.98/ range * (helpers.log10(newVal)-helpers.log10(me.minNotZero)));
+ }
} else {
+ range = helpers.log10(me.end) - helpers.log10(start);
innerDimension = me.height - (paddingTop + paddingBottom);
pixel = (me.bottom - paddingBottom) - (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));
- }
+ }
}
-
return pixel;
},
getValueForPixel: function(pixel) {
var me = this;
var range = helpers.log10(me.end) - helpers.log10(me.start);
var value, innerDimension;
if (me.isHorizontal()) {
innerDimension = me.width - (me.paddingLeft + me.paddingRight);
value = me.start * Math.pow(10, (pixel - me.left - me.paddingLeft) * range / innerDimension);
- } else {
+ } else { // todo: if start === 0
innerDimension = me.height - (me.paddingTop + me.paddingBottom);
value = Math.pow(10, (me.bottom - me.paddingBottom - pixel) * range / innerDimension) / me.start;
}
-
return value;
}
});
Chart.scaleService.registerScaleType("logarithmic", LogarithmicScale, defaultConfig);
@@ -14441,18 +14577,10 @@
}
me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true);
}
- me.smallestLabelSeparation = me.width;
-
- helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) {
- for (var i = 1; i < me.labelMoments[datasetIndex].length; i++) {
- me.smallestLabelSeparation = Math.min(me.smallestLabelSeparation, me.labelMoments[datasetIndex][i].diff(me.labelMoments[datasetIndex][i - 1], me.tickUnit, true));
- }
- }, me);
-
// Tick displayFormat override
if (me.options.time.displayFormat) {
me.displayFormat = me.options.time.displayFormat;
}
@@ -14479,11 +14607,11 @@
// this is a weird case. If the <max> option is the same as the end option, we can't just diff the times because the tick was created from the roundedStart
// but the last tick was not rounded.
if (me.options.time.max) {
me.ticks.push(me.lastTick.clone());
me.scaleSizeInUnits = me.lastTick.diff(me.ticks[0], me.tickUnit, true);
- } else {
+ } else if (me.scaleSizeInUnits === 0) {
me.ticks.push(me.lastTick.clone());
me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true);
}
}
@@ -14524,10 +14652,10 @@
},
getPixelForValue: function(value, index, datasetIndex) {
var me = this;
if (!value || !value.isValid) {
// not already a moment object
- value = moment(me.getRightValue(value));
+ value = me.parseTime(me.getRightValue(value));
}
var labelMoment = value && value.isValid && value.isValid() ? value : me.getLabelMoment(datasetIndex, index);
if (labelMoment) {
var offset = labelMoment.diff(me.firstTick, me.tickUnit, true);
\ No newline at end of file