%PDF- %PDF-
| Direktori : /home/tjamichg/cursos.tjamich.gob.mx/web/assets/chart.js/src/scales/ |
| Current File : /home/tjamichg/cursos.tjamich.gob.mx/web/assets/chart.js/src/scales/scale.logarithmic.js |
'use strict';
var defaults = require('../core/core.defaults');
var helpers = require('../helpers/index');
var Scale = require('../core/core.scale');
var Ticks = require('../core/core.ticks');
var valueOrDefault = helpers.valueOrDefault;
var log10 = helpers.math.log10;
/**
* Generate a set of logarithmic ticks
* @param generationOptions the options used to generate the ticks
* @param dataRange the range of the data
* @returns {number[]} array of tick values
*/
function generateTicks(generationOptions, dataRange) {
var ticks = [];
var tickVal = valueOrDefault(generationOptions.min, Math.pow(10, Math.floor(log10(dataRange.min))));
var endExp = Math.floor(log10(dataRange.max));
var endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp));
var exp, significand;
if (tickVal === 0) {
exp = Math.floor(log10(dataRange.minNotZero));
significand = Math.floor(dataRange.minNotZero / Math.pow(10, exp));
ticks.push(tickVal);
tickVal = significand * Math.pow(10, exp);
} else {
exp = Math.floor(log10(tickVal));
significand = Math.floor(tickVal / Math.pow(10, exp));
}
var precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1;
do {
ticks.push(tickVal);
++significand;
if (significand === 10) {
significand = 1;
++exp;
precision = exp >= 0 ? 1 : precision;
}
tickVal = Math.round(significand * Math.pow(10, exp) * precision) / precision;
} while (exp < endExp || (exp === endExp && significand < endSignificand));
var lastTick = valueOrDefault(generationOptions.max, tickVal);
ticks.push(lastTick);
return ticks;
}
var defaultConfig = {
position: 'left',
// label settings
ticks: {
callback: Ticks.formatters.logarithmic
}
};
// TODO(v3): change this to positiveOrDefault
function nonNegativeOrDefault(value, defaultValue) {
return helpers.isFinite(value) && value >= 0 ? value : defaultValue;
}
module.exports = Scale.extend({
determineDataLimits: function() {
var me = this;
var opts = me.options;
var chart = me.chart;
var datasets = chart.data.datasets;
var isHorizontal = me.isHorizontal();
function IDMatches(meta) {
return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
}
var datasetIndex, meta, value, data, i, ilen;
// Calculate Range
me.min = Number.POSITIVE_INFINITY;
me.max = Number.NEGATIVE_INFINITY;
me.minNotZero = Number.POSITIVE_INFINITY;
var hasStacks = opts.stacked;
if (hasStacks === undefined) {
for (datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {
meta = chart.getDatasetMeta(datasetIndex);
if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&
meta.stack !== undefined) {
hasStacks = true;
break;
}
}
}
if (opts.stacked || hasStacks) {
var valuesPerStack = {};
for (datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {
meta = chart.getDatasetMeta(datasetIndex);
var key = [
meta.type,
// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined
((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),
meta.stack
].join('.');
if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
if (valuesPerStack[key] === undefined) {
valuesPerStack[key] = [];
}
data = datasets[datasetIndex].data;
for (i = 0, ilen = data.length; i < ilen; i++) {
var values = valuesPerStack[key];
value = me._parseValue(data[i]);
// invalid, hidden and negative values are ignored
if (isNaN(value.min) || isNaN(value.max) || meta.data[i].hidden || value.min < 0 || value.max < 0) {
continue;
}
values[i] = values[i] || 0;
values[i] += value.max;
}
}
}
helpers.each(valuesPerStack, function(valuesForType) {
if (valuesForType.length > 0) {
var minVal = helpers.min(valuesForType);
var maxVal = helpers.max(valuesForType);
me.min = Math.min(me.min, minVal);
me.max = Math.max(me.max, maxVal);
}
});
} else {
for (datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {
meta = chart.getDatasetMeta(datasetIndex);
if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
data = datasets[datasetIndex].data;
for (i = 0, ilen = data.length; i < ilen; i++) {
value = me._parseValue(data[i]);
// invalid, hidden and negative values are ignored
if (isNaN(value.min) || isNaN(value.max) || meta.data[i].hidden || value.min < 0 || value.max < 0) {
continue;
}
me.min = Math.min(value.min, me.min);
me.max = Math.max(value.max, me.max);
if (value.min !== 0) {
me.minNotZero = Math.min(value.min, me.minNotZero);
}
}
}
}
}
me.min = helpers.isFinite(me.min) ? me.min : null;
me.max = helpers.isFinite(me.max) ? me.max : null;
me.minNotZero = helpers.isFinite(me.minNotZero) ? me.minNotZero : null;
// Common base implementation to handle ticks.min, ticks.max
this.handleTickRangeOptions();
},
handleTickRangeOptions: function() {
var me = this;
var tickOpts = me.options.ticks;
var DEFAULT_MIN = 1;
var DEFAULT_MAX = 10;
me.min = nonNegativeOrDefault(tickOpts.min, me.min);
me.max = nonNegativeOrDefault(tickOpts.max, me.max);
if (me.min === me.max) {
if (me.min !== 0 && me.min !== null) {
me.min = Math.pow(10, Math.floor(log10(me.min)) - 1);
me.max = Math.pow(10, Math.floor(log10(me.max)) + 1);
} else {
me.min = DEFAULT_MIN;
me.max = DEFAULT_MAX;
}
}
if (me.min === null) {
me.min = Math.pow(10, Math.floor(log10(me.max)) - 1);
}
if (me.max === null) {
me.max = me.min !== 0
? Math.pow(10, Math.floor(log10(me.min)) + 1)
: DEFAULT_MAX;
}
if (me.minNotZero === null) {
if (me.min > 0) {
me.minNotZero = me.min;
} else if (me.max < 1) {
me.minNotZero = Math.pow(10, Math.floor(log10(me.max)));
} else {
me.minNotZero = DEFAULT_MIN;
}
}
},
buildTicks: function() {
var me = this;
var tickOpts = me.options.ticks;
var reverse = !me.isHorizontal();
var generationOptions = {
min: nonNegativeOrDefault(tickOpts.min),
max: nonNegativeOrDefault(tickOpts.max)
};
var ticks = me.ticks = generateTicks(generationOptions, me);
// At this point, we need to update our max and min given the tick values since we have expanded the
// range of the scale
me.max = helpers.max(ticks);
me.min = helpers.min(ticks);
if (tickOpts.reverse) {
reverse = !reverse;
me.start = me.max;
me.end = me.min;
} else {
me.start = me.min;
me.end = me.max;
}
if (reverse) {
ticks.reverse();
}
},
convertTicksToLabels: function() {
this.tickValues = this.ticks.slice();
Scale.prototype.convertTicksToLabels.call(this);
},
// Get the correct tooltip label
getLabelForIndex: function(index, datasetIndex) {
return this._getScaleLabel(this.chart.data.datasets[datasetIndex].data[index]);
},
getPixelForTick: function(index) {
var ticks = this.tickValues;
if (index < 0 || index > ticks.length - 1) {
return null;
}
return this.getPixelForValue(ticks[index]);
},
/**
* Returns the value of the first tick.
* @param {number} value - The minimum not zero value.
* @return {number} The first tick value.
* @private
*/
_getFirstTickValue: function(value) {
var exp = Math.floor(log10(value));
var significand = Math.floor(value / Math.pow(10, exp));
return significand * Math.pow(10, exp);
},
_configure: function() {
var me = this;
var start = me.min;
var offset = 0;
Scale.prototype._configure.call(me);
if (start === 0) {
start = me._getFirstTickValue(me.minNotZero);
offset = valueOrDefault(me.options.ticks.fontSize, defaults.global.defaultFontSize) / me._length;
}
me._startValue = log10(start);
me._valueOffset = offset;
me._valueRange = (log10(me.max) - log10(start)) / (1 - offset);
},
getPixelForValue: function(value) {
var me = this;
var decimal = 0;
value = +me.getRightValue(value);
if (value > me.min && value > 0) {
decimal = (log10(value) - me._startValue) / me._valueRange + me._valueOffset;
}
return me.getPixelForDecimal(decimal);
},
getValueForPixel: function(pixel) {
var me = this;
var decimal = me.getDecimalForPixel(pixel);
return decimal === 0 && me.min === 0
? 0
: Math.pow(10, me._startValue + (decimal - me._valueOffset) * me._valueRange);
}
});
// INTERNAL: static default options, registered in src/index.js
module.exports._defaults = defaultConfig;