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

* Polar area: startAngle in degrees, 0 at top.
Co-authored-by: Jukka Kurkela <jukka.kurkela@gmail.com>
This commit is contained in:
Ben McCann
2020-01-10 15:30:29 -08:00
committed by Evert Timberg
parent 53d13f7026
commit d4109ca14e
9 changed files with 59 additions and 22 deletions

View File

@@ -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.
@@ -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;
```

View File

@@ -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`

View File

@@ -32,7 +32,7 @@ defaults._set('polarArea', {
}
},
startAngle: -0.5 * Math.PI,
startAngle: 0,
legend: {
labels: {
generateLabels: function(chart) {
@@ -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,
@@ -117,13 +123,10 @@ export default DatasetController.extend({
},
update: function(mode) {
var me = this;
var meta = me._cachedMeta;
var arcs = meta.data;
const arcs = this._cachedMeta.data;
me._updateRadius();
me.updateElements(arcs, 0, mode);
this._updateRadius();
this.updateElements(arcs, 0, mode);
},
/**
@@ -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;

View File

@@ -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);
}
/**
@@ -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 {

View File

@@ -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';
@@ -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);
@@ -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) {

View File

@@ -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
}
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -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)',

View File

@@ -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) {