import defaults from '../core/core.defaults';
import {_longestText, renderText} from '../helpers/helpers.canvas';
-import {HALF_PI, isNumber, TAU, toDegrees, toRadians, _normalizeAngle} from '../helpers/helpers.math';
+import {HALF_PI, isNumber, TAU, toDegrees, toRadians, _normalizeAngle, PI} from '../helpers/helpers.math';
import LinearScaleBase from './scale.linearbase';
import Ticks from '../core/core.ticks';
import {valueOrDefault, isArray, isFinite, callback as callCallback, isNullOrUndef} from '../helpers/helpers.core';
const opts = scale.options;
const tickBackdropHeight = getTickBackdropHeight(opts);
const outerDistance = scale.getDistanceFromCenterForValue(opts.ticks.reverse ? scale.min : scale.max);
+ const additionalAngle = opts.pointLabels.centerPointLabels ? PI / valueCount : 0;
for (let i = 0; i < valueCount; i++) {
// Extra pixels out for some label spacing
const extra = (i === 0 ? tickBackdropHeight / 2 : 0);
- const pointLabelPosition = scale.getPointPosition(i, outerDistance + extra + padding[i]);
- const angle = toDegrees(scale.getIndexAngle(i));
+ const pointLabelPosition = scale.getPointPosition(i, outerDistance + extra + padding[i], additionalAngle);
+ const angle = toDegrees(pointLabelPosition.angle + HALF_PI);
const size = labelSizes[i];
const y = yForAngle(pointLabelPosition.y, size.h, angle);
const textAlign = getTextAlignForAngle(angle);
}
}
- getPointPosition(index, distanceFromCenter) {
- const angle = this.getIndexAngle(index) - HALF_PI;
+ getPointPosition(index, distanceFromCenter, additionalAngle = 0) {
+ const angle = this.getIndexAngle(index) - HALF_PI + additionalAngle;
return {
x: Math.cos(angle) * distanceFromCenter + this.xCenter,
y: Math.sin(angle) * distanceFromCenter + this.yCenter,
},
// Number - Additionl padding between scale and pointLabel
- padding: 5
+ padding: 5,
+
+ // Boolean - if true, center point labels to slices in polar chart
+ centerPointLabels: false
}
};
size: 10
},
callback: defaultConfig.pointLabels.callback,
- padding: 5
+ padding: 5,
+ centerPointLabels: false
}
});
});
});
});
+
+ it('should correctly get the point positions in center', function() {
+ var chart = window.acquireChart({
+ type: 'polarArea',
+ data: {
+ datasets: [{
+ data: [10, 5, 0, 25, 78]
+ }],
+ labels: ['label1', 'label2', 'label3', 'label4', 'label5']
+ },
+ options: {
+ scales: {
+ r: {
+ pointLabels: {
+ display: true,
+ padding: 5,
+ centerPointLabels: true
+ },
+ ticks: {
+ display: false
+ }
+ }
+ }
+ }
+ });
+
+ const PI = Math.PI;
+ const lavelNum = 5;
+ const padding = 5;
+ const pointLabelItems = chart.scales.r._pointLabelItems;
+ const additionalAngle = PI / lavelNum;
+ const opts = chart.scales.r.options;
+ const outerDistance = chart.scales.r.getDistanceFromCenterForValue(opts.ticks.reverse ? chart.scales.r.min : chart.scales.r.max);
+ const tickBackdropHeight = 0;
+ const yForAngle = function(y, h, angle) {
+ if (angle === 90 || angle === 270) {
+ y -= (h / 2);
+ } else if (angle > 270 || angle < 90) {
+ y -= h;
+ }
+ return y;
+ };
+ const toDegrees = function(radians) {
+ return radians * (180 / PI);
+ };
+
+ for (var i = 0; i < 5; i++) {
+ const extra = (i === 0 ? tickBackdropHeight / 2 : 0);
+ const pointLabelItem = pointLabelItems[i];
+ const pointPosition = chart.scales.r.getPointPosition(i, outerDistance + extra + padding, additionalAngle);
+ expect(pointLabelItem.x).toBe(pointPosition.x);
+ expect(pointLabelItem.y).toBe(yForAngle(pointPosition.y, 12, toDegrees(pointPosition.angle + PI / 2)));
+ }
+
+ });
});