| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645 |
- /**
- * DevExtreme (viz/gauges/bar_gauge.js)
- * Version: 19.1.16
- * Build date: Tue Oct 18 2022
- *
- * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
- * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
- */
- "use strict";
- var PI_DIV_180 = Math.PI / 180;
- var _abs = Math.abs;
- var _round = Math.round;
- var _floor = Math.floor;
- var _min = Math.min;
- var _max = Math.max;
- var registerComponent = require("../../core/component_registrator");
- var objectUtils = require("../../core/utils/object");
- var commonUtils = require("../../core/utils/common");
- var extend = require("../../core/utils/extend").extend;
- var _normalizeEnum = require("../core/utils").normalizeEnum;
- var baseGaugeModule = require("./base_gauge");
- var dxBaseGauge = baseGaugeModule.dxBaseGauge;
- var _getSampleText = baseGaugeModule.getSampleText;
- var _formatValue = baseGaugeModule.formatValue;
- var _compareArrays = baseGaugeModule.compareArrays;
- var dxCircularGauge = require("./circular_gauge");
- var _isArray = Array.isArray;
- var vizUtils = require("../core/utils");
- var _convertAngleToRendererSpace = vizUtils.convertAngleToRendererSpace;
- var _getCosAndSin = vizUtils.getCosAndSin;
- var _patchFontOptions = vizUtils.patchFontOptions;
- var _Number = Number;
- var _isFinite = isFinite;
- var _noop = commonUtils.noop;
- var _extend = extend;
- var OPTION_VALUES = "values";
- var dxBarGauge = dxBaseGauge.inherit({
- _rootClass: "dxbg-bar-gauge",
- _themeSection: "barGauge",
- _fontFields: ["label.font", "legend.font", "legend.title.font", "legend.title.subtitle.font"],
- _initCore: function() {
- var that = this;
- that.callBase.apply(that, arguments);
- that._barsGroup = that._renderer.g().attr({
- "class": "dxbg-bars"
- }).linkOn(that._renderer.root, "bars");
- that._values = [];
- that._context = {
- renderer: that._renderer,
- translator: that._translator,
- tracker: that._tracker,
- group: that._barsGroup
- };
- that._animateStep = function(pos) {
- var bars = that._bars;
- var i;
- var ii;
- for (i = 0, ii = bars.length; i < ii; ++i) {
- bars[i].animate(pos)
- }
- };
- that._animateComplete = function() {
- that._bars.forEach(function(bar) {
- return bar.endAnimation()
- });
- that._checkOverlap()
- }
- },
- _disposeCore: function() {
- var that = this;
- that._barsGroup.linkOff();
- that._barsGroup = that._values = that._context = that._animateStep = that._animateComplete = null;
- that.callBase.apply(that, arguments)
- },
- _setupDomainCore: function() {
- var that = this;
- var startValue = that.option("startValue");
- var endValue = that.option("endValue");
- _isFinite(startValue) || (startValue = 0);
- _isFinite(endValue) || (endValue = 100);
- that._translator.setDomain(startValue, endValue);
- that._baseValue = that._translator.adjust(that.option("baseValue"));
- _isFinite(that._baseValue) || (that._baseValue = startValue < endValue ? startValue : endValue)
- },
- _getDefaultSize: function() {
- return {
- width: 300,
- height: 300
- }
- },
- _setupCodomain: dxCircularGauge.prototype._setupCodomain,
- _getApproximateScreenRange: function() {
- var that = this;
- var sides = that._area.sides;
- var width = that._canvas.width / (sides.right - sides.left);
- var height = that._canvas.height / (sides.down - sides.up);
- var r = width < height ? width : height;
- return -that._translator.getCodomainRange() * r * PI_DIV_180
- },
- _setupAnimationSettings: function() {
- var that = this;
- that.callBase.apply(that, arguments);
- if (that._animationSettings) {
- that._animationSettings.step = that._animateStep;
- that._animationSettings.complete = that._animateComplete
- }
- },
- _cleanContent: function() {
- var that = this;
- that._barsGroup.linkRemove();
- that._animationSettings && that._barsGroup.stopAnimation();
- that._barsGroup.clear()
- },
- _renderContent: function() {
- var that = this;
- var labelOptions = that.option("label");
- var text;
- var bBox;
- var context = that._context;
- that._barsGroup.linkAppend();
- context.textEnabled = void 0 === labelOptions || labelOptions && (!("visible" in labelOptions) || labelOptions.visible);
- if (context.textEnabled) {
- context.textColor = labelOptions && labelOptions.font && labelOptions.font.color || null;
- labelOptions = _extend(true, {}, that._themeManager.theme().label, labelOptions);
- context.formatOptions = {
- format: void 0 !== labelOptions.format ? labelOptions.format : that._defaultFormatOptions,
- customizeText: labelOptions.customizeText
- };
- context.textOptions = {
- align: "center"
- };
- context.fontStyles = _patchFontOptions(_extend({}, that._themeManager.theme().label.font, labelOptions.font, {
- color: null
- }));
- that._textIndent = labelOptions.indent > 0 ? _Number(labelOptions.indent) : 0;
- context.lineWidth = labelOptions.connectorWidth > 0 ? _Number(labelOptions.connectorWidth) : 0;
- context.lineColor = labelOptions.connectorColor || null;
- text = that._renderer.text(_getSampleText(that._translator, context.formatOptions), 0, 0).attr(context.textOptions).css(context.fontStyles).append(that._barsGroup);
- bBox = text.getBBox();
- text.remove();
- context.textY = bBox.y;
- context.textWidth = bBox.width;
- context.textHeight = bBox.height
- }
- dxCircularGauge.prototype._applyMainLayout.call(that);
- that._renderBars()
- },
- _measureMainElements: function() {
- var result = {
- maxRadius: this._area.radius
- };
- if (this._context.textEnabled) {
- result.horizontalMargin = this._context.textWidth;
- result.verticalMargin = this._context.textHeight;
- result.inverseHorizontalMargin = this._context.textWidth / 2;
- result.inverseVerticalMargin = this._context.textHeight / 2
- }
- return result
- },
- _renderBars: function() {
- var that = this;
- var options = _extend({}, that._themeManager.theme(), that.option());
- var radius;
- var area = that._area;
- var relativeInnerRadius = options.relativeInnerRadius > 0 && options.relativeInnerRadius < 1 ? _Number(options.relativeInnerRadius) : .1;
- radius = area.radius;
- if (that._context.textEnabled) {
- that._textIndent = _round(_min(that._textIndent, radius / 2));
- radius -= that._textIndent
- }
- that._outerRadius = _floor(radius);
- that._innerRadius = _floor(radius * relativeInnerRadius);
- that._barSpacing = options.barSpacing > 0 ? _Number(options.barSpacing) : 0;
- _extend(that._context, {
- backgroundColor: options.backgroundColor,
- x: area.x,
- y: area.y,
- startAngle: area.startCoord,
- endAngle: area.endCoord,
- baseAngle: that._translator.translate(that._baseValue)
- });
- that._arrangeBars()
- },
- _arrangeBars: function() {
- var that = this;
- var radius = that._outerRadius - that._innerRadius;
- var context = that._context;
- var i;
- var count = that._bars.length;
- that._beginValueChanging();
- context.barSize = count > 0 ? _max((radius - (count - 1) * that._barSpacing) / count, 1) : 0;
- var spacing = count > 1 ? _max(_min((radius - count * context.barSize) / (count - 1), that._barSpacing), 0) : 0;
- var _count = _min(_floor((radius + spacing) / context.barSize), count);
- that._setBarsCount(count);
- radius = that._outerRadius;
- context.textRadius = radius;
- context.textIndent = that._textIndent;
- that._palette.reset();
- var unitOffset = context.barSize + spacing;
- var colors = that._palette.generateColors(_count);
- for (i = 0; i < _count; ++i, radius -= unitOffset) {
- that._bars[i].arrange({
- radius: radius,
- color: colors[i]
- })
- }
- for (var _i = _count; _i < count; _i++) {
- that._bars[_i].hide()
- }
- if (that._animationSettings && !that._noAnimation) {
- that._animateBars()
- } else {
- that._updateBars()
- }
- that._endValueChanging()
- },
- _setBarsCount: function() {
- var that = this;
- if (that._bars.length > 0) {
- if (that._dummyBackground) {
- that._dummyBackground.dispose();
- that._dummyBackground = null
- }
- } else {
- if (!that._dummyBackground) {
- that._dummyBackground = that._renderer.arc().attr({
- "stroke-linejoin": "round"
- })
- }
- that._dummyBackground.attr({
- x: that._context.x,
- y: that._context.y,
- outerRadius: that._outerRadius,
- innerRadius: that._innerRadius,
- startAngle: that._context.endAngle,
- endAngle: that._context.startAngle,
- fill: that._context.backgroundColor
- }).append(that._barsGroup)
- }
- },
- _updateBars: function() {
- this._bars.forEach(function(bar) {
- return bar.applyValue()
- });
- this._checkOverlap()
- },
- _checkOverlap: function() {
- var that = this;
- var bars = that._bars;
- var overlapStrategy = _normalizeEnum(that._getOption("resolveLabelOverlapping", true));
- if ("none" === overlapStrategy) {
- return
- }
- var sortedBars = bars.concat().sort(function(a, b) {
- return a.getValue() - b.getValue()
- });
- var currentIndex = 0;
- var nextIndex = 1;
- while (currentIndex < sortedBars.length && nextIndex < sortedBars.length) {
- var current = sortedBars[currentIndex];
- var next = sortedBars[nextIndex];
- if (current.checkIntersect(next)) {
- next.hideLabel();
- nextIndex++
- } else {
- currentIndex = nextIndex;
- nextIndex = currentIndex + 1
- }
- }
- },
- _animateBars: function() {
- var that = this;
- var i;
- var ii = that._bars.length;
- if (ii > 0) {
- for (i = 0; i < ii; ++i) {
- that._bars[i].beginAnimation()
- }
- that._barsGroup.animate({
- _: 0
- }, that._animationSettings)
- }
- },
- _buildNodes: function() {
- var that = this;
- var options = that._options;
- that._palette = that._themeManager.createPalette(options.palette, {
- useHighlight: true,
- extensionMode: options.paletteExtensionMode
- });
- that._palette.reset();
- that._bars = that._bars || [];
- that._animationSettings && that._barsGroup.stopAnimation();
- var barValues = that._values.filter(_isFinite);
- var count = barValues.length;
- if (that._bars.length > count) {
- var ii = that._bars.length;
- for (var i = count; i < ii; ++i) {
- that._bars[i].dispose()
- }
- that._bars.splice(count, ii - count)
- } else {
- if (that._bars.length < count) {
- for (var _i2 = that._bars.length; _i2 < count; ++_i2) {
- that._bars.push(new BarWrapper(_i2, that._context))
- }
- }
- }
- that._bars.forEach(function(bar, index) {
- bar.update({
- color: that._palette.getNextColor(count),
- value: barValues[index]
- })
- })
- },
- _updateValues: function(values) {
- var that = this;
- var list = _isArray(values) && values || _isFinite(values) && [values] || [];
- var i;
- var ii = list.length;
- var value;
- that._values.length = ii;
- for (i = 0; i < ii; ++i) {
- value = list[i];
- that._values[i] = value = _Number(_isFinite(value) ? value : that._values[i])
- }
- if (!that._resizing) {
- if (!_compareArrays(that._values, that.option(OPTION_VALUES))) {
- that.option(OPTION_VALUES, that._values.slice())
- }
- }
- this._change(["NODES"])
- },
- values: function(arg) {
- if (void 0 !== arg) {
- this._updateValues(arg);
- return this
- } else {
- return this._values.slice(0)
- }
- },
- _optionChangesMap: {
- backgroundColor: "MOSTLY_TOTAL",
- relativeInnerRadius: "MOSTLY_TOTAL",
- barSpacing: "MOSTLY_TOTAL",
- label: "MOSTLY_TOTAL",
- resolveLabelOverlapping: "MOSTLY_TOTAL",
- palette: "MOSTLY_TOTAL",
- paletteExtensionMode: "MOSTLY_TOTAL",
- values: "VALUES"
- },
- _change_VALUES: function() {
- this._updateValues(this.option(OPTION_VALUES))
- },
- _factory: objectUtils.clone(dxBaseGauge.prototype._factory),
- _optionChangesOrder: ["VALUES", "NODES"],
- _initialChanges: ["VALUES"],
- _change_NODES: function() {
- this._buildNodes()
- },
- _change_MOSTLY_TOTAL: function() {
- this._change(["NODES"]);
- this.callBase()
- },
- _proxyData: [],
- _getLegendData: function() {
- var that = this;
- var formatOptions = {};
- var options = that._options;
- var labelFormatOptions = (options.label || {}).format;
- var legendFormatOptions = (options.legend || {}).itemTextFormat;
- if (legendFormatOptions) {
- formatOptions.format = legendFormatOptions
- } else {
- formatOptions.format = labelFormatOptions || that._defaultFormatOptions
- }
- return (this._bars || []).map(function(b) {
- return {
- id: b.index,
- item: {
- value: b.getValue(),
- color: b.getColor(),
- index: b.index
- },
- text: _formatValue(b.getValue(), formatOptions),
- visible: true,
- states: {
- normal: {
- fill: b.getColor()
- }
- }
- }
- })
- }
- });
- var BarWrapper = function(index, context) {
- var that = this;
- that._context = context;
- that._tracker = context.renderer.arc().attr({
- "stroke-linejoin": "round"
- });
- that.index = index
- };
- _extend(BarWrapper.prototype, {
- dispose: function() {
- var that = this;
- that._background.dispose();
- that._bar.dispose();
- if (that._context.textEnabled) {
- that._line.dispose();
- that._text.dispose()
- }
- that._context.tracker.detach(that._tracker);
- that._context = that._settings = that._background = that._bar = that._line = that._text = that._tracker = null;
- return that
- },
- arrange: function(options) {
- var that = this;
- var context = that._context;
- this._visible = true;
- context.tracker.attach(that._tracker, that, {
- index: that.index
- });
- that._background = context.renderer.arc().attr({
- "stroke-linejoin": "round",
- fill: context.backgroundColor
- }).append(context.group);
- that._settings = that._settings || {
- x: context.x,
- y: context.y,
- startAngle: context.baseAngle,
- endAngle: context.baseAngle
- };
- that._bar = context.renderer.arc().attr(_extend({
- "stroke-linejoin": "round"
- }, that._settings)).append(context.group);
- if (context.textEnabled) {
- that._line = context.renderer.path([], "line").attr({
- "stroke-width": context.lineWidth
- }).append(context.group);
- that._text = context.renderer.text().css(context.fontStyles).attr(context.textOptions).append(context.group)
- }
- that._angle = isFinite(that._angle) ? that._angle : context.baseAngle;
- that._settings.outerRadius = options.radius;
- that._settings.innerRadius = options.radius - context.barSize;
- that._settings.x = context.x;
- that._settings.y = context.y;
- that._background.attr(_extend({}, that._settings, {
- startAngle: context.endAngle,
- endAngle: context.startAngle,
- fill: that._context.backgroundColor
- }));
- that._bar.attr({
- x: context.x,
- y: context.y,
- outerRadius: that._settings.outerRadius,
- innerRadius: that._settings.innerRadius,
- fill: that._color
- });
- that._tracker.attr(that._settings);
- if (context.textEnabled) {
- that._line.attr({
- points: [context.x, context.y - that._settings.innerRadius, context.x, context.y - context.textRadius - context.textIndent],
- stroke: context.lineColor || that._color
- }).sharp();
- that._text.css({
- fill: context.textColor || that._color
- })
- }
- return that
- },
- getTooltipParameters: function() {
- var that = this;
- var cosSin = _getCosAndSin((that._angle + that._context.baseAngle) / 2);
- return {
- x: _round(that._context.x + (that._settings.outerRadius + that._settings.innerRadius) / 2 * cosSin.cos),
- y: _round(that._context.y - (that._settings.outerRadius + that._settings.innerRadius) / 2 * cosSin.sin),
- offset: 0,
- color: that._color,
- value: that._value
- }
- },
- setAngle: function(angle) {
- var that = this;
- var context = that._context;
- var settings = that._settings;
- var cosSin;
- that._angle = angle;
- setAngles(settings, context.baseAngle, angle);
- that._bar.attr(settings);
- that._tracker.attr(settings);
- if (context.textEnabled) {
- cosSin = _getCosAndSin(angle);
- var indent = context.textIndent;
- var radius = context.textRadius + indent;
- var x = context.x + radius * cosSin.cos;
- var y = context.y - radius * cosSin.sin;
- var halfWidth = .5 * context.textWidth;
- var textHeight = context.textHeight;
- var textY = context.textY;
- if (_abs(x - context.x) > indent) {
- x += x < context.x ? -halfWidth : halfWidth
- }
- if (_abs(y - context.y) <= indent) {
- y -= textY + .5 * textHeight
- } else {
- y -= y < context.y ? textY + textHeight : textY
- }
- var text = _formatValue(that._value, context.formatOptions, {
- index: that.index
- });
- var visibility = "" === text ? "hidden" : null;
- that._text.attr({
- text: text,
- x: x,
- y: y,
- visibility: visibility
- });
- that._line.attr({
- visibility: visibility
- });
- that._line.rotate(_convertAngleToRendererSpace(angle), context.x, context.y)
- }
- return that
- },
- hideLabel: function() {
- this._text.attr({
- visibility: "hidden"
- });
- this._line.attr({
- visibility: "hidden"
- })
- },
- checkIntersect: function(anotherBar) {
- var coords = this.calculateLabelCoords();
- var anotherCoords = anotherBar.calculateLabelCoords();
- if (!coords || !anotherCoords) {
- return false
- }
- var width = Math.max(0, Math.min(coords.bottomRight.x, anotherCoords.bottomRight.x) - Math.max(coords.topLeft.x, anotherCoords.topLeft.x));
- var height = Math.max(0, Math.min(coords.bottomRight.y, anotherCoords.bottomRight.y) - Math.max(coords.topLeft.y, anotherCoords.topLeft.y));
- return width * height !== 0
- },
- calculateLabelCoords: function() {
- if (!this._text) {
- return
- }
- var box = this._text.getBBox();
- return {
- topLeft: {
- x: box.x,
- y: box.y
- },
- bottomRight: {
- x: box.x + box.width,
- y: box.y + box.height
- }
- }
- },
- _processValue: function(value) {
- return this._context.translator.translate(this._context.translator.adjust(value))
- },
- applyValue: function() {
- if (!this._visible) {
- return this
- }
- return this.setAngle(this._processValue(this.getValue()))
- },
- update: function(_ref) {
- var color = _ref.color,
- value = _ref.value;
- this._color = color;
- this._value = value
- },
- hide: function() {
- this._visible = false
- },
- getColor: function() {
- return this._color
- },
- getValue: function() {
- return this._value
- },
- beginAnimation: function() {
- if (!this._visible) {
- return this
- }
- var that = this;
- var angle = this._processValue(this.getValue());
- if (!compareFloats(that._angle, angle)) {
- that._start = that._angle;
- that._delta = angle - that._angle;
- that._tracker.attr({
- visibility: "hidden"
- });
- if (that._context.textEnabled) {
- that._line.attr({
- visibility: "hidden"
- });
- that._text.attr({
- visibility: "hidden"
- })
- }
- } else {
- that.animate = _noop;
- that.setAngle(that._angle)
- }
- },
- animate: function(pos) {
- if (!this._visible) {
- return this
- }
- var that = this;
- that._angle = that._start + that._delta * pos;
- setAngles(that._settings, that._context.baseAngle, that._angle);
- that._bar.attr(that._settings)
- },
- endAnimation: function() {
- var that = this;
- if (void 0 !== that._delta) {
- if (compareFloats(that._angle, that._start + that._delta)) {
- that._tracker.attr({
- visibility: null
- });
- that.setAngle(that._angle)
- }
- } else {
- delete that.animate
- }
- delete that._start;
- delete that._delta
- }
- });
- function setAngles(target, angle1, angle2) {
- target.startAngle = angle1 < angle2 ? angle1 : angle2;
- target.endAngle = angle1 < angle2 ? angle2 : angle1
- }
- function compareFloats(value1, value2) {
- return _abs(value1 - value2) < 1e-4
- }
- registerComponent("dxBarGauge", dxBarGauge);
- exports.dxBarGauge = dxBarGauge;
- dxBarGauge.addPlugin(require("../components/legend").plugin);
|