helper.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. var numberUtil = require("../util/number");
  2. /**
  3. * For testable.
  4. */
  5. var roundNumber = numberUtil.round;
  6. /**
  7. * @param {Array.<number>} extent Both extent[0] and extent[1] should be valid number.
  8. * Should be extent[0] < extent[1].
  9. * @param {number} splitNumber splitNumber should be >= 1.
  10. * @param {number} [minInterval]
  11. * @param {number} [maxInterval]
  12. * @return {Object} {interval, intervalPrecision, niceTickExtent}
  13. */
  14. function intervalScaleNiceTicks(extent, splitNumber, minInterval, maxInterval) {
  15. var result = {};
  16. var span = extent[1] - extent[0];
  17. var interval = result.interval = numberUtil.nice(span / splitNumber, true);
  18. if (minInterval != null && interval < minInterval) {
  19. interval = result.interval = minInterval;
  20. }
  21. if (maxInterval != null && interval > maxInterval) {
  22. interval = result.interval = maxInterval;
  23. } // Tow more digital for tick.
  24. var precision = result.intervalPrecision = getIntervalPrecision(interval); // Niced extent inside original extent
  25. var niceTickExtent = result.niceTickExtent = [roundNumber(Math.ceil(extent[0] / interval) * interval, precision), roundNumber(Math.floor(extent[1] / interval) * interval, precision)];
  26. fixExtent(niceTickExtent, extent);
  27. return result;
  28. }
  29. /**
  30. * @param {number} interval
  31. * @return {number} interval precision
  32. */
  33. function getIntervalPrecision(interval) {
  34. // Tow more digital for tick.
  35. return numberUtil.getPrecisionSafe(interval) + 2;
  36. }
  37. function clamp(niceTickExtent, idx, extent) {
  38. niceTickExtent[idx] = Math.max(Math.min(niceTickExtent[idx], extent[1]), extent[0]);
  39. } // In some cases (e.g., splitNumber is 1), niceTickExtent may be out of extent.
  40. function fixExtent(niceTickExtent, extent) {
  41. !isFinite(niceTickExtent[0]) && (niceTickExtent[0] = extent[0]);
  42. !isFinite(niceTickExtent[1]) && (niceTickExtent[1] = extent[1]);
  43. clamp(niceTickExtent, 0, extent);
  44. clamp(niceTickExtent, 1, extent);
  45. if (niceTickExtent[0] > niceTickExtent[1]) {
  46. niceTickExtent[0] = niceTickExtent[1];
  47. }
  48. }
  49. function intervalScaleGetTicks(interval, extent, niceTickExtent, intervalPrecision) {
  50. var ticks = []; // If interval is 0, return [];
  51. if (!interval) {
  52. return ticks;
  53. } // Consider this case: using dataZoom toolbox, zoom and zoom.
  54. var safeLimit = 10000;
  55. if (extent[0] < niceTickExtent[0]) {
  56. ticks.push(extent[0]);
  57. }
  58. var tick = niceTickExtent[0];
  59. while (tick <= niceTickExtent[1]) {
  60. ticks.push(tick); // Avoid rounding error
  61. tick = roundNumber(tick + interval, intervalPrecision);
  62. if (tick === ticks[ticks.length - 1]) {
  63. // Consider out of safe float point, e.g.,
  64. // -3711126.9907707 + 2e-10 === -3711126.9907707
  65. break;
  66. }
  67. if (ticks.length > safeLimit) {
  68. return [];
  69. }
  70. } // Consider this case: the last item of ticks is smaller
  71. // than niceTickExtent[1] and niceTickExtent[1] === extent[1].
  72. if (extent[1] > (ticks.length ? ticks[ticks.length - 1] : niceTickExtent[1])) {
  73. ticks.push(extent[1]);
  74. }
  75. return ticks;
  76. }
  77. exports.intervalScaleNiceTicks = intervalScaleNiceTicks;
  78. exports.getIntervalPrecision = getIntervalPrecision;
  79. exports.fixExtent = fixExtent;
  80. exports.intervalScaleGetTicks = intervalScaleGetTicks;