|
| 1 | +/** |
| 2 | +* Copyright 2012-2018, Plotly, Inc. |
| 3 | +* All rights reserved. |
| 4 | +* |
| 5 | +* This source code is licensed under the MIT license found in the |
| 6 | +* LICENSE file in the root directory of this source tree. |
| 7 | +*/ |
| 8 | + |
| 9 | + |
| 10 | +'use strict'; |
| 11 | + |
| 12 | +var isNumeric = require('fast-isnumeric'); |
| 13 | +var Lib = require('../../lib'); |
| 14 | +var ONEDAY = require('../../constants/numerical').ONEDAY; |
| 15 | + |
| 16 | +/** |
| 17 | + * Return a validated dtick value for this axis |
| 18 | + * |
| 19 | + * @param {any} dtick: the candidate dtick. valid values are numbers and strings, |
| 20 | + * and further constrained depending on the axis type. |
| 21 | + * @param {string} axType: the axis type |
| 22 | + */ |
| 23 | +exports.dtick = function(dtick, axType) { |
| 24 | + var isLog = axType === 'log'; |
| 25 | + var isDate = axType === 'date'; |
| 26 | + var isCat = axType === 'category'; |
| 27 | + var dtickDflt = isDate ? ONEDAY : 1; |
| 28 | + |
| 29 | + if(!dtick) return dtickDflt; |
| 30 | + |
| 31 | + if(isNumeric(dtick)) { |
| 32 | + dtick = Number(dtick); |
| 33 | + if(dtick <= 0) return dtickDflt; |
| 34 | + if(isCat) { |
| 35 | + // category dtick must be positive integers |
| 36 | + return Math.max(1, Math.round(dtick)); |
| 37 | + } |
| 38 | + if(isDate) { |
| 39 | + // date dtick must be at least 0.1ms (our current precision) |
| 40 | + return Math.max(0.1, dtick); |
| 41 | + } |
| 42 | + return dtick; |
| 43 | + } |
| 44 | + |
| 45 | + if(typeof dtick !== 'string' || !(isDate || isLog)) { |
| 46 | + return dtickDflt; |
| 47 | + } |
| 48 | + |
| 49 | + var prefix = dtick.charAt(0); |
| 50 | + var dtickNum = dtick.substr(1); |
| 51 | + dtickNum = isNumeric(dtickNum) ? Number(dtickNum) : 0; |
| 52 | + |
| 53 | + if((dtickNum <= 0) || !( |
| 54 | + // "M<n>" gives ticks every (integer) n months |
| 55 | + (isDate && prefix === 'M' && dtickNum === Math.round(dtickNum)) || |
| 56 | + // "L<f>" gives ticks linearly spaced in data (not in position) every (float) f |
| 57 | + (isLog && prefix === 'L') || |
| 58 | + // "D1" gives powers of 10 with all small digits between, "D2" gives only 2 and 5 |
| 59 | + (isLog && prefix === 'D' && (dtickNum === 1 || dtickNum === 2)) |
| 60 | + )) { |
| 61 | + return dtickDflt; |
| 62 | + } |
| 63 | + |
| 64 | + return dtick; |
| 65 | +}; |
| 66 | + |
| 67 | +/** |
| 68 | + * Return a validated tick0 for this axis |
| 69 | + * |
| 70 | + * @param {any} tick0: the candidate tick0. Valid values are numbers and strings, |
| 71 | + * further constrained depending on the axis type |
| 72 | + * @param {string} axType: the axis type |
| 73 | + * @param {string} calendar: for date axes, the calendar to validate/convert with |
| 74 | + * @param {any} dtick: an already valid dtick. Only used for D1 and D2 log dticks, |
| 75 | + * which do not support tick0 at all. |
| 76 | + */ |
| 77 | +exports.tick0 = function(tick0, axType, calendar, dtick) { |
| 78 | + if(axType === 'date') { |
| 79 | + return Lib.cleanDate(tick0, Lib.dateTick0(calendar)); |
| 80 | + } |
| 81 | + if(dtick === 'D1' || dtick === 'D2') { |
| 82 | + // D1 and D2 modes ignore tick0 entirely |
| 83 | + return undefined; |
| 84 | + } |
| 85 | + // Aside from date axes, tick0 must be numeric |
| 86 | + return isNumeric(tick0) ? Number(tick0) : 0; |
| 87 | +}; |
0 commit comments