tick_generator.js 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  1. /**
  2. * DevExtreme (viz/axes/tick_generator.js)
  3. * Version: 19.1.16
  4. * Build date: Tue Oct 18 2022
  5. *
  6. * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
  7. * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
  8. */
  9. "use strict";
  10. var _utils = require("../core/utils");
  11. var _date = require("../../core/utils/date");
  12. var _date2 = _interopRequireDefault(_date);
  13. var _type = require("../../core/utils/type");
  14. var _math = require("../../core/utils/math");
  15. var _extend = require("../../core/utils/extend");
  16. function _interopRequireDefault(obj) {
  17. return obj && obj.__esModule ? obj : {
  18. "default": obj
  19. }
  20. }
  21. function _slicedToArray(arr, i) {
  22. return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest()
  23. }
  24. function _nonIterableRest() {
  25. throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
  26. }
  27. function _unsupportedIterableToArray(o, minLen) {
  28. if (!o) {
  29. return
  30. }
  31. if ("string" === typeof o) {
  32. return _arrayLikeToArray(o, minLen)
  33. }
  34. var n = Object.prototype.toString.call(o).slice(8, -1);
  35. if ("Object" === n && o.constructor) {
  36. n = o.constructor.name
  37. }
  38. if ("Map" === n || "Set" === n) {
  39. return Array.from(o)
  40. }
  41. if ("Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) {
  42. return _arrayLikeToArray(o, minLen)
  43. }
  44. }
  45. function _arrayLikeToArray(arr, len) {
  46. if (null == len || len > arr.length) {
  47. len = arr.length
  48. }
  49. for (var i = 0, arr2 = new Array(len); i < len; i++) {
  50. arr2[i] = arr[i]
  51. }
  52. return arr2
  53. }
  54. function _iterableToArrayLimit(arr, i) {
  55. var _i = null == arr ? null : "undefined" !== typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"];
  56. if (null == _i) {
  57. return
  58. }
  59. var _arr = [];
  60. var _n = true;
  61. var _d = false;
  62. var _s, _e;
  63. try {
  64. for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
  65. _arr.push(_s.value);
  66. if (i && _arr.length === i) {
  67. break
  68. }
  69. }
  70. } catch (err) {
  71. _d = true;
  72. _e = err
  73. } finally {
  74. try {
  75. if (!_n && null != _i.return) {
  76. _i.return()
  77. }
  78. } finally {
  79. if (_d) {
  80. throw _e
  81. }
  82. }
  83. }
  84. return _arr
  85. }
  86. function _arrayWithHoles(arr) {
  87. if (Array.isArray(arr)) {
  88. return arr
  89. }
  90. }
  91. var convertDateUnitToMilliseconds = _date2.default.convertDateUnitToMilliseconds;
  92. var dateToMilliseconds = _date2.default.dateToMilliseconds;
  93. var math = Math;
  94. var mathAbs = math.abs;
  95. var mathFloor = math.floor;
  96. var mathCeil = math.ceil;
  97. var mathPow = math.pow;
  98. var NUMBER_MULTIPLIERS = [1, 2, 2.5, 5];
  99. var LOGARITHMIC_MULTIPLIERS = [1, 2, 3, 5];
  100. var DATETIME_MULTIPLIERS = {
  101. millisecond: [1, 2, 5, 10, 25, 50, 100, 250, 500],
  102. second: [1, 2, 3, 5, 10, 15, 20, 30],
  103. minute: [1, 2, 3, 5, 10, 15, 20, 30],
  104. hour: [1, 2, 3, 4, 6, 8, 12],
  105. day: [1, 2],
  106. week: [1, 2],
  107. month: [1, 2, 3, 6]
  108. };
  109. var DATETIME_MULTIPLIERS_WITH_BIG_WEEKEND = (0, _extend.extend)({}, DATETIME_MULTIPLIERS, {
  110. day: [1]
  111. });
  112. var DATETIME_MINOR_MULTIPLIERS = {
  113. millisecond: [1, 2, 5, 10, 25, 50, 100, 250, 500],
  114. second: [1, 2, 3, 5, 10, 15, 20, 30],
  115. minute: [1, 2, 3, 5, 10, 15, 20, 30],
  116. hour: [1, 2, 3, 4, 6, 8, 12],
  117. day: [1, 2, 3, 7, 14],
  118. month: [1, 2, 3, 6]
  119. };
  120. var MINOR_DELIMITERS = [2, 4, 5, 8, 10];
  121. var VISIBILITY_DELIMITER = 3;
  122. var MINUTE = 6e4;
  123. function dummyGenerator(options) {
  124. return function(data, screenDelta, tickInterval, forceTickInterval) {
  125. var count = mathFloor(screenDelta / options.axisDivisionFactor);
  126. count = count < 1 ? 1 : count;
  127. var interval = screenDelta / count;
  128. return {
  129. ticks: interval > 0 ? Array.apply(null, new Array(count + 1)).map(function(_, i) {
  130. return interval * i
  131. }) : [],
  132. tickInterval: interval
  133. }
  134. }
  135. }
  136. function discreteGenerator(options) {
  137. return function(data, screenDelta, tickInterval, forceTickInterval) {
  138. var categories = (0, _utils.getCategoriesInfo)(data.categories, data.min, data.max).categories;
  139. return {
  140. ticks: categories,
  141. tickInterval: mathCeil(categories.length * options.axisDivisionFactor / screenDelta)
  142. }
  143. }
  144. }
  145. var getValue = function(value) {
  146. return value
  147. };
  148. var getLogValue = function(base) {
  149. return function(value) {
  150. return (0, _utils.getLog)(value, base)
  151. }
  152. };
  153. var raiseTo = function(base) {
  154. return function(value) {
  155. return mathPow(base, value)
  156. }
  157. };
  158. var correctValueByInterval = function(post, round, getValue) {
  159. return function(value, interval) {
  160. return (0, _math.adjust)(post(round((0, _math.adjust)(getValue(value) / interval)) * interval))
  161. }
  162. };
  163. function correctMinValueByEndOnTick(floorFunc, ceilFunc, resolveEndOnTick, endOnTick) {
  164. if ((0, _type.isDefined)(endOnTick)) {
  165. return endOnTick ? floorFunc : ceilFunc
  166. }
  167. return function(value, interval, businessViewInfo, forceEndOnTick) {
  168. var floorTickValue = floorFunc(value, interval);
  169. if (value - floorTickValue === 0 || !(0, _type.isDefined)(businessViewInfo) || resolveEndOnTick(value, floorTickValue, interval, businessViewInfo) || forceEndOnTick) {
  170. return floorTickValue
  171. }
  172. return ceilFunc(value, interval)
  173. }
  174. }
  175. function resolveEndOnTick(curValue, tickValue, interval, businessViewInfo) {
  176. var prevTickDataDiff = interval - mathAbs(tickValue - curValue);
  177. var intervalCount = math.max(mathCeil(businessViewInfo.businessDelta / interval), 2);
  178. var businessRatio = businessViewInfo.screenDelta / (intervalCount * interval);
  179. var potentialTickScreenDiff = math.round(businessRatio * prevTickDataDiff);
  180. var delimiterFactor = (0, _utils.getLog)(businessRatio * interval / businessViewInfo.axisDivisionFactor, 2) + 1;
  181. var delimiterMultiplier = (businessViewInfo.isSpacedMargin ? 2 : 1) * delimiterFactor;
  182. var screenDelimiter = math.round(VISIBILITY_DELIMITER * delimiterMultiplier);
  183. return businessViewInfo.businessDelta > businessViewInfo.interval && potentialTickScreenDiff >= screenDelimiter
  184. }
  185. function resolveEndOnTickLog(base) {
  186. return function(curValue, tickValue, interval, businessViewInfo) {
  187. return resolveEndOnTick((0, _utils.getLog)(curValue, base), (0, _utils.getLog)(tickValue, base), interval, businessViewInfo)
  188. }
  189. }
  190. function resolveEndOnTickDate(curValue, tickValue, interval, businessViewInfo) {
  191. return resolveEndOnTick(curValue.valueOf(), tickValue.valueOf(), dateToMilliseconds(interval), businessViewInfo)
  192. }
  193. function resolveExtraTickForHiddenDataPoint(checkDataVisibility, extremum, tick, businessViewInfo, isMin) {
  194. var screenRatio = businessViewInfo.screenDelta / businessViewInfo.businessDelta;
  195. var extDir = isMin ? 1 : -1;
  196. var tickDir = isMin ? -1 : 1;
  197. return checkDataVisibility && screenRatio * (extremum * extDir + tick * tickDir) < VISIBILITY_DELIMITER
  198. }
  199. function resolveExtraTickForHiddenDataPointLog(base) {
  200. return function(checkDataVisibility, extremum, tick, businessViewInfo, isMin) {
  201. return resolveExtraTickForHiddenDataPoint(checkDataVisibility, (0, _utils.getLog)(extremum, base), (0, _utils.getLog)(tick, base), businessViewInfo, isMin)
  202. }
  203. }
  204. function resolveExtraTickForHiddenDataPointDate(checkDataVisibility, extremum, tick, businessViewInfo, isMin) {
  205. return resolveExtraTickForHiddenDataPoint(checkDataVisibility, extremum.valueOf(), tick.valueOf(), businessViewInfo, isMin)
  206. }
  207. function getBusinessDelta(data, breaks) {
  208. var spacing = 0;
  209. if (breaks) {
  210. spacing = breaks.reduce(function(prev, item) {
  211. return prev + (item.to - item.from)
  212. }, 0)
  213. }
  214. return mathAbs(data.max - data.min - spacing)
  215. }
  216. function getBusinessDeltaLog(base) {
  217. var getLog = getLogValue(base);
  218. return function(data, breaks) {
  219. var spacing = 0;
  220. if (breaks) {
  221. spacing = breaks.reduce(function(prev, item) {
  222. return prev + mathAbs(getLog(item.to / item.from))
  223. }, 0)
  224. }
  225. return mathCeil(mathAbs(getLog(data.max / data.min)) - spacing)
  226. }
  227. }
  228. function getIntervalByFactor(businessDelta, screenDelta, axisDivisionFactor, addTickCount) {
  229. var count = screenDelta / axisDivisionFactor - (addTickCount || 0);
  230. count = count < 1 ? 1 : count;
  231. return businessDelta / count
  232. }
  233. function getMultiplierFactor(interval, factorDelta) {
  234. return mathPow(10, mathFloor((0, _utils.getLog)(interval, 10)) + (factorDelta || 0))
  235. }
  236. function calculateTickInterval(businessDelta, screenDelta, tickInterval, forceTickInterval, axisDivisionFactor, multipliers, allowDecimals, addTickCount, _, minTickInterval) {
  237. var interval = getIntervalByFactor(businessDelta, screenDelta, axisDivisionFactor, addTickCount);
  238. var result = 1;
  239. var onlyIntegers = false === allowDecimals;
  240. if (!forceTickInterval || !tickInterval) {
  241. if (interval >= 1 || !onlyIntegers && interval > 0) {
  242. result = adjustInterval(interval, multipliers, onlyIntegers)
  243. }
  244. if (!tickInterval || !forceTickInterval && tickInterval < result) {
  245. tickInterval = result
  246. }
  247. }
  248. if (!forceTickInterval && minTickInterval) {
  249. minTickInterval = adjustInterval(minTickInterval, multipliers, onlyIntegers);
  250. if (minTickInterval > tickInterval) {
  251. tickInterval = minTickInterval
  252. }
  253. }
  254. return tickInterval
  255. }
  256. function adjustInterval(interval, multipliers, onlyIntegers) {
  257. var factor = getMultiplierFactor(interval, -1);
  258. var result = 1;
  259. multipliers = multipliers || NUMBER_MULTIPLIERS;
  260. if (interval > 0) {
  261. interval /= factor;
  262. result = multipliers.concat(10 * multipliers[0]).map(function(m) {
  263. return 10 * m
  264. }).reduce(function(r, m) {
  265. if (.1 === factor && onlyIntegers && 25 === m) {
  266. return r
  267. }
  268. return r < interval ? m : r
  269. }, 0);
  270. result = (0, _math.adjust)(result * factor, factor)
  271. }
  272. return result
  273. }
  274. function calculateMinorTickInterval(businessDelta, screenDelta, tickInterval, axisDivisionFactor) {
  275. var interval = getIntervalByFactor(businessDelta, screenDelta, axisDivisionFactor);
  276. return tickInterval || MINOR_DELIMITERS.reduce(function(r, d) {
  277. var cur = businessDelta / d;
  278. return cur >= interval ? cur : r
  279. }, 0)
  280. }
  281. function getCalculateTickIntervalLog(skipCalculationLimits) {
  282. return function(businessDelta, screenDelta, tickInterval, forceTickInterval, axisDivisionFactor, multipliers, allowDecimals, _, __, minTickInterval) {
  283. var interval = getIntervalByFactor(businessDelta, screenDelta, axisDivisionFactor);
  284. var result = 0;
  285. var adjustInterval = getAdjustIntervalLog(skipCalculationLimits);
  286. if (!forceTickInterval || !tickInterval) {
  287. if (interval > 0) {
  288. result = adjustInterval(interval, multipliers)
  289. }
  290. if (!tickInterval || !forceTickInterval && tickInterval < result) {
  291. tickInterval = result
  292. }
  293. }
  294. if (!forceTickInterval && minTickInterval) {
  295. minTickInterval = adjustInterval(minTickInterval, multipliers);
  296. if (minTickInterval > tickInterval) {
  297. tickInterval = minTickInterval
  298. }
  299. }
  300. return tickInterval
  301. }
  302. }
  303. function getAdjustIntervalLog(skipCalculationLimits) {
  304. return function(interval, multipliers) {
  305. var factor = getMultiplierFactor(interval);
  306. multipliers = multipliers || LOGARITHMIC_MULTIPLIERS;
  307. if (!skipCalculationLimits && factor < 1) {
  308. factor = 1
  309. }
  310. return multipliers.concat(10 * multipliers[0]).reduce(function(r, m) {
  311. return r < interval ? m * factor : r
  312. }, 0)
  313. }
  314. }
  315. function getDataTimeMultipliers(gapSize) {
  316. if (gapSize && gapSize > 2) {
  317. return DATETIME_MULTIPLIERS_WITH_BIG_WEEKEND
  318. } else {
  319. return DATETIME_MULTIPLIERS
  320. }
  321. }
  322. function numbersReducer(interval, key) {
  323. return function(r, m) {
  324. if (!r && interval <= convertDateUnitToMilliseconds(key, m)) {
  325. r = {};
  326. r[key + "s"] = m
  327. }
  328. return r
  329. }
  330. }
  331. function yearsReducer(interval, factor) {
  332. return function(r, m) {
  333. var years = factor * m;
  334. if (!r && interval <= convertDateUnitToMilliseconds("year", years) && 2.5 !== years) {
  335. r = {
  336. years: years
  337. }
  338. }
  339. return r
  340. }
  341. }
  342. function calculateTickIntervalDateTime(businessDelta, screenDelta, tickInterval, forceTickInterval, axisDivisionFactor, multipliers, allowDecimals, addTickCount, gapSize, minTickInterval) {
  343. if (!forceTickInterval || !tickInterval) {
  344. var result = adjustIntervalDateTime(getIntervalByFactor(businessDelta, screenDelta, axisDivisionFactor), multipliers, null, gapSize);
  345. if (!tickInterval || !forceTickInterval && dateToMilliseconds(tickInterval) <= dateToMilliseconds(result)) {
  346. tickInterval = result
  347. }
  348. }
  349. if (!forceTickInterval && minTickInterval) {
  350. minTickInterval = adjustIntervalDateTime(minTickInterval, multipliers, null, gapSize);
  351. if (dateToMilliseconds(minTickInterval) > dateToMilliseconds(tickInterval)) {
  352. tickInterval = minTickInterval
  353. }
  354. }
  355. return tickInterval
  356. }
  357. function adjustIntervalDateTime(interval, multipliers, _, gapSize) {
  358. var result;
  359. multipliers = multipliers || getDataTimeMultipliers(gapSize);
  360. for (var key in multipliers) {
  361. result = multipliers[key].reduce(numbersReducer(interval, key), result);
  362. if (result) {
  363. break
  364. }
  365. }
  366. if (!result) {
  367. for (var factor = 1;; factor *= 10) {
  368. result = NUMBER_MULTIPLIERS.reduce(yearsReducer(interval, factor), result);
  369. if (result) {
  370. break
  371. }
  372. }
  373. }
  374. return result
  375. }
  376. function calculateMinorTickIntervalDateTime(businessDelta, screenDelta, tickInterval, axisDivisionFactor) {
  377. return calculateTickIntervalDateTime(businessDelta, screenDelta, tickInterval, true, axisDivisionFactor, DATETIME_MINOR_MULTIPLIERS)
  378. }
  379. function getTickIntervalByCustomTicks(getValue, postProcess) {
  380. return function(ticks) {
  381. return ticks ? postProcess(mathAbs((0, _math.adjust)(getValue(ticks[1]) - getValue(ticks[0])))) || void 0 : void 0
  382. }
  383. }
  384. function addInterval(value, interval, isNegative) {
  385. return _date2.default.addInterval(value, interval, isNegative)
  386. }
  387. function addIntervalLog(base) {
  388. return function(value, interval, isNegative) {
  389. return raiseTo(base)(addInterval((0, _utils.getLog)(value, base), interval, isNegative))
  390. }
  391. }
  392. function addIntervalDate(value, interval, isNegative) {
  393. return addInterval(value, interval, isNegative)
  394. }
  395. function addIntervalWithBreaks(addInterval, breaks, correctValue) {
  396. breaks = breaks.filter(function(b) {
  397. return !b.gapSize
  398. });
  399. return function(value, interval, isNegative) {
  400. var breakSize;
  401. value = addInterval(value, interval, isNegative);
  402. if (!breaks.every(function(item) {
  403. if (value >= addInterval(item.from, interval) && addInterval(value, interval) < item.to) {
  404. breakSize = item.to - item.from - 2 * (addInterval(item.from, interval) - item.from)
  405. }
  406. return !breakSize
  407. })) {
  408. value = correctValue(addInterval(value, breakSize), interval)
  409. }
  410. return value
  411. }
  412. }
  413. function calculateTicks(addInterval, correctMinValue, adjustInterval, resolveEndOnTick, resolveExtraTickForHiddenDataPoint) {
  414. return function(data, tickInterval, endOnTick, gaps, breaks, businessDelta, screenDelta, axisDivisionFactor, generateExtraTick) {
  415. var correctTickValue = correctTickValueOnGapSize(addInterval, gaps);
  416. var min = data.min;
  417. var max = data.max;
  418. var businessViewInfo = {
  419. screenDelta: screenDelta,
  420. businessDelta: businessDelta,
  421. axisDivisionFactor: axisDivisionFactor,
  422. isSpacedMargin: data.isSpacedMargin,
  423. interval: tickInterval
  424. };
  425. var cur = correctMinValue(min, tickInterval, businessViewInfo);
  426. var ticks = [];
  427. if (breaks && breaks.length) {
  428. addInterval = addIntervalWithBreaks(addInterval, breaks, correctMinValue)
  429. }
  430. if (cur > max) {
  431. cur = correctMinValue(min, adjustInterval(businessDelta / 2), businessViewInfo);
  432. if (cur > max) {
  433. endOnTick = true;
  434. cur = correctMinValue(min, tickInterval, businessViewInfo, endOnTick)
  435. }
  436. }
  437. cur = correctTickValue(cur);
  438. var prev;
  439. while (cur < max && cur !== prev || generateExtraTick && cur <= max) {
  440. ticks.push(cur);
  441. prev = cur;
  442. cur = correctTickValue(addInterval(cur, tickInterval))
  443. }
  444. if (endOnTick || cur - max === 0 || !(0, _type.isDefined)(endOnTick) && resolveEndOnTick(max, cur, tickInterval, businessViewInfo)) {
  445. ticks.push(cur)
  446. }
  447. if (ticks.length > 0) {
  448. if (ticks[0].valueOf() > 0 && resolveExtraTickForHiddenDataPoint(data.checkMinDataVisibility, min, ticks[0], businessViewInfo, true)) {
  449. cur = addInterval(ticks[0], tickInterval, true);
  450. ticks.unshift(cur)
  451. } else {
  452. if (ticks[ticks.length - 1].valueOf() < 0 && resolveExtraTickForHiddenDataPoint(data.checkMaxDataVisibility, max, ticks[ticks.length - 1], businessViewInfo, false)) {
  453. cur = addInterval(ticks[ticks.length - 1], tickInterval);
  454. ticks.push(cur)
  455. }
  456. }
  457. }
  458. return ticks
  459. }
  460. }
  461. function calculateMinorTicks(updateTickInterval, addInterval, correctMinValue, correctTickValue, ceil) {
  462. return function(min, max, majorTicks, minorTickInterval, tickInterval, breaks, maxCount) {
  463. var factor = tickInterval / minorTickInterval;
  464. var lastMajor = majorTicks[majorTicks.length - 1];
  465. var firstMajor = majorTicks[0];
  466. var tickBalance = maxCount - 1;
  467. if (breaks && breaks.length) {
  468. addInterval = addIntervalWithBreaks(addInterval, breaks, correctMinValue)
  469. }
  470. minorTickInterval = updateTickInterval(minorTickInterval, firstMajor, factor);
  471. if (0 === minorTickInterval) {
  472. return []
  473. }
  474. var cur = correctTickValue(correctMinValue(min, tickInterval, min), minorTickInterval);
  475. var ticks = [];
  476. while (cur < firstMajor && (!tickBalance || tickBalance > 0)) {
  477. cur >= min && ticks.push(cur);
  478. tickBalance--;
  479. cur = addInterval(cur, minorTickInterval)
  480. }
  481. var middleTicks = majorTicks.reduce(function(r, tick) {
  482. tickBalance = maxCount - 1;
  483. if (null === r.prevTick) {
  484. r.prevTick = tick;
  485. return r
  486. }
  487. minorTickInterval = updateTickInterval(minorTickInterval, tick, factor);
  488. var cur = correctTickValue(r.prevTick, minorTickInterval);
  489. while (cur < tick && (!tickBalance || tickBalance > 0)) {
  490. cur !== r.prevTick && r.minors.push(cur);
  491. tickBalance--;
  492. cur = addInterval(cur, minorTickInterval)
  493. }
  494. r.prevTick = tick;
  495. return r
  496. }, {
  497. prevTick: null,
  498. minors: []
  499. });
  500. ticks = ticks.concat(middleTicks.minors);
  501. minorTickInterval = updateTickInterval(minorTickInterval, ceil(max, tickInterval, min), factor);
  502. cur = correctTickValue(lastMajor, minorTickInterval);
  503. var prev;
  504. while (cur < max && cur !== prev) {
  505. ticks.push(cur);
  506. prev = cur;
  507. cur = addInterval(cur, minorTickInterval)
  508. }
  509. if (lastMajor - max !== 0 && cur - max === 0) {
  510. ticks.push(cur)
  511. }
  512. return ticks
  513. }
  514. }
  515. function filterTicks(ticks, breaks) {
  516. if (breaks.length) {
  517. var result = breaks.reduce(function(result, b) {
  518. var tmpTicks = [];
  519. var i;
  520. for (i = result[1]; i < ticks.length; i++) {
  521. var tickValue = ticks[i];
  522. if (tickValue < b.from) {
  523. tmpTicks.push(tickValue)
  524. }
  525. if (tickValue >= b.to) {
  526. break
  527. }
  528. }
  529. return [result[0].concat(tmpTicks), i]
  530. }, [
  531. [], 0
  532. ]);
  533. return result[0].concat(ticks.slice(result[1]))
  534. }
  535. return ticks
  536. }
  537. function correctTickValueOnGapSize(addInterval, breaks) {
  538. return function(value) {
  539. var gapSize;
  540. if (!breaks.every(function(item) {
  541. if (value >= item.from && value < item.to) {
  542. gapSize = item.gapSize
  543. }
  544. return !gapSize
  545. })) {
  546. value = addInterval(value, gapSize)
  547. }
  548. return value
  549. }
  550. }
  551. function generator(options, getBusinessDelta, calculateTickInterval, calculateMinorTickInterval, getMajorTickIntervalByCustomTicks, getMinorTickIntervalByCustomTicks, convertTickInterval, calculateTicks, calculateMinorTicks, processScaleBreaks) {
  552. function processCustomTicks(customTicks) {
  553. return {
  554. tickInterval: getMajorTickIntervalByCustomTicks(customTicks.majors),
  555. ticks: customTicks.majors || [],
  556. minorTickInterval: getMinorTickIntervalByCustomTicks(customTicks.minors),
  557. minorTicks: customTicks.minors || []
  558. }
  559. }
  560. function correctUserTickInterval(tickInterval, businessDelta, limit) {
  561. if (tickInterval && businessDelta / convertTickInterval(tickInterval) >= limit + 1) {
  562. options.incidentOccurred("W2003");
  563. tickInterval = void 0
  564. }
  565. return tickInterval
  566. }
  567. function generateMajorTicks(ticks, data, businessDelta, screenDelta, tickInterval, forceTickInterval, customTicks, breaks) {
  568. if (customTicks.majors) {
  569. ticks.breaks = breaks;
  570. return ticks
  571. }
  572. var gaps = breaks.filter(function(b) {
  573. return b.gapSize
  574. });
  575. var majorTicks;
  576. tickInterval = options.skipCalculationLimits ? tickInterval : correctUserTickInterval(tickInterval, businessDelta, screenDelta);
  577. tickInterval = calculateTickInterval(businessDelta, screenDelta, tickInterval, forceTickInterval, options.axisDivisionFactor, options.numberMultipliers, options.allowDecimals, breaks.length, gaps[0] && gaps[0].gapSize.days, options.minTickInterval);
  578. if (!options.skipTickGeneration) {
  579. majorTicks = calculateTicks(data, tickInterval, options.endOnTick, gaps, breaks, businessDelta, screenDelta, options.axisDivisionFactor, options.generateExtraTick);
  580. breaks = processScaleBreaks(breaks, majorTicks, tickInterval);
  581. majorTicks = filterTicks(majorTicks, breaks);
  582. ticks.breaks = breaks;
  583. ticks.ticks = ticks.ticks.concat(majorTicks)
  584. }
  585. ticks.tickInterval = tickInterval;
  586. return ticks
  587. }
  588. function generateMinorTicks(ticks, data, businessDelta, screenDelta, minorTickInterval, minorTickCount, customTicks) {
  589. if (!options.calculateMinors) {
  590. return ticks
  591. }
  592. if (customTicks.minors) {
  593. return ticks
  594. }
  595. var minorBusinessDelta = convertTickInterval(ticks.tickInterval);
  596. var minorScreenDelta = screenDelta * minorBusinessDelta / businessDelta;
  597. var breaks = ticks.breaks;
  598. if (!minorTickInterval && minorTickCount) {
  599. minorTickInterval = getMinorTickIntervalByCustomTicks([minorBusinessDelta / (minorTickCount + 1), minorBusinessDelta / (minorTickCount + 1) * 2])
  600. } else {
  601. minorTickCount = void 0
  602. }
  603. minorTickInterval = correctUserTickInterval(minorTickInterval, minorBusinessDelta, minorScreenDelta);
  604. minorTickInterval = calculateMinorTickInterval(minorBusinessDelta, minorScreenDelta, minorTickInterval, options.minorAxisDivisionFactor);
  605. ticks.minorTicks = filterTicks(ticks.minorTicks.concat(calculateMinorTicks(data.min, data.max, ticks.ticks, minorTickInterval, ticks.tickInterval, breaks, minorTickCount)), breaks);
  606. ticks.minorTickInterval = minorTickInterval;
  607. return ticks
  608. }
  609. return function(data, screenDelta, tickInterval, forceTickInterval, customTicks, minorTickInterval, minorTickCount, breaks) {
  610. customTicks = customTicks || {};
  611. var businessDelta = getBusinessDelta(data, breaks);
  612. var result = processCustomTicks(customTicks);
  613. if (!isNaN(businessDelta)) {
  614. if (0 === businessDelta && !customTicks.majors) {
  615. result.ticks = [data.min]
  616. } else {
  617. result = generateMajorTicks(result, data, businessDelta, screenDelta, tickInterval, forceTickInterval, customTicks, breaks || []);
  618. if (!options.skipTickGeneration && businessDelta > 0) {
  619. result = generateMinorTicks(result, data, businessDelta, screenDelta, minorTickInterval, minorTickCount, customTicks)
  620. }
  621. }
  622. }
  623. return result
  624. }
  625. }
  626. function getBaseTick(breakValue, _ref, interval, getValue) {
  627. var _ref2 = _slicedToArray(_ref, 2),
  628. tick = _ref2[0],
  629. insideTick = _ref2[1];
  630. if (!(0, _type.isDefined)(tick) || mathAbs(getValue(breakValue) - getValue(tick)) / interval > .25) {
  631. if ((0, _type.isDefined)(insideTick)) {
  632. tick = insideTick
  633. } else {
  634. if (!(0, _type.isDefined)(tick)) {
  635. tick = breakValue
  636. }
  637. }
  638. }
  639. return tick
  640. }
  641. function getScaleBreaksProcessor(convertTickInterval, getValue, addCorrection) {
  642. return function(breaks, ticks, tickInterval) {
  643. var interval = convertTickInterval(tickInterval);
  644. var correction = .5 * interval;
  645. return breaks.reduce(function(result, b) {
  646. var breakTicks = ticks.filter(function(tick) {
  647. return tick <= b.from
  648. });
  649. var from = addCorrection(getBaseTick(b.from, [].concat(breakTicks[breakTicks.length - 1], ticks[breakTicks.length]), interval, getValue), correction);
  650. breakTicks = ticks.filter(function(tick) {
  651. return tick >= b.to
  652. });
  653. var to = addCorrection(getBaseTick(b.to, [].concat(breakTicks[0], ticks[ticks.length - breakTicks.length - 1]), interval, getValue), -correction);
  654. if (getValue(to) - getValue(from) < interval && !b.gapSize) {
  655. return result
  656. }
  657. if (b.gapSize) {
  658. return result.concat([b])
  659. }
  660. return result.concat([{
  661. from: from,
  662. to: to,
  663. cumulativeWidth: b.cumulativeWidth
  664. }])
  665. }, [])
  666. }
  667. }
  668. function numericGenerator(options) {
  669. var floor = correctValueByInterval(getValue, mathFloor, getValue);
  670. var ceil = correctValueByInterval(getValue, mathCeil, getValue);
  671. var calculateTickIntervalByCustomTicks = getTickIntervalByCustomTicks(getValue, getValue);
  672. return generator(options, getBusinessDelta, calculateTickInterval, calculateMinorTickInterval, calculateTickIntervalByCustomTicks, calculateTickIntervalByCustomTicks, getValue, calculateTicks(addInterval, correctMinValueByEndOnTick(floor, ceil, resolveEndOnTick, options.endOnTick), adjustInterval, resolveEndOnTick, resolveExtraTickForHiddenDataPoint), calculateMinorTicks(getValue, addInterval, floor, addInterval, getValue), getScaleBreaksProcessor(getValue, getValue, function(value, correction) {
  673. return value + correction
  674. }))
  675. }
  676. function logarithmicGenerator(options) {
  677. var base = options.logBase;
  678. var raise = raiseTo(base);
  679. var log = getLogValue(base);
  680. var floor = correctValueByInterval(raise, mathFloor, log);
  681. var ceil = correctValueByInterval(raise, mathCeil, log);
  682. var ceilNumber = correctValueByInterval(getValue, mathCeil, getValue);
  683. return generator(options, getBusinessDeltaLog(base), getCalculateTickIntervalLog(options.skipCalculationLimits), calculateMinorTickInterval, getTickIntervalByCustomTicks(log, getValue), getTickIntervalByCustomTicks(getValue, getValue), getValue, calculateTicks(addIntervalLog(base), correctMinValueByEndOnTick(floor, ceil, resolveEndOnTickLog(base), options.endOnTick), getAdjustIntervalLog(options.skipCalculationLimits), resolveEndOnTickLog(base), resolveExtraTickForHiddenDataPointLog(base)), calculateMinorTicks(function(_, tick, factor) {
  684. return tick / factor
  685. }, addInterval, floor, ceilNumber, ceil), getScaleBreaksProcessor(getValue, log, function(value, correction) {
  686. return raise(log(value) + correction)
  687. }))
  688. }
  689. function dateGenerator(options) {
  690. function floor(value, interval) {
  691. var floorNumber = correctValueByInterval(getValue, mathFloor, getValue);
  692. var intervalObject = (0, _type.isString)(interval) ? _date2.default.getDateIntervalByString(interval.toLowerCase()) : interval;
  693. var divider = dateToMilliseconds(interval);
  694. if (intervalObject.days % 7 === 0 || interval.quarters) {
  695. intervalObject = adjustIntervalDateTime(divider)
  696. }
  697. var correctDateWithUnitBeginning = function(v) {
  698. return _date2.default.correctDateWithUnitBeginning(v, intervalObject, null, options.firstDayOfWeek)
  699. };
  700. var floorAtStartDate = function(v) {
  701. return new Date(mathFloor((v.getTime() - v.getTimezoneOffset() * MINUTE) / divider) * divider + v.getTimezoneOffset() * MINUTE)
  702. };
  703. value = correctDateWithUnitBeginning(value);
  704. if ("years" in intervalObject) {
  705. value.setFullYear(floorNumber(value.getFullYear(), intervalObject.years, 0))
  706. } else {
  707. if ("quarters" in intervalObject) {
  708. value = correctDateWithUnitBeginning(floorAtStartDate(value))
  709. } else {
  710. if ("months" in intervalObject) {
  711. value.setMonth(floorNumber(value.getMonth(), intervalObject.months, 0))
  712. } else {
  713. if ("weeks" in intervalObject || "days" in intervalObject) {
  714. value = correctDateWithUnitBeginning(floorAtStartDate(value))
  715. } else {
  716. if ("hours" in intervalObject) {
  717. value.setHours(floorNumber(value.getHours(), intervalObject.hours, 0))
  718. } else {
  719. if ("minutes" in intervalObject) {
  720. value.setMinutes(floorNumber(value.getMinutes(), intervalObject.minutes, 0))
  721. } else {
  722. if ("seconds" in intervalObject) {
  723. value.setSeconds(floorNumber(value.getSeconds(), intervalObject.seconds, 0))
  724. } else {
  725. if ("milliseconds" in intervalObject) {
  726. value = floorAtStartDate(value)
  727. }
  728. }
  729. }
  730. }
  731. }
  732. }
  733. }
  734. }
  735. return value
  736. }
  737. function ceil(value, interval) {
  738. var newValue = floor(value, interval);
  739. while (value - newValue > 0) {
  740. newValue = addIntervalDate(newValue, interval)
  741. }
  742. return newValue
  743. }
  744. var calculateTickIntervalByCustomTicks = getTickIntervalByCustomTicks(getValue, _date2.default.convertMillisecondsToDateUnits);
  745. return generator(options, getBusinessDelta, calculateTickIntervalDateTime, calculateMinorTickIntervalDateTime, calculateTickIntervalByCustomTicks, calculateTickIntervalByCustomTicks, dateToMilliseconds, calculateTicks(addIntervalDate, correctMinValueByEndOnTick(floor, ceil, resolveEndOnTickDate, options.endOnTick), adjustIntervalDateTime, resolveEndOnTickDate, resolveExtraTickForHiddenDataPointDate), calculateMinorTicks(getValue, addIntervalDate, floor, addIntervalDate, getValue), getScaleBreaksProcessor(dateToMilliseconds, getValue, function(value, correction) {
  746. return new Date(value.getTime() + correction)
  747. }))
  748. }
  749. exports.tickGenerator = function(options) {
  750. var result;
  751. if (options.rangeIsEmpty) {
  752. result = dummyGenerator(options)
  753. } else {
  754. if ("discrete" === options.axisType) {
  755. result = discreteGenerator(options)
  756. } else {
  757. if ("logarithmic" === options.axisType) {
  758. result = logarithmicGenerator(options)
  759. } else {
  760. if ("datetime" === options.dataType) {
  761. result = dateGenerator(options)
  762. } else {
  763. result = numericGenerator(options)
  764. }
  765. }
  766. }
  767. }
  768. return result
  769. };