| `fontFamily` | `String` | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Font family to use when rendering labels.
| `fontSize` | `Number` | 10 | font size in pixels.
| `fontStyle` | `String` | `'normal'` | Font style to use when rendering point labels.
+| `lineHeight` | `Number/String` | `1.2` | Height of an individual line of text (see [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/line-height)).
| `fontFamily` | `String` | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Font family for the tick labels, follows CSS font-family options.
| `fontSize` | `Number` | `12` | Font size for the tick labels.
| `fontStyle` | `String` | `'normal'` | Font style for the tick labels, follows CSS font-style options (i.e. normal, italic, oblique, initial, inherit).
+| `lineHeight` | `Number/String` | `1.2` | Height of an individual line of text (see [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/line-height)).
| `reverse` | `Boolean` | `false` | Reverses order of tick labels.
| `minor` | `object` | `{}` | Minor ticks configuration. Omitted options are inherited from options above.
| `major` | `object` | `{}` | Major ticks configuration. Omitted options are inherited from options above.
| `fontFamily` | `String` | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Font family for the tick labels, follows CSS font-family options.
| `fontSize` | `Number` | `12` | Font size for the tick labels.
| `fontStyle` | `String` | `'normal'` | Font style for the tick labels, follows CSS font-style options (i.e. normal, italic, oblique, initial, inherit).
+| `lineHeight` | `Number/String` | `1.2` | Height of an individual line of text (see [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/line-height)).
## Major Tick Configuration
The majorTick configuration is nested under the ticks configuration in the `major` key. It defines options for the major tick marks that are generated by the axis. Omitted options are inherited from `ticks` configuration.
| `fontFamily` | `String` | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Font family for the tick labels, follows CSS font-family options.
| `fontSize` | `Number` | `12` | Font size for the tick labels.
| `fontStyle` | `String` | `'normal'` | Font style for the tick labels, follows CSS font-style options (i.e. normal, italic, oblique, initial, inherit).
+| `lineHeight` | `Number/String` | `1.2` | Height of an individual line of text (see [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/line-height)).
'use strict';
-var helpers = require('../helpers/index');
+var helpers = require('../helpers/helpers.core');
module.exports = {
/**
defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
defaultFontSize: 12,
defaultFontStyle: 'normal',
+ defaultLineHeight: 1.2,
showLines: true,
// Element defaults defined in element extensions
// actual label
labelString: '',
- // line height
- lineHeight: 1.2,
-
// top/bottom padding
padding: {
top: 4,
context.measureText(tick).width;
}
-function parseFontOptions(options) {
- var valueOrDefault = helpers.valueOrDefault;
- var globalDefaults = defaults.global;
- var size = valueOrDefault(options.fontSize, globalDefaults.defaultFontSize);
- var style = valueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle);
- var family = valueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily);
-
- return {
- size: size,
- style: style,
- family: family,
- font: helpers.fontString(size, style, family)
- };
-}
-
-function parseLineHeight(options) {
- return helpers.options.toLineHeight(
- helpers.valueOrDefault(options.lineHeight, 1.2),
- helpers.valueOrDefault(options.fontSize, defaults.global.defaultFontSize));
-}
-
module.exports = Element.extend({
/**
* Get the padding needed for the scale
// Get the width of each grid by calculating the difference
// between x offsets between 0 and 1.
- var tickFont = parseFontOptions(tickOpts);
- context.font = tickFont.font;
+ var tickFont = helpers.options._parseFont(tickOpts);
+ context.font = tickFont.string;
var labelRotation = tickOpts.minRotation || 0;
if (labels.length && me.options.display && me.isHorizontal()) {
- var originalLabelWidth = helpers.longestText(context, tickFont.font, labels, me.longestTextCache);
+ var originalLabelWidth = helpers.longestText(context, tickFont.string, labels, me.longestTextCache);
var labelWidth = originalLabelWidth;
var cosRotation, sinRotation;
var position = opts.position;
var isHorizontal = me.isHorizontal();
- var tickFont = parseFontOptions(tickOpts);
+ var parseFont = helpers.options._parseFont;
+ var tickFont = parseFont(tickOpts);
var tickMarkLength = opts.gridLines.tickMarkLength;
// Width
// Are we showing a title for the scale?
if (scaleLabelOpts.display && display) {
- var scaleLabelLineHeight = parseLineHeight(scaleLabelOpts);
+ var scaleLabelFont = parseFont(scaleLabelOpts);
var scaleLabelPadding = helpers.options.toPadding(scaleLabelOpts.padding);
- var deltaHeight = scaleLabelLineHeight + scaleLabelPadding.height;
+ var deltaHeight = scaleLabelFont.lineHeight + scaleLabelPadding.height;
if (isHorizontal) {
minSize.height += deltaHeight;
// Don't bother fitting the ticks if we are not showing them
if (tickOpts.display && display) {
- var largestTextWidth = helpers.longestText(me.ctx, tickFont.font, labels, me.longestTextCache);
+ var largestTextWidth = helpers.longestText(me.ctx, tickFont.string, labels, me.longestTextCache);
var tallestLabelHeightInLines = helpers.numberOfLabelLines(labels);
var lineSpace = tickFont.size * 0.5;
var tickPadding = me.options.ticks.padding;
// TODO - improve this calculation
var labelHeight = (sinRotation * largestTextWidth)
- + (tickFont.size * tallestLabelHeightInLines)
- + (lineSpace * (tallestLabelHeightInLines - 1))
+ + (tickFont.lineHeight * tallestLabelHeightInLines)
+ lineSpace; // padding
minSize.height = Math.min(me.maxHeight, minSize.height + labelHeight + tickPadding);
- me.ctx.font = tickFont.font;
- var firstLabelWidth = computeTextSize(me.ctx, labels[0], tickFont.font);
- var lastLabelWidth = computeTextSize(me.ctx, labels[labels.length - 1], tickFont.font);
+ me.ctx.font = tickFont.string;
+ var firstLabelWidth = computeTextSize(me.ctx, labels[0], tickFont.string);
+ var lastLabelWidth = computeTextSize(me.ctx, labels[labels.length - 1], tickFont.string);
var offsetLeft = me.getPixelForTick(0) - me.left;
var offsetRight = me.right - me.getPixelForTick(labels.length - 1);
var paddingLeft, paddingRight;
var chart = me.chart;
var context = me.ctx;
var globalDefaults = defaults.global;
+ var defaultFontColor = globalDefaults.defaultFontColor;
var optionTicks = options.ticks.minor;
var optionMajorTicks = options.ticks.major || optionTicks;
var gridLines = options.gridLines;
var isMirrored = optionTicks.mirror;
var isHorizontal = me.isHorizontal();
+ var parseFont = helpers.options._parseFont;
var ticks = optionTicks.autoSkip ? me._autoSkip(me.getTicks()) : me.getTicks();
- var tickFontColor = helpers.valueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);
- var tickFont = parseFontOptions(optionTicks);
- var majorTickFontColor = helpers.valueOrDefault(optionMajorTicks.fontColor, globalDefaults.defaultFontColor);
- var majorTickFont = parseFontOptions(optionMajorTicks);
+ var tickFontColor = helpers.valueOrDefault(optionTicks.fontColor, defaultFontColor);
+ var tickFont = parseFont(optionTicks);
+ var lineHeight = tickFont.lineHeight;
+ var majorTickFontColor = helpers.valueOrDefault(optionMajorTicks.fontColor, defaultFontColor);
+ var majorTickFont = parseFont(optionMajorTicks);
var tickPadding = optionTicks.padding;
var labelOffset = optionTicks.labelOffset;
var tl = gridLines.drawTicks ? gridLines.tickMarkLength : 0;
- var scaleLabelFontColor = helpers.valueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);
- var scaleLabelFont = parseFontOptions(scaleLabel);
+ var scaleLabelFontColor = helpers.valueOrDefault(scaleLabel.fontColor, defaultFontColor);
+ var scaleLabelFont = parseFont(scaleLabel);
var scaleLabelPadding = helpers.options.toPadding(scaleLabel.padding);
var labelRotationRadians = helpers.toRadians(me.labelRotation);
}
// Common properties
- var tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY, textAlign;
- var textBaseline = 'middle';
+ var tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY, textOffset, textAlign;
+ var labelCount = helpers.isArray(label) ? label.length : 1;
var lineValue = getPixelForGridLine(me, index, gridLines.offsetGridLines);
if (isHorizontal) {
if (position === 'top') {
y1 = alignPixel(chart, chartArea.top, axisWidth) + axisWidth / 2;
y2 = chartArea.bottom;
- textBaseline = !isRotated ? 'bottom' : 'middle';
+ textOffset = ((!isRotated ? 0.5 : 1) - labelCount) * lineHeight;
textAlign = !isRotated ? 'center' : 'left';
labelY = me.bottom - labelYOffset;
} else {
y1 = chartArea.top;
y2 = alignPixel(chart, chartArea.bottom, axisWidth) - axisWidth / 2;
- textBaseline = !isRotated ? 'top' : 'middle';
+ textOffset = (!isRotated ? 0.5 : 0) * lineHeight;
textAlign = !isRotated ? 'center' : 'right';
labelY = me.top + labelYOffset;
}
tx2 = tickEnd;
ty1 = ty2 = y1 = y2 = alignPixel(chart, lineValue, lineWidth);
labelY = me.getPixelForTick(index) + labelOffset;
+ textOffset = (1 - labelCount) * lineHeight / 2;
if (position === 'left') {
x1 = alignPixel(chart, chartArea.left, axisWidth) + axisWidth / 2;
rotation: -1 * labelRotationRadians,
label: label,
major: tick.major,
- textBaseline: textBaseline,
+ textOffset: textOffset,
textAlign: textAlign
});
});
context.save();
context.translate(itemToDraw.labelX, itemToDraw.labelY);
context.rotate(itemToDraw.rotation);
- context.font = itemToDraw.major ? majorTickFont.font : tickFont.font;
+ context.font = itemToDraw.major ? majorTickFont.string : tickFont.string;
context.fillStyle = itemToDraw.major ? majorTickFontColor : tickFontColor;
- context.textBaseline = itemToDraw.textBaseline;
+ context.textBaseline = 'middle';
context.textAlign = itemToDraw.textAlign;
var label = itemToDraw.label;
+ var y = itemToDraw.textOffset;
if (helpers.isArray(label)) {
- var lineCount = label.length;
- var lineHeight = tickFont.size * 1.5;
- var y = isHorizontal ? 0 : -lineHeight * (lineCount - 1) / 2;
-
- for (var i = 0; i < lineCount; ++i) {
+ for (var i = 0; i < label.length; ++i) {
// We just make sure the multiline element is a string here..
context.fillText('' + label[i], 0, y);
- // apply same lineSpacing as calculated @ L#320
y += lineHeight;
}
} else {
- context.fillText(label, 0, 0);
+ context.fillText(label, 0, y);
}
context.restore();
}
var scaleLabelX;
var scaleLabelY;
var rotation = 0;
- var halfLineHeight = parseLineHeight(scaleLabel) / 2;
+ var halfLineHeight = scaleLabelFont.lineHeight / 2;
if (isHorizontal) {
scaleLabelX = me.left + ((me.right - me.left) / 2); // midpoint of the width
context.textAlign = 'center';
context.textBaseline = 'middle';
context.fillStyle = scaleLabelFontColor; // render in correct colour
- context.font = scaleLabelFont.font;
+ context.font = scaleLabelFont.string;
context.fillText(scaleLabel.labelString, 0, 0);
context.restore();
}
var Element = require('../core/core.element');
var helpers = require('../helpers/index');
-var globalDefaults = defaults.global;
+var defaultColor = defaults.global.defaultColor;
defaults._set('global', {
elements: {
line: {
tension: 0.4,
- backgroundColor: globalDefaults.defaultColor,
+ backgroundColor: defaultColor,
borderWidth: 3,
- borderColor: globalDefaults.defaultColor,
+ borderColor: defaultColor,
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
var ctx = me._chart.ctx;
var spanGaps = vm.spanGaps;
var points = me._children.slice(); // clone array
+ var globalDefaults = defaults.global;
var globalOptionLineElements = globalDefaults.elements.line;
var lastDrawnIndex = -1;
var index, current, previous, currentVM;
var x = vm.x;
var y = vm.y;
var epsilon = 0.0000001; // 0.0000001 is margin in pixels for Accumulated error.
+ var globalDefaults = defaults.global;
+ var defaultColor = globalDefaults.defaultColor; // eslint-disable-line no-shadow
if (vm.skip) {
return;
// Clipping for Points.
if (chartArea === undefined || (model.x > chartArea.left - epsilon && chartArea.right + epsilon > model.x && model.y > chartArea.top - epsilon && chartArea.bottom + epsilon > model.y)) {
ctx.strokeStyle = vm.borderColor || defaultColor;
- ctx.lineWidth = helpers.valueOrDefault(vm.borderWidth, defaults.global.elements.point.borderWidth);
+ ctx.lineWidth = helpers.valueOrDefault(vm.borderWidth, globalDefaults.elements.point.borderWidth);
ctx.fillStyle = vm.backgroundColor || defaultColor;
helpers.canvas.drawPoint(ctx, pointStyle, radius, x, y, rotation);
}
var defaults = require('../core/core.defaults');
var Element = require('../core/core.element');
+var defaultColor = defaults.global.defaultColor;
+
defaults._set('global', {
elements: {
rectangle: {
- backgroundColor: defaults.global.defaultColor,
- borderColor: defaults.global.defaultColor,
+ backgroundColor: defaultColor,
+ borderColor: defaultColor,
borderSkipped: 'bottom',
borderWidth: 0
}
'use strict';
+var defaults = require('../core/core.defaults');
var helpers = require('./helpers.core');
+/**
+ * Converts the given font object into a CSS font string.
+ * @param {Object} font - A font object.
+ * @return {Stringg} The CSS font string. See https://developer.mozilla.org/en-US/docs/Web/CSS/font
+ * @private
+ */
+function toFontString(font) {
+ if (!font || helpers.isNullOrUndef(font.size) || helpers.isNullOrUndef(font.family)) {
+ return null;
+ }
+
+ return (font.style ? font.style + ' ' : '')
+ + (font.weight ? font.weight + ' ' : '')
+ + font.size + 'px '
+ + font.family;
+}
+
/**
* @alias Chart.helpers.options
* @namespace
};
},
+ /**
+ * Parses font options and returns the font object.
+ * @param {Object} options - A object that contains font opttons to be parsed.
+ * @return {Object} The font object.
+ * @todo Support font.* options and renamed to toFont().
+ * @private
+ */
+ _parseFont: function(options) {
+ var valueOrDefault = helpers.valueOrDefault;
+ var globalDefaults = defaults.global;
+ var size = valueOrDefault(options.fontSize, globalDefaults.defaultFontSize);
+ var font = {
+ family: valueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily),
+ lineHeight: helpers.options.toLineHeight(valueOrDefault(options.lineHeight, globalDefaults.defaultLineHeight), size),
+ size: size,
+ style: valueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle),
+ weight: null,
+ string: ''
+ };
+
+ font.string = toFontString(font);
+ return font;
+ },
+
/**
* Evaluates the given `inputs` sequentially and returns the first defined value.
* @param {Array[]} inputs - An array of values, falling back to the last value.
var ctx = me.ctx;
- var globalDefault = defaults.global;
- var valueOrDefault = helpers.valueOrDefault;
- var fontSize = valueOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize);
- var fontStyle = valueOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle);
- var fontFamily = valueOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily);
- var labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);
+ var labelFont = helpers.options._parseFont(labelOpts);
+ var fontSize = labelFont.size;
// Reset hit boxes
var hitboxes = me.legendHitBoxes = [];
// Increase sizes here
if (display) {
- ctx.font = labelFont;
+ ctx.font = labelFont.string;
if (isHorizontal) {
// Labels
var me = this;
var opts = me.options;
var labelOpts = opts.labels;
- var globalDefault = defaults.global;
- var lineDefault = globalDefault.elements.line;
+ var globalDefaults = defaults.global;
+ var defaultColor = globalDefaults.defaultColor;
+ var lineDefault = globalDefaults.elements.line;
var legendWidth = me.width;
var lineWidths = me.lineWidths;
if (opts.display) {
var ctx = me.ctx;
var valueOrDefault = helpers.valueOrDefault;
- var fontColor = valueOrDefault(labelOpts.fontColor, globalDefault.defaultFontColor);
- var fontSize = valueOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize);
- var fontStyle = valueOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle);
- var fontFamily = valueOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily);
- var labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);
+ var fontColor = valueOrDefault(labelOpts.fontColor, globalDefaults.defaultFontColor);
+ var labelFont = helpers.options._parseFont(labelOpts);
+ var fontSize = labelFont.size;
var cursor;
// Canvas setup
ctx.lineWidth = 0.5;
ctx.strokeStyle = fontColor; // for strikethrough effect
ctx.fillStyle = fontColor; // render in correct colour
- ctx.font = labelFont;
+ ctx.font = labelFont.string;
var boxWidth = getBoxWidth(labelOpts, fontSize);
var hitboxes = me.legendHitBoxes;
// Set the ctx for the box
ctx.save();
- ctx.fillStyle = valueOrDefault(legendItem.fillStyle, globalDefault.defaultColor);
+ var lineWidth = valueOrDefault(legendItem.lineWidth, lineDefault.borderWidth);
+ ctx.fillStyle = valueOrDefault(legendItem.fillStyle, defaultColor);
ctx.lineCap = valueOrDefault(legendItem.lineCap, lineDefault.borderCapStyle);
ctx.lineDashOffset = valueOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset);
ctx.lineJoin = valueOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle);
- ctx.lineWidth = valueOrDefault(legendItem.lineWidth, lineDefault.borderWidth);
- ctx.strokeStyle = valueOrDefault(legendItem.strokeStyle, globalDefault.defaultColor);
- var isLineWidthZero = (valueOrDefault(legendItem.lineWidth, lineDefault.borderWidth) === 0);
+ ctx.lineWidth = lineWidth;
+ ctx.strokeStyle = valueOrDefault(legendItem.strokeStyle, defaultColor);
if (ctx.setLineDash) {
// IE 9 and 10 do not support line dash
helpers.canvas.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY);
} else {
// Draw box as legend symbol
- if (!isLineWidthZero) {
+ if (lineWidth !== 0) {
ctx.strokeRect(x, y, boxWidth, fontSize);
}
ctx.fillRect(x, y, boxWidth, fontSize);
display: false,
fontStyle: 'bold',
fullWidth: true,
- lineHeight: 1.2,
padding: 10,
position: 'top',
text: '',
beforeFit: noop,
fit: function() {
var me = this;
- var valueOrDefault = helpers.valueOrDefault;
var opts = me.options;
var display = opts.display;
- var fontSize = valueOrDefault(opts.fontSize, defaults.global.defaultFontSize);
var minSize = me.minSize;
var lineCount = helpers.isArray(opts.text) ? opts.text.length : 1;
- var lineHeight = helpers.options.toLineHeight(opts.lineHeight, fontSize);
- var textSize = display ? (lineCount * lineHeight) + (opts.padding * 2) : 0;
+ var fontOpts = helpers.options._parseFont(opts);
+ var textSize = display ? (lineCount * fontOpts.lineHeight) + (opts.padding * 2) : 0;
if (me.isHorizontal()) {
minSize.width = me.maxWidth; // fill all the width
var ctx = me.ctx;
var valueOrDefault = helpers.valueOrDefault;
var opts = me.options;
- var globalDefaults = defaults.global;
if (opts.display) {
- var fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize);
- var fontStyle = valueOrDefault(opts.fontStyle, globalDefaults.defaultFontStyle);
- var fontFamily = valueOrDefault(opts.fontFamily, globalDefaults.defaultFontFamily);
- var titleFont = helpers.fontString(fontSize, fontStyle, fontFamily);
- var lineHeight = helpers.options.toLineHeight(opts.lineHeight, fontSize);
+ var fontOpts = helpers.options._parseFont(opts);
+ var lineHeight = fontOpts.lineHeight;
var offset = lineHeight / 2 + opts.padding;
var rotation = 0;
var top = me.top;
var right = me.right;
var maxWidth, titleX, titleY;
- ctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour
- ctx.font = titleFont;
+ ctx.fillStyle = valueOrDefault(opts.fontColor, defaults.global.defaultFontColor); // render in correct colour
+ ctx.font = fontOpts.string;
// Horizontal
if (me.isHorizontal()) {
module.exports = function(Chart) {
- var globalDefaults = defaults.global;
-
var defaultConfig = {
display: true,
return opts.angleLines.display || opts.pointLabels.display ? scale.chart.data.labels.length : 0;
}
- function getPointLabelFontOptions(scale) {
- var pointLabelOptions = scale.options.pointLabels;
- var fontSize = helpers.valueOrDefault(pointLabelOptions.fontSize, globalDefaults.defaultFontSize);
- var fontStyle = helpers.valueOrDefault(pointLabelOptions.fontStyle, globalDefaults.defaultFontStyle);
- var fontFamily = helpers.valueOrDefault(pointLabelOptions.fontFamily, globalDefaults.defaultFontFamily);
- var font = helpers.fontString(fontSize, fontStyle, fontFamily);
-
- return {
- size: fontSize,
- style: fontStyle,
- family: fontFamily,
- font: font
- };
- }
-
- function getTickFontSize(scale) {
- var opts = scale.options;
+ function getTickBackdropHeight(opts) {
var tickOpts = opts.ticks;
if (tickOpts.display && opts.display) {
- return helpers.valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
+ return helpers.valueOrDefault(tickOpts.fontSize, defaults.global.defaultFontSize) + tickOpts.backdropPaddingY * 2;
}
return 0;
}
- function measureLabelSize(ctx, fontSize, label) {
+ function measureLabelSize(ctx, lineHeight, label) {
if (helpers.isArray(label)) {
return {
w: helpers.longestText(ctx, ctx.font, label),
- h: (label.length * fontSize) + ((label.length - 1) * 1.5 * fontSize)
+ h: label.length * lineHeight
};
}
return {
w: ctx.measureText(label).width,
- h: fontSize
+ h: lineHeight
};
}
};
} else if (angle < min || angle > max) {
return {
- start: pos - size - 5,
+ start: pos - size,
end: pos
};
}
return {
start: pos,
- end: pos + size + 5
+ end: pos + size
};
}
* https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif
*/
- var plFont = getPointLabelFontOptions(scale);
- var paddingTop = getTickFontSize(scale) / 2;
+ var plFont = helpers.options._parseFont(scale.options.pointLabels);
// Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.
// Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points
- var largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);
var furthestLimits = {
- r: scale.width,
l: 0,
- t: scale.height,
- b: 0
+ r: scale.width,
+ t: 0,
+ b: scale.height
};
var furthestAngles = {};
var i, textSize, pointPosition;
- scale.ctx.font = plFont.font;
+ scale.ctx.font = plFont.string;
scale._pointLabelSizes = [];
var valueCount = getValueCount(scale);
for (i = 0; i < valueCount; i++) {
- pointPosition = scale.getPointPosition(i, largestPossibleRadius);
- textSize = measureLabelSize(scale.ctx, plFont.size, scale.pointLabels[i] || '');
+ pointPosition = scale.getPointPosition(i, scale.drawingArea + 5);
+ textSize = measureLabelSize(scale.ctx, plFont.lineHeight, scale.pointLabels[i] || '');
scale._pointLabelSizes[i] = textSize;
// Add quarter circle to make degree 0 mean top of circle
}
}
- if (paddingTop && -paddingTop < furthestLimits.t) {
- furthestLimits.t = -paddingTop;
- furthestAngles.t = 0;
- }
-
- scale.setReductions(largestPossibleRadius, furthestLimits, furthestAngles);
- }
-
- /**
- * Helper function to fit a radial linear scale with no point labels
- */
- function fit(scale) {
- var paddingTop = getTickFontSize(scale) / 2;
- var largestPossibleRadius = Math.min((scale.height - paddingTop) / 2, scale.width / 2);
- scale.drawingArea = Math.floor(largestPossibleRadius);
- scale.setCenterPoint(0, 0, paddingTop, 0);
+ scale.setReductions(scale.drawingArea, furthestLimits, furthestAngles);
}
function getTextAlignForAngle(angle) {
return 'right';
}
- function fillText(ctx, text, position, fontSize) {
- if (helpers.isArray(text)) {
- var y = position.y;
- var spacing = 1.5 * fontSize;
+ function fillText(ctx, text, position, lineHeight) {
+ var y = position.y + lineHeight / 2;
+ var i, ilen;
- for (var i = 0; i < text.length; ++i) {
+ if (helpers.isArray(text)) {
+ for (i = 0, ilen = text.length; i < ilen; ++i) {
ctx.fillText(text[i], position.x, y);
- y += spacing;
+ y += lineHeight;
}
} else {
- ctx.fillText(text, position.x, position.y);
+ ctx.fillText(text, position.x, y);
}
}
var pointLabelOpts = opts.pointLabels;
var lineWidth = helpers.valueOrDefault(angleLineOpts.lineWidth, gridLineOpts.lineWidth);
var lineColor = helpers.valueOrDefault(angleLineOpts.color, gridLineOpts.color);
+ var tickBackdropHeight = getTickBackdropHeight(opts);
ctx.save();
ctx.lineWidth = lineWidth;
var outerDistance = scale.getDistanceFromCenterForValue(opts.ticks.reverse ? scale.min : scale.max);
// Point Label Font
- var plFont = getPointLabelFontOptions(scale);
+ var plFont = helpers.options._parseFont(pointLabelOpts);
- ctx.font = plFont.font;
- ctx.textBaseline = 'top';
+ ctx.font = plFont.string;
+ ctx.textBaseline = 'middle';
for (var i = getValueCount(scale) - 1; i >= 0; i--) {
if (angleLineOpts.display && lineWidth && lineColor) {
}
if (pointLabelOpts.display) {
- // Extra 3px out for some label spacing
- var pointLabelPosition = scale.getPointPosition(i, outerDistance + 5);
+ // Extra pixels out for some label spacing
+ var extra = (i === 0 ? tickBackdropHeight / 2 : 0);
+ var pointLabelPosition = scale.getPointPosition(i, outerDistance + extra + 5);
// Keep this in loop since we may support array properties here
- var pointLabelFontColor = helpers.valueAtIndexOrDefault(pointLabelOpts.fontColor, i, globalDefaults.defaultFontColor);
+ var pointLabelFontColor = helpers.valueAtIndexOrDefault(pointLabelOpts.fontColor, i, defaults.global.defaultFontColor);
ctx.fillStyle = pointLabelFontColor;
var angleRadians = scale.getIndexAngle(i);
var angle = helpers.toDegrees(angleRadians);
ctx.textAlign = getTextAlignForAngle(angle);
adjustPointPositionForLabelHeight(angle, scale._pointLabelSizes[i], pointLabelPosition);
- fillText(ctx, scale.pointLabels[i] || '', pointLabelPosition, plFont.size);
+ fillText(ctx, scale.pointLabels[i] || '', pointLabelPosition, plFont.lineHeight);
}
}
ctx.restore();
var LinearRadialScale = Chart.LinearScaleBase.extend({
setDimensions: function() {
var me = this;
- var opts = me.options;
- var tickOpts = opts.ticks;
+
// Set the unconstrained dimension before label rotation
me.width = me.maxWidth;
me.height = me.maxHeight;
+ me.paddingTop = getTickBackdropHeight(me.options) / 2;
me.xCenter = Math.floor(me.width / 2);
- me.yCenter = Math.floor(me.height / 2);
-
- var minSize = helpers.min([me.height, me.width]);
- var tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
- me.drawingArea = opts.display ? (minSize / 2) - (tickFontSize / 2 + tickOpts.backdropPaddingY) : (minSize / 2);
+ me.yCenter = Math.floor((me.height - me.paddingTop) / 2);
+ me.drawingArea = Math.min(me.height - me.paddingTop, me.width) / 2;
},
determineDataLimits: function() {
var me = this;
me.handleTickRangeOptions();
},
getTickLimit: function() {
- var tickOpts = this.options.ticks;
- var tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
- return Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize)));
+ var opts = this.options;
+ var tickOpts = opts.ticks;
+ var tickBackdropHeight = getTickBackdropHeight(opts);
+ return Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(this.drawingArea / tickBackdropHeight));
},
convertTicksToLabels: function() {
var me = this;
return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
},
fit: function() {
- if (this.options.pointLabels.display) {
- fitWithPointLabels(this);
+ var me = this;
+ var opts = me.options;
+
+ if (opts.display && opts.pointLabels.display) {
+ fitWithPointLabels(me);
} else {
- fit(this);
+ me.setCenterPoint(0, 0, 0, 0);
}
},
/**
var radiusReductionLeft = furthestLimits.l / Math.sin(furthestAngles.l);
var radiusReductionRight = Math.max(furthestLimits.r - me.width, 0) / Math.sin(furthestAngles.r);
var radiusReductionTop = -furthestLimits.t / Math.cos(furthestAngles.t);
- var radiusReductionBottom = -Math.max(furthestLimits.b - me.height, 0) / Math.cos(furthestAngles.b);
+ var radiusReductionBottom = -Math.max(furthestLimits.b - (me.height - me.paddingTop), 0) / Math.cos(furthestAngles.b);
radiusReductionLeft = numberOrZero(radiusReductionLeft);
radiusReductionRight = numberOrZero(radiusReductionRight);
var maxRight = me.width - rightMovement - me.drawingArea;
var maxLeft = leftMovement + me.drawingArea;
var maxTop = topMovement + me.drawingArea;
- var maxBottom = me.height - bottomMovement - me.drawingArea;
+ var maxBottom = (me.height - me.paddingTop) - bottomMovement - me.drawingArea;
me.xCenter = Math.floor(((maxLeft + maxRight) / 2) + me.left);
- me.yCenter = Math.floor(((maxTop + maxBottom) / 2) + me.top);
+ me.yCenter = Math.floor(((maxTop + maxBottom) / 2) + me.top + me.paddingTop);
},
getIndexAngle: function(index) {
if (opts.display) {
var ctx = me.ctx;
var startAngle = this.getIndexAngle(0);
-
- // Tick Font
- var tickFontSize = valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
- var tickFontStyle = valueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);
- var tickFontFamily = valueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily);
- var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
+ var tickFont = helpers.options._parseFont(tickOpts);
if (opts.angleLines.display || opts.pointLabels.display) {
drawPointLabels(me);
}
if (tickOpts.display) {
- var tickFontColor = valueOrDefault(tickOpts.fontColor, globalDefaults.defaultFontColor);
- ctx.font = tickLabelFont;
+ var tickFontColor = valueOrDefault(tickOpts.fontColor, defaults.global.defaultFontColor);
+ ctx.font = tickFont.string;
ctx.save();
ctx.translate(me.xCenter, me.yCenter);
ctx.fillStyle = tickOpts.backdropColor;
ctx.fillRect(
-labelWidth / 2 - tickOpts.backdropPaddingX,
- -yCenterOffset - tickFontSize / 2 - tickOpts.backdropPaddingY,
+ -yCenterOffset - tickFont.size / 2 - tickOpts.backdropPaddingY,
labelWidth + tickOpts.backdropPaddingX * 2,
- tickFontSize + tickOpts.backdropPaddingY * 2
+ tickFont.size + tickOpts.backdropPaddingY * 2
);
}
}));
[
- {x: 256, y: 256, cppx: 256, cppy: 256, cpnx: 256, cpny: 256},
- {x: 256, y: 256, cppx: 256, cppy: 256, cpnx: 256, cpny: 256},
- {x: 256, y: 256, cppx: 256, cppy: 256, cpnx: 256, cpny: 256},
- {x: 256, y: 256, cppx: 256, cppy: 256, cpnx: 256, cpny: 256},
+ {x: 256, y: 260, cppx: 256, cppy: 260, cpnx: 256, cpny: 260},
+ {x: 256, y: 260, cppx: 256, cppy: 260, cpnx: 256, cpny: 260},
+ {x: 256, y: 260, cppx: 256, cppy: 260, cpnx: 256, cpny: 260},
+ {x: 256, y: 260, cppx: 256, cppy: 260, cpnx: 256, cpny: 260},
].forEach(function(expected, i) {
expect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);
expect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);
meta.controller.update();
[
- {x: 256, y: 117, cppx: 246, cppy: 117, cpnx: 272, cpny: 117},
- {x: 464, y: 256, cppx: 464, cppy: 248, cpnx: 464, cpny: 262},
- {x: 256, y: 256, cppx: 277, cppy: 256, cpnx: 250, cpny: 256},
- {x: 200, y: 256, cppx: 200, cppy: 259, cpnx: 200, cpny: 245},
+ {x: 256, y: 120, cppx: 246, cppy: 120, cpnx: 272, cpny: 120},
+ {x: 464, y: 260, cppx: 464, cppy: 252, cpnx: 464, cpny: 266},
+ {x: 256, y: 260, cppx: 277, cppy: 260, cpnx: 250, cpny: 260},
+ {x: 200, y: 260, cppx: 200, cppy: 264, cpnx: 200, cpny: 250},
].forEach(function(expected, i) {
expect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);
expect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);
// Since tension is now 0, we don't care about the control points
[
- {x: 256, y: 117},
- {x: 464, y: 256},
- {x: 256, y: 256},
- {x: 200, y: 256},
+ {x: 256, y: 120},
+ {x: 464, y: 260},
+ {x: 256, y: 260},
+ {x: 200, y: 260},
].forEach(function(expected, i) {
expect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);
expect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);
}));
expect(meta.data[0]._model.x).toBeCloseToPixel(256);
- expect(meta.data[0]._model.y).toBeCloseToPixel(117);
+ expect(meta.data[0]._model.y).toBeCloseToPixel(120);
expect(meta.data[0]._model.controlPointPreviousX).toBeCloseToPixel(241);
- expect(meta.data[0]._model.controlPointPreviousY).toBeCloseToPixel(117);
+ expect(meta.data[0]._model.controlPointPreviousY).toBeCloseToPixel(120);
expect(meta.data[0]._model.controlPointNextX).toBeCloseToPixel(281);
- expect(meta.data[0]._model.controlPointNextY).toBeCloseToPixel(117);
+ expect(meta.data[0]._model.controlPointNextY).toBeCloseToPixel(120);
expect(meta.data[0]._model).toEqual(jasmine.objectContaining({
radius: 2.2,
backgroundColor: 'rgb(0, 1, 3)',
// then we will reset and see that they moved
expect(meta.data[0]._model.y).toBeCloseToPixel(333);
expect(meta.data[1]._model.y).toBeCloseToPixel(183);
- expect(meta.data[2]._model.y).toBe(32);
- expect(meta.data[3]._model.y).toBe(484);
+ expect(meta.data[2]._model.y).toBeCloseToPixel(32);
+ expect(meta.data[3]._model.y).toBeCloseToPixel(482);
chart.reset();
// For a line chart, the animation state is the bottom
- expect(meta.data[0]._model.y).toBe(484);
- expect(meta.data[1]._model.y).toBe(484);
- expect(meta.data[2]._model.y).toBe(484);
- expect(meta.data[3]._model.y).toBe(484);
+ expect(meta.data[0]._model.y).toBeCloseToPixel(482);
+ expect(meta.data[1]._model.y).toBeCloseToPixel(482);
+ expect(meta.data[2]._model.y).toBeCloseToPixel(482);
+ expect(meta.data[3]._model.y).toBeCloseToPixel(482);
});
});
// actual label
labelString: '',
- // actual label
- lineHeight: 1.2,
-
// top/bottom padding
padding: {
top: 4,
var options = Chart.helpers.options;
describe('toLineHeight', function() {
+ var toLineHeight = options.toLineHeight;
+
it ('should support keyword values', function() {
- expect(options.toLineHeight('normal', 16)).toBe(16 * 1.2);
+ expect(toLineHeight('normal', 16)).toBe(16 * 1.2);
});
it ('should support unitless values', function() {
- expect(options.toLineHeight(1.4, 16)).toBe(16 * 1.4);
- expect(options.toLineHeight('1.4', 16)).toBe(16 * 1.4);
+ expect(toLineHeight(1.4, 16)).toBe(16 * 1.4);
+ expect(toLineHeight('1.4', 16)).toBe(16 * 1.4);
});
it ('should support length values', function() {
- expect(options.toLineHeight('42px', 16)).toBe(42);
- expect(options.toLineHeight('1.4em', 16)).toBe(16 * 1.4);
+ expect(toLineHeight('42px', 16)).toBe(42);
+ expect(toLineHeight('1.4em', 16)).toBe(16 * 1.4);
});
it ('should support percentage values', function() {
- expect(options.toLineHeight('140%', 16)).toBe(16 * 1.4);
+ expect(toLineHeight('140%', 16)).toBe(16 * 1.4);
});
it ('should fallback to default (1.2) for invalid values', function() {
- expect(options.toLineHeight(null, 16)).toBe(16 * 1.2);
- expect(options.toLineHeight(undefined, 16)).toBe(16 * 1.2);
- expect(options.toLineHeight('foobar', 16)).toBe(16 * 1.2);
+ expect(toLineHeight(null, 16)).toBe(16 * 1.2);
+ expect(toLineHeight(undefined, 16)).toBe(16 * 1.2);
+ expect(toLineHeight('foobar', 16)).toBe(16 * 1.2);
});
});
describe('toPadding', function() {
+ var toPadding = options.toPadding;
+
it ('should support number values', function() {
- expect(options.toPadding(4)).toEqual(
+ expect(toPadding(4)).toEqual(
{top: 4, right: 4, bottom: 4, left: 4, height: 8, width: 8});
- expect(options.toPadding(4.5)).toEqual(
+ expect(toPadding(4.5)).toEqual(
{top: 4.5, right: 4.5, bottom: 4.5, left: 4.5, height: 9, width: 9});
});
it ('should support string values', function() {
- expect(options.toPadding('4')).toEqual(
+ expect(toPadding('4')).toEqual(
{top: 4, right: 4, bottom: 4, left: 4, height: 8, width: 8});
- expect(options.toPadding('4.5')).toEqual(
+ expect(toPadding('4.5')).toEqual(
{top: 4.5, right: 4.5, bottom: 4.5, left: 4.5, height: 9, width: 9});
});
it ('should support object values', function() {
- expect(options.toPadding({top: 1, right: 2, bottom: 3, left: 4})).toEqual(
+ expect(toPadding({top: 1, right: 2, bottom: 3, left: 4})).toEqual(
{top: 1, right: 2, bottom: 3, left: 4, height: 4, width: 6});
- expect(options.toPadding({top: 1.5, right: 2.5, bottom: 3.5, left: 4.5})).toEqual(
+ expect(toPadding({top: 1.5, right: 2.5, bottom: 3.5, left: 4.5})).toEqual(
{top: 1.5, right: 2.5, bottom: 3.5, left: 4.5, height: 5, width: 7});
- expect(options.toPadding({top: '1', right: '2', bottom: '3', left: '4'})).toEqual(
+ expect(toPadding({top: '1', right: '2', bottom: '3', left: '4'})).toEqual(
{top: 1, right: 2, bottom: 3, left: 4, height: 4, width: 6});
});
it ('should fallback to 0 for invalid values', function() {
- expect(options.toPadding({top: 'foo', right: 'foo', bottom: 'foo', left: 'foo'})).toEqual(
+ expect(toPadding({top: 'foo', right: 'foo', bottom: 'foo', left: 'foo'})).toEqual(
{top: 0, right: 0, bottom: 0, left: 0, height: 0, width: 0});
- expect(options.toPadding({top: null, right: null, bottom: null, left: null})).toEqual(
+ expect(toPadding({top: null, right: null, bottom: null, left: null})).toEqual(
{top: 0, right: 0, bottom: 0, left: 0, height: 0, width: 0});
- expect(options.toPadding({})).toEqual(
+ expect(toPadding({})).toEqual(
{top: 0, right: 0, bottom: 0, left: 0, height: 0, width: 0});
- expect(options.toPadding('foo')).toEqual(
+ expect(toPadding('foo')).toEqual(
{top: 0, right: 0, bottom: 0, left: 0, height: 0, width: 0});
- expect(options.toPadding(null)).toEqual(
+ expect(toPadding(null)).toEqual(
{top: 0, right: 0, bottom: 0, left: 0, height: 0, width: 0});
- expect(options.toPadding(undefined)).toEqual(
+ expect(toPadding(undefined)).toEqual(
{top: 0, right: 0, bottom: 0, left: 0, height: 0, width: 0});
});
});
+ describe('_parseFont', function() {
+ var parseFont = options._parseFont;
+
+ it ('should return a font with default values', function() {
+ var global = Chart.defaults.global;
+
+ Chart.defaults.global = {
+ defaultFontFamily: 'foobar',
+ defaultFontSize: 42,
+ defaultFontStyle: 'xxxyyy',
+ defaultLineHeight: 1.5
+ };
+
+ expect(parseFont({})).toEqual({
+ family: 'foobar',
+ lineHeight: 63,
+ size: 42,
+ string: 'xxxyyy 42px foobar',
+ style: 'xxxyyy',
+ weight: null
+ });
+
+ Chart.defaults.global = global;
+ });
+ it ('should return a font with given values', function() {
+ expect(parseFont({
+ fontFamily: 'bla',
+ lineHeight: 8,
+ fontSize: 21,
+ fontStyle: 'zzz'
+ })).toEqual({
+ family: 'bla',
+ lineHeight: 8 * 21,
+ size: 21,
+ string: 'zzz 21px bla',
+ style: 'zzz',
+ weight: null
+ });
+ });
+ it('should return null as a font string if fontSize or fontFamily are missing', function() {
+ var global = Chart.defaults.global;
+
+ Chart.defaults.global = {};
+
+ expect(parseFont({
+ fontStyle: 'italic',
+ fontSize: 12
+ }).string).toBeNull();
+ expect(parseFont({
+ fontStyle: 'italic',
+ fontFamily: 'serif'
+ }).string).toBeNull();
+
+ Chart.defaults.global = global;
+ });
+ it('fontStyle should be optional for font strings', function() {
+ var global = Chart.defaults.global;
+
+ Chart.defaults.global = {};
+
+ expect(parseFont({
+ fontSize: 12,
+ fontFamily: 'serif'
+ }).string).toBe('12px serif');
+
+ Chart.defaults.global = global;
+ });
+ });
+
describe('resolve', function() {
+ var resolve = options.resolve;
+
it ('should fallback to the first defined input', function() {
- expect(options.resolve([42])).toBe(42);
- expect(options.resolve([42, 'foo'])).toBe(42);
- expect(options.resolve([undefined, 42, 'foo'])).toBe(42);
- expect(options.resolve([42, 'foo', undefined])).toBe(42);
- expect(options.resolve([undefined])).toBe(undefined);
+ expect(resolve([42])).toBe(42);
+ expect(resolve([42, 'foo'])).toBe(42);
+ expect(resolve([undefined, 42, 'foo'])).toBe(42);
+ expect(resolve([42, 'foo', undefined])).toBe(42);
+ expect(resolve([undefined])).toBe(undefined);
});
it ('should correctly handle empty values (null, 0, "")', function() {
- expect(options.resolve([0, 'foo'])).toBe(0);
- expect(options.resolve(['', 'foo'])).toBe('');
- expect(options.resolve([null, 'foo'])).toBe(null);
+ expect(resolve([0, 'foo'])).toBe(0);
+ expect(resolve(['', 'foo'])).toBe('');
+ expect(resolve([null, 'foo'])).toBe(null);
});
it ('should support indexable options if index is provided', function() {
var input = [42, 'foo', 'bar'];
- expect(options.resolve([input], undefined, 0)).toBe(42);
- expect(options.resolve([input], undefined, 1)).toBe('foo');
- expect(options.resolve([input], undefined, 2)).toBe('bar');
+ expect(resolve([input], undefined, 0)).toBe(42);
+ expect(resolve([input], undefined, 1)).toBe('foo');
+ expect(resolve([input], undefined, 2)).toBe('bar');
});
it ('should fallback if an indexable option value is undefined', function() {
var input = [42, undefined, 'bar'];
- expect(options.resolve([input], undefined, 5)).toBe(undefined);
- expect(options.resolve([input, 'foo'], undefined, 1)).toBe('foo');
- expect(options.resolve([input, 'foo'], undefined, 5)).toBe('foo');
+ expect(resolve([input], undefined, 5)).toBe(undefined);
+ expect(resolve([input, 'foo'], undefined, 1)).toBe('foo');
+ expect(resolve([input, 'foo'], undefined, 5)).toBe('foo');
});
it ('should not handle indexable options if index is undefined', function() {
var array = [42, 'foo', 'bar'];
- expect(options.resolve([array])).toBe(array);
- expect(options.resolve([array], undefined, undefined)).toBe(array);
+ expect(resolve([array])).toBe(array);
+ expect(resolve([array], undefined, undefined)).toBe(array);
});
it ('should support scriptable options if context is provided', function() {
var input = function(context) {
return context.v * 2;
};
- expect(options.resolve([42], {v: 42})).toBe(42);
- expect(options.resolve([input], {v: 42})).toBe(84);
+ expect(resolve([42], {v: 42})).toBe(42);
+ expect(resolve([input], {v: 42})).toBe(84);
});
it ('should fallback if a scriptable option returns undefined', function() {
var input = function() {};
- expect(options.resolve([input], {v: 42})).toBe(undefined);
- expect(options.resolve([input, 'foo'], {v: 42})).toBe('foo');
- expect(options.resolve([input, undefined, 'foo'], {v: 42})).toBe('foo');
+ expect(resolve([input], {v: 42})).toBe(undefined);
+ expect(resolve([input, 'foo'], {v: 42})).toBe('foo');
+ expect(resolve([input, undefined, 'foo'], {v: 42})).toBe('foo');
});
it ('should not handle scriptable options if context is undefined', function() {
var input = function(context) {
return context.v * 2;
};
- expect(options.resolve([input])).toBe(input);
- expect(options.resolve([input], undefined)).toBe(input);
+ expect(resolve([input])).toBe(input);
+ expect(resolve([input], undefined)).toBe(input);
});
it ('should handle scriptable and indexable option', function() {
var input = function(context) {
return [context.v, undefined, 'bar'];
};
- expect(options.resolve([input, 'foo'], {v: 42}, 0)).toBe(42);
- expect(options.resolve([input, 'foo'], {v: 42}, 1)).toBe('foo');
- expect(options.resolve([input, 'foo'], {v: 42}, 5)).toBe('foo');
- expect(options.resolve([input, ['foo', 'bar']], {v: 42}, 1)).toBe('bar');
+ expect(resolve([input, 'foo'], {v: 42}, 0)).toBe(42);
+ expect(resolve([input, 'foo'], {v: 42}, 1)).toBe('foo');
+ expect(resolve([input, 'foo'], {v: 42}, 5)).toBe('foo');
+ expect(resolve([input, ['foo', 'bar']], {v: 42}, 1)).toBe('bar');
});
});
});
expect(chart.legend.left).toBeCloseToPixel(0);
expect(chart.legend.top).toBeCloseToPixel(6);
expect(chart.legend.width).toBeCloseToPixel(128);
- expect(chart.legend.height).toBeCloseToPixel(478);
+ expect(chart.legend.height).toBeCloseToPixel(476);
expect(chart.legend.legendHitBoxes.length).toBe(22);
[
fullWidth: true,
weight: 2000,
fontStyle: 'bold',
- lineHeight: 1.2,
padding: 10,
text: ''
});
expect(yScale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(77);
expect(yScale.getValueForPixel(77)).toBe(0);
- expect(yScale.getPixelForValue(0, 4, 0)).toBeCloseToPixel(439);
- expect(yScale.getValueForPixel(439)).toBe(4);
+ expect(yScale.getPixelForValue(0, 4, 0)).toBeCloseToPixel(437);
+ expect(yScale.getValueForPixel(437)).toBe(4);
});
it ('should get the correct pixel for a value when vertical and zoomed', function() {
chart.update();
expect(yScale.getPixelForValue(0, 1, 0)).toBeCloseToPixel(107);
- expect(yScale.getPixelForValue(0, 3, 0)).toBeCloseToPixel(409);
+ expect(yScale.getPixelForValue(0, 3, 0)).toBeCloseToPixel(407);
});
});
expect(yScale.getPixelForValue(-1, 0, 0)).toBeCloseToPixel(484); // left + paddingLeft
expect(yScale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(258); // halfway*/
- expect(yScale.getValueForPixel(32)).toBe(1);
- expect(yScale.getValueForPixel(484)).toBe(-1);
- expect(yScale.getValueForPixel(258)).toBe(0);
+ expect(yScale.getValueForPixel(32)).toBeCloseTo(1, 1e-2);
+ expect(yScale.getValueForPixel(484)).toBeCloseTo(-1, 1e-2);
+ expect(yScale.getValueForPixel(258)).toBeCloseTo(0, 1e-2);
});
it('should fit correctly', function() {
expect(xScale.paddingLeft).toBeCloseToPixel(0);
expect(xScale.paddingRight).toBeCloseToPixel(0);
expect(xScale.width).toBeCloseToPixel(468 - 6); // minus lineSpace
- expect(xScale.height).toBeCloseToPixel(28);
+ expect(xScale.height).toBeCloseToPixel(30);
var yScale = chart.scales.yScale0;
expect(yScale.paddingTop).toBeCloseToPixel(0);
expect(yScale.paddingLeft).toBeCloseToPixel(0);
expect(yScale.paddingRight).toBeCloseToPixel(0);
expect(yScale.width).toBeCloseToPixel(30 + 6); // plus lineSpace
- expect(yScale.height).toBeCloseToPixel(452);
+ expect(yScale.height).toBeCloseToPixel(450);
// Extra size when scale label showing
xScale.options.scaleLabel.display = true;
expect(xScale.paddingLeft).toBeCloseToPixel(0);
expect(xScale.paddingRight).toBeCloseToPixel(0);
expect(xScale.width).toBeCloseToPixel(440);
- expect(xScale.height).toBeCloseToPixel(50);
+ expect(xScale.height).toBeCloseToPixel(53);
expect(yScale.paddingTop).toBeCloseToPixel(0);
expect(yScale.paddingBottom).toBeCloseToPixel(0);
expect(yScale.paddingLeft).toBeCloseToPixel(0);
expect(yScale.paddingRight).toBeCloseToPixel(0);
expect(yScale.width).toBeCloseToPixel(58);
- expect(yScale.height).toBeCloseToPixel(430);
+ expect(yScale.height).toBeCloseToPixel(427);
});
it('should fit correctly when display is turned off', function() {
}
});
- expect(chart.scale.drawingArea).toBe(232);
+ expect(chart.scale.drawingArea).toBe(227);
expect(chart.scale.xCenter).toBe(256);
- expect(chart.scale.yCenter).toBe(279);
+ expect(chart.scale.yCenter).toBe(284);
});
it('should correctly get the label for a given data index', function() {
});
expect(chart.scale.getDistanceFromCenterForValue(chart.scale.min)).toBe(0);
- expect(chart.scale.getDistanceFromCenterForValue(chart.scale.max)).toBe(232);
+ expect(chart.scale.getDistanceFromCenterForValue(chart.scale.max)).toBe(227);
var position = chart.scale.getPointPositionForValue(1, 5);
expect(position.x).toBeCloseToPixel(270);
- expect(position.y).toBeCloseToPixel(275);
+ expect(position.y).toBeCloseToPixel(278);
chart.scale.options.ticks.reverse = true;
chart.update();
- expect(chart.scale.getDistanceFromCenterForValue(chart.scale.min)).toBe(232);
+ expect(chart.scale.getDistanceFromCenterForValue(chart.scale.min)).toBe(227);
expect(chart.scale.getDistanceFromCenterForValue(chart.scale.max)).toBe(0);
});