diff --git a/src/scales/scale.radialLinear.js b/src/scales/scale.radialLinear.js index ce605bde404..f75e594ad7f 100644 --- a/src/scales/scale.radialLinear.js +++ b/src/scales/scale.radialLinear.js @@ -423,15 +423,14 @@ module.exports = LinearScaleBase.extend({ }, getIndexAngle: function(index) { - var angleMultiplier = (Math.PI * 2) / getValueCount(this); - var startAngle = this.chart.options && this.chart.options.startAngle ? - this.chart.options.startAngle : - 0; - - var startAngleRadians = startAngle * Math.PI * 2 / 360; + var angleMultiplier = 360 / getValueCount(this); + var options = this.chart.options || {}; + var startAngle = options.startAngle || 0; // Start from the top instead of right, so remove a quarter of the circle - return index * angleMultiplier + startAngleRadians; + var angle = (index * angleMultiplier + startAngle) % 360; + + return (angle < 0 ? angle + 360 : angle) * Math.PI * 2 / 360; }, getDistanceFromCenterForValue: function(value) { diff --git a/test/context.js b/test/context.js index 4b683aff737..88966f230fe 100644 --- a/test/context.js +++ b/test/context.js @@ -9,6 +9,7 @@ var Context = function() { this._lineJoin = null; this._lineWidth = null; this._strokeStyle = null; + this._textAlign = null; // Define properties here so that we can record each time they are set Object.defineProperties(this, { @@ -66,6 +67,15 @@ var Context = function() { this.record('setStrokeStyle', [style]); } }, + textAlign: { + get: function() { + return this._textAlign; + }, + set: function(align) { + this._textAlign = align; + this.record('setTextAlign', [align]); + } + } }); }; diff --git a/test/specs/core.tooltip.tests.js b/test/specs/core.tooltip.tests.js index 6fb4880cb65..a7403eb81ec 100755 --- a/test/specs/core.tooltip.tests.js +++ b/test/specs/core.tooltip.tests.js @@ -1206,11 +1206,14 @@ describe('Core.Tooltip', function() { tooltip.draw(); expect(mockContext.getCalls()).toEqual(Array.prototype.concat(drawBody, [ + {name: 'setTextAlign', args: ['left']}, {name: 'setFillStyle', args: ['#fff']}, {name: 'fillText', args: ['title', 105, 105]}, + {name: 'setTextAlign', args: ['left']}, {name: 'setFillStyle', args: ['#fff']}, {name: 'setFillStyle', args: ['#fff']}, {name: 'fillText', args: ['label', 105, 123]}, + {name: 'setTextAlign', args: ['left']}, {name: 'setFillStyle', args: ['#fff']}, {name: 'fillText', args: ['footer', 105, 141]}, {name: 'restore', args: []} @@ -1223,11 +1226,14 @@ describe('Core.Tooltip', function() { tooltip.draw(); expect(mockContext.getCalls()).toEqual(Array.prototype.concat(drawBody, [ + {name: 'setTextAlign', args: ['right']}, {name: 'setFillStyle', args: ['#fff']}, {name: 'fillText', args: ['title', 195, 105]}, + {name: 'setTextAlign', args: ['right']}, {name: 'setFillStyle', args: ['#fff']}, {name: 'setFillStyle', args: ['#fff']}, {name: 'fillText', args: ['label', 195, 123]}, + {name: 'setTextAlign', args: ['right']}, {name: 'setFillStyle', args: ['#fff']}, {name: 'fillText', args: ['footer', 195, 141]}, {name: 'restore', args: []} @@ -1240,11 +1246,14 @@ describe('Core.Tooltip', function() { tooltip.draw(); expect(mockContext.getCalls()).toEqual(Array.prototype.concat(drawBody, [ + {name: 'setTextAlign', args: ['center']}, {name: 'setFillStyle', args: ['#fff']}, {name: 'fillText', args: ['title', 150, 105]}, + {name: 'setTextAlign', args: ['center']}, {name: 'setFillStyle', args: ['#fff']}, {name: 'setFillStyle', args: ['#fff']}, {name: 'fillText', args: ['label', 150, 123]}, + {name: 'setTextAlign', args: ['center']}, {name: 'setFillStyle', args: ['#fff']}, {name: 'fillText', args: ['footer', 150, 141]}, {name: 'restore', args: []} @@ -1257,11 +1266,14 @@ describe('Core.Tooltip', function() { tooltip.draw(); expect(mockContext.getCalls()).toEqual(Array.prototype.concat(drawBody, [ + {name: 'setTextAlign', args: ['right']}, {name: 'setFillStyle', args: ['#fff']}, {name: 'fillText', args: ['title', 195, 105]}, + {name: 'setTextAlign', args: ['center']}, {name: 'setFillStyle', args: ['#fff']}, {name: 'setFillStyle', args: ['#fff']}, {name: 'fillText', args: ['label', 150, 123]}, + {name: 'setTextAlign', args: ['left']}, {name: 'setFillStyle', args: ['#fff']}, {name: 'fillText', args: ['footer', 105, 141]}, {name: 'restore', args: []} diff --git a/test/specs/plugin.title.tests.js b/test/specs/plugin.title.tests.js index 4f00ee8925b..9b6d0ab0694 100644 --- a/test/specs/plugin.title.tests.js +++ b/test/specs/plugin.title.tests.js @@ -134,6 +134,9 @@ describe('Title block tests', function() { }, { name: 'rotate', args: [0] + }, { + name: 'setTextAlign', + args: ['center'], }, { name: 'fillText', args: ['My title', 0, 0, 400] @@ -184,6 +187,9 @@ describe('Title block tests', function() { }, { name: 'rotate', args: [-0.5 * Math.PI] + }, { + name: 'setTextAlign', + args: ['center'], }, { name: 'fillText', args: ['My title', 0, 0, 400] @@ -217,6 +223,9 @@ describe('Title block tests', function() { }, { name: 'rotate', args: [0.5 * Math.PI] + }, { + name: 'setTextAlign', + args: ['center'], }, { name: 'fillText', args: ['My title', 0, 0, 400] diff --git a/test/specs/scale.radialLinear.tests.js b/test/specs/scale.radialLinear.tests.js index 2102bfaefc9..1a7761808dd 100644 --- a/test/specs/scale.radialLinear.tests.js +++ b/test/specs/scale.radialLinear.tests.js @@ -485,4 +485,62 @@ describe('Test the radial linear scale', function() { expect(radToNearestDegree(chart.scale.getIndexAngle(x))).toBe((slice * x)); } }); + + it('should correctly get the correct label alignment for all points', function() { + var chart = window.acquireChart({ + type: 'radar', + data: { + datasets: [{ + data: [10, 5, 0, 25, 78] + }], + labels: ['label1', 'label2', 'label3', 'label4', 'label5'] + }, + options: { + scale: { + pointLabels: { + callback: function(value, index) { + return index.toString(); + } + }, + ticks: { + display: false + } + } + } + }); + + var scale = chart.scale; + + [{ + startAngle: 30, + textAlign: ['right', 'right', 'left', 'left', 'left'], + y: [82, 366, 506, 319, 53] + }, { + startAngle: -30, + textAlign: ['right', 'right', 'left', 'left', 'right'], + y: [319, 506, 366, 82, 53] + }, { + startAngle: 750, + textAlign: ['right', 'right', 'left', 'left', 'left'], + y: [82, 366, 506, 319, 53] + }].forEach(function(expected) { + chart.options.startAngle = expected.startAngle; + chart.update(); + + scale.ctx = window.createMockContext(); + chart.draw(); + + scale.ctx.getCalls().filter(function(x) { + return x.name === 'setTextAlign'; + }).forEach(function(x, i) { + expect(x.args[0]).toBe(expected.textAlign[i]); + }); + + scale.ctx.getCalls().filter(function(x) { + return x.name === 'fillText'; + }).map(function(x, i) { + expect(x.args[2]).toBeCloseToPixel(expected.y[i]); + }); + }); + }); });