Chart.js/src/controllers/controller.polarArea.js
Jukka Kurkela ce74eb76a1 Convert axis options from arrays to objects (#6773)
* Convert axis options from arrays to objects

* Updated all chart type defaults
* Throw errors when axis type or position are not specified
* Avoid raising unnecessary errors when merging options into the default configs

* Fix additional tests

* Ensure scale defaults are set if type is not explicitly defined

* Another step

* Include `scale` as `firstIDs.r`

* update docs

* Update for buildOrUpdateScales

* Update migration guide

* Add test back
2019-11-21 18:46:49 -05:00

280 lines
6.7 KiB
JavaScript

'use strict';
var DatasetController = require('../core/core.datasetController');
var defaults = require('../core/core.defaults');
var elements = require('../elements/index');
var helpers = require('../helpers/index');
var resolve = helpers.options.resolve;
defaults._set('polarArea', {
scales: {
r: {
type: 'radialLinear',
angleLines: {
display: false
},
beginAtZero: true,
gridLines: {
circular: true
},
pointLabels: {
display: false
}
}
},
// Boolean - Whether to animate the rotation of the chart
animation: {
animateRotate: true,
animateScale: true
},
startAngle: -0.5 * Math.PI,
legendCallback: function(chart) {
var list = document.createElement('ul');
var data = chart.data;
var datasets = data.datasets;
var labels = data.labels;
var i, ilen, listItem, listItemSpan;
list.setAttribute('class', chart.id + '-legend');
if (datasets.length) {
for (i = 0, ilen = datasets[0].data.length; i < ilen; ++i) {
listItem = list.appendChild(document.createElement('li'));
listItemSpan = listItem.appendChild(document.createElement('span'));
listItemSpan.style.backgroundColor = datasets[0].backgroundColor[i];
if (labels[i]) {
listItem.appendChild(document.createTextNode(labels[i]));
}
}
}
return list.outerHTML;
},
legend: {
labels: {
generateLabels: function(chart) {
var data = chart.data;
if (data.labels.length && data.datasets.length) {
return data.labels.map(function(label, i) {
var meta = chart.getDatasetMeta(0);
var style = meta.controller.getStyle(i);
return {
text: label,
fillStyle: style.backgroundColor,
strokeStyle: style.borderColor,
lineWidth: style.borderWidth,
hidden: isNaN(data.datasets[0].data[i]) || meta.data[i].hidden,
// Extra data used for toggling the correct item
index: i
};
});
}
return [];
}
},
onClick: function(e, legendItem) {
var index = legendItem.index;
var chart = this.chart;
var i, ilen, meta;
for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
meta = chart.getDatasetMeta(i);
meta.data[index].hidden = !meta.data[index].hidden;
}
chart.update();
}
},
// Need to override these to give a nice default
tooltips: {
callbacks: {
title: function() {
return '';
},
label: function(item, data) {
return data.labels[item.index] + ': ' + item.value;
}
}
}
});
module.exports = DatasetController.extend({
dataElementType: elements.Arc,
/**
* @private
*/
_dataElementOptions: [
'backgroundColor',
'borderColor',
'borderWidth',
'borderAlign',
'hoverBackgroundColor',
'hoverBorderColor',
'hoverBorderWidth',
],
/**
* @private
*/
_getIndexScaleId: function() {
return this._cachedMeta.rAxisID;
},
/**
* @private
*/
_getValueScaleId: function() {
return this._cachedMeta.rAxisID;
},
update: function(reset) {
var me = this;
var dataset = me.getDataset();
var meta = me._cachedMeta;
var start = me.chart.options.startAngle || 0;
var starts = me._starts = [];
var angles = me._angles = [];
var arcs = meta.data;
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;
}
me.updateElements(arcs, 0, arcs.length, reset);
},
/**
* @private
*/
_updateRadius: function() {
var me = this;
var chart = me.chart;
var chartArea = chart.chartArea;
var opts = chart.options;
var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
chart.outerRadius = Math.max(minSize / 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;
},
updateElements: function(arcs, start, count, reset) {
const me = this;
const chart = me.chart;
const dataset = me.getDataset();
const opts = chart.options;
const animationOpts = opts.animation;
const scale = chart.scales.r;
const centerX = scale.xCenter;
const centerY = scale.yCenter;
var i;
for (i = 0; i < start + count; i++) {
const arc = arcs[i];
// var negHalfPI = -0.5 * Math.PI;
const datasetStartAngle = opts.startAngle;
const distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[i]);
const startAngle = me._starts[i];
const endAngle = startAngle + (arc.hidden ? 0 : me._angles[i]);
const resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[i]);
const options = arc._options = me._resolveDataElementOptions(i);
arc._model = {
backgroundColor: options.backgroundColor,
borderColor: options.borderColor,
borderWidth: options.borderWidth,
borderAlign: options.borderAlign,
x: centerX,
y: centerY,
innerRadius: 0,
outerRadius: reset ? resetRadius : distance,
startAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle,
endAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle
};
arc.pivot(chart._animationsDisabled);
}
},
countVisibleElements: function() {
var dataset = this.getDataset();
var meta = this._cachedMeta;
var count = 0;
helpers.each(meta.data, function(element, index) {
if (!isNaN(dataset.data[index]) && !element.hidden) {
count++;
}
});
return count;
},
/**
* @protected
*/
setHoverStyle: function(arc) {
var model = arc._model;
var options = arc._options;
var getHoverColor = helpers.getHoverColor;
var valueOrDefault = helpers.valueOrDefault;
arc.$previousStyle = {
backgroundColor: model.backgroundColor,
borderColor: model.borderColor,
borderWidth: model.borderWidth,
};
model.backgroundColor = valueOrDefault(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));
model.borderColor = valueOrDefault(options.hoverBorderColor, getHoverColor(options.borderColor));
model.borderWidth = valueOrDefault(options.hoverBorderWidth, options.borderWidth);
},
/**
* @private
*/
_computeAngle: function(index) {
var me = this;
var meta = me._cachedMeta;
var count = meta.count;
var dataset = me.getDataset();
if (isNaN(dataset.data[index]) || meta.data[index].hidden) {
return 0;
}
// Scriptable options
var context = {
chart: me.chart,
dataIndex: index,
dataset: dataset,
datasetIndex: me.index
};
return resolve([
me.chart.options.elements.arc.angle,
(2 * Math.PI) / count
], context, index);
}
});