* Polar area: startAngle in degrees, 0 at top.
Co-authored-by: Jukka Kurkela <jukka.kurkela@gmail.com>
| 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.
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;
```
### 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`
}
},
- startAngle: -0.5 * Math.PI,
+ startAngle: 0,
legend: {
labels: {
generateLabels: function(chart) {
}
});
+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,
},
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);
},
/**
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;
};
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);
}
/**
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 {
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';
// 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);
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) {
--- /dev/null
+{
+ "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
+ }
+ }
+ }
+ }
+}
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)',
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) {