base_sparkline.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. /**
  2. * DevExtreme (viz/sparklines/base_sparkline.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 eventsEngine = require("../../events/core/events_engine");
  11. var domAdapter = require("../../core/dom_adapter");
  12. var ready = require("../../core/utils/ready_callbacks").add;
  13. var isFunction = require("../../core/utils/type").isFunction;
  14. var BaseWidget = require("../core/base_widget");
  15. var extend = require("../../core/utils/extend").extend;
  16. var DEFAULT_LINE_SPACING = 2;
  17. var DEFAULT_EVENTS_DELAY = 100;
  18. var eventUtils = require("../../events/utils");
  19. var translator2DModule = require("../translators/translator2d");
  20. var _extend = extend;
  21. var _noop = require("../../core/utils/common").noop;
  22. function generateDefaultCustomizeTooltipCallback(fontOptions, rtlEnabled) {
  23. var lineSpacing = fontOptions.lineSpacing;
  24. var lineHeight = (void 0 !== lineSpacing && null !== lineSpacing ? lineSpacing : DEFAULT_LINE_SPACING) + fontOptions.size;
  25. return function(customizeObject) {
  26. var html = "";
  27. var vt = customizeObject.valueText;
  28. for (var i = 0; i < vt.length; i += 2) {
  29. html += "<tr><td>" + vt[i] + "</td><td style='width: 15px'></td><td style='text-align: " + (rtlEnabled ? "left" : "right") + "'>" + vt[i + 1] + "</td></tr>"
  30. }
  31. return {
  32. html: "<table style='border-spacing:0px; line-height: " + lineHeight + "px'>" + html + "</table>"
  33. }
  34. }
  35. }
  36. function generateCustomizeTooltipCallback(customizeTooltip, fontOptions, rtlEnabled) {
  37. var defaultCustomizeTooltip = generateDefaultCustomizeTooltipCallback(fontOptions, rtlEnabled);
  38. if (isFunction(customizeTooltip)) {
  39. return function(customizeObject) {
  40. var res = customizeTooltip.call(customizeObject, customizeObject);
  41. if (!("html" in res) && !("text" in res)) {
  42. _extend(res, defaultCustomizeTooltip.call(customizeObject, customizeObject))
  43. }
  44. return res
  45. }
  46. } else {
  47. return defaultCustomizeTooltip
  48. }
  49. }
  50. function createAxis(isHorizontal) {
  51. var translator = new translator2DModule.Translator2D({}, {}, {
  52. shiftZeroValue: !isHorizontal,
  53. isHorizontal: !!isHorizontal
  54. });
  55. return {
  56. getTranslator: function() {
  57. return translator
  58. },
  59. update: function(range, canvas, options) {
  60. translator.update(range, canvas, options)
  61. },
  62. getVisibleArea: function() {
  63. var visibleArea = translator.getCanvasVisibleArea();
  64. return [visibleArea.min, visibleArea.max]
  65. },
  66. visualRange: _noop,
  67. calculateInterval: _noop,
  68. getMarginOptions: function() {
  69. return {}
  70. }
  71. }
  72. }
  73. var BaseSparkline = BaseWidget.inherit({
  74. _getLayoutItems: _noop,
  75. _useLinks: false,
  76. _themeDependentChanges: ["OPTIONS"],
  77. _initCore: function() {
  78. var that = this;
  79. that._tooltipTracker = that._renderer.root;
  80. that._tooltipTracker.attr({
  81. "pointer-events": "visible"
  82. });
  83. that._createHtmlElements();
  84. that._initTooltipEvents();
  85. that._argumentAxis = createAxis(true);
  86. that._valueAxis = createAxis()
  87. },
  88. _getDefaultSize: function() {
  89. return this._defaultSize
  90. },
  91. _disposeCore: function() {
  92. this._disposeWidgetElements();
  93. this._disposeTooltipEvents();
  94. this._ranges = null
  95. },
  96. _optionChangesOrder: ["OPTIONS"],
  97. _change_OPTIONS: function() {
  98. this._prepareOptions();
  99. this._change(["UPDATE"])
  100. },
  101. _customChangesOrder: ["UPDATE"],
  102. _change_UPDATE: function() {
  103. this._update()
  104. },
  105. _update: function() {
  106. var that = this;
  107. if (that._tooltipShown) {
  108. that._tooltipShown = false;
  109. that._tooltip.hide()
  110. }
  111. that._cleanWidgetElements();
  112. that._updateWidgetElements();
  113. that._drawWidgetElements()
  114. },
  115. _updateWidgetElements: function() {
  116. var canvas = this._getCorrectCanvas();
  117. this._updateRange();
  118. this._argumentAxis.update(this._ranges.arg, canvas, this._getStick());
  119. this._valueAxis.update(this._ranges.val, canvas)
  120. },
  121. _getStick: function() {},
  122. _applySize: function(rect) {
  123. this._allOptions.size = {
  124. width: rect[2] - rect[0],
  125. height: rect[3] - rect[1]
  126. };
  127. this._change(["UPDATE"])
  128. },
  129. _setupResizeHandler: _noop,
  130. _prepareOptions: function() {
  131. return _extend(true, {}, this._themeManager.theme(), this.option())
  132. },
  133. _getTooltipCoords: function() {
  134. var canvas = this._canvas;
  135. var rootOffset = this._renderer.getRootOffset();
  136. return {
  137. x: canvas.width / 2 + rootOffset.left,
  138. y: canvas.height / 2 + rootOffset.top
  139. }
  140. },
  141. _initTooltipEvents: function() {
  142. var that = this;
  143. var data = {
  144. widget: that
  145. };
  146. that._showTooltipCallback = function() {
  147. var tooltip;
  148. if (!that._tooltipShown) {
  149. that._tooltipShown = true;
  150. tooltip = that._getTooltip();
  151. tooltip.isEnabled() && that._tooltip.show(that._getTooltipData(), that._getTooltipCoords(), {})
  152. }
  153. };
  154. that._hideTooltipCallback = function() {
  155. that._hideTooltipTimeout = null;
  156. if (that._tooltipShown) {
  157. that._tooltipShown = false;
  158. that._tooltip.hide()
  159. }
  160. };
  161. that._disposeCallbacks = function() {
  162. that = that._showTooltipCallback = that._hideTooltipCallback = that._disposeCallbacks = null
  163. };
  164. that._tooltipTracker.on(mouseEvents, data).on(touchEvents, data);
  165. that._tooltipTracker.on(menuEvents)
  166. },
  167. _stopCurrentHandling: function() {
  168. this._hideTooltip()
  169. },
  170. _disposeTooltipEvents: function() {
  171. var that = this;
  172. clearTimeout(that._hideTooltipTimeout);
  173. that._tooltipTracker.off();
  174. that._disposeCallbacks()
  175. },
  176. _getTooltip: function() {
  177. var that = this;
  178. if (!that._tooltip) {
  179. _initTooltip.apply(this, arguments);
  180. that._setTooltipRendererOptions(that._tooltipRendererOptions);
  181. that._tooltipRendererOptions = null;
  182. that._setTooltipOptions()
  183. }
  184. return that._tooltip
  185. }
  186. });
  187. var menuEvents = {
  188. "contextmenu.sparkline-tooltip": function(event) {
  189. if (eventUtils.isTouchEvent(event) || eventUtils.isPointerEvent(event)) {
  190. event.preventDefault()
  191. }
  192. },
  193. "MSHoldVisual.sparkline-tooltip": function(event) {
  194. event.preventDefault()
  195. }
  196. };
  197. var mouseEvents = {
  198. "mouseover.sparkline-tooltip": function(event) {
  199. isPointerDownCalled = false;
  200. var widget = event.data.widget;
  201. widget._x = event.pageX;
  202. widget._y = event.pageY;
  203. widget._tooltipTracker.off(mouseMoveEvents).on(mouseMoveEvents, event.data);
  204. widget._showTooltip()
  205. },
  206. "mouseout.sparkline-tooltip": function(event) {
  207. if (isPointerDownCalled) {
  208. return
  209. }
  210. var widget = event.data.widget;
  211. widget._tooltipTracker.off(mouseMoveEvents);
  212. widget._hideTooltip(DEFAULT_EVENTS_DELAY)
  213. }
  214. };
  215. var mouseMoveEvents = {
  216. "mousemove.sparkline-tooltip": function(event) {
  217. var widget = event.data.widget;
  218. widget._x = event.pageX;
  219. widget._y = event.pageY;
  220. widget._showTooltip()
  221. }
  222. };
  223. var active_touch_tooltip_widget = null;
  224. var touchStartTooltipProcessing = function(event) {
  225. var widget = active_touch_tooltip_widget;
  226. if (widget && widget !== event.data.widget) {
  227. widget._hideTooltip(DEFAULT_EVENTS_DELAY)
  228. }
  229. widget = active_touch_tooltip_widget = event.data.widget;
  230. widget._showTooltip();
  231. widget._touch = true
  232. };
  233. var touchStartDocumentProcessing = function() {
  234. var widget = active_touch_tooltip_widget;
  235. if (widget) {
  236. if (!widget._touch) {
  237. widget._hideTooltip(DEFAULT_EVENTS_DELAY);
  238. active_touch_tooltip_widget = null
  239. }
  240. widget._touch = null
  241. }
  242. };
  243. var touchEndDocumentProcessing = function() {
  244. var widget = active_touch_tooltip_widget;
  245. if (widget) {
  246. widget._hideTooltip(DEFAULT_EVENTS_DELAY);
  247. active_touch_tooltip_widget = null
  248. }
  249. };
  250. var isPointerDownCalled = false;
  251. var touchEvents = {
  252. "pointerdown.sparkline-tooltip": touchStartTooltipProcessing,
  253. "touchstart.sparkline-tooltip": touchStartTooltipProcessing
  254. };
  255. ready(function() {
  256. eventsEngine.subscribeGlobal(domAdapter.getDocument(), {
  257. "pointerdown.sparkline-tooltip": function() {
  258. isPointerDownCalled = true;
  259. touchStartDocumentProcessing()
  260. },
  261. "touchstart.sparkline-tooltip": touchStartDocumentProcessing,
  262. "pointerup.sparkline-tooltip": touchEndDocumentProcessing,
  263. "touchend.sparkline-tooltip": touchEndDocumentProcessing
  264. })
  265. });
  266. module.exports = BaseSparkline;
  267. BaseSparkline.addPlugin(require("../core/tooltip").plugin);
  268. var _initTooltip = BaseSparkline.prototype._initTooltip;
  269. BaseSparkline.prototype._initTooltip = _noop;
  270. var _disposeTooltip = BaseSparkline.prototype._disposeTooltip;
  271. BaseSparkline.prototype._disposeTooltip = function() {
  272. if (this._tooltip) {
  273. _disposeTooltip.apply(this, arguments)
  274. }
  275. };
  276. BaseSparkline.prototype._setTooltipRendererOptions = function() {
  277. var options = this._getRendererOptions();
  278. if (this._tooltip) {
  279. this._tooltip.setRendererOptions(options)
  280. } else {
  281. this._tooltipRendererOptions = options
  282. }
  283. };
  284. BaseSparkline.prototype._setTooltipOptions = function() {
  285. var tooltip = this._tooltip;
  286. var options = tooltip && this._getOption("tooltip");
  287. tooltip && tooltip.update(_extend({}, options, {
  288. customizeTooltip: generateCustomizeTooltipCallback(options.customizeTooltip, options.font, this.option("rtlEnabled")),
  289. enabled: options.enabled && this._isTooltipEnabled()
  290. }))
  291. };
  292. BaseSparkline.prototype._showTooltip = function() {
  293. var that = this;
  294. clearTimeout(that._hideTooltipTimeout);
  295. that._hideTooltipTimeout = null;
  296. that._showTooltipCallback()
  297. };
  298. BaseSparkline.prototype._hideTooltip = function(delay) {
  299. var that = this;
  300. clearTimeout(that._hideTooltipTimeout);
  301. if (delay) {
  302. that._hideTooltipTimeout = setTimeout(that._hideTooltipCallback, delay)
  303. } else {
  304. that._hideTooltipCallback()
  305. }
  306. };
  307. var exportPlugin = extend(true, {}, require("../core/export").plugin, {
  308. init: _noop,
  309. dispose: _noop,
  310. customize: null,
  311. members: {
  312. _getExportMenuOptions: null
  313. }
  314. });
  315. BaseSparkline.addPlugin(exportPlugin);