Skip to content

Commit

Permalink
Normalize angle for index in radialLinear scale (chartjs#6177)
Browse files Browse the repository at this point in the history
  • Loading branch information
nagix authored and simonbrunel committed Apr 2, 2019
1 parent f0781c7 commit 9059935
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 7 deletions.
13 changes: 6 additions & 7 deletions src/scales/scale.radialLinear.js
Expand Up @@ -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) {
Expand Down
10 changes: 10 additions & 0 deletions test/context.js
Expand Up @@ -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, {
Expand Down Expand Up @@ -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]);
}
}
});
};

Expand Down
12 changes: 12 additions & 0 deletions test/specs/core.tooltip.tests.js
Expand Up @@ -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: []}
Expand All @@ -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: []}
Expand All @@ -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: []}
Expand All @@ -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: []}
Expand Down
9 changes: 9 additions & 0 deletions test/specs/plugin.title.tests.js
Expand Up @@ -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]
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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]
Expand Down
58 changes: 58 additions & 0 deletions test/specs/scale.radialLinear.tests.js
Expand Up @@ -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]);
});
});
});
});

0 comments on commit 9059935

Please sign in to comment.