package.es-modules.Extensions.MarkerClusters.MarkerClusters.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of highcharts Show documentation
Show all versions of highcharts Show documentation
JavaScript charting framework
The newest version!
/* *
*
* Marker clusters module.
*
* (c) 2010-2024 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