]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Linear and RadialLinear scales now derive from a common base class
authorEvert Timberg <evert.timberg+github@gmail.com>
Sun, 29 May 2016 14:16:47 +0000 (10:16 -0400)
committerEvert Timberg <evert.timberg+github@gmail.com>
Sun, 29 May 2016 14:16:47 +0000 (10:16 -0400)
src/chart.js
src/scales/scale.linear.js
src/scales/scale.linearbase.js [new file with mode: 0644]
src/scales/scale.radialLinear.js

index 90b9c77ee8af097f3f0e80bd90c4e086e1a7e618..f992a9e1c45a35b2473026994f64a01760f9143d 100644 (file)
@@ -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);
index f6363d44c0d543d50dd6a4fc787d63cffadcc128..c8905769b33e7ed21f59576de196fde788a6192d 100644 (file)
@@ -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 (file)
index 0000000..d127c88
--- /dev/null
@@ -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
index 017c0c7470c3af7faf44bcb12134631e1e9b0231..3cb23849339e217308b62b8766b4a72b16d10247 100644 (file)
@@ -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);
                                        }
                                }
                        }