var _____WB$wombat$assign$function_____ = function(name) {return (self._wb_wombat && self._wb_wombat.local_init && self._wb_wombat.local_init(name)) || self[name]; }; if (!self.__WB_pmw) { self.__WB_pmw = function(obj) { this.__WB_source = obj; return this; } } { let window = _____WB$wombat$assign$function_____("window"); let self = _____WB$wombat$assign$function_____("self"); let document = _____WB$wombat$assign$function_____("document"); let location = _____WB$wombat$assign$function_____("location"); let top = _____WB$wombat$assign$function_____("top"); let parent = _____WB$wombat$assign$function_____("parent"); let frames = _____WB$wombat$assign$function_____("frames"); let opener = _____WB$wombat$assign$function_____("opener"); var __aspxCrosshairVDivID = "_CHV-"; var __aspxCrosshairHDivID = "_CHH-"; var __aspxCrosshairLabelID = "_CHL-"; var __aspxCrosshairVLabelID = "_CHVL-"; var __aspxCrosshairHLabelID = "_CHHL-"; var __aspxChartToolTipID = "_CTT-"; var __aspxChartToolTipClassName = "dxchartsuiTooltip"; var __aspxChartCrosshairVLineClassName = "dxchartsuiCrosshairVLine"; var __aspxChartCrosshairHLineClassName = "dxchartsuiCrosshairHLine"; var __aspxChartCrosshairLabelClassName = "dxchartsuiCrosshairLabel"; function __aspxCrosshairValueItemsComparer(arrayElement, value) { if(arrayElement.value == value) return 0; else return arrayElement.value < value ? -1 : 1; }; function __aspxSortPointInfoByArgument(p1, p2) { if (p1.argument < p2.argument) return 1; if (p1.argument > p2.argument) return -1; return p1.value > p2.value ? -1 : 1; }; function __aspxSortPointInfoByValue(p1, p2) { if (p1.value < p2.value) return 1; if (p1.value > p2.value) return -1; return p1.argument > p2.argument ? -1 : 1; }; function __aspxChartGetHorizontalTable(cell1, cell2) { return "
" + cell1 + "" + cell2 + "
"; }; function __aspxGetToolTipX(dockPosition, dockTargetWidth, width, dockTargetX, offset) { if (dockPosition.indexOf("Right") > -1) { return dockTargetX + dockTargetWidth - width - offset; } else { return dockTargetX + offset; } }; function __aspxGetToolTipY(dockPosition, dockTargetHeight, height, dockTargetY, offset) { if (dockPosition.indexOf("Bottom") > -1) { return dockTargetY + dockTargetHeight - height - offset; } else { return dockTargetY + offset; } }; function __aspxSetCssClassName(object, chartControl, className) { if (chartControl.chart.cssPostfix != "") { className += "_" + chartControl.chart.cssPostfix; } object.className = className; }; function __aspxCreateChartDiv(chartControl, prefix, index) { var div = document.createElement("div"); div.onselectstart = function() { return false; }; div.id = __aspxGetChartDivId(chartControl, prefix, index); chartControl.mainElement.appendChild(div); return div; }; function __aspxGetChartDivId(chartControl, prefix, index) { return chartControl.uniqueID + prefix + index; }; function __aspxCreateChartToolTip(chartControl, prefix, index) { var div = __aspxCreateChartDiv(chartControl, prefix, index); __aspxSetCssClassName(div, chartControl, __aspxChartToolTipClassName); return div; }; function __aspxRemoveChartDiv(chartControl, prefix, index) { var id = __aspxGetChartDivId(chartControl, prefix, index); var mainElement = chartControl.GetMainDOMElement(); var element = _aspxGetChildById(chartControl.GetMainDOMElement(), id); mainElement.removeChild(element); }; function __aspxChartSetDivPosition(div, x, y) { _aspxSetAbsoluteX(div, x); _aspxSetAbsoluteY(div, y); }; function __aspxShowInFreePosition(div, chart, position, htmlElementX, htmlElementY) { var left; var top; if (_aspxIsExists(position.paneID) && chart.diagram instanceof ASPxClientXYDiagram2D) { var pane = chart.diagram.FindPaneByID(position.paneID); if (_aspxIsExists(pane)) { left = __aspxGetToolTipX(position.dockPosition, pane.boundsWidth, div.clientWidth, htmlElementX + pane.boundsLeft, position.offsetX); top = __aspxGetToolTipY(position.dockPosition, pane.boundsHeight, div.clientHeight, htmlElementY + pane.boundsTop, position.offsetY); } } else { left = __aspxGetToolTipX(position.dockPosition, chart.chartControl.GetWidth(), div.clientWidth, htmlElementX, position.offsetX); top = __aspxGetToolTipY(position.dockPosition, chart.chartControl.GetHeight(), div.clientHeight, htmlElementY, position.offsetY); } __aspxChartSetDivPosition(div, left, top); } ASPxClientCrosshairRenderer = _aspxCreateClass(ASPxClientControl, { constructor: function(chartControl, name) { this.constructor.prototype.constructor.call(this, name); this.chart = chartControl; this.hDivs = []; this.vDivs = []; this.labelDivs = []; this.hLabelDivs = []; this.vLabelDivs = []; this.diagram = chartControl.chart.diagram; this.snapToNearestArgument = this.chart.chart.crosshairOptions.snapMode == "NearestArgument"; this.isHorizontal = this.snapToNearestArgument ^ this.diagram.rotated; this.indent = 2; }, CreateVerticalLineDiv: function(index) { var div = __aspxCreateChartDiv(this.chart, __aspxCrosshairVDivID, index); __aspxSetCssClassName(div, this.chart, __aspxChartCrosshairVLineClassName); this.vDivs.push(div); return div; }, CreateHorizontalLineDiv: function(index) { var div = __aspxCreateChartDiv(this.chart, __aspxCrosshairHDivID, index); __aspxSetCssClassName(div, this.chart, __aspxChartCrosshairHLineClassName); this.hDivs.push(div); return div; }, CreateVerticalLabelDiv: function(index) { var div = __aspxCreateChartDiv(this.chart, __aspxCrosshairVLabelID, index); __aspxSetCssClassName(div, this.chart, __aspxChartCrosshairLabelClassName); this.vLabelDivs.push(div); return div; }, CreateHorizontalLabelDiv: function(index) { var div = __aspxCreateChartDiv(this.chart, __aspxCrosshairHLabelID, index); __aspxSetCssClassName(div, this.chart, __aspxChartCrosshairLabelClassName); this.hLabelDivs.push(div); return div; }, CreateMainLabelDiv: function(index) { var div = __aspxCreateChartToolTip(this.chart, __aspxCrosshairLabelID, index); this.labelDivs.push(div); return div; }, GetPane: function(x, y) { if (this.diagram != null && this.diagram instanceof ASPxClientXYDiagram2D) return this.diagram.FindPaneByXY(x, y); return null; }, ClearDivArray: function(divArray, prefix, index) { var length = divArray.length; if (index < length) { for (var i = index; i < length; i++) { divArray.pop(); __aspxRemoveChartDiv(this.chart, prefix, i); } } }, Hide: function() { this.ClearDivs(0, 0, 0, 0, 0); }, ClearDivs: function(hLineIndex, vLineIndex, hLabelIndex, vLabelIndex, labelIndex) { this.ClearDivArray(this.hDivs, __aspxCrosshairHDivID, hLineIndex); this.ClearDivArray(this.vDivs, __aspxCrosshairVDivID, vLineIndex); this.ClearDivArray(this.hLabelDivs, __aspxCrosshairHLabelID, hLabelIndex); this.ClearDivArray(this.vLabelDivs, __aspxCrosshairVLabelID, vLabelIndex); this.ClearDivArray(this.labelDivs, __aspxCrosshairLabelID, labelIndex); }, GetVerticalDiv: function(index) { if (index < this.vDivs.length) return this.vDivs[index]; return this.CreateVerticalLineDiv(index); }, GetHorizontalDiv: function(index) { if (index < this.hDivs.length) return this.hDivs[index]; return this.CreateHorizontalLineDiv(index); }, GetVerticalLabelDiv: function(index) { if (index < this.vLabelDivs.length) return this.vLabelDivs[index]; return this.CreateVerticalLabelDiv(index); }, GetHorizontalLabelDiv: function(index) { if (index < this.hLabelDivs.length) return this.hLabelDivs[index]; return this.CreateHorizontalLabelDiv(index); }, GetLabelDiv: function(index) { if (index < this.labelDivs.length) return this.labelDivs[index]; return this.CreateMainLabelDiv(index); }, GetCrosshairSeries: function(pane) { var crosshairSeries = []; for (var i = 0; i < this.chart.chart.series.length; i++) { var series = this.chart.chart.series[i]; if (series.pane == pane.name && series.visible) crosshairSeries.push(series); } return crosshairSeries; }, ClampCoord: function(coord, start, length) { if (coord < start) coord = start; else { if (coord > start + length) coord = start + length; } return coord; }, GetAxisByName: function(name, isXAxis) { if (isXAxis) { return this.diagram.FindAxisXByName(name); } return this.diagram.FindAxisYByName(name); }, GetDiff: function(value1, value2) { return value1 > value2 ? value1 - value2 : value2 - value1; }, GetValueItemsByValue: function(series, index) { var items = []; var crosshairValueItem = series.crosshairValueItems[index]; items.push(crosshairValueItem); for (var i = index - 1; i >= 0; i--) { if (series.crosshairValueItems[i].value == crosshairValueItem.value) { items.push(series.crosshairValueItems[i]); } else { break; } } for (var i = index + 1; i < series.crosshairValueItems.length; i++) { if (series.crosshairValueItems[i].value == crosshairValueItem.value) { items.push(series.crosshairValueItems[i]); } else { break; } } return items; }, GetAxisValue: function(axisValues, axisName) { for (var i = 0; i < axisValues.length; i++) { if (axisValues[i].axis.name == axisName) { return axisValues[i].internalValue; } } return null; }, FindNearestPoint: function(pane, series, valueItems, axisValues, primaryAxis, secondaryAxis) { var axisValue = this.GetAxisValue(axisValues, secondaryAxis.name); var value = null; var valueItem = null; for (var i = 0; i < valueItems.length; i++) { var point = series.points[valueItems[i].pointIndex]; if (this.snapToNearestArgument) { for (var j = 0; j < point.values.length; j++) { var pointValue = point.crosshairValues[j]; var isVisible = this.diagram.IsAxisValueVisible(pane, secondaryAxis, pointValue); if (isVisible && (value == null || this.GetDiff(axisValue, pointValue) < this.GetDiff(axisValue, value))) { value = pointValue; valueItem = valueItems[i]; } } } else { var pointValue = secondaryAxis.GetInternalArgument(point.argument); var isVisible = this.diagram.IsAxisValueVisible(pane, secondaryAxis, pointValue); if (isVisible && (value == null || this.GetDiff(axisValue, pointValue) < this.GetDiff(axisValue, value))) { value = pointValue; valueItem = valueItems[i]; } } } if (value == null || valueItem == null) { return null; } var point = series.points[valueItem.pointIndex]; var argument = this.snapToNearestArgument ? valueItem.value : value; if (_aspxIsExists(point.offset)) { argument += point.offset; } value = this.snapToNearestArgument ? value : valueItem.value; var x = this.diagram.MapInternalToPoint(pane, this.snapToNearestArgument ? primaryAxis.name : secondaryAxis.name, argument); var y = this.diagram.MapInternalToPoint(pane, this.snapToNearestArgument ? secondaryAxis.name : primaryAxis.name, value); if (_aspxIsExists(point.fixedOffset)) { x += point.fixedOffset; } var ax = this.diagram.rotated ? y : x; var ay = this.diagram.rotated ? x : y; return { point: point, x: ax, y: ay, argument: argument, value: value }; }, AddValueToPaneCrosshairInfo: function(paneCrosshairInfo, value, isArgument, isHorizontal, axis) { var shouldAddLine = isArgument ? this.chart.chart.crosshairOptions.showArgumentLine : this.chart.chart.crosshairOptions.showValueLine; var shouldAddLabel = isArgument ? this.chart.chart.crosshairOptions.showArgumentLabels : this.chart.chart.crosshairOptions.showValueLabels; if (shouldAddLine) { paneCrosshairInfo.AddLine(value, isHorizontal, this.snapToNearestArgument ^ isArgument); } if (shouldAddLabel && axis.actualCrosshairLabelVisibility) { paneCrosshairInfo.AddLabel(value, isHorizontal); } }, GetRange: function(pane, percent, maxValue) { var range = this.isHorizontal ? pane.boundsWidth : pane.boundsHeight; range *= percent; if (maxValue > 0 && range > maxValue) range = maxValue; return range; }, AddSecondaryItem: function(paneCrosshairInfo, secondaryItem) { if (this.chart.chart.crosshairOptions.showCrosshairLabels && secondaryItem.series.actualCrosshairLabelVisibility) { paneCrosshairInfo.pointsInfo.push(secondaryItem.pointInfo); } var value = this.isHorizontal ? secondaryItem.pointInfo.y : secondaryItem.pointInfo.x; var internalValue = this.snapToNearestArgument ? secondaryItem.pointInfo.value : secondaryItem.pointInfo.argument; this.AddValueToPaneCrosshairInfo(paneCrosshairInfo, new ASPxAxisValuePair(secondaryItem.secondaryAxis, internalValue, value), !this.snapToNearestArgument, this.isHorizontal, secondaryItem.secondaryAxis); }, GetCrosshairValueItemIndex: function(series, axisValue) { var index = _aspxArrayBinarySearch(series.crosshairValueItems, axisValue, __aspxCrosshairValueItemsComparer, 0, series.crosshairValueItems.length); if (index < 0) { index = -1 * index - 1; if (index >= series.crosshairValueItems.length) index = series.crosshairValueItems.length - 1; else { if (index > 0) { var prev = this.GetDiff(series.crosshairValueItems[index - 1].value, axisValue); var next = this.GetDiff(series.crosshairValueItems[index].value, axisValue); if (prev < next) index--; } } } return index; }, CalculatePaneCrosshairInfo: function(pane, x, y) { x = this.ClampCoord(x, pane.boundsLeft, pane.boundsWidth); y = this.ClampCoord(y, pane.boundsTop, pane.boundsHeight); var paneCrosshairInfo = new ASPxPaneCrosshairInfo(pane, x, y); var crosshairSeries = this.GetCrosshairSeries(pane); var axisValues = this.diagram.MapPointToInternal(pane, x, y); var smallRange = this.GetRange(pane, 0.08, 40); for (var i = 0; i < crosshairSeries.length; i++) { var series = crosshairSeries[i]; var primaryAxisName = this.snapToNearestArgument ? series.axisX : series.axisY; var primaryAxisValue = this.GetAxisValue(axisValues, primaryAxisName); var primaryAxis = this.GetAxisByName(primaryAxisName, this.snapToNearestArgument); var primaryScreenAxisValue = this.diagram.MapInternalToPoint(pane, primaryAxisName, primaryAxisValue); this.AddValueToPaneCrosshairInfo(paneCrosshairInfo, new ASPxAxisValuePair(primaryAxis, primaryAxisValue, primaryScreenAxisValue), this.snapToNearestArgument, !this.isHorizontal, primaryAxis); if (!series.actualCrosshairEnabled || series.crosshairValueItems.length == 0) continue; var index = this.GetCrosshairValueItemIndex(series, primaryAxisValue); var valueItems = this.GetValueItemsByValue(series, index); var secondaryAxisName = this.snapToNearestArgument ? series.axisY : series.axisX; var secondaryAxis = this.GetAxisByName(secondaryAxisName, !this.snapToNearestArgument); var pointInfo = this.FindNearestPoint(pane, series, valueItems, axisValues, primaryAxis, secondaryAxis); if (pointInfo != null && pane.InPane(pointInfo.x, pointInfo.y)) { var diff = this.GetDiff(this.isHorizontal ? x : y, this.isHorizontal ? pointInfo.x : pointInfo.y); if (diff <= smallRange) { this.AddSecondaryItem(paneCrosshairInfo, { pointInfo: pointInfo, secondaryAxis: secondaryAxis, series: series }); } } } return paneCrosshairInfo; }, AddUniqueValue: function(uniqueValues, value) { for (var i = 0; i < uniqueValues.length; i++) { if (uniqueValues[i] == value) return false; } uniqueValues.push(value); return true; }, FindAxisLabelBounds: function(pane, axisName) { if (_aspxIsExists(pane.axisLabelBounds)) { for (var i = 0; i < pane.axisLabelBounds.length; i++) { if (pane.axisLabelBounds[i].axisName == axisName) return pane.axisLabelBounds[i]; } } return null; }, GetLineLabelHtml: function(axisValuePair, isValueAxis) { var value = axisValuePair.axis.GetNativeArgument(axisValuePair.internalValue); return ASPxToolTipPatternHelper.GetAxisLabelText(axisValuePair.axis, isValueAxis, value); }, DrawVerticalElements: function(paneCrosshairInfo) { var chartX = _aspxGetAbsoluteX(this.chart.mainElement); var chartY = _aspxGetAbsoluteY(this.chart.mainElement); for (var i = 0; i < paneCrosshairInfo.verticalLines.length; i++) { var axisValuePair = paneCrosshairInfo.verticalLines[i]; var lineDiv = this.GetVerticalDiv(this.vLineIndex); __aspxChartSetDivPosition(lineDiv, chartX + axisValuePair.screenValue, chartY + paneCrosshairInfo.pane.boundsTop); lineDiv.style.height = paneCrosshairInfo.pane.boundsHeight + "px"; this.vLineIndex++; } for (var i = 0; i < paneCrosshairInfo.verticalLabels.length; i++) { var axisValuePair = paneCrosshairInfo.verticalLabels[i]; var axisLabelBounds = this.FindAxisLabelBounds(paneCrosshairInfo.pane, axisValuePair.axis.name); if (axisLabelBounds != null) { var labelDiv = this.GetVerticalLabelDiv(this.vLabelIndex); labelDiv.innerHTML = this.GetLineLabelHtml(axisValuePair, this.diagram.rotated); var offset = axisLabelBounds.top; if (axisLabelBounds.top < paneCrosshairInfo.pane.boundsTop) offset += axisLabelBounds.height - labelDiv.clientHeight; __aspxChartSetDivPosition(labelDiv, chartX + axisValuePair.screenValue - labelDiv.clientWidth / 2, chartY + offset); this.vLabelIndex++; } } }, DrawHorizontalElements: function(paneCrosshairInfo) { var chartX = _aspxGetAbsoluteX(this.chart.mainElement); var chartY = _aspxGetAbsoluteY(this.chart.mainElement); for (var i = 0; i < paneCrosshairInfo.horizontalLines.length; i++) { var axisValuePair = paneCrosshairInfo.horizontalLines[i]; var lineDiv = this.GetHorizontalDiv(this.hLineIndex); __aspxChartSetDivPosition(lineDiv, chartX + paneCrosshairInfo.pane.boundsLeft, chartY + axisValuePair.screenValue); lineDiv.style.width = paneCrosshairInfo.pane.boundsWidth + "px"; this.hLineIndex++; } for (var i = 0; i < paneCrosshairInfo.horizontalLabels.length; i++) { var axisValuePair = paneCrosshairInfo.horizontalLabels[i]; var axisLabelBounds = this.FindAxisLabelBounds(paneCrosshairInfo.pane, axisValuePair.axis.name); if (axisLabelBounds != null) { var labelDiv = this.GetHorizontalLabelDiv(this.hLabelIndex); labelDiv.innerHTML = this.GetLineLabelHtml(axisValuePair, !this.diagram.rotated); var offset = axisLabelBounds.left; if (axisLabelBounds.left < paneCrosshairInfo.pane.boundsLeft) offset += axisLabelBounds.width - labelDiv.clientWidth; __aspxChartSetDivPosition(labelDiv, chartX + offset, chartY + axisValuePair.screenValue - labelDiv.clientHeight / 2); this.hLabelIndex++; } } }, ShowLabel: function(paneCrosshairInfo, pointsInfo, pointInfo, content, isSingle) { var labelDiv = this.GetLabelDiv(this.labelIndex); labelDiv.innerHTML = content; var x = pointInfo.x - paneCrosshairInfo.pane.boundsLeft; var y = pointInfo.y - paneCrosshairInfo.pane.boundsTop; var labelBounds = { x: x, y: y, width: labelDiv.clientWidth, height: labelDiv.clientHeight }; var direction = { x: 1, y: -1 }; if (!isSingle) { direction = this.CorrectLabelBounds(paneCrosshairInfo, labelBounds, pointsInfo, x, y, direction.x, direction.y); } else { this.SetDirection(labelBounds, x, y, direction.x, direction.y); } var verticalPrefix = direction.y > 0 ? "Top" : "Bottom"; var horizontalPrefix = direction.x > 0 ? "Left" : "Right"; paneCrosshairInfo.labelsBounds.push(labelBounds); var offsetX = _aspxGetAbsoluteX(this.chart.mainElement) + paneCrosshairInfo.pane.boundsLeft; var offsetY = _aspxGetAbsoluteY(this.chart.mainElement) + paneCrosshairInfo.pane.boundsTop; __aspxSetCssClassName(labelDiv, this.chart, __aspxChartToolTipClassName + "_" + verticalPrefix + horizontalPrefix); __aspxChartSetDivPosition(labelDiv, offsetX + labelBounds.x, offsetY + labelBounds.y); this.labelIndex++; }, GetLabelHTML: function(point) { var color = _aspxIsExists(point.color) ? point.color : point.series.color; var marker = "
"; var text = ASPxToolTipPatternHelper.GetPointToolTipText(point.series.crosshairLabelPattern, point, point.series); return __aspxChartGetHorizontalTable(marker, text); }, ClacSquareLength: function(x1, y1, x2, y2) { return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); }, DrawPointLabels: function(paneCrosshairInfo) { if (this.diagram.rotated) { paneCrosshairInfo.pointsInfo.sort(__aspxSortPointInfoByValue); } else { paneCrosshairInfo.pointsInfo.sort(__aspxSortPointInfoByArgument); } var pointsInfo = paneCrosshairInfo.pointsInfo; if (pointsInfo.length == 0) { return; } switch (this.chart.chart.crosshairOptions.crosshairLabelMode) { case "ShowForEachSeries": for (var i = 0; i < pointsInfo.length; i++) { this.ShowLabel(paneCrosshairInfo, pointsInfo, pointsInfo[i], this.GetLabelHTML(pointsInfo[i].point), false); } break; case "ShowForNearestSeries": var min = this.ClacSquareLength(paneCrosshairInfo.x, paneCrosshairInfo.y, pointsInfo[0].x, pointsInfo[0].y); var index = 0; for (var i = 1; i < pointsInfo.length; i++) { var distance = this.ClacSquareLength(paneCrosshairInfo.x, paneCrosshairInfo.y, pointsInfo[i].x, pointsInfo[i].y); if (distance < min) { min = distance; index = i; } } this.ShowLabel(paneCrosshairInfo, pointsInfo, pointsInfo[index], this.GetLabelHTML(pointsInfo[index].point), true); break; } }, DrawCommonPointLabel: function(paneCrosshairInfoList) { var content = this.GetCommonLabelContent(paneCrosshairInfoList); if (_aspxIsExists(content)) { var chartX = _aspxGetAbsoluteX(this.chart.mainElement); var chartY = _aspxGetAbsoluteY(this.chart.mainElement); var labelDiv = this.GetLabelDiv(this.labelIndex); labelDiv.innerHTML = content; if (this.chart.chart.crosshairOptions.crosshairLabelPosition instanceof ASPxClientCrosshairFreePosition) { __aspxShowInFreePosition(labelDiv, this.chart.chart, this.chart.chart.crosshairOptions.crosshairLabelPosition, chartX, chartY); } else { var paneCrosshairInfo; for (var i = 0; i < paneCrosshairInfoList.length; i++) { if (paneCrosshairInfoList[i].pane == this.focusedPane) { paneCrosshairInfo = paneCrosshairInfoList[i]; break; } } var x = paneCrosshairInfo.x + this.chart.chart.crosshairOptions.crosshairLabelPosition.offsetX; if (x + labelDiv.clientWidth > this.chart.GetWidth()) { x -= labelDiv.clientWidth + 2 * this.chart.chart.crosshairOptions.crosshairLabelPosition.offsetX; } var y = paneCrosshairInfo.y - labelDiv.clientHeight - this.chart.chart.crosshairOptions.crosshairLabelPosition.offsetY; if (y < 0) { y += labelDiv.clientHeight + 2 * this.chart.chart.crosshairOptions.crosshairLabelPosition.offsetY; } __aspxChartSetDivPosition(labelDiv, chartX + x, chartY + y); } this.labelIndex++; } }, GetCommonLabelContent: function(paneCrosshairInfoList) { var content = ""; for (var i = 0; i < paneCrosshairInfoList.length; i++) { for (var j = 0; j < paneCrosshairInfoList[i].pointsInfo.length; j++) { content += "" + this.GetLabelHTML(paneCrosshairInfoList[i].pointsInfo[j].point) + ""; } } return content != "" ? "" + content + "
" : null; }, HasIntersection: function(v1, l1, v2, l2) { v1 -= this.indent; l1 += 2 * this.indent; var v12 = v1 + l1; var v22 = v2 + l2; return !(v1 <= v2 && v1 <= v22 && v12 <= v2 && v12 <= v22 || v1 >= v2 && v1 >= v22 && v12 >= v2 && v12 >= v22); }, CalcIntersectionArea: function(bounds1, bounds2) { var x1 = bounds1.x > bounds2.x ? bounds1.x : bounds2.x; var right1 = bounds1.x + bounds1.width; var right2 = bounds2.x + bounds2.width; var x2 = right1 < right2 ? right1 : right2; var y1 = bounds1.y > bounds2.y ? bounds1.y : bounds2.y; var bottom1 = bounds1.y + bounds1.height; var bottom2 = bounds2.y + bounds2.height; var y2 = bottom1 < bottom2 ? bottom1 : bottom2; var width = x2 - x1; var height = y2 - y1; return width * height; }, CheckWithLabelIntersection: function(paneCrosshairInfo, bounds) { var intersectionAreas = []; for (var i = 0; i < paneCrosshairInfo.labelsBounds.length; i++) { var hasXIntersection = this.HasIntersection(bounds.x, bounds.width, paneCrosshairInfo.labelsBounds[i].x, paneCrosshairInfo.labelsBounds[i].width); var hasYIntersection = this.HasIntersection(bounds.y, bounds.height, paneCrosshairInfo.labelsBounds[i].y, paneCrosshairInfo.labelsBounds[i].height); if (hasXIntersection && hasYIntersection) { intersectionAreas.push(this.CalcIntersectionArea(bounds, paneCrosshairInfo.labelsBounds[i])); } else { intersectionAreas.push(0); } } var sum = 0; for (var i = 0; i < intersectionAreas.length; i++) { sum += intersectionAreas[i]; } return sum; }, CheckWithPointIntersection: function(paneCrosshairInfo, bounds, pointsInfo) { for (var i = 0; i < pointsInfo.length; i++) { var x = pointsInfo[i].x - paneCrosshairInfo.pane.boundsLeft; var y = pointsInfo[i].y - paneCrosshairInfo.pane.boundsTop; if (x > bounds.x && x < bounds.x + bounds.width && y > bounds.y && y < bounds.y + bounds.height) { return false; } } return true; }, SetDirection: function(bounds, x, y, dirX, dirY) { bounds.x = x; bounds.x += dirX > 0 ? -10 : 10 - bounds.width; bounds.y = y; bounds.y += dirY > 0 ? 20 : -20 - bounds.height; }, CorrectLabelBounds: function(paneCrosshairInfo, bounds, pointsInfo, x, y, dirX, dirY) { var directions = []; directions.push({ x: dirX, y: dirY }); directions.push({ x: dirX, y: -dirY }); directions.push({ x: -dirX, y: dirY }); directions.push({ x: -dirX, y: -dirY }); var intersections = []; for (var i = 0; i < directions.length; i++) { this.SetDirection(bounds, x, y, directions[i].x, directions[i].y); var intersection = this.CheckWithLabelIntersection(paneCrosshairInfo, bounds); if (intersection == 0 && this.CheckWithPointIntersection(paneCrosshairInfo, bounds, pointsInfo)) { return directions[i]; } else { intersections.push(intersection); } } var min = intersections[0]; var index = 0; for (var i = 1; i < intersections.length; i++) { if (intersections[i] < min) { min = intersections[i]; index = i; } } this.SetDirection(bounds, x, y, directions[index].x, directions[index].y); return directions[index]; }, UpdateCrosshair: function(x, y) { this.focusedPane = this.GetPane(x, y); if (this.focusedPane == null) { this.Hide(); return; } var panes = []; if (!this.chart.chart.crosshairOptions.showOnlyInFocusedPane && ((this.diagram.paneLayoutDirection == "Vertical" && this.isHorizontal) || (this.diagram.paneLayoutDirection == "Horizontal" && !this.isHorizontal))) { panes.push(this.diagram.defaultPane); for (var i = 0; i < this.diagram.panes.length; i++) { panes.push(this.diagram.panes[i]); } } else { panes.push(this.focusedPane); } var paneCrosshairInfoList = []; for (var i = 0; i < panes.length; i++) { paneCrosshairInfoList.push(this.CalculatePaneCrosshairInfo(panes[i], x, y)); } this.hLineIndex = 0; this.hLabelIndex = 0; this.vLineIndex = 0; this.vLabelIndex = 0; this.labelIndex = 0; for (var i = 0; i < paneCrosshairInfoList.length; i++) { this.DrawVerticalElements(paneCrosshairInfoList[i]); this.DrawHorizontalElements(paneCrosshairInfoList[i]); if (this.chart.chart.crosshairOptions.crosshairLabelMode != "ShowCommonForAllSeries") { this.DrawPointLabels(paneCrosshairInfoList[i]); } } if (this.chart.chart.crosshairOptions.crosshairLabelMode == "ShowCommonForAllSeries") { this.DrawCommonPointLabel(paneCrosshairInfoList); } this.ClearDivs(this.hLineIndex, this.vLineIndex, this.hLabelIndex, this.vLabelIndex, this.labelIndex); } }); ASPxPaneCrosshairInfo = _aspxCreateClass(null, { constructor: function(pane, x, y) { this.pane = pane; this.horizontalLines = []; this.verticalLines = []; this.horizontalLabels = []; this.verticalLabels = []; this.pointsInfo = []; this.labelsBounds = []; this.x = x; this.y = y; }, AddLine: function(axisValuePair, isHorizontal, isSingle) { if (isHorizontal) { if ((isSingle || this.horizontalLines.length == 0) && !this.Contains(this.horizontalLines, axisValuePair)) { this.horizontalLines.push(axisValuePair); } } else { if ((isSingle || this.verticalLines.length == 0) && !this.Contains(this.verticalLines, axisValuePair)) { this.verticalLines.push(axisValuePair); } } }, AddLabel: function(axisValuePair, isHorizontal) { if (isHorizontal) { if (!this.Contains(this.horizontalLabels, axisValuePair)) { this.horizontalLabels.push(axisValuePair); } } else { if (!this.Contains(this.verticalLabels, axisValuePair)) { this.verticalLabels.push(axisValuePair); } } }, Contains: function(array, value) { for (var i = 0; i < array.length; i++) { if (array[i].axisName == value.axisName && array[i].internalValue == value.internalValue) { return true; } } return false; } }); ASPxAxisValuePair = _aspxCreateClass(null, { constructor: function(axis, internalValue, screenValue) { this.axis = axis; this.internalValue = internalValue; this.screenValue = screenValue; } }); } /* playback timings (ms): PetaboxLoader3.datanode: 412.811 (4) captures_list: 259.845 esindex: 0.015 PetaboxLoader3.resolve: 65.444 exclusion.robots.policy: 0.219 LoadShardBlock: 225.165 (3) exclusion.robots: 0.234 RedisCDXSource: 10.853 load_resource: 348.217 CDXLines.iter: 19.906 (3) */