%PDF-1.5 %���� ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµùÕ5sLOšuY
Server IP : 49.231.201.246 / Your IP : 216.73.216.149 Web Server : Apache/2.4.18 (Ubuntu) System : Linux 246 4.4.0-210-generic #242-Ubuntu SMP Fri Apr 16 09:57:56 UTC 2021 x86_64 User : root ( 0) PHP Version : 7.0.33-0ubuntu0.16.04.16 Disable Function : exec,passthru,shell_exec,system,proc_open,popen,pcntl_exec MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /proc/11585/root/var/www/html/ppaobm/vendor/bower-asset/chartjs/src/scales/ |
Upload File : |
'use strict'; var adapters = require('../core/core.adapters'); var defaults = require('../core/core.defaults'); var helpers = require('../helpers/index'); var Scale = require('../core/core.scale'); var valueOrDefault = helpers.valueOrDefault; // Integer constants are from the ES6 spec. var MIN_INTEGER = Number.MIN_SAFE_INTEGER || -9007199254740991; var MAX_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; var INTERVALS = { millisecond: { common: true, size: 1, steps: [1, 2, 5, 10, 20, 50, 100, 250, 500] }, second: { common: true, size: 1000, steps: [1, 2, 5, 10, 15, 30] }, minute: { common: true, size: 60000, steps: [1, 2, 5, 10, 15, 30] }, hour: { common: true, size: 3600000, steps: [1, 2, 3, 6, 12] }, day: { common: true, size: 86400000, steps: [1, 2, 5] }, week: { common: false, size: 604800000, steps: [1, 2, 3, 4] }, month: { common: true, size: 2.628e9, steps: [1, 2, 3] }, quarter: { common: false, size: 7.884e9, steps: [1, 2, 3, 4] }, year: { common: true, size: 3.154e10 } }; var UNITS = Object.keys(INTERVALS); function sorter(a, b) { return a - b; } function arrayUnique(items) { var hash = {}; var out = []; var i, ilen, item; for (i = 0, ilen = items.length; i < ilen; ++i) { item = items[i]; if (!hash[item]) { hash[item] = true; out.push(item); } } return out; } /** * Returns an array of {time, pos} objects used to interpolate a specific `time` or position * (`pos`) on the scale, by searching entries before and after the requested value. `pos` is * a decimal between 0 and 1: 0 being the start of the scale (left or top) and 1 the other * extremity (left + width or top + height). Note that it would be more optimized to directly * store pre-computed pixels, but the scale dimensions are not guaranteed at the time we need * to create the lookup table. The table ALWAYS contains at least two items: min and max. * * @param {number[]} timestamps - timestamps sorted from lowest to highest. * @param {string} distribution - If 'linear', timestamps will be spread linearly along the min * and max range, so basically, the table will contains only two items: {min, 0} and {max, 1}. * If 'series', timestamps will be positioned at the same distance from each other. In this * case, only timestamps that break the time linearity are registered, meaning that in the * best case, all timestamps are linear, the table contains only min and max. */ function buildLookupTable(timestamps, min, max, distribution) { if (distribution === 'linear' || !timestamps.length) { return [ {time: min, pos: 0}, {time: max, pos: 1} ]; } var table = []; var items = [min]; var i, ilen, prev, curr, next; for (i = 0, ilen = timestamps.length; i < ilen; ++i) { curr = timestamps[i]; if (curr > min && curr < max) { items.push(curr); } } items.push(max); for (i = 0, ilen = items.length; i < ilen; ++i) { next = items[i + 1]; prev = items[i - 1]; curr = items[i]; // only add points that breaks the scale linearity if (prev === undefined || next === undefined || Math.round((next + prev) / 2) !== curr) { table.push({time: curr, pos: i / (ilen - 1)}); } } return table; } // @see adapted from https://www.anujgakhar.com/2014/03/01/binary-search-in-javascript/ function lookup(table, key, value) { var lo = 0; var hi = table.length - 1; var mid, i0, i1; while (lo >= 0 && lo <= hi) { mid = (lo + hi) >> 1; i0 = table[mid - 1] || null; i1 = table[mid]; if (!i0) { // given value is outside table (before first item) return {lo: null, hi: i1}; } else if (i1[key] < value) { lo = mid + 1; } else if (i0[key] > value) { hi = mid - 1; } else { return {lo: i0, hi: i1}; } } // given value is outside table (after last item) return {lo: i1, hi: null}; } /** * Linearly interpolates the given source `value` using the table items `skey` values and * returns the associated `tkey` value. For example, interpolate(table, 'time', 42, 'pos') * returns the position for a timestamp equal to 42. If value is out of bounds, values at * index [0, 1] or [n - 1, n] are used for the interpolation. */ function interpolate(table, skey, sval, tkey) { var range = lookup(table, skey, sval); // Note: the lookup table ALWAYS contains at least 2 items (min and max) var prev = !range.lo ? table[0] : !range.hi ? table[table.length - 2] : range.lo; var next = !range.lo ? table[1] : !range.hi ? table[table.length - 1] : range.hi; var span = next[skey] - prev[skey]; var ratio = span ? (sval - prev[skey]) / span : 0; var offset = (next[tkey] - prev[tkey]) * ratio; return prev[tkey] + offset; } function toTimestamp(scale, input) { var adapter = scale._adapter; var options = scale.options.time; var parser = options.parser; var format = parser || options.format; var value = input; if (typeof parser === 'function') { value = parser(value); } // Only parse if its not a timestamp already if (!helpers.isFinite(value)) { value = typeof format === 'string' ? adapter.parse(value, format) : adapter.parse(value); } if (value !== null) { return +value; } // Labels are in an incompatible format and no `parser` has been provided. // The user might still use the deprecated `format` option for parsing. if (!parser && typeof format === 'function') { value = format(input); // `format` could return something else than a timestamp, if so, parse it if (!helpers.isFinite(value)) { value = adapter.parse(value); } } return value; } function parse(scale, input) { if (helpers.isNullOrUndef(input)) { return null; } var options = scale.options.time; var value = toTimestamp(scale, scale.getRightValue(input)); if (value === null) { return value; } if (options.round) { value = +scale._adapter.startOf(value, options.round); } return value; } /** * Returns the number of unit to skip to be able to display up to `capacity` number of ticks * in `unit` for the given `min` / `max` range and respecting the interval steps constraints. */ function determineStepSize(min, max, unit, capacity) { var range = max - min; var interval = INTERVALS[unit]; var milliseconds = interval.size; var steps = interval.steps; var i, ilen, factor; if (!steps) { return Math.ceil(range / (capacity * milliseconds)); } for (i = 0, ilen = steps.length; i < ilen; ++i) { factor = steps[i]; if (Math.ceil(range / (milliseconds * factor)) <= capacity) { break; } } return factor; } /** * Figures out what unit results in an appropriate number of auto-generated ticks */ function determineUnitForAutoTicks(minUnit, min, max, capacity) { var ilen = UNITS.length; var i, interval, factor; for (i = UNITS.indexOf(minUnit); i < ilen - 1; ++i) { interval = INTERVALS[UNITS[i]]; factor = interval.steps ? interval.steps[interval.steps.length - 1] : MAX_INTEGER; if (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) { return UNITS[i]; } } return UNITS[ilen - 1]; } /** * Figures out what unit to format a set of ticks with */ function determineUnitForFormatting(scale, ticks, minUnit, min, max) { var ilen = UNITS.length; var i, unit; for (i = ilen - 1; i >= UNITS.indexOf(minUnit); i--) { unit = UNITS[i]; if (INTERVALS[unit].common && scale._adapter.diff(max, min, unit) >= ticks.length) { return unit; } } return UNITS[minUnit ? UNITS.indexOf(minUnit) : 0]; } function determineMajorUnit(unit) { for (var i = UNITS.indexOf(unit) + 1, ilen = UNITS.length; i < ilen; ++i) { if (INTERVALS[UNITS[i]].common) { return UNITS[i]; } } } /** * Generates a maximum of `capacity` timestamps between min and max, rounded to the * `minor` unit, aligned on the `major` unit and using the given scale time `options`. * Important: this method can return ticks outside the min and max range, it's the * responsibility of the calling code to clamp values if needed. */ function generate(scale, min, max, capacity) { var adapter = scale._adapter; var options = scale.options; var timeOpts = options.time; var minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, capacity); var major = determineMajorUnit(minor); var stepSize = valueOrDefault(timeOpts.stepSize, timeOpts.unitStepSize); var weekday = minor === 'week' ? timeOpts.isoWeekday : false; var majorTicksEnabled = options.ticks.major.enabled; var interval = INTERVALS[minor]; var first = min; var last = max; var ticks = []; var time; if (!stepSize) { stepSize = determineStepSize(min, max, minor, capacity); } // For 'week' unit, handle the first day of week option if (weekday) { first = +adapter.startOf(first, 'isoWeek', weekday); last = +adapter.startOf(last, 'isoWeek', weekday); } // Align first/last ticks on unit first = +adapter.startOf(first, weekday ? 'day' : minor); last = +adapter.startOf(last, weekday ? 'day' : minor); // Make sure that the last tick include max if (last < max) { last = +adapter.add(last, 1, minor); } time = first; if (majorTicksEnabled && major && !weekday && !timeOpts.round) { // Align the first tick on the previous `minor` unit aligned on the `major` unit: // we first aligned time on the previous `major` unit then add the number of full // stepSize there is between first and the previous major time. time = +adapter.startOf(time, major); time = +adapter.add(time, ~~((first - time) / (interval.size * stepSize)) * stepSize, minor); } for (; time < last; time = +adapter.add(time, stepSize, minor)) { ticks.push(+time); } ticks.push(+time); return ticks; } /** * Returns the start and end offsets from edges in the form of {start, end} * where each value is a relative width to the scale and ranges between 0 and 1. * They add extra margins on the both sides by scaling down the original scale. * Offsets are added when the `offset` option is true. */ function computeOffsets(table, ticks, min, max, options) { var start = 0; var end = 0; var first, last; if (options.offset && ticks.length) { if (!options.time.min) { first = interpolate(table, 'time', ticks[0], 'pos'); if (ticks.length === 1) { start = 1 - first; } else { start = (interpolate(table, 'time', ticks[1], 'pos') - first) / 2; } } if (!options.time.max) { last = interpolate(table, 'time', ticks[ticks.length - 1], 'pos'); if (ticks.length === 1) { end = last; } else { end = (last - interpolate(table, 'time', ticks[ticks.length - 2], 'pos')) / 2; } } } return {start: start, end: end}; } function ticksFromTimestamps(scale, values, majorUnit) { var ticks = []; var i, ilen, value, major; for (i = 0, ilen = values.length; i < ilen; ++i) { value = values[i]; major = majorUnit ? value === +scale._adapter.startOf(value, majorUnit) : false; ticks.push({ value: value, major: major }); } return ticks; } var defaultConfig = { position: 'bottom', /** * Data distribution along the scale: * - 'linear': data are spread according to their time (distances can vary), * - 'series': data are spread at the same distance from each other. * @see https://github.com/chartjs/Chart.js/pull/4507 * @since 2.7.0 */ distribution: 'linear', /** * Scale boundary strategy (bypassed by min/max time options) * - `data`: make sure data are fully visible, ticks outside are removed * - `ticks`: make sure ticks are fully visible, data outside are truncated * @see https://github.com/chartjs/Chart.js/pull/4556 * @since 2.7.0 */ bounds: 'data', adapters: {}, time: { parser: false, // false == a pattern string from https://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment format: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from https://momentjs.com/docs/#/parsing/string-format/ unit: false, // false == automatic or override with week, month, year, etc. round: false, // none, or override with week, month, year, etc. displayFormat: false, // DEPRECATED isoWeekday: false, // override week start day - see https://momentjs.com/docs/#/get-set/iso-weekday/ minUnit: 'millisecond', displayFormats: {} }, ticks: { autoSkip: false, /** * Ticks generation input values: * - 'auto': generates "optimal" ticks based on scale size and time options. * - 'data': generates ticks from data (including labels from data {t|x|y} objects). * - 'labels': generates ticks from user given `data.labels` values ONLY. * @see https://github.com/chartjs/Chart.js/pull/4507 * @since 2.7.0 */ source: 'auto', major: { enabled: false } } }; module.exports = Scale.extend({ initialize: function() { this.mergeTicksOptions(); Scale.prototype.initialize.call(this); }, update: function() { var me = this; var options = me.options; var time = options.time || (options.time = {}); var adapter = me._adapter = new adapters._date(options.adapters.date); // DEPRECATIONS: output a message only one time per update if (time.format) { console.warn('options.time.format is deprecated and replaced by options.time.parser.'); } // Backward compatibility: before introducing adapter, `displayFormats` was // supposed to contain *all* unit/string pairs but this can't be resolved // when loading the scale (adapters are loaded afterward), so let's populate // missing formats on update helpers.mergeIf(time.displayFormats, adapter.formats()); return Scale.prototype.update.apply(me, arguments); }, /** * Allows data to be referenced via 't' attribute */ getRightValue: function(rawValue) { if (rawValue && rawValue.t !== undefined) { rawValue = rawValue.t; } return Scale.prototype.getRightValue.call(this, rawValue); }, determineDataLimits: function() { var me = this; var chart = me.chart; var adapter = me._adapter; var timeOpts = me.options.time; var unit = timeOpts.unit || 'day'; var min = MAX_INTEGER; var max = MIN_INTEGER; var timestamps = []; var datasets = []; var labels = []; var i, j, ilen, jlen, data, timestamp; var dataLabels = chart.data.labels || []; // Convert labels to timestamps for (i = 0, ilen = dataLabels.length; i < ilen; ++i) { labels.push(parse(me, dataLabels[i])); } // Convert data to timestamps for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { if (chart.isDatasetVisible(i)) { data = chart.data.datasets[i].data; // Let's consider that all data have the same format. if (helpers.isObject(data[0])) { datasets[i] = []; for (j = 0, jlen = data.length; j < jlen; ++j) { timestamp = parse(me, data[j]); timestamps.push(timestamp); datasets[i][j] = timestamp; } } else { for (j = 0, jlen = labels.length; j < jlen; ++j) { timestamps.push(labels[j]); } datasets[i] = labels.slice(0); } } else { datasets[i] = []; } } if (labels.length) { // Sort labels **after** data have been converted labels = arrayUnique(labels).sort(sorter); min = Math.min(min, labels[0]); max = Math.max(max, labels[labels.length - 1]); } if (timestamps.length) { timestamps = arrayUnique(timestamps).sort(sorter); min = Math.min(min, timestamps[0]); max = Math.max(max, timestamps[timestamps.length - 1]); } min = parse(me, timeOpts.min) || min; max = parse(me, timeOpts.max) || max; // In case there is no valid min/max, set limits based on unit time option min = min === MAX_INTEGER ? +adapter.startOf(Date.now(), unit) : min; max = max === MIN_INTEGER ? +adapter.endOf(Date.now(), unit) + 1 : max; // Make sure that max is strictly higher than min (required by the lookup table) me.min = Math.min(min, max); me.max = Math.max(min + 1, max); // PRIVATE me._horizontal = me.isHorizontal(); me._table = []; me._timestamps = { data: timestamps, datasets: datasets, labels: labels }; }, buildTicks: function() { var me = this; var min = me.min; var max = me.max; var options = me.options; var timeOpts = options.time; var timestamps = []; var ticks = []; var i, ilen, timestamp; switch (options.ticks.source) { case 'data': timestamps = me._timestamps.data; break; case 'labels': timestamps = me._timestamps.labels; break; case 'auto': default: timestamps = generate(me, min, max, me.getLabelCapacity(min), options); } if (options.bounds === 'ticks' && timestamps.length) { min = timestamps[0]; max = timestamps[timestamps.length - 1]; } // Enforce limits with user min/max options min = parse(me, timeOpts.min) || min; max = parse(me, timeOpts.max) || max; // Remove ticks outside the min/max range for (i = 0, ilen = timestamps.length; i < ilen; ++i) { timestamp = timestamps[i]; if (timestamp >= min && timestamp <= max) { ticks.push(timestamp); } } me.min = min; me.max = max; // PRIVATE me._unit = timeOpts.unit || determineUnitForFormatting(me, ticks, timeOpts.minUnit, me.min, me.max); me._majorUnit = determineMajorUnit(me._unit); me._table = buildLookupTable(me._timestamps.data, min, max, options.distribution); me._offsets = computeOffsets(me._table, ticks, min, max, options); if (options.ticks.reverse) { ticks.reverse(); } return ticksFromTimestamps(me, ticks, me._majorUnit); }, getLabelForIndex: function(index, datasetIndex) { var me = this; var adapter = me._adapter; var data = me.chart.data; var timeOpts = me.options.time; var label = data.labels && index < data.labels.length ? data.labels[index] : ''; var value = data.datasets[datasetIndex].data[index]; if (helpers.isObject(value)) { label = me.getRightValue(value); } if (timeOpts.tooltipFormat) { return adapter.format(toTimestamp(me, label), timeOpts.tooltipFormat); } if (typeof label === 'string') { return label; } return adapter.format(toTimestamp(me, label), timeOpts.displayFormats.datetime); }, /** * Function to format an individual tick mark * @private */ tickFormatFunction: function(time, index, ticks, format) { var me = this; var adapter = me._adapter; var options = me.options; var formats = options.time.displayFormats; var minorFormat = formats[me._unit]; var majorUnit = me._majorUnit; var majorFormat = formats[majorUnit]; var majorTime = +adapter.startOf(time, majorUnit); var majorTickOpts = options.ticks.major; var major = majorTickOpts.enabled && majorUnit && majorFormat && time === majorTime; var label = adapter.format(time, format ? format : major ? majorFormat : minorFormat); var tickOpts = major ? majorTickOpts : options.ticks.minor; var formatter = valueOrDefault(tickOpts.callback, tickOpts.userCallback); return formatter ? formatter(label, index, ticks) : label; }, convertTicksToLabels: function(ticks) { var labels = []; var i, ilen; for (i = 0, ilen = ticks.length; i < ilen; ++i) { labels.push(this.tickFormatFunction(ticks[i].value, i, ticks)); } return labels; }, /** * @private */ getPixelForOffset: function(time) { var me = this; var isReverse = me.options.ticks.reverse; var size = me._horizontal ? me.width : me.height; var start = me._horizontal ? isReverse ? me.right : me.left : isReverse ? me.bottom : me.top; var pos = interpolate(me._table, 'time', time, 'pos'); var offset = size * (me._offsets.start + pos) / (me._offsets.start + 1 + me._offsets.end); return isReverse ? start - offset : start + offset; }, getPixelForValue: function(value, index, datasetIndex) { var me = this; var time = null; if (index !== undefined && datasetIndex !== undefined) { time = me._timestamps.datasets[datasetIndex][index]; } if (time === null) { time = parse(me, value); } if (time !== null) { return me.getPixelForOffset(time); } }, getPixelForTick: function(index) { var ticks = this.getTicks(); return index >= 0 && index < ticks.length ? this.getPixelForOffset(ticks[index].value) : null; }, getValueForPixel: function(pixel) { var me = this; var size = me._horizontal ? me.width : me.height; var start = me._horizontal ? me.left : me.top; var pos = (size ? (pixel - start) / size : 0) * (me._offsets.start + 1 + me._offsets.start) - me._offsets.end; var time = interpolate(me._table, 'pos', pos, 'time'); // DEPRECATION, we should return time directly return me._adapter._create(time); }, /** * Crude approximation of what the label width might be * @private */ getLabelWidth: function(label) { var me = this; var ticksOpts = me.options.ticks; var tickLabelWidth = me.ctx.measureText(label).width; var angle = helpers.toRadians(ticksOpts.maxRotation); var cosRotation = Math.cos(angle); var sinRotation = Math.sin(angle); var tickFontSize = valueOrDefault(ticksOpts.fontSize, defaults.global.defaultFontSize); return (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation); }, /** * @private */ getLabelCapacity: function(exampleTime) { var me = this; // pick the longest format (milliseconds) for guestimation var format = me.options.time.displayFormats.millisecond; var exampleLabel = me.tickFormatFunction(exampleTime, 0, [], format); var tickLabelWidth = me.getLabelWidth(exampleLabel); var innerWidth = me.isHorizontal() ? me.width : me.height; var capacity = Math.floor(innerWidth / tickLabelWidth); return capacity > 0 ? capacity : 1; } }); // INTERNAL: static default options, registered in src/index.js module.exports._defaults = defaultConfig;