Skip to content

Commit

Permalink
Added 'angle' option to Polar Charts (#5279)
Browse files Browse the repository at this point in the history
* added 'angle' option to polar charts. image comparison test is work in progress; not currently passing

* removed unnecessary variable assignment

* code cleanup based on PR; for 'angle' option on polarCharts

* Made polar chart image comparison test pass by removing debug flag. Also explicitly marked _computeAngle as private.

* Removed visibleCount computation in polar chart

* split out code related to updating the radius in polar chart's update function, into it's own 'updateRadius' function

* made updateRadius method private

* fix linting error

* updated polar charts to read custom angles from "chart.options.elements.arc.angle" instead of "chart.options.angle"
  • Loading branch information
slinhart authored and etimberg committed Jun 17, 2018
1 parent f5140d2 commit a0a195f
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 24 deletions.
78 changes: 54 additions & 24 deletions src/controllers/controller.polarArea.js
Expand Up @@ -117,25 +117,47 @@ module.exports = function(Chart) {
linkScales: helpers.noop,

update: function(reset) {
var me = this;
var dataset = me.getDataset();
var meta = me.getMeta();
var start = me.chart.options.startAngle || 0;
var starts = me._starts = [];
var angles = me._angles = [];
var i, ilen, angle;

me._updateRadius();

meta.count = me.countVisibleElements();

for (i = 0, ilen = dataset.data.length; i < ilen; i++) {
starts[i] = start;
angle = me._computeAngle(i);
angles[i] = angle;
start += angle;
}

helpers.each(meta.data, function(arc, index) {
me.updateElement(arc, index, reset);
});
},

/**
* @private
*/
_updateRadius: function() {
var me = this;
var chart = me.chart;
var chartArea = chart.chartArea;
var meta = me.getMeta();
var opts = chart.options;
var arcOpts = opts.elements.arc;
var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);

chart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0);
chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);
chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();

me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);
me.innerRadius = me.outerRadius - chart.radiusLength;

meta.count = me.countVisibleElements();

helpers.each(meta.data, function(arc, index) {
me.updateElement(arc, index, reset);
});
},

updateElement: function(arc, index, reset) {
Expand All @@ -147,25 +169,14 @@ module.exports = function(Chart) {
var scale = chart.scale;
var labels = chart.data.labels;

var circumference = me.calculateCircumference(dataset.data[index]);
var centerX = scale.xCenter;
var centerY = scale.yCenter;

// If there is NaN data before us, we need to calculate the starting angle correctly.
// We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data
var visibleCount = 0;
var meta = me.getMeta();
for (var i = 0; i < index; ++i) {
if (!isNaN(dataset.data[i]) && !meta.data[i].hidden) {
++visibleCount;
}
}

// var negHalfPI = -0.5 * Math.PI;
var datasetStartAngle = opts.startAngle;
var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
var startAngle = datasetStartAngle + (circumference * visibleCount);
var endAngle = startAngle + (arc.hidden ? 0 : circumference);
var startAngle = me._starts[index];
var endAngle = startAngle + (arc.hidden ? 0 : me._angles[index]);

var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);

Expand Down Expand Up @@ -211,12 +222,31 @@ module.exports = function(Chart) {
return count;
},

calculateCircumference: function(value) {
/**
* @private
*/
_computeAngle: function(index) {
var me = this;
var count = this.getMeta().count;
if (count > 0 && !isNaN(value)) {
return (2 * Math.PI) / count;
var dataset = me.getDataset();
var meta = me.getMeta();

if (isNaN(dataset.data[index]) || meta.data[index].hidden) {
return 0;
}
return 0;

// Scriptable options
var context = {
chart: me.chart,
dataIndex: index,
dataset: dataset,
datasetIndex: me.index
};

return helpers.options.resolve([
me.chart.options.elements.arc.angle,
(2 * Math.PI) / count
], context, index);
}
});
};
34 changes: 34 additions & 0 deletions test/fixtures/controller.polarArea/angle-array.json
@@ -0,0 +1,34 @@
{
"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": {
"elements": {
"arc": {
"angle": [
1.0566, 1.7566, 1.0566, 2.1566, 0.2566
]
}
},
"responsive": false,
"legend": false,
"title": false,
"scale": {
"display": false
}
}
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions test/fixtures/controller.polarArea/angle-undefined.json
@@ -0,0 +1,27 @@
{
"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": false
}
}
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions test/specs/controller.polarArea.tests.js
@@ -1,3 +1,5 @@
describe('auto', jasmine.specsFromFixtures('controller.polarArea'));

describe('Chart.controllers.polarArea', function() {
it('should be constructed', function() {
var chart = window.acquireChart({
Expand Down

0 comments on commit a0a195f

Please sign in to comment.