UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

647 lines (519 loc) • 21.5 kB
"use strict"; var vizUtils = require("../core/utils"), isNumeric = require("../../core/utils/type").isNumeric, extend = require("../../core/utils/extend").extend, constants = require("./axes_constants"), circularAxes, xyAxesLinear = require("./xy_axes").linear, tick = require("./tick").tick, polarAxes, _map = vizUtils.map, _math = Math, _abs = _math.abs, _round = _math.round, convertPolarToXY = vizUtils.convertPolarToXY, _extend = extend, _noop = require("../../core/utils/common").noop, HALF_PI_ANGLE = 90; function getPolarQuarter(angle) { var quarter; angle = vizUtils.normalizeAngle(angle); if (angle >= 315 && angle <= 360 || angle < 45 && angle >= 0) { quarter = 1; } else if (angle >= 45 && angle < 135) { quarter = 2; } else if (angle >= 135 && angle < 225) { quarter = 3; } else if (angle >= 225 && angle < 315) { quarter = 4; } return quarter; } polarAxes = exports; circularAxes = polarAxes.circular = { _applyMargins: function _applyMargins(range) { return range; }, _getTranslatorOptions: function _getTranslatorOptions() { return { isHorizontal: true, conversionValue: true, addSpiderCategory: this._getSpiderCategoryOption(), stick: this._getStick() }; }, getCenter: function getCenter() { return this._center; }, getRadius: function getRadius() { return this._radius; }, getAngles: function getAngles() { var options = this._options; return [options.startAngle, options.endAngle]; }, _updateRadius: function _updateRadius(canvas) { var rad = Math.min(canvas.width - canvas.left - canvas.right, canvas.height - canvas.top - canvas.bottom) / 2; this._radius = rad < 0 ? 0 : rad; }, _updateCenter: function _updateCenter(canvas) { this._center = { x: canvas.left + (canvas.width - canvas.right - canvas.left) / 2, y: canvas.top + (canvas.height - canvas.top - canvas.bottom) / 2 }; }, _processCanvas: function _processCanvas(canvas) { var options = this._options; this._updateRadius(canvas); this._updateCenter(canvas); return { left: 0, right: 0, width: _math.abs(options.endAngle - options.startAngle) }; }, _createAxisElement: function _createAxisElement() { return this._renderer.circle(); }, _updateAxisElementPosition: function _updateAxisElementPosition() { var center = this.getCenter(); this._axisElement.attr({ cx: center.x, cy: center.y, r: this.getRadius() }); }, _boundaryTicksVisibility: { min: true }, _getSpiderCategoryOption: function _getSpiderCategoryOption() { // TODO rename spider return this._options.firstPointOnStartAngle; }, _getMinMax: function _getMinMax() { var options = this._options, min = isNumeric(options.originValue) ? options.originValue : undefined, max; if (options.period > 0 && options.argumentType === constants.numeric) { min = min || 0; max = min + options.period; } return { min: min, max: max }; }, _getStick: function _getStick() { return this._options.firstPointOnStartAngle || this._options.type !== constants.discrete; }, _getTranslatedCoord: function _getTranslatedCoord(value, offset) { return this._translator.translate(value, offset) - HALF_PI_ANGLE; }, _getCanvasStartEnd: function _getCanvasStartEnd() { return { start: 0 - HALF_PI_ANGLE, end: 360 - HALF_PI_ANGLE }; }, _getStripGraphicAttributes: function _getStripGraphicAttributes(fromAngle, toAngle) { var center = this.getCenter(), angle = this.getAngles()[0], r = this.getRadius(); return { x: center.x, y: center.y, innerRadius: 0, outerRadius: r, startAngle: -toAngle - angle, endAngle: -fromAngle - angle }; }, _createStrip: function _createStrip(fromAngle, toAngle, attr) { var coords = this._getStripGraphicAttributes(fromAngle, toAngle); return this._renderer.arc(coords.x, coords.y, coords.innerRadius, coords.outerRadius, coords.startAngle, coords.endAngle).attr(attr); }, _getStripLabelCoords: function _getStripLabelCoords(from, to) { var that = this, coords = that._getStripGraphicAttributes(from, to), angle = coords.startAngle + (coords.endAngle - coords.startAngle) / 2, cosSin = vizUtils.getCosAndSin(angle), halfRad = that.getRadius() / 2, center = that.getCenter(), x = _round(center.x + halfRad * cosSin.cos), y = _round(center.y - halfRad * cosSin.sin); return { x: x, y: y, align: constants.center }; }, _getConstantLineGraphicAttributes: function _getConstantLineGraphicAttributes(value) { var center = this.getCenter(), r = this.getRadius(); return { points: [center.x, center.y, center.x + r, center.y] }; }, _createConstantLine: function _createConstantLine(value, attr) { var center = this.getCenter(); return this._createPathElement(this._getConstantLineGraphicAttributes(value).points, attr).rotate(value + this.getAngles()[0], center.x, center.y); }, _getConstantLineLabelsCoords: function _getConstantLineLabelsCoords(value) { var that = this, cosSin = vizUtils.getCosAndSin(-value - that.getAngles()[0]), halfRad = that.getRadius() / 2, center = that.getCenter(), x = _round(center.x + halfRad * cosSin.cos), y = _round(center.y - halfRad * cosSin.sin); return { x: x, y: y }; }, _checkAlignmentConstantLineLabels: _noop, _getScreenDelta: function _getScreenDelta() { var angles = this.getAngles(); return _abs(angles[0] - angles[1]) * this.getRadius() * Math.PI / 180; }, _getTickMarkPoints: function _getTickMarkPoints(tick, length) { var center = this.getCenter(), corrections = { inside: -1, center: -0.5, outside: 0 }, radiusWithTicks = this.getRadius() + length * corrections[this._options.tickOrientation || "center"]; return [center.x + radiusWithTicks, center.y, center.x + radiusWithTicks + length, center.y]; }, _getLabelAdjustedCoord: function _getLabelAdjustedCoord(tick) { var that = this, labelCoords = tick.labelCoords, labelY = labelCoords.y, labelAngle = labelCoords.angle, cosSin = vizUtils.getCosAndSin(labelAngle), cos = cosSin.cos, sin = cosSin.sin, box = tick.labelBBox, halfWidth = box.width / 2, halfHeight = box.height / 2, indentFromAxis = that._options.label.indentFromAxis || 0, x = labelCoords.x + indentFromAxis * cos, y = labelY + (labelY - box.y - halfHeight) + indentFromAxis * sin; switch (getPolarQuarter(labelAngle)) { case 1: x += halfWidth; y += halfHeight * sin; break; case 2: x += halfWidth * cos; y += halfHeight; break; case 3: x += -halfWidth; y += halfHeight * sin; break; case 4: x += halfWidth * cos; y += -halfHeight; break; } return { x: x, y: y }; }, _getGridLineDrawer: function _getGridLineDrawer() { var that = this; return function (tick, gridStyle) { var center = that.getCenter(); return that._createPathElement(that._getGridPoints().points, gridStyle).rotate(tick.coords.angle, center.x, center.y); }; }, _getGridPoints: function _getGridPoints() { var r = this.getRadius(), center = this.getCenter(); return { points: [center.x, center.y, center.x + r, center.y] }; }, _getTranslatedValue: function _getTranslatedValue(value, offset) { var startAngle = this.getAngles()[0], angle = this._translator.translate(value, -offset), coords = convertPolarToXY(this.getCenter(), startAngle, angle, this.getRadius()); return { x: coords.x, y: coords.y, angle: angle + startAngle - HALF_PI_ANGLE }; }, _getAdjustedStripLabelCoords: function _getAdjustedStripLabelCoords(strip) { var box = strip.labelBBox; return { translateY: strip.label.attr("y") - box.y - box.height / 2 }; }, coordsIn: function coordsIn(x, y) { return vizUtils.convertXYToPolar(this.getCenter(), x, y).r > this.getRadius(); }, _rotateTick: function _rotateTick(element, coords) { var center = this.getCenter(); element.rotate(coords.angle, center.x, center.y); }, _validateOverlappingMode: function _validateOverlappingMode(mode) { return constants.validateOverlappingMode(mode); }, _validateDisplayMode: function _validateDisplayMode() { return "standard"; }, _getStep: function _getStep(boxes) { var that = this, radius = that.getRadius() + (that._options.label.indentFromAxis || 0), maxLabelBox = boxes.reduce(function (prevValue, box) { var curValue = prevValue; if (prevValue.width < box.width) { curValue.width = box.width; } if (prevValue.height < box.height) { curValue.height = box.height; } return curValue; }, { width: 0, height: 0 }), angle1 = _abs(2 * _math.atan(maxLabelBox.height / (2 * radius - maxLabelBox.width)) * 180 / _math.PI), angle2 = _abs(2 * _math.atan(maxLabelBox.width / (2 * radius - maxLabelBox.height)) * 180 / _math.PI); return constants.getTicksCountInRange(that._majorTicks, "angle", _math.max(angle1, angle2)); }, _checkBoundedLabelsOverlapping: function _checkBoundedLabelsOverlapping(step, majorTicks, boxes) { var lastVisibleLabelIndex = _math.floor((boxes.length - 1) / step) * step, labelOpt = this._options.label; if (!lastVisibleLabelIndex) { return; } if (constants.areLabelsOverlap(boxes[0], boxes[lastVisibleLabelIndex], labelOpt.minSpacing, constants.center)) { labelOpt.overlappingBehavior.hideFirstOrLast === "first" ? majorTicks[0].label.remove() : majorTicks[lastVisibleLabelIndex].label.remove(); } }, shift: function shift(margins) { this._axisGroup.attr({ translateX: margins.right, translateY: margins.bottom }); } }; exports.circularSpider = _extend({}, circularAxes, { _createAxisElement: function _createAxisElement() { return this._renderer.path([], "area"); }, _updateAxisElementPosition: function _updateAxisElementPosition() { this._axisElement.attr({ points: _map(this.getSpiderTicks(), function (tick) { return { x: tick.coords.x, y: tick.coords.y }; }) }); }, _getStick: function _getStick() { return true; }, _getSpiderCategoryOption: function _getSpiderCategoryOption() { return true; }, getSpiderTicks: function getSpiderTicks() { var that = this, ticks = that.getFullTicks(); that._spiderTicks = ticks.map(tick(that, that.renderer, {}, {}, that._getSkippedCategory(ticks), true)); that._spiderTicks.forEach(function (tick) { tick.initCoords(); }); return that._spiderTicks; }, _getStripGraphicAttributes: function _getStripGraphicAttributes(fromAngle, toAngle) { var center = this.getCenter(), spiderTicks = this.getSpiderTicks(), firstTick, lastTick, nextTick, tick, points = [], i = 0, len = spiderTicks.length; while (i < len) { tick = spiderTicks[i].coords; if (tick.angle >= fromAngle && tick.angle <= toAngle) { if (!firstTick) { firstTick = (spiderTicks[i - 1] || spiderTicks[spiderTicks.length - 1]).coords; points.push((tick.x + firstTick.x) / 2, (tick.y + firstTick.y) / 2); } points.push(tick.x, tick.y); nextTick = (spiderTicks[i + 1] || spiderTicks[0]).coords; lastTick = { x: (tick.x + nextTick.x) / 2, y: (tick.y + nextTick.y) / 2 }; } i++; } points.push(lastTick.x, lastTick.y); points.push(center.x, center.y); return { points: points }; }, _createStrip: function _createStrip(fromAngle, toAngle, attr) { var points = this._getStripGraphicAttributes(fromAngle, toAngle).points; return this._renderer.path(points, "area").attr(attr); }, _getTranslatedCoord: function _getTranslatedCoord(value, offset) { return this._translator.translate(value, offset) - HALF_PI_ANGLE; }, _setTickOffset: function _setTickOffset() { this._tickOffset = false; } }); polarAxes.linear = { _getMinMax: circularAxes._getMinMax, _getStick: xyAxesLinear._getStick, _getSpiderCategoryOption: _noop, _getTranslatorOptions: function _getTranslatorOptions() { return { isHorizontal: true, stick: this._getStick() }; }, _updateRadius: circularAxes._updateRadius, getRadius: circularAxes.getRadius, getCenter: circularAxes.getCenter, getAngles: circularAxes.getAngles, _updateCenter: circularAxes._updateCenter, _processCanvas: function _processCanvas(canvas) { this._updateRadius(canvas); this._updateCenter(canvas); return { left: 0, right: 0, width: this.getRadius() }; }, _createAxisElement: xyAxesLinear._createAxisElement, _updateAxisElementPosition: function _updateAxisElementPosition() { var centerCoord = this.getCenter(); this._axisElement.attr({ points: [centerCoord.x, centerCoord.y, centerCoord.x + this.getRadius(), centerCoord.y] }).rotate(this.getAngles()[0] - HALF_PI_ANGLE, centerCoord.x, centerCoord.y); }, _getScreenDelta: function _getScreenDelta() { return this.getRadius(); }, _getTickMarkPoints: function _getTickMarkPoints(tick, length) { var coords = tick.coords; return [coords.x - length / 2, coords.y, coords.x + length / 2, coords.y]; }, _getLabelAdjustedCoord: function _getLabelAdjustedCoord(tick) { var that = this, labelCoords = tick.labelCoords, labelY = labelCoords.y, cosSin = vizUtils.getCosAndSin(labelCoords.angle), indentFromAxis = that._options.label.indentFromAxis || 0, box = tick.labelBBox, x, y; x = labelCoords.x - _abs(indentFromAxis * cosSin.sin) + _abs(box.width / 2 * cosSin.cos) - box.width / 2; y = labelY + (labelY - box.y) - _abs(box.height / 2 * cosSin.sin) + _abs(indentFromAxis * cosSin.cos); return { x: x, y: y }; }, _getGridLineDrawer: function _getGridLineDrawer() { var that = this; return function (tick, gridStyle) { var grid = that._getGridPoints(tick.coords); return that._renderer.circle(grid.x, grid.y, grid.r).attr(gridStyle).sharp(); }; }, _getGridPoints: function _getGridPoints(coords) { var pos = this.getCenter(); return { x: pos.x, y: pos.y, r: vizUtils.getDistance(pos.x, pos.y, coords.x, coords.y) }; }, _getTranslatedValue: function _getTranslatedValue(value, offset) { var startAngle = this.getAngles()[0], xy = convertPolarToXY(this.getCenter(), startAngle, 0, this._translator.translate(value, offset)); return { x: xy.x, y: xy.y, angle: startAngle - HALF_PI_ANGLE }; }, _getTranslatedCoord: function _getTranslatedCoord(value, offset) { return this._translator.translate(value, offset); }, _getCanvasStartEnd: function _getCanvasStartEnd() { return { start: 0, end: this.getRadius() }; }, _getStripGraphicAttributes: function _getStripGraphicAttributes(fromPoint, toPoint) { var center = this.getCenter(); return { x: center.x, y: center.y, innerRadius: fromPoint, outerRadius: toPoint }; }, _createStrip: function _createStrip(fromPoint, toPoint, attr) { var attrs = this._getStripGraphicAttributes(fromPoint, toPoint); return this._renderer.arc(attrs.x, attrs.y, attrs.innerRadius, attrs.outerRadius, 0, 360).attr(attr); }, _getAdjustedStripLabelCoords: circularAxes._getAdjustedStripLabelCoords, _getStripLabelCoords: function _getStripLabelCoords(from, to) { var that = this, labelPos = from + (to - from) / 2, center = that.getCenter(), y = _round(center.y - labelPos); return { x: center.x, y: y, align: constants.center }; }, _getConstantLineGraphicAttributes: function _getConstantLineGraphicAttributes(value) { var center = this.getCenter(); return { cx: center.x, cy: center.y, r: value }; }, _createConstantLine: function _createConstantLine(value, attr) { var attrs = this._getConstantLineGraphicAttributes(value); return this._renderer.circle(attrs.cx, attrs.cy, attrs.r).attr(attr).sharp(); }, _getConstantLineLabelsCoords: function _getConstantLineLabelsCoords(value) { var that = this, center = that.getCenter(), y = _round(center.y - value); return { x: center.x, y: y }; }, _checkAlignmentConstantLineLabels: _noop, _rotateTick: function _rotateTick(element, coords) { element.rotate(coords.angle + HALF_PI_ANGLE, coords.x, coords.y); }, _validateOverlappingMode: circularAxes._validateOverlappingMode, _validateDisplayMode: circularAxes._validateDisplayMode, _getStep: function _getStep(boxes) { var quarter = getPolarQuarter(this.getAngles()[0]), spacing = this._options.label.minSpacing, func = quarter === 2 || quarter === 4 ? function (box) { return box.width + spacing; } : function (box) { return box.height; }, maxLabelLength = boxes.reduce(function (prevValue, box) { return _math.max(prevValue, func(box)); }, 0); return constants.getTicksCountInRange(this._majorTicks, quarter === 2 || quarter === 4 ? "x" : "y", maxLabelLength); } }; polarAxes.linearSpider = _extend({}, polarAxes.linear, { _createPathElement: function _createPathElement(points, attr) { return this._renderer.path(points, "area").attr(attr).sharp(); }, setSpiderTicks: function setSpiderTicks(ticks) { this._spiderTicks = ticks; }, _getGridLineDrawer: function _getGridLineDrawer() { var that = this; return function (tick, gridStyle, element) { return that._createPathElement(that._getGridPoints(tick.coords).points, gridStyle); }; }, _getGridPoints: function _getGridPoints(coords) { var pos = this.getCenter(), radius = vizUtils.getDistance(pos.x, pos.y, coords.x, coords.y); return this._getGridPointsByRadius(radius); }, _getGridPointsByRadius: function _getGridPointsByRadius(radius) { var pos = this.getCenter(); return { points: _map(this._spiderTicks, function (tick) { var cosSin = vizUtils.getCosAndSin(tick.coords.angle); return { x: _round(pos.x + radius * cosSin.cos), y: _round(pos.y + radius * cosSin.sin) }; }) }; }, _getStripGraphicAttributes: function _getStripGraphicAttributes(fromPoint, toPoint) { var innerPoints = this._getGridPointsByRadius(toPoint).points, outerPoints = this._getGridPointsByRadius(fromPoint).points; return { points: [outerPoints, innerPoints.reverse()] }; }, _createStrip: function _createStrip(fromPoint, toPoint, attr) { var points = this._getStripGraphicAttributes(fromPoint, toPoint).points; return this._renderer.path(points, "area").attr(attr); }, _getConstantLineGraphicAttributes: function _getConstantLineGraphicAttributes(value) { return this._getGridPointsByRadius(value); }, _createConstantLine: function _createConstantLine(value, attr) { return this._createPathElement(this._getConstantLineGraphicAttributes(value).points, attr); } });