| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634 |
- /**
- * DevExtreme (viz/chart_components/tracker.js)
- * Version: 19.1.16
- * Build date: Tue Oct 18 2022
- *
- * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
- * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
- */
- "use strict";
- var domAdapter = require("../../core/dom_adapter");
- var eventsEngine = require("../../events/core/events_engine");
- var clickEvent = require("../../events/click");
- var extend = require("../../core/utils/extend").extend;
- var each = require("../../core/utils/iterator").each;
- var consts = require("../components/consts");
- var eventsConsts = consts.events;
- var vizUtils = require("../core/utils");
- var pointerEvents = require("../../events/pointer");
- var holdEvent = require("../../events/hold");
- var addNamespace = require("../../events/utils").addNamespace;
- var isDefined = require("../../core/utils/type").isDefined;
- var _normalizeEnum = require("../core/utils").normalizeEnum;
- var _floor = Math.floor;
- var _each = each;
- var _noop = require("../../core/utils/common").noop;
- var HOVER_STATE = consts.states.hoverMark;
- var NORMAL_STATE = consts.states.normalMark;
- var EVENT_NS = "dxChartTracker";
- var DOT_EVENT_NS = "." + EVENT_NS;
- var POINTER_ACTION = addNamespace([pointerEvents.down, pointerEvents.move], EVENT_NS);
- var LEGEND_CLICK = "legendClick";
- var SERIES_CLICK = "seriesClick";
- var POINT_CLICK = "pointClick";
- var POINT_DATA = "chart-data-point";
- var SERIES_DATA = "chart-data-series";
- var ARG_DATA = "chart-data-argument";
- var DELAY = 100;
- var NONE_MODE = "none";
- var ALL_ARGUMENT_POINTS_MODE = "allargumentpoints";
- var INCLUDE_POINTS_MODE = "includepoints";
- var EXLUDE_POINTS_MODE = "excludepoints";
- var LEGEND_HOVER_MODES = [INCLUDE_POINTS_MODE, EXLUDE_POINTS_MODE, NONE_MODE];
- function getData(event, dataKey) {
- var target = event.target;
- return ("tspan" === target.tagName ? target.parentNode : target)[dataKey]
- }
- function eventCanceled(event, target) {
- return event.cancel || !target.getOptions()
- }
- function inCanvas(canvas, x, y) {
- return x >= canvas.left && x <= canvas.right && y >= canvas.top && y <= canvas.bottom
- }
- function correctLegendHoverMode(mode) {
- if (LEGEND_HOVER_MODES.indexOf(mode) > -1) {
- return mode
- } else {
- return INCLUDE_POINTS_MODE
- }
- }
- function correctHoverMode(target) {
- var mode = target.getOptions().hoverMode;
- return mode === NONE_MODE ? mode : ALL_ARGUMENT_POINTS_MODE
- }
- var baseTrackerPrototype = {
- ctor: function(options) {
- var that = this;
- var data = {
- tracker: that
- };
- that._renderer = options.renderer;
- that._legend = options.legend;
- that._tooltip = options.tooltip;
- that._eventTrigger = options.eventTrigger;
- that._seriesGroup = options.seriesGroup;
- options.seriesGroup.off(DOT_EVENT_NS).on(addNamespace(eventsConsts.showPointTooltip, EVENT_NS), data, that._showPointTooltip).on(addNamespace(eventsConsts.hidePointTooltip, EVENT_NS), data, that._hidePointTooltip);
- that._renderer.root.off(DOT_EVENT_NS).on(POINTER_ACTION, data, that._pointerHandler).on(addNamespace(clickEvent.name, EVENT_NS), data, that._clickHandler).on(addNamespace(holdEvent.name, EVENT_NS), {
- timeout: 300
- }, _noop)
- },
- update: function() {},
- updateSeries: function(series, resetDecorations) {
- var that = this;
- var noHoveredSeries = !(series && series.some(function(s) {
- return s === that.hoveredSeries
- }) || that._hoveredPoint && that._hoveredPoint.series);
- if (that._storedSeries !== series) {
- that._storedSeries = series || []
- }
- if (noHoveredSeries) {
- that._clean();
- that._renderer.initHatching()
- }
- if (resetDecorations) {
- that.clearSelection();
- if (!noHoveredSeries) {
- that._hideTooltip(that.pointAtShownTooltip);
- that.clearHover()
- }
- }
- },
- setCanvases: function(mainCanvas, paneCanvases) {
- this._mainCanvas = mainCanvas;
- this._canvases = paneCanvases
- },
- repairTooltip: function() {
- var point = this.pointAtShownTooltip;
- if (!point || !point.series || !point.isVisible()) {
- this._hideTooltip(point, true)
- } else {
- this._showTooltip(point)
- }
- },
- _setHoveredPoint: function(point) {
- if (point === this._hoveredPoint) {
- return
- }
- this._releaseHoveredPoint();
- point.hover();
- this._hoveredPoint = point
- },
- _releaseHoveredPoint: function() {
- if (this._hoveredPoint && this._hoveredPoint.getOptions()) {
- this._hoveredPoint.clearHover();
- this._hoveredPoint = null;
- if (this._tooltip.isEnabled()) {
- this._hideTooltip(this._hoveredPoint)
- }
- }
- },
- _setHoveredSeries: function(series, mode) {
- this._releaseHoveredSeries();
- this._releaseHoveredPoint();
- series.hover(mode);
- this.hoveredSeries = series
- },
- _releaseHoveredSeries: function(needSetHoverView, hoveredPoint) {
- if (this.hoveredSeries) {
- this.hoveredSeries.clearHover();
- this.hoveredSeries = null
- }
- },
- clearSelection: function() {
- this._storedSeries.forEach(function(series) {
- if (series) {
- series.clearSelection();
- series.getPoints().forEach(function(point) {
- point.clearSelection()
- })
- }
- })
- },
- _clean: function() {
- var that = this;
- that.hoveredPoint = that.hoveredSeries = that._hoveredArgumentPoints = null;
- that._hideTooltip(that.pointAtShownTooltip)
- },
- clearHover: function() {
- this._resetHoveredArgument();
- this._releaseHoveredSeries();
- this._releaseHoveredPoint()
- },
- _hideTooltip: function(point, silent) {
- var that = this;
- if (!that._tooltip || point && that.pointAtShownTooltip !== point) {
- return
- }
- if (!silent && that.pointAtShownTooltip) {
- that.pointAtShownTooltip = null
- }
- that._tooltip.hide()
- },
- _showTooltip: function(point) {
- var that = this;
- var tooltipFormatObject;
- var eventData;
- if (point && point.getOptions()) {
- tooltipFormatObject = point.getTooltipFormatObject(that._tooltip);
- if (!isDefined(tooltipFormatObject.valueText) && !tooltipFormatObject.points || !point.isVisible()) {
- return
- }
- if (!that.pointAtShownTooltip || that.pointAtShownTooltip !== point) {
- eventData = {
- target: point
- }
- }
- var coords = point.getTooltipParams(that._tooltip.getLocation());
- var rootOffset = that._renderer.getRootOffset();
- coords.x += rootOffset.left;
- coords.y += rootOffset.top;
- if (!that._tooltip.show(tooltipFormatObject, coords, eventData)) {
- return
- }
- that.pointAtShownTooltip = point
- }
- },
- _showPointTooltip: function(event, point) {
- var that = event.data.tracker;
- var pointWithTooltip = that.pointAtShownTooltip;
- if (pointWithTooltip && pointWithTooltip !== point) {
- that._hideTooltip(pointWithTooltip)
- }
- that._showTooltip(point)
- },
- _hidePointTooltip: function(event, point) {
- event.data.tracker._hideTooltip(point)
- },
- _enableOutHandler: function() {
- if (this._outHandler) {
- return
- }
- var that = this;
- var handler = function(e) {
- var rootOffset = that._renderer.getRootOffset();
- var x = _floor(e.pageX - rootOffset.left);
- var y = _floor(e.pageY - rootOffset.top);
- if (!inCanvas(that._mainCanvas, x, y)) {
- that._pointerOut();
- that._disableOutHandler()
- }
- };
- eventsEngine.on(domAdapter.getDocument(), POINTER_ACTION, handler);
- this._outHandler = handler
- },
- _disableOutHandler: function() {
- this._outHandler && eventsEngine.off(domAdapter.getDocument(), POINTER_ACTION, this._outHandler);
- this._outHandler = null
- },
- stopCurrentHandling: function() {
- this._pointerOut(true)
- },
- _pointerOut: function(force) {
- this.clearHover();
- (force || this._tooltip.isEnabled()) && this._hideTooltip(this.pointAtShownTooltip)
- },
- _triggerLegendClick: function(eventArgs, elementClick) {
- var eventTrigger = this._eventTrigger;
- eventTrigger(LEGEND_CLICK, eventArgs, function() {
- !eventCanceled(eventArgs.event, eventArgs.target) && eventTrigger(elementClick, eventArgs)
- })
- },
- _hoverLegendItem: function(x, y) {
- var that = this;
- var item = that._legend.getItemByCoord(x, y);
- var series;
- var legendHoverMode = correctLegendHoverMode(that._legend.getOptions().hoverMode);
- if (item) {
- series = that._storedSeries[item.id];
- if (!series.isHovered() || series.lastHoverMode !== legendHoverMode) {
- that._setHoveredSeries(series, legendHoverMode)
- }
- that._tooltip.isEnabled() && that._hideTooltip(that.pointAtShownTooltip)
- } else {
- that.clearHover()
- }
- },
- _hoverArgument: function(argument, argumentIndex) {
- var that = this;
- var hoverMode = that._getArgumentHoverMode();
- if (isDefined(argument)) {
- that._releaseHoveredPoint();
- that._hoveredArgument = argument;
- that._argumentIndex = argumentIndex;
- that._notifySeries({
- action: "pointHover",
- notifyLegend: that._notifyLegendOnHoverArgument,
- target: {
- argument: argument,
- fullState: HOVER_STATE,
- argumentIndex: argumentIndex,
- getOptions: function() {
- return {
- hoverMode: hoverMode
- }
- }
- }
- })
- }
- },
- _resetHoveredArgument: function() {
- var that = this;
- var hoverMode;
- if (isDefined(that._hoveredArgument)) {
- hoverMode = that._getArgumentHoverMode();
- that._notifySeries({
- action: "clearPointHover",
- notifyLegend: that._notifyLegendOnHoverArgument,
- target: {
- fullState: NORMAL_STATE,
- argumentIndex: that._argumentIndex,
- argument: that._hoveredArgument,
- getOptions: function() {
- return {
- hoverMode: hoverMode
- }
- }
- }
- });
- that._hoveredArgument = null
- }
- },
- _notifySeries: function(data) {
- this._storedSeries.forEach(function(series) {
- series.notify(data)
- })
- },
- _pointerHandler: function(e) {
- var that = e.data.tracker;
- var rootOffset = that._renderer.getRootOffset();
- var x = _floor(e.pageX - rootOffset.left);
- var y = _floor(e.pageY - rootOffset.top);
- var canvas = that._getCanvas(x, y);
- var series = getData(e, SERIES_DATA);
- var point = getData(e, POINT_DATA) || series && series.getPointByCoord(x, y);
- if (point && !point.getMarkerVisibility()) {
- point = void 0
- }
- that._enableOutHandler();
- if (that._legend.coordsIn(x, y)) {
- that._hoverLegendItem(x, y);
- return
- }
- if (that.hoveredSeries && that.hoveredSeries !== that._stuckSeries) {
- that._releaseHoveredSeries()
- }
- if (that._hoverArgumentAxis(x, y, e)) {
- return
- }
- if (that._isPointerOut(canvas, point)) {
- that._pointerOut()
- }
- if (!canvas && !point) {
- return
- }
- if (series && !point) {
- point = series.getNeighborPoint(x, y);
- if (!that._stickyHovering && point && !point.coordsIn(x, y)) {
- point = null
- }
- if (series !== that.hoveredSeries) {
- that._setTimeout(function() {
- that._setHoveredSeries(series);
- that._setStuckSeries(e, series, x, y);
- that._pointerComplete(point, x, y)
- }, series);
- return
- }
- } else {
- if (point) {
- if (e.type !== pointerEvents.move && "touch" !== e.pointerType) {
- return
- }
- if (that.hoveredSeries) {
- that._setTimeout(function() {
- that._pointerOnPoint(point, x, y, e)
- }, point)
- } else {
- that._pointerOnPoint(point, x, y, e)
- }
- return
- } else {
- if (that._setStuckSeries(e, void 0, x, y) && that._stickyHovering) {
- series = that._stuckSeries;
- point = series.getNeighborPoint(x, y);
- that._releaseHoveredSeries();
- point && point.getMarkerVisibility() && that._setHoveredPoint(point)
- } else {
- if (!that._stickyHovering) {
- that._pointerOut()
- }
- }
- }
- }
- that._pointerComplete(point, x, y)
- },
- _pointerOnPoint: function(point, x, y) {
- this._resetHoveredArgument();
- this._setHoveredPoint(point);
- this._pointerComplete(point, x, y)
- },
- _pointerComplete: function(point) {
- this.pointAtShownTooltip !== point && this._tooltip.isEnabled() && this._showTooltip(point)
- },
- _clickHandler: function(e) {
- var that = e.data.tracker;
- var rootOffset = that._renderer.getRootOffset();
- var x = _floor(e.pageX - rootOffset.left);
- var y = _floor(e.pageY - rootOffset.top);
- var point = getData(e, POINT_DATA);
- var series = that._stuckSeries || getData(e, SERIES_DATA) || point && point.series;
- var axis = that._argumentAxis;
- if (that._legend.coordsIn(x, y)) {
- var item = that._legend.getItemByCoord(x, y);
- if (item) {
- that._legendClick(item, e)
- }
- } else {
- if (axis && axis.coordsIn(x, y)) {
- var argument = getData(e, ARG_DATA);
- if (isDefined(argument)) {
- that._eventTrigger("argumentAxisClick", {
- argument: argument,
- event: e
- })
- }
- } else {
- if (series) {
- point = point || series.getPointByCoord(x, y);
- if (point && point.getMarkerVisibility()) {
- that._pointClick(point, e)
- } else {
- getData(e, SERIES_DATA) && that._eventTrigger(SERIES_CLICK, {
- target: series,
- event: e
- })
- }
- }
- }
- }
- },
- dispose: function() {
- var that = this;
- that._disableOutHandler();
- that._renderer.root.off(DOT_EVENT_NS);
- that._seriesGroup.off(DOT_EVENT_NS)
- }
- };
- var ChartTracker = function(options) {
- this.ctor(options)
- };
- extend(ChartTracker.prototype, baseTrackerPrototype, {
- _pointClick: function(point, event) {
- var that = this;
- var eventTrigger = that._eventTrigger;
- var series = point.series;
- eventTrigger(POINT_CLICK, {
- target: point,
- event: event
- }, function() {
- !eventCanceled(event, series) && eventTrigger(SERIES_CLICK, {
- target: series,
- event: event
- })
- })
- },
- update: function(options) {
- var that = this;
- baseTrackerPrototype.update.call(this, options);
- that._argumentAxis = options.argumentAxis || {};
- that._axisHoverEnabled = that._argumentAxis && _normalizeEnum(that._argumentAxis.getOptions().hoverMode) === ALL_ARGUMENT_POINTS_MODE;
- that._chart = options.chart;
- that._rotated = options.rotated;
- that._crosshair = options.crosshair;
- that._stickyHovering = options.stickyHovering
- },
- _getCanvas: function(x, y) {
- var that = this;
- var canvases = that._canvases || [];
- for (var i = 0; i < canvases.length; i++) {
- var c = canvases[i];
- if (inCanvas(c, x, y)) {
- return c
- }
- }
- return null
- },
- _isPointerOut: function(canvas) {
- return !canvas && this._stuckSeries
- },
- _hideCrosshair: function() {
- this._crosshair && this._crosshair.hide()
- },
- _moveCrosshair: function(point, x, y) {
- if (point && this._crosshair && point.isVisible()) {
- this._crosshair.show({
- point: point,
- x: x,
- y: y
- })
- }
- },
- _clean: function() {
- var that = this;
- baseTrackerPrototype._clean.call(that);
- that._resetTimer();
- that._stuckSeries = null
- },
- _getSeriesForShared: function(x, y) {
- var that = this;
- var points = [];
- var point = null;
- var distance = 1 / 0;
- if (that._tooltip.isShared() && !that.hoveredSeries) {
- _each(that._storedSeries, function(_, series) {
- var point = series.getNeighborPoint(x, y);
- point && points.push(point)
- });
- _each(points, function(_, p) {
- var coords = p.getCrosshairData(x, y);
- var d = vizUtils.getDistance(x, y, coords.x, coords.y);
- if (d < distance) {
- point = p;
- distance = d
- }
- })
- }
- return point && point.series
- },
- _setTimeout: function(callback, keeper) {
- var that = this;
- if (that._timeoutKeeper !== keeper) {
- that._resetTimer();
- that._hoverTimeout = setTimeout(function() {
- callback();
- that._timeoutKeeper = null
- }, DELAY);
- that._timeoutKeeper = keeper
- }
- },
- _resetTimer: function() {
- clearTimeout(this._hoverTimeout);
- this._timeoutKeeper = this._hoverTimeout = null
- },
- _stopEvent: function(e) {
- if (!isDefined(e.cancelable) || e.cancelable) {
- e.preventDefault();
- e.stopPropagation()
- }
- },
- _setStuckSeries: function(e, series, x, y) {
- if ("mouse" !== e.pointerType) {
- this._stuckSeries = null
- } else {
- this._stuckSeries = series || this._stuckSeries || this._getSeriesForShared(x, y)
- }
- return !!this._stuckSeries
- },
- _pointerOut: function() {
- var that = this;
- that._stuckSeries = null;
- that._hideCrosshair();
- that._resetTimer();
- baseTrackerPrototype._pointerOut.apply(that, arguments)
- },
- _hoverArgumentAxis: function(x, y, e) {
- var that = this;
- that._resetHoveredArgument();
- if (that._axisHoverEnabled && that._argumentAxis.coordsIn(x, y)) {
- that._hoverArgument(getData(e, ARG_DATA));
- return true
- }
- },
- _pointerComplete: function(point, x, y) {
- var that = this;
- that.hoveredSeries && that.hoveredSeries.updateHover(x, y);
- that._resetTimer();
- that._moveCrosshair(point, x, y);
- baseTrackerPrototype._pointerComplete.call(that, point)
- },
- _legendClick: function(item, e) {
- var series = this._storedSeries[item.id];
- this._triggerLegendClick({
- target: series,
- event: e
- }, SERIES_CLICK)
- },
- _hoverLegendItem: function(x, y) {
- this._stuckSeries = null;
- this._hideCrosshair();
- baseTrackerPrototype._hoverLegendItem.call(this, x, y)
- },
- _pointerOnPoint: function(point, x, y, e) {
- this._setStuckSeries(e, point.series, x, y);
- this._releaseHoveredSeries();
- baseTrackerPrototype._pointerOnPoint.call(this, point, x, y, e)
- },
- _notifyLegendOnHoverArgument: false,
- _getArgumentHoverMode: function() {
- return correctHoverMode(this._argumentAxis)
- },
- dispose: function() {
- this._resetTimer();
- baseTrackerPrototype.dispose.call(this)
- }
- });
- var PieTracker = function(options) {
- this.ctor(options)
- };
- extend(PieTracker.prototype, baseTrackerPrototype, {
- _isPointerOut: function(_, point) {
- return !point
- },
- _legendClick: function(item, e) {
- var that = this;
- var points = [];
- that._storedSeries.forEach(function(s) {
- return points.push.apply(points, s.getPointsByKeys(item.argument, item.argumentIndex))
- });
- that._eventTrigger(LEGEND_CLICK, {
- target: item.argument,
- points: points,
- event: e
- })
- },
- _pointClick: function(point, e) {
- this._eventTrigger(POINT_CLICK, {
- target: point,
- event: e
- })
- },
- _hoverLegendItem: function(x, y) {
- var that = this;
- var item = that._legend.getItemByCoord(x, y);
- that._resetHoveredArgument();
- if (item) {
- that._hoverArgument(item.argument, item.argumentIndex)
- } else {
- that.clearHover()
- }
- },
- _getArgumentHoverMode: function() {
- return correctHoverMode(this._legend)
- },
- _hoverArgumentAxis: _noop,
- _setStuckSeries: _noop,
- _getCanvas: _noop,
- _notifyLegendOnHoverArgument: true
- });
- exports.ChartTracker = ChartTracker;
- exports.PieTracker = PieTracker;
|