UNPKG

highcharts

Version:
1,445 lines (1,414 loc) 383 kB
// 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