mirror of
https://github.com/chartjs/Chart.js.git
synced 2026-03-06 08:24:05 +01:00
256 lines
6.7 KiB
JavaScript
256 lines
6.7 KiB
JavaScript
'use strict';
|
|
|
|
var defaults = require('../core/core.defaults');
|
|
var elements = require('../elements/index');
|
|
var helpers = require('../helpers/index');
|
|
|
|
defaults._set('polarArea', {
|
|
scale: {
|
|
type: 'radialLinear',
|
|
angleLines: {
|
|
display: false
|
|
},
|
|
gridLines: {
|
|
circular: true
|
|
},
|
|
pointLabels: {
|
|
display: false
|
|
},
|
|
ticks: {
|
|
beginAtZero: true
|
|
}
|
|
},
|
|
|
|
// Boolean - Whether to animate the rotation of the chart
|
|
animation: {
|
|
animateRotate: true,
|
|
animateScale: true
|
|
},
|
|
|
|
startAngle: -0.5 * Math.PI,
|
|
legendCallback: function(chart) {
|
|
var text = [];
|
|
text.push('<ul class="' + chart.id + '-legend">');
|
|
|
|
var data = chart.data;
|
|
var datasets = data.datasets;
|
|
var labels = data.labels;
|
|
|
|
if (datasets.length) {
|
|
for (var i = 0; i < datasets[0].data.length; ++i) {
|
|
text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>');
|
|
if (labels[i]) {
|
|
text.push(labels[i]);
|
|
}
|
|
text.push('</li>');
|
|
}
|
|
}
|
|
|
|
text.push('</ul>');
|
|
return text.join('');
|
|
},
|
|
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 ds = data.datasets[0];
|
|
var arc = meta.data[i];
|
|
var custom = arc.custom || {};
|
|
var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
|
|
var arcOpts = chart.options.elements.arc;
|
|
var fill = custom.backgroundColor ? custom.backgroundColor : valueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
|
|
var stroke = custom.borderColor ? custom.borderColor : valueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
|
|
var bw = custom.borderWidth ? custom.borderWidth : valueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
|
|
|
|
return {
|
|
text: label,
|
|
fillStyle: fill,
|
|
strokeStyle: stroke,
|
|
lineWidth: bw,
|
|
hidden: isNaN(ds.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.yLabel;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
module.exports = function(Chart) {
|
|
|
|
Chart.controllers.polarArea = Chart.DatasetController.extend({
|
|
|
|
dataElementType: elements.Arc,
|
|
|
|
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 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;
|
|
},
|
|
|
|
updateElement: function(arc, index, reset) {
|
|
var me = this;
|
|
var chart = me.chart;
|
|
var dataset = me.getDataset();
|
|
var opts = chart.options;
|
|
var animationOpts = opts.animation;
|
|
var scale = chart.scale;
|
|
var labels = chart.data.labels;
|
|
|
|
var centerX = scale.xCenter;
|
|
var centerY = scale.yCenter;
|
|
|
|
// var negHalfPI = -0.5 * Math.PI;
|
|
var datasetStartAngle = opts.startAngle;
|
|
var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
|
|
var startAngle = me._starts[index];
|
|
var endAngle = startAngle + (arc.hidden ? 0 : me._angles[index]);
|
|
|
|
var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
|
|
|
|
helpers.extend(arc, {
|
|
// Utility
|
|
_datasetIndex: me.index,
|
|
_index: index,
|
|
_scale: scale,
|
|
|
|
// Desired view properties
|
|
_model: {
|
|
x: centerX,
|
|
y: centerY,
|
|
innerRadius: 0,
|
|
outerRadius: reset ? resetRadius : distance,
|
|
startAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle,
|
|
endAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle,
|
|
label: helpers.valueAtIndexOrDefault(labels, index, labels[index])
|
|
}
|
|
});
|
|
|
|
// Apply border and fill style
|
|
var elementOpts = this.chart.options.elements.arc;
|
|
var custom = arc.custom || {};
|
|
var valueOrDefault = helpers.valueAtIndexOrDefault;
|
|
var model = arc._model;
|
|
|
|
model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor);
|
|
model.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor);
|
|
model.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth);
|
|
|
|
arc.pivot();
|
|
},
|
|
|
|
countVisibleElements: function() {
|
|
var dataset = this.getDataset();
|
|
var meta = this.getMeta();
|
|
var count = 0;
|
|
|
|
helpers.each(meta.data, function(element, index) {
|
|
if (!isNaN(dataset.data[index]) && !element.hidden) {
|
|
count++;
|
|
}
|
|
});
|
|
|
|
return count;
|
|
},
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
_computeAngle: function(index) {
|
|
var me = this;
|
|
var count = this.getMeta().count;
|
|
var dataset = me.getDataset();
|
|
var meta = me.getMeta();
|
|
|
|
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 helpers.options.resolve([
|
|
me.chart.options.elements.arc.angle,
|
|
(2 * Math.PI) / count
|
|
], context, index);
|
|
}
|
|
});
|
|
};
|