From 3cd21c805344bc8bb366275230c05aa74645b651 Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Sun, 29 May 2016 10:16:47 -0400 Subject: [PATCH] Linear and RadialLinear scales now derive from a common base class --- src/chart.js | 1 + src/scales/scale.linear.js | 128 ++------------ src/scales/scale.linearbase.js | 127 ++++++++++++++ src/scales/scale.radialLinear.js | 284 +++++++++++++------------------ 4 files changed, 264 insertions(+), 276 deletions(-) create mode 100644 src/scales/scale.linearbase.js diff --git a/src/chart.js b/src/chart.js index 90b9c77ee..f992a9e1c 100644 --- a/src/chart.js +++ b/src/chart.js @@ -18,6 +18,7 @@ require('./elements/element.line')(Chart); require('./elements/element.point')(Chart); require('./elements/element.rectangle')(Chart); +require('./scales/scale.linearbase.js')(Chart); require('./scales/scale.category')(Chart); require('./scales/scale.linear')(Chart); require('./scales/scale.logarithmic')(Chart); diff --git a/src/scales/scale.linear.js b/src/scales/scale.linear.js index f6363d44c..c8905769b 100644 --- a/src/scales/scale.linear.js +++ b/src/scales/scale.linear.js @@ -35,7 +35,7 @@ module.exports = function(Chart) { } }; - var LinearScale = Chart.Scale.extend({ + var LinearScale = Chart.LinearScaleBase.extend({ determineDataLimits: function() { var _this = this; var opts = _this.options; @@ -130,129 +130,35 @@ module.exports = function(Chart) { }); } - // If we are forcing it to begin at 0, but 0 will already be rendered on the chart, - // do nothing since that would make the chart weird. If the user really wants a weird chart - // axis, they can manually override it - if (tickOpts.beginAtZero) { - var minSign = helpers.sign(_this.min); - var maxSign = helpers.sign(_this.max); - - if (minSign < 0 && maxSign < 0) { - // move the top up to 0 - _this.max = 0; - } else if (minSign > 0 && maxSign > 0) { - // move the botttom down to 0 - _this.min = 0; - } - } - - if (tickOpts.min !== undefined) { - _this.min = tickOpts.min; - } else if (tickOpts.suggestedMin !== undefined) { - _this.min = Math.min(_this.min, tickOpts.suggestedMin); - } - - if (tickOpts.max !== undefined) { - _this.max = tickOpts.max; - } else if (tickOpts.suggestedMax !== undefined) { - _this.max = Math.max(_this.max, tickOpts.suggestedMax); - } - - if (_this.min === _this.max) { - _this.max++; - - if (!tickOpts.beginAtZero) { - _this.min--; - } - } + // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero + this.handleTickRangeOptions(); }, - buildTicks: function() { - var _this = this; - var opts = _this.options; - var tickOpts = opts.ticks; - var getValueOrDefault = helpers.getValueOrDefault; - var isHorizontal = _this.isHorizontal(); - - var ticks = _this.ticks = []; - - // Figure out what the max number of ticks we can support it is based on the size of - // the axis area. For now, we say that the minimum tick spacing in pixels must be 50 - // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on - // the graph - + getTickLimit: function() { var maxTicks; + var me = this; + var tickOpts = me.options.ticks; - if (isHorizontal) { - maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(_this.width / 50)); + if (me.isHorizontal()) { + maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.width / 50)); } else { // The factor of 2 used to scale the font size has been experimentally determined. - var tickFontSize = getValueOrDefault(tickOpts.fontSize, Chart.defaults.global.defaultFontSize); - maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(_this.height / (2 * tickFontSize))); + var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, Chart.defaults.global.defaultFontSize); + maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.height / (2 * tickFontSize))); } - // Make sure we always have at least 2 ticks - maxTicks = Math.max(2, maxTicks); - - // To get a "nice" value for the tick spacing, we will use the appropriately named - // "nice number" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks - // for details. - - var spacing; - var fixedStepSizeSet = (tickOpts.fixedStepSize && tickOpts.fixedStepSize > 0) || (tickOpts.stepSize && tickOpts.stepSize > 0); - if (fixedStepSizeSet) { - spacing = getValueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize); - } else { - var niceRange = helpers.niceNum(_this.max - _this.min, false); - spacing = helpers.niceNum(niceRange / (maxTicks - 1), true); - } - var niceMin = Math.floor(_this.min / spacing) * spacing; - var niceMax = Math.ceil(_this.max / spacing) * spacing; - var numSpaces = (niceMax - niceMin) / spacing; - - // If very close to our rounded value, use it. - if (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) { - numSpaces = Math.round(numSpaces); - } else { - numSpaces = Math.ceil(numSpaces); - } - - // Put the values into the ticks array - ticks.push(tickOpts.min !== undefined ? tickOpts.min : niceMin); - for (var j = 1; j < numSpaces; ++j) { - ticks.push(niceMin + (j * spacing)); - } - ticks.push(tickOpts.max !== undefined ? tickOpts.max : niceMax); - - if (!isHorizontal) { + return maxTicks; + }, + // Called after the ticks are built. We need + handleDirectionalChanges: function() { + var me = this; + if (!me.isHorizontal()) { // We are in a vertical orientation. The top value is the highest. So reverse the array - ticks.reverse(); - } - - // At this point, we need to update our max and min given the tick values since we have expanded the - // range of the scale - _this.max = helpers.max(ticks); - _this.min = helpers.min(ticks); - - if (tickOpts.reverse) { - ticks.reverse(); - - _this.start = _this.max; - _this.end = _this.min; - } else { - _this.start = _this.min; - _this.end = _this.max; + me.ticks.reverse(); } }, getLabelForIndex: function(index, datasetIndex) { return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]); }, - convertTicksToLabels: function() { - var _this = this; - _this.ticksAsNumbers = _this.ticks.slice(); - _this.zeroLineIndex = _this.ticks.indexOf(0); - - Chart.Scale.prototype.convertTicksToLabels.call(_this); - }, // Utils getPixelForValue: function(value, index, datasetIndex, includeOffset) { // This must be called after fit has been run so that diff --git a/src/scales/scale.linearbase.js b/src/scales/scale.linearbase.js new file mode 100644 index 000000000..d127c88f8 --- /dev/null +++ b/src/scales/scale.linearbase.js @@ -0,0 +1,127 @@ +"use strict"; + +module.exports = function(Chart) { + + var helpers = Chart.helpers, + noop = helpers.noop; + + Chart.LinearScaleBase = Chart.Scale.extend({ + handleTickRangeOptions: function() { + var _this = this; + var opts = _this.options; + var tickOpts = opts.ticks; + + // If we are forcing it to begin at 0, but 0 will already be rendered on the chart, + // do nothing since that would make the chart weird. If the user really wants a weird chart + // axis, they can manually override it + if (tickOpts.beginAtZero) { + var minSign = helpers.sign(_this.min); + var maxSign = helpers.sign(_this.max); + + if (minSign < 0 && maxSign < 0) { + // move the top up to 0 + _this.max = 0; + } else if (minSign > 0 && maxSign > 0) { + // move the botttom down to 0 + _this.min = 0; + } + } + + if (tickOpts.min !== undefined) { + _this.min = tickOpts.min; + } else if (tickOpts.suggestedMin !== undefined) { + _this.min = Math.min(_this.min, tickOpts.suggestedMin); + } + + if (tickOpts.max !== undefined) { + _this.max = tickOpts.max; + } else if (tickOpts.suggestedMax !== undefined) { + _this.max = Math.max(_this.max, tickOpts.suggestedMax); + } + + if (_this.min === _this.max) { + _this.max++; + + if (!tickOpts.beginAtZero) { + _this.min--; + } + } + }, + getTickLimit: noop, + handleDirectionalChanges: noop, + + buildTicks: function() { + var _this = this; + var opts = _this.options; + var tickOpts = opts.ticks; + var getValueOrDefault = helpers.getValueOrDefault; + var isHorizontal = _this.isHorizontal(); + + var ticks = _this.ticks = []; + + // Figure out what the max number of ticks we can support it is based on the size of + // the axis area. For now, we say that the minimum tick spacing in pixels must be 50 + // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on + // the graph + + var maxTicks = this.getTickLimit(); + + // Make sure we always have at least 2 ticks + maxTicks = Math.max(2, maxTicks); + + // To get a "nice" value for the tick spacing, we will use the appropriately named + // "nice number" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks + // for details. + + var spacing; + var fixedStepSizeSet = (tickOpts.fixedStepSize && tickOpts.fixedStepSize > 0) || (tickOpts.stepSize && tickOpts.stepSize > 0); + if (fixedStepSizeSet) { + spacing = getValueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize); + } else { + var niceRange = helpers.niceNum(_this.max - _this.min, false); + spacing = helpers.niceNum(niceRange / (maxTicks - 1), true); + } + var niceMin = Math.floor(_this.min / spacing) * spacing; + var niceMax = Math.ceil(_this.max / spacing) * spacing; + var numSpaces = (niceMax - niceMin) / spacing; + + // If very close to our rounded value, use it. + if (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) { + numSpaces = Math.round(numSpaces); + } else { + numSpaces = Math.ceil(numSpaces); + } + + // Put the values into the ticks array + ticks.push(tickOpts.min !== undefined ? tickOpts.min : niceMin); + for (var j = 1; j < numSpaces; ++j) { + ticks.push(niceMin + (j * spacing)); + } + ticks.push(tickOpts.max !== undefined ? tickOpts.max : niceMax); + + this.handleDirectionalChanges(); + + // At this point, we need to update our max and min given the tick values since we have expanded the + // range of the scale + _this.max = helpers.max(ticks); + _this.min = helpers.min(ticks); + + if (tickOpts.reverse) { + ticks.reverse(); + + _this.start = _this.max; + _this.end = _this.min; + } else { + _this.start = _this.min; + _this.end = _this.max; + } + }, + convertTicksToLabels: function() { + var _this = this; + _this.ticksAsNumbers = _this.ticks.slice(); + _this.zeroLineIndex = _this.ticks.indexOf(0); + + Chart.Scale.prototype.convertTicksToLabels.call(_this); + }, + }); +}; \ No newline at end of file diff --git a/src/scales/scale.radialLinear.js b/src/scales/scale.radialLinear.js index 017c0c747..3cb238493 100644 --- a/src/scales/scale.radialLinear.js +++ b/src/scales/scale.radialLinear.js @@ -45,136 +45,71 @@ module.exports = function(Chart) { } }; - var LinearRadialScale = Chart.Scale.extend({ + var LinearRadialScale = Chart.LinearScaleBase.extend({ getValueCount: function() { return this.chart.data.labels.length; }, setDimensions: function() { - var options = this.options; + var me = this; + var opts = me.options; + var tickOpts = opts.ticks; // Set the unconstrained dimension before label rotation - this.width = this.maxWidth; - this.height = this.maxHeight; - this.xCenter = Math.round(this.width / 2); - this.yCenter = Math.round(this.height / 2); - - var minSize = helpers.min([this.height, this.width]); - var tickFontSize = helpers.getValueOrDefault(options.ticks.fontSize, globalDefaults.defaultFontSize); - this.drawingArea = (options.display) ? (minSize / 2) - (tickFontSize / 2 + options.ticks.backdropPaddingY) : (minSize / 2); + me.width = me.maxWidth; + me.height = me.maxHeight; + me.xCenter = Math.round(me.width / 2); + me.yCenter = Math.round(me.height / 2); + + var minSize = helpers.min([me.height, me.width]); + var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize); + me.drawingArea = opts.display ? (minSize / 2) - (tickFontSize / 2 + tickOpts.backdropPaddingY) : (minSize / 2); }, determineDataLimits: function() { - this.min = null; - this.max = null; + var me = this; + var chart = me.chart; + me.min = null; + me.max = null; + + + helpers.each(chart.data.datasets, function(dataset, datasetIndex) { + if (chart.isDatasetVisible(datasetIndex)) { + var meta = chart.getDatasetMeta(datasetIndex); - helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) { - if (this.chart.isDatasetVisible(datasetIndex)) { - var meta = this.chart.getDatasetMeta(datasetIndex); helpers.each(dataset.data, function(rawValue, index) { - var value = +this.getRightValue(rawValue); + var value = +me.getRightValue(rawValue); if (isNaN(value) || meta.data[index].hidden) { return; } - if (this.min === null) { - this.min = value; - } else if (value < this.min) { - this.min = value; + if (me.min === null) { + me.min = value; + } else if (value < me.min) { + me.min = value; } - if (this.max === null) { - this.max = value; - } else if (value > this.max) { - this.max = value; + if (me.max === null) { + me.max = value; + } else if (value > me.max) { + me.max = value; } - }, this); - } - }, this); - - // If we are forcing it to begin at 0, but 0 will already be rendered on the chart, - // do nothing since that would make the chart weird. If the user really wants a weird chart - // axis, they can manually override it - if (this.options.ticks.beginAtZero) { - var minSign = helpers.sign(this.min); - var maxSign = helpers.sign(this.max); - - if (minSign < 0 && maxSign < 0) { - // move the top up to 0 - this.max = 0; - } else if (minSign > 0 && maxSign > 0) { - // move the botttom down to 0 - this.min = 0; + }); } - } - - if (this.options.ticks.min !== undefined) { - this.min = this.options.ticks.min; - } else if (this.options.ticks.suggestedMin !== undefined) { - this.min = Math.min(this.min, this.options.ticks.suggestedMin); - } - - if (this.options.ticks.max !== undefined) { - this.max = this.options.ticks.max; - } else if (this.options.ticks.suggestedMax !== undefined) { - this.max = Math.max(this.max, this.options.ticks.suggestedMax); - } + }); - if (this.min === this.max) { - this.min--; - this.max++; - } + // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero + me.handleTickRangeOptions(); }, - buildTicks: function() { - - - this.ticks = []; - - // Figure out what the max number of ticks we can support it is based on the size of - // the axis area. For now, we say that the minimum tick spacing in pixels must be 50 - // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on - // the graph - var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, globalDefaults.defaultFontSize); - var maxTicks = Math.min(this.options.ticks.maxTicksLimit ? this.options.ticks.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize))); - maxTicks = Math.max(2, maxTicks); // Make sure we always have at least 2 ticks - - // To get a "nice" value for the tick spacing, we will use the appropriately named - // "nice number" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks - // for details. - - var niceRange = helpers.niceNum(this.max - this.min, false); - var spacing = helpers.niceNum(niceRange / (maxTicks - 1), true); - var niceMin = Math.floor(this.min / spacing) * spacing; - var niceMax = Math.ceil(this.max / spacing) * spacing; - - var numSpaces = Math.ceil((niceMax - niceMin) / spacing); - - // Put the values into the ticks array - this.ticks.push(this.options.ticks.min !== undefined ? this.options.ticks.min : niceMin); - for (var j = 1; j < numSpaces; ++j) { - this.ticks.push(niceMin + (j * spacing)); - } - this.ticks.push(this.options.ticks.max !== undefined ? this.options.ticks.max : niceMax); - - // At this point, we need to update our max and min given the tick values since we have expanded the - // range of the scale - this.max = helpers.max(this.ticks); - this.min = helpers.min(this.ticks); - - if (this.options.ticks.reverse) { - this.ticks.reverse(); - - this.start = this.max; - this.end = this.min; - } else { - this.start = this.min; - this.end = this.max; - } - - this.zeroLineIndex = this.ticks.indexOf(0); + getTickLimit: function() { + var me = this; + var tickOpts = me.options.ticks; + var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize); + return Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.drawingArea / (1.5 * tickFontSize))); }, convertTicksToLabels: function() { - Chart.Scale.prototype.convertTicksToLabels.call(this); + var me = this; + Chart.LinearScaleBase.prototype.convertTicksToLabels.call(me); // Point labels - this.pointLabels = this.chart.data.labels.map(this.options.pointLabels.callback, this); + me.pointLabels = me.chart.data.labels.map(me.options.pointLabels.callback, me); }, getLabelForIndex: function(index, datasetIndex) { return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]); @@ -283,13 +218,13 @@ module.exports = function(Chart) { this.setCenterPoint(radiusReductionLeft, radiusReductionRight); }, setCenterPoint: function(leftMovement, rightMovement) { + var me = this; + var maxRight = me.width - rightMovement - me.drawingArea, + maxLeft = leftMovement + me.drawingArea; - var maxRight = this.width - rightMovement - this.drawingArea, - maxLeft = leftMovement + this.drawingArea; - - this.xCenter = Math.round(((maxLeft + maxRight) / 2) + this.left); + me.xCenter = Math.round(((maxLeft + maxRight) / 2) + me.left); // Always vertically in the centre as the text height doesn't change - this.yCenter = Math.round((this.height / 2) + this.top); + me.yCenter = Math.round((me.height / 2) + me.top); }, getIndexAngle: function(index) { @@ -299,23 +234,26 @@ module.exports = function(Chart) { return index * angleMultiplier - (Math.PI / 2); }, getDistanceFromCenterForValue: function(value) { + var me = this; + if (value === null) { return 0; // null always in center } // Take into account half font size + the yPadding of the top value - var scalingFactor = this.drawingArea / (this.max - this.min); - if (this.options.reverse) { - return (this.max - value) * scalingFactor; + var scalingFactor = me.drawingArea / (me.max - me.min); + if (me.options.reverse) { + return (me.max - value) * scalingFactor; } else { - return (value - this.min) * scalingFactor; + return (value - me.min) * scalingFactor; } }, getPointPosition: function(index, distanceFromCenter) { - var thisAngle = this.getIndexAngle(index); + var me = this; + var thisAngle = me.getIndexAngle(index); return { - x: Math.round(Math.cos(thisAngle) * distanceFromCenter) + this.xCenter, - y: Math.round(Math.sin(thisAngle) * distanceFromCenter) + this.yCenter + x: Math.round(Math.cos(thisAngle) * distanceFromCenter) + me.xCenter, + y: Math.round(Math.sin(thisAngle) * distanceFromCenter) + me.yCenter }; }, getPointPositionForValue: function(index, value) { @@ -335,30 +273,45 @@ module.exports = function(Chart) { }, draw: function() { - if (this.options.display) { - var ctx = this.ctx; - helpers.each(this.ticks, function(label, index) { + var me = this; + var opts = me.options; + var gridLineOpts = opts.gridLines; + var tickOpts = opts.ticks; + var angleLineOpts = opts.angleLines; + var pointLabelOpts = opts.pointLabels; + var getValueOrDefault = helpers.getValueOrDefault; + + if (opts.display) { + var ctx = me.ctx; + + // Tick Font + var tickFontSize = getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize); + var tickFontStyle = getValueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle); + var tickFontFamily = getValueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily); + var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily); + + helpers.each(me.ticks, function(label, index) { // Don't draw a centre value (if it is minimum) - if (index > 0 || this.options.reverse) { - var yCenterOffset = this.getDistanceFromCenterForValue(this.ticks[index]); - var yHeight = this.yCenter - yCenterOffset; + if (index > 0 || opts.reverse) { + var yCenterOffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]); + var yHeight = me.yCenter - yCenterOffset; // Draw circular lines around the scale - if (this.options.gridLines.display) { - ctx.strokeStyle = this.options.gridLines.color; - ctx.lineWidth = this.options.gridLines.lineWidth; + if (gridLineOpts.display) { + ctx.strokeStyle = gridLineOpts.color; + ctx.lineWidth = gridLineOpts.lineWidth; - if (this.options.lineArc) { + if (opts.lineArc) { // Draw circular arcs between the points ctx.beginPath(); - ctx.arc(this.xCenter, this.yCenter, yCenterOffset, 0, Math.PI * 2); + ctx.arc(me.xCenter, me.yCenter, yCenterOffset, 0, Math.PI * 2); ctx.closePath(); ctx.stroke(); } else { // Draw straight lines connecting each index ctx.beginPath(); - for (var i = 0; i < this.getValueCount(); i++) { - var pointPosition = this.getPointPosition(i, this.getDistanceFromCenterForValue(this.ticks[index])); + for (var i = 0; i < me.getValueCount(); i++) { + var pointPosition = me.getPointPosition(i, yCenterOffset); if (i === 0) { ctx.moveTo(pointPosition.x, pointPosition.y); } else { @@ -370,60 +323,61 @@ module.exports = function(Chart) { } } - if (this.options.ticks.display) { - var tickFontColor = helpers.getValueOrDefault(this.options.ticks.fontColor, globalDefaults.defaultFontColor); - var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, globalDefaults.defaultFontSize); - var tickFontStyle = helpers.getValueOrDefault(this.options.ticks.fontStyle, globalDefaults.defaultFontStyle); - var tickFontFamily = helpers.getValueOrDefault(this.options.ticks.fontFamily, globalDefaults.defaultFontFamily); - var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily); + if (tickOpts.display) { + var tickFontColor = getValueOrDefault(tickOpts.fontColor, globalDefaults.defaultFontColor); ctx.font = tickLabelFont; - if (this.options.ticks.showLabelBackdrop) { + if (tickOpts.showLabelBackdrop) { var labelWidth = ctx.measureText(label).width; - ctx.fillStyle = this.options.ticks.backdropColor; + ctx.fillStyle = tickOpts.backdropColor; ctx.fillRect( - this.xCenter - labelWidth / 2 - this.options.ticks.backdropPaddingX, - yHeight - tickFontSize / 2 - this.options.ticks.backdropPaddingY, - labelWidth + this.options.ticks.backdropPaddingX * 2, - tickFontSize + this.options.ticks.backdropPaddingY * 2 + me.xCenter - labelWidth / 2 - tickOpts.backdropPaddingX, + yHeight - tickFontSize / 2 - tickOpts.backdropPaddingY, + labelWidth + tickOpts.backdropPaddingX * 2, + tickFontSize + tickOpts.backdropPaddingY * 2 ); } ctx.textAlign = 'center'; ctx.textBaseline = "middle"; ctx.fillStyle = tickFontColor; - ctx.fillText(label, this.xCenter, yHeight); + ctx.fillText(label, me.xCenter, yHeight); } } - }, this); - - if (!this.options.lineArc) { - ctx.lineWidth = this.options.angleLines.lineWidth; - ctx.strokeStyle = this.options.angleLines.color; - - for (var i = this.getValueCount() - 1; i >= 0; i--) { - if (this.options.angleLines.display) { - var outerPosition = this.getPointPosition(i, this.getDistanceFromCenterForValue(this.options.reverse ? this.min : this.max)); + }); + + if (!opts.lineArc) { + ctx.lineWidth = angleLineOpts.lineWidth; + ctx.strokeStyle = angleLineOpts.color; + + var outerDistance = me.getDistanceFromCenterForValue(opts.reverse ? me.min : me.max); + + // Point Label Font + var pointLabelFontSize = getValueOrDefault(pointLabelOpts.fontSize, globalDefaults.defaultFontSize); + var pointLabeFontStyle = getValueOrDefault(pointLabelOpts.fontStyle, globalDefaults.defaultFontStyle); + var pointLabeFontFamily = getValueOrDefault(pointLabelOpts, globalDefaults.defaultFontFamily); + var pointLabeFont = helpers.fontString(pointLabelFontSize, pointLabeFontStyle, pointLabeFontFamily); + + for (var i = me.getValueCount() - 1; i >= 0; i--) { + if (angleLineOpts.display) { + var outerPosition = me.getPointPosition(i, outerDistance); ctx.beginPath(); - ctx.moveTo(this.xCenter, this.yCenter); + ctx.moveTo(me.xCenter, me.yCenter); ctx.lineTo(outerPosition.x, outerPosition.y); ctx.stroke(); ctx.closePath(); } // Extra 3px out for some label spacing - var pointLabelPosition = this.getPointPosition(i, this.getDistanceFromCenterForValue(this.options.reverse ? this.min : this.max) + 5); - - var pointLabelFontColor = helpers.getValueOrDefault(this.options.pointLabels.fontColor, globalDefaults.defaultFontColor); - var pointLabelFontSize = helpers.getValueOrDefault(this.options.pointLabels.fontSize, globalDefaults.defaultFontSize); - var pointLabeFontStyle = helpers.getValueOrDefault(this.options.pointLabels.fontStyle, globalDefaults.defaultFontStyle); - var pointLabeFontFamily = helpers.getValueOrDefault(this.options.pointLabels.fontFamily, globalDefaults.defaultFontFamily); - var pointLabeFont = helpers.fontString(pointLabelFontSize, pointLabeFontStyle, pointLabeFontFamily); + var pointLabelPosition = me.getPointPosition(i, outerDistance + 5); + // Keep this in loop since we may support array properties here + var pointLabelFontColor = getValueOrDefault(pointLabelOpts.fontColor, globalDefaults.defaultFontColor); ctx.font = pointLabeFont; ctx.fillStyle = pointLabelFontColor; - var labelsCount = this.pointLabels.length, - halfLabelsCount = this.pointLabels.length / 2, + var pointLabels = me.pointLabels, + labelsCount = pointLabels.length, + halfLabelsCount = pointLabels.length / 2, quarterLabelsCount = halfLabelsCount / 2, upperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount), exactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount); @@ -446,7 +400,7 @@ module.exports = function(Chart) { ctx.textBaseline = 'top'; } - ctx.fillText(this.pointLabels[i] ? this.pointLabels[i] : '', pointLabelPosition.x, pointLabelPosition.y); + ctx.fillText(pointLabels[i] ? pointLabels[i] : '', pointLabelPosition.x, pointLabelPosition.y); } } } -- 2.47.3