| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391 | /** * @license  Highcharts JS v7.0.2 (2019-01-17) * Tilemap module * * (c) 2010-2019 Highsoft AS * * License: www.highcharts.com/license */'use strict';(function (factory) {	if (typeof module === 'object' && module.exports) {		factory['default'] = factory;		module.exports = factory;	} else if (typeof define === 'function' && define.amd) {		define(function () {			return factory;		});	} else {		factory(typeof Highcharts !== 'undefined' ? Highcharts : undefined);	}}(function (Highcharts) {	(function (H) {		/**		 * (c) 2010-2019 Torstein Honsi		 *		 * License: www.highcharts.com/license		 */		var defined = H.defined,		    noop = H.noop,		    seriesTypes = H.seriesTypes;		/**		 * Mixin for maps and heatmaps		 *		 * @private		 * @mixin Highcharts.colorPointMixin		 */		H.colorPointMixin = {		    /**		     * Color points have a value option that determines whether or not it is		     * a null point		     *		     * @function Highcharts.colorPointMixin.isValid		     *		     * @return {boolean}		     */		    isValid: function () {		        // undefined is allowed		        return (		            this.value !== null &&		            this.value !== Infinity &&		            this.value !== -Infinity		        );		    },		    /**		     * Set the visibility of a single point		     *		     * @function Highcharts.colorPointMixin.setVisible		     *		     * @param {boolean} visible		     */		    setVisible: function (vis) {		        var point = this,		            method = vis ? 'show' : 'hide';		        point.visible = Boolean(vis);		        // Show and hide associated elements		        ['graphic', 'dataLabel'].forEach(function (key) {		            if (point[key]) {		                point[key][method]();		            }		        });		    },		    /**		     * @function Highcharts.colorPointMixin.setState		     *		     * @param {string} state		     */		    setState: function (state) {		        H.Point.prototype.setState.call(this, state);		        if (this.graphic) {		            this.graphic.attr({		                zIndex: state === 'hover' ? 1 : 0		            });		        }		    }		};		/**		 * @private		 * @mixin Highcharts.colorSeriesMixin		 */		H.colorSeriesMixin = {		    pointArrayMap: ['value'],		    axisTypes: ['xAxis', 'yAxis', 'colorAxis'],		    optionalAxis: 'colorAxis',		    trackerGroups: ['group', 'markerGroup', 'dataLabelsGroup'],		    getSymbol: noop,		    parallelArrays: ['x', 'y', 'value'],		    colorKey: 'value',		    pointAttribs: seriesTypes.column.prototype.pointAttribs,		    /**		     * In choropleth maps, the color is a result of the value, so this needs		     * translation too		     *		     * @function Highcharts.colorSeriesMixin.translateColors		     */		    translateColors: function () {		        var series = this,		            nullColor = this.options.nullColor,		            colorAxis = this.colorAxis,		            colorKey = this.colorKey;		        this.data.forEach(function (point) {		            var value = point[colorKey],		                color;		            color = point.options.color ||		                (		                    point.isNull ?		                        nullColor :		                        (colorAxis && value !== undefined) ?		                            colorAxis.toColor(value, point) :		                            point.color || series.color		                );		            if (color) {		                point.color = color;		            }		        });		    },		    /**		     * Get the color attibutes to apply on the graphic		     *		     * @function Highcharts.colorSeriesMixin.colorAttribs		     *		     * @param {Highcharts.Point} point		     *		     * @return {Highcharts.Dictionary<Highcharts.ColorString>}		     */		    colorAttribs: function (point) {		        var ret = {};		        if (defined(point.color)) {		            ret[this.colorProp || 'fill'] = point.color;		        }		        return ret;		    }		};	}(Highcharts));	(function (H) {		/**		 * (c) 2010-2019 Torstein Honsi		 *		 * License: www.highcharts.com/license		 */		var colorPointMixin = H.colorPointMixin,		    colorSeriesMixin = H.colorSeriesMixin,		    LegendSymbolMixin = H.LegendSymbolMixin,		    merge = H.merge,		    noop = H.noop,		    pick = H.pick,		    Series = H.Series,		    seriesType = H.seriesType,		    seriesTypes = H.seriesTypes;		/**		 * @private		 * @class		 * @name Highcharts.seriesTypes.heatmap		 *		 * @augments Highcharts.Series		 */		seriesType(		    'heatmap',		    'scatter'		    /**		     * A heatmap is a graphical representation of data where the individual		     * values contained in a matrix are represented as colors.		     *		     * @sample highcharts/demo/heatmap/		     *         Simple heatmap		     * @sample highcharts/demo/heatmap-canvas/		     *         Heavy heatmap		     *		     * @extends      plotOptions.scatter		     * @excluding    animationLimit, connectEnds, connectNulls, dashStyle,		     *               findNearestPointBy, getExtremesFromAll, jitter, linecap,		     *               lineWidth, marker, pointInterval, pointIntervalUnit,		     *               pointRange, pointStart, shadow, softThreshold, stacking,		     *               step, threshold		     * @product      highcharts highmaps		     * @optionparent plotOptions.heatmap		     */		    , {		        /**		         * Animation is disabled by default on the heatmap series.		         */		        animation: false,		        /**		         * The border width for each heat map item.		         */		        borderWidth: 0,		        /**		         * Padding between the points in the heatmap.		         *		         * @type      {number}		         * @default   0		         * @since     6.0		         * @apioption plotOptions.heatmap.pointPadding		         */		        /**		         * The main color of the series. In heat maps this color is rarely used,		         * as we mostly use the color to denote the value of each point. Unless		         * options are set in the [colorAxis](#colorAxis), the default value		         * is pulled from the [options.colors](#colors) array.		         *		         * @type      {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}		         * @since     4.0		         * @product   highcharts		         * @apioption plotOptions.heatmap.color		         */		        /**		         * The column size - how many X axis units each column in the heatmap		         * should span.		         *		         * @sample {highcharts} maps/demo/heatmap/		         *         One day		         * @sample {highmaps} maps/demo/heatmap/		         *         One day		         *		         * @type      {number}		         * @default   1		         * @since     4.0		         * @product   highcharts highmaps		         * @apioption plotOptions.heatmap.colsize		         */		        /**		         * The row size - how many Y axis units each heatmap row should span.		         *		         * @sample {highcharts} maps/demo/heatmap/		         *         1 by default		         * @sample {highmaps} maps/demo/heatmap/		         *         1 by default		         *		         * @type      {number}		         * @default   1		         * @since     4.0		         * @product   highcharts highmaps		         * @apioption plotOptions.heatmap.rowsize		         */		        /**		         * The color applied to null points. In styled mode, a general CSS class		         * is applied instead.		         *		         * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}		         */		        nullColor: '#f7f7f7',		        dataLabels: {		            formatter: function () { // #2945		                return this.point.value;		            },		            inside: true,		            verticalAlign: 'middle',		            crop: false,		            overflow: false,		            padding: 0 // #3837		        },		        /** @ignore */		        marker: null,		        /**		     * @ignore		     */		        pointRange: null, // dynamically set to colsize by default		        tooltip: {		            pointFormat: '{point.x}, {point.y}: {point.value}<br/>'		        },		        states: {		            hover: {		                /** @ignore */		                halo: false, // #3406, halo is disabled on heatmaps by default		                /**		             * How much to brighten the point on interaction. Requires the main		             * color to be defined in hex or rgb(a) format.		             *		             * In styled mode, the hover brightening is by default replaced with		             * a fill-opacity set in the `.highcharts-point:hover` rule.		             */		                brightness: 0.2		            }		        }		    }, merge(colorSeriesMixin, {		        pointArrayMap: ['y', 'value'],		        hasPointSpecificOptions: true,		        getExtremesFromAll: true,		        directTouch: true,		        /**		     * Override the init method to add point ranges on both axes.		     *		     * @private		     * @function Highcharts.seriesTypes.heatmap#init		     */		        init: function () {		            var options;		            seriesTypes.scatter.prototype.init.apply(this, arguments);		            options = this.options;		            // #3758, prevent resetting in setData		            options.pointRange = pick(options.pointRange, options.colsize || 1);		            // general point range		            this.yAxis.axisPointRange = options.rowsize || 1;		        },		        /**		     * @private		     * @function Highcharts.seriesTypes.heatmap#translate		     */		        translate: function () {		            var series = this,		                options = series.options,		                xAxis = series.xAxis,		                yAxis = series.yAxis,		                seriesPointPadding = options.pointPadding || 0,		                between = function (x, a, b) {		                    return Math.min(Math.max(a, x), b);		                },		                pointPlacement = series.pointPlacementToXValue(); // #7860		            series.generatePoints();		            series.points.forEach(function (point) {		                var xPad = (options.colsize || 1) / 2,		                    yPad = (options.rowsize || 1) / 2,		                    x1 = between(		                        Math.round(		                            xAxis.len -		                        xAxis.translate(point.x - xPad,		                            0,		                            1,		                            0,		                            1,		                            -pointPlacement)		                        ),		                        -xAxis.len, 2 * xAxis.len		                    ),		                    x2 = between(		                        Math.round(		                            xAxis.len -		                        xAxis.translate(point.x + xPad,		                            0,		                            1,		                            0,		                            1,		                            -pointPlacement)		                        ),		                        -xAxis.len, 2 * xAxis.len		                    ),		                    y1 = between(		                        Math.round(yAxis.translate(point.y - yPad, 0, 1, 0, 1)),		                        -yAxis.len, 2 * yAxis.len		                    ),		                    y2 = between(		                        Math.round(yAxis.translate(point.y + yPad, 0, 1, 0, 1)),		                        -yAxis.len, 2 * yAxis.len		                    ),		                    pointPadding = pick(point.pointPadding, seriesPointPadding);		                // Set plotX and plotY for use in K-D-Tree and more		                point.plotX = point.clientX = (x1 + x2) / 2;		                point.plotY = (y1 + y2) / 2;		                point.shapeType = 'rect';		                point.shapeArgs = {		                    x: Math.min(x1, x2) + pointPadding,		                    y: Math.min(y1, y2) + pointPadding,		                    width: Math.abs(x2 - x1) - pointPadding * 2,		                    height: Math.abs(y2 - y1) - pointPadding * 2		                };		            });		            series.translateColors();		        },		        /**		         * @private		         * @function Highcharts.seriesTypes.heatmap#drawPoints		         */		        drawPoints: function () {		            // In styled mode, use CSS, otherwise the fill used in the style		            // sheet will take precedence over the fill attribute.		            var func = this.chart.styledMode ? 'css' : 'attr';		            seriesTypes.column.prototype.drawPoints.call(this);		            this.points.forEach(function (point) {		                point.graphic[func](this.colorAttribs(point));		            }, this);		        },		        /**		         * @ignore		         * @deprecated		         * @function Highcharts.seriesTypes.heatmap#animate		         */		        animate: noop,		        /**		         * @ignore		         * @deprecated		         * @function Highcharts.seriesTypes.heatmap#getBox		         */		        getBox: noop,		        /**		         * @private		         * @borrows Highcharts.LegendSymbolMixin.drawRectangle as Highcharts.seriesTypes.heatmap#drawLegendSymbol		         */		        drawLegendSymbol: LegendSymbolMixin.drawRectangle,		        /**		         * @private		         * @borrows Highcharts.seriesTypes.column#alignDataLabel as Highcharts.seriesTypes.heatmap#alignDataLabel		         */		        alignDataLabel: seriesTypes.column.prototype.alignDataLabel,		        /**		         * @private		         * @function Highcharts.seriesTypes.heatmap#getExtremes		         */		        getExtremes: function () {		        // Get the extremes from the value data		            Series.prototype.getExtremes.call(this, this.valueData);		            this.valueMin = this.dataMin;		            this.valueMax = this.dataMax;		            // Get the extremes from the y data		            Series.prototype.getExtremes.call(this);		        }		    }), H.extend({		        /**		         * @private		         * @function Highcharts.Point#haloPath		         *		         * @param {number} size		         *		         * @return {Highcharts.SVGPathArray}		         */		        haloPath: function (size) {		            if (!size) {		                return [];		            }		            var rect = this.shapeArgs;		            return [		                'M', rect.x - size, rect.y - size,		                'L', rect.x - size, rect.y + rect.height + size,		                rect.x + rect.width + size, rect.y + rect.height + size,		                rect.x + rect.width + size, rect.y - size,		                'Z'		            ];		        }		    }, colorPointMixin)		);		/**		 * A `heatmap` series. If the [type](#series.heatmap.type) option is		 * not specified, it is inherited from [chart.type](#chart.type).		 *		 * @extends   series,plotOptions.heatmap		 * @excluding dataParser, dataURL, marker, pointRange, stack		 * @product   highcharts highmaps		 * @apioption series.heatmap		 */		/**		 * An array of data points for the series. For the `heatmap` series		 * type, points can be given in the following ways:		 *		 * 1.  An array of arrays with 3 or 2 values. In this case, the values		 * correspond to `x,y,value`. If the first value is a string, it is		 * applied as the name of the point, and the `x` value is inferred.		 * The `x` value can also be omitted, in which case the inner arrays		 * should be of length 2\. Then the `x` value is automatically calculated,		 * either starting at 0 and incremented by 1, or from `pointStart`		 * and `pointInterval` given in the series options.		 *		 *  ```js		 *     data: [		 *         [0, 9, 7],		 *         [1, 10, 4],		 *         [2, 6, 3]		 *     ]		 *  ```		 *		 * 2.  An array of objects with named values. The following snippet shows only a		 * few settings, see the complete options set below. If the total number of data		 * points exceeds the series' [turboThreshold](#series.heatmap.turboThreshold),		 * this option is not available.		 *		 *  ```js		 *     data: [{		 *         x: 1,		 *         y: 3,		 *         value: 10,		 *         name: "Point2",		 *         color: "#00FF00"		 *     }, {		 *         x: 1,		 *         y: 7,		 *         value: 10,		 *         name: "Point1",		 *         color: "#FF00FF"		 *     }]		 *  ```		 *		 * @sample {highcharts} highcharts/chart/reflow-true/		 *         Numerical values		 * @sample {highcharts} highcharts/series/data-array-of-arrays/		 *         Arrays of numeric x and y		 * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/		 *         Arrays of datetime x and y		 * @sample {highcharts} highcharts/series/data-array-of-name-value/		 *         Arrays of point.name and y		 * @sample {highcharts} highcharts/series/data-array-of-objects/		 *         Config objects		 *		 * @type      {Array<Array<number>|*>}		 * @extends   series.line.data		 * @excluding marker		 * @product   highcharts highmaps		 * @apioption series.heatmap.data		 */		/**		 * The color of the point. In heat maps the point color is rarely set		 * explicitly, as we use the color to denote the `value`. Options for		 * this are set in the [colorAxis](#colorAxis) configuration.		 *		 * @type      {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}		 * @product   highcharts highmaps		 * @apioption series.heatmap.data.color		 */		/**		 * The value of the point, resulting in a color controled by options		 * as set in the [colorAxis](#colorAxis) configuration.		 *		 * @type      {number}		 * @product   highcharts highmaps		 * @apioption series.heatmap.data.value		 */		/**		 * The x value of the point. For datetime axes,		 * the X value is the timestamp in milliseconds since 1970.		 *		 * @type      {number}		 * @product   highcharts highmaps		 * @apioption series.heatmap.data.x		 */		/**		 * The y value of the point.		 *		 * @type      {number}		 * @product   highcharts highmaps		 * @apioption series.heatmap.data.y		 */		/**		 * Point padding for a single point.		 *		 * @sample maps/plotoptions/tilemap-pointpadding		 *         Point padding on tiles		 *		 * @type      {number}		 * @product   highcharts highmaps		 * @apioption series.heatmap.data.pointPadding		 */	}(Highcharts));	(function (H) {		/* *		 * Tilemaps module		 *		 * (c) 2010-2017 Highsoft AS		 * Author: Øystein Moseng		 *		 * License: www.highcharts.com/license		 */		var seriesType = H.seriesType,		    pick = H.pick,		    // Utility func to get the middle number of 3		    between = function (x, a, b) {		        return Math.min(Math.max(a, x), b);		    },		    // Utility func to get padding definition from tile size division		    tilePaddingFromTileSize = function (series, xDiv, yDiv) {		        var options = series.options;		        return {		            xPad: (options.colsize || 1) / -xDiv,		            yPad: (options.rowsize || 1) / -yDiv		        };		    };		// Map of shape types.		H.tileShapeTypes = {		    // Hexagon shape type.		    hexagon: {		        alignDataLabel: H.seriesTypes.scatter.prototype.alignDataLabel,		        getSeriesPadding: function (series) {		            return tilePaddingFromTileSize(series, 3, 2);		        },		        haloPath: function (size) {		            if (!size) {		                return [];		            }		            var hexagon = this.tileEdges;		            return [		                'M', hexagon.x2 - size, hexagon.y1 + size,		                'L', hexagon.x3 + size, hexagon.y1 + size,		                hexagon.x4 + size * 1.5, hexagon.y2,		                hexagon.x3 + size, hexagon.y3 - size,		                hexagon.x2 - size, hexagon.y3 - size,		                hexagon.x1 - size * 1.5, hexagon.y2,		                'Z'		            ];		        },		        translate: function () {		            var series = this,		                options = series.options,		                xAxis = series.xAxis,		                yAxis = series.yAxis,		                seriesPointPadding = options.pointPadding || 0,		                xPad = (options.colsize || 1) / 3,		                yPad = (options.rowsize || 1) / 2,		                yShift;		            series.generatePoints();		            series.points.forEach(function (point) {		                var x1 = between(		                        Math.floor(		                            xAxis.len -		                            xAxis.translate(point.x - xPad * 2, 0, 1, 0, 1)		                        ), -xAxis.len, 2 * xAxis.len		                    ),		                    x2 = between(		                        Math.floor(		                            xAxis.len -		                            xAxis.translate(point.x - xPad, 0, 1, 0, 1)		                        ), -xAxis.len, 2 * xAxis.len		                    ),		                    x3 = between(		                        Math.floor(		                            xAxis.len -		                            xAxis.translate(point.x + xPad, 0, 1, 0, 1)		                        ), -xAxis.len, 2 * xAxis.len		                    ),		                    x4 = between(		                        Math.floor(		                            xAxis.len -		                            xAxis.translate(point.x + xPad * 2, 0, 1, 0, 1)		                        ), -xAxis.len, 2 * xAxis.len		                    ),		                    y1 = between(		                        Math.floor(yAxis.translate(point.y - yPad, 0, 1, 0, 1)),		                        -yAxis.len,		                        2 * yAxis.len		                    ),		                    y2 = between(		                        Math.floor(yAxis.translate(point.y, 0, 1, 0, 1)),		                        -yAxis.len,		                        2 * yAxis.len		                    ),		                    y3 = between(		                        Math.floor(yAxis.translate(point.y + yPad, 0, 1, 0, 1)),		                        -yAxis.len,		                        2 * yAxis.len		                    ),		                    pointPadding = pick(point.pointPadding, seriesPointPadding),		                    // We calculate the point padding of the midpoints to		                    // preserve the angles of the shape.		                    midPointPadding = pointPadding *		                        Math.abs(x2 - x1) / Math.abs(y3 - y2),		                    xMidPadding = xAxis.reversed ?		                        -midPointPadding : midPointPadding,		                    xPointPadding = xAxis.reversed ?		                        -pointPadding : pointPadding,		                    yPointPadding = yAxis.reversed ?		                        -pointPadding : pointPadding;		                // Shift y-values for every second grid column		                if (point.x % 2) {		                    yShift = yShift || Math.round(Math.abs(y3 - y1) / 2) *		                        // We have to reverse the shift for reversed y-axes		                        (yAxis.reversed ? -1 : 1);		                    y1 += yShift;		                    y2 += yShift;		                    y3 += yShift;		                }		                // Set plotX and plotY for use in K-D-Tree and more		                point.plotX = point.clientX = (x2 + x3) / 2;		                point.plotY = y2;		                // Apply point padding to translated coordinates		                x1 += xMidPadding + xPointPadding;		                x2 += xPointPadding;		                x3 -= xPointPadding;		                x4 -= xMidPadding + xPointPadding;		                y1 -= yPointPadding;		                y3 += yPointPadding;		                // Store points for halo creation		                point.tileEdges = {		                    x1: x1, x2: x2, x3: x3, x4: x4, y1: y1, y2: y2, y3: y3		                };		                // Finally set the shape for this point		                point.shapeType = 'path';		                point.shapeArgs = {		                    d: [		                        'M', x2, y1,		                        'L', x3, y1,		                        x4, y2,		                        x3, y3,		                        x2, y3,		                        x1, y2,		                        'Z'		                    ]		                };		            });		            series.translateColors();		        }		    },		    // Diamond shape type.		    diamond: {		        alignDataLabel: H.seriesTypes.scatter.prototype.alignDataLabel,		        getSeriesPadding: function (series) {		            return tilePaddingFromTileSize(series, 2, 2);		        },		        haloPath: function (size) {		            if (!size) {		                return [];		            }		            var diamond = this.tileEdges;		            return [		                'M', diamond.x2, diamond.y1 + size,		                'L', diamond.x3 + size, diamond.y2,		                diamond.x2, diamond.y3 - size,		                diamond.x1 - size, diamond.y2,		                'Z'		            ];		        },		        translate: function () {		            var series = this,		                options = series.options,		                xAxis = series.xAxis,		                yAxis = series.yAxis,		                seriesPointPadding = options.pointPadding || 0,		                xPad = (options.colsize || 1),		                yPad = (options.rowsize || 1) / 2,		                yShift;		            series.generatePoints();		            series.points.forEach(function (point) {		                var x1 = between(		                        Math.round(		                            xAxis.len -		                            xAxis.translate(point.x - xPad, 0, 1, 0, 0)		                        ), -xAxis.len, 2 * xAxis.len		                    ),		                    x2 = between(		                        Math.round(		                            xAxis.len -		                            xAxis.translate(point.x, 0, 1, 0, 0)		                        ), -xAxis.len, 2 * xAxis.len		                    ),		                    x3 = between(		                        Math.round(		                            xAxis.len -		                            xAxis.translate(point.x + xPad, 0, 1, 0, 0)		                        ), -xAxis.len, 2 * xAxis.len		                    ),		                    y1 = between(		                        Math.round(yAxis.translate(point.y - yPad, 0, 1, 0, 0)),		                        -yAxis.len,		                        2 * yAxis.len		                    ),		                    y2 = between(		                        Math.round(yAxis.translate(point.y, 0, 1, 0, 0)),		                        -yAxis.len,		                        2 * yAxis.len		                    ),		                    y3 = between(		                        Math.round(yAxis.translate(point.y + yPad, 0, 1, 0, 0)),		                        -yAxis.len,		                        2 * yAxis.len		                    ),		                    pointPadding = pick(point.pointPadding, seriesPointPadding),		                    // We calculate the point padding of the midpoints to		                    // preserve the angles of the shape.		                    midPointPadding = pointPadding *		                        Math.abs(x2 - x1) / Math.abs(y3 - y2),		                    xPointPadding = xAxis.reversed ?		                        -midPointPadding : midPointPadding,		                    yPointPadding = yAxis.reversed ?		                        -pointPadding : pointPadding;		                // Shift y-values for every second grid column		                // We have to reverse the shift for reversed y-axes		                if (point.x % 2) {		                    yShift = Math.abs(y3 - y1) / 2 * (yAxis.reversed ? -1 : 1);		                    y1 += yShift;		                    y2 += yShift;		                    y3 += yShift;		                }		                // Set plotX and plotY for use in K-D-Tree and more		                point.plotX = point.clientX = x2;		                point.plotY = y2;		                // Apply point padding to translated coordinates		                x1 += xPointPadding;		                x3 -= xPointPadding;		                y1 -= yPointPadding;		                y3 += yPointPadding;		                // Store points for halo creation		                point.tileEdges = {		                    x1: x1, x2: x2, x3: x3, y1: y1, y2: y2, y3: y3		                };		                // Set this point's shape parameters		                point.shapeType = 'path';		                point.shapeArgs = {		                    d: [		                        'M', x2, y1,		                        'L', x3, y2,		                        x2, y3,		                        x1, y2,		                        'Z'		                    ]		                };		            });		            series.translateColors();		        }		    },		    // Circle shape type.		    circle: {		        alignDataLabel: H.seriesTypes.scatter.prototype.alignDataLabel,		        getSeriesPadding: function (series) {		            return tilePaddingFromTileSize(series, 2, 2);		        },		        haloPath: function (size) {		            return H.seriesTypes.scatter.prototype.pointClass.prototype.haloPath		                .call(		                    this,		                    size + (size && this.radius)		                );		        },		        translate: function () {		            var series = this,		                options = series.options,		                xAxis = series.xAxis,		                yAxis = series.yAxis,		                seriesPointPadding = options.pointPadding || 0,		                yRadius = (options.rowsize || 1) / 2,		                colsize = (options.colsize || 1),		                colsizePx,		                yRadiusPx,		                xRadiusPx,		                radius,		                forceNextRadiusCompute = false;		            series.generatePoints();		            series.points.forEach(function (point) {		                var x = between(		                        Math.round(		                            xAxis.len -		                            xAxis.translate(point.x, 0, 1, 0, 0)		                        ), -xAxis.len, 2 * xAxis.len		                    ),		                    y = between(		                        Math.round(yAxis.translate(point.y, 0, 1, 0, 0)),		                        -yAxis.len,		                        2 * yAxis.len		                    ),		                    pointPadding = seriesPointPadding,		                    hasPerPointPadding = false;		                // If there is point padding defined on a single point, add it		                if (point.pointPadding !== undefined) {		                    pointPadding = point.pointPadding;		                    hasPerPointPadding = true;		                    forceNextRadiusCompute = true;		                }		                // Find radius if not found already.		                // Use the smallest one (x vs y) to avoid overlap.		                // Note that the radius will be recomputed for each series.		                // Ideal (max) x radius is dependent on y radius:		                /*		                                * (circle 2)		                                        * (circle 3)		                                        |    yRadiusPx		                    (circle 1)    *-------|		                                 colsizePx		                    The distance between circle 1 and 3 (and circle 2 and 3) is		                    2r, which is the hypotenuse of the triangle created by		                    colsizePx and yRadiusPx. If the distance between circle 2		                    and circle 1 is less than 2r, we use half of that distance		                    instead (yRadiusPx).		                */		                if (!radius || forceNextRadiusCompute) {		                    colsizePx = Math.abs(		                        between(		                            Math.floor(		                                xAxis.len -		                                xAxis.translate(point.x + colsize, 0, 1, 0, 0)		                            ), -xAxis.len, 2 * xAxis.len		                        ) - x		                    );		                    yRadiusPx = Math.abs(		                        between(		                            Math.floor(		                                yAxis.translate(point.y + yRadius, 0, 1, 0, 0)		                            ), -yAxis.len, 2 * yAxis.len		                        ) - y		                    );		                    xRadiusPx = Math.floor(		                        Math.sqrt(		                            (colsizePx * colsizePx + yRadiusPx * yRadiusPx)		                        ) / 2		                    );		                    radius = Math.min(		                        colsizePx, xRadiusPx, yRadiusPx		                    ) - pointPadding;		                    // If we have per point padding we need to always compute		                    // the radius for this point and the next. If we used to		                    // have per point padding but don't anymore, don't force		                    // compute next radius.		                    if (forceNextRadiusCompute && !hasPerPointPadding) {		                        forceNextRadiusCompute = false;		                    }		                }		                // Shift y-values for every second grid column.		                // Note that we always use the optimal y axis radius for this.		                // Also note: We have to reverse the shift for reversed y-axes.		                if (point.x % 2) {		                    y += yRadiusPx * (yAxis.reversed ? -1 : 1);		                }		                // Set plotX and plotY for use in K-D-Tree and more		                point.plotX = point.clientX = x;		                point.plotY = y;		                // Save radius for halo		                point.radius = radius;		                // Set this point's shape parameters		                point.shapeType = 'circle';		                point.shapeArgs = {		                    x: x,		                    y: y,		                    r: radius		                };		            });		            series.translateColors();		        }		    },		    // Square shape type.		    square: {		        alignDataLabel: H.seriesTypes.heatmap.prototype.alignDataLabel,		        translate: H.seriesTypes.heatmap.prototype.translate,		        getSeriesPadding: function () {		        },		        haloPath: H.seriesTypes.heatmap.prototype.pointClass.prototype.haloPath		    }		};		// Extension to add pixel padding for series. Uses getSeriesPixelPadding on each		// series and adds the largest padding required. If no series has this function		// defined, we add nothing.		H.addEvent(H.Axis, 'afterSetAxisTranslation', function () {		    if (this.recomputingForTilemap) {		        return;		    }		    var axis = this,		        // Find which series' padding to use		        seriesPadding = axis.series		            .map(function (series) {		                return series.getSeriesPixelPadding &&		                    series.getSeriesPixelPadding(axis);		            })		            .reduce(function (a, b) {		                return (a && a.padding) > (b && b.padding) ? a : b;		            }, undefined) ||		            {		                padding: 0,		                axisLengthFactor: 1		            },		        lengthPadding = Math.round(		            seriesPadding.padding * seriesPadding.axisLengthFactor		        );		    // Don't waste time on this if we're not adding extra padding		    if (seriesPadding.padding) {		        // Recompute translation with new axis length now (minus padding)		        axis.len -= lengthPadding;		        axis.recomputingForTilemap = true;		        axis.setAxisTranslation();		        delete axis.recomputingForTilemap;		        axis.minPixelPadding += seriesPadding.padding;		        axis.len += lengthPadding;		    }		});		/**		 * @private		 * @class		 * @name Highcharts.seriesTypes.tilemap		 *		 * @augments Highcharts.Series		 */		seriesType('tilemap', 'heatmap'		    /**		 * A tilemap series is a type of heatmap where the tile shapes are configurable.		 *		 * @sample highcharts/demo/honeycomb-usa/		 *         Honeycomb tilemap, USA		 * @sample maps/plotoptions/honeycomb-brazil/		 *         Honeycomb tilemap, Brazil		 * @sample maps/plotoptions/honeycomb-china/		 *         Honeycomb tilemap, China		 * @sample maps/plotoptions/honeycomb-europe/		 *         Honeycomb tilemap, Europe		 * @sample maps/demo/circlemap-africa/		 *         Circlemap tilemap, Africa		 * @sample maps/demo/diamondmap		 *         Diamondmap tilemap		 *		 * @extends      plotOptions.heatmap		 * @since        6.0.0		 * @excluding    jitter, joinBy, shadow, allAreas, mapData, data		 * @product      highcharts highmaps		 * @optionparent plotOptions.tilemap		 */		    , { // Default options		        states: {		            hover: {		                halo: {		                    enabled: true,		                    size: 2,		                    opacity: 0.5,		                    attributes: {		                        zIndex: 3		                    }		                }		            }		        },		        /**		     * The padding between points in the tilemap.		     *		     * @sample maps/plotoptions/tilemap-pointpadding		     *         Point padding on tiles		     */		        pointPadding: 2,		        /**		     * The column size - how many X axis units each column in the tilemap		     * should span. Works as in [Heatmaps](#plotOptions.heatmap.colsize).		     *		     * @sample {highcharts} maps/demo/heatmap/		     *         One day		     * @sample {highmaps} maps/demo/heatmap/		     *         One day		     *		     * @type      {number}		     * @default   1		     * @product   highcharts highmaps		     * @apioption plotOptions.tilemap.colsize		     */		        /**		     * The row size - how many Y axis units each tilemap row should span.		     * Analogous to [colsize](#plotOptions.tilemap.colsize).		     *		     * @sample {highcharts} maps/demo/heatmap/		     *         1 by default		     * @sample {highmaps} maps/demo/heatmap/		     *         1 by default		     *		     * @type      {number}		     * @default   1		     * @product   highcharts highmaps		     * @apioption plotOptions.tilemap.rowsize		     */		        /**		     * The shape of the tiles in the tilemap. Possible values are `hexagon`,		     * `circle`, `diamond`, and `square`.		     *		     * @sample maps/demo/circlemap-africa		     *         Circular tile shapes		     * @sample maps/demo/diamondmap		     *         Diamond tile shapes		     *		     * @validvalue ["circle", "diamond", "hexagon", "square"]		     */		        tileShape: 'hexagon'		    }, { // Prototype functions		        // Set tile shape object on series		        setOptions: function () {		        // Call original function		            var ret = H.seriesTypes.heatmap.prototype.setOptions.apply(		                this,		                Array.prototype.slice.call(arguments)		            );		            this.tileShape = H.tileShapeTypes[ret.tileShape];		            return ret;		        },		        // Use the shape's defined data label alignment function		        alignDataLabel: function () {		            return this.tileShape.alignDataLabel.apply(		                this,		                Array.prototype.slice.call(arguments)		            );		        },		        // Get metrics for padding of axis for this series		        getSeriesPixelPadding: function (axis) {		            var isX = axis.isXAxis,		                padding = this.tileShape.getSeriesPadding(this),		                coord1,		                coord2;		            // If the shape type does not require padding, return no-op padding		            if (!padding) {		                return {		                    padding: 0,		                    axisLengthFactor: 1		                };		            }		            // Use translate to compute how far outside the points we		            // draw, and use this difference as padding.		            coord1 = Math.round(		                axis.translate(		                    isX ?		                        padding.xPad * 2 :		                        padding.yPad,		                    0, 1, 0, 1		                )		            );		            coord2 = Math.round(		                axis.translate(		                    isX ? padding.xPad : 0,		                    0, 1, 0, 1		                )		            );		            return {		                padding: Math.abs(coord1 - coord2) || 0,		                // Offset the yAxis length to compensate for shift. Setting the		                // length factor to 2 would add the same margin to max as min.		                // Now we only add a slight bit of the min margin to max, as we		                // don't actually draw outside the max bounds. For the xAxis we		                // draw outside on both sides so we add the same margin to min		                // and max.		                axisLengthFactor: isX ? 2 : 1.1		            };		        },		        // Use translate from tileShape		        translate: function () {		            return this.tileShape.translate.apply(		                this,		                Array.prototype.slice.call(arguments)		            );		        }		    }, H.extend({		        /**		     * @private		     * @function Highcharts.Point#haloPath		     *		     * @return {Highcharts.SVGPathArray}		     */		        haloPath: function () {		            return this.series.tileShape.haloPath.apply(		                this,		                Array.prototype.slice.call(arguments)		            );		        }		    }, H.colorPointMixin));		/**		 * A `tilemap` series. If the [type](#series.tilemap.type) option is		 * not specified, it is inherited from [chart.type](#chart.type).		 *		 * @extends   series,plotOptions.tilemap		 * @excluding allAreas, dataParser, dataURL, joinBy, mapData, marker,		 *            pointRange, shadow, stack		 * @product   highcharts highmaps		 * @apioption series.tilemap		 */		/**		 * An array of data points for the series. For the `tilemap` series		 * type, points can be given in the following ways:		 *		 * 1. An array of arrays with 3 or 2 values. In this case, the values correspond		 *    to `x,y,value`. If the first value is a string, it is applied as the name		 *    of the point, and the `x` value is inferred. The `x` value can also be		 *    omitted, in which case the inner arrays should be of length 2\. Then the		 *    `x` value is automatically calculated, either starting at 0 and		 *    incremented by 1, or from `pointStart` and `pointInterval` given in the		 *    series options.		 *    ```js		 *    data: [		 *        [0, 9, 7],		 *        [1, 10, 4],		 *        [2, 6, 3]		 *    ]		 *    ```		 *		 * 2. An array of objects with named values. The objects are point configuration		 *    objects as seen below. If the total number of data points exceeds the		 *    series' [turboThreshold](#series.tilemap.turboThreshold), this option is		 *    not available.		 *    ```js		 *    data: [{		 *        x: 1,		 *        y: 3,		 *        value: 10,		 *        name: "Point2",		 *        color: "#00FF00"		 *    }, {		 *        x: 1,		 *        y: 7,		 *        value: 10,		 *        name: "Point1",		 *        color: "#FF00FF"		 *    }]		 *    ```		 *		 * Note that for some [tileShapes](#plotOptions.tilemap.tileShape) the grid		 * coordinates are offset.		 *		 * @sample maps/series/tilemap-gridoffset		 *         Offset grid coordinates		 * @sample {highcharts} highcharts/series/data-array-of-arrays/		 *         Arrays of numeric x and y		 * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/		 *         Arrays of datetime x and y		 * @sample {highcharts} highcharts/series/data-array-of-name-value/		 *         Arrays of point.name and y		 * @sample {highcharts} highcharts/series/data-array-of-objects/		 *         Config objects		 *		 * @type      {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}		 * @extends   series.heatmap.data		 * @excluding marker		 * @product   highcharts highmaps		 * @apioption series.tilemap.data		 */		/**		 * The color of the point. In tilemaps the point color is rarely set		 * explicitly, as we use the color to denote the `value`. Options for		 * this are set in the [colorAxis](#colorAxis) configuration.		 *		 * @type      {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}		 * @product   highcharts highmaps		 * @apioption series.tilemap.data.color		 */		/**		 * The x coordinate of the point.		 *		 * Note that for some [tileShapes](#plotOptions.tilemap.tileShape) the grid		 * coordinates are offset.		 *		 * @sample maps/series/tilemap-gridoffset		 *         Offset grid coordinates		 *		 * @type      {number}		 * @product   highcharts highmaps		 * @apioption series.tilemap.data.x		 */		/**		 * The y coordinate of the point.		 *		 * Note that for some [tileShapes](#plotOptions.tilemap.tileShape) the grid		 * coordinates are offset.		 *		 * @sample maps/series/tilemap-gridoffset		 *         Offset grid coordinates		 *		 * @type      {number}		 * @product   highcharts highmaps		 * @apioption series.tilemap.data.y		 */	}(Highcharts));	return (function () {	}());}));
 |