Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Polar area: startAngle in degrees, 0 at top. #6936

Merged
merged 3 commits into from
Jan 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/charts/polar.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ These are the customisation options specific to Polar Area charts. These options

| Name | Type | Default | Description
| ---- | ---- | ------- | -----------
| `startAngle` | `number` | `-0.5 * Math.PI` | Starting angle to draw arcs for the first item in a dataset.
| `startAngle` | `number` | `0` | Starting angle to draw arcs for the first item in a dataset. In degrees, 0 is at top.
| `animation.animateRotate` | `boolean` | `true` | If true, the chart will animate in with a rotation animation. This property is in the `options.animation` object.
| `animation.animateScale` | `boolean` | `true` | If true, will animate scaling the chart from the center outwards.

Expand All @@ -112,6 +112,7 @@ The polar area chart uses the [radialLinear](../axes/radial/linear.md) scale. Ad
We can also change these defaults values for each PolarArea type that is created, this object is available at `Chart.defaults.polarArea`. Changing the global options only affects charts created after the change. Existing charts are not changed.

For example, to configure all new polar area charts with `animateScale = false` you would do:

```javascript
Chart.defaults.polarArea.animation.animateScale = false;
```
Expand Down
1 change: 1 addition & 0 deletions docs/getting-started/v3-migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Chart.js 3.0 introduces a number of breaking changes. Chart.js 2.0 was released

### Options

* `Polar area` `startAngle` option is now consistent with `Radar`, 0 is at top and value is in degrees. Default is changed from `-½π` to `0`.
* `scales.[x/y]Axes` arrays were removed. Scales are now configured directly to `options.scales` object with the object key being the scale Id.
* `scales.[x/y]Axes.barPercentage` was moved to dataset option `barPercentage`
* `scales.[x/y]Axes.barThickness` was moved to dataset option `barThickness`
Expand Down
19 changes: 11 additions & 8 deletions src/controllers/controller.polarArea.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ defaults._set('polarArea', {
}
},

startAngle: -0.5 * Math.PI,
startAngle: 0,
legend: {
labels: {
generateLabels: function(chart) {
Expand Down Expand Up @@ -85,6 +85,12 @@ defaults._set('polarArea', {
}
});

function getStartAngleRadians(deg) {
// radialLinear scale draws angleLines using startAngle. 0 is expected to be at top.
// Here we adjust to standard unit circle used in drawing, where 0 is at right.
return helpers.math.toRadians(deg) - 0.5 * Math.PI;
}

export default DatasetController.extend({

dataElementType: elements.Arc,
Expand Down Expand Up @@ -117,13 +123,10 @@ export default DatasetController.extend({
},

update: function(mode) {
var me = this;
var meta = me._cachedMeta;
var arcs = meta.data;

me._updateRadius();
const arcs = this._cachedMeta.data;

me.updateElements(arcs, 0, mode);
this._updateRadius();
this.updateElements(arcs, 0, mode);
},

/**
Expand Down Expand Up @@ -154,7 +157,7 @@ export default DatasetController.extend({
const scale = chart.scales.r;
const centerX = scale.xCenter;
const centerY = scale.yCenter;
const datasetStartAngle = opts.startAngle || 0;
const datasetStartAngle = getStartAngleRadians(opts.startAngle);
let angle = datasetStartAngle;
let i;

Expand Down
8 changes: 4 additions & 4 deletions src/helpers/helpers.math.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@ export const sign = Math.sign ?
};

export function toRadians(degrees) {
return degrees * (Math.PI / 180);
return degrees * (PI / 180);
}

export function toDegrees(radians) {
return radians * (180 / Math.PI);
return radians * (180 / PI);
}

/**
Expand Down Expand Up @@ -118,8 +118,8 @@ export function getAngleFromPoint(centrePoint, anglePoint) {

var angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);

if (angle < (-0.5 * Math.PI)) {
angle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2]
if (angle < (-0.5 * PI)) {
angle += TAU; // make sure the returned angle is in the range of (-PI/2, 3PI/2]
}

return {
Expand Down
11 changes: 4 additions & 7 deletions src/scales/scale.radialLinear.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import defaults from '../core/core.defaults';
import helpers from '../helpers/index';
import {isNumber, toDegrees} from '../helpers/helpers.math';
import {isNumber, toDegrees, toRadians, _normalizeAngle} from '../helpers/helpers.math';
import LinearScaleBase from './scale.linearbase';
import Ticks from '../core/core.ticks';

Expand Down Expand Up @@ -157,7 +157,7 @@ function fitWithPointLabels(scale) {

// Add quarter circle to make degree 0 mean top of circle
var angleRadians = scale.getIndexAngle(i);
var angle = toDegrees(angleRadians) % 360;
var angle = toDegrees(angleRadians);
var hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);
var vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);

Expand Down Expand Up @@ -380,14 +380,11 @@ class RadialLinearScale extends LinearScaleBase {

getIndexAngle(index) {
var chart = this.chart;
var angleMultiplier = 360 / chart.data.labels.length;
var angleMultiplier = Math.PI * 2 / chart.data.labels.length;
var options = chart.options || {};
var startAngle = options.startAngle || 0;

// Start from the top instead of right, so remove a quarter of the circle
var angle = (index * angleMultiplier + startAngle) % 360;

return (angle < 0 ? angle + 360 : angle) * Math.PI * 2 / 360;
return _normalizeAngle(index * angleMultiplier + toRadians(startAngle));
}

getDistanceFromCenterForValue(value) {
Expand Down
35 changes: 35 additions & 0 deletions test/fixtures/controller.polarArea/angle-lines.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"threshold": 0.05,
"config": {
"type": "polarArea",
"data": {
"labels": ["A", "B", "C", "D", "E"],
"datasets": [{
"data": [11, 16, 21, 7, 10],
"backgroundColor": [
"rgba(255, 99, 132, 0.8)",
"rgba(54, 162, 235, 0.8)",
"rgba(255, 206, 86, 0.8)",
"rgba(75, 192, 192, 0.8)",
"rgba(153, 102, 255, 0.8)",
"rgba(255, 159, 64, 0.8)"
]
}]
},
"options": {
"responsive": false,
"legend": false,
"title": false,
"scale": {
"display": true,
"angleLines": {
"display": true,
"color": "#000"
},
"ticks": {
"display": false
}
}
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test/specs/controller.polarArea.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ describe('Chart.controllers.polarArea', function() {
showLines: true,
legend: false,
title: false,
startAngle: 0, // default is -0.5 * Math.PI
startAngle: 90, // default is 0
elements: {
arc: {
backgroundColor: 'rgb(255, 0, 0)',
Expand Down
2 changes: 1 addition & 1 deletion test/specs/scale.radialLinear.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ describe('Test the radial linear scale', function() {
scale.ctx.getCalls().filter(function(x) {
return x.name === 'setTextAlign';
}).forEach(function(x, i) {
expect(x.args[0]).toBe(expected.textAlign[i]);
expect(x.args[0]).withContext('startAngle: ' + expected.startAngle + ', tick: ' + i).toBe(expected.textAlign[i]);
});

scale.ctx.getCalls().filter(function(x) {
Expand Down