UNPKG

highcharts

Version:
172 lines (171 loc) 5.5 kB
/* * * * Marker clusters module. * * (c) 2010-2025 Torstein Honsi * * Author: Wojciech Chmiel * * License: www.highcharts.com/license * * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!! * * */ 'use strict'; import A from '../../Core/Animation/AnimationUtilities.js'; const { animObject } = A; import D from '../../Core/Defaults.js'; const { defaultOptions } = D; import H from '../../Core/Globals.js'; const { composed } = H; import MarkerClusterDefaults from './MarkerClusterDefaults.js'; import MarkerClusterScatter from './MarkerClusterScatter.js'; import U from '../../Core/Utilities.js'; const { addEvent, defined, error, isFunction, merge, pushUnique, syncTimeout } = U; /* * * * Constants * * */ (defaultOptions.plotOptions || {}).series = merge((defaultOptions.plotOptions || {}).series, MarkerClusterDefaults); /* * * * Functions * * */ /** @private */ function compose(AxisClass, ChartClass, highchartsDefaultOptions, SeriesClass) { if (pushUnique(composed, 'MarkerClusters')) { const PointClass = SeriesClass.prototype.pointClass, { scatter: ScatterSeries } = SeriesClass.types; addEvent(AxisClass, 'setExtremes', onAxisSetExtremes); addEvent(ChartClass, 'render', onChartRender); addEvent(PointClass, 'drillToCluster', onPointDrillToCluster); addEvent(PointClass, 'update', onPointUpdate); addEvent(SeriesClass, 'afterRender', onSeriesAfterRender); if (ScatterSeries) { MarkerClusterScatter .compose(highchartsDefaultOptions, ScatterSeries); } } } /** * Destroy the old tooltip after zoom. * @private */ function onAxisSetExtremes() { const chart = this.chart; let animationDuration = 0; for (const series of chart.series) { if (series.markerClusterInfo) { animationDuration = (animObject((series.options.cluster || {}).animation).duration || 0); } } syncTimeout(() => { if (chart.tooltip) { chart.tooltip.destroy(); } }, animationDuration); } /** * Handle animation. * @private */ function onChartRender() { const chart = this; for (const series of (chart.series || [])) { if (series.markerClusterInfo) { const options = series.options.cluster, pointsState = (series.markerClusterInfo || {}).pointsState, oldState = (pointsState || {}).oldState; if ((options || {}).animation && series.markerClusterInfo && (series.chart.pointer?.pinchDown || []).length === 0 && ((series.xAxis || {}).eventArgs || {}).trigger !== 'pan' && oldState && Object.keys(oldState).length) { for (const cluster of series.markerClusterInfo.clusters) { series.animateClusterPoint(cluster); } for (const noise of series.markerClusterInfo.noise) { series.animateClusterPoint(noise); } } } } } /** @private */ function onPointDrillToCluster(event) { const point = event.point || event.target, series = point.series, clusterOptions = series.options.cluster, onDrillToCluster = ((clusterOptions || {}).events || {}).drillToCluster; if (isFunction(onDrillToCluster)) { onDrillToCluster.call(this, event); } } /** * Override point prototype to throw a warning when trying to update * clustered point. * @private */ function onPointUpdate() { const point = this; if (point.dataGroup) { error('Highcharts marker-clusters module: ' + 'Running `Point.update` when point belongs to clustered series' + ' is not supported.', false, point.series.chart); return false; } } /** * Add classes, change mouse cursor. * @private */ function onSeriesAfterRender() { const series = this, clusterZoomEnabled = (series.options.cluster || {}).drillToCluster; if (series.markerClusterInfo && series.markerClusterInfo.clusters) { for (const cluster of series.markerClusterInfo.clusters) { if (cluster.point && cluster.point.graphic) { cluster.point.graphic.addClass('highcharts-cluster-point'); // Change cursor to pointer when drillToCluster is enabled. if (clusterZoomEnabled && cluster.point) { cluster.point.graphic.css({ cursor: 'pointer' }); if (cluster.point.dataLabel) { cluster.point.dataLabel.css({ cursor: 'pointer' }); } } if (defined(cluster.clusterZone)) { cluster.point.graphic.addClass(cluster.clusterZoneClassName || 'highcharts-cluster-zone-' + cluster.clusterZone.zoneIndex); } } } } } /* * * * Default Export * * */ const MarkerClusters = { compose }; export default MarkerClusters; /* * * * API Options * * */ /** * Function callback when a cluster is clicked. * * @callback Highcharts.MarkerClusterDrillCallbackFunction * * @param {Highcharts.Point} this * The point where the event occurred. * * @param {Highcharts.PointClickEventObject} event * Event arguments. */ ''; // Keeps doclets above in JS file