highcharts
Version:
JavaScript charting framework
1,445 lines (1,414 loc) • 383 kB
JavaScript
// SPDX-License-Identifier: LicenseRef-Highcharts
/**
* @license Highmaps JS v13.0.1 (2026-08-17)
* @module highcharts/modules/map
* @requires highcharts
*
* Highmaps as a plugin for Highcharts or Highcharts Stock.
*
* (c) 2011-2026 Highsoft AS
* Author: Torstein Hønsi
*
* A commercial license may be required depending on use,
* see www.highcharts.com/license
*/
import * as __WEBPACK_EXTERNAL_MODULE__highcharts_src_js_8202131d__ from "../highcharts.src.js";
import "./coloraxis.src.js";
/******/ // The require scope
/******/ const __webpack_require__ = {};
/******/
/************************************************************************/
/******/ /* webpack/runtime/compat get default export */
/******/ (() => {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = (module) => {
/******/ const getter = module && module.__esModule ?
/******/ () => (module['default']) :
/******/ () => (module);
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter/value functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ if(Array.isArray(definition)) {
/******/ var i = 0;
/******/ while(i < definition.length) {
/******/ var key = definition[i++];
/******/ var binding = definition[i++];
/******/ if(!__webpack_require__.o(exports, key)) {
/******/ if(binding === 0) {
/******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
/******/ } else {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
/******/ }
/******/ } else if(binding === 0) { i++; }
/******/ }
/******/ } else {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/************************************************************************/
;// external ["../highcharts.src.js","default"]
const external_highcharts_src_js_default_namespaceObject = __WEBPACK_EXTERNAL_MODULE__highcharts_src_js_8202131d__["default"];
var external_highcharts_src_js_default_default = /*#__PURE__*/__webpack_require__.n(external_highcharts_src_js_default_namespaceObject);
;// external "./coloraxis.src.js"
;// ./code/es-modules/Maps/MapNavigationDefaults.js
/* *
*
* (c) 2010-2026 Highsoft AS
* Author: Torstein Hønsi
*
* Integration of this software requires a license.
* - For commercial use, see www.highcharts.com/license
* - For non-commercial, see www.highcharts.com/license-eula
*
*
* */
/* *
*
* Constants
*
* */
const lang = {
zoomIn: 'Zoom in',
zoomOut: 'Zoom out'
};
/**
* The `mapNavigation` option handles buttons for navigation in addition to
* `mousewheel` and `doubleclick` handlers for map zooming.
*
* @product highmaps
* @optionparent mapNavigation
*/
const mapNavigation = {
/**
* General options for the map navigation buttons. Individual options
* can be given from the [mapNavigation.buttons](#mapNavigation.buttons)
* option set.
*
* @sample {highmaps} maps/mapnavigation/button-theme/
* Theming the navigation buttons
*/
buttonOptions: {
/**
* What box to align the buttons to. Possible values are `plotBox`
* and `spacingBox`.
*
* @type {Highcharts.ButtonRelativeToValue}
*/
alignTo: 'plotBox',
/**
* The alignment of the navigation buttons.
*
* @type {Highcharts.AlignValue}
*/
align: 'left',
/**
* The vertical alignment of the buttons. Individual alignment can
* be adjusted by each button's `y` offset.
*
* @type {Highcharts.VerticalAlignValue}
*/
verticalAlign: 'top',
/**
* The X offset of the buttons relative to its `align` setting.
*/
x: 0,
/**
* The width of the map navigation buttons.
*/
width: 18,
/**
* The pixel height of the map navigation buttons.
*/
height: 18,
/**
* Padding for the navigation buttons.
*
* @since 5.0.0
*/
padding: 5,
/**
* Text styles for the map navigation buttons.
*
* @type {Highcharts.CSSObject}
* @default {"fontSize": "1em", "fontWeight": "bold"}
*/
style: {
/** @ignore */
color: 'var(--highcharts-neutral-color-60)',
/** @ignore */
fontSize: '1em',
/** @ignore */
fontWeight: 'bold'
},
/**
* A configuration object for the button theme. The object accepts
* SVG properties like `stroke-width`, `stroke` and `fill`. Tri-state
* button styles are supported by the `states.hover` and `states.select`
* objects.
*
* @sample {highmaps} maps/mapnavigation/button-theme/
* Themed navigation buttons
*
* @type {Highcharts.SVGAttributes}
* @default {"stroke-width": 1, "text-align": "center"}
*/
theme: {
/** @ignore */
fill: 'var(--highcharts-background-color)',
/** @ignore */
stroke: 'var(--highcharts-neutral-color-10)',
/** @ignore */
'stroke-width': 1,
/** @ignore */
'text-align': 'center'
}
},
/**
* The individual buttons for the map navigation. This usually includes
* the zoom in and zoom out buttons. Properties for each button is
* inherited from [mapNavigation.buttonOptions](#mapNavigation.buttonOptions),
* while individual options can be overridden. But default, the `onclick`,
* `text` and `y` options are individual.
*/
buttons: {
/**
* Options for the zoom in button. Properties for the zoom in and zoom
* out buttons are inherited from
* [mapNavigation.buttonOptions](#mapNavigation.buttonOptions), while
* individual options can be overridden. By default, the `onclick`,
* `text` and `y` options are individual.
*
* @extends mapNavigation.buttonOptions
*/
zoomIn: {
// eslint-disable-next-line valid-jsdoc
/**
* Click handler for the button.
*
* @type {Function}
* @default function () { this.mapZoom(0.5); }
*/
onclick: function () {
this.mapZoom(0.5);
},
/**
* The text for the button. The tooltip (title) is a language option
* given by [lang.zoomIn](#lang.zoomIn).
*/
text: '+',
/**
* The position of the zoomIn button relative to the vertical
* alignment.
*/
y: 0
},
/**
* Options for the zoom out button. Properties for the zoom in and
* zoom out buttons are inherited from
* [mapNavigation.buttonOptions](#mapNavigation.buttonOptions), while
* individual options can be overridden. By default, the `onclick`,
* `text` and `y` options are individual.
*
* @extends mapNavigation.buttonOptions
*/
zoomOut: {
// eslint-disable-next-line valid-jsdoc
/**
* Click handler for the button.
*
* @type {Function}
* @default function () { this.mapZoom(2); }
*/
onclick: function () {
this.mapZoom(2);
},
/**
* The text for the button. The tooltip (title) is a language option
* given by [lang.zoomOut](#lang.zoomIn).
*/
text: '-',
/**
* The position of the zoomOut button relative to the vertical
* alignment.
*/
y: 28
}
},
/**
* Whether to enable navigation buttons. By default it inherits the
* [enabled](#mapNavigation.enabled) setting.
*
* @type {boolean}
* @apioption mapNavigation.enableButtons
*/
/**
* Whether to enable map navigation. The default is not to enable
* navigation, as many choropleth maps are simple and don't need it.
* Additionally, when touch zoom and mouse wheel zoom is enabled, it breaks
* the default behavior of these interactions in the website, and the
* implementer should be aware of this.
*
* Individual interactions can be enabled separately, namely buttons,
* multitouch zoom, double click zoom, double click zoom to element and
* mouse wheel zoom.
*
* @type {boolean}
* @default false
* @apioption mapNavigation.enabled
*/
/**
* Enables zooming in on an area on double clicking in the map. By default
* it inherits the [enabled](#mapNavigation.enabled) setting.
*
* @type {boolean}
* @apioption mapNavigation.enableDoubleClickZoom
*/
/**
* Whether to zoom in on an area when that area is double clicked.
*
* @sample {highmaps} maps/mapnavigation/doubleclickzoomto/
* Enable double click zoom to
*
* @type {boolean}
* @default false
* @apioption mapNavigation.enableDoubleClickZoomTo
*/
/**
* Enables zooming by mouse wheel. By default it inherits the [enabled](
* #mapNavigation.enabled) setting.
*
* @type {boolean}
* @apioption mapNavigation.enableMouseWheelZoom
*/
/**
* Whether to enable multitouch zooming. Note that if the chart covers the
* viewport, this prevents the user from using multitouch and touchdrag on
* the web page, so you should make sure the user is not trapped inside the
* chart. By default it inherits the [enabled](#mapNavigation.enabled)
* setting.
*
* @type {boolean}
* @apioption mapNavigation.enableTouchZoom
*/
/**
* Sensitivity of mouse wheel or trackpad scrolling. 1 is no sensitivity,
* while with 2, one mouse wheel delta will zoom in 50%.
*
* @since 4.2.4
*/
mouseWheelSensitivity: 1.1
// Enabled: false,
// enableButtons: null, // inherit from enabled
// enableTouchZoom: null, // inherit from enabled
// enableDoubleClickZoom: null, // inherit from enabled
// enableDoubleClickZoomTo: false
// enableMouseWheelZoom: null, // inherit from enabled
};
/* *
*
* Default Export
*
* */
const mapNavigationDefaults = {
lang,
mapNavigation
};
/* harmony default export */ const MapNavigationDefaults = (mapNavigationDefaults);
;// ./code/es-modules/Maps/MapPointer.js
/* *
*
* (c) 2010-2026 Highsoft AS
* Author: Torstein Hønsi
*
* Integration of this software requires a license.
* - For commercial use, see www.highcharts.com/license
* - For non-commercial, see www.highcharts.com/license-eula
*
*
* */
/* *
*
* Composition
*
* */
/** @internal */
var MapPointer;
(function (MapPointer) {
/* *
*
* Variables
*
* */
let totalWheelDelta = 0;
let totalWheelDeltaTimer;
/* *
*
* Functions
*
* */
/**
* Extend the Pointer.
* @internal
*/
function compose(PointerClass) {
const pointerProto = PointerClass.prototype;
if (!pointerProto.onContainerDblClick) {
(0,external_highcharts_src_js_default_namespaceObject.extend)(pointerProto, {
onContainerDblClick,
onContainerMouseWheel
});
(0,external_highcharts_src_js_default_namespaceObject.wrap)(pointerProto, 'normalize', wrapNormalize);
(0,external_highcharts_src_js_default_namespaceObject.wrap)(pointerProto, 'zoomOption', wrapZoomOption);
}
}
MapPointer.compose = compose;
/**
* The event handler for the doubleclick event.
* @internal
*/
function onContainerDblClick(e) {
const chart = this.chart;
e = this.normalize(e);
if (chart.options.mapNavigation.enableDoubleClickZoomTo) {
if (chart.pointer.inClass(e.target, 'highcharts-tracker') &&
chart.hoverPoint) {
chart.hoverPoint.zoomTo();
}
}
else if (chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)) {
chart.mapZoom(0.5, void 0, void 0, e.chartX, e.chartY);
}
}
/**
* The event handler for the mouse scroll event.
* @internal
*/
function onContainerMouseWheel(e) {
const chart = this.chart;
e = this.normalize(e);
// Firefox uses e.deltaY or e.detail, WebKit and IE uses wheelDelta
// try wheelDelta first #15656
const delta = ((0,external_highcharts_src_js_default_namespaceObject.defined)(e.wheelDelta) && -e.wheelDelta / 120) ||
e.deltaY || e.detail;
// Wheel zooming on trackpads have different behaviors in Firefox vs
// WebKit. In Firefox the delta increments in steps by 1, so it is not
// distinguishable from true mouse wheel. Therefore we use this timer
// to avoid trackpad zooming going too fast and out of control. In
// WebKit however, the delta is < 1, so we simply disable animation in
// the `chart.mapZoom` call below.
if (Math.abs(delta) >= 1) {
totalWheelDelta += Math.abs(delta);
if (totalWheelDeltaTimer) {
(0,external_highcharts_src_js_default_namespaceObject.internalClearTimeout)(totalWheelDeltaTimer);
}
totalWheelDeltaTimer = setTimeout(() => {
totalWheelDelta = 0;
}, 50);
}
if (totalWheelDelta < 10 && chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop) && chart.mapView) {
chart.mapView.zoomBy((chart.options.mapNavigation.mouseWheelSensitivity -
1) * -delta, void 0, [e.chartX, e.chartY],
// Delta less than 1 indicates stepless/trackpad zooming, avoid
// animation delaying the zoom
Math.abs(delta) < 1 ? false : void 0);
}
}
/**
* Add lon and lat information to pointer events
* @internal
*/
function wrapNormalize(proceed, e, chartPosition) {
const chart = this.chart;
e = proceed.call(this, e, chartPosition);
if (chart && chart.mapView) {
const lonLat = chart.mapView.pixelsToLonLat({
x: e.chartX - chart.plotLeft,
y: e.chartY - chart.plotTop
});
if (lonLat) {
(0,external_highcharts_src_js_default_namespaceObject.extend)(e, lonLat);
}
}
return e;
}
/**
* The pinchType is inferred from mapNavigation options.
* @internal
*/
function wrapZoomOption(proceed) {
const mapNavigation = this.chart.options.mapNavigation;
// Pinch status
if (mapNavigation &&
(0,external_highcharts_src_js_default_namespaceObject.pick)(mapNavigation.enableTouchZoom, mapNavigation.enabled)) {
this.chart.zooming.pinchType = 'xy';
}
proceed.apply(this, [].slice.call(arguments, 1));
}
})(MapPointer || (MapPointer = {}));
/* *
*
* Default Export
*
* */
/** @internal */
/* harmony default export */ const Maps_MapPointer = (MapPointer);
;// ./code/es-modules/Maps/MapSymbols.js
/* *
*
* (c) 2010-2026 Highsoft AS
* Author: Torstein Hønsi
*
* Integration of this software requires a license.
* - For commercial use, see www.highcharts.com/license
* - For non-commercial, see www.highcharts.com/license-eula
*
*
* */
/* *
*
* Variables
*
* */
let symbols;
/* *
*
* Functions
*
* */
/** @internal */
function bottomButton(x, y, w, h, options) {
if (options) {
const r = options?.r || 0;
options.brBoxY = y - r;
options.brBoxHeight = h + r;
}
return symbols.roundedRect(x, y, w, h, options);
}
/** @internal */
function compose(SVGRendererClass) {
symbols = SVGRendererClass.prototype.symbols;
symbols.bottombutton = bottomButton;
symbols.topbutton = topButton;
}
/** @internal */
function topButton(x, y, w, h, options) {
if (options) {
const r = options?.r || 0;
options.brBoxHeight = h + r;
}
return symbols.roundedRect(x, y, w, h, options);
}
/* *
*
* Default Export
*
* */
/** @internal */
const MapSymbols = {
compose
};
/** @internal */
/* harmony default export */ const Maps_MapSymbols = (MapSymbols);
;// ./code/es-modules/Maps/MapNavigation.js
/* *
*
* (c) 2010-2026 Highsoft AS
* Author: Torstein Hønsi
*
* Integration of this software requires a license.
* - For commercial use, see www.highcharts.com/license
* - For non-commercial, see www.highcharts.com/license-eula
*
*
* */
const { setOptions } = (external_highcharts_src_js_default_default());
const { composed } = (external_highcharts_src_js_default_default());
/* *
*
* Functions
*
* */
/** @internal */
function stopEvent(e) {
if (e) {
e.preventDefault?.();
e.stopPropagation?.();
e.cancelBubble = true;
}
}
/* *
*
* Class
*
* */
/**
* The MapNavigation handles buttons for navigation in addition to mousewheel
* and doubleclick handlers for chart zooming.
*
* @internal
* @class
* @name MapNavigation
*
* @param {Highcharts.Chart} chart
* The Chart instance.
*/
class MapNavigation {
/* *
*
* Static Functions
*
* */
static compose(MapChartClass, PointerClass, SVGRendererClass) {
Maps_MapPointer.compose(PointerClass);
Maps_MapSymbols.compose(SVGRendererClass);
if ((0,external_highcharts_src_js_default_namespaceObject.pushUnique)(composed, 'Map.Navigation')) {
// Extend the Chart.render method to add zooming and panning
(0,external_highcharts_src_js_default_namespaceObject.addEvent)(MapChartClass, 'beforeRender', function () {
// Render the plus and minus buttons. Doing this before the
// shapes makes getBBox much quicker, at least in Chrome.
this.mapNavigation = new MapNavigation(this);
this.mapNavigation.update();
});
setOptions(MapNavigationDefaults);
}
}
/* *
*
* Constructor
*
* */
constructor(chart) {
this.chart = chart;
this.navButtons = [];
}
/* *
*
* Functions
*
* */
/**
* Update the map navigation with new options. Calling this is the same as
* calling `chart.update({ mapNavigation: {} })`.
*
* @function MapNavigation#update
*
* @param {Partial<Highcharts.MapNavigationOptions>} [options]
* New options for the map navigation.
*/
update(options) {
const mapNav = this, chart = mapNav.chart, navButtons = mapNav.navButtons, outerHandler = function (e) {
this.handler.call(chart, e);
stopEvent(e); // Stop default click event (#4444)
};
let navOptions = chart.options.mapNavigation;
// Merge in new options in case of update, and register back to chart
// options.
if (options) {
navOptions = chart.options.mapNavigation =
(0,external_highcharts_src_js_default_namespaceObject.merge)(chart.options.mapNavigation, options);
}
// Destroy buttons in case of dynamic update
while (navButtons.length) {
navButtons.pop()?.destroy();
}
if (!chart.renderer.forExport &&
(0,external_highcharts_src_js_default_namespaceObject.pick)(navOptions.enableButtons, navOptions.enabled)) {
if (!mapNav.navButtonsGroup) {
mapNav.navButtonsGroup = chart.renderer.g()
.attr({
zIndex: 7 // #4955, #8392, #20476
})
.add();
}
(0,external_highcharts_src_js_default_namespaceObject.objectEach)(navOptions.buttons, (buttonOptions, n) => {
buttonOptions = (0,external_highcharts_src_js_default_namespaceObject.merge)(navOptions.buttonOptions, buttonOptions);
const attr = {
padding: buttonOptions.padding
};
// Presentational
if (!chart.styledMode && buttonOptions.theme) {
(0,external_highcharts_src_js_default_namespaceObject.extend)(attr, buttonOptions.theme);
attr.style = (0,external_highcharts_src_js_default_namespaceObject.merge)(buttonOptions.theme.style, buttonOptions.style // #3203
);
}
const { text, width = 0, height = 0, padding = 0 } = buttonOptions;
const button = chart.renderer
.button(
// Display the text from options only if it is not plus
// or minus
(text !== '+' && text !== '-' && text) || '', 0, 0, outerHandler, attr, void 0, void 0, void 0, n === 'zoomIn' ? 'topbutton' : 'bottombutton')
.addClass('highcharts-map-navigation highcharts-' + {
zoomIn: 'zoom-in',
zoomOut: 'zoom-out'
}[n])
.attr({
width,
height,
title: chart.options.lang[n],
zIndex: 5
})
.add(mapNav.navButtonsGroup);
// Add SVG paths for the default symbols, because the text
// representation of + and - is not sharp and position is not
// easy to control.
if (text === '+' || text === '-') {
// Mysterious +1 to achieve centering
const w = width + 1, d = [
['M', padding + 3, padding + height / 2],
['L', padding + w - 3, padding + height / 2]
];
if (text === '+') {
d.push(['M', padding + w / 2, padding + 3], ['L', padding + w / 2, padding + height - 3]);
}
chart.renderer
.path(d)
.addClass('highcharts-button-symbol')
.attr(chart.styledMode ? {} : {
stroke: buttonOptions.style?.color,
'stroke-width': 3,
'stroke-linecap': 'round'
})
.add(button);
}
button.handler = buttonOptions.onclick;
// Stop double click event (#4444)
(0,external_highcharts_src_js_default_namespaceObject.addEvent)(button.element, 'dblclick', stopEvent);
navButtons.push(button);
(0,external_highcharts_src_js_default_namespaceObject.extend)(buttonOptions, {
width: button.width,
height: 2 * (button.height || 0)
});
if (!chart.hasLoaded) {
// Align it after the plotBox is known (#12776)
const unbind = (0,external_highcharts_src_js_default_namespaceObject.addEvent)(chart, 'load', () => {
// #15406: Make sure button hasn't been destroyed
if (button.element) {
button.align(buttonOptions, false, buttonOptions.alignTo);
}
unbind();
});
}
else {
button.align(buttonOptions, false, buttonOptions.alignTo);
}
});
// Borrowed from overlapping-datalabels. Consider a shared module.
const isIntersectRect = (box1, box2) => !(box2.x >= box1.x + box1.width ||
box2.x + box2.width <= box1.x ||
box2.y >= box1.y + box1.height ||
box2.y + box2.height <= box1.y);
// Check the mapNavigation buttons collision with exporting button
// and translate the mapNavigation button if they overlap.
const adjustMapNavBtn = function () {
const expBtnBBox = chart.exporting?.group?.getBBox();
if (expBtnBBox) {
const navBtnsBBox = mapNav.navButtonsGroup.getBBox();
// If buttons overlap
if (isIntersectRect(expBtnBBox, navBtnsBBox)) {
// Adjust the mapNav buttons' position by translating
// them above or below the exporting button
const aboveExpBtn = -navBtnsBBox.y -
navBtnsBBox.height + expBtnBBox.y - 5, belowExpBtn = expBtnBBox.y + expBtnBBox.height -
navBtnsBBox.y + 5, mapNavVerticalAlign = (navOptions.buttonOptions &&
navOptions.buttonOptions.verticalAlign);
// If bottom aligned and adjusting the mapNav button
// would translate it out of the plotBox, translate it
// up instead of down
mapNav.navButtonsGroup.attr({
translateY: mapNavVerticalAlign === 'bottom' ?
aboveExpBtn :
belowExpBtn
});
}
}
};
if (!chart.hasLoaded) {
// Align it after the plotBox is known (#12776) and after the
// hamburger button's position is known so they don't overlap
// (#15782)
(0,external_highcharts_src_js_default_namespaceObject.addEvent)(chart, 'render', adjustMapNavBtn);
}
}
this.updateEvents(navOptions);
}
/**
* Update events, called internally from the update function. Add new event
* handlers, or unbinds events if disabled.
*
* @function MapNavigation#updateEvents
*
* @param {Partial<Highcharts.MapNavigationOptions>} options
* Options for map navigation.
*/
updateEvents(options) {
const chart = this.chart;
// Add the double click event
if ((0,external_highcharts_src_js_default_namespaceObject.pick)(options.enableDoubleClickZoom, options.enabled) ||
options.enableDoubleClickZoomTo) {
this.unbindDblClick = this.unbindDblClick || (0,external_highcharts_src_js_default_namespaceObject.addEvent)(chart.container, 'dblclick', function (e) {
chart.pointer.onContainerDblClick(e);
});
}
else if (this.unbindDblClick) {
// Unbind and set unbinder to undefined
this.unbindDblClick = this.unbindDblClick();
}
// Add the mousewheel event
if ((0,external_highcharts_src_js_default_namespaceObject.pick)(options.enableMouseWheelZoom, options.enabled)) {
this.unbindMouseWheel = this.unbindMouseWheel || (0,external_highcharts_src_js_default_namespaceObject.addEvent)(chart.container, 'wheel', function (e) {
// Prevent scrolling when the pointer is over the element
// with that class, for example annotation popup #12100.
if (!chart.pointer.inClass(e.target, 'highcharts-no-mousewheel')) {
const initialZoom = chart.mapView?.zoom;
chart.pointer.onContainerMouseWheel(e);
// If the zoom level changed, prevent the default action
// which is to scroll the page
if (initialZoom !== chart.mapView?.zoom) {
stopEvent(e);
}
}
return false;
});
}
else if (this.unbindMouseWheel) {
// Unbind and set unbinder to undefined
this.unbindMouseWheel = this.unbindMouseWheel();
}
}
}
/* *
*
* Default Export
*
* */
/** @internal */
/* harmony default export */ const Maps_MapNavigation = (MapNavigation);
;// external ["../highcharts.src.js","default","SeriesRegistry"]
const external_highcharts_src_js_default_SeriesRegistry_namespaceObject = __WEBPACK_EXTERNAL_MODULE__highcharts_src_js_8202131d__["default"].SeriesRegistry;
var external_highcharts_src_js_default_SeriesRegistry_default = /*#__PURE__*/__webpack_require__.n(external_highcharts_src_js_default_SeriesRegistry_namespaceObject);
;// external ["../highcharts.src.js","default","SVGElement"]
const external_highcharts_src_js_default_SVGElement_namespaceObject = __WEBPACK_EXTERNAL_MODULE__highcharts_src_js_8202131d__["default"].SVGElement;
var external_highcharts_src_js_default_SVGElement_default = /*#__PURE__*/__webpack_require__.n(external_highcharts_src_js_default_SVGElement_namespaceObject);
;// ./code/es-modules/Series/ColorMapComposition.js
/* *
*
* (c) 2010-2026 Highsoft AS
* Author: Torstein Hønsi
*
* Integration of this software requires a license.
* - For commercial use, see www.highcharts.com/license
* - For non-commercial, see www.highcharts.com/license-eula
*
*
* */
const { column: { prototype: columnProto } } = (external_highcharts_src_js_default_SeriesRegistry_default()).seriesTypes;
/* *
*
* Composition
*
* */
var ColorMapComposition;
(function (ColorMapComposition) {
/* *
*
* Constants
*
* */
/** @internal */
ColorMapComposition.pointMembers = {
dataLabelOnNull: true,
moveToTopOnHover: true,
isValid: pointIsValid
};
/** @internal */
ColorMapComposition.seriesMembers = {
colorKey: 'value',
axisTypes: ['xAxis', 'yAxis', 'colorAxis'],
parallelArrays: ['x', 'y', 'value'],
pointArrayMap: ['value'],
trackerGroups: ['group', 'markerGroup', 'dataLabelsGroup'],
colorAttribs: seriesColorAttribs,
pointAttribs: columnProto.pointAttribs
};
/* *
*
* Functions
*
* */
/**
* @internal
*/
function compose(SeriesClass) {
const PointClass = SeriesClass.prototype.pointClass;
(0,external_highcharts_src_js_default_namespaceObject.addEvent)(PointClass, 'afterSetState', onPointAfterSetState);
return SeriesClass;
}
ColorMapComposition.compose = compose;
/**
* Move points to the top of the z-index order when hovered.
* @internal
*/
function onPointAfterSetState(e) {
const point = this, series = point.series, renderer = series.chart.renderer;
if (point.moveToTopOnHover && point.graphic) {
if (!series.stateMarkerGraphic) {
// Create a `use` element and add it to the end of the group,
// which would make it appear on top of the other elements. This
// deals with z-index without reordering DOM elements (#13049).
series.stateMarkerGraphic = new (external_highcharts_src_js_default_SVGElement_default())(renderer, 'use')
.css({
pointerEvents: 'none'
})
.add(point.graphic.parentGroup);
}
if (e?.state === 'hover') {
// Give the graphic DOM element the same id as the Point
// instance
point.graphic.attr({
id: this.id
});
series.stateMarkerGraphic.attr({
href: `${renderer.url}#${this.id}`,
visibility: 'visible'
});
}
else {
series.stateMarkerGraphic.attr({
href: ''
});
}
}
}
/**
* Color points have a value option that determines whether or not it is
* a null point
* @internal
*/
function pointIsValid() {
return (this.value !== null &&
this.value !== Infinity &&
this.value !== -Infinity &&
// Undefined is allowed, but NaN is not (#17279)
(this.value === void 0 || !isNaN(this.value)));
}
/**
* Get the color attributes to apply on the graphic
* @internal
* @function Highcharts.colorMapSeriesMixin.colorAttribs
* @param {Highcharts.Point} point
* @return {Highcharts.SVGAttributes}
* The SVG attributes
*/
function seriesColorAttribs(point) {
const ret = {};
if ((0,external_highcharts_src_js_default_namespaceObject.defined)(point.color) &&
(!point.state || point.state === 'normal') // #15746
) {
ret[this.colorProp || 'fill'] = point.color;
}
return ret;
}
})(ColorMapComposition || (ColorMapComposition = {}));
/* *
*
* Default Export
*
* */
/** @internal */
/* harmony default export */ const Series_ColorMapComposition = (ColorMapComposition);
;// ./code/es-modules/Series/CenteredUtilities.js
/* *
*
* (c) 2010-2026 Highsoft AS
* Author: Torstein Hønsi
*
* Integration of this software requires a license.
* - For commercial use, see www.highcharts.com/license
* - For non-commercial, see www.highcharts.com/license-eula
*
*
* */
const { deg2rad } = (external_highcharts_src_js_default_default());
/**
* @internal
*/
var CenteredUtilities;
(function (CenteredUtilities) {
/* *
*
* Declarations
*
* */
/* *
*
* Functions
*
* */
/**
* Get the center of the pie based on the size and center options relative
* to the plot area. Borrowed by the polar and gauge series types.
*
* @internal
* @function Highcharts.CenteredSeriesMixin.getCenter
*/
function getCenter() {
const options = this.options, chart = this.chart, slicingRoom = 2 * (options.slicedOffset || 0), plotWidth = chart.plotWidth - 2 * slicingRoom, plotHeight = chart.plotHeight - 2 * slicingRoom, centerOption = options.center, smallestSize = Math.min(plotWidth, plotHeight), thickness = options.thickness;
let handleSlicingRoom, size = options.size, innerSize = options.innerSize || 0, i, value;
if (typeof size === 'string') {
size = parseFloat(size);
}
if (typeof innerSize === 'string') {
innerSize = parseFloat(innerSize);
}
const positions = [
(0,external_highcharts_src_js_default_namespaceObject.pick)(centerOption?.[0], '50%'),
(0,external_highcharts_src_js_default_namespaceObject.pick)(centerOption?.[1], '50%'),
// Prevent from negative values
(0,external_highcharts_src_js_default_namespaceObject.pick)(size && size < 0 ? void 0 : options.size, '100%'),
(0,external_highcharts_src_js_default_namespaceObject.pick)(innerSize && innerSize < 0 ? void 0 : options.innerSize || 0, '0%')
];
for (i = 0; i < 4; ++i) {
value = positions[i];
handleSlicingRoom = i < 2 || (i === 2 && /%$/.test(value));
// I == 0: centerX, relative to width
// i == 1: centerY, relative to height
// i == 2: size, relative to smallestSize
// i == 3: innerSize, relative to size
positions[i] = (0,external_highcharts_src_js_default_namespaceObject.relativeLength)(value, [plotWidth, plotHeight, smallestSize, positions[2]][i]) + (handleSlicingRoom ? slicingRoom : 0);
}
// Inner size cannot be larger than size (#3632)
if (positions[3] > positions[2]) {
positions[3] = positions[2];
}
// Thickness overrides innerSize, need to be less than pie size (#6647)
if ((0,external_highcharts_src_js_default_namespaceObject.isNumber)(thickness) &&
thickness * 2 < positions[2] && thickness > 0) {
positions[3] = positions[2] - thickness * 2;
}
(0,external_highcharts_src_js_default_namespaceObject.fireEvent)(this, 'afterGetCenter', { positions });
return positions;
}
CenteredUtilities.getCenter = getCenter;
/**
* GetStartAndEndRadians - Calculates start and end angles in radians.
* Used in series types such as pie and sunburst.
*
* @internal
* @function Highcharts.CenteredSeriesMixin.getStartAndEndRadians
*
* @param {number} [start]
* Start angle in degrees.
*
* @param {number} [end]
* Start angle in degrees.
*
* @return {Highcharts.RadianAngles}
* Returns an object containing start and end angles as radians.
*/
function getStartAndEndRadians(start, end) {
const startAngle = (0,external_highcharts_src_js_default_namespaceObject.isNumber)(start) ? start : 0, // Must be a number
endAngle = (((0,external_highcharts_src_js_default_namespaceObject.isNumber)(end) && // Must be a number
end > startAngle && // Must be larger than the start angle
// difference must be less than 360 degrees
(end - startAngle) < 360) ?
end :
startAngle + 360), correction = -90;
return {
start: deg2rad * (startAngle + correction),
end: deg2rad * (endAngle + correction)
};
}
CenteredUtilities.getStartAndEndRadians = getStartAndEndRadians;
})(CenteredUtilities || (CenteredUtilities = {}));
/* *
*
* Default Export
*
* */
/** @internal */
/* harmony default export */ const Series_CenteredUtilities = (CenteredUtilities);
/* *
*
* API Declarations
*
* */
/**
* @internal
* @interface Highcharts.RadianAngles
*/ /**
* @name Highcharts.RadianAngles#end
* @type {number}
*/ /**
* @name Highcharts.RadianAngles#start
* @type {number}
*/
''; // Keeps doclets above in JS file
;// ./code/es-modules/Data/ColumnUtils.js
/* *
*
* (c) 2020-2026 Highsoft AS
*
* Integration of this software requires a license.
* - For commercial use, see www.highcharts.com/license
* - For non-commercial, see www.highcharts.com/license-eula
*
*
* Authors:
* - Dawid Draguła
*
* */
/* *
*
* Functions
*
* */
/**
* Sets the length of the column array.
*
* @param {DataTableColumn} column
* Column to be modified.
*
* @param {number} length
* New length of the column.
*
* @param {boolean} asSubarray
* If column is a typed array, return a subarray instead of a new array. It
* is faster `O(1)`, but the entire buffer will be kept in memory until all
* views of it are destroyed. Default is `false`.
*
* @return {DataTableColumn}
* Modified column.
*
* @private
*/
function setLength(column, length, asSubarray) {
if (Array.isArray(column)) {
column.length = length;
return column;
}
return column[asSubarray ? 'subarray' : 'slice'](0, length);
}
/**
* Splices a column array.
*
* @param {DataTableColumn} column
* Column to be modified.
*
* @param {number} start
* Index at which to start changing the array.
*
* @param {number} deleteCount
* An integer indicating the number of old array elements to remove.
*
* @param {boolean} removedAsSubarray
* If column is a typed array, return a subarray instead of a new array. It
* is faster `O(1)`, but the entire buffer will be kept in memory until all
* views to it are destroyed. Default is `true`.
*
* @param {Array<number>|TypedArray} items
* The elements to add to the array, beginning at the start index. If you
* don't specify any elements, `splice()` will only remove elements from the
* array.
*
* @return {SpliceResult}
* Object containing removed elements and the modified column.
*
* @private
*/
function splice(column, start, deleteCount, removedAsSubarray, items = []) {
if (Array.isArray(column)) {
if (!Array.isArray(items)) {
items = Array.from(items);
}
return {
removed: column.splice(start, deleteCount, ...items),
array: column
};
}
const Constructor = Object.getPrototypeOf(column)
.constructor;
const removed = column[removedAsSubarray ? 'subarray' : 'slice'](start, start + deleteCount);
const newLength = column.length - deleteCount + items.length;
const result = new Constructor(newLength);
result.set(column.subarray(0, start), 0);
result.set(items, start);
result.set(column.subarray(start + deleteCount), start + items.length);
return {
removed: removed,
array: result
};
}
/**
* Converts a cell value to a number.
*
* @param {DataTableCellType} value
* Cell value to convert to a number.
*
* @param {boolean} useNaN
* If `true`, returns `NaN` for non-numeric values; if `false`,
* returns `null` instead.
*
* @return {number | null}
* Number or `null` if the value is not a number.
*
* @private
*/
function convertToNumber(value, useNaN) {
switch (typeof value) {
case 'boolean':
return (value ? 1 : 0);
case 'number':
return (isNaN(value) && !useNaN ? null : value);
default:
value = parseFloat(`${value ?? ''}`);
return (isNaN(value) && !useNaN ? null : value);
}
}
/* *
*
* Default Export
*
* */
const ColumnUtils = {
convertToNumber,
setLength,
splice
};
/* harmony default export */ const Data_ColumnUtils = (ColumnUtils);
;// ./code/es-modules/Data/DataTableCore.js
/* *
*
* (c) 2009-2026 Highsoft AS
*
* Integration of this software requires a license.
* - For commercial use, see www.highcharts.com/license
* - For non-commercial, see www.highcharts.com/license-eula
*
*
* Authors:
* - Sophie Bremer
* - Gøran Slettemark
* - Torstein Hønsi
*
* */
const { setLength: DataTableCore_setLength, splice: DataTableCore_splice } = Data_ColumnUtils;
/* *
*
* Class
*
* */
/**
* Class to manage columns and rows in a table structure. It provides methods
* to add, remove, and manipulate columns and rows, as well as to retrieve data
* from specific cells.
*
* Highcharts allows passing a `DataTable` or a configuration object for a data
* table in the `dataTable` property, either chart-level
* [dataTable](https://api.highcharts.com/highcharts/dataTable) or as
* [series.dataTable](https://api.highcharts.com/highcharts/series.dataTable).
* The `DataTable` is then used as a source for the series data points, mapped
* by the `series.dataMapping` option.
*
* After chart instantiation, the data table can be accessed from the series as
* `series.dataTable`. CRUD operations on the data table will be reflected in
* the chart.
*
* @example
* const dataTable = new Highcharts.DataTable({
* columns: {
* year: [2020, 2021, 2022, 2023],
* cost: [11, 13, 12, 14],
* revenue: [12, 15, 14, 18]
* }
* });
*
* @class
* @name Highcharts.DataTable
*
* @param {Highcharts.DataTableOptionsObject} [options]
* Options to initialize the new DataTable instance.
*/
class DataTableCore {
constructor(options = {}) {
this.isDataTable = true;
this.autoId = !options.id;
this.columns = {};
this.id = (options.id || (0,external_highcharts_src_js_default_namespaceObject.uniqueKey)());
this.rowCount = 0;
this.versionTag = (0,external_highcharts_src_js_default_namespaceObject.uniqueKey)();
let rowCount = 0;
(0,external_highcharts_src_js_default_namespaceObject.objectEach)(options.columns || {}, (column, columnId) => {
this.columns[columnId] = column.slice();
rowCount = Math.max(rowCount, column.length);
});
this.applyRowCount(rowCount);
}
/* *
*
* Functions
*
* */
/**
* Applies a row count to the table by setting the `rowCount` property and
* adjusting the length of all columns.
*
* @private
* @param {number} rowCount The new row count.
*/
applyRowCount(rowCount) {
this.rowCount = rowCount;
(0,external_highcharts_src_js_default_namespaceObject.objectEach)(this.columns, (column, columnId) => {
if (column.length !== rowCount) {
this.columns[columnId] = DataTableCore_setLength(column, rowCount);
}
});
}
/**
* Delete rows. Simplified version of the full
* `DataTable.deleteRows` method.
*
* @sample highcharts/datatable/live-chart/
* Add and delete rows in a live chart
* @sample highcharts/datatable/shared-with-grid/
* Chart with data table CRUD operations
*
* @function Highcharts.DataTable#deleteRows
*
* @param {number} rowIndex
* The start row index
*
* @param {number} [rowCount=1]
* The number of rows to delete
*
* @return {void}
*
* @emits #afterDeleteRows
*/
deleteRows(rowIndex, rowCount = 1) {
if (rowCount > 0 && rowIndex < this.rowCount) {
let length = 0;
(0,external_highcharts_src_js_default_namespaceObject.objectEach)(this.columns, (column, columnId) => {
this.columns[columnId] =
DataTableCore_splice(column, rowIndex, rowCount).array;
length = column.length;
});
this.rowCount = length;
}
(0,external_highcharts_src_js_default_namespaceObject.fireEvent)(this, 'afterDeleteRows', { rowIndex, rowCount });
this.versionTag = (0,external_highcharts_src_js_default_namespaceObject.uniqueKey)();
}
/**
* Fetches the given column by the canonical column ID. Simplified version
* of the full `DataTable.getRow` method, always returning by reference.
*
* @function Highcharts.DataTable#getColumn
*
* @param {string} columnId
* ID of the column to get.
*
* @return {Highcharts.DataTableColumn|undefined}
* A copy of the column, or `undefined` if not found.
*/
getColumn(columnId,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
asReference) {
return this.columns[columnId];
}
/**
* Retrieves all or the given columns. Simplified version of the full
* `DataTable.getColumns` method, always returning by reference.
*
* @function Highcharts.DataTable#getColumns
*
* @param {Array<string>} [columnIds]
* Column ids to retrieve.
*
* @return {Highcharts.DataTableColumnCollection}
* Collection of columns. If a requested column was not found, it is
* `undefined`.
*/
getColumns(columnIds,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
asReference) {
return (columnIds || Object.keys(this.columns)).reduce((columns, columnId) => {
columns[columnId] = this.columns[columnId];
return columns;
}, {});
}
/**
* Retrieves the row at a given index.
*
* @function Highcharts.DataTable#getRowObject
*
* @param {number} rowIndex
* Row index to retrieve. First row has index 0.
*
* @param {Array<string>} [columnNames]
* Column names to retrieve.
*
* @return {Record<string, number|string|undefined>|undefined}
* Returns the row values, or `undefined` if not found.
*/
getRowObject(rowIndex, columnNames) {
const row = {}, columns = this.columns;
columnNames ?? (columnNames = Object.keys(this.columns));
for (const columnName of columnNames) {
row[columnName] = columns[columnName]?.[rowIndex];
}
return row;
}
/**
* Sets cell values for a column. Will insert a new column, if not found.
*
* @function Highcharts.DataTable#setColumn
*
* @param {string} columnId
* Column name to set.
*
* @param {Highcharts.DataTableColumn} [column]
* Values to set in the column.
*
* @param {number} [rowIndex]
* Index of the first row to change. (Default: 0)
*
* @param {Record<string, (boolean|number|string|null|undefined)>} [eventDetail]
* Custom information for pending events.
*
* @emits #setColumns
* @emits #afterSetColumns
*/
setColumn(columnId, column = [], rowIndex = 0, eventDetail) {
this.setColumns({ [columnId]: column }, rowIndex, eventDetail);
}
/**
* Sets cell values for multiple columns. Will insert new columns, if not
* found. Simplified version of the full `DataTable.setColumns`, limited
* to full replacement of the columns (undefined `rowIndex`).
*
* @sample highcharts/datatable/shared-with-grid/
* Chart with data table CRUD operations
*
* @function Highcharts.DataTable#setColumns
*
* @param {Highcharts.DataTableColumnCollection} columns
* Columns as a collection, where the keys are the column names.
*
* @param {number} [rowIndex]
* Index of the first