DateTimeAxis.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /**
  2. * (c) 2010-2019 Torstein Honsi
  3. *
  4. * License: www.highcharts.com/license
  5. */
  6. 'use strict';
  7. import H from './Globals.js';
  8. import './Utilities.js';
  9. var Axis = H.Axis,
  10. getMagnitude = H.getMagnitude,
  11. normalizeTickInterval = H.normalizeTickInterval,
  12. timeUnits = H.timeUnits;
  13. /**
  14. * Set the tick positions to a time unit that makes sense, for example
  15. * on the first of each month or on every Monday. Return an array
  16. * with the time positions. Used in datetime axes as well as for grouping
  17. * data on a datetime axis.
  18. *
  19. * @private
  20. * @function Highcharts.Axis#getTimeTicks
  21. *
  22. * @param {*} normalizedInterval
  23. * The interval in axis values (ms) and thecount
  24. *
  25. * @param {number} min
  26. * The minimum in axis values
  27. *
  28. * @param {number} max
  29. * The maximum in axis values
  30. *
  31. * @param {number} startOfWeek
  32. *
  33. * @return {number}
  34. */
  35. Axis.prototype.getTimeTicks = function () {
  36. return this.chart.time.getTimeTicks.apply(this.chart.time, arguments);
  37. };
  38. /**
  39. * Get a normalized tick interval for dates. Returns a configuration object with
  40. * unit range (interval), count and name. Used to prepare data for getTimeTicks.
  41. * Previously this logic was part of getTimeTicks, but as getTimeTicks now runs
  42. * of segments in stock charts, the normalizing logic was extracted in order to
  43. * prevent it for running over again for each segment having the same interval.
  44. * #662, #697.
  45. *
  46. * @private
  47. * @function Highcharts.Axis#normalizeTimeTickInterval
  48. *
  49. * @param {number} tickInterval
  50. *
  51. * @param {Array<Array<number|string>>} [unitsOption]
  52. *
  53. * @return {*}
  54. */
  55. Axis.prototype.normalizeTimeTickInterval = function (
  56. tickInterval,
  57. unitsOption
  58. ) {
  59. var units = unitsOption || [[
  60. 'millisecond', // unit name
  61. [1, 2, 5, 10, 20, 25, 50, 100, 200, 500] // allowed multiples
  62. ], [
  63. 'second',
  64. [1, 2, 5, 10, 15, 30]
  65. ], [
  66. 'minute',
  67. [1, 2, 5, 10, 15, 30]
  68. ], [
  69. 'hour',
  70. [1, 2, 3, 4, 6, 8, 12]
  71. ], [
  72. 'day',
  73. [1, 2]
  74. ], [
  75. 'week',
  76. [1, 2]
  77. ], [
  78. 'month',
  79. [1, 2, 3, 4, 6]
  80. ], [
  81. 'year',
  82. null
  83. ]],
  84. unit = units[units.length - 1], // default unit is years
  85. interval = timeUnits[unit[0]],
  86. multiples = unit[1],
  87. count,
  88. i;
  89. // loop through the units to find the one that best fits the tickInterval
  90. for (i = 0; i < units.length; i++) {
  91. unit = units[i];
  92. interval = timeUnits[unit[0]];
  93. multiples = unit[1];
  94. if (units[i + 1]) {
  95. // lessThan is in the middle between the highest multiple and the
  96. // next unit.
  97. var lessThan = (interval * multiples[multiples.length - 1] +
  98. timeUnits[units[i + 1][0]]) / 2;
  99. // break and keep the current unit
  100. if (tickInterval <= lessThan) {
  101. break;
  102. }
  103. }
  104. }
  105. // prevent 2.5 years intervals, though 25, 250 etc. are allowed
  106. if (interval === timeUnits.year && tickInterval < 5 * interval) {
  107. multiples = [1, 2, 5];
  108. }
  109. // get the count
  110. count = normalizeTickInterval(
  111. tickInterval / interval,
  112. multiples,
  113. unit[0] === 'year' ?
  114. Math.max(getMagnitude(tickInterval / interval), 1) : // #1913, #2360
  115. 1
  116. );
  117. return {
  118. unitRange: interval,
  119. count: count,
  120. unitName: unit[0]
  121. };
  122. };