mirror of
https://github.com/chartjs/Chart.js.git
synced 2026-03-13 19:56:49 +01:00
166 lines
4.0 KiB
JavaScript
166 lines
4.0 KiB
JavaScript
'use strict';
|
|
|
|
var helpers = require('../helpers/index');
|
|
var LinearScaleBase = require('./scale.linearbase');
|
|
var Ticks = require('../core/core.ticks');
|
|
|
|
var defaultConfig = {
|
|
position: 'left',
|
|
ticks: {
|
|
callback: Ticks.formatters.linear
|
|
}
|
|
};
|
|
|
|
var DEFAULT_MIN = 0;
|
|
var DEFAULT_MAX = 1;
|
|
|
|
function getOrCreateStack(stacks, stacked, meta) {
|
|
var key = [
|
|
meta.type,
|
|
// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined
|
|
stacked === undefined && meta.stack === undefined ? meta.index : '',
|
|
meta.stack
|
|
].join('.');
|
|
|
|
if (stacks[key] === undefined) {
|
|
stacks[key] = {
|
|
pos: [],
|
|
neg: []
|
|
};
|
|
}
|
|
|
|
return stacks[key];
|
|
}
|
|
|
|
function stackData(scale, stacks, meta, data) {
|
|
var opts = scale.options;
|
|
var stacked = opts.stacked;
|
|
var stack = getOrCreateStack(stacks, stacked, meta);
|
|
var pos = stack.pos;
|
|
var neg = stack.neg;
|
|
var ilen = data.length;
|
|
var i, value;
|
|
|
|
for (i = 0; i < ilen; ++i) {
|
|
value = scale._parseValue(data[i]);
|
|
if (isNaN(value.min) || isNaN(value.max) || meta.data[i].hidden) {
|
|
continue;
|
|
}
|
|
|
|
pos[i] = pos[i] || 0;
|
|
neg[i] = neg[i] || 0;
|
|
|
|
if (value.min < 0 || value.max < 0) {
|
|
neg[i] += value.min;
|
|
} else {
|
|
pos[i] += value.max;
|
|
}
|
|
}
|
|
}
|
|
|
|
function updateMinMax(scale, meta, data) {
|
|
var ilen = data.length;
|
|
var i, value;
|
|
|
|
for (i = 0; i < ilen; ++i) {
|
|
value = scale._parseValue(data[i]);
|
|
if (isNaN(value.min) || isNaN(value.max) || meta.data[i].hidden) {
|
|
continue;
|
|
}
|
|
|
|
scale.min = Math.min(scale.min, value.min);
|
|
scale.max = Math.max(scale.max, value.max);
|
|
}
|
|
}
|
|
|
|
module.exports = LinearScaleBase.extend({
|
|
determineDataLimits: function() {
|
|
var me = this;
|
|
var opts = me.options;
|
|
var chart = me.chart;
|
|
var datasets = chart.data.datasets;
|
|
var metasets = me._getMatchingVisibleMetas();
|
|
var hasStacks = opts.stacked;
|
|
var stacks = {};
|
|
var ilen = metasets.length;
|
|
var i, meta, data, values;
|
|
|
|
me.min = Number.POSITIVE_INFINITY;
|
|
me.max = Number.NEGATIVE_INFINITY;
|
|
|
|
if (hasStacks === undefined) {
|
|
for (i = 0; !hasStacks && i < ilen; ++i) {
|
|
meta = metasets[i];
|
|
hasStacks = meta.stack !== undefined;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < ilen; ++i) {
|
|
meta = metasets[i];
|
|
data = datasets[meta.index].data;
|
|
if (hasStacks) {
|
|
stackData(me, stacks, meta, data);
|
|
} else {
|
|
updateMinMax(me, meta, data);
|
|
}
|
|
}
|
|
|
|
helpers.each(stacks, function(stackValues) {
|
|
values = stackValues.pos.concat(stackValues.neg);
|
|
helpers._setMinAndMax(values, me);
|
|
});
|
|
|
|
me.min = helpers.isFinite(me.min) && !isNaN(me.min) ? me.min : DEFAULT_MIN;
|
|
me.max = helpers.isFinite(me.max) && !isNaN(me.max) ? me.max : DEFAULT_MAX;
|
|
|
|
// Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero
|
|
me.handleTickRangeOptions();
|
|
},
|
|
|
|
// Returns the maximum number of ticks based on the scale dimension
|
|
_computeTickLimit: function() {
|
|
var me = this;
|
|
var tickFont;
|
|
|
|
if (me.isHorizontal()) {
|
|
return Math.ceil(me.width / 40);
|
|
}
|
|
tickFont = helpers.options._parseFont(me.options.ticks);
|
|
return Math.ceil(me.height / tickFont.lineHeight);
|
|
},
|
|
|
|
/**
|
|
* Called after the ticks are built
|
|
* @private
|
|
*/
|
|
_handleDirectionalChanges: function(ticks) {
|
|
// If we are in a vertical orientation the top value is the highest so reverse the array
|
|
return this.isHorizontal() ? ticks : ticks.reverse();
|
|
},
|
|
|
|
getLabelForIndex: function(index, datasetIndex) {
|
|
return this._getScaleLabel(this.chart.data.datasets[datasetIndex].data[index]);
|
|
},
|
|
|
|
// Utils
|
|
getPixelForValue: function(value) {
|
|
var me = this;
|
|
return me.getPixelForDecimal((+me.getRightValue(value) - me._startValue) / me._valueRange);
|
|
},
|
|
|
|
getValueForPixel: function(pixel) {
|
|
return this._startValue + this.getDecimalForPixel(pixel) * this._valueRange;
|
|
},
|
|
|
|
getPixelForTick: function(index) {
|
|
var ticks = this._tickValues;
|
|
if (index < 0 || index > ticks.length - 1) {
|
|
return null;
|
|
}
|
|
return this.getPixelForValue(ticks[index]);
|
|
}
|
|
});
|
|
|
|
// INTERNAL: static default options, registered in src/index.js
|
|
module.exports._defaults = defaultConfig;
|