UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

1,112 lines (1,090 loc) • 44.9 kB
/** * DevExtreme (viz/chart.js) * Version: 18.1.3 * Build date: Tue May 15 2018 * * Copyright (c) 2012 - 2018 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, _extend = require("../core/utils/extend").extend, inArray = require("../core/utils/array").inArray, each = require("../core/utils/iterator").each, registerComponent = require("../core/component_registrator"), vizUtils = require("./core/utils"), mathUtils = require("../core/utils/math"), overlapping = require("./chart_components/base_chart").overlapping, LayoutManagerModule = require("./chart_components/layout_manager"), multiAxesSynchronizer = require("./chart_components/multi_axes_synchronizer"), AdvancedChart = require("./chart_components/advanced_chart").AdvancedChart, scrollBarModule = require("./chart_components/scroll_bar"), crosshairModule = require("./chart_components/crosshair"), rangeModule = require("./translators/range"), DEFAULT_PANE_NAME = "default", DEFAULT_PANES = [{ name: DEFAULT_PANE_NAME, border: {} }], _map = vizUtils.map, _each = each, _isArray = Array.isArray, _isDefined = require("../core/utils/type").isDefined; function getFirstAxisNameForPane(axes, paneName, defaultPane) { var result; for (var i = 0; i < axes.length; i++) { if (axes[i].pane === paneName || void 0 === axes[i].pane && paneName === defaultPane) { result = axes[i].name; break } } if (!result) { result = axes[0].name } return result } function changeVisibilityAxisGrids(axis, gridVisibility, minorGridVisibility) { var gridOpt = axis.getOptions().grid, minorGridOpt = axis.getOptions().minorGrid; gridOpt.visible = gridVisibility; minorGridOpt && (minorGridOpt.visible = minorGridVisibility) } function hideGridsOnNonFirstValueAxisForPane(axesForPane) { var axisShown = false, hiddenStubAxis = [], minorGridVisibility = axesForPane.some(function(axis) { var minorGridOptions = axis.getOptions().minorGrid; return minorGridOptions && minorGridOptions.visible }), gridVisibility = axesForPane.some(function(axis) { var gridOptions = axis.getOptions().grid; return gridOptions && gridOptions.visible }); if (axesForPane.length > 1) { axesForPane.forEach(function(axis) { var gridOpt = axis.getOptions().grid; if (axisShown) { changeVisibilityAxisGrids(axis, false, false) } else { if (gridOpt && gridOpt.visible) { if (!axis.getTranslator().getBusinessRange().stubData) { axisShown = true; changeVisibilityAxisGrids(axis, gridVisibility, minorGridVisibility) } else { changeVisibilityAxisGrids(axis, false, false); hiddenStubAxis.push(axis) } } } }); !axisShown && hiddenStubAxis.length && changeVisibilityAxisGrids(hiddenStubAxis[0], gridVisibility, minorGridVisibility) } } function findAxisOptions(valueAxes, valueAxesOptions, axisName) { var result, axInd; for (axInd = 0; axInd < valueAxesOptions.length; axInd++) { if (valueAxesOptions[axInd].name === axisName) { result = valueAxesOptions[axInd]; result.priority = axInd; break } } if (!result) { for (axInd = 0; axInd < valueAxes.length; axInd++) { if (valueAxes[axInd].name === axisName) { result = valueAxes[axInd].getOptions(); result.priority = valueAxes[axInd].priority; break } } } return result } function findAxis(paneName, axisName, axes) { var axis, i; for (i = 0; i < axes.length; i++) { axis = axes[i]; if (axis.name === axisName && axis.pane === paneName) { return axis } } if (paneName) { return findAxis(void 0, axisName, axes) } } function applyClipSettings(clipRects, settings) { _each(clipRects || [], function(_, c) { c && c.attr(settings) }) } function compareAxes(a, b) { return a.priority - b.priority } function doesPaneExist(panes, paneName) { var found = false; _each(panes, function(_, pane) { if (pane.name === paneName) { found = true; return false } }); return found } var prepareSegmentRectPoints = function(left, top, width, height, borderOptions) { var maxSW = ~~((width < height ? width : height) / 2), sw = borderOptions.width || 0, newSW = sw < maxSW ? sw : maxSW; left += newSW / 2; top += newSW / 2; width -= newSW; height -= newSW; var segmentSequence, right = left + width, bottom = top + height, points = [], segments = [], visiblyOpt = 0, prevSegmentVisibility = 0; var allSegment = { top: [ [left, top], [right, top] ], right: [ [right, top], [right, bottom] ], bottom: [ [right, bottom], [left, bottom] ], left: [ [left, bottom], [left, top] ] }; _each(allSegment, function(seg) { var visibility = !!borderOptions[seg]; visiblyOpt = 2 * visiblyOpt + ~~visibility }); switch (visiblyOpt) { case 13: case 9: segmentSequence = ["left", "top", "right", "bottom"]; break; case 11: segmentSequence = ["bottom", "left", "top", "right"]; break; default: segmentSequence = ["top", "right", "bottom", "left"] } _each(segmentSequence, function(_, seg) { var segmentVisibility = !!borderOptions[seg]; if (!prevSegmentVisibility && segments.length) { points.push(segments); segments = [] } if (segmentVisibility) { _each(allSegment[seg].slice(prevSegmentVisibility), function(_, segment) { segments = segments.concat(segment) }) } prevSegmentVisibility = ~~segmentVisibility }); segments.length && points.push(segments); 1 === points.length && (points = points[0]); return { points: points, pathType: 15 === visiblyOpt ? "area" : "line" } }; function accumulate(field, src1, src2, auxSpacing) { var val1 = src1[field] || 0, val2 = src2[field] || 0; return val1 + val2 + (val1 && val2 ? auxSpacing : 0) } function pickMax(field, src1, src2) { return pickMaxValue(src1[field], src2[field]) } function pickMaxValue(val1, val2) { return Math.max(val1 || 0, val2 || 0) } function getAxisMargins(axis) { return axis.getMargins() } function getHorizontalAxesMargins(axes, getMarginsFunc) { return axes.reduce(function(margins, axis) { var axisMargins = getMarginsFunc(axis), paneMargins = margins.panes[axis.pane] = margins.panes[axis.pane] || {}, spacing = axis.getMultipleAxesSpacing(); paneMargins.top = accumulate("top", paneMargins, axisMargins, spacing); paneMargins.bottom = accumulate("bottom", paneMargins, axisMargins, spacing); paneMargins.left = pickMax("left", paneMargins, axisMargins); paneMargins.right = pickMax("right", paneMargins, axisMargins); margins.top = pickMax("top", paneMargins, margins); margins.bottom = pickMax("bottom", paneMargins, margins); margins.left = pickMax("left", paneMargins, margins); margins.right = pickMax("right", paneMargins, margins); return margins }, { panes: {} }) } function getVerticalAxesMargins(axes) { return axes.reduce(function(margins, axis) { var axisMargins = axis.getMargins(), paneMargins = margins.panes[axis.pane] = margins.panes[axis.pane] || {}, spacing = axis.getMultipleAxesSpacing(); paneMargins.top = pickMax("top", paneMargins, axisMargins); paneMargins.bottom = pickMax("bottom", paneMargins, axisMargins); paneMargins.left = accumulate("left", paneMargins, axisMargins, spacing); paneMargins.right = accumulate("right", paneMargins, axisMargins, spacing); margins.top = pickMax("top", paneMargins, margins); margins.bottom = pickMax("bottom", paneMargins, margins); margins.left = pickMax("left", paneMargins, margins); margins.right = pickMax("right", paneMargins, margins); return margins }, { panes: {} }) } function performActionOnAxes(axes, action, actionArgument1, actionArgument2) { axes.forEach(function(axis) { axis[action](actionArgument1 && actionArgument1[axis.pane], actionArgument2 && actionArgument2[axis.pane]) }) } function shrinkCanvases(isRotated, canvases, verticalMargins, horizontalMargins) { function getMargin(side, margins, pane) { var m = (isRotated ? ["left", "right"] : ["top", "bottom"]).indexOf(side) === -1 ? margins : margins.panes[pane] || {}; return m[side] } function getMaxMargin(side, margins1, margins2, pane) { return pickMaxValue(getMargin(side, margins1, pane), getMargin(side, margins2, pane)) } for (var pane in canvases) { canvases[pane].top = canvases[pane].originalTop + getMaxMargin("top", verticalMargins, horizontalMargins, pane); canvases[pane].bottom = canvases[pane].originalBottom + getMaxMargin("bottom", verticalMargins, horizontalMargins, pane); canvases[pane].left = canvases[pane].originalLeft + getMaxMargin("left", verticalMargins, horizontalMargins, pane); canvases[pane].right = canvases[pane].originalRight + getMaxMargin("right", verticalMargins, horizontalMargins, pane) } return canvases } function drawAxesWithTicks(axes, condition, canvases, panesBorderOptions) { if (condition) { performActionOnAxes(axes, "createTicks", canvases); multiAxesSynchronizer.synchronize(axes) } performActionOnAxes(axes, "draw", !condition && canvases, panesBorderOptions) } function shiftAxis(side1, side2) { var shifts = {}; return function(axis) { var shift = shifts[axis.pane] = shifts[axis.pane] || { top: 0, left: 0, bottom: 0, right: 0 }, spacing = axis.getMultipleAxesSpacing(), margins = axis.getMargins(); axis.shift(shift); shift[side1] = accumulate(side1, shift, margins, spacing); shift[side2] = accumulate(side2, shift, margins, spacing) } } function getCommonSize(side, margins) { var pane, paneMargins, size = 0; for (pane in margins.panes) { paneMargins = margins.panes[pane]; size += "height" === side ? paneMargins.top + paneMargins.bottom : paneMargins.left + paneMargins.right } return size } function checkUsedSpace(sizeShortage, side, axes, getMarginFunc) { var size = 0; if (sizeShortage[side] > 0) { size = getCommonSize(side, getMarginFunc(axes, getAxisMargins)); performActionOnAxes(axes, "hideTitle"); sizeShortage[side] -= size - getCommonSize(side, getMarginFunc(axes, getAxisMargins)) } if (sizeShortage[side] > 0) { performActionOnAxes(axes, "hideOuterElements") } } var dxChart = AdvancedChart.inherit({ _chartType: "chart", _setDeprecatedOptions: function() { this.callBase.apply(this, arguments); _extend(this._deprecatedOptions, { "argumentAxis.label.overlappingBehavior.rotationAngle": { since: "17.1", message: "Use the 'argumentAxis.label.rotationAngle' option instead" }, "argumentAxis.label.overlappingBehavior.staggeringSpacing": { since: "17.1", message: "Use the 'argumentAxis.label.staggeringSpacing' option instead" }, "argumentAxis.label.overlappingBehavior.mode": { since: "17.1", message: "Use the 'overlappingBehavior' option directly" }, "valueAxis.label.overlappingBehavior.rotationAngle": { since: "17.1", message: "Use the 'valueAxis.label.rotationAngle' option instead" }, "valueAxis.label.overlappingBehavior.staggeringSpacing": { since: "17.1", message: "Use the 'valueAxis.label.staggeringSpacing' option instead" }, "valueAxis.label.overlappingBehavior.mode": { since: "17.1", message: "Use the 'overlappingBehavior' option directly" }, "commonAxisSettings.label.overlappingBehavior.rotationAngle": { since: "17.1", message: "Use the 'commonAxisSettings.label.rotationAngle' option instead" }, "commonAxisSettings.label.overlappingBehavior.staggeringSpacing": { since: "17.1", message: "Use the 'commonAxisSettings.label.staggeringSpacing' option instead" }, "commonAxisSettings.label.overlappingBehavior.mode": { since: "17.1", message: "Use the 'overlappingBehavior' option directly" }, useAggregation: { since: "18.1", message: "Use the 'commonSeriesSettings.aggregation.enabled' or 'series.aggregation.enabled' option instead" } }) }, _initCore: function() { this.paneAxis = {}; this._panesClipRects = {}; this.callBase() }, _disposeCore: function() { var that = this, disposeObjectsInArray = this._disposeObjectsInArray, panesClipRects = that._panesClipRects; that.callBase(); disposeObjectsInArray.call(panesClipRects, "fixed"); disposeObjectsInArray.call(panesClipRects, "base"); disposeObjectsInArray.call(panesClipRects, "wide"); that._panesClipRects = null }, _correctAxes: function() { this._correctValueAxes(true) }, _getExtraOptions: noop, _cleanPanesClipRects: function(clipArrayName) { var that = this, clipArray = that._panesClipRects[clipArrayName]; _each(clipArray || [], function(_, clipRect) { clipRect && clipRect.dispose() }); that._panesClipRects[clipArrayName] = [] }, _createPanes: function() { var defaultPane, that = this, panes = that.option("panes"), panesNameCounter = 0; if (!panes || _isArray(panes) && !panes.length) { panes = DEFAULT_PANES } that._cleanPanesClipRects("fixed"); that._cleanPanesClipRects("base"); that._cleanPanesClipRects("wide"); defaultPane = that.option("defaultPane"); panes = _extend(true, [], _isArray(panes) ? panes : [panes]); _each(panes, function(_, pane) { pane.name = !_isDefined(pane.name) ? DEFAULT_PANE_NAME + panesNameCounter++ : pane.name }); if (_isDefined(defaultPane)) { if (!doesPaneExist(panes, defaultPane)) { that._incidentOccurred("W2101", [defaultPane]); defaultPane = panes[panes.length - 1].name } } else { defaultPane = panes[panes.length - 1].name } that.defaultPane = defaultPane; panes = that._isRotated() ? panes.reverse() : panes; return panes }, _getAxisRenderingOptions: function() { return { axisType: "xyAxes", drawingType: "linear" } }, _prepareAxisOptions: function(typeSelector, userOptions, rotated) { return { isHorizontal: "argumentAxis" === typeSelector !== rotated, containerColor: this._themeManager.getOptions("containerBackgroundColor") } }, _checkPaneName: function(seriesTheme) { var paneList = _map(this.panes, function(pane) { return pane.name }); seriesTheme.pane = seriesTheme.pane || this.defaultPane; return inArray(seriesTheme.pane, paneList) !== -1 }, _getValueAxis: function(paneName, axisName) { var axisOptions, axis, that = this, valueAxes = that._valueAxes, valueAxisOptions = that.option("valueAxis") || {}, valueAxesOptions = _isArray(valueAxisOptions) ? valueAxisOptions : [valueAxisOptions], rotated = that._isRotated(), crosshairMargins = that._getCrosshairMargins(); axisName = axisName || getFirstAxisNameForPane(valueAxes, paneName, that.defaultPane); axis = findAxis(paneName, axisName, valueAxes); if (!axis) { axisOptions = findAxisOptions(valueAxes, valueAxesOptions, axisName); if (!axisOptions) { that._incidentOccurred("W2102", [axisName]); axisOptions = { name: axisName, priority: valueAxes.length } } axis = that._createAxis("valueAxis", axisOptions, { pane: paneName, name: axisName, crosshairMargin: rotated ? crosshairMargins.y : crosshairMargins.x }, rotated); valueAxes.push(axis) } axis.setPane(paneName); return axis }, _correctValueAxes: function(needHideGrids) { var that = this, synchronizeMultiAxes = that._themeManager.getOptions("synchronizeMultiAxes"), valueAxes = that._valueAxes, paneWithAxis = {}; that.series.forEach(function(series) { var axis = series.getValueAxis(); paneWithAxis[axis.pane] = true }); that.panes.forEach(function(pane) { var paneName = pane.name; if (!paneWithAxis[paneName]) { that._getValueAxis(paneName) } if (needHideGrids && synchronizeMultiAxes) { hideGridsOnNonFirstValueAxisForPane(valueAxes.filter(function(axis) { return axis.pane === paneName })) } }); that._valueAxes = valueAxes.filter(function(axis) { if (!axis.pane) { axis.setPane(that.defaultPane) } return doesPaneExist(that.panes, axis.pane) }).sort(compareAxes) }, _getSeriesForPane: function(paneName) { var paneSeries = []; _each(this.series, function(_, oneSeries) { if (oneSeries.pane === paneName) { paneSeries.push(oneSeries) } }); return paneSeries }, _createPanesBorderOptions: function() { var commonBorderOptions = this._themeManager.getOptions("commonPaneSettings").border, panesBorderOptions = {}; _each(this.panes, function(_, pane) { panesBorderOptions[pane.name] = _extend(true, {}, commonBorderOptions, pane.border) }); return panesBorderOptions }, _createScrollBar: function() { var that = this, scrollBarOptions = that._themeManager.getOptions("scrollBar") || {}, scrollBarGroup = that._scrollBarGroup; if (scrollBarOptions.visible) { scrollBarOptions.rotated = that._isRotated(); that._scrollBar = (that._scrollBar || new scrollBarModule.ScrollBar(that._renderer, scrollBarGroup)).update(scrollBarOptions) } else { scrollBarGroup.linkRemove(); that._scrollBar && that._scrollBar.dispose(); that._scrollBar = null } }, _prepareToRender: function(drawOptions) { var panesBorderOptions = this._createPanesBorderOptions(); this._createPanesBackground(); this._appendAxesGroups(); this._transformed && this._resetTransform(); this._updatePanesCanvases(drawOptions); this._adjustViewport(); return panesBorderOptions }, _adjustViewport: function() { var that = this; var series = that._getVisibleSeries(); var argumentAxis = that._getArgumentAxis(); var argumentViewport = argumentAxis.getViewport(); var minMaxDefined = argumentViewport && (_isDefined(argumentViewport.min) || _isDefined(argumentViewport.max)); var useAggregation = series.some(function(s) { return s.useAggregation() }); var adjustOnZoom = that._themeManager.getOptions("adjustOnZoom"); if (!useAggregation && !(minMaxDefined && adjustOnZoom)) { return } var isArgumentAxisZoomed = argumentAxis.isZoomed(); that._valueAxes.forEach(function(axis) { if (!isArgumentAxisZoomed && axis.isZoomed()) { return } var viewport = series.filter(function(s) { return s.getValueAxis() === axis }).reduce(function(range, s) { var seriesRange = s.getViewport(); range.min = _isDefined(seriesRange.min) ? range.min < seriesRange.min ? range.min : seriesRange.min : range.min; range.max = _isDefined(seriesRange.max) ? range.max > seriesRange.max ? range.max : seriesRange.max : range.max; if (s.showZero) { range = new rangeModule.Range(range); range.correctValueZeroLevel() } return range }, {}); if (_isDefined(viewport.min) && _isDefined(viewport.max)) { axis.zoom(viewport.min, viewport.max) } }) }, _recreateSizeDependentObjects: function(isCanvasChanged) { var that = this, series = that._getVisibleSeries(), useAggregation = series.some(function(s) { return s.useAggregation() }), zoomChanged = that._isZooming(); if (!useAggregation) { return } that._argumentAxes.forEach(function(axis) { axis.updateCanvas(that._canvas) }); series.forEach(function(series) { if (series.useAggregation() && (isCanvasChanged || zoomChanged || !series._useAllAggregatedPoints)) { series.createPoints() } }); that._processSeriesFamilies() }, _isZooming: function() { var that = this, argumentAxis = that._getArgumentAxis(); if (!argumentAxis || !argumentAxis.getTranslator()) { return false } var businessRange = argumentAxis.getTranslator().getBusinessRange(); var min = that._zoomMinArg ? that._zoomMinArg : 0; var max = that._zoomMaxArg ? that._zoomMaxArg : 0; if ("logarithmic" === businessRange.axisType) { min = vizUtils.getLog(min, businessRange.base); max = vizUtils.getLog(max, businessRange.base) } var viewportDistance = "discrete" === businessRange.axisType ? vizUtils.getCategoriesInfo(businessRange.categories, min, max).categories.length : Math.abs(max - min); var precision = mathUtils.getPrecision(viewportDistance); precision = precision > 1 ? Math.pow(10, precision - 2) : 1; var zoomChanged = Math.round((that._zoomLength - viewportDistance) * precision) / precision !== 0; that._zoomLength = viewportDistance; return zoomChanged }, _handleSeriesDataUpdated: function() { var that = this, viewport = new rangeModule.Range; that.series.forEach(function(s) { viewport.addRange(s.getArgumentRange()) }); if (!viewport.isDefined()) { viewport.setStubData(that._argumentAxes[0].getOptions().argumentType) } that._argumentAxes.forEach(function(axis) { axis.updateCanvas(that._canvas); axis.setBusinessRange(viewport) }); that.callBase() }, _isLegendInside: function() { return this._legend && "inside" === this._legend.getPosition() }, _isRotated: function() { return this._themeManager.getOptions("rotated") }, _getLayoutTargets: function() { return this.panes }, _applyClipRects: function(panesBorderOptions) { var i, that = this, canvasClipRectID = that._getCanvasClipRectID(); that._drawPanesBorders(panesBorderOptions); that._createClipRectsForPanes(); for (i = 0; i < that._argumentAxes.length; i++) { that._argumentAxes[i].applyClipRects(that._getElementsClipRectID(that._argumentAxes[i].pane), canvasClipRectID) } for (i = 0; i < that._valueAxes.length; i++) { that._valueAxes[i].applyClipRects(that._getElementsClipRectID(that._valueAxes[i].pane), canvasClipRectID) } that._fillPanesBackground() }, _updateLegendPosition: function(drawOptions, legendHasInsidePosition) { var that = this; if (drawOptions.drawLegend && that._legend && legendHasInsidePosition) { var panes = that.panes, newCanvas = _extend({}, panes[0].canvas), layoutManager = new LayoutManagerModule.LayoutManager; newCanvas.right = panes[panes.length - 1].canvas.right; newCanvas.bottom = panes[panes.length - 1].canvas.bottom; layoutManager.setOptions({ width: 0, height: 0 }); layoutManager.layoutElements([that._legend], newCanvas, noop, [{ canvas: newCanvas }], void 0) } }, _applyExtraSettings: function(series) { var that = this, paneIndex = that._getPaneIndex(series.pane), panesClipRects = that._panesClipRects, wideClipRect = panesClipRects.wide[paneIndex]; series.setClippingParams(panesClipRects.base[paneIndex].id, wideClipRect && wideClipRect.id, that._getPaneBorderVisibility(paneIndex)) }, _updatePanesCanvases: function(drawOptions) { if (!drawOptions.recreateCanvas) { return } vizUtils.updatePanesCanvases(this.panes, this._canvas, this._isRotated()) }, _renderScaleBreaks: function() { this._valueAxes.concat(this._argumentAxes).forEach(function(axis) { axis.drawScaleBreaks() }) }, _renderAxes: function(drawOptions, panesBorderOptions) { var that = this, rotated = that._isRotated(), synchronizeMultiAxes = that._themeManager.getOptions("synchronizeMultiAxes"), extendedArgAxes = (that._scrollBar ? [that._scrollBar] : []).concat(that._argumentAxes), verticalAxes = rotated ? extendedArgAxes : that._valueAxes, horizontalAxes = rotated ? that._valueAxes : extendedArgAxes, allAxes = verticalAxes.concat(horizontalAxes); that._updatePanesCanvases(drawOptions); var panesCanvases = that.panes.reduce(function(canvases, pane) { canvases[pane.name] = _extend({}, pane.canvas); return canvases }, {}), cleanPanesCanvases = _extend(true, {}, panesCanvases); if (!drawOptions.adjustAxes) { drawAxesWithTicks(verticalAxes, !rotated && synchronizeMultiAxes, panesCanvases, panesBorderOptions); drawAxesWithTicks(horizontalAxes, rotated && synchronizeMultiAxes, panesCanvases, panesBorderOptions); that._renderScaleBreaks(); return false } if (that._scrollBar) { that._scrollBar.setPane(that.panes) } var vAxesMargins = { panes: {} }, hAxesMargins = getHorizontalAxesMargins(horizontalAxes, function(axis) { return axis.estimateMargins(panesCanvases[axis.pane]) }); panesCanvases = shrinkCanvases(rotated, panesCanvases, vAxesMargins, hAxesMargins); drawAxesWithTicks(verticalAxes, !rotated && synchronizeMultiAxes, panesCanvases, panesBorderOptions); vAxesMargins = getVerticalAxesMargins(verticalAxes); panesCanvases = shrinkCanvases(rotated, panesCanvases, vAxesMargins, hAxesMargins); drawAxesWithTicks(horizontalAxes, rotated && synchronizeMultiAxes, panesCanvases, panesBorderOptions); hAxesMargins = getHorizontalAxesMargins(horizontalAxes, getAxisMargins); panesCanvases = shrinkCanvases(rotated, panesCanvases, vAxesMargins, hAxesMargins); performActionOnAxes(allAxes, "updateSize", panesCanvases); horizontalAxes.forEach(shiftAxis("top", "bottom")); verticalAxes.forEach(shiftAxis("left", "right")); that._renderScaleBreaks(); that.panes.forEach(function(pane) { _extend(pane.canvas, panesCanvases[pane.name]) }); return cleanPanesCanvases }, _shrinkAxes: function(drawOptions, sizeShortage, panesCanvases) { if (!sizeShortage || !panesCanvases) { return } var that = this, rotated = that._isRotated(), extendedArgAxes = (that._scrollBar ? [that._scrollBar] : []).concat(that._argumentAxes), verticalAxes = rotated ? extendedArgAxes : that._valueAxes, horizontalAxes = rotated ? that._valueAxes : extendedArgAxes, allAxes = verticalAxes.concat(horizontalAxes); if (sizeShortage.width || sizeShortage.height) { checkUsedSpace(sizeShortage, "height", horizontalAxes, getHorizontalAxesMargins); checkUsedSpace(sizeShortage, "width", verticalAxes, getVerticalAxesMargins); performActionOnAxes(allAxes, "updateSize", panesCanvases); panesCanvases = shrinkCanvases(rotated, panesCanvases, getVerticalAxesMargins(verticalAxes), getHorizontalAxesMargins(horizontalAxes, getAxisMargins)); performActionOnAxes(allAxes, "updateSize", panesCanvases); horizontalAxes.forEach(shiftAxis("top", "bottom")); verticalAxes.forEach(shiftAxis("left", "right")); that.panes.forEach(function(pane) { _extend(pane.canvas, panesCanvases[pane.name]) }) } }, _getPanesParameters: function() { var i, that = this, panes = that.panes, params = []; for (i = 0; i < panes.length; i++) { if (that._getPaneBorderVisibility(i)) { params.push({ coords: panes[i].borderCoords, clipRect: that._panesClipRects.fixed[i] }) } } return params }, _createCrosshairCursor: function() { var that = this, options = that._themeManager.getOptions("crosshair") || {}, index = that._displayedArgumentAxisIndex, axes = !that._isRotated() ? [ [that._argumentAxes[index]], that._valueAxes ] : [that._valueAxes, [that._argumentAxes[index]]], parameters = { canvas: that._getCommonCanvas(), panes: that._getPanesParameters(), axes: axes }; if (!options || !options.enabled) { return } if (!that._crosshair) { that._crosshair = new crosshairModule.Crosshair(that._renderer, options, parameters, that._crosshairCursorGroup) } else { that._crosshair.update(options, parameters) } that._crosshair.render() }, _getCommonCanvas: function() { var i, canvas, commonCanvas, panes = this.panes; for (i = 0; i < panes.length; i++) { canvas = panes[i].canvas; if (!commonCanvas) { commonCanvas = _extend({}, canvas) } else { commonCanvas.right = canvas.right; commonCanvas.bottom = canvas.bottom } } return commonCanvas }, _createPanesBackground: function() { var backgroundColor, rect, i, that = this, defaultBackgroundColor = that._themeManager.getOptions("commonPaneSettings").backgroundColor, renderer = that._renderer, rects = []; that._panesBackgroundGroup.clear(); for (i = 0; i < that.panes.length; i++) { backgroundColor = that.panes[i].backgroundColor || defaultBackgroundColor; if (!backgroundColor || "none" === backgroundColor) { rects.push(null); continue } rect = renderer.rect(0, 0, 0, 0).attr({ fill: backgroundColor, "stroke-width": 0 }).append(that._panesBackgroundGroup); rects.push(rect) } that.panesBackground = rects }, _fillPanesBackground: function() { var bc, that = this; _each(that.panes, function(i, pane) { bc = pane.borderCoords; if (null !== that.panesBackground[i]) { that.panesBackground[i].attr({ x: bc.left, y: bc.top, width: bc.width, height: bc.height }) } }) }, _calcPaneBorderCoords: function(pane) { var canvas = pane.canvas, bc = pane.borderCoords = pane.borderCoords || {}; bc.left = canvas.left; bc.top = canvas.top; bc.right = canvas.width - canvas.right; bc.bottom = canvas.height - canvas.bottom; bc.width = Math.max(bc.right - bc.left, 0); bc.height = Math.max(bc.bottom - bc.top, 0) }, _drawPanesBorders: function(panesBorderOptions) { var that = this, rotated = that._isRotated(); that._panesBorderGroup.linkRemove().clear(); _each(that.panes, function(i, pane) { var bc, segmentRectParams, borderOptions = panesBorderOptions[pane.name], attr = { fill: "none", stroke: borderOptions.color, "stroke-opacity": borderOptions.opacity, "stroke-width": borderOptions.width, dashStyle: borderOptions.dashStyle, "stroke-linecap": "square" }; that._calcPaneBorderCoords(pane, rotated); if (!borderOptions.visible) { return } bc = pane.borderCoords; segmentRectParams = prepareSegmentRectPoints(bc.left, bc.top, bc.width, bc.height, borderOptions); that._renderer.path(segmentRectParams.points, segmentRectParams.pathType).attr(attr).append(that._panesBorderGroup) }); that._panesBorderGroup.linkAppend() }, _createClipRect: function(clipArray, index, left, top, width, height) { var that = this, clipRect = clipArray[index]; if (!clipRect) { clipRect = that._renderer.clipRect(left, top, width, height); clipArray[index] = clipRect } else { clipRect.attr({ x: left, y: top, width: width, height: height }) } }, _createClipRectsForPanes: function() { var that = this, canvas = that._canvas; _each(that.panes, function(i, pane) { var needWideClipRect = false, bc = pane.borderCoords, left = bc.left, top = bc.top, width = bc.width, height = bc.height, panesClipRects = that._panesClipRects; that._createClipRect(panesClipRects.fixed, i, left, top, width, height); that._createClipRect(panesClipRects.base, i, left, top, width, height); _each(that.series, function(_, series) { if (series.pane === pane.name && (series.isFinancialSeries() || series.areErrorBarsVisible())) { needWideClipRect = true } }); if (needWideClipRect) { if (that._isRotated()) { top = 0; height = canvas.height } else { left = 0; width = canvas.width } that._createClipRect(panesClipRects.wide, i, left, top, width, height) } else { panesClipRects.wide[i] = null } }) }, _getPaneIndex: function(paneName) { var paneIndex; _each(this.panes, function(index, pane) { if (pane.name === paneName) { paneIndex = index; return false } }); return paneIndex }, _getPaneBorderVisibility: function(paneIndex) { var commonPaneBorderVisible = this._themeManager.getOptions("commonPaneSettings").border.visible, pane = this.panes[paneIndex] || {}, paneBorder = pane.border || {}; return "visible" in paneBorder ? paneBorder.visible : commonPaneBorderVisible }, _getElementsClipRectID: function(paneName) { return this._panesClipRects.fixed[this._getPaneIndex(paneName)].id }, _getCanvasForPane: function(paneName) { var i, panes = this.panes, panesNumber = panes.length; for (i = 0; i < panesNumber; i++) { if (panes[i].name === paneName) { return panes[i].canvas } } }, _transformArgument: function(translate, scale) { var settings, clipSettings, that = this, rotated = that._isRotated(), panesClipRects = that._panesClipRects; if (!that._transformed) { that._transformed = true; that._labelsGroup.remove(); that._resetIsReady(); _each(that.series || [], function(i, s) { s.applyClip() }) } if (rotated) { settings = { translateY: translate, scaleY: scale }; clipSettings = { translateY: -translate / scale, scaleY: 1 / scale } } else { settings = { translateX: translate, scaleX: scale }; clipSettings = { translateX: -translate / scale, scaleX: 1 / scale } } applyClipSettings(panesClipRects.base, clipSettings); applyClipSettings(panesClipRects.wide, clipSettings); that._seriesGroup.attr(settings); that._scrollBar && that._scrollBar.transform(-translate, scale) }, _resetTransform: function() { var that = this, settings = { translateX: 0, translateY: 0, scaleX: null, scaleY: null }, panesClipRects = that._panesClipRects; applyClipSettings(panesClipRects.base, settings); applyClipSettings(panesClipRects.wide, settings); that._seriesGroup.attr(settings); _each(that.series || [], function(i, s) { s.resetClip() }); that._transformed = false }, _getTrackerSettings: function() { var that = this, themeManager = that._themeManager; return _extend(this.callBase(), { chart: that, zoomingMode: themeManager.getOptions("zoomingMode"), scrollingMode: themeManager.getOptions("scrollingMode"), rotated: that._isRotated(), crosshair: that._getCrosshairOptions().enabled ? that._crosshair : null }) }, _resolveLabelOverlappingStack: function() { var that = this, isRotated = that._isRotated(), shiftDirection = isRotated ? function(box, length) { return { x: box.x - length, y: box.y } } : function(box, length) { return { x: box.x, y: box.y - length } }; _each(that._getStackPoints(), function(_, stacks) { _each(stacks, function(_, points) { overlapping.resolveLabelOverlappingInOneDirection(points, that._getCommonCanvas(), isRotated, shiftDirection) }) }) }, _getStackPoints: function() { var stackPoints = {}, visibleSeries = this._getVisibleSeries(); _each(visibleSeries, function(_, singleSeries) { var points = singleSeries.getPoints(), stackName = singleSeries.getStackName() || null; _each(points, function(_, point) { var argument = point.argument; if (!stackPoints[argument]) { stackPoints[argument] = {} } if (!stackPoints[argument][stackName]) { stackPoints[argument][stackName] = [] } stackPoints[argument][stackName].push(point) }) }); return stackPoints }, _getCrosshairOptions: function() { return this._getOption("crosshair") }, zoomArgument: function(min, max, gesturesUsed) { var bounds, zoomArg, that = this; if (!_isDefined(min) && !_isDefined(max)) { return } if (!gesturesUsed) { that._eventTrigger("zoomStart") } that._argumentAxes.forEach(function(axis) { zoomArg = axis.zoom(min, max, gesturesUsed) }); that._zoomMinArg = zoomArg && zoomArg.min; that._zoomMaxArg = zoomArg && zoomArg.max; that._notApplyMargins = gesturesUsed; that._recreateSizeDependentObjects(false); that._doRender({ force: true, drawTitle: false, drawLegend: false, adjustAxes: false, animate: false }); bounds = that.getVisibleArgumentBounds(); that._eventTrigger("zoomEnd", { rangeStart: bounds.minVisible, rangeEnd: bounds.maxVisible }) }, _resetZoom: function() { var that = this; that._zoomMinArg = that._zoomMaxArg = that._notApplyMargins = void 0; that._argumentAxes[0].resetZoom(); that._valueAxes.forEach(function(axis) { axis.resetZoom() }) }, getVisibleArgumentBounds: function() { var translator = this._argumentAxes[0].getTranslator(), range = translator.getBusinessRange(), isDiscrete = "discrete" === range.axisType, categories = range.categories; return { minVisible: isDiscrete ? range.minVisible || categories[0] : range.minVisible, maxVisible: isDiscrete ? range.maxVisible || categories[categories.length - 1] : range.maxVisible } } }); dxChart.addPlugin(require("./chart_components/shutter_zoom")); registerComponent("dxChart", dxChart); module.exports = dxChart; module.exports.default = module.exports;