UNPKG

@progress/kendo-charts

Version:

Kendo UI platform-independent Charts library

1,492 lines (1,209 loc) 79.5 kB
import { drawing as draw, throttle, geometry } from '@progress/kendo-drawing'; import { RootElement, Title, CategoryAxis, Point } from '../core'; import Highlight from './highlight'; import Pannable from './pan-and-zoom/pannable'; import ZoomSelection from './pan-and-zoom/zoom-selection'; import MousewheelZoom from './pan-and-zoom/mousewheel-zoom'; import Legend from './legend/legend'; import PlotAreaFactory from './plotarea/plotarea-factory'; import Selection from './selection'; import SeriesBinder from './series-binder'; import Tooltip from './tooltip/tooltip'; import SharedTooltip from './tooltip/shared-tooltip'; import CategoricalPlotArea from './plotarea/categorical-plotarea'; import PlotAreaBase from './plotarea/plotarea-base'; import { ChartService, DomEventsBuilder } from '../services'; import isDateAxis from './utils/is-date-axis'; import { ChartPane, ChartPlotArea, findAxisByName } from './api-elements'; import { X, Y, VALUE, DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_SERIES_OPACITY, ARROW_DOWN, ARROW_UP, ARROW_LEFT, ARROW_RIGHT, ARIA_ACTIVE_DESCENDANT, TAB, TOP, LEFT, BLACK, ENTER, ESCAPE, BOTTOM } from '../common/constants'; import { addClass, removeClass, Class, setDefaultOptions, deepExtend, defined, find, isObject, isFunction, elementSize, elementOffset, elementScale, elementStyles, eventCoordinates, bindEvents, unbindEvents, mousewheelDelta, FontLoader, inArray, round, valueOrDefault, isString, cycleUp, cycleDown, hasOwnProperty, hasClasses } from '../common'; import { DRAG_START, DRAG, DRAG_END, ZOOM_START, ZOOM, ZOOM_END, SELECT_START, SELECT, SELECT_END, PLOT_AREA_HOVER, PLOT_AREA_LEAVE, RENDER, CATEGORY, PIE, DONUT, FUNNEL, PYRAMID, COLUMN, MOUSEWHEEL, MOUSEWHEEL_DELAY, MOUSEWHEEL_ZOOM_RATE, SHOW_TOOLTIP, SERIES_HOVER, SERIES_OVER, SERIES_LEAVE, SERIES_CLICK, DRILLDOWN, LEGEND_ITEM_CLICK } from './constants'; import './animations'; import './register-charts'; import { parseDateCategory } from './utils'; var AXIS_NAMES = [ CATEGORY, VALUE, X, Y ]; var MOUSEDOWN = "mousedown"; var MOUSEMOVE = "mousemove"; var CONTEXTMENU = "contextmenu"; var MOUSELEAVE = "mouseleave"; var KEYDOWN = "keydown"; var FOCUS = "focus"; var BLUR = "blur"; var MOUSEMOVE_DELAY = 20; var NO_DATA_OVERLAY_TOP_CLASS = "k-chart-overlay-top"; var Chart = (function (Class) { function Chart(element, userOptions, themeOptions, context) { var this$1 = this; if ( context === void 0 ) context = {}; Class.call(this); this.observers = []; this.addObserver(context.observer); this.chartService = new ChartService(this, context); this.chartService.theme = themeOptions; this._initElement(element); var options = deepExtend({}, this.options, userOptions); this._originalOptions = deepExtend({}, options); this._theme = themeOptions; this._initTheme(options, themeOptions); this._focusState = {}; this._initHandlers(); this._initSurface(); this.bindCategories(); FontLoader.preloadFonts(userOptions, function () { this$1.fontLoaded = true; if (!this$1._destroyed) { this$1.trigger('init'); this$1._redraw(); this$1._attachEvents(); this$1._restoreOverlayElement(); } }); } if ( Class ) Chart.__proto__ = Class; Chart.prototype = Object.create( Class && Class.prototype ); Chart.prototype.constructor = Chart; Chart.prototype._initElement = function _initElement (element) { var this$1 = this; this._setElementClass(element); element.style.position = "relative"; element.tabIndex = element.getAttribute("tabindex") ? element.getAttribute("tabindex") : 0; // To support user agents and assistive technologies based on the ARIA 1.0 specification, authors may wish to include the document role as a fallback value, in the form role="graphics-document document". element.setAttribute("role", "graphics-document document"); for (var i = element.childNodes.length - 1; i >= 0; i--) { var child = element.childNodes[i]; if (!hasClasses(child, "k-chart-overlay")) { element.removeChild(child); } else { // this is necessary if the overlay is rendered server-side, e.g. in blazor // but drawing the surface clears the contents of the element // and thus the no data overlay is lost this$1.overlayElement = child; } } this.element = element; }; Chart.prototype._setElementClass = function _setElementClass (element) { addClass(element, "k-chart"); }; Chart.prototype._restoreOverlayElement = function _restoreOverlayElement () { if (!this.overlayElement) { return; } if (this._hasSeriesData()) { this.overlayElement.style.display = "none"; } else { if (!this.options.title || (this.options.title && this.options.title.position !== BOTTOM)) { addClass(this.overlayElement, NO_DATA_OVERLAY_TOP_CLASS); } else { removeClass(this.overlayElement, NO_DATA_OVERLAY_TOP_CLASS); } this.overlayElement.style.display = ""; } if (this.overlayElement.parentElement !== this.element) { this.element.appendChild(this.overlayElement); } }; Chart.prototype._hasSeriesData = function _hasSeriesData () { var series = this.options.series || []; var hasData = series.length > 0 && series.some(function (x) { return x.data && x.data.length > 0; }); return hasData; }; Chart.prototype._initTheme = function _initTheme (options, themeOptions) { var seriesCopies = []; var series = options.series || []; for (var i = 0; i < series.length; i++) { seriesCopies.push(Object.assign({}, series[i])); } options.series = seriesCopies; resolveAxisAliases(options); this.applyDefaults(options, themeOptions); // Clean up default if not overriden by data attributes if (options.seriesColors === null) { delete options.seriesColors; } if (isString(options.title)) { options.title = { text: options.title }; } this.options = deepExtend({}, themeOptions, options); this.applySeriesColors(); }; Chart.prototype.getSize = function getSize () { var chartArea = this.options.chartArea || {}; var width = chartArea.width ? parseInt(chartArea.width, 10) : Math.floor(this.element.offsetWidth); var height = chartArea.height ? parseInt(chartArea.height, 10) : Math.floor(this.element.offsetHeight); return { width: width, height: height }; }; Chart.prototype.resize = function resize (force) { var size = this.getSize(); var currentSize = this._size; var hasSize = size.width > 0 || size.height > 0; if (force || hasSize && (!currentSize || size.width !== currentSize.width || size.height !== currentSize.height)) { this._size = size; this._resize(size, force); this.trigger("resize", size); } else if (hasSize && this._selections && find(this._selections, function (s) { return !s.visible; })) { this._destroySelections(); this._setupSelection(); } }; Chart.prototype._resize = function _resize () { this._noTransitionsRedraw(); }; Chart.prototype.redraw = function redraw (paneName) { this.applyDefaults(this.options); this.applySeriesColors(); if (paneName) { var plotArea = this._model._plotArea; var pane = plotArea.findPane(paneName); plotArea.redraw(pane); } else { this._redraw(); } }; Chart.prototype.getAxis = function getAxis (name) { return findAxisByName(name, this._plotArea.axes); }; Chart.prototype.findAxisByName = function findAxisByName (name) { return this.getAxis(name); }; Chart.prototype.findPaneByName = function findPaneByName (name) { var panes = this._plotArea.panes; for (var idx = 0; idx < panes.length; idx++) { if (panes[idx].options.name === name) { return new ChartPane(panes[idx]); } } }; Chart.prototype.findPaneByIndex = function findPaneByIndex (idx) { var panes = this._plotArea.panes; if (panes[idx]) { return new ChartPane(panes[idx]); } }; Chart.prototype.plotArea = function plotArea () { return new ChartPlotArea(this._plotArea); }; Chart.prototype.toggleHighlight = function toggleHighlight (show, filter) { var plotArea = this._plotArea; var firstSeries = (plotArea.srcSeries || plotArea.series || [])[0]; var points; if (isFunction(filter)) { points = plotArea.filterPoints(filter); } else { var seriesName, categoryName; if (isObject(filter)) { seriesName = filter.series; categoryName = filter.category; } else { seriesName = categoryName = filter; } if (firstSeries.type === DONUT) { points = pointByCategoryName(plotArea.pointsBySeriesName(seriesName), categoryName); } else if (inArray(firstSeries.type, [ PIE, FUNNEL, PYRAMID ])) { points = pointByCategoryName((plotArea.charts[0] || {}).points, categoryName); } else { points = plotArea.pointsBySeriesName(seriesName); } } if (points) { this.togglePointsHighlight(show, points); } }; Chart.prototype.togglePointsHighlight = function togglePointsHighlight (show, points) { var highlight = this._highlight; for (var idx = 0; idx < points.length; idx++) { highlight.togglePointHighlight(points[idx], show); } }; Chart.prototype.showTooltip = function showTooltip (filter) { var shared = this._sharedTooltip(); var ref = this; var tooltip = ref._tooltip; var plotArea = ref._plotArea; var point, categoryIndex; if (isFunction(filter)) { point = plotArea.findPoint(filter); if (point && shared) { categoryIndex = point.categoryIx; } } else if (shared && defined(filter)) { categoryIndex = plotArea.categoryAxis.categoryIndex(filter); } if (shared) { if (categoryIndex >= 0) { var points = this._plotArea.pointsByCategoryIndex(categoryIndex); tooltip.showAt(points); } } else if (point) { tooltip.show(point); } }; Chart.prototype.hideTooltip = function hideTooltip () { this._tooltip.hide(); }; Chart.prototype._initSurface = function _initSurface () { var surface = this.surface; var wrap = this._surfaceWrap(); var chartArea = this.options.chartArea || {}; if (chartArea.width) { elementSize(wrap, { width: chartArea.width }); } if (chartArea.height) { elementSize(wrap, { height: chartArea.height }); } if (!surface || surface.options.type !== this.options.renderAs) { this._destroySurface(); this.surface = draw.Surface.create(wrap, { type: this.options.renderAs }); this.surface.bind("mouseenter", this._surfaceMouseenterHandler); this.surface.bind("mouseleave", this._surfaceMouseleaveHandler); } else { this.surface.clear(); this.surface.resize(); } // Override the surface _kendoExportVisual in order to accept export options with size. this.element._kendoExportVisual = this._kendoExportVisual.bind(this); }; Chart.prototype._surfaceWrap = function _surfaceWrap () { return this.element; }; Chart.prototype._redraw = function _redraw () { var model = this._getModel(); this._size = { width: model.options.width, height: model.options.height }; this._destroyView(); this._setElementAccessibilityAttributes(); this._model = model; this._plotArea = model._plotArea; this._legend = model._legend; model.renderVisual(); if (this.options.transitions !== false) { model.traverse(function(element) { if (element.animation) { element.animation.setup(); } }); } this._initSurface(); this.surface.draw(model.visual); if (this.options.transitions !== false) { model.traverse(function(element) { if (element.animation) { element.animation.play(); } }); } this._tooltip = this._createTooltip(); this._highlight = new Highlight(); this._setupSelection(); this._createPannable(); this._createZoomSelection(); this._createMousewheelZoom(); this._setComputedStyles(); this.trigger(RENDER); triggerPaneRender(this._plotArea.panes); if (!this._navState) { this._cancelDomEvents(); } this._redrawFocusHighlight(); }; Chart.prototype._setComputedStyles = function _setComputedStyles () { var titleHeight = this.titleHeight(); this.element.style.setProperty('--kendo-chart-computed-title-height', (titleHeight + "px")); }; Chart.prototype._redrawFocusHighlight = function _redrawFocusHighlight () { if (this._destroyed) { return; } var ref = this; var ref_focusState = ref._focusState; var legendInFocus = ref_focusState.legendInFocus; var preserveHighlight = ref_focusState.preserveHighlight; if (legendInFocus && preserveHighlight) { this._focusElement(this._getFocusedLegendItem(), false); this._focusState.preserveHighlight = false; } }; Chart.prototype._setElementAccessibilityAttributes = function _setElementAccessibilityAttributes () { var titleOptions = this.options.title; var title = isString(titleOptions) ? titleOptions : (titleOptions.description || titleOptions.text); if (title) { this.element.setAttribute("aria-roledescription", title); } }; Chart.prototype._kendoExportVisual = function _kendoExportVisual (size) { if (size && size.width && size.height) { var chartArea = this._originalOptions.chartArea || {}; var exportOptions = { width: chartArea.width || size.width, height: chartArea.height || size.height }; return this.exportVisual(exportOptions); } return this.exportVisual(); }; Chart.prototype.exportVisual = function exportVisual (exportOptions) { var visual; if (exportOptions && (exportOptions.width || exportOptions.height || exportOptions.options)) { var currentOptions = this.options; var options = deepExtend({}, exportOptions.options, { chartArea: { width: exportOptions.width, height: exportOptions.height } }); clearMissingValues(this._originalOptions, options); this.options = deepExtend({}, this._originalOptions, options); this._initTheme(this.options, this._theme); this.bindCategories(); var model = this._getModel(); model.renderVisual(); triggerPaneRender(model._plotArea.panes); visual = model.visual; this.options = currentOptions; } else { visual = this.surface.exportVisual(); } return visual; }; Chart.prototype._sharedTooltip = function _sharedTooltip () { return this._plotArea instanceof CategoricalPlotArea && this.options.tooltip && this.options.tooltip.shared; }; Chart.prototype._createPannable = function _createPannable () { var options = this.options; if (options.pannable !== false) { this._pannable = new Pannable(this._plotArea, options.pannable); } }; Chart.prototype._createZoomSelection = function _createZoomSelection () { var zoomable = this.options.zoomable; var selection = (zoomable || {}).selection; if (zoomable !== false && selection !== false) { this._zoomSelection = new ZoomSelection(this, selection); } }; Chart.prototype._createMousewheelZoom = function _createMousewheelZoom () { var zoomable = this.options.zoomable; var mousewheel = (zoomable || {}).mousewheel; if (zoomable !== false && mousewheel !== false) { this._mousewheelZoom = new MousewheelZoom(this, mousewheel); } }; Chart.prototype._toggleDragZoomEvents = function _toggleDragZoomEvents () { var pannable = this.options.pannable; var zoomable = this.options.zoomable; var selection = (zoomable || {}).selection; var mousewheel = (zoomable || {}).mousewheel; var allowDrag = !pannable && (zoomable === false || selection === false) && !this.requiresHandlers([ DRAG_START, DRAG, DRAG_END ]); var allowZoom = (zoomable === false || mousewheel === false) && !this.requiresHandlers([ ZOOM_START, ZOOM, ZOOM_END ]); var element = this.element; if (this._dragZoomEnabled && allowDrag && allowZoom) { element.style.touchAction = this._touchAction || ''; this._dragZoomEnabled = false; } else if (!this._dragZoomEnabled && !(allowDrag && allowZoom)) { element.style.touchAction = "none"; this._dragZoomEnabled = true; } this._toggleDomEvents(!allowDrag, !allowZoom); }; Chart.prototype._toggleDomEvents = function _toggleDomEvents (drag, zoom) { var domEvents = this.domEvents; if (!domEvents) { return; } if (domEvents.toggleDrag) { domEvents.toggleDrag(drag); } if (domEvents.toggleZoom) { domEvents.toggleZoom(zoom); } }; Chart.prototype._createTooltip = function _createTooltip () { var ref = this; var tooltipOptions = ref.options.tooltip; var tooltip; if (this._sharedTooltip()) { tooltip = this._createSharedTooltip(tooltipOptions); } else { tooltip = new Tooltip(this.chartService, tooltipOptions); } return tooltip; }; Chart.prototype._createSharedTooltip = function _createSharedTooltip (options) { return new SharedTooltip(this._plotArea, options); }; Chart.prototype.applyDefaults = function applyDefaults (options, themeOptions) { applyAxisDefaults(options, themeOptions); applySeriesDefaults(options, themeOptions); }; Chart.prototype.applySeriesColors = function applySeriesColors () { var options = this.options; var series = options.series; var colors = options.seriesColors || []; for (var i = 0; i < series.length; i++) { var currentSeries = series[i]; var seriesColor = colors[i % colors.length]; var defaults = currentSeries._defaults; currentSeries.color = currentSeries.color || seriesColor; if (defaults) { defaults.color = defaults.color || seriesColor; } } }; Chart.prototype._getModel = function _getModel () { var options = this.options; var plotArea = this._createPlotArea(); var model = new RootElement(this._modelOptions()); model.chart = this; model._plotArea = plotArea; var title = Title.buildTitle(options.title); var subtitle = Title.buildTitle(options.subtitle, { align: options.title.align, position: options.title.position }); model.append.apply(model, Title.orderTitles([title, subtitle])); if (options.legend && options.legend.visible) { var legend = new Legend(plotArea.options.legend, this.chartService); model.append(legend); model._legend = legend; } model.append(plotArea); model.reflow(); this._setTitleBox(title, subtitle); return model; }; Chart.prototype._setTitleBox = function _setTitleBox (title, subtitle) { if (!title && !subtitle) { return; } this._titleBox = (title || subtitle).box.clone(); var titlePosition = title ? title.options.position : ''; var subtitlePosition = subtitle ? subtitle.options.position : ''; var samePosition = titlePosition === subtitlePosition; var subtitleAtTop = subtitlePosition !== BOTTOM; if (samePosition && subtitle) { this._titleBox.wrap(subtitle.box); } else if (title && subtitle && subtitleAtTop) { this._titleBox = subtitle.box.clone(); } }; Chart.prototype._modelOptions = function _modelOptions () { var options = this.options; var size = this.getSize(); return deepExtend({ transitions: options.transitions, width: size.width || DEFAULT_WIDTH, height: size.height || DEFAULT_HEIGHT }, options.chartArea); }; Chart.prototype._createPlotArea = function _createPlotArea (skipSeries) { var options = this.options; var plotArea = PlotAreaFactory.current.create(skipSeries ? [] : options.series, options, this.chartService); return plotArea; }; Chart.prototype._setupSelection = function _setupSelection () { var this$1 = this; var ref = this; var axes = ref._plotArea.axes; var selections = this._selections = []; for (var i = 0; i < axes.length; i++) { var axis = axes[i]; var options = axis.options; if (axis instanceof CategoryAxis && options.select && !options.vertical) { var range = axis.range(); var selection = new Selection(this$1, axis, deepExtend({ min: range.min, max: range.max }, options.select) ); selections.push(selection); } } }; Chart.prototype._selectStart = function _selectStart (e) { return this.trigger(SELECT_START, e); }; Chart.prototype._select = function _select (e) { return this.trigger(SELECT, e); }; Chart.prototype._selectEnd = function _selectEnd (e) { return this.trigger(SELECT_END, e); }; Chart.prototype._initHandlers = function _initHandlers () { this._clickHandler = this._click.bind(this); this._keydownHandler = this._keydown.bind(this); this._focusHandler = this._focus.bind(this); this._blurHandler = this._blur.bind(this); this._mousedownHandler = this._mousedown.bind(this); this._mousewheelHandler = this._mousewheel.bind(this); this._mouseleaveHandler = this._mouseleave.bind(this); this._surfaceMouseenterHandler = this._mouseover.bind(this); this._surfaceMouseleaveHandler = this._mouseout.bind(this); this._mousemove = throttle( this._mousemove.bind(this), MOUSEMOVE_DELAY ); }; Chart.prototype.addObserver = function addObserver (observer) { if (observer) { this.observers.push(observer); } }; Chart.prototype.removeObserver = function removeObserver (observer) { var index = this.observers.indexOf(observer); if (index >= 0) { this.observers.splice(index, 1); } }; Chart.prototype.requiresHandlers = function requiresHandlers (eventNames) { var observers = this.observers; for (var idx = 0; idx < observers.length; idx++) { if (observers[idx].requiresHandlers(eventNames)) { return true; } } }; Chart.prototype.trigger = function trigger (name, args) { if ( args === void 0 ) args = {}; args.sender = this; if (name === SHOW_TOOLTIP) { args.anchor.point = this._toDocumentCoordinates(args.anchor.point); } else if (name === SERIES_OVER) { this._updateDrilldownPoint(args.point); } else if (name === SERIES_LEAVE) { this._resetDrilldownPoint(); } else if (name === SERIES_CLICK) { this._focusPoint(args.point); this._startDrilldown(args.point); } else if (name === LEGEND_ITEM_CLICK) { this._focusLegendItem(args); } var observers = this.observers; var isDefaultPrevented = false; for (var idx = 0; idx < observers.length; idx++) { if (observers[idx].trigger(name, args)) { isDefaultPrevented = true; } } return isDefaultPrevented; }; Chart.prototype.titleHeight = function titleHeight () { if (!this._titleBox) { return 0; } return this._titleBox.height(); }; Chart.prototype._attachEvents = function _attachEvents () { var obj, obj$1; var element = this.element; this._touchAction = element.style.touchAction; bindEvents(element, ( obj = {}, obj[ CONTEXTMENU ] = this._clickHandler, obj[ MOUSEWHEEL ] = this._mousewheelHandler, obj[ MOUSELEAVE ] = this._mouseleaveHandler, obj[ KEYDOWN ] = this._keydownHandler, obj[ MOUSEDOWN ] = this._mousedownHandler, obj[ FOCUS ] = this._focusHandler, obj[ BLUR] = this._blurHandler, obj )); if (this._shouldAttachMouseMove()) { bindEvents(element, ( obj$1 = {}, obj$1[ MOUSEMOVE ] = this._mousemove, obj$1 )); } this.domEvents = DomEventsBuilder.create(this.element, { start: this._start.bind(this), move: this._move.bind(this), end: this._end.bind(this), tap: this._tap.bind(this), gesturestart: this._gesturestart.bind(this), gesturechange: this._gesturechange.bind(this), gestureend: this._gestureend.bind(this) }); this._toggleDragZoomEvents(); }; Chart.prototype._mouseleave = function _mouseleave (e) { if (this._hoveredPoint) { this._hoveredPoint.out(this, e); this._hoveredPoint = null; } if (this._plotAreaHovered) { this._plotAreaHovered = false; this.trigger(PLOT_AREA_LEAVE); } if (this._hasInactiveOpacity() && this._activeChartInstance) { this._applySeriesOpacity(this._activeChartInstance.children, null, true); this._updateSeriesOpacity(null, true); } }; Chart.prototype._cancelDomEvents = function _cancelDomEvents () { if (this.domEvents && this.domEvents.cancel) { this.domEvents.cancel(); } }; Chart.prototype._gesturestart = function _gesturestart (e) { if (this._mousewheelZoom && !this._stopChartHandlers(e)) { this._gestureDistance = e.distance; this._unsetActivePoint(); this._clearFocusedElement(); this.surface.suspendTracking(); } }; Chart.prototype._gestureend = function _gestureend (e) { if (this._zooming && !this._stopChartHandlers(e)) { if (this.surface) { this.surface.resumeTracking(); } this._zooming = false; this.trigger(ZOOM_END, {}); } }; Chart.prototype._gesturechange = function _gesturechange (e) { var mousewheelZoom = this._mousewheelZoom; if (mousewheelZoom && !this._stopChartHandlers(e)) { e.preventDefault(); var previousGestureDistance = this._gestureDistance; var scaleDelta = -e.distance / previousGestureDistance + 1; if (Math.abs(scaleDelta) >= 0.1) { scaleDelta = Math.round(scaleDelta * 10); this._gestureDistance = e.distance; var args = { delta: scaleDelta, axisRanges: axisRanges(this._plotArea.axes), originalEvent: e }; if (this._zooming || !this.trigger(ZOOM_START, args)) { var coords = this._eventCoordinates(e); if (!this._zooming) { this._zooming = true; } var ranges = args.axisRanges = mousewheelZoom.updateRanges(scaleDelta, coords); if (ranges && !this.trigger(ZOOM, args)) { mousewheelZoom.zoom(); } } } } }; Chart.prototype._mouseout = function _mouseout (e) { if (e.element) { var element = this._drawingChartElement(e.element, e); if (element && element.leave) { element.leave(this, e.originalEvent); } } }; Chart.prototype._start = function _start (e) { var coords = this._eventCoordinates(e); if (this._stopChartHandlers(e) || !this._plotArea.backgroundContainsPoint(coords)) { return; } if (this.requiresHandlers([ DRAG_START, DRAG, DRAG_END ])) { this._startNavigation(e, coords, DRAG_START); } if (this._pannable && this._pannable.start(e)) { this.surface.suspendTracking(); this._unsetActivePoint(); this._clearFocusedElement(); this._suppressHover = true; this.chartService.panning = true; } if (this._zoomSelection) { if (this._zoomSelection.start(e)) { this.trigger(ZOOM_START, { axisRanges: axisRanges(this._plotArea.axes), originalEvent: e }); } } }; Chart.prototype._move = function _move (e) { var ref = this; var state = ref._navState; var pannable = ref._pannable; if (this._stopChartHandlers(e)) { return; } if (pannable) { var ranges = pannable.move(e); if (ranges && !this.trigger(DRAG, { axisRanges: ranges, originalEvent: e })) { pannable.pan(); } } else if (state) { var ranges$1 = {}; var axes = state.axes; for (var i = 0; i < axes.length; i++) { var currentAxis = axes[i]; var axisName = currentAxis.options.name; if (axisName) { var axis = currentAxis.options.vertical ? e.y : e.x; var delta = axis.startLocation - axis.location; if (delta !== 0) { ranges$1[currentAxis.options.name] = currentAxis.translateRange(delta); } } } state.axisRanges = ranges$1; this.trigger(DRAG, { axisRanges: ranges$1, originalEvent: e }); } if (this._zoomSelection) { this._zoomSelection.move(e); } }; Chart.prototype._end = function _end (e) { if (this._stopChartHandlers(e)) { return; } var pannable = this._pannable; if (pannable && pannable.end(e)) { this.surface.resumeTracking(); this.trigger(DRAG_END, { axisRanges: axisRanges(this._plotArea.axes), originalEvent: e }); this._suppressHover = false; this.chartService.panning = false; } else { this._endNavigation(e, DRAG_END); } if (this._zoomSelection) { var ranges = this._zoomSelection.end(e); if (ranges && !this.trigger(ZOOM, { axisRanges: ranges, originalEvent: e })) { this._zoomSelection.zoom(); this.trigger(ZOOM_END, { axisRanges: ranges, originalEvent: e }); } } }; Chart.prototype._stopChartHandlers = function _stopChartHandlers (e) { var selections = this._selections || []; if (!selections.length) { return false; } var coords = this._eventCoordinates(e); var pane = this._plotArea.paneByPoint(coords); if (pane) { for (var idx = 0; idx < selections.length; idx++) { if (selections[idx].onPane(pane)) { return true; } } } }; Chart.prototype._mousewheelZoomRate = function _mousewheelZoomRate () { var zoomable = this.options.zoomable; var mousewheel = (zoomable || {}).mousewheel || {}; return valueOrDefault(mousewheel.rate, MOUSEWHEEL_ZOOM_RATE); }; Chart.prototype._mousewheel = function _mousewheel (e) { var this$1 = this; var delta = mousewheelDelta(e); var mousewheelZoom = this._mousewheelZoom; var coords = this._eventCoordinates(e); if (this._stopChartHandlers(e) || !this._plotArea.backgroundContainsPoint(coords)) { return; } if (mousewheelZoom) { var args = { delta: delta, axisRanges: axisRanges(this._plotArea.axes), originalEvent: e }; if (this._zooming || !this.trigger(ZOOM_START, args)) { e.preventDefault(); if (!this._zooming) { this._unsetActivePoint(); this._clearFocusedElement(); this.surface.suspendTracking(); this._zooming = true; } if (this._mwTimeout) { clearTimeout(this._mwTimeout); } args.axisRanges = mousewheelZoom.updateRanges(delta, coords); if (args.axisRanges && !this.trigger(ZOOM, args)) { mousewheelZoom.zoom(); } this._mwTimeout = setTimeout(function () { this$1.trigger(ZOOM_END, args); this$1._zooming = false; if (this$1.surface) { this$1.surface.resumeTracking(); } }, MOUSEWHEEL_DELAY); } } else { var state = this._navState; if (!state) { var prevented = this._startNavigation(e, coords, ZOOM_START); if (!prevented) { state = this._navState; } } if (state) { var totalDelta = state.totalDelta || delta; state.totalDelta = totalDelta + delta; var axes = this._navState.axes; var ranges = {}; for (var i = 0; i < axes.length; i++) { var currentAxis = axes[i]; var axisName = currentAxis.options.name; if (axisName) { ranges[axisName] = currentAxis.scaleRange(-totalDelta * this$1._mousewheelZoomRate(), coords); } } this.trigger(ZOOM, { delta: delta, axisRanges: ranges, originalEvent: e }); if (this._mwTimeout) { clearTimeout(this._mwTimeout); } this._mwTimeout = setTimeout(function () { this$1._endNavigation(e, ZOOM_END); }, MOUSEWHEEL_DELAY); } } }; Chart.prototype._startNavigation = function _startNavigation (e, coords, chartEvent) { var plotArea = this._model._plotArea; var pane = plotArea.findPointPane(coords); var axes = plotArea.axes.slice(0); if (!pane) { return; } var ranges = axisRanges(axes); var prevented = this.trigger(chartEvent, { axisRanges: ranges, originalEvent: e }); if (prevented) { this._cancelDomEvents(); } else { this._suppressHover = true; this._unsetActivePoint(); this._clearFocusedElement(); this._navState = { axisRanges: ranges, pane: pane, axes: axes }; } }; Chart.prototype._endNavigation = function _endNavigation (e, chartEvent) { if (this._navState) { this.trigger(chartEvent, { axisRanges: this._navState.axisRanges, originalEvent: e }); this._suppressHover = false; this._navState = null; } }; Chart.prototype._getChartElement = function _getChartElement (e, match) { var element = this.surface.eventTarget(e); if (element) { return this._drawingChartElement(element, e, match); } }; Chart.prototype._drawingChartElement = function _drawingChartElement (element, e, match) { var current = element; var chartElement; while (current && !chartElement) { chartElement = current.chartElement; current = current.parent; } if (chartElement) { if (chartElement.aliasFor) { chartElement = chartElement.aliasFor(e, this._eventCoordinates(e)); } if (match) { chartElement = chartElement.closest(match); if (chartElement && chartElement.aliasFor) { chartElement = chartElement.aliasFor(); } } return chartElement; } }; Chart.prototype._eventCoordinates = function _eventCoordinates (e) { var coordinates = eventCoordinates(e); return this._toModelCoordinates(coordinates.x, coordinates.y); }; Chart.prototype._elementPadding = function _elementPadding () { if (!this._padding) { var ref = elementStyles(this.element, [ "paddingLeft", "paddingTop" ]); var paddingLeft = ref.paddingLeft; var paddingTop = ref.paddingTop; this._padding = { top: paddingTop, left: paddingLeft }; } return this._padding; }; Chart.prototype._toDocumentCoordinates = function _toDocumentCoordinates (point) { var padding = this._elementPadding(); var offset = elementOffset(this.element); return { left: round(point.x + padding.left + offset.left), top: round(point.y + padding.top + offset.top) }; }; // TODO: Breaking change due to peer version change // Reuse by exposing _surfacePoint on Surface Chart.prototype._toModelCoordinates = function _toModelCoordinates (clientX, clientY) { var element = this.element; var offset = elementOffset(element); var padding = this._elementPadding(); var inverseTransform = elementScale(element).invert(); var point = new geometry.Point( clientX - offset.left - padding.left, clientY - offset.top - padding.top ).transform(inverseTransform); return new Point(point.x, point.y); }; Chart.prototype._tap = function _tap (e) { var this$1 = this; var drawingElement = this.surface.eventTarget(e); var element = this._drawingChartElement(drawingElement, e); var sharedTooltip = this._sharedTooltip(); if (!this._startHover(drawingElement, e) && !sharedTooltip) { this._unsetActivePoint(); } if (sharedTooltip) { this._trackSharedTooltip(this._eventCoordinates(e), e, true); } this._propagateClick(element, e); //part of fix for hover issue on windows touch this.handlingTap = true; setTimeout(function () { this$1.handlingTap = false; }, 0); }; Chart.prototype._click = function _click (e) { var element = this._getChartElement(e); this._propagateClick(element, e); }; Chart.prototype._propagateClick = function _propagateClick (element, e) { var this$1 = this; var current = element; while (current) { if (current.click) { current.click(this$1, e); } current = current.parent; } }; Chart.prototype._isLegendBeforeChart = function _isLegendBeforeChart () { var ref = this; var legendPosition = ref.options.legend.position; var legend = ref._legend; return legend && legend.hasItems() && (legendPosition === TOP || legendPosition === LEFT); }; Chart.prototype._focus = function _focus () { if (!this._preventInitialPointFocus) { if (this._isLegendBeforeChart()) { this._focusFirstLegendItem(); } else { this._focusFirstPoint(); } } this._preventInitialPointFocus = false; }; Chart.prototype._keydown = function _keydown (e) { var ref = this; var ref_focusState = ref._focusState; var legendInFocus = ref_focusState.legendInFocus; var focusedElement = ref_focusState.focusedElement; var legend = ref._legend; if (e.key === TAB) { this._clearFocusedElement(); var isLegendBeforeChart = this._isLegendBeforeChart(); if (legendInFocus && isLegendBeforeChart !== e.shiftKey) { this._navigatePoints(e); } else if (!legendInFocus && isLegendBeforeChart === e.shiftKey && legend.hasItems()) { this._navigateLegend(e); } } else if (e.key === ESCAPE) { if (focusedElement) { e.stopPropagation(); } if (this._tooltip && this._tooltip.visible) { this._hideTooltip(); } else { this._blur(); } } else if (e.key === ENTER) { if (focusedElement) { this._focusState.preserveHighlight = true; this._propagateClick(focusedElement, e); this._focusElement(focusedElement); } } else if (!legendInFocus) { this._navigatePoints(e); } else { this._navigateLegend(e); } }; Chart.prototype._navigatePoints = function _navigatePoints (e) { var this$1 = this; var ref = this; var focusState = ref._focusState; var plotArea = ref._plotArea; focusState.legendInFocus = false; if (!focusState.focusedElement) { this._focusFirstPoint(); e.preventDefault(); return; } var moveFocus = function (point) { focusState.focusedPoint = point; this$1._focusElement(focusState.focusedPoint); this$1._displayTooltip(point); e.preventDefault(); }; switch (e.key) { case ARROW_RIGHT: moveFocus(plotArea.getPointToTheRight(focusState.focusedPoint)); break; case ARROW_LEFT: moveFocus(plotArea.getPointToTheLeft(focusState.focusedPoint)); break; case ARROW_DOWN: moveFocus(plotArea.getPointBelow(focusState.focusedPoint)); break; case ARROW_UP: moveFocus(plotArea.getPointAbove(focusState.focusedPoint)); break; default: break; } }; Chart.prototype._navigateLegend = function _navigateLegend (e) { var this$1 = this; var ref = this; var focusState = ref._focusState; var legend = ref._legend; var rtl = ref.chartService.rtl; focusState.legendInFocus = true; if (!focusState.focusedElement) { this._focusFirstLegendItem(); e.preventDefault(); return; } var itemsLength = legend.getItems().length; var moveFocus = function (cycleFunc) { focusState.focusedLegendItemIndex = cycleFunc( focusState.focusedLegendItemIndex, itemsLength ); this$1._focusElement(this$1._getFocusedLegendItem()); e.preventDefault(); }; switch (e.key) { case ARROW_UP: case ARROW_LEFT: moveFocus(rtl ? cycleUp : cycleDown); break; case ARROW_DOWN: case ARROW_RIGHT: moveFocus(rtl ? cycleDown : cycleUp); break; default: break; } }; Chart.prototype._focusFirstPoint = function _focusFirstPoint () { var point = this._focusState.focusedPoint = this._plotArea.getFirstPoint(); if (point) { this._focusElement(point); this._displayTooltip(point); } }; Chart.prototype._hasFocus = function _hasFocus () { return this.element.ownerDocument.activeElement === this.element; }; Chart.prototype._mousedown = function _mousedown () { if (!this._hasFocus()) { this._preventInitialPointFocus = true; } }; Chart.prototype._focusChart = function _focusChart () { if (!this._hasFocus()) { this._preventInitialPointFocus = true; this.element.focus(); } }; Chart.prototype._focusPoint = function _focusPoint (point) { this._focusState.focusedPoint = point; this._focusChart(); this._focusElement(point, true); }; Chart.prototype._focusFirstLegendItem = function _focusFirstLegendItem () { var ref = this; var focusState = ref._focusState; focusState.focusedLegendItemIndex = 0; this._focusElement(this._getFocusedLegendItem()); focusState.legendInFocus = true; this._hideTooltip(); }; Chart.prototype._focusLegendItem = function _focusLegendItem (args) { var ref = this; var focusState = ref._focusState; focusState.focusedLegendItemIndex = this._legend .getItems() .findIndex(function (x) { return x.options.series.index === args.seriesIndex && x.options.pointIndex === args.pointIndex; }); focusState.legendInFocus = true; this._focusChart(); this._focusElement(this._getFocusedLegendItem(), true); }; Chart.prototype._getFocusedLegendItem = function _getFocusedLegendItem () { var ref = this; var focusState = ref._focusState; var legend = ref._legend; return legend.getItems()[focusState.focusedLegendItemIndex]; }; Chart.prototype._focusElement = function _focusElement (element, omitHighlight) { var ref = this; var focusState = ref._focusState; this._clearFocusedElement(); if (!element) { return; } focusState.focusedElement = element; this._setElementActiveDescendant(element); if (!omitHighlight) { element.focusVisual(); if (focusState.legendInFocus) { var options = element.options; this._showSeriesInactiveOpacity(options.series.index, options.pointIndex); } else { this._showInactiveOpacity(element); } } }; Chart.prototype._clearFocusedElement = function _clearFocusedElement () { var ref = this; var focusState = ref._focusState; if (!focusState) { return; } if (focusState.focusedElement && focusState.focusedElement.clearFocusFromVisual) { focusState.focusedElement.clearFocusFromVisual(); this._clearElementActiveDescendant(); } focusState.focusedElement = null; }; Chart.prototype._setElementActiveDescendant = function _setElementActiveDescendant (element) { if (this.options.renderAs === "canvas") { this._pseudoFocusedElement = this._createPseudoFocusedElement(element); this.element.append(this._pseudoFocusedElement); } this.element.setAttribute(ARIA_ACTIVE_DESCENDANT, element._id); }; Chart.prototype._clearElementActiveDescendant = function _clearElementActiveDescendant () { if (this._pseudoFocusedElement) { this._pseudoFocusedElement.remove(); this._pseudoFocusedElement = null; } this.element.removeAttribute(ARIA_ACTIVE_DESCENDANT); }; Chart.prototype._createPseudoFocusedElement = function _createPseudoFocusedElement (element) { var pseudoElement = document.createElement("div"); var accessibilityOptions = element.options.accessibility; pseudoElement.id = element._id; pseudoElement.setAttribute("aria-label"