mirror of
https://github.com/chartjs/Chart.js.git
synced 2026-03-12 03:06:54 +01:00
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:
committed by
Evert Timberg
parent
53d13f7026
commit
d4109ca14e
@@ -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;
|
||||
```
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
35
test/fixtures/controller.polarArea/angle-lines.json
vendored
Normal file
35
test/fixtures/controller.polarArea/angle-lines.json
vendored
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
test/fixtures/controller.polarArea/angle-lines.png
vendored
Normal file
BIN
test/fixtures/controller.polarArea/angle-lines.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
@@ -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)',
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user