LogarithmicAxis.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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. pick = H.pick;
  13. /*
  14. * Methods defined on the Axis prototype
  15. */
  16. /**
  17. * Set the tick positions of a logarithmic axis.
  18. *
  19. * @private
  20. * @function Highcharts.Axis#getLogTickPositions
  21. *
  22. * @param {number} interval
  23. *
  24. * @param {number} min
  25. *
  26. * @param {number} max
  27. *
  28. * @param {number} minor
  29. *
  30. * @return {Array<number>}
  31. */
  32. Axis.prototype.getLogTickPositions = function (interval, min, max, minor) {
  33. var axis = this,
  34. options = axis.options,
  35. axisLength = axis.len,
  36. // Since we use this method for both major and minor ticks,
  37. // use a local variable and return the result
  38. positions = [];
  39. // Reset
  40. if (!minor) {
  41. axis._minorAutoInterval = null;
  42. }
  43. // First case: All ticks fall on whole logarithms: 1, 10, 100 etc.
  44. if (interval >= 0.5) {
  45. interval = Math.round(interval);
  46. positions = axis.getLinearTickPositions(interval, min, max);
  47. // Second case: We need intermediary ticks. For example
  48. // 1, 2, 4, 6, 8, 10, 20, 40 etc.
  49. } else if (interval >= 0.08) {
  50. var roundedMin = Math.floor(min),
  51. intermediate,
  52. i,
  53. j,
  54. len,
  55. pos,
  56. lastPos,
  57. break2;
  58. if (interval > 0.3) {
  59. intermediate = [1, 2, 4];
  60. // 0.2 equals five minor ticks per 1, 10, 100 etc
  61. } else if (interval > 0.15) {
  62. intermediate = [1, 2, 4, 6, 8];
  63. } else { // 0.1 equals ten minor ticks per 1, 10, 100 etc
  64. intermediate = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  65. }
  66. for (i = roundedMin; i < max + 1 && !break2; i++) {
  67. len = intermediate.length;
  68. for (j = 0; j < len && !break2; j++) {
  69. pos = axis.log2lin(axis.lin2log(i) * intermediate[j]);
  70. // #1670, lastPos is #3113
  71. if (
  72. pos > min &&
  73. (!minor || lastPos <= max) &&
  74. lastPos !== undefined
  75. ) {
  76. positions.push(lastPos);
  77. }
  78. if (lastPos > max) {
  79. break2 = true;
  80. }
  81. lastPos = pos;
  82. }
  83. }
  84. // Third case: We are so deep in between whole logarithmic values that
  85. // we might as well handle the tick positions like a linear axis. For
  86. // example 1.01, 1.02, 1.03, 1.04.
  87. } else {
  88. var realMin = axis.lin2log(min),
  89. realMax = axis.lin2log(max),
  90. tickIntervalOption = minor ?
  91. this.getMinorTickInterval() :
  92. options.tickInterval,
  93. filteredTickIntervalOption = tickIntervalOption === 'auto' ?
  94. null :
  95. tickIntervalOption,
  96. tickPixelIntervalOption =
  97. options.tickPixelInterval / (minor ? 5 : 1),
  98. totalPixelLength = minor ?
  99. axisLength / axis.tickPositions.length :
  100. axisLength;
  101. interval = pick(
  102. filteredTickIntervalOption,
  103. axis._minorAutoInterval,
  104. (realMax - realMin) *
  105. tickPixelIntervalOption / (totalPixelLength || 1)
  106. );
  107. interval = normalizeTickInterval(
  108. interval,
  109. null,
  110. getMagnitude(interval)
  111. );
  112. positions = axis.getLinearTickPositions(
  113. interval,
  114. realMin,
  115. realMax
  116. ).map(axis.log2lin);
  117. if (!minor) {
  118. axis._minorAutoInterval = interval / 5;
  119. }
  120. }
  121. // Set the axis-level tickInterval variable
  122. if (!minor) {
  123. axis.tickInterval = interval;
  124. }
  125. return positions;
  126. };
  127. /**
  128. * @private
  129. * @function Highcharts.Axis#log2lin
  130. *
  131. * @param {number} num
  132. *
  133. * @return {number}
  134. */
  135. Axis.prototype.log2lin = function (num) {
  136. return Math.log(num) / Math.LN10;
  137. };
  138. /**
  139. * @private
  140. * @function Highcharts.Axis#lin2log
  141. *
  142. * @param {number} num
  143. *
  144. * @return {number}
  145. */
  146. Axis.prototype.lin2log = function (num) {
  147. return Math.pow(10, num);
  148. };