| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490 |
- /**
- * DevExtreme (viz/core/utils.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 noop = require("../../core/utils/common").noop;
- var typeUtils = require("../../core/utils/type");
- var extend = require("../../core/utils/extend").extend;
- var each = require("../../core/utils/iterator").each;
- var adjust = require("../../core/utils/math").adjust;
- var dateToMilliseconds = require("../../core/utils/date").dateToMilliseconds;
- var isDefined = typeUtils.isDefined;
- var isNumber = typeUtils.isNumeric;
- var isExponential = typeUtils.isExponential;
- var _math = Math;
- var _round = _math.round;
- var _sqrt = Math.sqrt;
- var PI = Math.PI;
- var MAX_PIXEL_COUNT = 1e10;
- var PI_DIV_180 = PI / 180;
- var LN10 = Math.LN10;
- var cosFunc = Math.cos;
- var sinFunc = Math.sin;
- var abs = Math.abs;
- var log = Math.log;
- var floor = Math.floor;
- var ceil = Math.ceil;
- var max = Math.max;
- var _isNaN = isNaN;
- var _Number = Number;
- var _NaN = NaN;
- var getLog = function(value, base) {
- if (!value) {
- return _NaN
- }
- return Math.log(value) / Math.log(base)
- };
- var getAdjustedLog10 = function(value) {
- return adjust(getLog(value, 10))
- };
- var raiseTo = function(power, base) {
- return Math.pow(base, power)
- };
- var normalizeAngle = function(angle) {
- return (angle % 360 + 360) % 360
- };
- var convertAngleToRendererSpace = function(angle) {
- return 90 - angle
- };
- var degreesToRadians = function(value) {
- return PI * value / 180
- };
- var getCosAndSin = function(angle) {
- var angleInRadians = degreesToRadians(angle);
- return {
- cos: cosFunc(angleInRadians),
- sin: sinFunc(angleInRadians)
- }
- };
- var DECIMAL_ORDER_THRESHOLD = 1e-14;
- var getDistance = function(x1, y1, x2, y2) {
- var diffX = x2 - x1;
- var diffY = y2 - y1;
- return Math.sqrt(diffY * diffY + diffX * diffX)
- };
- var getDecimalOrder = function(number) {
- var n = abs(number);
- var cn;
- if (!_isNaN(n)) {
- if (n > 0) {
- n = log(n) / LN10;
- cn = ceil(n);
- return cn - n < DECIMAL_ORDER_THRESHOLD ? cn : floor(n)
- }
- return 0
- }
- return _NaN
- };
- var getAppropriateFormat = function(start, end, count) {
- var order = max(getDecimalOrder(start), getDecimalOrder(end));
- var precision = -getDecimalOrder(abs(end - start) / count);
- var format;
- if (!_isNaN(order) && !_isNaN(precision)) {
- if (abs(order) <= 4) {
- format = "fixedPoint";
- precision < 0 && (precision = 0);
- precision > 4 && (precision = 4)
- } else {
- format = "exponential";
- precision += order - 1;
- precision > 3 && (precision = 3)
- }
- return {
- type: format,
- precision: precision
- }
- }
- return null
- };
- var roundValue = function(value, precision) {
- if (precision > 20) {
- precision = 20
- }
- if (isNumber(value)) {
- if (isExponential(value)) {
- return _Number(value.toExponential(precision))
- } else {
- return _Number(value.toFixed(precision))
- }
- }
- };
- var getPower = function(value) {
- return value.toExponential().split("e")[1]
- };
- function map(array, callback) {
- var i = 0;
- var len = array.length;
- var result = [];
- while (i < len) {
- var value = callback(array[i], i);
- if (null !== value) {
- result.push(value)
- }
- i++
- }
- return result
- }
- function selectByKeys(object, keys) {
- return map(keys, function(key) {
- return object[key] ? object[key] : null
- })
- }
- function decreaseFields(object, keys, eachDecrease, decrease) {
- var dec = decrease;
- each(keys, function(_, key) {
- if (object[key]) {
- object[key] -= eachDecrease;
- dec -= eachDecrease
- }
- });
- return dec
- }
- function normalizeEnum(value) {
- return String(value).toLowerCase()
- }
- function setCanvasValues(canvas) {
- if (canvas) {
- canvas.originalTop = canvas.top;
- canvas.originalBottom = canvas.bottom;
- canvas.originalLeft = canvas.left;
- canvas.originalRight = canvas.right
- }
- return canvas
- }
- function normalizeBBoxField(value) {
- return -MAX_PIXEL_COUNT < value && value < +MAX_PIXEL_COUNT ? value : 0
- }
- function normalizeBBox(bBox) {
- var xl = normalizeBBoxField(floor(bBox.x));
- var yt = normalizeBBoxField(floor(bBox.y));
- var xr = normalizeBBoxField(ceil(bBox.width + bBox.x));
- var yb = normalizeBBoxField(ceil(bBox.height + bBox.y));
- var result = {
- x: xl,
- y: yt,
- width: xr - xl,
- height: yb - yt
- };
- result.isEmpty = !result.x && !result.y && !result.width && !result.height;
- return result
- }
- function rotateBBox(bBox, center, angle) {
- var cos = _Number(cosFunc(angle * PI_DIV_180).toFixed(3));
- var sin = _Number(sinFunc(angle * PI_DIV_180).toFixed(3));
- var w2 = bBox.width / 2;
- var h2 = bBox.height / 2;
- var centerX = bBox.x + w2;
- var centerY = bBox.y + h2;
- var w2_ = abs(w2 * cos) + abs(h2 * sin);
- var h2_ = abs(w2 * sin) + abs(h2 * cos);
- var centerX_ = center[0] + (centerX - center[0]) * cos + (centerY - center[1]) * sin;
- var centerY_ = center[1] - (centerX - center[0]) * sin + (centerY - center[1]) * cos;
- return normalizeBBox({
- x: centerX_ - w2_,
- y: centerY_ - h2_,
- width: 2 * w2_,
- height: 2 * h2_
- })
- }
- extend(exports, {
- decreaseGaps: function(object, keys, decrease) {
- var arrayGaps;
- do {
- arrayGaps = selectByKeys(object, keys);
- arrayGaps.push(_math.ceil(decrease / arrayGaps.length));
- decrease = decreaseFields(object, keys, _math.min.apply(null, arrayGaps), decrease)
- } while (decrease > 0 && arrayGaps.length > 1);
- return decrease
- },
- normalizeEnum: normalizeEnum,
- parseScalar: function(value, defaultValue) {
- return void 0 !== value ? value : defaultValue
- },
- enumParser: function(values) {
- var stored = {};
- var i;
- var ii;
- for (i = 0, ii = values.length; i < ii; ++i) {
- stored[normalizeEnum(values[i])] = 1
- }
- return function(value, defaultValue) {
- var _value = normalizeEnum(value);
- return stored[_value] ? _value : defaultValue
- }
- },
- patchFontOptions: function(options) {
- var fontOptions = {};
- each(options || {}, function(key, value) {
- if (/^(cursor|opacity)$/i.test(key)) {} else {
- if ("color" === key) {
- key = "fill"
- } else {
- key = "font-" + key
- }
- }
- fontOptions[key] = value
- });
- return fontOptions
- },
- convertPolarToXY: function(centerCoords, startAngle, angle, radius) {
- var shiftAngle = 90;
- angle = isDefined(angle) ? angle + startAngle - shiftAngle : 0;
- var cosSin = getCosAndSin(angle);
- return {
- x: _round(centerCoords.x + radius * cosSin.cos),
- y: _round(centerCoords.y + radius * cosSin.sin)
- }
- },
- convertXYToPolar: function(centerCoords, x, y) {
- var radius = getDistance(centerCoords.x, centerCoords.y, x, y);
- var angle = _math.atan2(y - centerCoords.y, x - centerCoords.x);
- return {
- phi: _round(normalizeAngle(180 * angle / _math.PI)),
- r: _round(radius)
- }
- },
- processSeriesTemplate: function(seriesTemplate, items) {
- var customizeSeries = typeUtils.isFunction(seriesTemplate.customizeSeries) ? seriesTemplate.customizeSeries : noop;
- var nameField = seriesTemplate.nameField;
- var generatedSeries = {};
- var seriesOrder = [];
- var series;
- var i = 0;
- items = items || [];
- for (var length = items.length; i < length; i++) {
- var data = items[i];
- if (nameField in data) {
- series = generatedSeries[data[nameField]];
- if (!series) {
- series = generatedSeries[data[nameField]] = {
- name: data[nameField],
- nameFieldValue: data[nameField]
- };
- seriesOrder.push(series.name)
- }
- }
- }
- return map(seriesOrder, function(orderedName) {
- var group = generatedSeries[orderedName];
- return extend(group, customizeSeries.call(null, group.name))
- })
- },
- getCategoriesInfo: function(categories, startValue, endValue) {
- if (0 === categories.length) {
- return {
- categories: []
- }
- }
- startValue = isDefined(startValue) ? startValue : categories[0];
- endValue = isDefined(endValue) ? endValue : categories[categories.length - 1];
- var categoriesValue = map(categories, function(category) {
- return isDefined(category) ? category.valueOf() : null
- });
- var indexStartValue = categoriesValue.indexOf(startValue.valueOf());
- var indexEndValue = categoriesValue.indexOf(endValue.valueOf());
- var inverted = false;
- indexStartValue < 0 && (indexStartValue = 0);
- indexEndValue < 0 && (indexEndValue = categories.length - 1);
- if (indexEndValue < indexStartValue) {
- var swapBuf = indexEndValue;
- indexEndValue = indexStartValue;
- indexStartValue = swapBuf;
- inverted = true
- }
- var visibleCategories = categories.slice(indexStartValue, indexEndValue + 1);
- var lastIdx = visibleCategories.length - 1;
- return {
- categories: visibleCategories,
- start: visibleCategories[inverted ? lastIdx : 0],
- end: visibleCategories[inverted ? 0 : lastIdx],
- inverted: inverted
- }
- },
- setCanvasValues: setCanvasValues,
- updatePanesCanvases: function(panes, canvas, rotated) {
- var weightSum = 0;
- each(panes, function(_, pane) {
- pane.weight = pane.weight || 1;
- weightSum += pane.weight
- });
- var distributedSpace = 0;
- var padding = panes.padding || 10;
- var paneSpace = rotated ? canvas.width - canvas.left - canvas.right : canvas.height - canvas.top - canvas.bottom;
- var oneWeight = (paneSpace - padding * (panes.length - 1)) / weightSum;
- var startName = rotated ? "left" : "top";
- var endName = rotated ? "right" : "bottom";
- each(panes, function(_, pane) {
- var calcLength = _round(pane.weight * oneWeight);
- pane.canvas = pane.canvas || {};
- extend(pane.canvas, canvas);
- pane.canvas[startName] = canvas[startName] + distributedSpace;
- pane.canvas[endName] = canvas[endName] + (paneSpace - calcLength - distributedSpace);
- distributedSpace = distributedSpace + calcLength + padding;
- setCanvasValues(pane.canvas)
- })
- },
- unique: function(array) {
- var values = {};
- return map(array, function(item) {
- var result = !values[item] ? item : null;
- values[item] = true;
- return result
- })
- },
- map: map,
- getVerticallyShiftedAngularCoords: function(bBox, dy, center) {
- var isPositive = bBox.x + bBox.width / 2 >= center.x;
- var horizontalOffset1 = (isPositive ? bBox.x : bBox.x + bBox.width) - center.x;
- var verticalOffset1 = bBox.y - center.y;
- var verticalOffset2 = verticalOffset1 + dy;
- var horizontalOffset2 = _round(_sqrt(horizontalOffset1 * horizontalOffset1 + verticalOffset1 * verticalOffset1 - verticalOffset2 * verticalOffset2));
- var dx = (isPositive ? +horizontalOffset2 : -horizontalOffset2) || horizontalOffset1;
- return {
- x: center.x + (isPositive ? dx : dx - bBox.width),
- y: bBox.y + dy
- }
- },
- mergeMarginOptions: function(opt1, opt2) {
- return {
- checkInterval: opt1.checkInterval || opt2.checkInterval,
- size: Math.max(opt1.size || 0, opt2.size || 0),
- percentStick: opt1.percentStick || opt2.percentStick,
- sizePointNormalState: Math.max(opt1.sizePointNormalState || 0, opt2.sizePointNormalState || 0)
- }
- }
- });
- function getVizRangeObject(value) {
- if (Array.isArray(value)) {
- return {
- startValue: value[0],
- endValue: value[1]
- }
- } else {
- return value || {}
- }
- }
- function convertVisualRangeObject(visualRange, convertToVisualRange) {
- if (convertToVisualRange) {
- return visualRange
- }
- return [visualRange.startValue, visualRange.endValue]
- }
- function getAddFunction(range, correctZeroLevel) {
- if ("datetime" === range.dataType) {
- return function(rangeValue, marginValue) {
- var sign = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : 1;
- return new Date(rangeValue.getTime() + sign * marginValue)
- }
- }
- if ("logarithmic" === range.axisType) {
- return function(rangeValue, marginValue) {
- var sign = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : 1;
- var log = getLog(rangeValue, range.base) + sign * marginValue;
- return raiseTo(log, range.base)
- }
- }
- return function(rangeValue, marginValue) {
- var sign = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : 1;
- var newValue = rangeValue + sign * marginValue;
- return correctZeroLevel && newValue * rangeValue <= 0 ? 0 : newValue
- }
- }
- function adjustVisualRange(options, visualRange, wholeRange, dataRange) {
- var minDefined = typeUtils.isDefined(visualRange.startValue);
- var maxDefined = typeUtils.isDefined(visualRange.endValue);
- var nonDiscrete = "discrete" !== options.axisType;
- dataRange = dataRange || wholeRange;
- var add = getAddFunction(options, false);
- var min = minDefined ? visualRange.startValue : dataRange.min;
- var max = maxDefined ? visualRange.endValue : dataRange.max;
- var rangeLength = visualRange.length;
- var categories = dataRange.categories;
- if (nonDiscrete && !typeUtils.isDefined(min) && !typeUtils.isDefined(max)) {
- return {
- startValue: min,
- endValue: max
- }
- }
- if (isDefined(rangeLength)) {
- if (nonDiscrete) {
- if ("datetime" === options.dataType && !isNumber(rangeLength)) {
- rangeLength = dateToMilliseconds(rangeLength)
- }
- if (maxDefined && !minDefined || !maxDefined && !minDefined) {
- isDefined(wholeRange.max) && (max = max > wholeRange.max ? wholeRange.max : max);
- min = add(max, rangeLength, -1)
- } else {
- if (minDefined && !maxDefined) {
- isDefined(wholeRange.min) && (min = min < wholeRange.min ? wholeRange.min : min);
- max = add(min, rangeLength)
- }
- }
- } else {
- rangeLength = parseInt(rangeLength);
- if (!isNaN(rangeLength) && isFinite(rangeLength)) {
- rangeLength--;
- if (!maxDefined && !minDefined) {
- max = categories[categories.length - 1];
- min = categories[categories.length - 1 - rangeLength]
- } else {
- if (minDefined && !maxDefined) {
- var categoriesInfo = exports.getCategoriesInfo(categories, min, void 0);
- max = categoriesInfo.categories[rangeLength]
- } else {
- if (!minDefined && maxDefined) {
- var _categoriesInfo = exports.getCategoriesInfo(categories, void 0, max);
- min = _categoriesInfo.categories[_categoriesInfo.categories.length - 1 - rangeLength]
- }
- }
- }
- }
- }
- }
- if (nonDiscrete) {
- if (isDefined(wholeRange.max) && max > wholeRange.max) {
- max = wholeRange.max
- }
- if (isDefined(wholeRange.min) && min < wholeRange.min) {
- min = wholeRange.min
- }
- }
- return {
- startValue: min,
- endValue: max
- }
- }
- exports.getVizRangeObject = getVizRangeObject;
- exports.convertVisualRangeObject = convertVisualRangeObject;
- exports.adjustVisualRange = adjustVisualRange;
- exports.getAddFunction = getAddFunction;
- exports.getLog = getLog;
- exports.getAdjustedLog10 = getAdjustedLog10;
- exports.raiseTo = raiseTo;
- exports.normalizeAngle = normalizeAngle;
- exports.convertAngleToRendererSpace = convertAngleToRendererSpace;
- exports.degreesToRadians = degreesToRadians;
- exports.getCosAndSin = getCosAndSin;
- exports.getDecimalOrder = getDecimalOrder;
- exports.getAppropriateFormat = getAppropriateFormat;
- exports.getDistance = getDistance;
- exports.roundValue = roundValue;
- exports.getPower = getPower;
- exports.rotateBBox = rotateBBox;
- exports.normalizeBBox = normalizeBBox;
|