UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

448 lines (446 loc) • 16.1 kB
/** * DevExtreme (esm/viz/gauges/base_indicators.js) * Version: 21.1.4 * Build date: Mon Jun 21 2021 * * Copyright (c) 2012 - 2021 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ import { noop } from "../../core/utils/common"; import { each } from "../../core/utils/iterator"; var _isFinite = isFinite; var _Number = Number; var _round = Math.round; import { formatValue, getSampleText } from "./base_gauge"; var _formatValue = formatValue; var _getSampleText = getSampleText; import { patchFontOptions as _patchFontOptions } from "../core/utils"; import { extend } from "../../core/utils/extend"; import Class from "../../core/class"; export var BaseElement = Class.inherit({ ctor: function(parameters) { var that = this; each(parameters, (function(name, value) { that["_" + name] = value })); that._init() }, dispose: function() { var that = this; that._dispose(); each(that, (function(name) { that[name] = null })); return that }, getOffset: function() { return _Number(this._options.offset) || 0 } }); export var BaseIndicator = BaseElement.inherit({ _init: function() { this._rootElement = this._createRoot().linkOn(this._owner, { name: "value-indicator", after: "core" }); this._trackerElement = this._createTracker() }, _dispose: function() { this._rootElement.linkOff() }, _setupAnimation: function() { var that = this; if (that._options.animation) { that._animation = { step: function(pos) { that._actualValue = that._animation.start + that._animation.delta * pos; that._actualPosition = that._translator.translate(that._actualValue); that._move() }, duration: that._options.animation.duration > 0 ? _Number(that._options.animation.duration) : 0, easing: that._options.animation.easing } } }, _runAnimation: function(value) { var animation = this._animation; animation.start = this._actualValue; animation.delta = value - this._actualValue; this._rootElement.animate({ _: 0 }, { step: animation.step, duration: animation.duration, easing: animation.easing }) }, _createRoot: function() { return this._renderer.g().attr({ class: this._className }) }, _createTracker: function() { return this._renderer.path([], "area") }, _getTrackerSettings: noop, clean: function() { this._animation && this._rootElement.stopAnimation(); this._rootElement.linkRemove().clear(); this._clear(); this._tracker.detach(this._trackerElement); this._options = this.enabled = this._animation = null; return this }, render: function(options) { this.type = options.type; this._options = options; this._actualValue = this._currentValue = this._translator.adjust(this._options.currentValue); this.enabled = this._isEnabled(); if (this.enabled) { this._setupAnimation(); this._rootElement.attr({ fill: this._options.color }).linkAppend(); this._tracker.attach(this._trackerElement, this, this._trackerInfo) } return this }, resize: function(layout) { this._rootElement.clear(); this._clear(); this.visible = this._isVisible(layout); if (this.visible) { extend(this._options, layout); this._actualPosition = this._translator.translate(this._actualValue); this._render(); this._trackerElement.attr(this._getTrackerSettings()); this._move() } return this }, value: function(arg, _noAnimation) { var val; var rootElement = this._rootElement; var visibility = null; if (void 0 === arg) { return this._currentValue } if (null === arg) { visibility = "hidden"; this._currentValue = arg } else { val = this._translator.adjust(arg); if (this._currentValue !== val && _isFinite(val)) { this._currentValue = val; if (this.visible) { if (this._animation && !_noAnimation) { this._runAnimation(val) } else { this._actualValue = val; this._actualPosition = this._translator.translate(val); this._move() } } } } rootElement.attr({ visibility: visibility }); return this }, _isEnabled: null, _isVisible: null, _render: null, _clear: null, _move: null }); var COEFFICIENTS_MAP = {}; COEFFICIENTS_MAP["right-bottom"] = COEFFICIENTS_MAP.rb = [0, -1, -1, 0, 0, 1, 1, 0]; COEFFICIENTS_MAP["bottom-right"] = COEFFICIENTS_MAP.br = [-1, 0, 0, -1, 1, 0, 0, 1]; COEFFICIENTS_MAP["left-bottom"] = COEFFICIENTS_MAP.lb = [0, -1, 1, 0, 0, 1, -1, 0]; COEFFICIENTS_MAP["bottom-left"] = COEFFICIENTS_MAP.bl = [1, 0, 0, -1, -1, 0, 0, 1]; COEFFICIENTS_MAP["left-top"] = COEFFICIENTS_MAP.lt = [0, 1, 1, 0, 0, -1, -1, 0]; COEFFICIENTS_MAP["top-left"] = COEFFICIENTS_MAP.tl = [1, 0, 0, 1, -1, 0, 0, -1]; COEFFICIENTS_MAP["right-top"] = COEFFICIENTS_MAP.rt = [0, 1, -1, 0, 0, -1, 1, 0]; COEFFICIENTS_MAP["top-right"] = COEFFICIENTS_MAP.tr = [-1, 0, 0, 1, 1, 0, 0, -1]; function getTextCloudInfo(options) { var x = options.x; var y = options.y; var type = COEFFICIENTS_MAP[options.type]; var cloudWidth = options.cloudWidth; var cloudHeight = options.cloudHeight; var tailWidth; var tailHeight; var cx = x; var cy = y; tailWidth = tailHeight = options.tailLength; if (1 & type[0]) { tailHeight = Math.min(tailHeight, cloudHeight / 3) } else { tailWidth = Math.min(tailWidth, cloudWidth / 3) } return { cx: _round(cx + type[0] * tailWidth + (type[0] + type[2]) * cloudWidth / 2), cy: _round(cy + type[1] * tailHeight + (type[1] + type[3]) * cloudHeight / 2), points: [_round(x), _round(y), _round(x += type[0] * (cloudWidth + tailWidth)), _round(y += type[1] * (cloudHeight + tailHeight)), _round(x += type[2] * cloudWidth), _round(y += type[3] * cloudHeight), _round(x += type[4] * cloudWidth), _round(y += type[5] * cloudHeight), _round(x += type[6] * (cloudWidth - tailWidth)), _round(y += type[7] * (cloudHeight - tailHeight))] } } export var BaseTextCloudMarker = BaseIndicator.inherit({ _move: function() { var options = this._options; var textCloudOptions = this._getTextCloudOptions(); var text = _formatValue(this._actualValue, options.text); this._text.attr({ text: text }); var bBox = this._text.getBBox(); var x = textCloudOptions.x; var y = textCloudOptions.y; var cloudWidth = (bBox.width || text.length * this._textUnitWidth) + 2 * options.horizontalOffset; var cloudHeight = (bBox.height || this._textHeight) + 2 * options.verticalOffset; var info = getTextCloudInfo({ x: x, y: y, cloudWidth: cloudWidth, cloudHeight: cloudHeight, tailLength: options.arrowLength, type: this._correctCloudType(textCloudOptions.type, { x: x, y: y }, { width: cloudWidth, height: cloudHeight }) }); this._text.attr({ x: info.cx, y: info.cy + this._textVerticalOffset }); this._cloud.attr({ points: info.points }); this._trackerElement && this._trackerElement.attr({ points: info.points }) }, _measureText: function() { var root; var text; var bBox; var sampleText; if (!this._textVerticalOffset) { root = this._createRoot().append(this._owner); sampleText = _getSampleText(this._translator, this._options.text); text = this._renderer.text(sampleText, 0, 0).attr({ align: "center" }).css(_patchFontOptions(this._options.text.font)).append(root); bBox = text.getBBox(); root.remove(); this._textVerticalOffset = -bBox.y - bBox.height / 2; this._textWidth = bBox.width; this._textHeight = bBox.height; this._textUnitWidth = this._textWidth / sampleText.length; this._textFullWidth = this._textWidth + 2 * this._options.horizontalOffset; this._textFullHeight = this._textHeight + 2 * this._options.verticalOffset } }, _render: function() { this._measureText(); this._cloud = this._cloud || this._renderer.path([], "area").append(this._rootElement); this._text = this._text || this._renderer.text().append(this._rootElement); this._text.attr({ align: "center" }).css(_patchFontOptions(this._options.text.font)) }, _clear: function() { delete this._cloud; delete this._text }, getTooltipParameters: function() { var position = this._getTextCloudOptions(); return { x: position.x, y: position.y, value: this._currentValue, color: this._options.color } }, _correctCloudType: type => type }); export var BaseRangeBar = BaseIndicator.inherit({ _measureText: function() { var root; var text; var bBox; this._hasText = this._isTextVisible(); if (this._hasText && !this._textVerticalOffset) { root = this._createRoot().append(this._owner); text = this._renderer.text(_getSampleText(this._translator, this._options.text), 0, 0).attr({ class: "dxg-text", align: "center" }).css(_patchFontOptions(this._options.text.font)).append(root); bBox = text.getBBox(); root.remove(); this._textVerticalOffset = -bBox.y - bBox.height / 2; this._textWidth = bBox.width; this._textHeight = bBox.height } }, _move: function() { this._updateBarItemsPositions(); if (this._hasText) { this._text.attr({ text: _formatValue(this._actualValue, this._options.text) }); this._updateTextPosition(); this._updateLinePosition() } }, _updateBarItems: function() { var options = this._options; var spaceColor; var translator = this._translator; this._setBarSides(); this._startPosition = translator.translate(translator.getDomainStart()); this._endPosition = translator.translate(translator.getDomainEnd()); this._basePosition = translator.translate(options.baseValue); this._space = this._getSpace(); var backgroundColor = options.backgroundColor || "none"; if ("none" !== backgroundColor && this._space > 0) { spaceColor = options.containerBackgroundColor || "none" } else { this._space = 0; spaceColor = "none" } this._backItem1.attr({ fill: backgroundColor }); this._backItem2.attr({ fill: backgroundColor }); this._spaceItem1.attr({ fill: spaceColor }); this._spaceItem2.attr({ fill: spaceColor }) }, _getSpace: function() { return 0 }, _updateTextItems: function() { if (this._hasText) { this._line = this._line || this._renderer.path([], "line").attr({ class: "dxg-main-bar", "stroke-linecap": "square" }).append(this._rootElement); this._text = this._text || this._renderer.text("", 0, 0).attr({ class: "dxg-text" }).append(this._rootElement); this._text.attr({ align: this._getTextAlign() }).css(this._getFontOptions()); this._setTextItemsSides() } else { if (this._line) { this._line.remove(); delete this._line } if (this._text) { this._text.remove(); delete this._text } } }, _isTextVisible: function() { return false }, _getTextAlign: function() { return "center" }, _getFontOptions: function() { var options = this._options; var font = options.text.font; if (!font || !font.color) { font = extend({}, font, { color: options.color }) } return _patchFontOptions(font) }, _updateBarItemsPositions: function() { var positions = this._getPositions(); this._backItem1.attr(this._buildItemSettings(positions.start, positions.back1)); this._backItem2.attr(this._buildItemSettings(positions.back2, positions.end)); this._spaceItem1.attr(this._buildItemSettings(positions.back1, positions.main1)); this._spaceItem2.attr(this._buildItemSettings(positions.main2, positions.back2)); this._mainItem.attr(this._buildItemSettings(positions.main1, positions.main2)); this._trackerElement && this._trackerElement.attr(this._buildItemSettings(positions.main1, positions.main2)) }, _render: function() { this._measureText(); if (!this._backItem1) { this._backItem1 = this._createBarItem(); this._backItem1.attr({ class: "dxg-back-bar" }) } if (!this._backItem2) { this._backItem2 = this._createBarItem(); this._backItem2.attr({ class: "dxg-back-bar" }) } if (!this._spaceItem1) { this._spaceItem1 = this._createBarItem(); this._spaceItem1.attr({ class: "dxg-space-bar" }) } if (!this._spaceItem2) { this._spaceItem2 = this._createBarItem(); this._spaceItem2.attr({ class: "dxg-space-bar" }) } if (!this._mainItem) { this._mainItem = this._createBarItem(); this._mainItem.attr({ class: "dxg-main-bar" }) } this._updateBarItems(); this._updateTextItems() }, _clear: function() { delete this._backItem1; delete this._backItem2; delete this._spaceItem1; delete this._spaceItem2; delete this._mainItem; delete this._hasText; delete this._line; delete this._text }, getTooltipParameters: function() { var position = this._getTooltipPosition(); return { x: position.x, y: position.y, value: this._currentValue, color: this._options.color, offset: 0 } } });