UNPKG

scichart

Version:

Fast WebGL JavaScript Charting Library and Framework

988 lines 52.9 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.updateRolloverModifierProps = exports.adjustClusterPositions = exports.mergeOverlappingClusters = exports.splitIntoClusters = exports.calcTooltipPositions = exports.calcTooltipProps = exports.RolloverModifier = exports.TOOLTIP_SPACING = void 0; var classFactory_1 = require("../../Builder/classFactory"); var BaseType_1 = require("../../types/BaseType"); var ChartModifierType_1 = require("../../types/ChartModifierType"); var MousePosition_1 = require("../../types/MousePosition"); var SeriesType_1 = require("../../types/SeriesType"); var tooltip_1 = require("../../utils/tooltip"); var translate_1 = require("../../utils/translate"); var IThemeProvider_1 = require("../Themes/IThemeProvider"); var AnnotationBase_1 = require("../Visuals/Annotations/AnnotationBase"); var LineAnnotation_1 = require("../Visuals/Annotations/LineAnnotation"); var RolloverLegendSvgAnnotation_1 = require("../Visuals/Annotations/RolloverLegendSvgAnnotation"); var RolloverMarkerSvgAnnotation_1 = require("../Visuals/Annotations/RolloverMarkerSvgAnnotation"); var RolloverTooltipSvgAnnotation_1 = require("../Visuals/Annotations/RolloverTooltipSvgAnnotation"); var SciChartSurfaceBase_1 = require("../Visuals/SciChartSurfaceBase"); var DpiHelper_1 = require("../Visuals/TextureManager/DpiHelper"); var ChartModifierBase2D_1 = require("./ChartModifierBase2D"); var constants_1 = require("./constants"); /** @ignore */ exports.TOOLTIP_SPACING = 4; /** * The RolloverModifier provides tooltip and cursor behavior on a 2D {@link SciChartSurface} * within SciChart - High Performance {@link https://www.scichart.com/javascript-chart-features | JavaScript Charts} * @remarks * * To apply the RolloverModifier to a {@link SciChartSurface} and add tooltip behavior, * use the following code: * * ```ts * const sciChartSurface: SciChartSurface; * sciChartSurface.chartModifiers.add(new RolloverModifier()); * ``` */ var RolloverModifier = /** @class */ (function (_super) { __extends(RolloverModifier, _super); /** * Creates an instance of the RolloverModifier * @param options Optional parameters {@link IRolloverModifierOptions} used to configure the modifier */ function RolloverModifier(options) { var _this = this; var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; _this = _super.call(this, options) || this; _this.type = ChartModifierType_1.EChart2DModifierType.Rollover; /** * Gets or sets the legend X offset */ _this.tooltipLegendOffsetX = 0; /** * Gets or sets the legend Y offset */ _this.tooltipLegendOffsetY = 0; /** * Gets or sets the snapToDataPoint flag. If True the {@link RolloverModifier} line snaps to * the nearest data-point of the first visible renderable series */ _this.snapToDataPoint = false; /** * If this is set greater than the default of zero, the toolip will only show values for points in this radius, rather than all points on the vertical line */ _this.hitTestRadius = 0; _this.showRolloverLineProperty = true; _this.showTooltipProperty = true; _this.absoluteXCoord = 0; _this.mousePosition = MousePosition_1.EMousePosition.OutOfCanvas; _this.allowTooltipOverlappingProperty = false; _this.includedSeriesMap = new Map(); _this.hitTestRenderableSeries = _this.hitTestRenderableSeries.bind(_this); _this.placementDivIdProperty = (_a = options === null || options === void 0 ? void 0 : options.placementDivId) !== null && _a !== void 0 ? _a : _this.placementDivIdProperty; _this.rolloverLineAnnotation = _this.createLine(options); if (options === null || options === void 0 ? void 0 : options.tooltipLegendTemplate) { if (typeof options.tooltipLegendTemplate === "string") { _this.typeMap.set("tooltipLegendTemplate", options.tooltipLegendTemplate); options.tooltipLegendTemplate = (0, classFactory_1.getFunction)(BaseType_1.EBaseType.OptionFunction, options.tooltipLegendTemplate); } } _this.tooltipLegendTemplate = (_b = options === null || options === void 0 ? void 0 : options.tooltipLegendTemplate) !== null && _b !== void 0 ? _b : _this.tooltipLegendTemplate; _this.tooltipLegendOffsetX = (_c = options === null || options === void 0 ? void 0 : options.tooltipLegendOffsetX) !== null && _c !== void 0 ? _c : _this.tooltipLegendOffsetX; _this.tooltipLegendOffsetY = (_d = options === null || options === void 0 ? void 0 : options.tooltipLegendOffsetY) !== null && _d !== void 0 ? _d : _this.tooltipLegendOffsetY; if (options === null || options === void 0 ? void 0 : options.tooltipDataTemplate) { if (typeof options.tooltipDataTemplate === "string") { _this.typeMap.set("tooltipDataTemplate", options.tooltipDataTemplate); options.tooltipDataTemplate = (0, classFactory_1.getFunction)(BaseType_1.EBaseType.OptionFunction, options.tooltipDataTemplate); } } _this.tooltipDataTemplateProperty = (_e = options === null || options === void 0 ? void 0 : options.tooltipDataTemplate) !== null && _e !== void 0 ? _e : _this.tooltipDataTemplateProperty; _this.showRolloverLineProperty = (_f = options === null || options === void 0 ? void 0 : options.showRolloverLine) !== null && _f !== void 0 ? _f : _this.showRolloverLineProperty; _this.showTooltipProperty = (_g = options === null || options === void 0 ? void 0 : options.showTooltip) !== null && _g !== void 0 ? _g : _this.showTooltipProperty; _this.legendAnnotation = new RolloverLegendSvgAnnotation_1.RolloverLegendSvgAnnotation({ tooltipLegendTemplate: _this.tooltipLegendTemplate, tooltipLegendOffsetX: _this.tooltipLegendOffsetX, tooltipLegendOffsetY: _this.tooltipLegendOffsetY, xAxisId: _this.xAxisId, yAxisId: _this.yAxisId }); _this.allowTooltipOverlappingProperty = (_h = options === null || options === void 0 ? void 0 : options.allowTooltipOverlapping) !== null && _h !== void 0 ? _h : _this.allowTooltipOverlappingProperty; _this.snapToDataPoint = (_j = options === null || options === void 0 ? void 0 : options.snapToDataPoint) !== null && _j !== void 0 ? _j : _this.snapToDataPoint; _this.hitTestRadius = (_k = options === null || options === void 0 ? void 0 : options.hitTestRadius) !== null && _k !== void 0 ? _k : _this.hitTestRadius; return _this; } RolloverModifier.prototype.createLine = function (options) { var _a, _b, _c; return new LineAnnotation_1.LineAnnotation({ xCoordinateMode: AnnotationBase_1.ECoordinateMode.Pixel, yCoordinateMode: AnnotationBase_1.ECoordinateMode.Pixel, strokeDashArray: options === null || options === void 0 ? void 0 : options.rolloverLineStrokeDashArray, strokeThickness: (_a = options === null || options === void 0 ? void 0 : options.rolloverLineStrokeThickness) !== null && _a !== void 0 ? _a : 2, stroke: (_b = options === null || options === void 0 ? void 0 : options.rolloverLineStroke) !== null && _b !== void 0 ? _b : SciChartSurfaceBase_1.SciChartSurfaceBase.DEFAULT_THEME.cursorLineBrush, xAxisId: this.xAxisId, yAxisId: this.yAxisId, showLabel: (_c = options === null || options === void 0 ? void 0 : options.showAxisLabel) !== null && _c !== void 0 ? _c : false }); }; /** * @inheritDoc */ RolloverModifier.prototype.applyTheme = function (themeProvider) { if (this.parentSurface) { var previousThemeProvider = this.parentSurface.previousThemeProvider; if (this.rolloverLineAnnotation.stroke === previousThemeProvider.cursorLineBrush) { this.rolloverLineAnnotation.stroke = themeProvider.cursorLineBrush; } } }; Object.defineProperty(RolloverModifier.prototype, "rolloverLineStroke", { /** Gets or Sets the color of the vertical rollover line as an html color code */ get: function () { return this.rolloverLineAnnotation.stroke; }, /** Gets or Sets the color of the vertical rollover line as an html color code */ set: function (rolloverLineStroke) { this.rolloverLineAnnotation.stroke = rolloverLineStroke; this.notifyPropertyChanged(constants_1.PROPERTY.STROKE); }, enumerable: false, configurable: true }); Object.defineProperty(RolloverModifier.prototype, "rolloverLineStrokeThickness", { /** Gets or Sets the thickness of the vertical rollover line */ get: function () { return this.rolloverLineAnnotation.strokeThickness; }, /** Gets or Sets the thickness of the vertical rollover line */ set: function (rolloverLineStrokeThickness) { this.rolloverLineAnnotation.strokeThickness = rolloverLineStrokeThickness; this.notifyPropertyChanged(constants_1.PROPERTY.STROKE_THICKNESS); }, enumerable: false, configurable: true }); Object.defineProperty(RolloverModifier.prototype, "rolloverLineStrokeDashArray", { /** Gets or Sets the dash array of the vertical rollover line */ get: function () { return this.rolloverLineAnnotation.strokeDashArray; }, /** Gets or Sets the dash array of the vertical rollover line */ set: function (rolloverLineStrokeDashArray) { this.rolloverLineAnnotation.strokeDashArray = rolloverLineStrokeDashArray; this.notifyPropertyChanged(constants_1.PROPERTY.STROKE_DASH_ARRAY); }, enumerable: false, configurable: true }); Object.defineProperty(RolloverModifier.prototype, "showRolloverLine", { /** Gets or Sets whether to show the vertical rollover line. Default true */ get: function () { return this.showRolloverLineProperty; }, /** Gets or Sets whether to show the vertical rollover line. Default true */ set: function (showRolloverLine) { this.showRolloverLineProperty = showRolloverLine; this.notifyPropertyChanged(constants_1.PROPERTY.SHOW_ROLLOVER_LINE); }, enumerable: false, configurable: true }); Object.defineProperty(RolloverModifier.prototype, "tooltipDataTemplate", { /** Gets or Sets the tooltipDataTemplate, which allows you to customize content for the tooltip */ get: function () { return this.tooltipDataTemplateProperty; }, /** Gets or Sets the tooltipDataTemplate, which allows you to customize content for the tooltip */ set: function (value) { this.tooltipDataTemplateProperty = value; this.notifyPropertyChanged(constants_1.PROPERTY.TOOLTIP_DATA_TEMPLATE); }, enumerable: false, configurable: true }); Object.defineProperty(RolloverModifier.prototype, "showTooltip", { /** Gets or Sets whether to show the tooltip. Default true */ get: function () { return this.showTooltipProperty; }, /** Gets or Sets whether to show the tooltip. Default true */ set: function (value) { this.showTooltipProperty = value; this.notifyPropertyChanged(constants_1.PROPERTY.SHOW_TOOLTIP); }, enumerable: false, configurable: true }); Object.defineProperty(RolloverModifier.prototype, "allowTooltipOverlapping", { /** Gets or Sets if tooltips for multiple series are allowed to overlap. Default false */ get: function () { return this.allowTooltipOverlappingProperty; }, /** Gets or Sets if tooltips for multiple series are allowed to overlap. Default false */ set: function (value) { this.allowTooltipOverlappingProperty = value; this.notifyPropertyChanged(constants_1.PROPERTY.ALLOW_TOOLTIP_OVERLAPPING); }, enumerable: false, configurable: true }); /** * @inheritDoc */ RolloverModifier.prototype.onAttach = function () { var _this = this; _super.prototype.onAttach.call(this); this.addLineAnnotationToSurface(); this.parentSurface.modifierAnnotations.add(this.legendAnnotation); this.getIncludedRenderableSeries().forEach(function (rs) { return _this.addSeriesAnnotationsToParentSurface(rs); }); }; RolloverModifier.prototype.addLineAnnotationToSurface = function () { this.parentSurface.modifierAnnotations.add(this.rolloverLineAnnotation); }; /** * @inheritDoc */ RolloverModifier.prototype.onDetach = function () { var _this = this; _super.prototype.onDetach.call(this); this.parentSurface.modifierAnnotations.remove(this.rolloverLineAnnotation, true); this.parentSurface.modifierAnnotations.remove(this.legendAnnotation); this.getIncludedRenderableSeries().forEach(function (rs) { return _this.removeSeriesAnnotationsFromParentSurface(rs); }); }; /** * @inheritDoc */ RolloverModifier.prototype.onAttachSeries = function (rs) { _super.prototype.onAttachSeries.call(this, rs); if (this.getIncludedRenderableSeries().includes(rs)) { this.addSeriesAnnotationsToParentSurface(rs); this.legendAnnotation.seriesInfos = this.getSeriesInfos(); } }; /** * @inheritDoc */ RolloverModifier.prototype.onDetachSeries = function (rs) { _super.prototype.onDetachSeries.call(this, rs); this.removeSeriesAnnotationsFromParentSurface(rs); }; /** * @inheritDoc */ RolloverModifier.prototype.modifierMouseMove = function (args) { // If this is on a subchart, only respond to events from the active subchart if (this.parentSurface.isSubSurface && !args.isActiveSubChartEvent) return; this.activePointerEvents.set(args.pointerId, args); _super.prototype.modifierMouseMove.call(this, args); var translatedMousePoint; if (!this.mousePoint) { this.mousePosition = MousePosition_1.EMousePosition.OutOfCanvas; } else { translatedMousePoint = (0, translate_1.translateFromCanvasToSeriesViewRect)(this.mousePoint, this.parentSurface.seriesViewRect); if (!translatedMousePoint) { this.mousePosition = MousePosition_1.EMousePosition.AxisArea; } else { this.mousePosition = MousePosition_1.EMousePosition.SeriesArea; } } var isActionAllowed = this.getIsActionAllowed(args); if (isActionAllowed) { this.update(); } }; /** * @inheritDoc */ RolloverModifier.prototype.modifierMouseLeave = function (args) { _super.prototype.modifierMouseLeave.call(this, args); this.mousePosition = MousePosition_1.EMousePosition.OutOfCanvas; this.update(); }; /** * @inheritDoc */ RolloverModifier.prototype.onParentSurfaceRendered = function () { this.update(); }; /** * @inheritDoc */ RolloverModifier.prototype.includeSeries = function (series, isIncluded) { var _a; var valueChanged = (this.includedSeriesMap.get(series) === undefined && !isIncluded) || (this.includedSeriesMap.get(series) === true && !isIncluded) || (this.includedSeriesMap.get(series) === false && isIncluded); if (valueChanged) { this.includedSeriesMap.set(series, isIncluded); if (this.isAttached) { if (isIncluded === true) { this.addSeriesAnnotationsToParentSurface(series); } if (isIncluded === false) { this.removeSeriesAnnotationsFromParentSurface(series); } if (this.parentSurface) { this.legendAnnotation.seriesInfos = this.getSeriesInfos(); } (_a = this.parentSurface) === null || _a === void 0 ? void 0 : _a.invalidateElement(); } } }; /** * @inheritDoc */ RolloverModifier.prototype.getIncludedRenderableSeries = function () { var _this = this; var regularSeries = this.parentSurface.renderableSeries .asArray() .filter(function (rs) { return !rs.isStacked && rs.isVisible && rs.rolloverModifierProps.showRollover && _this.testIsIncludedSeries(rs); }); var stackedSeries = this.parentSurface.renderableSeries.asArray().filter(function (rs) { return rs.isStacked; }); var result = regularSeries; stackedSeries.forEach(function (rs) { rs.getVisibleSeries().forEach(function (childRs) { if (childRs.rolloverModifierProps.showRollover && _this.testIsIncludedSeries(childRs)) { result.push(childRs); } }); }); return result; }; /** * Override hitTestRenderableSeries and add a custom logic * @param rs * @param mousePoint */ RolloverModifier.prototype.hitTestRenderableSeries = function (rs, mousePoint) { if (!mousePoint) { return undefined; } if (this.hitTestRadius <= 0) { return rs.hitTestProvider.hitTestXSlice(mousePoint.x, mousePoint.y); } else { return rs.hitTestProvider.hitTestDataPoint(mousePoint.x, mousePoint.y, this.hitTestRadius); } }; /** * Returns current mouse position */ RolloverModifier.prototype.getMousePosition = function () { return this.mousePosition; }; /** @inheritDoc */ RolloverModifier.prototype.toJSON = function () { var _a, _b; var json = _super.prototype.toJSON.call(this); var options = { snapToDataPoint: this.snapToDataPoint, placementDivId: this.placementDivId, hitTestRadius: this.hitTestRadius, allowTooltipOverlapping: this.allowTooltipOverlapping, rolloverLineStrokeDashArray: this.rolloverLineStrokeDashArray, rolloverLineStroke: this.rolloverLineStroke, rolloverLineStrokeThickness: this.rolloverLineStrokeThickness, showRolloverLine: this.showRolloverLine, showTooltip: this.showTooltip, showAxisLabel: (_b = (_a = this.rolloverLineAnnotation) === null || _a === void 0 ? void 0 : _a.showLabel) !== null && _b !== void 0 ? _b : false, tooltipDataTemplate: this.typeMap.get("tooltipDataTemplate"), tooltipLegendOffsetX: this.tooltipLegendOffsetX, tooltipLegendOffsetY: this.tooltipLegendOffsetY, tooltipLegendTemplate: this.typeMap.get("tooltipLegendTemplate") }; Object.assign(json.options, options); return json; }; /** * Called internally to adjust the positions of tooltips if there are overlaps, or if it is a vertical chart * @param tooltipArray * @param allowTooltipOverlapping * @param spacing * @param seriesViewRect * @param pixelRatio * @param isVerticalChart * @returns TTooltipProps[] */ RolloverModifier.prototype.CalculateTooltipPositions = function (tooltipArray, allowTooltipOverlapping, spacing, seriesViewRect, pixelRatio, isVerticalChart) { if (isVerticalChart === void 0) { isVerticalChart = false; } return (0, exports.calcTooltipPositions)(tooltipArray, allowTooltipOverlapping, spacing, seriesViewRect, pixelRatio, isVerticalChart); }; /** @inheritDoc */ RolloverModifier.prototype.notifyPropertyChanged = function (propertyName) { _super.prototype.notifyPropertyChanged.call(this, propertyName); if (propertyName === constants_1.PROPERTY.X_AXIS_ID) { this.rolloverLineAnnotation.xAxisId = this.xAxisId; this.legendAnnotation.xAxisId = this.xAxisId; } if (propertyName === constants_1.PROPERTY.Y_AXIS_ID) { this.rolloverLineAnnotation.yAxisId = this.yAxisId; this.legendAnnotation.yAxisId = this.yAxisId; } }; RolloverModifier.prototype.isVerticalChart = function () { var _a, _b; var xAxis = ((_a = this.parentSurface) === null || _a === void 0 ? void 0 : _a.getXAxisById(this.xAxisId)) || ((_b = this.parentSurface) === null || _b === void 0 ? void 0 : _b.xAxes.get(0)); if (xAxis) { return xAxis.isVerticalChart; } return false; }; RolloverModifier.prototype.removeSeriesAnnotationsFromParentSurface = function (rs) { var _this = this; if (!this.parentSurface) return; if (rs.isStacked) { var stackedSeries = rs; stackedSeries.asArray().forEach(function (childRs) { _this.parentSurface.modifierAnnotations.remove(_this.getRolloverProps(childRs).marker); _this.parentSurface.modifierAnnotations.remove(_this.getRolloverProps(childRs).tooltip); _this.getRolloverProps(childRs).delete(); }); } else { this.parentSurface.modifierAnnotations.remove(this.getRolloverProps(rs).marker); this.parentSurface.modifierAnnotations.remove(this.getRolloverProps(rs).tooltip); this.getRolloverProps(rs).delete(); if (rs.type === SeriesType_1.ESeriesType.BandSeries) { this.parentSurface.modifierAnnotations.remove(this.getRolloverProps1(rs).marker); this.parentSurface.modifierAnnotations.remove(this.getRolloverProps1(rs).tooltip); this.getRolloverProps1(rs).delete(); } } }; /** * @param rs */ RolloverModifier.prototype.addSeriesAnnotationsToParentSurface = function (rs) { if (!this.parentSurface || rs.type === SeriesType_1.ESeriesType.StackedMountainCollection || rs.type === SeriesType_1.ESeriesType.StackedColumnCollection) { return; } this.getRolloverProps(rs).rolloverModifier = this; createAnnotations(rs, this.getRolloverProps(rs), this.getRolloverProps1(rs), this.placementDivIdProperty); var marker = this.getRolloverProps(rs).marker; if (!this.parentSurface.modifierAnnotations.contains(marker)) { this.parentSurface.modifierAnnotations.add(this.getRolloverProps(rs).marker); this.parentSurface.modifierAnnotations.add(this.getRolloverProps(rs).tooltip); if (rs.type === SeriesType_1.ESeriesType.BandSeries) { this.getRolloverProps1(rs).rolloverModifier = this; this.parentSurface.modifierAnnotations.add(this.getRolloverProps1(rs).marker); this.parentSurface.modifierAnnotations.add(this.getRolloverProps1(rs).tooltip); } } }; RolloverModifier.prototype.getRolloverProps = function (rs) { return rs.rolloverModifierProps; }; RolloverModifier.prototype.getRolloverProps1 = function (rs) { return rs.rolloverModifierProps1; }; RolloverModifier.prototype.update = function () { this.updateLine(); this.updateSeriesAnnotations(); if (this.tooltipLegendTemplate) { this.legendAnnotation.seriesInfos = this.getSeriesInfos(); } }; RolloverModifier.prototype.updateLine = function () { if (this.mousePosition !== MousePosition_1.EMousePosition.SeriesArea) { this.rolloverLineAnnotation.isHidden = true; return; } if (!this.showRolloverLineProperty) { this.rolloverLineAnnotation.isHidden = true; return; } if (this.snapToDataPoint) { var firstSeries = this.getIncludedRenderableSeries()[0]; if (firstSeries) { var hitTestInfo = this.hitTestRenderableSeries(firstSeries, this.mousePoint); if (hitTestInfo && hitTestInfo.isWithinDataBounds) { this.rolloverLineAnnotation.isHidden = false; var x = (0, translate_1.translateToNotScaled)(hitTestInfo.xCoord); this.rolloverLineAnnotation.x1 = x; this.rolloverLineAnnotation.x2 = x; this.rolloverLineAnnotation.y1 = 0; this.rolloverLineAnnotation.y2 = this.isVerticalChart() ? (0, translate_1.translateToNotScaled)(this.parentSurface.seriesViewRect.right) : (0, translate_1.translateToNotScaled)(this.parentSurface.seriesViewRect.bottom); } else { this.rolloverLineAnnotation.isHidden = true; } } else { this.rolloverLineAnnotation.isHidden = true; } } else { this.rolloverLineAnnotation.isHidden = false; var translatedMousePoint = (0, translate_1.translateFromCanvasToSeriesViewRect)(this.mousePoint, this.parentSurface.seriesViewRect); if (translatedMousePoint) { var x = (0, translate_1.translateToNotScaled)(translatedMousePoint.x); var y = (0, translate_1.translateToNotScaled)(translatedMousePoint.y); if (this.isVerticalChart()) { this.rolloverLineAnnotation.x1 = y; this.rolloverLineAnnotation.x2 = y; this.rolloverLineAnnotation.y1 = 0; this.rolloverLineAnnotation.y2 = (0, translate_1.translateToNotScaled)(this.parentSurface.seriesViewRect.right); } else { this.rolloverLineAnnotation.x1 = x; this.rolloverLineAnnotation.x2 = x; this.rolloverLineAnnotation.y1 = 0; this.rolloverLineAnnotation.y2 = (0, translate_1.translateToNotScaled)(this.parentSurface.seriesViewRect.bottom); } } } }; /** * @description Update Markers and Tooltips */ RolloverModifier.prototype.updateSeriesAnnotations = function () { var _this = this; var rsList = this.getIncludedRenderableSeries(); rsList.forEach(function (rs) { var props = _this.getRolloverProps(rs); if (!props.marker) { _this.addSeriesAnnotationsToParentSurface(rs); } props.marker.suspendInvalidate(); props.tooltip.suspendInvalidate(); props.marker.isHidden = true; props.tooltip.isHidden = true; props.tooltip.x1 = undefined; props.tooltip.y1 = undefined; // TODO should be more general than looking at series type if (rs.type === SeriesType_1.ESeriesType.BandSeries) { props.marker.suspendInvalidate(); props.tooltip.suspendInvalidate(); props.marker.isHidden = true; props.tooltip.isHidden = true; props.tooltip.x1 = undefined; props.tooltip.y1 = undefined; } }); if (this.mousePosition !== MousePosition_1.EMousePosition.SeriesArea) { rsList.forEach(function (rs) { var props = _this.getRolloverProps(rs); props.marker.resumeInvalidate(); props.tooltip.resumeInvalidate(); if (rs.type === SeriesType_1.ESeriesType.BandSeries) { // leave for now _this.getRolloverProps1(rs).marker.resumeInvalidate(); _this.getRolloverProps1(rs).tooltip.resumeInvalidate(); } }); return; } var tooltipArray = []; var height = this.isVerticalChart() ? this.parentSurface.seriesViewRect.width : this.parentSurface.seriesViewRect.height; rsList.forEach(function (rs, index) { var hitTestInfo = _this.hitTestRenderableSeries(rs, _this.mousePoint); if (hitTestInfo) { if ((rs.type !== SeriesType_1.ESeriesType.StackedColumnSeries && _this.hitTestRadius === 0) || hitTestInfo.isHit) { var isVisible = 0 <= hitTestInfo.yCoord && hitTestInfo.yCoord <= height; if (isVisible) { _this.absoluteXCoord = _this.isVerticalChart() ? hitTestInfo.yCoord : hitTestInfo.xCoord; var absoluteYCoord = _this.isVerticalChart() ? hitTestInfo.xCoord : hitTestInfo.yCoord; var tooltipProps = (0, exports.calcTooltipProps)(index, rs, _this.getRolloverProps(rs), _this.parentSurface.seriesViewRect, hitTestInfo.xValue, hitTestInfo.yValue, _this.absoluteXCoord, absoluteYCoord, hitTestInfo, DpiHelper_1.DpiHelper.PIXEL_RATIO, false, _this.isVerticalChart()); if (tooltipProps) tooltipArray.push(tooltipProps); } } if (rs.type === SeriesType_1.ESeriesType.BandSeries) { var isVisibleY1 = 0 <= hitTestInfo.y1Coord && hitTestInfo.y1Coord <= height; if (isVisibleY1) { var absoluteXCoord = _this.isVerticalChart() ? hitTestInfo.y1Coord : hitTestInfo.xCoord; var absoluteYCoord = _this.isVerticalChart() ? hitTestInfo.xCoord : hitTestInfo.y1Coord; var tooltipY1Props = (0, exports.calcTooltipProps)(index, rs, _this.getRolloverProps1(rs), _this.parentSurface.seriesViewRect, hitTestInfo.xValue, hitTestInfo.y1Value, absoluteXCoord, absoluteYCoord, hitTestInfo, DpiHelper_1.DpiHelper.PIXEL_RATIO, true, _this.isVerticalChart()); if (tooltipY1Props) tooltipArray.push(tooltipY1Props); } } } }); var orderedTooltipArray; if (this.isVerticalChart()) { orderedTooltipArray = tooltipArray.sort(function (a, b) { return (a.xCoord > b.xCoord ? 1 : b.xCoord > a.xCoord ? -1 : 0); }); } else { orderedTooltipArray = tooltipArray.sort(function (a, b) { return (a.yCoord > b.yCoord ? 1 : b.yCoord > a.yCoord ? -1 : 0); }); } var tooltipPositions = this.CalculateTooltipPositions(orderedTooltipArray, this.allowTooltipOverlapping, exports.TOOLTIP_SPACING * DpiHelper_1.DpiHelper.PIXEL_RATIO, this.parentSurface.seriesViewRect, DpiHelper_1.DpiHelper.PIXEL_RATIO, this.isVerticalChart()); tooltipPositions.forEach(function (el) { var rs = rsList[el.index]; var showTooltip = _this.showTooltip && el.seriesInfo.isHit; var showMarker = el.seriesInfo.isHit; if (el.isY1) { (0, exports.updateRolloverModifierProps)(_this.getRolloverProps1(rs), rs, el, showTooltip, showMarker, _this.placementDivId); } else { (0, exports.updateRolloverModifierProps)(_this.getRolloverProps(rs), rs, el, showTooltip, showMarker, _this.placementDivId); } }); rsList.forEach(function (rs) { _this.getRolloverProps(rs).marker.resumeInvalidate(); _this.getRolloverProps(rs).tooltip.resumeInvalidate(); if (rs.type === SeriesType_1.ESeriesType.BandSeries) { _this.getRolloverProps1(rs).marker.resumeInvalidate(); _this.getRolloverProps1(rs).tooltip.resumeInvalidate(); } }); }; /** * Test if the series is included or excluded, by default it is included * @param series * @private */ RolloverModifier.prototype.testIsIncludedSeries = function (series) { return this.includedSeriesMap.get(series) !== false; }; RolloverModifier.prototype.getSeriesInfos = function () { var _this = this; return this.getIncludedRenderableSeries() .map(function (rs) { var hitTestInfo = _this.hitTestRenderableSeries(rs, _this.mousePoint); if (!hitTestInfo) { return undefined; } return rs.getSeriesInfo(hitTestInfo); }) .filter(function (rs) { return rs !== undefined; }); }; Object.defineProperty(RolloverModifier.prototype, "placementDivId", { /** * Gets or sets the parent div element reference or id for the Tooltip */ get: function () { return this.placementDivIdProperty; }, /** * Gets or sets the parent div element reference or id for the Tooltip */ set: function (value) { var _this = this; var _a; if (this.placementDivIdProperty !== value) { this.placementDivIdProperty = value; (_a = this.parentSurface) === null || _a === void 0 ? void 0 : _a.renderableSeries.asArray().forEach(function (rs) { _this.getRolloverProps(rs).tooltip.placementDivId = _this.placementDivIdProperty; _this.getRolloverProps1(rs).tooltip.placementDivId = _this.placementDivIdProperty; }); } }, enumerable: false, configurable: true }); return RolloverModifier; }(ChartModifierBase2D_1.ChartModifierBase2D)); exports.RolloverModifier = RolloverModifier; /** * @ignore * @description Used internally, calculates tooltip props * @param index * @param rs * @param rolloverProps * @param seriesViewRect * @param xValue * @param yValue * @param absoluteXCoord * @param absoluteYCoord * @param hitTestInfo * @param pixelRatio * @param isY1 */ var calcTooltipProps = function (index, rs, rolloverProps, seriesViewRect, xValue, yValue, absoluteXCoord, absoluteYCoord, hitTestInfo, pixelRatio, isY1, isVerticalChart) { if (isY1 === void 0) { isY1 = false; } if (isVerticalChart === void 0) { isVerticalChart = false; } // This check is done in calling code // const visibleRange = rs.yAxis.visibleRange; // const isVisible = visibleRange.min <= yValue && yValue <= visibleRange.max); // if (isVisible) { var seriesInfo = rs.getSeriesInfo(hitTestInfo); var width = rolloverProps.tooltip.width; var scaledWidth = width * pixelRatio; var height = rolloverProps.tooltip.height; var scaledHeight = height * pixelRatio; var distTop = absoluteYCoord; var distBottom = seriesViewRect.height - absoluteYCoord; var defaultVerticalShift = 5 * pixelRatio; var xCoordShift = seriesViewRect.width - absoluteXCoord < scaledWidth ? -width : 5; var yCoordShift = isVerticalChart ? defaultVerticalShift : -height / 2; if (isVerticalChart) { if (distBottom < scaledHeight + defaultVerticalShift) { yCoordShift = ((scaledHeight + defaultVerticalShift) / pixelRatio) * -1; } } else { if (distTop < scaledHeight / 2) { yCoordShift = -distTop / pixelRatio; } else if (distBottom < scaledHeight / 2) { yCoordShift = -(scaledHeight - distBottom) / pixelRatio; } } var newRecord = { index: index, isY1: isY1, xValue: xValue, yValue: yValue, xCoord: absoluteXCoord, yCoord: absoluteYCoord, hitTestPointValues: hitTestInfo.hitTestPointValues, isCategoryAxis: hitTestInfo.isCategoryAxis, xCoordShift: xCoordShift, yCoordShift: yCoordShift, height: scaledHeight, width: scaledWidth, seriesInfo: seriesInfo }; return newRecord; }; exports.calcTooltipProps = calcTooltipProps; /** * @ignore * @description Used internally, calculates tooltip positions to avoid overlapping * @param tooltipArray * @param allowTooltipOverlapping * @param spacing * @param seriesViewRect * @param pixelRatio * @param isVerticalChart */ var calcTooltipPositions = function (tooltipArray, allowTooltipOverlapping, spacing, seriesViewRect, pixelRatio, isVerticalChart) { if (isVerticalChart === void 0) { isVerticalChart = false; } var positionProperties = (0, tooltip_1.getTooltipPositionProperties)(isVerticalChart); // centering for vertical charts if (isVerticalChart) { tooltipArray.forEach(function (tooltip) { var halfWidth = tooltip.width / 2 / pixelRatio; if (tooltip.xCoord > halfWidth) { tooltip[positionProperties.shiftPropertyName] = -(tooltip.width / 2) / pixelRatio; } }); } var hasOverlap = (0, tooltip_1.checkHasOverlap)(tooltipArray, spacing, pixelRatio, positionProperties); var length = tooltipArray.length; if (!allowTooltipOverlapping && length >= 2 && hasOverlap) { var clusters = (0, exports.splitIntoClusters)(tooltipArray, spacing, pixelRatio, positionProperties); clusters = (0, exports.mergeOverlappingClusters)(clusters, spacing, pixelRatio, positionProperties); clusters.forEach(function (cluster) { if (cluster.length >= 2) { var spreadMap_1 = (0, tooltip_1.spreadTooltips)(cluster, pixelRatio, positionProperties, spacing, seriesViewRect); cluster.forEach(function (tooltip) { tooltip[positionProperties.shiftPropertyName] = spreadMap_1.get(tooltip.index); }); } }); // After positioning, check for cluster overlap (0, exports.adjustClusterPositions)(clusters, spacing, pixelRatio, positionProperties, seriesViewRect); } return tooltipArray; }; exports.calcTooltipPositions = calcTooltipPositions; /** * @description Splits tooltips into clusters based on their proximity * @param tooltipArray * @param spacing * @param pixelRatio * @param positionProperties * @returns Array of tooltip clusters */ var splitIntoClusters = function (tooltipArray, spacing, pixelRatio, positionProperties) { var sorted = __spreadArray([], tooltipArray, true).sort(function (a, b) { return a[positionProperties.coordPropertyName] - b[positionProperties.coordPropertyName]; }); var clusters = []; var currentCluster = []; for (var _i = 0, sorted_1 = sorted; _i < sorted_1.length; _i++) { var tooltip = sorted_1[_i]; if (currentCluster.length === 0) { currentCluster.push(tooltip); } else { var currentStart = (0, tooltip_1.getStartPoint)(tooltip[positionProperties.coordPropertyName], tooltip[positionProperties.shiftPropertyName], pixelRatio); var lastTooltip = currentCluster[currentCluster.length - 1]; var lastEnd = (0, tooltip_1.getEndPoint)(lastTooltip[positionProperties.coordPropertyName], lastTooltip[positionProperties.shiftPropertyName], pixelRatio, lastTooltip[positionProperties.sizePropertyName]); if (currentStart < lastEnd + spacing / pixelRatio) { currentCluster.push(tooltip); } else { clusters.push(currentCluster); currentCluster = [tooltip]; } } } if (currentCluster.length > 0) { clusters.push(currentCluster); } return clusters; }; exports.splitIntoClusters = splitIntoClusters; /** * Merges clusters that might overlap after internal positioning * @param clusters Array of tooltip clusters * @param spacing Minimum spacing between tooltips * @param pixelRatio Display pixel ratio * @param positionProperties Position property names * @returns Merged clusters array */ var mergeOverlappingClusters = function (clusters, spacing, pixelRatio, positionProperties) { if (clusters.length <= 1) return clusters; var merged = true; while (merged) { merged = false; for (var i = 0; i < clusters.length - 1; i++) { var cluster1 = clusters[i]; var cluster2 = clusters[i + 1]; // rightmost tooltip in 1st cluster var rightmost = cluster1.reduce(function (max, tooltip) { var end = (0, tooltip_1.getEndPoint)(tooltip[positionProperties.coordPropertyName], tooltip[positionProperties.shiftPropertyName], pixelRatio, tooltip[positionProperties.sizePropertyName]); return end > max ? end : max; }, -Infinity); // leftmost tooltip in 2nd cluster var leftmost = cluster2.reduce(function (min, tooltip) { var start = (0, tooltip_1.getStartPoint)(tooltip[positionProperties.coordPropertyName], tooltip[positionProperties.shiftPropertyName], pixelRatio); return start < min ? start : min; }, Infinity); var avgWidth1 = cluster1.reduce(function (sum, t) { return sum + t[positionProperties.sizePropertyName] / pixelRatio; }, 0) / cluster1.length; var avgWidth2 = cluster2.reduce(function (sum, t) { return sum + t[positionProperties.sizePropertyName] / pixelRatio; }, 0) / cluster2.length; var safetyMargin = (spacing * 2) / pixelRatio + Math.max(avgWidth1, avgWidth2) * 0.5; if (leftmost - rightmost < safetyMargin) { // merge clusters[i] = __spreadArray(__spreadArray([], cluster1, true), cluster2, true); clusters.splice(i + 1, 1); merged = true; break; } } } return clusters; }; exports.mergeOverlappingClusters = mergeOverlappingClusters; /** * Adjust positioning of entire clusters if they overlap after internal positioning * @param clusters Array of tooltip clusters * @param spacing Minimum spacing between tooltips * @param pixelRatio Display pixel ratio * @param positionProperties Position property names * @param seriesViewRect Chart view rectangle */ var adjustClusterPositions = function (clusters, spacing, pixelRatio, positionProperties, seriesViewRect) { if (clusters.length <= 1) return; // Sort clusters by their leftmost point clusters.sort(function (a, b) { var aLeft = Math.min.apply(Math, a.map(function (t) { return (0, tooltip_1.getStartPoint)(t[positionProperties.coordPropertyName], t[positionProperties.shiftPropertyName], pixelRatio); })); var bLeft = Math.min.apply(Math, b.map(function (t) { return (0, tooltip_1.getStartPoint)(t[positionProperties.coordPropertyName], t[positionProperties.shiftPropertyName], pixelRatio); })); return aLeft - bLeft; }); var _loop_1 = function (i) { var currentCluster = clusters[i]; var nextCluster = clusters[i + 1]; // Find rightmost point of current cluster var currentRight = Math.max.apply(Math, currentCluster.map(function (t) { return (0, tooltip_1.getEndPoint)(t[positionProperties.coordPropertyName], t[positionProperties.shiftPropertyName], pixelRatio, t[positionProperties.sizePropertyName]); })); // Find leftmost point of next cluster var nextLeft = Math.min.apply(Math, nextCluster.map(function (t) { return (0, tooltip_1.getStartPoint)(t[positionProperties.coordPropertyName], t[positionProperties.shiftPropertyName], pixelRatio); })); // If clusters overlap or are too close if (nextLeft < currentRight + spacing / pixelRatio) { var overlap_1 = currentRight + spacing / pixelRatio - nextLeft; // Check if we have room to shift right var nextClusterWidth = Math.max.apply(Math, nextCluster.map(function (t) { return (0, tooltip_1.getEndPoint)(t[positionProperties.coordPropertyName], t[positionProperties.shiftPropertyName], pixelRatio, t[positionProperties.sizePropertyName]); })) - nextLeft; var chartRight = seriesViewRect.x + seriesViewRect.width; var rightBoundary = (chartRight - nextLeft - nextClusterWidth) * pixelRatio; if (overlap_1 * pixelRatio <= rightBoundary) { // We have room to shift the next cluster right nextCluster.forEach(function (tooltip) { var currentShift = tooltip[positionProperties.shiftPropertyName] || 0; tooltip[positionProperties.shiftPropertyName] = currentShift + overlap_1; }); } else { // Not enough room to shift right fully, distribute the adjustment var maxRightShift_1 = Math.max(0, rightBoundary / pixelRatio); var remainingShift = overlap_1 - maxRightShift_1; // Shift next cluster right as much as possible if (maxRightShift_1 > 0) { nextCluster.forEach(function (tooltip) { var currentShift = tooltip[positionProperties.shiftPropertyName] || 0; tooltip[positionProperties.shiftPropertyName] = currentShift + maxRightShift_1; }); } // Shift current cluster left with the remaining amount if (remainingShift > 0) { // Check if we have room to shift left var currentClusterLeft = Math.min.apply(Math, currentCluster.map(function (t) { return (0, tooltip_1.getStartPoint)(t[positionProperties.coordPropertyName], t[positionProperties.shiftPropertyName], pixelRatio); })); var leftBoundary = (currentClusterLeft - seriesViewRect.x) * pixelRatio; var maxLeftShift_1 = Math.min(remainingShift, leftBoundary / pixelRatio); if (maxLeftShift_1 > 0) { currentCluster.forEach(function (tooltip) { var currentShift = tooltip[positionProperties.shiftPropertyName] || 0; tooltip[positionProperties.shiftPropertyName] = currentShift - maxLeftShift_1; }); } } } } }; // Check for overlaps between clusters and adjust for (var i = 0; i < clusters.length - 1; i++) { _loop_1(i); } }; exports.adjustClusterPositions = adjustClusterPositions; /** * @ignore * @description Creates MarkerAnnotation and TooltipAnnotation and assigns to rolloverSeries properties * @param rs RenderableSeries */ var createAnnotations = function (rs, rolloverModifierProps, rolloverModifierProps1, placementDivId) { var _a, _b, _c, _d; if (!rolloverModifierProps.marker) { rolloverModifierProps.marker = new RolloverMarkerSvgAnnotation_1.RolloverMarkerSvgAnnotation(rolloverModifierProps); rolloverModifierProps.marker.xAxisId = rs.xAxisId; rolloverModifierProps.marker.yAxisId = rs.yAxisId; } if (!rolloverModifierProps.tooltip) { rolloverModifierProps.tooltipTitle = (_b = (_a = rolloverModifierProps.tooltipTitle) !== null && _a !== void 0 ? _a : rs.getDataSeriesName()) !== null && _b !== void 0 ? _b : ""; rolloverModifierProps.tooltipColor = rolloverModifierProps.tooltipColor; rolloverModifierProps.shadowColor = rs.parentSurface.themeProvider.s