mirror of
https://github.com/chartjs/Chart.js.git
synced 2025-12-08 20:36:08 +00:00
* 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
280 lines
6.7 KiB
JavaScript
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);
|
|
}
|
|
});
|