base_range_container.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /**
  2. * DevExtreme (viz/gauges/base_range_container.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 iterateUtils = require("../../core/utils/iterator");
  11. var BaseElement = require("./base_indicators").BaseElement;
  12. var _Number = Number;
  13. var _abs = Math.abs;
  14. var _isString = require("../../core/utils/type").isString;
  15. var _isArray = Array.isArray;
  16. var _isFinite = isFinite;
  17. var _each = iterateUtils.each;
  18. var BaseRangeContainer = BaseElement.inherit({
  19. _init: function() {
  20. this._root = this._renderer.g().attr({
  21. "class": "dxg-range-container"
  22. }).linkOn(this._container, "range-container")
  23. },
  24. _dispose: function() {
  25. this._root.linkOff()
  26. },
  27. clean: function() {
  28. this._root.linkRemove().clear();
  29. this._options = this.enabled = null;
  30. return this
  31. },
  32. _getRanges: function() {
  33. var that = this;
  34. var options = that._options;
  35. var translator = that._translator;
  36. var totalStart = translator.getDomain()[0];
  37. var totalEnd = translator.getDomain()[1];
  38. var totalDelta = totalEnd - totalStart;
  39. var isNotEmptySegment = totalDelta >= 0 ? isNotEmptySegmentAsc : isNotEmptySegmentDesc;
  40. var subtractSegment = totalDelta >= 0 ? subtractSegmentAsc : subtractSegmentDesc;
  41. var list = [];
  42. var ranges = [];
  43. var backgroundRanges = [{
  44. start: totalStart,
  45. end: totalEnd
  46. }];
  47. var threshold = _abs(totalDelta) / 1e4;
  48. var backgroundColor = _isString(options.backgroundColor) ? options.backgroundColor : "none";
  49. var width = options.width || {};
  50. var startWidth = _Number(width > 0 ? width : width.start);
  51. var endWidth = _Number(width > 0 ? width : width.end);
  52. var deltaWidth = endWidth - startWidth;
  53. if (void 0 !== options.ranges && !_isArray(options.ranges)) {
  54. return null
  55. }
  56. if (!(startWidth >= 0 && endWidth >= 0 && startWidth + endWidth > 0)) {
  57. return null
  58. }
  59. list = (_isArray(options.ranges) ? options.ranges : []).reduce(function(result, rangeOptions, i) {
  60. rangeOptions = rangeOptions || {};
  61. var start = translator.adjust(rangeOptions.startValue);
  62. var end = translator.adjust(rangeOptions.endValue);
  63. if (_isFinite(start) && _isFinite(end) && isNotEmptySegment(start, end, threshold)) {
  64. result.push({
  65. start: start,
  66. end: end,
  67. color: rangeOptions.color,
  68. classIndex: i
  69. })
  70. }
  71. return result
  72. }, []);
  73. var palette = that._themeManager.createPalette(options.palette, {
  74. type: "indicatingSet",
  75. extensionMode: options.paletteExtensionMode,
  76. keepLastColorInEnd: true,
  77. count: list.length
  78. });
  79. _each(list, function(_, item) {
  80. var paletteColor = palette.getNextColor();
  81. item.color = _isString(item.color) && item.color || paletteColor || "none";
  82. item.className = "dxg-range dxg-range-" + item.classIndex;
  83. delete item.classIndex
  84. });
  85. _each(list, function(_, item) {
  86. var i;
  87. var ii;
  88. var sub;
  89. var subs;
  90. var range;
  91. var newRanges = [];
  92. var newBackgroundRanges = [];
  93. for (i = 0, ii = ranges.length; i < ii; ++i) {
  94. range = ranges[i];
  95. subs = subtractSegment(range.start, range.end, item.start, item.end);
  96. (sub = subs[0]) && (sub.color = range.color) && (sub.className = range.className) && newRanges.push(sub);
  97. (sub = subs[1]) && (sub.color = range.color) && (sub.className = range.className) && newRanges.push(sub)
  98. }
  99. newRanges.push(item);
  100. ranges = newRanges;
  101. for (i = 0, ii = backgroundRanges.length; i < ii; ++i) {
  102. range = backgroundRanges[i];
  103. subs = subtractSegment(range.start, range.end, item.start, item.end);
  104. (sub = subs[0]) && newBackgroundRanges.push(sub);
  105. (sub = subs[1]) && newBackgroundRanges.push(sub)
  106. }
  107. backgroundRanges = newBackgroundRanges
  108. });
  109. _each(backgroundRanges, function(_, range) {
  110. range.color = backgroundColor;
  111. range.className = "dxg-range dxg-background-range";
  112. ranges.push(range)
  113. });
  114. _each(ranges, function(_, range) {
  115. range.startWidth = (range.start - totalStart) / totalDelta * deltaWidth + startWidth;
  116. range.endWidth = (range.end - totalStart) / totalDelta * deltaWidth + startWidth
  117. });
  118. return ranges
  119. },
  120. render: function(options) {
  121. var that = this;
  122. that._options = options;
  123. that._processOptions();
  124. that._ranges = that._getRanges();
  125. if (that._ranges) {
  126. that.enabled = true;
  127. that._root.linkAppend()
  128. }
  129. return that
  130. },
  131. resize: function(layout) {
  132. var that = this;
  133. that._root.clear();
  134. if (that._isVisible(layout)) {
  135. _each(that._ranges, function(_, range) {
  136. that._createRange(range, layout).attr({
  137. fill: range.color,
  138. "class": range.className
  139. }).append(that._root)
  140. })
  141. }
  142. return that
  143. },
  144. _processOptions: null,
  145. _isVisible: null,
  146. _createRange: null,
  147. getColorForValue: function(value) {
  148. var color = null;
  149. _each(this._ranges, function(_, range) {
  150. if (range.start <= value && value <= range.end || range.start >= value && value >= range.end) {
  151. color = range.color;
  152. return false
  153. }
  154. });
  155. return color
  156. }
  157. });
  158. function subtractSegmentAsc(segmentStart, segmentEnd, otherStart, otherEnd) {
  159. var result;
  160. if (otherStart > segmentStart && otherEnd < segmentEnd) {
  161. result = [{
  162. start: segmentStart,
  163. end: otherStart
  164. }, {
  165. start: otherEnd,
  166. end: segmentEnd
  167. }]
  168. } else {
  169. if (otherStart >= segmentEnd || otherEnd <= segmentStart) {
  170. result = [{
  171. start: segmentStart,
  172. end: segmentEnd
  173. }]
  174. } else {
  175. if (otherStart <= segmentStart && otherEnd >= segmentEnd) {
  176. result = []
  177. } else {
  178. if (otherStart > segmentStart) {
  179. result = [{
  180. start: segmentStart,
  181. end: otherStart
  182. }]
  183. } else {
  184. if (otherEnd < segmentEnd) {
  185. result = [{
  186. start: otherEnd,
  187. end: segmentEnd
  188. }]
  189. }
  190. }
  191. }
  192. }
  193. }
  194. return result
  195. }
  196. function subtractSegmentDesc(segmentStart, segmentEnd, otherStart, otherEnd) {
  197. var result;
  198. if (otherStart < segmentStart && otherEnd > segmentEnd) {
  199. result = [{
  200. start: segmentStart,
  201. end: otherStart
  202. }, {
  203. start: otherEnd,
  204. end: segmentEnd
  205. }]
  206. } else {
  207. if (otherStart <= segmentEnd || otherEnd >= segmentStart) {
  208. result = [{
  209. start: segmentStart,
  210. end: segmentEnd
  211. }]
  212. } else {
  213. if (otherStart >= segmentStart && otherEnd <= segmentEnd) {
  214. result = []
  215. } else {
  216. if (otherStart < segmentStart) {
  217. result = [{
  218. start: segmentStart,
  219. end: otherStart
  220. }]
  221. } else {
  222. if (otherEnd > segmentEnd) {
  223. result = [{
  224. start: otherEnd,
  225. end: segmentEnd
  226. }]
  227. }
  228. }
  229. }
  230. }
  231. }
  232. return result
  233. }
  234. function isNotEmptySegmentAsc(start, end, threshold) {
  235. return end - start >= threshold
  236. }
  237. function isNotEmptySegmentDesc(start, end, threshold) {
  238. return start - end >= threshold
  239. }
  240. module.exports = BaseRangeContainer;