translator2d.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. /**
  2. * DevExtreme (viz/translators/translator2d.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 extend = require("../../core/utils/extend").extend;
  11. var each = require("../../core/utils/iterator").each;
  12. var Range = require("./range").Range;
  13. var categoryTranslator = require("./category_translator");
  14. var intervalTranslator = require("./interval_translator");
  15. var datetimeTranslator = require("./datetime_translator");
  16. var logarithmicTranslator = require("./logarithmic_translator");
  17. var vizUtils = require("../core/utils");
  18. var typeUtils = require("../../core/utils/type");
  19. var getLog = vizUtils.getLog;
  20. var getPower = vizUtils.getPower;
  21. var isDefined = typeUtils.isDefined;
  22. var adjust = require("../../core/utils/math").adjust;
  23. var _abs = Math.abs;
  24. var CANVAS_PROP = ["width", "height", "left", "top", "bottom", "right"];
  25. var _Translator2d;
  26. var addInterval = require("../../core/utils/date").addInterval;
  27. var dummyTranslator = {
  28. to: function(value) {
  29. var coord = this._canvasOptions.startPoint + (this._options.conversionValue ? value : Math.round(value));
  30. return coord > this._canvasOptions.endPoint ? this._canvasOptions.endPoint : coord
  31. },
  32. from: function(value) {
  33. return value - this._canvasOptions.startPoint
  34. }
  35. };
  36. var validateCanvas = function(canvas) {
  37. each(CANVAS_PROP, function(_, prop) {
  38. canvas[prop] = parseInt(canvas[prop]) || 0
  39. });
  40. return canvas
  41. };
  42. var makeCategoriesToPoints = function(categories) {
  43. var categoriesToPoints = {};
  44. categories.forEach(function(item, i) {
  45. categoriesToPoints[item.valueOf()] = i
  46. });
  47. return categoriesToPoints
  48. };
  49. var validateBusinessRange = function(businessRange) {
  50. if (!(businessRange instanceof Range)) {
  51. businessRange = new Range(businessRange)
  52. }
  53. function validate(valueSelector, baseValueSelector) {
  54. if (!isDefined(businessRange[valueSelector]) && isDefined(businessRange[baseValueSelector])) {
  55. businessRange[valueSelector] = businessRange[baseValueSelector]
  56. }
  57. }
  58. validate("minVisible", "min");
  59. validate("maxVisible", "max");
  60. return businessRange
  61. };
  62. function prepareBreaks(breaks, range) {
  63. var transform = "logarithmic" === range.axisType ? function(value) {
  64. return getLog(value, range.base)
  65. } : function(value) {
  66. return value
  67. };
  68. var array = [];
  69. var br;
  70. var transformFrom;
  71. var transformTo;
  72. var i;
  73. var length = breaks.length;
  74. var sum = 0;
  75. for (i = 0; i < length; i++) {
  76. br = breaks[i];
  77. transformFrom = transform(br.from);
  78. transformTo = transform(br.to);
  79. sum += transformTo - transformFrom;
  80. array.push({
  81. trFrom: transformFrom,
  82. trTo: transformTo,
  83. from: br.from,
  84. to: br.to,
  85. length: sum,
  86. cumulativeWidth: br.cumulativeWidth
  87. })
  88. }
  89. return array
  90. }
  91. function getCanvasBounds(range) {
  92. var min = range.min;
  93. var max = range.max;
  94. var minVisible = range.minVisible;
  95. var maxVisible = range.maxVisible;
  96. var isLogarithmic = "logarithmic" === range.axisType;
  97. if (isLogarithmic) {
  98. maxVisible = getLog(maxVisible, range.base);
  99. minVisible = getLog(minVisible, range.base);
  100. min = getLog(min, range.base);
  101. max = getLog(max, range.base)
  102. }
  103. return {
  104. base: range.base,
  105. rangeMin: min,
  106. rangeMax: max,
  107. rangeMinVisible: minVisible,
  108. rangeMaxVisible: maxVisible
  109. }
  110. }
  111. function getCheckingMethodsAboutBreaks(inverted) {
  112. return {
  113. isStartSide: !inverted ? function(pos, breaks, start, end) {
  114. return pos < breaks[0][start]
  115. } : function(pos, breaks, start, end) {
  116. return pos <= breaks[breaks.length - 1][end]
  117. },
  118. isEndSide: !inverted ? function(pos, breaks, start, end) {
  119. return pos >= breaks[breaks.length - 1][end]
  120. } : function(pos, breaks, start, end) {
  121. return pos > breaks[0][start]
  122. },
  123. isInBreak: !inverted ? function(pos, br, start, end) {
  124. return pos >= br[start] && pos < br[end]
  125. } : function(pos, br, start, end) {
  126. return pos > br[end] && pos <= br[start]
  127. },
  128. isBetweenBreaks: !inverted ? function(pos, br, prevBreak, start, end) {
  129. return pos < br[start] && pos >= prevBreak[end]
  130. } : function(pos, br, prevBreak, start, end) {
  131. return pos >= br[end] && pos < prevBreak[start]
  132. },
  133. getLength: !inverted ? function(br) {
  134. return br.length
  135. } : function(br, lastBreak) {
  136. return lastBreak.length - br.length
  137. },
  138. getBreaksSize: !inverted ? function(br) {
  139. return br.cumulativeWidth
  140. } : function(br, lastBreak) {
  141. return lastBreak.cumulativeWidth - br.cumulativeWidth
  142. }
  143. }
  144. }
  145. exports.Translator2D = _Translator2d = function(businessRange, canvas, options) {
  146. this.update(businessRange, canvas, options)
  147. };
  148. _Translator2d.prototype = {
  149. constructor: _Translator2d,
  150. reinit: function() {
  151. var that = this;
  152. var options = that._options;
  153. var range = that._businessRange;
  154. var categories = range.categories || [];
  155. var script = {};
  156. var canvasOptions = that._prepareCanvasOptions();
  157. var visibleCategories = vizUtils.getCategoriesInfo(categories, range.minVisible, range.maxVisible).categories;
  158. var categoriesLength = visibleCategories.length;
  159. if (range.isEmpty()) {
  160. script = dummyTranslator
  161. } else {
  162. switch (range.axisType) {
  163. case "logarithmic":
  164. script = logarithmicTranslator;
  165. break;
  166. case "semidiscrete":
  167. script = intervalTranslator;
  168. canvasOptions.ratioOfCanvasRange = canvasOptions.canvasLength / (addInterval(canvasOptions.rangeMaxVisible, options.interval) - canvasOptions.rangeMinVisible);
  169. break;
  170. case "discrete":
  171. script = categoryTranslator;
  172. that._categories = categories;
  173. canvasOptions.interval = that._getDiscreteInterval(options.addSpiderCategory ? categoriesLength + 1 : categoriesLength, canvasOptions);
  174. that._categoriesToPoints = makeCategoriesToPoints(categories, canvasOptions.invert);
  175. if (categoriesLength) {
  176. canvasOptions.startPointIndex = that._categoriesToPoints[visibleCategories[0].valueOf()];
  177. that.visibleCategories = visibleCategories
  178. }
  179. break;
  180. default:
  181. if ("datetime" === range.dataType) {
  182. script = datetimeTranslator
  183. }
  184. }
  185. }(that._oldMethods || []).forEach(function(methodName) {
  186. delete that[methodName]
  187. });
  188. that._oldMethods = Object.keys(script);
  189. extend(that, script);
  190. that._conversionValue = options.conversionValue ? function(value) {
  191. return value
  192. } : function(value) {
  193. return Math.round(value)
  194. };
  195. that.sc = {};
  196. that._checkingMethodsAboutBreaks = [getCheckingMethodsAboutBreaks(false), getCheckingMethodsAboutBreaks(that.isInverted())];
  197. that._translateBreaks();
  198. that._calculateSpecialValues()
  199. },
  200. _translateBreaks: function() {
  201. var breaks = this._breaks;
  202. var size = this._options.breaksSize;
  203. var i;
  204. var b;
  205. var end;
  206. var length;
  207. if (void 0 === breaks) {
  208. return
  209. }
  210. for (i = 0, length = breaks.length; i < length; i++) {
  211. b = breaks[i];
  212. end = this.translate(b.to);
  213. b.end = end;
  214. b.start = !b.gapSize ? !this.isInverted() ? end - size : end + size : end
  215. }
  216. },
  217. _checkValueAboutBreaks: function(breaks, pos, start, end, methods) {
  218. var i;
  219. var length;
  220. var prop = {
  221. length: 0,
  222. breaksSize: void 0,
  223. inBreak: false
  224. };
  225. var br;
  226. var prevBreak;
  227. var lastBreak = breaks[breaks.length - 1];
  228. if (methods.isStartSide(pos, breaks, start, end)) {
  229. return prop
  230. } else {
  231. if (methods.isEndSide(pos, breaks, start, end)) {
  232. return {
  233. length: lastBreak.length,
  234. breaksSize: lastBreak.cumulativeWidth,
  235. inBreak: false
  236. }
  237. }
  238. }
  239. for (i = 0, length = breaks.length; i < length; i++) {
  240. br = breaks[i];
  241. prevBreak = breaks[i - 1];
  242. if (methods.isInBreak(pos, br, start, end)) {
  243. prop.inBreak = true;
  244. prop.break = br;
  245. break
  246. }
  247. if (prevBreak && methods.isBetweenBreaks(pos, br, prevBreak, start, end)) {
  248. prop = {
  249. length: methods.getLength(prevBreak, lastBreak),
  250. breaksSize: methods.getBreaksSize(prevBreak, lastBreak),
  251. inBreak: false
  252. };
  253. break
  254. }
  255. }
  256. return prop
  257. },
  258. isInverted: function() {
  259. return !(this._options.isHorizontal ^ this._businessRange.invert)
  260. },
  261. _getDiscreteInterval: function(categoriesLength, canvasOptions) {
  262. var correctedCategoriesCount = categoriesLength - (this._options.stick ? 1 : 0);
  263. return correctedCategoriesCount > 0 ? canvasOptions.canvasLength / correctedCategoriesCount : canvasOptions.canvasLength
  264. },
  265. _prepareCanvasOptions: function() {
  266. var that = this;
  267. var businessRange = that._businessRange;
  268. var canvasOptions = that._canvasOptions = getCanvasBounds(businessRange);
  269. var canvas = that._canvas;
  270. var breaks = that._breaks;
  271. var length;
  272. canvasOptions.startPadding = canvas.startPadding || 0;
  273. canvasOptions.endPadding = canvas.endPadding || 0;
  274. if (that._options.isHorizontal) {
  275. canvasOptions.startPoint = canvas.left + canvasOptions.startPadding;
  276. length = canvas.width;
  277. canvasOptions.endPoint = canvas.width - canvas.right - canvasOptions.endPadding;
  278. canvasOptions.invert = businessRange.invert
  279. } else {
  280. canvasOptions.startPoint = canvas.top + canvasOptions.startPadding;
  281. length = canvas.height;
  282. canvasOptions.endPoint = canvas.height - canvas.bottom - canvasOptions.endPadding;
  283. canvasOptions.invert = !businessRange.invert
  284. }
  285. that.canvasLength = canvasOptions.canvasLength = canvasOptions.endPoint - canvasOptions.startPoint;
  286. canvasOptions.rangeDoubleError = Math.pow(10, getPower(canvasOptions.rangeMax - canvasOptions.rangeMin) - getPower(length) - 2);
  287. canvasOptions.ratioOfCanvasRange = canvasOptions.canvasLength / (canvasOptions.rangeMaxVisible - canvasOptions.rangeMinVisible);
  288. if (void 0 !== breaks) {
  289. canvasOptions.ratioOfCanvasRange = (canvasOptions.canvasLength - breaks[breaks.length - 1].cumulativeWidth) / (canvasOptions.rangeMaxVisible - canvasOptions.rangeMinVisible - breaks[breaks.length - 1].length)
  290. }
  291. return canvasOptions
  292. },
  293. updateCanvas: function(canvas) {
  294. this._canvas = validateCanvas(canvas);
  295. this.reinit()
  296. },
  297. updateBusinessRange: function(businessRange) {
  298. var that = this;
  299. var breaks = businessRange.breaks || [];
  300. that._businessRange = validateBusinessRange(businessRange);
  301. that._breaks = breaks.length ? prepareBreaks(breaks, that._businessRange) : void 0;
  302. that.reinit()
  303. },
  304. update: function(businessRange, canvas, options) {
  305. var that = this;
  306. that._options = extend(that._options || {}, options);
  307. that._canvas = validateCanvas(canvas);
  308. that.updateBusinessRange(businessRange)
  309. },
  310. getBusinessRange: function() {
  311. return this._businessRange
  312. },
  313. getEventScale: function(zoomEvent) {
  314. return zoomEvent.deltaScale || 1
  315. },
  316. getCanvasVisibleArea: function() {
  317. return {
  318. min: this._canvasOptions.startPoint,
  319. max: this._canvasOptions.endPoint
  320. }
  321. },
  322. _calculateSpecialValues: function() {
  323. var that = this;
  324. var canvasOptions = that._canvasOptions;
  325. var startPoint = canvasOptions.startPoint - canvasOptions.startPadding;
  326. var endPoint = canvasOptions.endPoint + canvasOptions.endPadding;
  327. var range = that._businessRange;
  328. var minVisible = range.minVisible;
  329. var maxVisible = range.maxVisible;
  330. var canvas_position_center_middle = startPoint + canvasOptions.canvasLength / 2;
  331. var canvas_position_default;
  332. if (minVisible < 0 && maxVisible > 0 && minVisible !== maxVisible) {
  333. canvas_position_default = that.translate(0, 1)
  334. }
  335. if (!isDefined(canvas_position_default)) {
  336. var invert = range.invert ^ (minVisible < 0 && maxVisible <= 0);
  337. if (that._options.isHorizontal) {
  338. canvas_position_default = invert ? endPoint : startPoint
  339. } else {
  340. canvas_position_default = invert ? startPoint : endPoint
  341. }
  342. }
  343. that.sc = {
  344. canvas_position_default: canvas_position_default,
  345. canvas_position_left: startPoint,
  346. canvas_position_top: startPoint,
  347. canvas_position_center: canvas_position_center_middle,
  348. canvas_position_middle: canvas_position_center_middle,
  349. canvas_position_right: endPoint,
  350. canvas_position_bottom: endPoint,
  351. canvas_position_start: canvasOptions.invert ? endPoint : startPoint,
  352. canvas_position_end: canvasOptions.invert ? startPoint : endPoint
  353. }
  354. },
  355. translateSpecialCase: function(value) {
  356. return this.sc[value]
  357. },
  358. _calculateProjection: function(distance) {
  359. var canvasOptions = this._canvasOptions;
  360. return canvasOptions.invert ? canvasOptions.endPoint - distance : canvasOptions.startPoint + distance
  361. },
  362. _calculateUnProjection: function(distance) {
  363. var canvasOptions = this._canvasOptions;
  364. return canvasOptions.invert ? canvasOptions.rangeMaxVisible.valueOf() - distance : canvasOptions.rangeMinVisible.valueOf() + distance
  365. },
  366. getMinBarSize: function(minBarSize) {
  367. var visibleArea = this.getCanvasVisibleArea();
  368. var minValue = this.from(visibleArea.min + minBarSize);
  369. return _abs(this.from(visibleArea.min) - (!isDefined(minValue) ? this.from(visibleArea.max) : minValue))
  370. },
  371. checkMinBarSize: function(value, minShownValue, stackValue) {
  372. return _abs(value) < minShownValue ? value >= 0 ? minShownValue : -minShownValue : value
  373. },
  374. translate: function(bp, direction) {
  375. var specialValue = this.translateSpecialCase(bp);
  376. if (isDefined(specialValue)) {
  377. return Math.round(specialValue)
  378. }
  379. if (isNaN(bp)) {
  380. return null
  381. }
  382. return this.to(bp, direction)
  383. },
  384. getInterval: function(interval) {
  385. var canvasOptions = this._canvasOptions;
  386. interval = isDefined(interval) ? interval : this._businessRange.interval;
  387. if (interval) {
  388. return Math.round(canvasOptions.ratioOfCanvasRange * interval)
  389. }
  390. return Math.round(canvasOptions.endPoint - canvasOptions.startPoint)
  391. },
  392. zoom: function(translate, scale, wholeRange) {
  393. var canvasOptions = this._canvasOptions;
  394. if (canvasOptions.rangeMinVisible.valueOf() === canvasOptions.rangeMaxVisible.valueOf() && 0 !== translate) {
  395. return this.zoomZeroLengthRange(translate, scale)
  396. }
  397. var startPoint = canvasOptions.startPoint;
  398. var endPoint = canvasOptions.endPoint;
  399. var isInverted = this.isInverted();
  400. var newStart = (startPoint + translate) / scale;
  401. var newEnd = (endPoint + translate) / scale;
  402. wholeRange = wholeRange || {};
  403. var minPoint = this.to(isInverted ? wholeRange.endValue : wholeRange.startValue);
  404. var maxPoint = this.to(isInverted ? wholeRange.startValue : wholeRange.endValue);
  405. var min;
  406. var max;
  407. if (minPoint > newStart) {
  408. newEnd -= newStart - minPoint;
  409. newStart = minPoint;
  410. min = isInverted ? wholeRange.endValue : wholeRange.startValue
  411. }
  412. if (maxPoint < newEnd) {
  413. newStart -= newEnd - maxPoint;
  414. newEnd = maxPoint;
  415. max = isInverted ? wholeRange.startValue : wholeRange.endValue
  416. }
  417. if (maxPoint - minPoint < newEnd - newStart) {
  418. newStart = minPoint;
  419. newEnd = maxPoint
  420. }
  421. translate = (endPoint - startPoint) * newStart / (newEnd - newStart) - startPoint;
  422. scale = (startPoint + translate) / newStart || 1;
  423. min = isDefined(min) ? min : adjust(this.from(newStart, 1));
  424. max = isDefined(max) ? max : adjust(this.from(newEnd, -1));
  425. if (min > max) {
  426. min = min > wholeRange.endValue ? wholeRange.endValue : min;
  427. max = max < wholeRange.startValue ? wholeRange.startValue : max
  428. } else {
  429. min = min < wholeRange.startValue ? wholeRange.startValue : min;
  430. max = max > wholeRange.endValue ? wholeRange.endValue : max
  431. }
  432. return {
  433. min: min,
  434. max: max,
  435. translate: adjust(translate),
  436. scale: adjust(scale)
  437. }
  438. },
  439. zoomZeroLengthRange: function(translate, scale) {
  440. var canvasOptions = this._canvasOptions;
  441. var min = canvasOptions.rangeMin;
  442. var max = canvasOptions.rangeMax;
  443. var correction = (max.valueOf() !== min.valueOf() ? max.valueOf() - min.valueOf() : _abs(canvasOptions.rangeMinVisible.valueOf() - min.valueOf())) / canvasOptions.canvasLength;
  444. var isDateTime = typeUtils.isDate(max) || typeUtils.isDate(min);
  445. var isLogarithmic = "logarithmic" === this._businessRange.axisType;
  446. var newMin = canvasOptions.rangeMinVisible.valueOf() - correction;
  447. var newMax = canvasOptions.rangeMaxVisible.valueOf() + correction;
  448. newMin = isLogarithmic ? adjust(Math.pow(canvasOptions.base, newMin)) : isDateTime ? new Date(newMin) : newMin;
  449. newMax = isLogarithmic ? adjust(Math.pow(canvasOptions.base, newMax)) : isDateTime ? new Date(newMax) : newMax;
  450. return {
  451. min: newMin,
  452. max: newMax,
  453. translate: translate,
  454. scale: scale
  455. }
  456. },
  457. getMinScale: function(zoom) {
  458. return zoom ? 1.1 : .9
  459. },
  460. getScale: function(val1, val2) {
  461. var canvasOptions = this._canvasOptions;
  462. if (canvasOptions.rangeMax === canvasOptions.rangeMin) {
  463. return 1
  464. }
  465. val1 = isDefined(val1) ? this._fromValue(val1) : canvasOptions.rangeMin;
  466. val2 = isDefined(val2) ? this._fromValue(val2) : canvasOptions.rangeMax;
  467. return (canvasOptions.rangeMax - canvasOptions.rangeMin) / Math.abs(val1 - val2)
  468. },
  469. isValid: function(value) {
  470. var co = this._canvasOptions;
  471. value = this._fromValue(value);
  472. return null !== value && !isNaN(value) && value.valueOf() + co.rangeDoubleError >= co.rangeMin && value.valueOf() - co.rangeDoubleError <= co.rangeMax
  473. },
  474. getCorrectValue: function(value, direction) {
  475. var that = this;
  476. var breaks = that._breaks;
  477. var prop;
  478. value = that._fromValue(value);
  479. if (that._breaks) {
  480. prop = that._checkValueAboutBreaks(breaks, value, "trFrom", "trTo", that._checkingMethodsAboutBreaks[0]);
  481. if (true === prop.inBreak) {
  482. return that._toValue(direction > 0 ? prop.break.trTo : prop.break.trFrom)
  483. }
  484. }
  485. return that._toValue(value)
  486. },
  487. to: function(bp, direction) {
  488. var range = this.getBusinessRange();
  489. if (isDefined(range.maxVisible) && isDefined(range.minVisible) && range.maxVisible.valueOf() === range.minVisible.valueOf()) {
  490. if (!isDefined(bp) || range.maxVisible.valueOf() !== bp.valueOf()) {
  491. return null
  492. }
  493. return this.translateSpecialCase(0 === bp && this._options.shiftZeroValue ? "canvas_position_default" : "canvas_position_middle")
  494. }
  495. bp = this._fromValue(bp);
  496. var that = this;
  497. var canvasOptions = that._canvasOptions;
  498. var breaks = that._breaks;
  499. var prop = {
  500. length: 0
  501. };
  502. var commonBreakSize = 0;
  503. if (void 0 !== breaks) {
  504. prop = that._checkValueAboutBreaks(breaks, bp, "trFrom", "trTo", that._checkingMethodsAboutBreaks[0]);
  505. commonBreakSize = isDefined(prop.breaksSize) ? prop.breaksSize : 0
  506. }
  507. if (true === prop.inBreak) {
  508. if (direction > 0) {
  509. return prop.break.start
  510. } else {
  511. if (direction < 0) {
  512. return prop.break.end
  513. } else {
  514. return null
  515. }
  516. }
  517. }
  518. return that._conversionValue(that._calculateProjection((bp - canvasOptions.rangeMinVisible - prop.length) * canvasOptions.ratioOfCanvasRange + commonBreakSize))
  519. },
  520. from: function(pos, direction) {
  521. var that = this;
  522. var breaks = that._breaks;
  523. var prop = {
  524. length: 0
  525. };
  526. var canvasOptions = that._canvasOptions;
  527. var startPoint = canvasOptions.startPoint;
  528. var commonBreakSize = 0;
  529. if (void 0 !== breaks) {
  530. prop = that._checkValueAboutBreaks(breaks, pos, "start", "end", that._checkingMethodsAboutBreaks[1]);
  531. commonBreakSize = isDefined(prop.breaksSize) ? prop.breaksSize : 0
  532. }
  533. if (true === prop.inBreak) {
  534. if (direction > 0) {
  535. return that._toValue(prop.break.trTo)
  536. } else {
  537. if (direction < 0) {
  538. return that._toValue(prop.break.trFrom)
  539. } else {
  540. return null
  541. }
  542. }
  543. }
  544. return that._toValue(that._calculateUnProjection((pos - startPoint - commonBreakSize) / canvasOptions.ratioOfCanvasRange + prop.length))
  545. },
  546. isValueProlonged: false,
  547. getRange: function() {
  548. return [this._toValue(this._canvasOptions.rangeMin), this._toValue(this._canvasOptions.rangeMax)]
  549. },
  550. getScreenRange: function() {
  551. return [this._canvasOptions.startPoint, this._canvasOptions.endPoint]
  552. },
  553. add: function(value, diff, dir) {
  554. return this._add(value, diff, (this._businessRange.invert ? -1 : 1) * dir)
  555. },
  556. _add: function(value, diff, coeff) {
  557. return this._toValue(this._fromValue(value) + diff * coeff)
  558. },
  559. _fromValue: function(value) {
  560. return null !== value ? Number(value) : null
  561. },
  562. _toValue: function(value) {
  563. return null !== value ? Number(value) : null
  564. },
  565. ratioOfCanvasRange: function() {
  566. return this._canvasOptions.ratioOfCanvasRange
  567. }
  568. };